LLM 应用可观测性:日志、评估与成本监控
LLM 应用一上线,最怕的就是“不知道它在干什么”:回答质量滑坡、成本暴涨、用户投诉,查都不知道从哪查。可观测性就是给 LLM 应用装仪表盘:每次调用都留下记录,质量和成本都能量化,出了问题能定位。这篇把 LLM 可观测性讲透:三支柱、日志设计、指标体系、评估、成本、追踪、告警、复盘、工具选型。
一、可观测性三支柱:日志、指标、追踪
传统服务的可观测性有三支柱,LLM 应用也一样,只是内容变了。
| 支柱 | 传统服务 | LLM 应用 |
|---|---|---|
| 日志 | 请求日志、错误日志 | 每次调用的 prompt、回答、token 数、延迟 |
| 指标 | QPS、延迟、错误率 | token 消耗、首 token 延迟、幻觉率、成本 |
| 追踪 | 调用链 | Agent 的多步调用链、工具调用链 |
三样缺一不可:日志用来排障,指标用来看趋势,追踪用来定位多步流程里哪一步出了问题。Agent 应用尤其需要追踪,单步看不出来问题,要看整条链。
二、日志设计:每次调用都留下记录
# 给 LLM 调用包一层日志(示意)
import time
import json
import hashlib
from openai import OpenAI
client = OpenAI(base_url="http://localhost:11434/v1", api_key="ollama")
def chat_with_log(messages, model="qwen2.5:7b", user_id="anonymous"):
start = time.time()
resp = client.chat.completions.create(model=model, messages=messages)
usage = resp.usage
record = {
"timestamp": time.strftime("%Y-%m-%dT%H:%M:%S"),
"user_id": user_id,
"model": model,
"prompt_tokens": usage.prompt_tokens,
"completion_tokens": usage.completion_tokens,
"latency_ms": int((time.time() - start) * 1000),
"prompt_hash": hashlib.sha256(
messages[-1]["content"].encode()).hexdigest()[:16],
"prompt_preview": messages[-1]["content"][:200],
"answer_preview": resp.choices[0].message.content[:200],
"finish_reason": resp.choices[0].finish_reason,
}
with open("/var/log/llm-calls.jsonl", "a", encoding="utf-8") as f:
f.write(json.dumps(record, ensure_ascii=False) + "\n")
return resp.choices[0].message.content
- 记什么:算钱的(token 数、模型)和排障的(prompt、回答、延迟、finish_reason)。finish_reason 是 length 说明被截断了,是 stop 说明正常结束,是 content_filter 说明触发了过滤。
- 隐私:prompt 和回答别全量存,截前 200 字就够排障用,全量存既占地方又有隐私风险。敏感信息(密钥、身份证号)要脱敏,存 hash 不存原文。
- 采样:量大了全量存扛不住,按比例采样(比如 10%),错误和慢请求全量存,正常请求采样存。
- 存储:JSONL 格式写文件,定期归档到对象存储或者日志系统,别让日志把磁盘打满。
三、指标体系:SLO 要能量化
| 指标 | 含义 | 告警阈值(示例) |
|---|---|---|
| 请求量 | 每分钟调用次数 | 突增 3 倍 |
| 平均延迟 | 从请求到完整回答的时间 | 超过 10 秒 |
| P99 首 token 延迟 | 99% 的请求首 token 在多少以内 | 超过 5 秒 |
| 错误率 | 超时、5xx、限流的比例 | 超过 1% |
| Token 消耗 | 每天的 prompt + completion token | 超过预算 80% |
| 点踩率 | 用户点踩的比例 | 连续三天上升 |
| 幻觉率 | 答案和资料不符的比例 | 超过 5% |
指标要进 Prometheus 或者类似的时序库,别只记日志里。SLO 定三条就够:可用性(错误率低于 1%)、延迟(P99 首 token 低于 5 秒)、成本(单日 token 不超预算)。SLO 不达标就告警,达标了别天天盯着看。
四、评估体系:质量要能量化
- 离线评估集:准备 100 到 200 个真实问题和标准答案,每次改提示词或者换模型都跑一遍,看通过率是升了还是降了。没有评估集的迭代等于蒙着眼睛调参。
- 在线反馈:回答下面放点赞和点踩,踩的自动进复盘清单,每周看一次。点踩率是最真实的质量信号。
- 幻觉检测:有知识库的场景,对比回答和检索片段的重合度,答非所问的比例就是幻觉率。也可以用另一个模型当裁判,判断回答是不是有资料支撑。
- A/B 测试:新提示词或者新模型先切 10% 流量,对比通过率和点踩率,没问题再全量。别直接全量上线,出问题影响所有人。
五、成本分析:token 就是钱
# 从日志里统计每天的 token 和成本(示意)
python3 -c "
import json
total_prompt = total_completion = 0
for line in open('/var/log/llm-calls.jsonl', encoding='utf-8'):
r = json.loads(line)
total_prompt += r['prompt_tokens']
total_completion += r['completion_tokens']
print(f'prompt tokens: {total_prompt}, completion tokens: {total_completion}')
# 成本 = prompt tokens × 单价 + completion tokens × 单价
# 单价按模型和厂商定价表算
"
# 按用户和功能分摊成本
python3 -c "
import json
from collections import defaultdict
cost = defaultdict(lambda: {'prompt': 0, 'completion': 0})
for line in open('/var/log/llm-calls.jsonl', encoding='utf-8'):
r = json.loads(line)
cost[r['user_id']]['prompt'] += r['prompt_tokens']
cost[r['user_id']]['completion'] += r['completion_tokens']
for user, v in sorted(cost.items(), key=lambda x: -x[1]['prompt'])[:10]:
print(user, v)
"
成本优化三板斧:提示词缓存(重复的系统提示词只算一次)、模型路由(简单问题走小模型,复杂问题走大模型)、结果缓存(同样的问题直接返回上次的答案)。三招下来,成本经常能砍一半以上。成本要按用户和功能分摊,哪个功能最烧钱一目了然,优化才有方向。
六、调用链追踪:Agent 的多步流程
Agent 应用一次任务可能调十几次模型、调好几个工具,单步日志看不出来问题,要看整条链。追踪的思路是给每次任务一个 trace_id,每一步是一个 span,记录每步的输入、输出、耗时、token。LangSmith、Langfuse 都是现成的追踪工具,自研的话按这个结构记日志也行。
- trace_id:一次用户任务一个 trace_id,全链路透传。
- span:每步调用一个 span,记录模型、工具、耗时、token、输入输出摘要。
- 慢步骤定位:链路里哪一步耗时最长、token 最多,一眼就能看出来。
- 死循环定位:Agent 反复调同一个工具不收敛,追踪图里一眼就能看出来。
七、告警设计:别让告警变成噪音
- 延迟告警:平均延迟超过阈值,或者错误率突增,立刻告警。
- 成本告警:单日 token 超预算 80% 就告警,别等到月底账单来了才发现。
- 质量告警:点踩率连续三天上升,说明提示词或者模型出了问题,进复盘。
- 告警分级:服务不可用是 P0,立刻处理;成本超预算是 P1,当天处理;点踩率上升是 P2,每周复盘。别所有告警都一个级别,全是 P0 等于没有 P0。
- 误报控制:告警阈值要按历史数据定,别拍脑袋。阈值太松等于没告警,太紧天天误报,值班的人很快就不看了。
八、复盘流程:bad case 是最好的老师
- 每周复盘:挑 10 个最差的 case(点踩的、幻觉的、超时的),定位是提示词问题、检索问题、模型问题还是工具问题,分到人头上改。
- 根因分类:每个 bad case 打一个根因标签,月底统计哪类问题最多,优先解决高频问题。
- 回归:修完之后把 bad case 加进评估集,下次迭代跑一遍,确认修好了没复发。
九、工具选型
| 方案 | 优点 | 缺点 | 适用 |
|---|---|---|---|
| 自研(日志 + Prometheus) | 完全可控,成本低 | 要自己写 | 小团队、需求简单 |
| LangSmith | 开箱即用,追踪强 | 商业,数据在外边 | 用 LangChain 的团队 |
| Langfuse | 开源可自部署,评估强 | 要自己运维 | 要评估和追踪,中等规模 |
| Helicone | 代理模式,接入简单 | 商业 | 用 OpenAI API 的团队 |
可观测性的终点不是看板好看,是出了问题能回答三个问题:什么时候开始的、影响了多少人、根因是什么。日志、评估、成本三样齐了,这三个问题都有答案。
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。






