智能体测试策略:单元测试、集成测试与模拟LLM
从“修了三个月bug改一个坏三个”到“改完Prompt敢直接上线”我踩过的坑和总结出来的路先讲个让我至今后背发凉的事。去年做了一个自动审批报销单的Agent逻辑不复杂读邮件里的发票图片OCR提取金额跟公司预算系统比对低于500块自动批超过的转人工。测试阶段跑了五十多个case全过。信心满满上线。第二周财务总监在群里发了一张截图问“这个报销是怎么回事”。我点开一看Agent把一个3520元的差旅住宿费判断成了520元自动批准了。原因是一个实习生写Prompt的时候在金额提取的描述里写了一句“如果有小数点只取整数部分”。结果35.20变成了35再乘以100变成了3520不它把小数点后面的“20”识别成了20元然后做了一个迷之运算输出了520。更让我崩溃的是我花了三天时间修好了这个问题然后跑回归测试发现另一个case又开始报错了——Agent开始把“500.01”识别成“500”导致一个刚超过自动审批阈值的报销单被错误地自动批了。这就是智能体测试和传统软件测试最大的区别。在传统代码里你修好一个if语句所有依赖这个if的路径都会一起被修好。但Agent的“代码”是Prompt是LLM的推理路径。你修好了A场景B场景可能因为Prompt的变化而变差。你永远无法像断言函数返回值那样断言一个LLM的“思考过程”。那之后我花了半年时间系统性地研究了智能体的测试策略。这篇文章我就把这段经历浓缩成一套可落地的测试框架从单元测试怎么Mock LLM到集成测试怎么验证工具调用链再到端到端测试怎么模拟真实用户以及2026年有哪些工具能让这事儿不那么痛苦。一、为什么智能体测试比传统软件测试难十倍在深入具体策略之前先搞明白为什么这事儿这么难。我把它总结为四个根本原因。1. 非确定性输出同样的输入不同的输出传统程序是确定性的。你给add(2, 3)它永远返回5。Agent呢你问“今天天气怎么样”模型可能回答“今天晴天22度”也可能回答“天气晴朗体感舒适大约22度”。两个答案都对但你没法写一个断言说“必须包含‘晴天’”或者“必须包含‘22度’”。更麻烦的是遇到模糊需求模型的输出可能天差地别。你没法用简单的等值断言来验证。2. 多步骤依赖第一步错后面步步错ReAct模式下Agent的每一步决策都依赖前一步。Monday Service团队在技术复盘里提到一个小错误在早期被传播开来可能会导致后面完全不同且错误的输出——一个Prompt或工具调用结果的轻微偏差可能在整个任务链中被显著放大。你修复了第三步的bug但第一步的Prompt改动可能导致第二步走了一条完全不同的分支第三步根本没走到你修复的那条路。3. 状态爆炸执行路径的组合太多了一个20步的任务每一步可能有3-5种不同的分支取决于工具返回结果、用户反馈、模型自己的“思考”。组合起来可能的执行路径数量是天文数字。你不可能穷举所有路径来测试。更别提Agent还有记忆——上次对话中用户说过的话会影响这次的决策。传统测试里没有这种“跨会话污染”的问题。4. 环境依赖Agent活在真实世界里Agent要调用真实API真实API会超时、会改版、会限流。你本地跑测试的时候一切正常一上线第三方物流接口改了个字段名Agent开始把“已签收”识别成“运输中”。这不是Agent的问题但它确实导致了错误。这些外部依赖的不确定性让测试变得极其困难。面对这四个挑战很多团队的选择是——不测试了直接上线出了问题再修。结果就是每个周末都在加班修线上bug。我觉得这条路走不通。经过半年的摸索我们总结出了一个三层测试体系让这个问题至少变得可控。二、智能体测试的三层体系传统的软件测试有单元测试、集成测试、端到端测试。智能体测试也借鉴了这个分层思想但每一层的内涵和工具完全不同。单元测试验证Agent的单步决策逻辑比如“给定这个用户输入Agent会不会调用正确的工具、提取正确的参数”。这一层需要用Mock LLM来隔离外部依赖确保测试是确定性的。集成测试验证Agent的工具链集成和状态管理比如“调用订单查询工具后状态里有没有正确记录订单号”“多轮对话中记忆有没有正确更新”。这一层需要真实的工具调用或者在可控的沙箱环境中运行。端到端测试模拟真实用户的完整交互流程覆盖正常流程和异常流程比如“用户发起退款→Agent要求提供订单号→用户提供→Agent执行退款→通知用户”。下面我们一层一层来拆。三、单元测试用Mock驯服LLM的“任性”单元测试的目标是验证Agent的决策逻辑——给定一个输入Agent会不会做出正确的决策、调用正确的工具、提取正确的参数。在传统软件里单元测试很简单你mock掉外部依赖比如数据库、API只测试函数本身的逻辑。在Agent的世界里最大的外部依赖就是LLM本身。如果我们不Mock LLM每次跑单元测试都要等几秒钟LLM推理时间、花几分钱token费用而且结果还不稳定——今天跑过了明天模型升级了可能就挂了。那怎么Mock LLM2026年的工具生态给出了不错的答案。MockLLM是一个可扩展的Mock服务器用于模拟大语言模型API支持插件式架构可以轻松添加新的提供商模拟器而不修改核心代码。它能够为你提供确定性、可配置的响应非常适合测试和评估场景。pytest-mockllm是一个零配置的pytest插件可以mock OpenAI、Anthropic、Gemini、LangChain等多种LLM API让你测试AI应用的时候不用真的调用模型既省token又快。有了这些工具我们可以这样写一个单元测试deftest_weather_agent_calls_correct_tool():# 1. 设置Mock LLM让它“假扮”成真实的模型mock_llmMockLLM()mock_llm.add_response( 思考: 用户想查北京的天气我需要调用get_weather工具。 行动: {tool: get_weather, args: {city: 北京}} )# 2. 用Mock LLM初始化AgentagentWeatherAgent(llmmock_llm)# 3. 执行测试resultagent.process(北京今天天气怎么样)# 4. 验证Agent调用了正确的工具assertagent.last_tool_call.nameget_weatherassertagent.last_tool_call.args[city]北京这个测试可以在几毫秒内跑完不需要真实LLM调用不需要网络不需要花钱。你可以把这个测试放在CI里每次提交代码自动跑。但Mock LLM有一个关键问题你Mock的响应应该是什么你需要在Mock的响应里模拟Agent的“思考-行动”输出。这意味着你必须在写测试的时候就知道“对于这个输入Agent应该输出什么”。这看起来像是“作弊”但实际上是单元测试的本质——你在验证Agent的编排逻辑而不是在测试LLM本身。为了生成高质量的Mock响应我们团队采用了一个策略先用真实模型比如GPT-5跑一遍测试用例把它的思考轨迹记录下来作为后续单元测试的Mock基准。这样你既保证了Mock的真实性又不用每次都调用昂贵的大模型。用deepeval做LLM单元测试除了Mock LLM还有一个思路是用专门的LLM评估框架来做“语义级别的单元测试”。DeepEval是一个开源的LLM评估框架类似于Pytest但专门为LLM应用设计。它支持通过G-Eval、任务完成度、答案相关性、幻觉等多种指标进行评估这些评估基于LLM-as-a-judge和其他在你的机器上本地运行的NLP模型。DeepEval有几个专门针对Agent的评估指标可以直接用来做单元测试Tool Correctness检查是否调用了正确的工具和参数Goal Accuracy衡量Agent达成目标的准确度Step Efficiency评估Agent是否走了不必要的步骤Plan Adherence检查Agent是否遵循了预期的计划。这些指标的价值在于你不需要手动写规则来判定“调用工具是否正确”直接让评估框架来做比自己写正则表达式靠谱得多。四、集成测试验证Agent与世界的“握手”单元测试保证了Agent的“大脑”在Mock环境下的正确性。但Agent能干活是因为它能和外部世界互动——调用工具、读写数据库、发送邮件。集成测试的任务就是验证这些“握手”是否正常。1. 工具调用链验证假设你的Agent在执行“查订单”任务时需要依次调用get_order_info获取订单详情和get_logistics_info获取物流信息。集成测试需要验证工具是否按正确的顺序被调用参数传递是否正确中间状态是否有正确记录。百度开发者中心的一篇文章给出了一个很好的示例结构针对日历调度智能体验证工具调用正确性classCalendarAgentTest(TestCase):deftest_memory_update(self):# 初始化测试环境envTestEnvironment(mock_fsTrue)agentCalendarAgent(env)# 执行测试指令responseagent.process(永远不要在9点前安排会议)# 验证执行轨迹self.assertEqual(env.mock_fs.last_path,/memories/preferences.json)self.assertIn(no_morning_meetings,env.mock_fs.last_content)# 验证最终状态self.assertTrue(response.contains(记忆已更新))这个示例里TestEnvironment提供了一个可控的测试环境包括Mock的文件系统。测试可以断言Agent是否在正确的路径写入了正确的配置而不仅仅是检查最终的回答。2. 多轮对话状态验证集成测试的另一大重点是验证多轮对话中的状态管理。一个日历调度Agent的核心需求可能包括记忆用户设定的会议时间偏好比如“禁止早9点前会议”、动态协调参会人时区冲突、自动生成会议纪要并归档。传统测试只能验证最终会议时间是否符合约束但集成测试需要确认用户偏好是否持久化存储到指定文件路径、时区转换工具是否被正确调用两次发起者参与者、会议纪要是否包含所有决议项。3. LangGraph的检查点机制集成测试的秘密武器LangGraph内置的检查点Checkpoint机制是集成测试的杀手锏。检查点会在图的每个超级步骤自动保存状态快照包括对话历史、工具调用记录、所有中间变量。在集成测试中你可以在Agent执行完成后通过get_state_history()拉出完整的执行轨迹然后逐段验证——比如第3步用户说了什么、第5步Agent调用了什么工具、第8步状态里记录了什么偏好。LangGraph的时间旅行能力允许你在任意检查点位置注入新状态后继续执行或者在某个历史检查点分叉出一条新的时间线并行验证。这对于集成测试来说价值巨大——你可以让两个Agent从同一个检查点出发一个走A路径一个走B路径对比结果。4. CrewAI的AgentEvaluator框架如果你用的是CrewAI框架它的AgentEvaluator框架专门为多智能体集成测试设计。它通过监听crewai_event_bus上的Agent事件来运作当Agent完成任务时触发配置的评估指标。内置的评估指标包括GoalAlignmentEvaluator目标对齐、SemanticQualityEvaluator语义质量等。在集成测试中你可以用AgentEvaluator框架来验证整个Crew的任务执行结果是否符合预期。五、端到端测试让Agent在“真实世界”里跑一遍单元测试验证了决策逻辑集成测试验证了工具交互但这两层都是在受控环境下跑的。Agent最终要在真实世界里面对真实用户——模糊的需求、意外的输入、情绪化的表达、外部服务的不稳定。端到端测试就是模拟这些真实场景验证Agent在混沌环境中的表现。1. 真实用户场景模拟端到端测试最核心的内容是模拟真实用户的多轮交互。三层测试框架建议构建包含以下要素的测试框架对话状态管理器维护跨轮次上下文用户模拟器生成符合行为模式的输入序列响应验证器检查输出连贯性和正确性。一个典型的多轮测试场景包括用户设置偏好→智能体记录状态用户发起请求→智能体结合历史状态响应用户修改偏好→智能体更新状态并反馈。Zendesk在2025年底分享了一个非常实用的方法从真实生产对话中提取测试用例。他们从真实客服对话中提取数据将对话拆分为带有预期API结果的独立测试用例。这种方法的好处是测试数据来自真实世界不是人工臆造的覆盖了真实用户可能提出的各种边缘问题。2. 异常流程验证除了“用户正常使用”的场景端到端测试还必须覆盖各种异常。工具调用失败怎么办、网络超时怎么办、用户输入恶意指令怎么办、LLM产生幻觉怎么办等等。异常场景需要在测试中有意识地注入。你可以通过Mock外部服务返回错误码来模拟工具失败或者通过在沙箱中设置延迟来模拟网络波动。百度开发者中心的文章提到测试环境应该实现三级管理——基础环境标准化操作系统和依赖库服务镜像容器化部署测试依赖服务数据隔离确保每个测试用例使用独立数据空间。通过环境标准化某实践案例将测试结果波动率从28%降至3%以内。3. 混沌测试与对抗性测试2026年还有一个值得关注的测试方向是“混沌测试”。LangSmith平台提供了三层次测试方案其中第三层就是混沌测试——模拟异常输入、网络延迟等边界条件。更前沿的方向是用AI来测试AI。例如TAI3框架能够系统性地发现LLM Agent中的意图完整性违规生成基于工具包文档的真实测试任务并应用定向变异来暴露Agent中的错误同时保持用户意图不变。另一篇论文介绍了Neo框架它耦合了问题生成Agent和评估Agent通过共享上下文中心来模块化地组合领域提示、场景控制和动态反馈实现可配置的多轮自动化评估。六、2026年的智能体测试工具链理论讲完了下面推荐几个我们团队在用、也觉得确实好用的工具。LangSmith——大语言模型应用的全生命周期管理平台提供开发工作台、测试验证中心、部署编排系统、监控告警体系四大模块通过统一数据总线实现各模块数据互通形成“开发-测试-部署-监控-优化”的完整闭环。Monday Service团队基于LangSmith构建了一个代码优先的测试框架将AI Agent的评估时间从162秒缩短到了18秒提升了8.7倍。DeepEval是专门为LLM应用设计的单元测试框架支持Agentic Metrics任务完成度、工具正确性、目标准确度等和RAG Metrics答案相关性、忠实度等。它的价值在于用标准化指标替代手工编写验证规则。CrewAI本身也是一套测试框架除了前面提到的AgentEvaluator还可以用promptfoo对CrewAI Agent进行结构化评估定义测试提示、检查输出、运行自动化对比甚至进行红队测试来捕捉意外的失败。CrewAI的AgentEvaluator采用事件驱动架构拦截Agent执行并应用特定评估指标。LangGraph的检查点系统除了用于状态管理和故障恢复本身也是强大的调试和测试工具。时间旅行能力包括get_state_history像Git log一样浏览全部历史检查点、Fork从历史快照分叉出新的执行分支、update_state在任意检查点注入新状态后继续执行。当集成测试失败时你可以直接从生产环境拉出失败的trace转化为单元测试用例完全复现当时的执行环境然后在本地调试修好了再上线。七、CI/CD集成与测试左移说了这么多测试方法如果没有嵌入到开发流程中效果会大打折扣。把Agent测试嵌入CI/CD流水线的实践方案已经非常成熟。离线评估作为“单元测试”在代码合并前运行在线评估监控生产流量。Monday Service的做法是将评估逻辑放在TypeScript文件中走PR评审流程通过CI/CD部署——工程师合并PR时系统自动将Prompt定义推送到LangSmith注册中心同时自行编写测试来验证评估器本身的准确性。“测试左移”——在开发阶段尽早引入测试的理念至关重要。智能体评估体系应引入测试左移策略。当你修改Prompt时立刻跑一遍回归测试确保改动没有破坏已有功能。数据集管理与版本控制是测试左移的基础。LangSmith支持带版本化的示例数据集、自定义评估器确定性的和LLM-as-a-judge、Agent行为的轨迹评估以及跨运行的实验对比。每次Prompt修改都应该对应一个数据集版本你可以在LangSmith里对比v1和v2在不同数据集上的表现数据驱动决策。八、从零搭建一个分阶段的测试路线图最后根据团队的实际经验总结一个从零搭建智能体测试体系的分阶段路线图。第一阶段手动验证 简单断言MVP阶段目标验证核心流程能跑通。做法是用5-10个核心场景手动测试确认Agent能完成最重要的任务。不用写自动化测试但要记日志——把Agent的思考过程、工具调用、最终输出都记下来。这个阶段大概持续1-2周。第二阶段Mock LLM 单元测试稳定期当核心逻辑确定后引入pytest-mockllm或类似工具为核心工具调用决策编写Mock测试。用deepeval补充语义验证确保核心功能不会被后续改动破坏。这个阶段大概需要2-3周。第三阶段集成测试 状态验证成长期Agent开始处理更复杂的多步任务后启用LangGraph检查点编写集成测试验证工具调用链。为多轮对话场景编写状态验证测试确保Agent不会“失忆”状态在不同轮次间正确传递。这个阶段大概需要3-4周。第四阶段端到端测试 CI/CD集成成熟期从真实生产数据构建测试集接入LangSmith做全链路评估。关键场景设置自动化回归测试评估结果与CI/CD流水线集成。这个阶段大概需要4-6周。第五阶段混沌测试 对抗性测试企业级模拟外部服务故障、网络延迟、异常输入等边界条件验证Agent在极端情况下的表现。对高风险Agent引入红队测试定期评估安全性。写在最后回到文章开头的报销Agent。那次事故之后我们彻底重构了测试流程。现在每次修改Prompt都会触发一个包含200单元测试、50集成测试和20端到端测试的流水线。虽然跑一遍要十几分钟但再也没有出现过“改一个坏三个”的情况。智能体测试不是在限制你迭代的速度而是在保护你迭代的方向。没有测试的Agent迭代就像在雷区里跑步你永远不知道下一步会不会踩到雷。建立测试体系确实需要投入——需要时间、需要工具、需要改变开发习惯。但长期来看这是省时间而不是浪费时间。最后送你一句话在AI Agent开发中测试不是在代码写完后再做的事测试和开发是同一件事。