AI 应用调用链追踪与日志标准化实战指南:从 Prompt 到响应的端到端可调试性
2026-09-03 · 约 12 分钟阅读
AI 应用的"日志"和传统服务不一样——你不仅要记"请求成功/失败",还要记录 Prompt 内容、模型选择、Token 消耗、工具调用链、用户反馈……否则一旦线上出问题,调试基本等于"考古"。本文从生产实践出发,讲清楚怎么把 LLM 应用的日志和追踪体系搭起来。
一、为什么需要专门的 LLM 可观测方案
传统微服务的可观测体系(Prometheus + Grafana + Loki)可以监控延迟、错误率、QPS,但回答不了 LLM 应用特有的问题:
- 这个用户上一轮问了什么?Prompt 完整长什么样?
- 同样的 Prompt,不同模型、不同时间的输出差异有多大?
- 哪一类请求在烧 Token?实际成本是否超出预期?
- 用户对哪条回答点了"👎",为什么?
- Function Calling 调用了几次?为什么中间某一步失败?
要回答这些问题,必须有 专门面向 GenAI 的可观测体系。好消息是:OpenTelemetry 在过去两年已经把 GenAI 语义规范标准化了,可以直接套用。
二、OpenTelemetry GenAI 语义规范
OpenTelemetry GenAI Semantic Conventions 定义了 LLM 调用应该上报的标准字段:
| 字段 | 含义 | 示例 |
|---|---|---|
gen_ai.system | 模型厂商 | openai, anthropic, vertex_ai |
gen_ai.request.model | 实际请求的模型 | gpt-5.6, claude-opus-5 |
gen_ai.request.max_tokens | 最大输出 token | 1024 |
gen_ai.request.temperature | 温度参数 | 0.7 |
gen_ai.usage.input_tokens | 输入 token 数 | 1532 |
gen_ai.usage.output_tokens | 输出 token 数 | 482 |
gen_ai.response.model | 实际生效模型(兼容降级后) | gpt-5.6-mini |
gen_ai.response.finish_reasons | 结束原因 | stop, length, tool_calls |
只要按这套规范上报,主流 APM 系统(Datadog、New Relic、Grafana)都能直接识别并生成对应的仪表盘。
三、三种主流落地形态
3.1 完整自建(OpenTelemetry + 自己的后端)
适用:数据合规要求高、有 SRE 团队、能维护存储后端。
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
provider = TracerProvider()
processor = BatchSpanProcessor(OTLPSpanExporter(endpoint="http://collector:4317"))
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
tracer = trace.get_tracer("llm-app")
with tracer.start_as_current_span("chat_completion") as span:
span.set_attribute("gen_ai.system", "openai")
span.set_attribute("gen_ai.request.model", "gpt-5.6")
span.set_attribute("gen_ai.request.temperature", 0.7)
response = client.chat.completions.create(...)
span.set_attribute("gen_ai.usage.input_tokens", response.usage.prompt_tokens)
span.set_attribute("gen_ai.usage.output_tokens", response.usage.completion_tokens)
OTLP Collector 把数据落到 Jaeger / Tempo / ClickHouse 都可以。
3.2 用现成的可观测 SaaS(推荐起步)
| 平台 | 特点 | 价格 |
|---|---|---|
| Langfuse | 开源、可自部署、有完善 SDK | 免费 + 云端按量 |
| LangSmith | LangChain 官方出品,深度集成 LangChain/LangGraph | 免费额度 + 团队订阅 |
| Arize Phoenix | 强调评估与 drift 检测 | 开源 + 云服务 |
| Helicone | OpenAI 协议代理层,零代码接入 | 免费 + 团队套餐 |
Helicone 几乎零成本:你只需要把 base_url 从官方改成 https:// helicone.ai/openai/v1,所有请求自动被记录——不用改一行业务代码。这种"反向代理层"是上手最快的方案。
3.3 自建 + 开源面板
推荐组合:OpenTelemetry SDK 上报 → OTLP Collector → Grafana Tempo / ClickHouse → Grafana 仪表盘。
投入中等但灵活性最高,代码完全可控。
四、日志结构化:每条 LLM 调用应该记录什么
不管用哪一套体系,每次 LLM 调用至少记录以下 7 类数据:
{
"timestamp": "2026-09-03T10:23:15.123Z",
"trace_id": "abc123def456",
"span_id": "span-001",
"user_id_hash": "u_xxx",
"session_id": "s_xxx",
"request": {
"model": "gpt-5.6",
"temperature": 0.7,
"messages": [{"role": "system", "content": "..."}, {"role": "user", "content": "..."}],
"tools": [{"name": "search_docs", "description": "..."}]
},
"response": {
"model_actual": "gpt-5.6",
"finish_reason": "stop",
"content": "...",
"tool_calls": [{"name": "search_docs", "arguments": {...}}]
},
"usage": {
"input_tokens": 1532,
"output_tokens": 482,
"cost_usd": 0.0132,
"latency_ms": 1842
},
"metadata": {
"feature": "customer-support-bot",
"deployment_env": "production",
"prompt_version": "v3.2.1"
},
"feedback": {
"user_rating": null,
"thumbs": null,
"comment": null
}
}
几个关键点:
trace_id必须透传:从前端到 LLM 调用到下游工具,整个调用链共用一个 IDprompt_version一定要记:出了"答案变差"的问题,第一反应是查 Prompt 版本cost_usd自己算:不同模型的价目表经常变,别依赖第三方回填feedback字段先空着:上线后第一时间补上用户反馈采集,这是后期评测的金矿
五、追踪多轮对话与 Function Calling
LLM 应用最复杂的不是单次调用,而是 多轮对话 + 工具调用 的链路。
5.1 Span 的设计原则
- 一次
chat.completions.create= 一个 span - 一次 Function Call = 一个独立 span(与 LLM span 通过 trace_id 关联)
- 一轮多步工具调用 = 一个父 span,下面挂多个子 span
session
└── turn-1 (parent span)
├── llm-call-1 (LLM span)
├── tool-call-search (Function Call span)
│ └── external-http-call (下游 HTTP span)
└── llm-call-2 (LLM span,基于工具结果)
5.2 实战代码骨架(Python)
from opentelemetry import trace
tracer = trace.get_tracer("llm-app")
def chat_turn(user_message, history):
with tracer.start_as_current_span("chat_turn") as turn_span:
turn_span.set_attribute("session.id", session_id)
# LLM 第一次调用
with tracer.start_as_current_span("llm_call") as llm_span:
llm_span.set_attribute("gen_ai.system", "openai")
llm_span.set_attribute("gen_ai.request.model", "gpt-5.6")
response1 = client.chat.completions.create(...)
llm_span.set_attribute("gen_ai.usage.input_tokens", response1.usage.prompt_tokens)
# 处理工具调用
if response1.choices[0].message.tool_calls:
for tc in response1.choices[0].message.tool_calls:
with tracer.start_as_current_span(f"tool_{tc.function.name}") as tool_span:
tool_span.set_attribute("tool.name", tc.function.name)
tool_span.set_attribute("tool.arguments", tc.function.arguments)
result = execute_tool(tc)
tool_span.set_attribute("tool.result_size", len(str(result)))
# LLM 第二次调用(基于工具结果)
with tracer.start_as_current_span("llm_call") as llm_span2:
final = client.chat.completions.create(...)
llm_span2.set_attribute("gen_ai.usage.input_tokens", final.usage.prompt_tokens)
return final.choices[0].message.content
六、用户反馈采集:把数据闭环跑通
再多的日志,不接用户反馈也是"自嗨"。最简单也最有效的三档反馈:
| 反馈类型 | 实现难度 | 价值 |
|---|---|---|
| 👍 / 👎 | 极低 | 必备,至少能区分"明显失败"和"还不错" |
| 文字评论 | 低 | 用户主动写的反馈是金矿,做主题分析用 |
| 隐式信号(点赞、停留、转化) | 中 | 不打扰用户,但需要产品埋点 |
闭环方式:用户反馈 → 入库 → 关联到具体 trace_id → 触发离线评测 → 发现 Prompt / 模型退化 → 触发告警。
Langfuse 和 Arize Phoenix 都原生支持 trace ↔ feedback 关联。
七、成本看板:每月看一次账单不叫可观测
成本是 LLM 应用最容易被忽视的"异常指标"。建议至少监控以下维度:
| 维度 | 看板维度 | 阈值建议 |
|---|---|---|
| 每日总成本 | 按天聚合 | 与预算对比 |
| 单次调用成本 | P50 / P95 / P99 | 监控异常飙升 |
| 按模型分布 | 饼图 | 成本最高的模型占比 |
| 按功能模块 | 树状图 | 哪个产品线在烧钱 |
| 按用户 | Top 10 重度用户 | 防止误用/滥用 |
关键监控项:当某个用户的成本 24 小时环比上涨 5 倍,几乎一定有滥用、bug 循环或被攻击。
八、避坑清单:生产里最容易踩的几个坑
1. Prompt 整段打日志——注意隐私合规。记 hash 或截断版本,日志系统单独做权限隔离
2. Tool Call 参数里塞了用户敏感数据——工具调用日志要按字段脱敏
3. 不区分开发/生产环境——开发环境的"假数据"被生产日志系统抓到就会污染分析
4. 追踪系统没有采样策略——全量追踪很快把存储撑爆,建议线上 10%-20% 采样、慢请求 100% 采样
5. 反馈字段从一开始就缺——上线时没埋点,半年后想用反馈数据做评测,发现一条都拿不出来
九、推荐落地路径
如果你是从零开始,按这个顺序铺:
1. 第一周:用 Helicone 这种反向代理方案把日志和成本数据先拿到(零代码)
2. 第二周:在关键链路加上 OpenTelemetry SDK 上报,按 GenAI 语义规范填字段
3. 第二个月:接入 Langfuse 或 Arize Phoenix 做调用链可视化 + 评测
4. 第三个月:补上用户反馈埋点,搭建完整的数据闭环
需要选一个稳定的中转平台跑这些调用吗?openairouter.net 汇总了主流 AI API 中转站的模型覆盖、价格、稳定性指标和实时状态,方便你按当前成本结构挑出最合适的供应商。