大模型应用日志体系、Callback 源码链路、Trace 复盘、企业级落地
开篇:AI 应用没有日志,就是黑盒
大模型应用最怕的不是慢,也不是贵。最怕的是:用户说答案错了,你不知道错在哪。
普通业务系统出了问题,看接口日志、SQL 日志、异常堆栈,大多能定位。但大模型应用不一样。一次回答背后可能经过问题改写、意图识别、知识库检索、Rerank、Prompt 拼接、模型调用、工具调用、多轮记忆、结构化输出和安全拦截。任何一层出错,最后答案都会跑偏。
一、为什么传统日志不够用?
传统日志看的是“接口是否正常执行”。大模型日志看的是“答案为什么这样生成”。这两件事不是一个维度。
比如用户问企业制度,最终答案错了。原因可能不是模型弱,而是:问题改写错了;Retriever 没召回正确文档;Rerank 把关键 Chunk 排到后面;Prompt 把上下文拼反了;工具返回了旧数据;Memory 把上一个用户的状态串进来了。
所以 AI 日志必须从“结果日志”升级成“过程日志”。不只记录 final answer,还要记录每一步的输入、输出、版本、耗时、分数、错误和关联 ID。
二、一次回答必须留下完整证据链
真正可上线的 AI 系统,每一次回答都应该能回答 7 个问题:谁问的?系统怎么理解的?用了哪些资料?Prompt 怎么拼的?调用了哪个模型?执行了哪些工具?用户反馈如何?
这条证据链的价值很直接:当答案出错时,不用猜;当成本升高时,不用拍脑袋;当效果下降时,可以回放历史 Trace,对比模型版本、Prompt 版本、检索策略和工具返回。
三、AI 日志字段怎么设计?
日志字段不要贪多,也不能太少。最少要覆盖请求、输入、检索、Prompt、模型、工具、记忆、输出和反馈 9 层。每一层都对应一个排查入口。
字段设计的原则:能复盘的才有价值。不能定位问题、不能计算指标、不能沉淀评测集的字段,不要乱记。
四、LangSmith 的 Trace / Run / Thread 给了我们标准答案
LangSmith 的数据结构很适合借鉴。它把一个应用或服务放在 Project 里;一次完整操作是 Trace;Trace 由多个 Run 组成;多轮会话可以用 Thread 把多个 Trace 串起来。官方文档也明确说明,Run 可以代表一次 LLM 调用、Prompt 格式化、检索调用或其他离散操作。
这套结构非常适合大模型应用日志:request_id 对应业务请求,trace_id 对应一次 AI 任务,run_id 对应每个子步骤,parent_run_id 还原调用树。
Project:一个应用或服务,例如 customer-service-agent、stock-analysis-agent。
Trace:一次用户请求的完整执行链路。
Run:链路里的一个步骤,例如 Retriever、Tool、LLM、Parser。
Thread:多轮会话,把多次 Trace 按 conversation_id / thread_id 关联。
Metadata / Tags:用于写入环境、版本、用户、渠道、业务场景、Prompt 版本等筛选字段。
五、源码级理解:Callback 是 LangChain 的日志切入点
LangChain 的日志体系不是在最后统一 print。它在框架生命周期里埋点。模型开始、模型结束、工具开始、工具结束、检索开始、检索结束、Chain 开始、Chain 结束,这些都是事件。
源码里,CallbackManager 会维护一组 CallbackHandler。事件发生时,manager 调用 handle_event,把 on_llm_start、on_llm_end、on_tool_start、on_tool_end 等事件分发给所有 handler。每个 handler 可以选择写 LangSmith、写控制台、写自建数据库,或者写 MQ。
这就是为什么日志系统应该做成“观察者”,而不是散落在业务代码里。业务链路负责执行,Callback / Middleware 负责采集。
六、源码链路压缩成一句话
Runnable.invoke() → CallbackManager.configure() → on_chain_start() 创建 Run → get_child() 传递 parent_run_id → LLM / Retriever / Tool 触发 start/end/error → CallbackHandler 写入 LangSmith 或自建日志。
这里有三个关键点。第一,run_id 是每个步骤的身份。第二,parent_run_id 把子步骤挂回父步骤。第三,tags 和 metadata 会随着子 run 继承下去,所以你可以在根请求写入 user_id、env、prompt_version、biz_scene,后面的 LLM、Tool、Retriever 都能带上。
源码里的 BaseRunManager 会持有 run_id、parent_run_id、tags、metadata 和 handlers。CallbackManagerForLLMRun 负责 LLM 相关事件,例如新 token、结束、异常。CallbackManagerForChainRun 负责 chain 事件。Tool、Retriever 也有自己的 manager。每个 manager 都是在做一件事:把生命周期事件变成可观测数据。
七、答案错了,日志怎么帮你定位?
有日志之后,排查路径会非常清楚。不要一上来就说“模型幻觉”。先看链路。
先看 original_question 和 rewritten_question,确认问题有没有被改歪。
再看 intent 和 route,确认是不是走错了 FAQ / RAG / Tool / Agent。
再看 retriever topK 和 score,确认资料有没有召回。
再看 rerank_score,确认正确资料有没有被排掉。
再看 prompt_version 和 final_prompt_hash,确认上下文和模板是否正确。
再看 tool_args 和 tool_result,确认外部系统有没有返回旧数据或错误数据。
最后再看模型参数、temperature、finish_reason、token 截断和最终输出。
八、自建日志库怎么设计?
LangSmith 适合调试、追踪和评测。但企业系统通常还需要自建日志库。原因很简单:你要和用户、订单、权限、业务场景、工单、反馈、告警打通。
推荐设计成“主表 + 子表”。主表记录一次请求的总览,子表记录每类细节。不要把所有东西塞进一张大 JSON 表,否则后面查询、统计、回放都会痛苦。
ai_request_log:一次请求的主记录,保存问题、答案、状态、总耗时、trace_id。
ai_run_log:所有子步骤的通用运行表,保存 run_id、parent_run_id、run_type。
ai_model_call_log:模型调用明细,保存模型、token、成本、耗时、finish_reason。
ai_retrieval_log:检索明细,保存 query、doc_id、chunk_id、score、rerank_score、source。
ai_tool_call_log:工具调用明细,保存 tool_name、args、result、error、retry。
ai_feedback_log:用户反馈、人工标注、评测分数和失败分类。
九、企业级落地:Java 主服务 + Python AI 服务
在真实项目里,不建议让 Python AI 服务承担所有日志治理。更合理的是:Java 主服务负责业务身份和请求主链路,Python AI 服务负责 LangChain 事件采集,异步队列负责削峰,日志存储负责查询和分析,LangSmith 负责 Trace 可视化。
Java 主服务生成 request_id,并把 user_id、tenant_id、biz_scene、channel 写进请求上下文。Python AI 服务接收到这些上下文后,放入 RunnableConfig 的 metadata / tags 或 Agent runtime context。模型、工具、检索、记忆的所有事件都带着这些元数据,最后才能按用户、场景、模型版本、Prompt 版本聚合分析。
十、日志不是越全越好:还要脱敏、采样、异步
AI 日志很容易踩坑。最常见的是把完整 Prompt、用户隐私、工具返回、订单数据全部明文落库。短期看方便排查,长期就是安全风险。
敏感字段必须脱敏:手机号、身份证、邮箱、地址、token、cookie、API Key、银行卡。
Prompt 可以保存 hash、版本和变量摘要,完整内容按权限查看或短期留存。
工具参数和返回要分级:普通字段可记录,敏感字段只记录 hash 或脱敏值。
日志写入要异步化,不能阻塞主回答链路。
大流量场景要采样,但失败请求、低分请求、人工差评请求必须全量保存。
保留周期要分层:明细短期留,聚合指标长期留。
十一、日志如何变成评测闭环?
日志不是终点。日志真正的价值,是把线上失败样本沉淀为评测集。
LangSmith 的 Evaluation 工作流也强调:离线评测可以在上线前基于数据集测试版本;在线评测可以在生产环境监控真实交互;失败生产样本可以加入数据集,再通过离线实验验证修复效果。这个思路也应该进入自建系统。
用户点踩或人工标注失败,写入 ai_feedback_log。
系统根据 failure_type 分类:召回失败、Prompt 失败、工具失败、模型幻觉、格式错误。
失败样本进入 eval_dataset。
每次改 Prompt、改模型、改检索策略,都跑一次离线回归。
上线后继续做在线抽样评测,观察准确率、延迟、成本和差评率。
十二、上线检查清单
十三、总结
大模型应用的日志体系,核心不是“把输出存下来”。核心是把一次回答拆成可复盘的运行链路。
一套合格的日志体系,应该同时服务四件事:线上排障、效果评测、成本治理、产品迭代。没有日志,AI 应用就是黑盒;有了证据链,AI 应用才真正可控。
内容来源:https://news.eeebb.com/article/3710