云原生观测性怎样覆盖模型服务延迟和成本
来源:17golang原创
时间:2026-11-07 23:51:32 426浏览 收藏
云原生模型服务的“慢”和“贵”通常不是一个组件单独造成的:请求可能先在网关排队,再等待模型首 token,生成过程中还会触发工具调用或重试。如果只有 Kubernetes CPU、GPU 和接口总耗时,团队很难回答“慢在哪里、贵在哪个模型、哪类业务最值得优化”。
更实用的迁移方式,是把传统的服务观测扩展成一条可关联的模型调用链:用 trace 解释一次请求的时间,用 GenAI 语义字段记录模型与 token,用指标聚合延迟分位数和成本估算。OpenTelemetry 是这类跨后端采集的一个中立参考,但它本身不是存储或可视化后端。
官方地址:https://opentelemetry.io/
CNCF 公告:https://www.cncf.io/announcements/2026/05/21/cloud-native-computing-foundation-announces-opentelemetrys-graduation-solidifying-status-as-the-de-facto-observability-standard/
先统一请求、模型调用、工具调用和资源上下文的关联键,再谈延迟与成本。延迟看 trace 的时间分解,成本看 token、模型和价格快照;两者都要保留业务切片,但不要把完整提示词当作默认指标标签。

一、先把传统观测迁移到模型调用边界
传统 HTTP 服务往往把一次请求看成一个接口 span;模型服务则至少需要多一层“模型调用 span”。外层记录入口、租户、路由和总耗时,内层记录具体模型、模型版本、输入输出 token、结束原因以及工具调用关系。这样既能从业务请求下钻到模型调用,也能从模型调用回看资源和版本。
边界可以按下面的变更表落地:
| 观测对象 | 旧做法容易遗漏什么 | 迁移后的最小字段 | 主要用途 |
|---|---|---|---|
| 用户请求 | 只记录接口总耗时 | trace_id、路由、租户、业务场景 | 定位端到端延迟与成本归属 |
| 模型调用 | 只在日志里写模型名 | 模型、版本、输入 token、输出 token | 比较模型延迟、用量和估算成本 |
| 工具调用 | 被算进模型耗时 | 工具名称、调用 span、错误状态 | 区分模型等待与外部依赖等待 |
| 运行资源 | 只看节点或 GPU 总量 | 服务、命名空间、Pod、区域、资源池 | 观察资源上下文与业务切片 |
这不是要求所有团队一次性改造完。最小可用边界是:同一条 trace 能把入口请求和至少一次模型调用连起来;随后再补齐工具、队列和资源属性。
二、用 trace 拆开“模型服务很慢”
总延迟只能告诉你用户等了多久,不能告诉你等待发生在哪个阶段。可以把一次请求拆成入口、排队、模型调用、工具调用和输出编码等 span;模型调用内部再记录首 token 时间、生成时长和重试次数。不要把每个 token 设计成一个 span,否则遥测量会随输出长度快速膨胀。
# 用统一属性把模型调用与外层请求放在同一条关联链上 resource: service.name: "model-gateway" deployment.environment: "production" attributes: gen_ai.request.model: "模型标识" gen_ai.response.model: "实际响应模型" gen_ai.usage.input_tokens: "输入 token 数" gen_ai.usage.output_tokens: "输出 token 数" gen_ai.response.finish_reasons: "结束原因" app.tenant: "租户或业务分组" # 提示词和生成内容默认不写入指标标签,避免高基数与敏感数据扩散
上面的字段是语义设计示例,不是某个供应商的完整配置文件。关键点有三个:模型标识要能区分路由前后的实际模型;输入输出 token 要落在调用事实上;租户或业务分组要使用稳定、低基数的枚举值。
如果总耗时上升,先看 trace 中哪一段的 p95 或 p99 发生变化:
- 排队 span 变长,优先检查并发上限、批处理和资源调度。
- 首 token 变慢而生成时长稳定,优先检查模型冷启动、队列或上游网络。
- 工具调用变慢,模型本身未必是根因,应单独查看工具依赖的 trace。
- 重试 span 增多时,要把重试次数和失败原因与模型调用关联,避免把重试后的总耗时误认为单次推理耗时。
三、把 GenAI 字段当作调用事实,而不是宣传指标
OpenTelemetry 的 GenAI 观测实践把模型、输入输出 token 和结束原因放在可关联的 trace 与 metric 里,这比在一行自由文本日志中拼接“模型=某某、耗时=某某”更容易聚合。对于模型服务,建议把字段分成三层:
- 调用事实:模型标识、调用类型、输入 token、输出 token、结束原因和错误状态。
- 链路上下文:trace_id、span_id、服务版本、部署环境、区域和资源池。
- 业务切片:租户、产品线、请求类型或成本中心,控制在有限枚举范围。
提示词、回答内容、工具参数可能帮助排查质量问题,但它们可能包含个人信息、业务机密或高容量文本,不应该默认进入所有 trace、日志和指标。需要内容调试时,可以采用显式开关、短期保留、脱敏和访问控制,并把它与基础延迟面板分开。
四、用 token 和价格快照估算请求成本
模型成本可以先做“可解释估算”,不必假装等同于最终账单。最小公式是:
# 输入和输出单价按统一计费单位保存,例如每百万 token
请求成本 = 输入 token / 计费单位 × 输入单价
+ 输出 token / 计费单位 × 输出单价
# 若存在缓存、批处理、工具或 GPU 自托管费用,应作为独立项记录
价格快照要和模型标识、区域、计费时间或价格版本一起保存。不要直接把“当前价格”写死在应用代码中,因为路由层可能把同一个逻辑模型切换到不同版本或区域。请求成本可以写入 span 的数值属性,也可以在采集层转换成指标;但模型名、租户和业务场景才适合作为有限维度。

一个面向指标系统的字段示例可以保持简洁:
# 只保留可聚合的低基数维度,避免把完整请求内容打进指标 metric: model_request_cost_estimated labels: model: "模型标识" region: "区域" tenant_group: "租户分组" workload: "业务场景" values: input_tokens: 0 output_tokens: 0 estimated_cost: 0 price_snapshot: "价格版本" # 账单对账仍以供应商或内部计费系统为准,不用估算指标替代财务数据
五、从旧方案迁移时要做哪些回归检查
迁移完成后,不要只看面板是否有线。可以用一组小而明确的回归检查判断观测方案是否真的覆盖了标题中的两个问题:
| 检查项 | 通过标准 | 不通过时先查什么 |
|---|---|---|
| 链路关联 | 一个请求可以找到对应模型调用和工具调用 | 上下文传播、异步任务和重试是否复用了错误的 span |
| 延迟拆分 | 总耗时可以拆成排队、模型、工具和重试等阶段 | span 边界是否把多个等待阶段合并了 |
| 模型区分 | 路由模型与实际响应模型都可查询 | 网关重写模型名或版本信息是否丢失 |
| 成本解释 | token、价格快照和估算值能回到同一次调用 | 计费单位、缓存命中和价格版本是否一致 |
| 隐私控制 | 默认不采集完整提示词和回答内容 | 日志、trace、采集器处理器是否有重复采集 |
采样策略也要单独记录。错误、超时、成本异常或延迟异常的 trace 可以提高保留概率;正常请求可以按比例采样。指标则应持续保留低基数汇总,避免用“把所有 trace 永久保存”来弥补字段设计不足。
迁移清单:先做到可解释,再追求完整
- 为外层请求、模型调用和工具调用建立父子关系或明确的关联键。
- 至少记录实际模型、模型版本、输入 token、输出 token、错误状态和结束原因。
- 用 trace 看延迟分解,用 metric 看分位数、用量和按业务切片的估算成本。
- 把价格快照视为估算依据,把最终账单留给计费系统对账。
- 默认关闭完整提示词和回答采集,必要时采用脱敏、短期保留和访问控制。
- 用异常 trace、低基数指标和资源上下文联合判断模型、平台或业务哪一层需要优化。
常见问题
只采集 Prometheus 指标,能不能定位模型慢?
可以发现分位数变化,但很难解释一次请求内部的等待来源。至少需要把入口与模型调用关联起来,再用 trace 拆分关键阶段。
成本估算为什么不能直接当账单?
估算通常只覆盖 token 单价,实际账单还可能包含缓存、批处理、区域、套餐、工具或自托管资源等项目。因此它适合趋势和责任归属,不替代计费对账。
是否应该把完整提示词放进 trace?
不建议默认这样做。完整内容会增加容量、隐私和访问控制风险;只有在明确授权的调试场景中,才考虑脱敏、短期保留和最小访问范围。
参考资料
OpenTelemetry 文档:https://opentelemetry.io/docs/
OpenTelemetry 信号说明:https://opentelemetry.io/docs/concepts/signals/
OpenTelemetry GenAI 观测实践:https://opentelemetry.io/blog/2026/genai-observability/
CNCF 云原生 AI 工程文章:https://www.cncf.io/blog/2026/03/26/the-platform-under-the-model-how-cloud-native-powers-ai-engineering-in-production/
-
214 收藏
-
143 收藏
-
147 收藏
-
228 收藏
-
500 收藏
-
377 收藏
-
123 收藏
-
444 收藏
-
279 收藏
-
196 收藏
-
336 收藏
-
332 收藏
-
179 收藏
-
228 收藏
-
170 收藏
-
469 收藏
-
372 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 543次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 516次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 500次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 485次学习