构建产品和应用程序从未像现在这样简单,但有效地度量这些系统仍然是一个巨大的挑战。虽然团队通常面临着快速发布的压力,但花时间严格评估性能和质量能带来长期的回报,并最终使团队能够以更强的信心更快地行动。如果没有严格的评估和度量,关于发布哪些变更的决策将变得更加困难。严格的度量和验证不仅对于优化性能至关重要,而且对于建立信任和确保符合用户期望也是必不可少的。
本章探讨了评估基于智能体(Agent-based)系统的方法,涵盖关键原则、度量技术和验证策略。我们将探讨定义明确目标、选择合适指标以及实施稳健测试框架的关键作用,评估系统在现实条件下的性能。除了基本功能外,智能体输出的可靠性——包括准确性、一致性、连贯性和响应能力——需要系统的审查,特别是考虑到驱动这些系统的基础模型(Foundation Models)通常具有概率性质。
在本章中,我们将使用一个处理常见电商场景的客户支持智能体案例:一位客户报告咖啡杯破损并要求退款。我们将以此案例为基础,探索诸如多件商品订单、取消订单或更改地址等变体,来说明度量、验证和部署的过程。
本书代码请见:https://github.com/alanhou/ai-agent。
度量智能体系统 (Measuring Agentic Systems)
如果没有严格的度量,就不可能确保系统达到其预期目标或应对现实环境的复杂性。通过定义明确的目标、建立相关的指标并采用系统的评估流程,开发人员可以指导智能体系统的设计和实施,从而实现高性能和用户满意度。

度量是基石
有效的度量始于确定清晰、可操作的指标,这些指标应与智能体系统的目标和要求保持一致。这些指标是评估智能体执行任务和满足用户期望能力的基准。成功取决于定义具体的、可衡量的目标,这些目标反映了系统的预期结果,例如增强用户参与度或自动化复杂流程。通过构建“英雄场景”(hero scenarios)——即高优先级用例的代表性示例——开发人员可以确保其度量标准针对的是定义智能体成功的核心功能。缺乏严格和持续的度量,就不可能知道变更是否真正带来了改进,无法了解智能体在现实和对抗性设置中的表现,也无法防范意外的性能回退。
选择正确的指标同样至关重要。指标应包含定量指标(如准确性、响应时间、鲁棒性、可扩展性、精确率和召回率)以及定性指标(如用户满意度)。例如,在客户服务智能体中,响应时间和准确性可以衡量性能,而用户反馈则对应整体满意度。这些指标必须反映系统将面临的现实世界需求。
对于基于语言的智能体,传统的精确匹配(exact-match)指标通常无法捕捉真正的效用,因为正确的答案可能有多种形式。因此,现代实践越来越依赖语义相似度度量——例如基于嵌入的距离(embedding-based distance)、BERTScore、BLEU(双语评估替补)或 ROUGE(面向召回的摘要评估替补)——来评估智能体的输出是否真正符合给定任务的意图,即使措辞与参考答案不同。
为了实现度量的益处,至关重要的是将评估机制直接集成到智能体开发生命周期中。成功的团队不会将评估留到最后,而是尽可能实现自动化,每当合并新代码或更新模型时就触发测试。通过随时间推移维护关键指标的一致事实来源(source of truth),可以及早发现回退,防止新的错误或降级进入生产环境。然而,自动化评估很少能说明全部情况。特别是在新颖或高风险领域,定期抽样和人在环路(human-in-the-loop)的审查可以揭示智能体输出中的微妙问题,并提供关于进展或遗留挑战的定性感知。最有效的团队将评估视为一个迭代过程,根据持续的反馈和不断变化的需求来完善他们的智能体和度量标准。
将评估集成到开发生命周期中
度量绝不能是事后诸葛亮,也不能留给非正式的方法,如简单地“目测”输出或依赖直觉。如果没有系统的评估,即便是专家团队也很容易自欺欺人,相信他们的智能体系统正在改进,而实际上这种进步是虚幻的或不均衡的。领先的团队将自动化的离线评估集成到开发的每个阶段。当新的工具或工作流被添加到智能体时,相应的测试用例和评估示例也应添加到不断增长的评估集中。这种严格的方法确保了进步不仅是针对固定基准进行衡量的,而且是跨越系统能力不断扩大的范围进行衡量的。
高质量的评估集可以作为智能体必须处理的内容的“活规范”,支持系统演变时的可复现性和回退检测。通过跟踪这些评估集上的历史结果,团队可以识别出表面上的改进何时是以系统中其他地方新引入的错误或降级为代价的。与临时或手动审查相比,这种严格的实践强制执行了一种问责文化,并为决策提供了量化基础。最终,正是对评估集的精心策划和持续扩展——不仅匹配遗留功能也匹配新兴功能——使得团队能够保持对其指标的信任,并确保智能体系统真正朝着预期目标前进。
创建和扩展评估集
任何度量策略的基础都是高质量的评估集——它反映了系统在现实世界中将面临的多样性、模糊性和边缘情况。静态的、手工策划的测试套件对于现代智能体系统来说是不够的:它们有过度拟合的风险,会错过长尾故障模式,并且无法跟上不断演变的工作流和用户行为。
一个好的评估集定义了输入状态和预期结果,从而实现智能体行为的自动化验证。来看这个客服智能体的说明性示例,它扩展了我们的马克杯破损场景,现在包含多个项目:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
{ "order": { "order_id": "A89268", "status": "Delivered", "total": 39.99, "items": [ {"sku": "MUG-001", "name": "Ceramic Coffee Mug", "qty": 1, "unit_price": 19.99}, {"sku": "TSHIRT-S", "name": "T-Shirt-Small", "qty": 1, "unit_price": 20.00} ], "delivered_at": "2025-05-15" }, "conversation": [ {"role": "customer", "content": "你好,我的咖啡杯到了,但是裂了。我可以换货或者退款吗?"}, {"role": "assistant", "content": "非常抱歉听到这个消息!您能发一张损坏照片给我们吗?这样我们可以为您办理全额退款。"}, {"role": "customer", "content": "好的,这是照片。"} ], "expected": { "final_state": { "tool_calls": [ {"tool": "issue_refund", "params": {"order_id": "A12345", "amount": 19.99}} ], "customer_msg_contains": ["已处理", "工作日"] } }} |
这个单例同时测试了几件事。它验证智能体是否可以针对多商品订单进行正确推理,将对话上下文与工具使用相匹配,并生成人性化的确认信息。诸如工具召回率、参数准确性和短语召回率等评估指标可以量化这些行为。如果智能体对整个订单退款,或者未能在最终消息中包含适当的语言,这些指标将反映出错误——为改进提供精确、可操作的信号。
通过以结构化格式(包括输入状态、对话历史和预期最终状态)形式化评估示例,团队可以自动化评分并跨各种场景聚合指标。这种格式具有很好的扩展性。一旦建立,新的示例可以手工添加,从生产日志中挖掘,甚至使用基础模型生成。语言模型可以通过提示来引入歧义、注入罕见的成语,或将工作示例突变为边缘情况。这些模型生成的样本随后可以由人类在纳入测试集之前进行审查和完善。
为了进一步突破界限,团队可以应用有针对性的生成技术,如对抗性提示(例如,“找到一条导致智能体自相矛盾的用户消息”)、反事实编辑(例如,“更改提示中的一个词,看看智能体是否会失败”)或分布插值(例如,“混合两个意图以创建一个故意模棱两可的请求”)。这些策略可以揭示微妙的错误并探查智能体行为的鲁棒性。
在拥有现实世界数据(如客服日志或 API 调用跟踪)的领域中,特定领域的挖掘提供了另一个丰富的评估材料来源。同时,像 MMLU、BBH 和 HELM 这样的标准基准可以帮助在更广泛的领域趋势中情境化性能,即使自定义基准对于特定领域的智能体仍然至关重要。
随着时间的推移,结构良好的评估集不仅仅是一个测试套件——它变成了智能体预期处理内容的活规范。它支持回退检测,确保持续监控,并推动真正的进步,确保智能体行为不仅在平均水平上有所改善,而且在最重要的地方也有所改善。这种方法将评估从静态的防护功能转变为直接塑造系统开发轨迹的动态、模型驱动的反馈循环。
对于新兴的领域,团队应投资创建自定义基准,通常由工程师与主题专家配对,以定义任务、基本事实(ground truth)和成功标准。这包括用于下游分析的元数据,例如故障类型标记或覆盖率跟踪。
定期针对这个不断演变的评估语料库进行评估,提供了一种可扩展的方式来检测回退、暴露系统性弱点,并以统计严谨性量化改进。这种方法将评估从静态的问答关卡转变为动态的、模型驱动的反馈循环。
组件评估 (Component Evaluation)
单元测试是软件开发中的基本实践,对于验证基于智能体的系统的各个组件至关重要。有效的单元测试确保系统的每个部分都能按预期运行,从而有助于智能体的整体可靠性和性能。
评估工具 (Evaluating Tools)
工具是赋予智能体对其环境采取行动、检索或转换数据以及与外部系统交互的核心功能。工具的高质量单元测试始于用例的详尽枚举,不仅包括典型的“快乐路径(happy path)”,还包括可能揭示脆弱边缘或隐藏假设的罕见、对抗性或格式错误的场景。
在成熟的智能体开发流程中会为每个工具定义一套自动化测试。例如,数据检索工具应在不同的数据格式、变化的网络条件以及有效和故意损坏的数据源下进行测试。测试不仅要明确验证输出的正确性,还要验证延迟、资源消耗和错误处理——确保工具在负载或故障下优雅地降级。
工具测试应断言相同的输入有确定性的输出,除非随机性是工具设计的一部分(在这种情况下,必须检查统计属性)。对于具有外部依赖项(如 API 或数据库)的工具,开发人员应使用模拟(mocks)或仿真器来重现生产中可能罕见但如果处理不当将是灾难性的边缘情况。回归测试至关重要;每次修改工具时,都必须重新运行全套测试,以验证过去的能力没有被破坏。
评估规划 (Evaluating Planning)
规划模块将高级目标转换为可操作的步骤序列——通常涉及动态决策、分支逻辑和环境适应反馈。与传统脚本不同,智能体规划通常是概率性或自适应的,需要仔细测试以避免脆弱或不一致的行为。规划器可能需要根据执行过程中学到的内容对工具调用进行排序、协调条件句或提前停止。这使得验证既更加微妙又更加重要。
为了评估规划质量,我们从规范的工作流开始:常见、易于理解的用户意图与已知的良好智能体响应配对。对于每个场景,我们编码起始环境、对话历史以及在工具使用和用户沟通方面的预期结果。例如,在我们的客户支持智能体案例中,当客户要求为损坏的杯子退款时,规划器应确定发放退款是正确的行动,而不是取消订单或修改地址。它还应包括一条自然语言的确认消息,让客户放心问题已得到解决。
为了系统地评估这些计划,我们端到端地运行智能体并提取其选择的行动。具体来说,我们从智能体生成的输出中捕获工具调用列表及其参数。这些将与场景的基本事实预期进行比较。通过这种比较,我们计算几个自动化指标:
-
工具召回率 (Tool recall): 规划器是否包含了所有预期的工具调用?
-
工具精确率 (Tool precision): 是否避免了调用不必要的工具?
-
参数准确性 (Parameter accuracy): 对于每个工具,它是否提供了正确的参数——例如特定的订单 ID 或退款金额?
这些指标提供了对规划器行为的细粒度洞察。低召回率分数可能表明规划器未能采取必要行动,而低精确率则表明它误解了目标或误读了用户的意图。参数不匹配可以突出上下文依据(contextual grounding)的失败——例如退款了错误的商品或为已成功交付的订单发放退款:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
def tool_metrics(pred_tools: List[str], expected_calls: List[dict]): expected_names = [c.get("tool") for c in expected_calls] if not expected_names: return {"tool_recall": 1.0, "tool_precision": 1.0} pred_set = set(pred_tools) exp_set = set(expected_names) tp = len(exp_set & pred_set) recall = tp / len(exp_set) precision = tp / len(pred_set) if pred_set else 0.0 return {"tool_recall": recall, "tool_precision": precision} def param_accuracy(pred_calls: List[dict], expected_calls: List[dict]) -> float: if not expected_calls: return 1.0 matched = 0 for exp in expected_calls: for pred in pred_calls: if pred.get("tool") == exp.get("tool") \ and pred.get("params") == exp.get("params"): matched += 1 break return matched / len(expected_calls) |
由于规划通常依赖于上下文,因此测试边缘情况尤为重要。如果订单包含多个商品,且只有一个有缺陷怎么办?如果用户提供模棱两可的输入或在消息之间自相矛盾怎么办?测试应覆盖这些情况,以确保规划器能够驾驭歧义并从中间故障中恢复。
规划模块还应评估一致性。在确定性场景中,相同的输入应产生相同的输出;在概率性情况下,计划的范围仍应落在可接受的界限内。测试可以检查可复现性、对微小输入变化的敏感性以及对意外情况(如订单对象中缺少字段或工具执行失败)的优雅处理。
随着时间的推移,我们维护着一个不断增长的规划场景语料库,反映了智能体必须支持的全部范围——从简单的单步流程到涉及多个相互依赖行动的复杂多轮对话。这个语料库成为规划集成测试的骨干。通过在系统演变时持续评估规划行为,我们可以尽早检测回退,并确保新能力不会引入不稳定性或漂移。
最终,规划评估告诉我们智能体是否知道该做什么。它确认智能体不仅理解用户意图,而且可以将该意图转换为精确、连贯且基于上下文的行动。作为感知与执行之间的桥梁,必须仔细审查规划——因为下游的一切都依赖于它。
评估记忆 (Evaluating Memory)
记忆对于需要连续性和上下文感知的智能体至关重要,无论是用于多轮对话、长时间运行的工作流还是持久的用户档案。测试记忆模块并非易事,因为它不仅涉及验证原始存储和检索,还要确保随着记忆存储的增长,数据的完整性、相关性和效率。
记忆的单元测试应首先验证写入记忆的数据是否被准确存储并能被精确检索,无论是立即检索还是在经过相当长时间或其他操作介入之后。这包括边界情况,如最大记忆容量、不寻常的数据类型或快速的读/写循环。测试应故意用格式错误、重复或模棱两可的条目对系统施压,以确保鲁棒性:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
def evaluate_memory_retrieval( retrieve_fn: Any, queries: List[str], expected_results: List[List[Any]], top_k: int = 1) -> Dict[str, float]: """ 给定一个检索函数 `retrieve_fn(query, k)` 返回 k 个记忆项列表, 对多个查询进行评估。 返回: - `retrieval_accuracy@k`:至少有一个预期项出现在前 k 个结果中的查询比例。 """ hits = 0 for query, expect in zip(queries, expected_results): results = retrieve_fn(query, top_k) # 我们是否检索到了任何预期的项目? if set(results) & set(expect): hits += 1 accuracy = hits / len(queries) if queries else 1.0 return {f"retrieval_accuracy@{top_k}": accuracy} |
除了正确性之外,必须测试记忆模块的相关性——确保检索逻辑不会浮现陈旧或无关的信息。例如,如果智能体被要求提供用户最近的偏好,测试必须确认不会由于数据泄漏或索引错误而返回过时或错误的偏好。测试还应检查无关但相似的数据不会仅仅因为措辞或语义上的表面相似性而被检索出来。
效率是一个关键维度,特别是随着记忆体量的增长。开发人员应对不断增加的记忆负载下的检索时间和资源使用情况进行基准测试,识别所有性能断崖或瓶颈。如果使用向量搜索或语义记忆,测试应包括“简单”和“困难”两种检索场景,以捕捉嵌入或索引逻辑中的微妙错误。
最后,记忆系统必须对部分故障具有弹性。测试应模拟数据库不可用、数据损坏或版本迁移,以确保智能体要么优雅地恢复,要么以受控方式失败,并将对用户的影响降至最低。
评估学习 (Evaluating Learning)
学习组件可能是最难进行单元测试的,因为它们具有随机性并依赖于数据。然而,严格的测试对于确保智能体随着时间的推移真正改进,而不是简单地过拟合、退化或“遗忘”之前掌握的行为至关重要。
测试学习始于验证基本的学习循环:智能体是否针对标记数据、反馈或奖励信号正确更新其参数、缓存或规则?对于采用监督学习的智能体,单元测试应确认,当在规范数据集上训练时,智能体达到了预期的准确性并能正确泛化到验证数据。对于强化学习智能体,测试应检查奖励最大化是否导致行为随时间改善,并且能够检测和处理学习停滞(例如,通过早停或动态探索)。
泛化至关重要。测试应评估智能体将学到的行为应用于新的、分布外场景的能力。这包括“保留”(holdout)集、合成示例或专门构建的对抗性测试用例,以挑战脆弱的启发式方法或死记硬背的反应。
适应性也至关重要。测试应模拟分布偏移——例如新类型的用户输入、以前未见过的工具故障或不断变化的奖励环境——并确认智能体可以适应而不发生灾难性遗忘或性能崩溃。在适当的情况下,应跨多个范式(监督、无监督、强化)测试学习模块,确保跨范式交互不会引入微妙的错误。
通过严格测试这些组件——工具、规划、记忆和学习——开发人员可以确保基于智能体系统的基础元素可靠有效地运行。这种全面的单元测试方法为构建用于实际应用的稳健且可扩展的智能体提供了所需的信心。
整体评估 (Holistic Evaluation)
虽然单元测试在隔离状态下验证单个组件的正确性,但集成测试旨在评估整个智能体系统,确保所有子系统——工具、规划、记忆和学习——在现实设置中无缝协作。集成测试暴露了复杂的交互、涌现行为和仅靠单元测试无法预测的端到端问题。在基于智能体的系统中,一个模块的输出通常成为另一个模块的输入,集成测试对于发现在实际使用过程中才会出现的问题至关重要。
端到端场景中的性能
集成测试的主要目标是在类似于实际使用的条件下验证系统从开始到结束执行完整任务的能力。这涉及构建代表性的工作流或用户旅程,以行使智能体系统的全栈功能——感知、规划、工具调用和通信。例如,客户支持智能体可能会在多步对话上进行测试,涉及解释用户请求、根据订单数据做出决策、调用业务工具(如 issue_refund),并向客户提供适当的后续消息。这些评估必须确保智能体不仅选择正确的行动,而且沟通清晰并与用户意图保持一致。
在我们的框架中,这种评估通过 evaluate_single_instance 函数进行操作,该函数执行一个完整的测试用例并计算一组指标。智能体被赋予结构化输入——包括订单数据和对话历史——其输出将与预期的最终状态进行比较。包括检查调用了哪些工具、使用了什么参数,以及最终消息是否包含所需的短语。结果总结在工具召回率、工具精确率、参数准确性、短语召回率和总体任务成功分数等指标中。这使得评估智能体的完整行为成为可能——它是否理解了情况,采取了正确的行动,并很好地解释了它们?以下是一个辅助函数,用于执行单个场景的端到端集成测试——在结构化输入上调用智能体并计算工具使用、参数准确性、短语召回率和总体任务成功的指标:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
def evaluate_single_instance(raw: str, graph) -> Optional[Dict[str, float]]: if not raw.strip(): return None try: ex = json.loads(raw) order = ex["order"] messages = [to_lc_message(t) for t in ex["conversation"]] expected = ex["expected"]["final_state"] result = graph.invoke({"order": order, "messages": messages}) # 提取助手的最终消息 final_reply = "" for msg in reversed(result["messages"]): if isinstance(msg, AIMessage) \ and not msg.additional_kwargs.get("tool_calls"): final_reply = msg.content or "" break # 收集预测的工具名称和参数 pred_tools, pred_calls = [], [] for m in result["messages"]: if isinstance(m, AIMessage): for tc in m.additional_kwargs.get("tool_calls", []): name = tc.get("function", {}).get("name") or tc.get("name") args = json.loads(tc["function"]["arguments"]) \ if "function" in tc else tc.get("args", {}) pred_tools.append(name) pred_calls.append({"tool": name, "params": args}) # 计算并返回指标 tm = tool_metrics(pred_tools, expected.get("tool_calls", [])) return { "phrase_recall": phrase_recall(final_reply, expected.get("customer_msg_contains", [])), "tool_recall": tm["tool_recall"], "tool_precision": tm["tool_precision"], "param_accuracy": param_accuracy(pred_calls, expected.get("tool_calls", [])), "task_success": task_success(final_reply, pred_tools, expected), } except Exception as e: print(f"[SKIPPED] example failed with error: {e!r}") return None |
这种方法使得能够跨越数十或数百个不同场景对端到端智能体行为进行可扩展、可重复的度量。一个关键的局限性是,自动化测试的好坏取决于它们所采用的评估集和指标。如果测试用例太狭窄或不具代表性,智能体可能在离线测试中表现良好,但在生产中却失败。同样,过度依赖一小组指标可能导致“指标过拟合”,即系统被调整为在基准测试中表现出色,但牺牲了更广泛的效用。这在基于文本的智能体中尤为常见,优化单一分数(如 BLEU 或精确匹配)可能会激励公式化或不自然的输出,从而错失用户请求背后的真实意图。
最佳实践是将评估视为一个持续的过程,而不是静态的检查清单。团队应定期扩展和完善测试集,以反映新功能、真实用户行为和新出现的故障模式。结合反馈——来自内部审阅者或试点用户——有助于揭示自动化管道遗漏的盲点。对评估方法和指标的迭代改进确保智能体是根据在目标环境中真正重要的成功标准来衡量的。
通过将每个评估构建为一个完整的交互——从输入状态到智能体输出——我们可以跟踪系统在现实任务中的表现,检测随时间推移的回退,并发现规划、基座(grounding)或沟通中的弱点。这些测试还可以扩展用以捕获延迟、吞吐量和负载下的行为——确保系统在现实操作条件下保持稳健和响应迅速。在故障情况下,我们可以验证智能体是否优雅地降级:它是否尝试回退策略或适当地升级问题?通过这种方式,集成测试成为自信地部署智能体系统的严格且必要的保障。
一致性 (Consistency)
智能体系统的一致性测试尤其具有挑战性,因为这些系统通常依赖于本质上具有概率性和非确定性的基础模型。与对相同输入确保相同输出的传统系统不同,由 LLM 驱动的智能体可能会因其概率性质而产生不同的响应。因此,一致性测试侧重于确保智能体的输出与其输入保持一致,在延长的交流中保持连贯,并可靠地解决用户的预期问题或任务。
在我们要一直使用的客服智能体示例中,一致性测试确保对破损咖啡杯退款请求(例如,order_id A89268)的响应在概率变化中保持一致,例如在调用 issue_refund 工具之前始终要求提供损坏照片,即使用户的措辞略有不同。对于延长的交互,如从退款演变为取消订单(如在 cancel_1_refund 中,当订单已交付时),智能体必须在不与先前关于订单状态的陈述相矛盾的情况下继续进行。
一致性测试的一个关键目标是验证智能体的响应在不同场景下是否与给定输入保持一致。这涉及评估智能体是否提供直接解决用户查询的相关且准确的答案。自动化工具可以帮助检测响应偏离预期一致性的情况。自动化验证系统可以将输出与输入上下文进行交叉检查,以标记不一致之处供进一步审查。
更长的交互引入了额外的复杂性,因为性能可能会随着时间的推移而下降。智能体必须在多轮对话中保持逻辑递进,避免出现响应与早期陈述相矛盾或偏离手头主题的情况。例如,客服机器人必须在整个交互过程中保留上下文,确保其响应与用户早期的输入和交流的总体目标一致。这一领域的测试通常需要延长的模拟对话,以评估系统随时间维持一致性能的能力。
一个微妙的风险是,自动化评估可能会遗漏罕见但关键的边缘情况,特别是那些由新型输入或系统交互引起的情况。智能体可能“通过”所有标准测试,但在遇到测试集分布之外的情况时仍表现的不可预测。因此,持续的人工检查和定期更新评估数据至关重要。
自动化和人工审查在应对这些挑战中都发挥着重要作用。人工审查者可以评估细微的不一致性,并就智能体是否遵守其响应的预期目的提供反馈。这一过程对于评估边缘情况或模糊输入尤为重要,因为在这些情况下自动化系统可能力不从心。同时,可以通过基于 LLM 的评估技术实现可扩展的验证。通过使用相同或相关的模型进行一致性检查,智能体可以针对预期评估自己的输出。为这些评估模型提供构成一致和相关响应的少样本(few-shot)示例,可以提高它们的可靠性。
Actor-Critic(行动者-评论家)方法为一致性测试提供了另一个有价值的工具。在这个框架中,“Actor”生成响应,而“Critic”根据预定义的标准评估它们的一致性和相关性。虽然有效,但仅靠这些方法可能不足以应对复杂或高度动态的场景。将 Actor-Critic 评估与基于 LLM 的评估和人类反馈相结合,创建了一个更全面的框架来识别和解决不一致问题。
一致性测试最终确保智能体系统提供的输出是一致的、合乎逻辑的和有目的的,即使面对非确定性行为也是如此。通过利用自动化验证、人工监督和先进的评估技术(如 Actor-Critic 框架和 LLM 驱动的评估)的组合,开发人员可以构建在短期和长期交互中都能激发信任并可靠运行的系统。这种方法解决了基于 LLM 的智能体所面临的独特挑战,确保其输出符合实际应用所需的高标准。
连贯性 (Coherence)
连贯性测试确保智能体的输出在交互过程中保持逻辑性、上下文相关性以及一致性。对于管理多步工作流或维持长时间对话的智能体来说,连贯性是实现无缝、直观交流的关键。智能体必须保留并适当地使用上下文——例如用户偏好或先前的行动——以便其响应自然地建立在之前的内容之上。这在多轮对话中尤为关键,智能体应在不提示用户重复自己的情况下引用先前的信息。
例如,在我们的客服智能体运行示例中的破损杯子场景中,连贯性要求智能体在确认退款时引用初始损坏报告和照片上传,避免诸如忽略多商品订单细节(例如,仅退款 order_id A89268 中的杯子而忽略其他商品)之类的疏忽。在更复杂的情况下,如退款后的修改请求(如在 modify_2 中),智能体必须通过确认地址更改来保持逻辑流,而不在对话历史中引入矛盾。
测试连贯性涉及模拟延长的交互,验证智能体保持对状态的一致理解,并且其行动遵循逻辑的、目标导向的序列。矛盾或失误——如相互冲突的建议或被忽视的依赖关系——被标记为连贯性失败。例如,在客户服务中,连贯性测试确保智能体的响应逻辑地解决用户问题并保持专业、明确的沟通。
最终,连贯性测试对于保持信任、可用性以及智能体系统在现实应用中的实用价值至关重要。通过严格评估逻辑流、上下文保留和避免矛盾,开发人员确保智能体即使在任务变得复杂或会话长度增加时也能可靠运行。
幻觉 (Hallucination)
AI 系统中的幻觉发生在智能体生成不正确、荒谬或捏造的信息时。这一挑战在设计用于知识检索、决策制定或用户交互的系统中尤为显著,因为在这些系统中准确性和可靠性至关重要。解决幻觉问题需要严格的测试和缓解策略,以确保智能体始终产生基于现实的响应。
为了减轻这种情况,开发人员应使用诸如检索增强生成(RAG)等技术将输出建立在可验证数据的基础上,该技术交叉引用可信来源以提高事实准确性,正如法律 AI 工具通过此方法相比通用模型减少了幻觉。
其核心在于,减轻幻觉始于确保内容准确性。这涉及验证智能体的输出是基于事实数据而非捏造。系统必须经过严格测试,以便将其响应与可信的信息来源进行交叉检查。例如,医疗诊断智能体应将其建议建立在经过验证的临床指南之上,而提供历史事实的对话智能体必须依赖经过验证的数据库。定期审核系统的知识库和决策过程对于维持这一准确性标准至关重要。
数据依赖性是解决幻觉问题的另一个关键因素。智能体输出的可靠性直接取决于其数据源的质量。依赖过时、不完整或未经审查数据的系统更容易产生错误信息。测试流程必须确保智能体始终从准确、相关且最新的来源获取数据。例如,总结新闻文章的 AI 应依赖可信、备受推崇的出版物,并避免未经验证的来源。
反馈机制对于检测和解决幻觉至关重要。这些系统监控智能体的输出,标记不准确之处以供审查和更正。人在环路(human-in-the-loop)的反馈循环特别有效,使领域专家能够随着时间的推移完善系统的响应。在动态应用中,自动化反馈机制可以识别智能体预测与实际结果之间的差异,触发模型或数据源的更新以提高可靠性。
针对幻觉的缓解措施已经演变为强调混合的人类-AI 反馈循环,其中领域专家在实时监督中与 AI 系统协作——例如在危机自救场景中——以完善输出,减少用户的认知负担,并在捏造信息传播之前予以纠正。这种方法将自动化检测与人类判断相结合,增强了医疗保健或法律咨询等高风险应用的可靠性。此外,成本感知评估正受到关注,重点是在减少幻觉与推理费用之间取得平衡;例如,现在的框架通过权衡准确性改进与计算开销的指标来量化“幻觉成本”,从而在不牺牲性能的情况下实现更高效的部署。
通过优先考虑内容准确性、强制执行数据依赖性、利用反馈机制以及针对各种场景进行严格测试,开发人员可以将幻觉风险降至最低,并构建能够提供可靠、有依据且值得信赖的输出的智能体。这种严格的方法确保系统在其预期领域成为可靠的合作伙伴,满足用户期望并遵守准确性和完整性的高标准。
处理意外输入 (Handling Unexpected Inputs)
现实世界环境是不可预测的,智能体必须在面对意外、格式错误甚至恶意输入时保持鲁棒性。该领域的集成测试故意提供超出训练或设计假设的输入——例如意外的数据格式、用户语言中的俚语或拼写错误,或外部服务的部分故障。目标是确保智能体既不崩溃也不产生有害输出,而是优雅地响应:视情况进行澄清、拒绝或升级。
在我们的电商智能体中,意外输入可能包括格式错误的订单 ID(例如,在破损杯子退款期间“A89268”中的拼写错误)或混合意图的模糊请求(如在 cancel_4_refund 中,对已交付的订单请求取消),这就要求智能体进行澄清或升级,而不是继续进行错误的工具调用(如 issue_refund)。使用来自我们评估集的对抗性变体进行系统测试,例如注入俚语或照片上传中的部分故障,可确保在不泄露敏感订单信息的情况下进行优雅处理。
有效的集成测试不仅涵盖输入的随机“模糊测试(fuzzing)”,还包括基于历史事件或对抗性分析对边缘情况的系统探索。对于重安全型应用,验证即使在压力下智能体也不会泄露敏感信息、违反策略或导致下游故障是很重要的。通过随着智能体的演变不断扩展和完善这些测试,开发人员可以构建稳健、值得信赖且准备好应对现实世界复杂性的系统。
准备部署 (Preparing for Deployment)
随着智能体系统的成熟,从开发过渡到部署需要严格的准备情况检查和质量门控,以确保生产中的可靠性和可信度。生产就绪不仅仅是通过测试——它是对系统能否在现实环境中安全、一致和高效地执行其预期功能的整体评估。
建立明确的部署标准是第一步。这些通常包括在相关评估集上达到量化性能阈值,证明在压力和边缘情况下的稳定性,并验证所有核心工作流按预期运行。在实践中,团队应使用结构化检查清单来确认所有组件——工具、规划、记忆、学习和集成——都已经过严格测试和审查。关键标准可能包括通过端到端集成测试、达到延迟和正常运行时间目标,以及验证不存在严重或高优先级的错误。
对于我们的客服智能体,部署标准可能包括在退款和取消场景(例如,正确调用 issue_refund 处理像 order_id A89268 中破损杯子这样的损坏商品)上达到至少 95% 的工具召回率,并且如果在多轮测试(如地址修改 modify_5)中出现回退,自动化门控将阻止升级。这一过程结合针对现实世界变体的试点监控,使得能够在自信地推出的同时,一旦生产中出现问题能够快速回滚。
执行这些标准的一个关键机制是使用门控机制(gating mechanisms)。门控是阻止升级到生产环境的自动化或手动检查,除非满足所有要求。这可能涉及如果在最新的评估套件上检测到任何回退就阻止部署,或者在成功的试点或测试阶段后需要技术和产品负责人的明确批准。当自动化结果模棱两可时,门控可以配置为将问题升级以供人工审查。
同样重要的是建立一个可靠的流程来推出新版本,在发布后监控回退,并在出现意外问题时实现快速回滚。这就是稳健的离线评估基础带来回报的地方,它提供了部署系统将按预期运行的信心,同时将对用户和业务的风险降至最低。
通过严格准备部署并建立明确的质量门控,团队创造了一种负责任和卓越的文化,确保只有符合最高标准的智能体系统才能触达用户。
结论
度量和验证构成了开发稳健可靠的智能体系统的支柱,确保它们准备好在现实场景中有效运行。通过定义明确的目标和选择相关的指标,开发人员为评估智能体的性能创建了一个结构化基础。彻底的错误分析揭示了弱点并为有针对性的改进提供信息,而多层次评估提供了系统能力的整体视图,从单个组件到全面的用户交互。
正如我们的电商客服智能体运行示例所示——处理从简单的破损杯子退款(order_id A89268)到复杂的取消和修改等所有事务——这些度量和验证实践确保了跨各种场景的稳健性能。通过基于此类线索案例迭代完善指标和评估集,团队可以部署不仅满足目标而且适应不断变化的用户需求的智能体,最终在实际应用中促进信任和效率。
这种分层和有条理的方法确保基于智能体的系统实现其性能目标,提供无缝且令人满意的用户体验,并在动态和复杂的环境中保持可靠性。全面的单元和集成测试保障了核心功能和全系统行为的完整性,使开发人员能够在部署前解决潜在问题。
最终,勤勉的度量和验证赋予团队自信地部署智能体系统的能力,深知它们能够经受住现实世界操作的挑战,同时满足用户需求。通过优先考虑这些实践,开发人员不仅提高了系统的质量和可靠性,也为各行各业和用例中的预期应用做出了有意义的贡献铺平了道路。
翻译整理自Building Applications with AI Agents一书,仅供学习交流使用