Agent 研发流程怎么改:从 dev/test/prod 到 Trace、评测集和 Replay

0 阅读12分钟

大家好,我是 Naco

做传统软件,我们已经很熟悉这条链路:

代码修改 → dev 验证 → test 回归 → prod 发布 → 线上 Bug → 下一次修复

Agent 上线以后,这条链路仍然需要,但已经不够了。

不少 Agent 问题只会在真实用户、真实表达和真实上下文里出现。它可能给出一句很流畅的回答,却没有调用工具;也可能 Prompt 没问题,真正失败的是知识库、权限、超时或页面链路。

如果团队只保留“用户问题 + 最终答案”,改完 Prompt 或模型以后,就很难回答两个问题:

  • 原来的问题真的解决了吗?
  • 新版本有没有把其他能力改坏?

Agent 没有替换 dev/test/prod,而是在发布主线之外增加了一条 prod → Trace → Evaluation Dataset → Replay → dev/test → prod 的反馈循环。

传统软件发布链路与 Agent 反馈循环对比

△ Agent 研发在传统发布链路之外,增加了由生产数据驱动的评测循环。

这个判断来自我最近看到的 Schneider Electric LLMOps 实践。[1]

他们公开了一组有代表性的规模数据:一个 350 人的内部 AI Hub,60 多个处于开发或生产阶段的 AI 产品,以及覆盖全球员工的内部 AI 助手。[1]

更值得研究的是他们的研发组织方式:按 AI 产品划分 LangSmith workspace,让开发、测试和生产环境共用同一条产品生命周期。生产 Trace 可以被领域专家标注、放进评测集,再拿去回放新版本。[1]

下面是我基于这个公开案例做的工程拆解,不是 Schneider Electric 给出的统一实施标准。

dev/test/prod 没有消失,变化的是数据开始反向流动

传统软件也会处理线上问题。

传统软件从代码修改到 dev、test、prod 及线上 Bug 回修的流程

△ 传统软件以代码和发布包向前流动,线上 Bug 修复后进入下一次发布。

成熟团队会把线上 Bug 补成回归用例。传统功能通常比较容易定义确定的输入、输出和通过条件,修复完成后也能用单元测试、集成测试或端到端测试验证。

Agent 的一次输出却同时受到多种因素影响:

  • Prompt 和模型版本;
  • RAG 召回结果;
  • 工具定义、参数和权限;
  • Agent 的规划和路由过程;
  • 知识库数据;
  • UI、流式输出和运行基础设施。

团队拿到一张“回答错误”的 Bug 单,通常还不够。需要保留完整过程,判断错误发生在哪一步,再决定用什么方式验证修复。

Agent 从生产 Trace 到评测集、开发测试和灰度发布的研发循环

△ Agent 在 dev/test/prod 发布主线之外,增加了由生产 Trace 反向驱动开发测试的评测循环。

环境没有被替换,变化的是环境之间流动的东西。

过去主要是代码和发布包向前流动;现在生产数据、失败案例和专家判断还要反向流回开发测试。

如果 dev、test、prod 分散在彼此隔离的 workspace,生产 Trace、标注结果、评测集和实验记录就容易断开。Schneider Electric 按产品组织 workspace,解决的正是这条反馈路径的连续性问题。[1]

第一步不是调 Prompt,而是先把 Trace 串完整

同一句错误回答,背后可能是完全不同的问题。

比如,一个游戏助手收到:

打开王者荣耀

最后却回复:

王者荣耀是一款热门游戏……

只看输入和答案,我们只能知道“它没有完成任务”。

完整 Trace 可能显示,意图识别已经成功,缺失的是 open_app 工具调用。这个问题就不该继续靠润色 Prompt 解决,而应该标记为 tool_call_missing,回到 Agent 规划或工具策略里处理。

一次 Agent Trace 需要记录的完整调用过程

△ Trace 需要保留模型、规划、召回、工具调用、结果和运行指标。

一条可用于排错和评测的 Trace,至少要能串起:

  • 用户输入和最终输出;
  • Prompt、模型和 Agent 版本;
  • RAG 召回的文档与相关信息;
  • 工具调用名称、参数、结果和异常;
  • 每一步的耗时、Token 和成本;
  • 用户反馈、人工标注和任务是否完成。

采集这些信息不是为了堆日志。判断标准很简单:一次失败发生后,团队能不能沿着 Trace 找到责任环节。

涉及用户隐私、内部知识和工具返回数据时,还要提前定义脱敏规则、留存期限和访问权限。Trace 能帮助排错,不代表所有原始内容都应该无条件保存。

从 Trace 到评测集,中间要经过筛选和标注

有了 Trace,只是看得见问题。想让同一个失败在后续版本里被重复验证,还要把它整理成 Evaluation Dataset,也就是评测集。

可以先用一份最小模板保存案例:

id: eval-tool-call-001
source_trace_id: trace-prod-xxxx
input: 打开王者荣耀
expected_behavior:
  - 调用 open_app
  - 参数中的应用名为 王者荣耀
actual_behavior: 介绍了游戏,没有执行工具
error_type: tool_call_missing
context:
  agent_version: v1
  model_version: model-a
review_status: approved
privacy: desensitized

这份模板不必一次设计到位,关键是先把四件事写清楚:

  1. 输入是什么;
  2. 期望行为是什么;
  3. 实际行为错在哪里;
  4. 以后用什么条件判断它是否修复。

工具异常、超时、用户点踩和重复提问可以帮助自动发现候选案例,但“什么才算正确”经常需要业务专家参与。Schneider Electric 的做法也是让领域专家进入标注队列,审核真实输出并参与构建评测集。[1]

生产 Trace 经过候选筛选和专家标注进入评测集

△ 评测集不是 Trace 仓库,候选案例还要经过筛选和专家判断。

模型、Prompt 和框架可以快速替换,企业积累的真实任务、历史失败和专家判断却很难从外部购买。时间越长,这套评测集越能反映产品真正面对的问题。

但也没必要把每条 Trace 都收进去。

重复问题、缺少上下文的反馈、无法确认期望行为的样本,直接进入评测集反而会制造噪声。

回答得不好需要修,不代表一定要新增评测案例

这是反馈系统里很容易混淆的一点。

判断标准不应该只是“回答好不好”,而应该看:这次修复是否需要通过重复评测 Agent 的输出行为来验证。

可以用下面这张表做问题路由:

问题类型是否进入评测集修复目标主要验证方式
Prompt、模型行为、RAG 选择或 Agent 决策错误通常需要修正 Agent 的输出或决策行为Evaluation + Replay
知识库或数据源过期不一定修数据更新和新鲜度机制数据质量检查
外部 API、工具超时、权限或配置错误通常不需要修重试、降级、权限和配置集成测试
流式输出中断、页面截断、引用未展示通常不需要修 UI 或调用链路端到端测试
基础设施临时故障通常不需要修容错、监控和告警故障演练与监控
原始 Trace 含敏感信息不能直接进入先脱敏或构造等价案例安全检查 + 对等评测
已有等价评测案例不重复新增提高优先级或补充上下文复用现有 Replay

还有两类情况也要谨慎:

  • 期望行为还没有业务共识,先交给产品或领域专家判断;
  • 只是个体偏好、尚未形成产品标准,不宜直接变成通用评测规则。

修复完成后,可以再问一次:

这个问题能不能被抽象成稳定、脱敏、可重复验证的案例?

能,就补进评测集;不能,就用工程测试、监控或发布检查证明修复有效。

回答不好之后,根据修复目标进入不同的问题队列

△ 回答不好只是起点,修复目标决定问题去向和验证方式。

每次改 Prompt、模型或 RAG,都先回放真实问题

评测集准备好以后,团队不必再凭感觉判断新版本。

修改 Prompt、模型、RAG 或 Agent 流程后,让候选版本回放同一批真实问题,再比较:

  • 任务成功率有没有提高;
  • 原有能力是否出现回归;
  • 严重错误是否仍然存在;
  • 延迟和成本发生了什么变化;
  • 高风险场景是否仍然满足规则。

评测也不能只看“回答像不像人”。

不同 Agent 的首要成功条件不同:

问答类 Agent:事实是否正确、引用是否可靠、表达是否清楚

执行类 Agent:工具是否正确调用、参数是否正确、任务是否完成

流程类 Agent:关键步骤是否执行、状态是否正确流转、异常是否被处理

用户说“打开微信”,Agent 正确调用工具并确认启动,才算成功。它如果写了一段很流畅的微信产品介绍,语言得分再高,也没有完成任务。

我会把发布门槛拆成三层:

  1. 失败案例回放:历史高价值问题必须通过;
  2. 核心能力回归:不能修好一个场景,却破坏原有能力;
  3. 非功能指标检查:延迟、成本和高风险错误不能超过团队设定的边界。

离线 Replay 用来判断候选版本能不能进入灰度,线上评测用来观察真实流量中的漂移和新问题。两者接上以后,Agent 的迭代才不再是一次次孤立调参。

反馈数据可以共享,Runtime 风险仍要隔离

Schneider Electric 在研发反馈层和运行层做了不同选择。

在研发反馈层,一个 AI 产品对应一个 workspace,覆盖开发、QA、预发布和生产环境。Trace、标注、评测集和实验结果跟着产品走,生产问题才能顺畅回到开发评测。[1]

到了运行层,每个 AI 产品保留独立 Runtime。

各产品团队自己负责延迟、成本和故障响应,同时隔离单个产品的运行故障。这会增加基础设施和升级成本,但可以避免一个运行时问题影响全部 Agent。[1]

这两个选择并不冲突:

共享的是标准、数据和控制能力

隔离的是运行风险和产品责任

共享平台能力与独立 Runtime 的架构关系

△ 平台能力可以共享,但每个产品仍保留独立 Runtime。

企业可以共享 Agent 注册、模型网关、MCP 管理、Trace、评测、回放、发布和成本分析等平台能力,同时让不同产品保留独立运行边界。

Schneider Electric 选择自托管 LangSmith,也和关键基础设施、数据驻留及网络安全要求有关。自托管会带来集群维护、版本升级和网络策略调试等成本,不应该被照搬成所有企业的默认答案。[1]

从零开始,不必先建设一套大而全的平台

如果团队现在还没有完整的 Agent 反馈系统,我会先做四步。

1. 选一个真实 Agent,把 Trace 串完整

确保一次请求能追踪到 Prompt、模型、召回、工具调用、结果、耗时和版本。

先解决“出了问题能不能定位”,不要一上来建设大而全的平台。

2. 从真实失败中整理第一批评测案例

可以先从几十条高价值问题起步,验证筛选、脱敏、标注和回放流程能不能跑通。这个数量只是起点,不是所有 Agent 都要遵守的固定门槛。

优先收集:

  • 任务没有完成;
  • 工具调用错误;
  • 用户重复尝试;
  • 领域专家明确判错;
  • 修复后可能再次回归。

每条案例都要写清期望行为和通过条件。

3. 把 Replay 变成发布前的固定动作

任何 Prompt、模型、知识库或 Agent 流程变更,都跑同一套回归评测。

结果至少同时看任务成功率、严重错误、延迟和成本,不用一个总分掩盖问题。

4. 再补线上评测和灰度发布

离线评测通过后先放小流量,观察新 Trace、用户反馈和关键指标。新的失败继续进入候选队列,经过筛选和标注后成为下一轮评测资产。

从生产 Trace 到评测集、回放和灰度发布的反馈循环

△ 线上失败经过筛选和标注进入评测集,再通过回放与灰度发布回到生产。

可以把最小流程压缩成这张检查表:

[ ] 生产请求能够定位到完整 Trace
[ ] 候选失败有明确的问题类型和责任队列
[ ] 进入评测集的案例已脱敏,并写清期望行为
[ ] Prompt、模型、RAG 或 Agent 变更会触发 Replay
[ ] 发布前同时检查任务结果、严重错误、延迟和成本
[ ] 灰度阶段继续收集新 Trace,并回流到下一轮

这套方法能解决什么,不能解决什么

这套反馈循环不会让 Agent 从此不出错。

它主要解决两个问题:

  1. 错误发生后,团队有没有留下足够的证据;
  2. 修改上线前,团队能不能用真实问题验证这次修改。

它不能替代传统工程能力。

工具超时仍然需要重试和降级,知识库过期仍然需要数据治理,页面故障仍然需要端到端测试,基础设施问题仍然需要监控和容错。

评测集本身也需要维护。产品标准变了、数据过期了、旧案例已经被新案例覆盖,都要及时清理,否则评测资产也会变成噪声。

dev/test/prod 没有过时。对 Agent 来说,prod 只是结束了一次发布,同时开启了下一轮评测。

如果现在只能先做一件事,我会先检查:

今天出现的失败,明天能不能变成一条可回放的测试?

参考资料

[1] LangChain、Schneider Electric,How Schneider Electric Built Their LLMOps Foundations With LangSmith,2026-07-07:
www.langchain.com/blog/how-sc…