给Agent写测试-工具调用的回归怎么保

发布时间:2026/11/5 2:03:51
给Agent写测试-工具调用的回归怎么保 给 Agent 写测试工具调用的回归怎么保改了两句提示词昨天还好好的 Agent 今天开始乱调工具。想写测试可 Agent 的输出是模型生成的每次都不一样断言写什么这是所有写 Agent 的人迟早撞上的墙。答案是把「测行为」和「测文字」分开行为可以断言文字不必。三层防线把这件事说清楚。三层防线工具单测纯函数老手艺循环集成测mock 模型驱动断言行为评测集固定问答对回归对比提示词改动敢合并第一层工具单测工具是普通的 Java 方法入参出参确定单元测试原样适用这一层没有任何新东西。Tool只是便签测试测的是方法本身。把工具写成纯函数不依赖模型、不依赖上下文这层测试就是免费的。第二层循环集成测这一层是 Agent 测试的核心。思路是把不确定的那头模型换成确定的脚本只测你的循环和工具协作是否正确。Mock 模型返回预设的 tool_use你的循环照常解析、执行、回填然后断言三件事。该调的工具被调了用户问天气就必须调 get_weather不能调 get_user。参数是对的。city 的值是「北京」不是「上海」。回填是对的。tool_result 的配对 ID 与 tool_use 对上格式没散。文字不必断言相等模型的措辞会变行为不该变。这就是「测行为不测文字」的分界记住一句话断言工具的调用不要断言模型的措辞。第三层评测集攒一批固定的问答对问题、期望的行为、期望的工具调用每次改提示词或换模型就全量跑一遍输出行为快照并与上次对比。退没退步有数据说话改动才敢合并。提示词和评测集要一起版本化它们是一对就像代码和测试。评测集的质量比数量重要二十个覆盖典型场景的用例胜过两百个重复的闲聊。亲手跑下面用一段 Java 写一个自带断言的回归演示mock 模型返回预设工单跑完整循环检查工具调用。断言不过直接抛异常这就是一个最简测试运行器。直接运行java AgentRegression.javaJDK 16用了 record 语法。// 直接运行java AgentRegression.java// agent 回归测试mock 模型驱动循环断言工具行为。importjava.util.ArrayList;importjava.util.List;publicclassAgentRegression{recordToolCall(Stringid,Stringname,Stringargs){}staticclassToolTracker{finalListToolCallcallsnewArrayList();Stringexecute(ToolCallcall){calls.add(call);returnswitch(call.name()){caseget_weather-call.args()晴25 度;default-thrownewIllegalStateException(不该被调的工具call.name());};}}// mock 模型按脚本返回工单替掉不确定的那头staticToolCallmockModel(StringuserMessage){if(userMessage.contains(天气)){returnnewToolCall(tu_1,get_weather,北京);}returnnull;}staticvoidrunLoop(StringuserMessage,ToolTrackertracker){ToolCallcallmockModel(userMessage);if(call!null){Stringresulttracker.execute(call);// 工单与回执的配对在真实实现里靠 idSystem.out.println(回填 tool_resultresult);}System.out.println(生成最终回答略。);}staticvoidassertTrue(booleanok,Stringmessage){if(!ok){thrownewAssertionError(回归失败message);}}publicstaticvoidmain(String[]args){ToolTrackertrackernewToolTracker();runLoop(北京今天多少度,tracker);// 断言行为三件事assertTrue(tracker.calls.size()1,应该恰好调用一次工具实际 tracker.calls.size());assertTrue(tracker.calls.get(0).name().equals(get_weather),应该调 get_weather);assertTrue(tracker.calls.get(0).args().contains(北京),参数里应该有北京);System.out.println(回归通过该调的调了参数对了。);// 反例改坏的提示词让模型调错工具断言立刻抓住ToolTrackerbadnewToolTracker();bad.calls.add(newToolCall(tu_2,delete_user,北京));try{assertTrue(bad.calls.get(0).name().equals(get_weather),应该调 get_weather实际 bad.calls.get(0).name());}catch(AssertionErrore){System.out.println(反例被抓住了e.getMessage());}}}适用边界这一篇管回归的骨架。LLM-as-judge用模型给模型打分、线上的行为监控与告警、以及评测集的自动构造是另外的题。Mock 模型的脚本要随真实行为更新它模拟的是「模型会怎么写工单」模型升级时记得同步。跑完把 Demo 的断言抄进你的 CI从今天起改提示词之前先跑回归改完心里有底。

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询