关联任务、模型、检索和工具调用,用失败类别解释耗时与成本。
本文于 2026-09-12 补充整理,按 2026-07 专题归档。示例为方案设计,参数用于说明方法,不代表已上线项目或实测成果。
从一次用户请求追到最终结果
普通 HTTP 服务常以请求完成作为一次调用的边界。Agent 可能持续多轮、等待审批并在另一个工作进程恢复,单条 HTTP trace 无法自然覆盖全部生命周期。
建议让 taskId 成为业务关联键,traceId 描述一次执行片段,attemptId 区分重试。三者用途不同:任务可以跨多个 trace,同一工具操作也可以有多个尝试。
观测结构按执行步骤组织
task execution
├─ route decision
├─ retrieval
│ ├─ keyword search
│ ├─ vector search
│ └─ rerank
├─ model call
├─ tool authorization
├─ tool execution
└─ checkpoint commit
这是逻辑 span 树。长时间等待人工审批时,可以结束当前 trace,恢复后通过 taskId 和关联关系连接新片段,避免让一个 span 持续数天。
Spring AI 的观测文档覆盖模型和相关组件的观测能力。业务终态、审批和账本提交则是应用需要补充的部分。字段名称与实际依赖版本一起固定,不假设所有版本完全相同。
指标和日志各司其职
指标适合回答“失败率是否上升”,日志与 trace 用于定位“哪一步失败”。不应把 taskId、完整问题或工单编号设为指标标签,否则高基数会增加监控成本。
可以使用低基数维度,如路由名称、工具类型、错误分类和发布版本。租户数量巨大时,不宜默认按每个租户生成所有时间序列,可以把详细租户信息放在受控查询数据中。
错误至少区分模型限流、检索无证据、授权拒绝、输出契约失败、工具超时和业务结果不确定。正常拒答不应与基础设施故障混为一个异常计数。
时间需要拆开测量
记录排队时间、首次模型 token 时间、首次业务内容时间、工具总耗时和任务完成时间。SSE 的心跳或“正在处理”不应算作真正的首个答案 token。
模型调用完成得快,但用户仍等很久,可能是排队或代理缓冲;总 token 很低但费用偏高,可能是重试或模型路由变化。只有分步骤数据才能解释这些现象。
成功率还要连接业务系统:工单服务确实创建记录,任务才进入成功。最终回答里的文字只是展示层证据。
默认避免保存完整敏感上下文
日志记录提示词版本、输入长度、证据 ID 和脱敏参数即可。需要排查原文时,通过短期、受控的采样或对象引用访问,并记录访问行为。
工具结果可能包含凭据或个人信息。即便采集系统支持完整内容,也应明确脱敏、保留期和删除方式。调试方便不能成为无限期复制知识库的理由。
用一个故障验证整条链
让重排服务超时、模型调用成功、最终回答缺失必要引用。预期在一次任务查询中看到重排降级、模型消耗、引用校验失败和最终未成功状态,而不是只看到模型返回 HTTP 200。
然后比较“只查 API 日志”和“按 taskId 查完整执行片段”需要多少步骤定位问题。这里不需要先搭一个复杂平台,稳定标识和合理错误分类就能显著改善排查过程。
告警应面向可行动的症状,例如结果不确定的写操作持续积压,而不是对每一次正常的用户澄清都报警。
