前 10 篇我们做了一堆优化:重试、缓存、上下文压缩、混合检索、评测集、本地兜底、多 Agent 流水线。但这些优化有没有效果、哪天生效哪天回归,目前全是”感觉”。第 01 篇诊断时就说了:成本不可见、无埋点。本篇用 Langfuse 给整个系统装上仪表盘,让每一条请求可回放、每个指标可度量、每次回归可告警。
一、为什么传统监控不够用
传统后端监控(Prometheus、Sentry)衡量的是”HTTP 200 还是 500、响应几毫秒”。但 LLM 应用的失败往往是”HTTP 200,回答却是错的“——模型幻觉、检索跑偏、Prompt 改坏了。这种失败只能靠内容级可观测性发现:你要能看到”这条请求发给了哪个模型、喂了什么 Prompt、检索到哪些 chunk、模型怎么回答、花了几块钱”。
这就是 LLMOps 的核心:把每一次 LLM 调用、每一步 Agent 决策、每一份注入的上下文,都变成可检索、可回放、可评分的 trace。
二、Langfuse 的核心概念
Langfuse 是主流的开源 LLMOps 平台(可自托管,也兼容 OpenTelemetry)。它围绕两个概念组织:
1 | Trace(一次完整会话/任务) |
trace 能回答所有”感觉”问题:这条回答花了多少钱?检索召回对不对?用的是哪个版本的 Prompt?模型是不是降级到本地了?
三、给 ByteBot 接入 Langfuse
3.1 埋点的最小集合
api/chat.js 是 serverless 函数,埋点不能喧宾夺主。最小方案:在关键边界打 span,异步上报。
1 | const { Langfuse } = require('langfuse'); |
3.2 关键埋点清单
| 埋点 | 位置 | 采集内容 |
|---|---|---|
| 意图分类结果 | buildBlogMessages | intent=blog/casual |
| 检索调用 | rankArticles / hybridSearch | query、Top 结果、分数、引擎版本 |
| 检索降级 | 缓存/重试命中 | 是否命中缓存、重试了几次 |
| LLM 调用 | fetch DeepSeek | 模型、token、费用、延迟、是否降级本地 |
| Prompt 版本 | 生成 system prompt 处 | version 标签(见下一节) |
| 前端渲染修正 | validateLinks | 修正了几个链接(反映输出质量) |
先埋再优化:埋点本身不能引入延迟(异步上报、失败静默),且敏感信息必须脱敏——用户输入只存前 50 字符 + IP 匿名化,绝不存密钥。
四、Prompt 版本管理
第 01 篇诊断过:ByteBot 的 system prompt 是”打补丁”式演进,改坏了无法回滚。Langfuse 的 Prompt 管理功能解决这个问题:
1 | prompt_name: bytebot-system-v2 |
接入方式:
1 | const prompt = langfuse.getPrompt('bytebot-system-v2'); |
工程收益:
- 线上回答质量突然下降 → 打开 Langfuse 报表,按 prompt 版本分组看 Faithfulness/成本 → 一秒定位”是 v2.3 引入的回归” → 一键回滚到 v2.2。
- 第 03 篇的 system prompt 重构(滚动摘要、结构化输出)全部走版本管理,每次改动可 A/B 对比。
五、效果回归测试与告警
5.1 离线评测入 CI
第 05 篇的 eval 脚本现在接入 CI(deploy.yml 的测试步骤):
1 | 步骤:node --test + pytest |
这样任何改动(改 Prompt、改检索、改 chunk)如果让评测指标劣化,push 直接失败,问题在合入前就被拦住——这是”评测不劣化”红线,也是第 05 篇承诺的回归检查。
5.2 线上指标与告警
Langfuse 的自定义指标(metrics)可以定义”异常区间”:
| 指标 | 告警阈值 | 含义 |
|---|---|---|
| 成本/天 | > ¥10 | 成本异常(可能被刷或 prompt 膨胀) |
| 降级率 | > 5% | DeepSeek 故障或密钥失效 |
| 检索空结果率 | > 10% | 索引过期或检索坏了 |
| 首 token 延迟 | > 5s | 模型或网络异常 |
| 429 率 | > 5% | 限流,需要降速 |
第 02 篇的 usage 埋点、第 06 篇的”降级打标”、第 09 篇的工具日志,所有埋点在这里汇合——这就是为什么全系列反复强调”先埋点再优化”。
六、落地清单与小结
| 优先级 | 改造 | 收益 |
|---|---|---|
| P0 | Langfuse 接入 + 5 个核心 span 埋点 | 每次请求可回放、成本可见 |
| P0 | Prompt 版本管理(v2.1→v2.3) | 回归可定位、可回滚 |
| P1 | CI 评测回归门禁 | 改动劣化即失败 |
| P1 | 成本/降级率/429 告警 | 线上异常主动发现 |
| P2 | 前端渲染修正率埋点 | 度量模型输出质量 |
| P2 | 线上问题回流评估集 | 评测集滚动进化 |
核心结论:
- 传统监控看”HTTP 200”,LLMOps 看”回答对不对”;内容级可观测性才能发现模型层的失败。
- Langfuse 的 trace/span 模型正好映射 ByteBot 的调用链:意图→检索→Prompt→LLM→渲染。
- 埋点要脱敏、要异步、要静默失败;serverless 里埋点不能喧宾夺主。
- Prompt 版本管理让”改坏了回滚”从 git 层面下沉到应用层面,还能按版本对比指标。
- 离线评测进 CI + 线上指标告警,双闸门兜住质量与成本。
下一篇是系列收官:ByteBot v2 综合实战。把第 01~11 篇的改造全部收口,给出 ByteBot v2 的完整架构图、改造前后对比数据(质量/成本/延迟)和未来演进方向。
本系列持续更新中,每周一篇。