猪头少年 - 云南AI专家 - 云南独立开发者

Engineering note

日志、指标与可观测性:看见 Agent 到底做了什么

这是「Agent 工程实战」的第 14 篇。专题从一个能聊天、能调工具的 .NET Agent 出发,逐步补齐可靠性、安全、测试与发布能力。

本篇要解决的问题: 把请求、工具、耗时和错误串成可追踪事件,同时避免日志泄露敏感信息。

返回专题路线


本章定位:本章建立 Agent 的观察能力。你会区分日志、指标和审计,设计 session、turn、tool call 三种关联 ID,并处理敏感信息脱敏。

建议阅读方式:先通读原理,再对照当前项目源码,最后完成本章实践。当 Agent 出现“偶尔不工作”时,没有可观测性就只能猜;本章会把猜测变成证据。

本章导读

本章建立 Agent 的观察能力。你会区分日志、指标和审计,设计 session、turn、tool call 三种关联 ID,并处理敏感信息脱敏。

本章采用“源码观察 → 概念拆解 → 工程改造 → 实践验证”的顺序。示例中的接口和代码骨架用于说明设计方向,真正提交代码时应结合项目当前状态逐步落地。

14.1 你至少需要知道什么

一次用户请求应能回答:

  • 什么时候开始、什么时候结束;
  • 调用了哪一个模型;
  • 进行了几步工具调用;
  • 每个工具耗时多久、是否成功;
  • 模型请求是否重试;
  • 输入输出 token 或字符数是多少;
  • 最终失败发生在哪一层。

14.2 结构化日志

不要只使用 Console.WriteLine 拼字符串。建议日志字段固定化:

{
  "event": "tool.completed",
  "session_id": "...",
  "tool": "filesystem.read_file",
  "duration_ms": 18,
  "success": true
}

敏感参数应脱敏。文件内容、API Key 和完整命令参数不应默认写入日志。

14.3 指标

第一批指标可以很少:

  • agent_turn_total
  • agent_turn_failure_total
  • model_request_duration_ms
  • tool_call_duration_ms
  • tool_call_failure_total
  • model_tokens_total

14.4 本章交付物

  • ILogger
  • request/session/turn/tool correlation ID;
  • 结构化事件日志;
  • 工具耗时和失败统计;
  • 一份脱敏规则。

14.5 日志不是把所有内容都打印出来

调试阶段很容易把请求 JSON、完整工具参数和文件内容全部打印出来。短期看很方便,长期会造成密钥泄露、隐私泄露和日志成本上升。

建议日志分为三类:

  • 生命周期日志:请求开始、结束、取消、失败;
  • 决策日志:模型选择了哪个工具、调用 ID 是什么;
  • 诊断日志:耗时、状态码、解析失败位置。

内容本身只在明确的 debug 模式下记录,并且仍然经过脱敏和截断。

14.6 相关 ID 的传递

一次用户输入至少需要三个 ID:

session_id:长期会话
turn_id:一次用户输入到最终回答
tool_call_id:模型发起的一次工具调用

日志中同时写入这三个 ID,才能从用户问题追踪到某次工具失败。不要只依赖时间戳,因为并发请求的时间可能重叠。

14.7 指标与日志的区别

日志适合解释一次具体请求为什么失败;指标适合观察整体趋势。例如“某次 ReadFile 失败”是日志,“过去 5 分钟 ReadFile 失败率为 12%”是指标。

先用内存计数器或简单 JSON 日志都可以,但字段一旦稳定,就不要频繁改名。稳定的指标名称能支持后续告警和仪表盘。

14.8 练习:设计一次失败的追踪

想象用户请求最终失败在第三次工具调用。写出至少五条日志事件,并确保只通过 session_idturn_idtool_call_id 就能还原执行顺序。再检查这些日志是否泄露了文件内容和密钥。

14.9 本章产出

完成本章后,遇到“模型没有回答”这种模糊问题,你应该可以定位是配置、HTTP、SSE、循环、工具还是上下文导致的。

单篇实战作业

实践:设计一条失败请求的日志链,确认只凭三个关联 ID 就能还原完整执行顺序。

建议把作业拆成一个独立提交,并在提交说明中写清楚:改动前的行为、改动后的行为、验证命令、尚未解决的风险。当 Agent 出现“偶尔不工作”时,没有可观测性就只能猜;本章会把猜测变成证据。

章节复盘

复盘问题:发生线上故障时,你能否区分 provider、网络、循环、工具和数据问题?

本章的完成标准不是把所有设计一次性做完,而是能把它变成项目中的一个明确边界,并为下一章留下可验证的接口。


下一篇:第 15 篇《测试 Agent,而不是只测试方法》

如果你正在把 Agent 放进真实工作流,建议完成本篇的实战作业后再继续:每一步都应留下可验证的代码、测试或运行记录。

Next step

不要停在单篇文章。

沿主专题继续阅读,查看同一问题从概念到实战的完整路径。

返回「Agent 工程实战」路线