LangChain 学习笔记 07:没有运行轨迹,LLM 应用只能靠猜来排错

传统接口报错时,我们至少能看到状态码和堆栈。LLM 应用更麻烦:它可能没有抛出异常,只是悄悄给出一个不完整、跑题或缺少证据的答案。

第 8 章介绍回调处理器。篇幅不算长,却提醒了我一件很重要的事:模型调用、检索和工具执行如果没有留下轨迹,系统上线以后几乎只能靠猜。

一次回答里到底发生了什么

一个 RAG 问答请求可能经历:

用户问题 -> 查询改写 -> 检索 -> 重排序 -> Prompt -> 模型 -> 输出解析

最终答案错了,原因可能是检索不到、检索正确但 Prompt 截断了、模型忽略证据,或者解析器删掉了字段。只记录最后答案,无法区分这些情况。

回调或追踪机制的作用,就是在组件开始、结束、失败和流式输出时收集事件,把一条请求还原成完整路径。

我希望一条 Trace 至少包含什么

{
  "trace_id": "req-20260730-001",
  "step": "retrieve_documents",
  "duration_ms": 86,
  "input_summary": "如何重置企业账号密码",
  "result_count": 4,
  "status": "success"
}

除了步骤和耗时,LLM 应用还应记录模型名称、Prompt 版本、token 使用量、检索文档 ID、工具名称、重试次数和错误类型。

但日志不应原样保存全部用户输入、文档正文和密钥。可观察性和隐私需要同时设计:敏感字段脱敏,正文只记摘要或引用 ID,日志设置访问权限和保留期限。

日志、指标和 Trace 各看什么

日志适合记录离散事件,例如某次解析失败、某个工具返回权限不足。

指标适合看整体趋势,例如请求量、P95 延迟、错误率、平均 token、检索空结果率和单次成本。

Trace用来还原一次请求跨组件的完整路径,特别适合排查“没有报错但回答变差”的问题。

三者不能互相替代。只有日志,很难看趋势;只有指标,看不到某次请求的细节;只有 Trace,也不容易快速发现系统性退化。

流式输出也需要被观察

流式返回可以改善等待体验,却增加了取消、断线和部分结果处理。除了总耗时,还可以记录首 token 延迟、流式中断位置和客户端取消状态。

如果输出解析必须等待完整内容,就要明确告诉调用链:前面可以流式展示,最终结构校验仍在结束后完成。不能因为用户已经看到半段文字,就默认整个调用成功。

先定义问题,再决定记录什么

可观察性不是“能记多少就记多少”。我更愿意从排障问题反推字段:

  • 为什么这次回答没有引用?记录检索文档与引用映射。
  • 为什么今天成本突然升高?记录模型、输入输出 token 和重试次数。
  • 为什么 Agent 一直不结束?记录每轮工具、参数、结果和停止原因。
  • 为什么新版 Prompt 质量下降?记录 Prompt 版本并保留评测样本。

有了明确问题,日志才不会变成昂贵又没人看的数据堆积。

这章给我的启发

Callback 不只是一个打印 token 的辅助功能,它是 LLM 应用可观察性的入口。

当系统由多个非确定组件组成时,“运行成功”不能只看有没有返回 200。我们还要知道它走过哪些步骤、使用了哪些证据、花了多少成本,以及结果为什么变成现在这样。能回答这些问题,应用才真正具备迭代和维护的基础。

posted @ 2026-07-31 17:57  Hazy_star  阅读(5)  评论(0)    收藏  举报