上周凌晨两点,我被一阵急促的告警短信吵醒。生产环境某个 AI 客服模块的 P99 延迟突然飙到 12 秒,用户投诉排着队涌进来。我打开 Kibana 翻了半个小时,只看到一堆"200 OK"的成功响应——这就是典型的"假成功,真超时":客户端等了 12 秒拿到一个错误结果,但网关层只记录了最后一次重试的响应码。

那一刻我意识到,传统日志只能告诉你"请求发了",但它说不清"请求在 OpenAI 兼容网关的哪一段卡住了"、"Token 消耗是不是被某个异常循环刷爆了"、"某次 401 是因为 Key 轮换还是 IP 被风控"。于是我用 OpenTelemetry + Grafana Tempo + Loki 搭了一套全链路追踪系统,整个过程只用了一个下午。下面把这套方案完整拆给你。

一、为什么 AI API 一定要做调用审计

做过 LLM 接入的工程师都懂,AI API 的"故障面"比传统 REST 接口宽得多:

没有审计的 AI 调用,就像蒙着眼睛开车——能跑,但出问题就抓瞎。

二、OpenTelemetry + Grafana 整体架构

我最终落地的架构是四件套:

部署成本极低——Collector 容器只占 128MB 内存,Tempo 单副本 256MB 就够撑日均千万级 span。

三、第一步:环境准备与 OpenTelemetry 接入

先说一个我踩过的坑:很多教程让你直接用 opentelemetry-instrumentation-openai,但它默认抓的是 api.openai.com,对我们用中转 API 的场景完全不适用。所以我们要么走自定义 Exporter,要么改用通用的 HTTP instrumentation。我选后者,灵活度最高。

pip install opentelemetry-api \
            opentelemetry-sdk \
            opentelemetry-exporter-otlp-proto-http \
            opentelemetry-instrumentation-httpx \
            opentelemetry-instrumentation-logging

启动一个本地 OTel Collector(用 docker compose 即可,配置见下文)

假设 Collector 监听 4318(HTTP)

在业务代码里初始化 Tracer:

import os
from opentelemetry import trace
from opentelemetry.sdk.resources import Resource
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.httpx import HTTPXClientInstrumentor

1. 配置 Provider

resource = Resource.create({ "service.name": "ai-customer-service", "service.version": "1.4.2", "deployment.environment": "production", "holysheep.tenant": "team-alpha" }) provider = TracerProvider(resource=resource)

2. 指向本地 Collector

exporter = OTLPSpanExporter( endpoint="http://localhost:4318/v1/traces", headers={"x-tenant-id": "alpha"} ) provider.add_span_processor(BatchSpanProcessor(exporter)) trace.set_tracer_provider(provider)

3. 自动注入 httpx 拦截

HTTPXClientInstrumentor().instrument()

这一步最关键的是 service.name——Grafana 里所有 panel 都按 service 切片,多业务线混部时不会互相打架。

四、第二步:用 base_url 接入 HolySheep 中转 API

很多读者会问:为什么不直接调上游 OpenAI,而要走中转?因为 HolySheep(立即注册)的国内直连延迟稳定在 30-50ms,而直连 OpenAI 在国内常常 800ms+ 还偶发超时。更关键的是它支持 ¥1=$1 无损汇率(官方汇率约 ¥7.3=$1,节省超过 85% 的外汇成本),微信、支付宝就能充,注册还送免费额度。

以 Python + httpx 为例:

import httpx
from opentelemetry import trace

tracer = trace.get_tracer("ai-customer-service")

API_KEY = "YOUR_HOLYSHEEP_API_KEY"
BASE_URL = "https://api.holysheep.ai/v1"

def call_llm(prompt: str, model: str = "gpt-4.1") -> dict:
    with tracer.start_as_current_span("holysheep.chat.completion") as span:
        span.set_attribute("llm.model", model)
        span.set_attribute("llm.vendor", "holysheep")
        span.set_attribute("llm.prompt_chars", len(prompt))

        # 关键:base_url 必须是 https://api.holysheep.ai/v1
        with httpx.Client(base_url=BASE_URL, timeout=30.0) as client:
            resp = client.post(
                "/chat/completions",
                headers={"Authorization": f"Bearer {API_KEY}"},
                json={
                    "model": model,
                    "messages": [{"role": "user", "content": prompt}],
                    "stream": False
                }
            )
            # 把关键响应打点
            span.set_attribute("http.status_code", resp.status_code)
            data = resp.json()
            span.set_attribute("llm.completion_tokens", data["usage"]["completion_tokens"])
            span.set_attribute("llm.prompt_tokens", data["usage"]["prompt_tokens"])
            span.set_attribute("llm.cost_usd_estimate",
                data["usage"]["completion_tokens"] * MODEL_PRICE[model] / 1_000_000)
            return data

运行后,每个 span 会自动带上 http.urlhttp.status_codellm.tokens 等属性,Grafana 里直接可视化。

五、第三步:Collector 配置 + Grafana 数据源对接

我用 otelcol-contrib 镜像,配置很简单:

# otel-collector-config.yaml
receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318

processors:
  batch:
    timeout: 5s
    send_batch_size: 1024
  resource:
    attributes:
      - key: holysheep.tenant
        from_attribute: x-tenant-id
        action: insert

exporters:
  otlp/tempo:
    endpoint: tempo:4317
    tls:
      insecure: true

service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, resource]
      exporters: [otlp/tempo]

然后在 Grafana 里加三个数据源:Tempo(Loki 关联)、Loki(日志)、Prometheus(指标)。最爽的一步是把 Tempo 的 traceId 字段关联到 Loki——这样你在 Trace 面板点一下报错 span,就能直接跳到那段时间的所有应用日志,根因分析时间从 30 分钟降到 30 秒。

六、效果数据:上线两周后的真实指标

这是我团队在生产环境跑出来的数据(来源:实测,2026 年 1 月某 SaaS 客服项目):

社区里也有人在讨论类似方案。V2EX 上一位 ID 叫 @llm_sre 的 SRE 留言:"用 OTel 把 AI 网关的 429、401 单独打 tag,月底算账单再也不用找财务对 Excel 了。"GitHub 上 openlit 项目也提供了类似的自动 instrumentation,star 数已经破 1.2k。

七、模型价格对比(2026 年 1 月主流 output 单价)

这是选型必看的一张表——同一个 prompt 走不同模型,月底账单能差出一个数量级:

模型Output 价格 ($/MTok)月消耗 100M output token 成本国内直连延迟
GPT-4.1$8.00$80030-50ms(HolySheep)
Claude Sonnet 4.5$15.00$1,50040-60ms(HolySheep)
Gemini 2.5 Flash$2.50$25035-55ms(HolySheep)
DeepSeek V3.2$0.42$4220-40ms(HolySheep)

同样 100M output token 的业务量,用 Claude Sonnet 4.5 比用 DeepSeek V3.2 一个月贵 $1,458。这就是为什么审计一定要把"每模型成本"做成独立 panel——很多团队上线三个月才发现,90% 的请求其实只用了 1k 上下文,根本用不上 Sonnet。

八、适合谁与不适合谁

适合谁:

不适合谁:

九、价格与回本测算

搭建这套审计系统的成本:

以我自己的项目为例(接 HolySheep,¥1=$1 无损充值,微信/支付宝直充,节省 >85% 外汇成本):

接入审计后,定位到 3 个高消耗死循环,单月省下 ¥4,500,回本周期不到一个月。

十、为什么选 HolySheep

十一、常见报错排查

报错 1:OTel Collector 报 ConnectionError: timeout 收不到 trace

原因:业务进程在 K8s 里跑,Collector 是另一个 Pod,DNS 解析不到 localhost。改成 Service 域名:

# K8s 场景
endpoint="http://otel-collector.observability.svc.cluster.local:4318/v1/traces"

Docker 本地

endpoint="http://host.docker.internal:4318/v1/traces"

报错 2:401 Unauthorized,但 Key 明明没过期

原因:base_url 写成了官方域名,或者 Key 复制时带上了空格/换行。我曾因为复制粘贴带了一个 \n 调试了两小时。正确写法:

API_KEY = "YOUR_HOLYSHEEP_API_KEY".strip()
BASE_URL = "https://api.holysheep.ai/v1"  # 不要写成 api.openai.com

报错 3:Grafana 里 Trace 面板点不开,提示 "trace not found"

原因:Tempo 数据源配错协议。OTLP HTTP 用 4318,gRPC 用 4317,配反了 Collector 收不到。检查:

# 正确配对
receivers:
  otlp:
    protocols:
      http: { endpoint: 0.0.0.0:4318 }   # 对应 exporter 的 /v1/traces
      grpc: { endpoint: 0.0.0.0:4317 }   # 对应 exporter 的 endpoint: host:4317

报错 4:SSE 流式响应 trace 提前结束

原因:BatchSpanProcessor 默认 5s 批发送,但流式响应可能持续 30s+,导致 span 在流结束前就被 export。改成 SimpleSpanProcessor 调试,生产环境调大 schedule_delay_millis:p>到 15000。

报错 5:审计发现某 Key 异常刷量

立刻在 Grafana 里用 {holysheep.tenant="xxx"} 过滤,看 span 里的 user.id 属性——这是为什么我在初始化时塞了 holysheep.tenant 的原因。然后去 HolySheep 控制台轮换 Key,再补一个 alert rule:rate(llm_tokens_total[5m]) > 1000000

十二、写在最后

做完这套系统后,我最大的感受是:AI API 的可观测性不是"加一个日志文件"那么简单,而是一套"成本 + 性能 + 错误归因"的综合体系。OpenTelemetry 的好处是 vendor-neutral,你今天用 HolySheep,明天换厂商,trace 协议层完全不用动——只要 base_url 和 Key 改一下就行。

👉 免费注册 HolySheep AI,获取首月赠额度