生产 Agent 排障别先改 Prompt:先把 trace、tool span 和证据字段补齐
这两天公开信号里,CSDN 上涨得最明显的一类内容,不是抽象的 Agent 愿景,而是可观测性、监控和故障排查。
这其实很符合真实项目节奏。
团队把 Agent 接进工单、订单、设备、审批或内部运维流程以后,第一批真正让人头疼的问题,通常不是“模型是不是还不够聪明”,而是:
- 为什么同一类任务有时几秒,有时几十秒;
- 为什么成本突然飙高,但追不到是哪一步多跑了两轮;
- 为什么用户说结果错了,团队却只能看到最终回复;
- 为什么工具明明返回了
partial,下游还是把结果当成“完整成功”继续写了状态; - 为什么事故复盘时,没人能回答到底是模型判断错了、工具契约不清,还是重试策略把故障放大了。
这类问题如果还在靠继续改 prompt 处理,排障成本会非常高。生产环境更有效的做法,是先把一条最小可追溯证据链补齐,再讨论模型优化。
先给一个判断标准
如果一个 Agent 已经满足下面三个条件里的任意两个,就不该再只看最终回复日志:
- 会调用两个以上外部工具;
- 会写真实业务状态;
- 会在失败时自动重试、降级或切人工。
一旦进入这个阶段,问题不再只是“答得对不对”,而是“整条运行链到底发生了什么”。
minimum_agent_trace:run:run_id:requiredtask_type:requiredtenant_or_env:requiredfinal_status:requiredtotal_latency_ms:requiredmodel_span:provider_model_version:requiredinput_output_tokens:requiredduration_ms:requiredpurpose:requiredtool_span:tool_name:requiredinput_summary:requiredoutput_summary:requirederror_code:requiredretry_count:requiredresult_state:requiredsafety:write_gate_hit:requiredhuman_handoff:requiredrollback_or_block_reason:optional这套字段不花哨,但足够把很多“玄学问题”变成工程问题。
一条最小诊断链路可以先长这样:
1. run 级记录先把事故装进同一个盒子里
很多团队的问题不是没有日志,而是日志太散。模型日志一份、工具日志一份、业务系统审计一份,最后没人能把它们拼成一次完整运行。
所以第一层一定是 run 级上下文,至少包含:
run_idtask_typesession_id或业务单号tenant / env / actorstarted_at / finished_atfinal_statustotal_latency_msestimated_cost
如果这层没有打平,后面就很难判断一次事故到底影响了哪个任务、哪个租户、哪个业务动作。
2. model span 解决“慢”和“贵”到底出在哪
很多团队看到成本上升,先怀疑模型太贵;看到延迟升高,先怀疑 provider 波动。
但真实项目里,经常是下面几种情况更常见:
- 工具返回太碎,导致模型多做两轮规划;
- 输出 schema 校验失败,补了一次修复调用;
- 同一个高复杂任务走了不该走的大模型;
- 某个降级分支没有命中,结果多花了一次总结步骤。
所以每次模型调用都建议至少记录:
- provider / model / version
- input tokens / output tokens
- duration
- 调用目的:规划、抽取、总结、回复
- schema 是否失败
- fallback 是否触发
只要这些字段存在,很多“模型不稳定”的判断都会被快速纠正。
3. tool span 才是生产 Agent 最容易漏、也最值钱的一层
公开信号里,这轮最值得参考的一点,是 CSDN 热门内容明显在向工程落地和排障闭环靠拢。对 Agent 来说,真正能撑住排障的不是一句“工具调用失败”,而是这次失败具体失败在哪一层。
每次工具调用至少建议落这几类字段:
tool_nameinput_summaryoutput_summarystatus_code / error_codeattemptretry_countduration_msresult_state:success/partial/blocked/failedpolicy_gate_hit
尤其是partial和blocked,不能和普通成功混在一起。
很多事故并不是“调用失败”,而是:
- 工具只回了部分字段;
- 权限校验挡住了写操作;
- 下游 200 了,但业务语义其实没完成;
- 重试成功了,但用户看到的是重复写入的副作用。
这些都需要结构化记录,不能只留一句文本。
4. 先抓 6 类证据字段,足够覆盖第一轮排障
如果团队现在还没有完整 tracing 基础设施,我建议先补这 6 类证据字段:
run_id + task_typeprovider_model_version + token + latencytool_name + input_summary + output_summaryerror_code + retry_countresult_state = success/partial/blocked/failedhuman_handoff / write_gate / rollback_signal
一旦这 6 类字段有了,很多模糊争论会立刻变得清楚:
- 是模型判断错,还是工具返回不完整;
- 是工具超时,还是重试策略把问题放大;
- 是写操作该拦没拦住,还是本来就不该放行;
- 是单次故障,还是某类任务系统性不稳。
5. 一个够用的结构示例
下面这类结构,已经足够支持第一轮排障和复盘:
{"runId":"run_20260628_101502","taskType":"refund_triage","finalStatus":"blocked","latencyMs":18440,"estimatedCostUsd":0.27,"modelSpans":[{"name":"plan-next-step","provider":"openai","model":"gpt-5.1-mini","durationMs":1520,"inputTokens":4210,"outputTokens":381}],"toolSpans":[{"toolName":"fetch_order_context","resultState":"partial","durationMs":480,"missingFields":["latest_payment_status"]},{"toolName":"issue_refund","resultState":"blocked","errorCode":"HUMAN_APPROVAL_REQUIRED","retryCount":0,"policyGateHit":"refund_write_requires_approval"}],"handoff":{"triggered":true,"reason":"high_risk_write_blocked"}}关键不在字段名,而在你能不能稳定回答:
- 哪一步先变慢;
- 哪一步开始不可信;
- 哪一步触发了风险闸门;
- 这次运行到底该不该继续自动执行。
6. 先排障,再把数据反写回控制面
trace 和 span 的价值,不只是“出了事故能回看”。
一旦证据字段稳定下来,后面还能直接推动三类生产改进:
- 哪些任务应该切到更便宜的模型;
- 哪些工具要增加幂等和参数契约;
- 哪些高风险写操作必须前置人工确认。
这也是为什么我通常把 trace、tool-calling、审计、模型路由、权限边界放在同一套控制面里看。它们不是独立优化项,而是一组生产能力。
结尾判断
如果一个 Agent 已经接进真实工单、订单、设备或资金流,却还回答不了“这次到底用了哪个模型、调了哪个工具、为什么被拦、为什么重试、哪一步开始失真”,那它离真正可运营还差一层很关键的证据基础。
如果最近在准备 AI Agent Production-Readiness Review,这类项通常也会优先检查:trace 是否覆盖关键任务、tool span 是否能支撑复盘、写操作是否有拦截证据、人工接管和回滚信号是否能被稳定记录。重点不是把 Agent 讲得更聪明,而是确认它出了问题以后能查得清、停得住、改得动。
