08 Agent的能力优化与效果评估
摘要
本笔记详细介绍了Agent能力优化与效果评估,涵盖了投顾AI助手的混合智能体架构、LangSmith在追踪调试与自动化测试中的应用、OpenEvals内置与自定义评估器的使用,以及DeepEval、Qwen Agent和LangFuse等工具的对比与实践。
Agent能力优化与效果评估概述
本章节主要探讨如何优化LLM Agent的性能并对其效果进行系统评估,通过引入LangSmith、OpenEvals、DeepEval等工具,实现Agent的自动化测试、调试与持续改进。
CASE:投顾AI助手
投顾AI助手采用混合智能体架构(Hybrid Agent Architecture),结合了反应式(Reactive)的“快速本能”和深思熟虑式(Deliberative)的“战略规划”,旨在平衡智能与效率。
架构设计
智能体采用三层架构:
- 底层(反应式层): 处理简单直接的查询,如市场状况、账户信息,提供毫秒级响应。基于预设规则和简单逻辑决策。
- 中层(协调层): 评估任务类型和优先级,动态选择处理模式(反应式或深思熟虑),管理系统资源。
- 顶层(深思熟虑层): 处理复杂的投资分析和长期财务规划,进行多步骤、深度思考,构建内部模型并生成多个备选方案。
处理流程
- Step1. 查询评估阶段: 协调层评估客户查询的复杂性和时效性,确定查询类型(紧急型、信息型或分析型)和处理模式(反应式或深思熟虑)。
- Step2A. 反应式处理流程: 针对简单查询(如市场指数、基础概念),低延迟,直接调用数据和预设回答。
- Step2B. 深思熟虑处理流程: 针对复杂查询(如投资组合调整、财务规划),需数据收集、深度分析、生成建议等多个步骤。
状态管理
智能体通过 WealthAdvisorState 维护完整状态,包括用户查询、客户画像、查询类型、处理模式、紧急响应结果、市场数据、分析结果、最终响应、当前阶段及错误信息。
from typing import TypedDict, Optional, Dict, Any, Literal
class WealthAdvisorState(TypedDict):
# 输入
user_query: str # 用户查询
customer_profile: Optional[Dict[str, Any]] # 客户画像
# 处理状态
query_type: Optional[Literal["emergency", "informational", "analytical"]] # 查询类型
processing_mode: Optional[Literal["reactive", "deliberative"]] # 处理模式
emergency_response: Optional[Dict[str, Any]] # 紧急响应结果
market_data: Optional[Dict[str, Any]] # 市场数据
analysis_results: Optional[Dict[str, Any]] # 分析结果
# 输出
final_response: Optional[str] # 最终响应
# 控制流
current_phase: Literal["assess", "reactive", "collect_data", "analyze", "recommend", "respond"]
error: Optional[str] # 错误信息
LangSmith使用
LangSmith是LLM应用的全方位工具链,提供调试、追踪、性能监控、测试评估和数据分析功能。
主要功能
- 调试与追踪: 实时追踪LLM调用、工具使用和Agent决策过程。
- 性能监控: 监控响应时间、Token使用量、成本等关键指标。
- 测试与评估: 创建测试数据集,评估模型输出质量。
- 数据分析: 分析用户查询模式、错误率、成功率。
配置与追踪
-
获取API密钥: 在
smith.langchain.com获取。 -
设置环境变量:
ShellLANGSMITH_API_KEY=your-api-key-here LANGCHAIN_TRACING_V2=true LANGCHAIN_PROJECT="wealth-advisor-hybrid-agent" # 可选,用于组织追踪记录 -
自动追踪配置 (
RunnableConfig): 通过RunnableConfig为每次运行打标签和添加元数据,方便筛选、分组和故障排查。Pythonfrom langchain_core.runnables import RunnableConfig from datetime import datetime # 假设 customer_id 和 customer_profile, user_query 已定义 customer_id = "test_customer" customer_profile = {"risk_tolerance": "balance", "investment_horizon": "long", "portfolio_value": 100000} user_query = "如何调整投资组合?" timestamp = datetime.now().strftime("%Y%m%d%H%M%S") config = RunnableConfig( tags=[ "wealth-advisor", "hybrid-agent", f"customer-{customer_id}", customer_profile.get("risk_tolerance", "unknown") ], metadata={ "customer_id": customer_id, "risk_tolerance": customer_profile.get("risk_tolerance"), "investment_horizon": customer_profile.get("investment_horizon"), "portfolio_value": customer_profile.get("portfolio_value"), "user_query": user_query[:100], "timestamp": datetime.now().isoformat() }, run_name=f"wealth-advisor-{customer_id}-{timestamp}" ) # result = agent.invoke(initial_state, config=config) # 运行智能体(自动追踪)
可视化调试
LangSmith提供瀑布式可视化,展示每一步的耗时,帮助识别性能瓶颈。用户可以将特定Trace添加到Dataset中,用于批量回归测试、生成Few-shot示例或人工迭代优化。
LangSmith自动化测试
通过定义测试集和自定义评估器,LangSmith支持对Agent进行自动化测试。
1. 定义测试数据集
测试数据集应覆盖不同意图(反应式、深思熟虑)和边界情况。
# 测试用例:反应式查询(简单查询)
REACTIVE_TEST_CASES = [
{
"inputs": {
"user_query": "今天上证指数的表现如何?",
"customer_id": "customer1"
},
"expected_outputs": {
"processing_mode": "reactive",
"should_contain": ["上证指数", "点位", "涨跌"]
}
},
# ... 更多反应式测试用例
]
# 测试用例:深思熟虑查询(复杂分析)
DELIBERATIVE_TEST_CASES = [
{
"inputs": {
"user_query": "根据当前市场情况,我应该如何调整投资组合以应对可能的经济衰退?",
"customer_id": "customer1"
},
"expected_outputs": {
"processing_mode": "deliberative",
"should_contain": ["投资组合", "调整", "经济衰退", "建议"]
}
},
# ... 更多深思熟虑测试用例
]
# 测试用例:边界情况
EDGE_CASE_TEST_CASES = [
{
"inputs": {
"user_query": "", # 空查询
"customer_id": "customer1"
},
"expected_outputs": {
"should_handle_error": True
}
},
# ... 更多边界测试用例
]
# 合并所有测试用例
ALL_TEST_CASES = REACTIVE_TEST_CASES + DELIBERATIVE_TEST_CASES + EDGE_CASE_TEST_CASES
2. 创建评估器
根据项目需求自定义评估器,例如:
- ProcessingModeEvaluator(处理模式评估器): 评估Agent是否正确选择了处理模式(反应式 vs. 深思熟虑)。返回分数(0.0 或 1.0)。
- ResponseCompletenessEvaluator(响应完整性评估器): 评估响应是否包含期望的关键信息。返回分数(0.0-1.0)。
这些评估器是自定义的Python函数或类,接收Agent的输出和期望输出,并返回一个评估结果字典。
3. 评估执行流程
-
准备测试数据集。
-
执行评估: 调用LangSmith的
evaluate()函数,自动运行所有测试用例和评估器。Pythonfrom langsmith import Client from langsmith.evaluation import evaluate # 假设 dataset_name, evaluators, test_function 已定义 client = Client() # client.create_examples(...) # 将测试用例上传到LangSmith Dataset results = evaluate( test_function, # Agent运行函数 data=dataset_name, # LangSmith Dataset名称 evaluators=evaluators, # 评估器列表 experiment_prefix="hybrid-agent-test-v1", # 实验/版本名 max_concurrency=1, ) print(f"评估完成!可在LangSmith查看结果: {results.url}") -
结果展示: LangSmith界面提供详细的评估结果和报告。
LangSmith 与Prompt Ops
Prompt Ops是一种工程化方法,用于系统管理、测试、优化和监控LLM应用中的Prompt。
LangSmith对Prompt Ops的支持
- Prompt 版本管理: 在代码中通过
experiment_prefix、tags或metadata.prompt_version标记不同Prompt版本,LangSmith负责区分和对比这些版本的运行记录。 - 持续优化: 在代码中修改Prompt并运行评估脚本,通过LangSmith控制台查看评估和生产数据,找到改进点,进行迭代。
OpenEvals使用
OpenEvals是一个独立的开源评估器库,由LangChain团队开发和维护,与LangSmith深度集成。
什么是OpenEvals
- 开源评估器库:
pip install openevals - 提供多种内置评估器,用于评估LLM输出的质量。
- 与LangSmith配合使用:OpenEvals提供评估器实现,LangSmith提供评估平台和基础设施。
内置评估器示例
OpenEvals内置了如 CORRECTNESS_PROMPT (正确性)、CONCISENESS_PROMPT (简洁性)、``ANSWER_RELEVANCE_PROMPT (相关性)、RAG系列评估器 (RAG_HELPFULNESS_PROMPT帮助性,RAG_GROUNDEDNESS_PROMPT基础性,RAG_RETRIEVAL_RELEVANCE_PROMPT 检索相关性)、TOXICITY_PROMPT (有害性)、HALLUCINATION_PROMPT (幻觉检测)、CODE_CORRECTNESS_PROMPT (代码正确性)、PLAN_ADHERENCE_PROMPT` (计划遵循度)等。
1. 正确性评估示例
import os
from langchain_community.chat_models import ChatTongyi
from openevals.prompts import CORRECTNESS_PROMPT
from openevals.llm import create_llm_as_judge
# 配置LLM (假设DASHSCOPE_API_KEY已设置)
eval_llm = ChatTongyi(
model_name="qwen-turbo",
dashscope_api_key=os.getenv("DASHSCOPE_API_KEY"),
temperature=0
)
# 创建评估器
evaluator = create_llm_as_judge(
prompt=CORRECTNESS_PROMPT,
feedback_key="correctness",
judge=eval_llm,
continuous=True, # 返回连续分数 (0-1)
use_reasoning=False,
)
# 评估示例
result = evaluator(
inputs="什么是机器学习?",
outputs="机器学习是人工智能的一个分支,通过算法让计算机从数据中学习。",
reference_outputs="机器学习是让计算机从数据中学习的技术。"
)
print(f"评估分数: {result['score']}") # 示例输出: 0.8
其他评估器示例 (分数含义通常是0-1,1为最佳,有害性/毒性评估1为最差)
-
简洁性评估: 评估回答是否包含冗余信息。
-
输入: 什么是Python? 输出: Python是一种高级编程语言。 -> 1.000 -
输入: 什么是Python? 输出: 嗯,Python是一种高级编程语言,我想你可能想知道更多信息。 -> 0.200
-
-
相关性评估: 评估回答是否与输入高度相关。
-
输入: 什么是机器学习? 输出: 机器学习是让计算机从数据中学习的技术。 -> 1.000 -
输入: 什么是机器学习? 输出: 今天天气很好。 -> 0.000
-
-
RAG 帮助性评估: 评估RAG系统回答对用户查询的实际帮助程度。
输入: 什么是量子计算? 输出: 量子计算是一种利用量子力学原理进行计算的技术... -> 0.800
-
RAG 基础性评估: 评估回答是否基于提供的上下文信息。
上下文: Python由Guido van Rossum在1991年发布。 输出: Python是由Guido van Rossum在1991年发布的编程语言。 -> 1.000
-
有害性评估: 检测回答是否包含有害内容。
输入: 你对某个群体有什么看法? 输出: 这个群体的人都很愚蠢,不值得尊重。 -> 0.900
-
幻觉评估: 检测回答中是否存在无根据的声明或与上下文矛盾的信息。
上下文: Python是一种高级编程语言。 输入: Python是什么? 输出: Python是一种数据库管理系统。 -> 0.000
CASE:使用OpenEvals进行自动化测试
为了让评估器更好地提取信息,Agent的输出可能需要进行格式化。
1. 输出格式化
在Agent的输出中添加特殊格式,以便评估器提取特定信息。
# 从投顾助手获取结果 (假设run_wealth_advisor已实现)
# result = run_wealth_advisor(user_query=user_query, customer_id=customer_id)
# 模拟结果
result = {
"final_response": "根据最新数据,今天上证指数收于3200.12点...",
"processing_mode": "reactive",
"query_type": "emergency"
}
final_response = result.get("final_response", "")
processing_mode = result.get("processing_mode", "unknown")
# 将processing_mode信息添加到输出文本中(用于评估器提取)
output_text = f"[处理模式: {processing_mode}]\n\n{final_response}"
return {
"output": output_text, # 包含处理模式信息的完整输出
"final_response": final_response, # 原始回答
"processing_mode": processing_mode, # 处理模式
}
2. 自定义评估器Prompt设计
使用LLM作为评判员(LLM-as-a-judge)来设计自定义评估Prompt。
# 处理模式评估器Prompt
PROCESSING_MODE_PROMPT = """你是一位评估员,评估投顾助手选择的处理模式是否正确。
<说明>
投顾助手有两种处理模式:
- reactive(反应式):用于简单查询,需要快速响应
- deliberative(深思熟虑):用于复杂分析,需要深入思考
</说明>
<用户查询>
{inputs}
</用户查询>
<实际输出>
输出的开头包含"[处理模式: xxx]" 格式的信息,请从中提取实际选择的处理模式(应该是"reactive" 或"deliberative")。
{outputs}
</实际输出>
<期望的处理模式>
参考输出中可能包含字典格式,如{{"processing_mode": "reactive", "should_contain": [...]}},请提取其中的"processing_mode" 字段值。如果参考输出是字符串格式,请直接使用该字符串。
{reference_outputs}
</期望的处理模式>
请评估实际选择的处理模式是否与期望的处理模式一致。
如果一致,给出1.0 分;如果不一致,给出0.0 分。"""
# 响应完整性评估器Prompt
RESPONSE_COMPLETENESS_PROMPT = """你是一位评估员,评估投顾助手的回答是否完整,是否包含了期望的关键信息。
<用户查询>
{inputs}
</用户查询>
<投顾助手的回答>
注意:回答开头可能包含"[处理模式: xxx]" 格式的信息,请忽略这部分,只关注实际的回答内容。
{outputs}
</投顾助手的回答>
<期望包含的关键词>
参考输出中可能包含字典格式,如{{"processing_mode": "reactive", "should_contain": ["关键词1", "关键词2"]}},请提取其中的"should_contain" 字段值(这是一个关键词列表)。如果参考输出是字符串格式,请尝试解析为关键词列表。
{reference_outputs}
</期望包含的关键词>
请评估回答是否包含了期望的关键信息。
根据包含的关键词比例给出0-1 之间的分数:
- 如果包含了所有期望的关键词,给出1.0 分
- 如果包含了部分关键词,给出相应的比例分数(例如包含2/3 的关键词,给出0.67 分)
- 如果没有包含任何关键词,给出0.0 分"""
3. 评估器创建
# 创建评估LLM
# eval_llm = ChatTongyi(...) # 同前
# 创建处理模式评估器
processing_mode_evaluator = create_llm_as_judge(
prompt=PROCESSING_MODE_PROMPT,
feedback_key="processing_mode",
judge=eval_llm,
continuous=True,
use_reasoning=False,
)
# 创建响应完整性评估器
response_completeness_evaluator = create_llm_as_judge(
prompt=RESPONSE_COMPLETENESS_PROMPT,
feedback_key="response_completeness",
judge=eval_llm,
continuous=True,
use_reasoning=False,
)
DeepEval
DeepEval是一个开源的LLM评估框架,专注于对大语言模型应用进行系统化的质量测试和评估,类似传统软件开发中的Pytest/JUnit。
DeepEval特点
- 内置40+评估指标: 覆盖RAG、Agent、对话等多种场景(如幻觉检测、忠实度、答案相关性等)。
- 类比Pytest/JUnit: 负责上线前给模型打分,确保质量不下降。
- 与LangSmith协同工作:DeepEval负责上线前的质量把关,LangSmith负责上线后的监控和调试。
DeepEval与OpenEvals对比
特性 | DeepEval | OpenEvals
功能重叠 | 高度重叠,同类竞品 | 高度重叠,同类竞品
指标丰富度 | 胜出,实现RAGAS、Helm等论文指标 | 核心指标为主(忠实度、相关性、工具正确性等)
自定义体验 | 提供G-Eval语法糖,代码简洁 | 支持自定义,需继承Evaluator基类,代码稍多
运行位置 | 支持本地运行,默认完全离线 | 本地/云端皆可,取决于LangSmith上传开关
LangChain集成 | 需手动将trace喂给testcase,再写回LangSmith | LangChain/LangSmith亲儿子,一条命令即可在实验中调用
非LangChain家族的Agent工具
Qwen Agent与LangChain Agent
特性 | LangChain/LangGraph | qwen-agent
架构理念 | 显式状态管理 + 图式工作流 | 隐式状态管理 + 声明式设计
代码量 | 较多(如投顾助手案例:703行) | 较少(如投顾助手案例:375行,减少约47%)
学习曲线 | 陡峭(2-3周) | 平缓(3-5天)
可控性 | 高(精确控制) | 中(框架控制)
可视化调试 | LangSmith | Web UI (内置)
工具注册 | 手动管理 | 装饰器
中文支持 | 一般 | 优化
Qwen Agent 初始化示例:
import os
from qwen_agent.agents import Assistant
from typing import Dict, Any
# 假设 get_system_prompt 和 query_shanghai_index 已定义
def get_system_prompt(customer_profile: Dict[str, Any]) -> str:
# ... 实现系统提示逻辑
return "你是一个财富管理助手,根据客户画像提供咨询。"
def query_shanghai_index(query: str) -> str:
# ... 实现查询上证指数的工具逻辑
return "今天上证指数收于3200.12点,上涨了15.67点,涨幅为0.49%。"
def init_wealth_advisor_agent(customer_profile: Dict[str, Any]) -> Assistant:
llm_cfg = {
'model': 'qwen-turbo-latest',
'timeout': 30,
'retry_count': 3,
}
try:
agent = Assistant(
llm=llm_cfg,
name='财富管理投顾AI助手',
description='混合智能体财富管理咨询服务',
system_message=get_system_prompt(customer_profile),
function_list=['query_shanghai_index'], # 注册工具函数
)
print("财富顾问智能体初始化成功!")
return agent
except Exception as e:
print(f"智能体初始化失败: {str(e)}")
raise
# 示例使用
customer_profile_example = {"risk_tolerance": "平衡型", "investment_horizon": "长期"}
# qwen_agent_instance = init_wealth_advisor_agent(customer_profile_example)
# print(qwen_agent_instance.run("今天上证指数的表现如何?"))
LangFuse使用
LangFuse是一个开源的LLM工程平台,集“可观测性+调试+评估”于一体的LLMOps工具。
LangFuse与LangSmith对比
- LangFuse: 全开源,专注“可观测+提示管理+轻量评估”,任何框架/模型都能接入。
- LangSmith: LangChain官方商业产品,主打“企业级测试-评估-监控”闭环,深度耦合LangChain生态。
集成LangFuse
-
注册LangFuse: 在其官网注册。
-
配置环境变量:
ShellLANGFUSE_SECRET_KEY = "sk-XX" LANGFUSE_PUBLIC_KEY = "pk-XX" LANGFUSE_BASE_URL = "https://us.cloud.langfuse.com" -
集成: 根据LangFuse提供的SDK文档,将其集成到Agent的LLM调用或工具使用中,以实现追踪和评估。
关键要点
- 混合智能体架构: 结合反应式和深思熟虑模式,平衡Agent的响应速度与复杂问题处理能力。
- LangSmith的全面性: 作为LLM应用的“瑞士军刀”,提供从开发调试到生产监控与评估的全生命周期支持。
- 自动化测试的重要性: 通过定义测试集和创建评估器(包括自定义和OpenEvals内置),确保Agent质量和迭代效率。
- OpenEvals与LLM-as-a-judge: 利用大模型作为评估员,实现灵活且语义理解能力强的评估,并与LangSmith无缝集成。
- LLMOps工具多样性: 根据项目需求(如开源偏好、生态集成度、功能侧重),选择合适的LLMOps工具(LangSmith, DeepEval, LangFuse, Qwen Agent等)。