131 个测试 + 4 层架构:我的 Agent 评估框架
完整分享 AI Agent 系统的多层次评估框架设计和成本控制方案,涵盖隐性失败检测和可信度验证。
完整分享 AI Agent 系统的多层次评估框架设计和成本控制方案,涵盖隐性失败检测和可信度验证。
最初发布于 AIdeazz——本文同步发布于此,并设置了 canonical link。
我曾将一次无声的故障发布到了生产环境。它不是崩溃,不是 500 错误,也不是内存泄漏。那是一个执行过程完全正常的 Agent,却自信满满地向客户交付了错误答案。这种错误会让你损失金钱和信任。那件事发生在我构建 AI Agent 评估体系之前。现在,我的评估体系包含四个不同层级、共 131 项测试,完整执行一次只需 0.03 美元,能够在这些故障进入生产环境之前将其拦截下来。
我的多 Agent 系统运行在 Oracle Cloud Infrastructure(OCI)上,并在 Groq 和 Claude 之间进行路由,通过 Telegram 和 WhatsApp 为客户处理关键的生产任务。一个 Agent 可能同时涉及负责规划的 LLM、负责工具调用的 LLM、检索系统以及最终的结果综合步骤。单元测试可以发现代码 Bug,却无法发现 LLM 幻觉出一个根本不存在的产品 ID、工具误解了用户查询中的细微含义,或者检索系统拉取了无关上下文,进而污染最终答案。这些都是 AI Agent 特有的涌现式故障,需要采用不同的测试方法。
我的第一个生产级 Agent 用于为定制生产订单生成报价。它从 PostgreSQL 数据库中提取产品数据,应用定价规则,然后格式化输出结果。我的单元测试覆盖了数据库查询、定价逻辑和输出格式。Agent 通过了所有测试。
一位客户要求为“200 个采用 Titanium 表面处理选项的 Alpha-Pro 部件”报价。Agent 返回的却是“200 个采用 Standard 表面处理的 Alpha-Pro 部件”的报价。两者价格相差 15%。客户看到较低的价格后批准了报价。直到材料已经订购、进入最终生产审核阶段,我们才发现这个问题。仅这一笔订单,返工成本和损失的利润就估计高达 25 万美元。
根本原因在于:负责规划的 LLM(当时使用 GPT-4,现在复杂规划任务使用 Claude 3 Opus)误将“Titanium”理解成了描述性形容词,而不是一个具体的表面处理选项 ID。随后,它将“Standard”传给负责获取表面处理选项的工具,而该工具返回了一个有效 ID。工具执行正确,数据库查询执行正确,定价逻辑执行正确,但 Agent 失败了。评估体系要防止的,正是这种故障。
在 Agent 发生故障之前,首先必须保证它的工具能够正常工作。我的工具是 Python 函数,并通过 Pydantic schema 对输入和输出进行校验。“原子工具测试”用于验证:给工具一个明确且有效的输入时,它是否能够生成预期输出。这与传统单元测试类似,但更关注工具与外部系统交互或执行复杂逻辑时的语义正确性。
示例:get_product_details(product_id: str)。测试用例:get_product_details("PROD-001") 应返回 {"name": "Alpha-Pro", "base_price": 120.00}。另一个测试用例:get_product_details("NON-EXISTENT-ID") 应抛出 ProductNotFoundError。
这些测试在本地运行,必要时会使用 mock 的外部服务,同时也是我标准 CI/CD 流水线的一部分。它们速度快、成本低。这一层的 38 项测试确保所有基础构件都足够可靠。由于不会调用 LLM,其成本几乎可以忽略不计,通常每次运行不到 0.0001 美元。
这一层测试的是 LLM 正确调用工具的能力。给定一条用户查询,LLM 是否会调用正确的工具,并传入正确的参数?对于依赖 function calling 的 Agent,这一点至关重要。
我的测试体系会将用户查询输入 LLM,并捕获其工具调用,包括函数名称和参数,然后断言它是否符合预期的工具调用。
示例:
get_product_details(product_id="PROD-001")这一层可以发现以下问题:
get_customer_info,而不是 get_product_details。get_product_details(product_id="Alpha-Pro component"),而不是 get_product_details(product_id="PROD-001")。这正是前面“Titanium”表面处理选项出现问题时的故障模式。我使用了一套小型专用数据集,其中包含用户查询及其对应的预期工具调用。每项测试只涉及一次 LLM 调用。借助 Groq 的 Llama 3 8B,这些测试速度极快,成本也非常低。完整执行 45 项测试大约需要 0.005 美元。我每天都会运行这些测试。
这一层测试完整的 Agent 调用链,从最初的用户查询一直到最终输出。这些测试会验证工具调用顺序、中间推理步骤(如果可以获取)以及最终响应是否正确、是否遵循指令。
每个测试用例包括:
示例:
这些测试成本更高,因为它们会涉及多次 LLM 调用和工具执行。对于对速度敏感的 Agent,我使用 Groq;对于需要更复杂推理的任务,则使用 Claude 3 Haiku/Sonnet。完整执行 30 项测试的成本约为 0.02 美元。我会在每次重大部署之前运行这些测试,并每周执行一次回归测试。
这一层关注的是系统的健壮性。Agent 如何处理含糊不清的查询、超出范围的请求或恶意输入?
"" 或 "asdfghjkl"(Agent 应妥善处理。)这些测试通常不存在唯一的“正确”答案,而是关注预期行为,例如“不应生成报价”“应要求提供更多信息”或“应拒绝回答”。我结合使用正则表达式匹配和一个小型专用 LLM(Groq 的 Llama 3 8B),评估 Agent 的响应是否遵循安全规范和职责范围要求。
这 18 项测试对于系统达到生产就绪状态至关重要。由于它们通常需要 Agent 执行一次 LLM 调用,再进行一次评估调用,因此每次运行的成本约为 0.005 美元。我每周运行一次。
我的整套评估体系使用 Python 构建,并使用 pytest 编排测试。测试数据存储在 YAML 文件中,方便阅读和版本控制。
完整运行一次的成本(131 项测试):
这 0.03 美元对应的是一套完整的端到端回归测试。与我曾经犯下的那次 25 万美元错误相比,这点开销微不足道。该评估体系已经集成到我的 CI/CD 中,每次向 main 分支 push 代码时以及每天夜间都会自动运行。要交付可靠的 AI Agent,这种主动测试没有商量的余地。
答:对于第 2 层(LLM 与工具交互测试),我断言的是工具调用的结构和语义意图,而不是要求字符串完全匹配。对于第 3 层(端到端测试),我会使用正则表达式模式或语义相似度检查,例如计算 embedding 的余弦相似度,将输出与一系列可接受结果进行比较;通常还会使用一个小型专用 LLM 来评估响应。
答:这是一个始终存在的风险。我的评估体系相当于一张回归测试安全网。模型行为一旦发生显著变化,第 2、3 或 4 层的测试就会失败,并立即向我发出警报。这样,我就可以重新调整 Agent,或者修改预期的测试输出。
答:测试数据与 Agent 代码一起接受版本控制。添加新功能或有意修改 Agent 行为时,我会更新相关测试用例。对于复杂 Agent,我采用“golden dataset”方案:定期将成功的生产环境交互匿名化,然后加入测试套件。
答:许多现有框架要么过于通用,主要关注 LLM benchmark;要么过于固执己见,不适合我这种多 Agent、多 LLM、多工具架构。构建自定义评估体系,使我能够精准针对生产环境 Agent 特有的故障模式,同时与现有 CI/CD 和 Oracle Cloud 基础设施无缝集成。成本控制也是一个重要因素。
答:我会有策略地将测试路由给能够完成相应任务的最低成本 LLM。大多数工具调用和简单推理测试使用 Groq 的 Llama 3 8B。更复杂的规划和结果综合测试可能会使用 Claude 3 Haiku/Sonnet。在本地开发期间,对于相同的 prompt,我还会缓存 LLM 响应,以尽量减少 API 调用。
——Elena Revicheva · AIdeazz · Portfolio
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。