当前位置:首页 > 文章列表 > 科技周边 > 人工智能 > AI OpenTelemetry 补 trace 怎样处理

AI OpenTelemetry 补 trace 怎样处理

来源:17golang原创 2026-10-22 07:00:21 0浏览 收藏

AI 应用出现“响应很慢”时,只在入口打一个 span 往往不够:你还需要把模型请求、工具调用和重试放在同一条 trace 里。最稳妥的补法是沿着现有的请求 Context 创建子 span,再用低基数的 GenAI 属性描述调用;不要把完整提示词、用户输入和模型输出默认塞进 span。

官方地址:https://opentelemetry.io/docs/

补 trace 的关键不是“每个函数都打点”,而是让入口、模型和工具保持正确的父子关系,并留下足够判断耗时、错误和重试的证据。

先把 AI 请求拆成三层边界

我在给 Agent 补观测时,最容易犯的错是只包住 SDK 的一行调用。这样能看到模型耗时,却看不出请求是在检索、工具执行还是模型重试上变慢。一个可维护的边界通常是:

  • 入口 span:代表一次用户请求或一次 Agent 调度,记录服务名、路由和请求结果。
  • 模型 span:代表一次 chat、generate_content 或 embedding 调用,记录 provider、模型名、流式开关和 token 统计。
  • 工具 span:代表一次检索、数据库查询或外部 API 调用,记录工具名、低基数结果和错误类型。
AI 请求入口、模型调用和工具调用的 OpenTelemetry 静态结构图
图1:结构说明图,查看入口、模型和工具三层 span 的静态关系;它是原创说明图,不是运行截图。

用当前 Context 补模型和工具 span

OpenTelemetry Python 的手动埋点可以用 start_as_current_span 创建当前 span。只要入口 span 已经处于当前 Context,模型和工具 span 就会自动成为子 span;异步任务或跨线程时,则要确认 Context 没有在调度边界丢失。

from opentelemetry import trace
from opentelemetry.trace import Status, StatusCode

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

def call_tool(tool_name, fn):
    # 工具 span 只记录工具身份和低基数结果,不记录完整用户数据。
    with tracer.start_as_current_span("execute_tool " + tool_name) as span:
        span.set_attribute("gen_ai.operation.name", "execute_tool")
        span.set_attribute("gen_ai.tool.name", tool_name)
        try:
            result = fn()
            span.set_attribute("tool.result", "ok")
            return result
        except Exception as exc:
            # 把错误类型写入 span,正文或敏感参数留在受控日志中。
            span.record_exception(exc)
            span.set_status(Status(StatusCode.ERROR, "tool failed"))
            span.set_attribute("error.type", type(exc).__name__)
            raise

def call_model(client, model, messages):
    # 模型 span 继承当前 Context,自动挂到入口或 Agent span 下。
    with tracer.start_as_current_span("chat " + model) as span:
        span.set_attribute("gen_ai.operation.name", "chat")
        span.set_attribute("gen_ai.provider.name", "configured-provider")
        span.set_attribute("gen_ai.request.model", model)
        span.set_attribute("gen_ai.request.stream", False)
        try:
            response = client.chat(messages)
            usage = getattr(response, "usage", None)
            if usage is not None:
                # token 数适合用于聚合;不要把 prompt 原文当作属性。
                span.set_attribute("gen_ai.usage.input_tokens", usage.input_tokens)
                span.set_attribute("gen_ai.usage.output_tokens", usage.output_tokens)
            return response
        except Exception as exc:
            span.record_exception(exc)
            span.set_status(Status(StatusCode.ERROR, "model failed"))
            span.set_attribute("error.type", type(exc).__name__)
            raise

这段代码只展示补 trace 的边界,client.chat 和工具函数仍由业务实现。模型调用若由已有自动 instrumentation 产生 span,应先确认是否已经有重复的模型 span,再决定只补 Agent/工具层,避免一条调用出现两套难以区分的记录。

属性要少而稳定,内容采集要显式开启

OpenTelemetry 的语义约定提供了统一的 gen_ai.operation.name、gen_ai.provider.name 和 gen_ai.request.model 等字段。它们适合检索和聚合;用户问题、系统提示词、完整工具参数则可能含有个人信息或业务机密,应当默认关闭,或先做截断、脱敏和采样。

建议把下面几类信息分开处理:

信息建议用途
模型名、provider、operation默认记录按调用类型和模型聚合耗时
输入/输出 token有返回值才记录分析成本和上下文膨胀
错误类型、异常事件记录低基数类型,限制堆栈范围区分超时、鉴权和服务端错误
提示词、输出、工具参数显式开关后再脱敏采集只在确有排障需要时关联内容
AI trace 中模型属性、token 统计、工具错误和内容采集边界的静态结构图
图2:结构说明图,查看哪些属性适合聚合、哪些内容需要显式控制;它不是观测平台截图。

用 span 证据反向确认到底补对没有

不要只看“有没有 trace”。打开一条慢请求后,先确认入口 span 是根节点,模型和工具是否挂在它下面;再比较各子 span 的时长。如果模型 span 很短而工具 span 很长,问题不在模型;如果同一工具出现多个连续子 span,优先检查重试或循环;如果模型属性存在但没有父节点,通常是异步调度时 Context 没有传过去。

导出端可以使用 OTLP Collector 或已有后端。开发期先用控制台 exporter 看父子关系,生产再通过采样、脱敏和数据保留策略控制成本。确认时至少保留三条证据:trace ID 能贯穿入口到子 span、模型 span 有稳定的 operation/model 属性、失败调用带有 error.type 和异常事件。

常见问题

只给模型调用加 span,为什么还是看不出 Agent 慢在哪里?

因为检索、工具和重试没有独立边界。模型 span 只能回答一次模型调用花了多久,不能解释它之前或之后的业务耗时。

要不要把完整 prompt 写进 trace?

默认不要。先用 token 数、消息数量、模板版本和脱敏后的摘要满足排障;只有在明确的合规范围内开启内容采集,并设置截断、访问控制和保留期限。

最终可以把补 trace 的判断浓缩成一句话:先保证 Context 关系正确,再补低基数 GenAI 属性,最后用 span 时长和错误证据反向定位。这样既能看见 AI 请求的关键链路,也不会把可观测性变成敏感内容的另一个存储点。

版本声明
本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
AI vLLM 限制显存 怎样处理AI vLLM 限制显存 怎样处理
上一篇
AI vLLM 限制显存 怎样处理
AI JSON Schema 约束输出 怎样处理
下一篇
AI JSON Schema 约束输出 怎样处理
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • PubMedQA数据集详解:生物医学问答基准、功能与应用指南
    PubMedQA
    深入了解PubMedQA生物医学问答数据集,涵盖其核心功能、使用方法及在临床决策、药物研发等场景的应用,助力提升NLP模型性能。
    586次使用
  • H2O EvalGPT:开源LLM大模型评估与排行榜工具
    H2O EvalGPT
    H2O EvalGPT是H2O.ai推出的开源LLM评估平台,提供详细的大模型性能排行榜、行业特定基准测试及A/B测试功能,助您快速选择最适合项目的高性能大语言模型。
    622次使用
  • LMArena是什么?伯克利AI模型评估平台使用指南与功能解析
    LMArena
    LMArena是加州大学伯克利分校推出的AI模型匿名评测平台。通过盲测投票机制,用户可对比不同大模型回答并生成实时排行榜,助力开发者优化模型及用户选择最佳AI工具。
    656次使用
  • 斯坦福HELM:大语言模型Holistic Evaluation整体评估框架详解
    HELM
    深入了解斯坦福推出的HELM(Holistic Evaluation of Language Models)大模型评测体系。本文解析其核心功能、安装配置步骤及应用场景,涵盖准确性、公平性、鲁棒性等多维度指标,助力开发者全面优化语言模型性能。
    622次使用
  • MMBench详解:多模态大模型基准测试、功能特点与使用指南
    MMBench
    MMBench是由上海人工智能实验室等机构联合推出的多模态基准测试平台,提供细粒度能力评估、大规模数据集及VLMEvalKit工具。本文详细介绍其核心功能、安装使用方法及应用场景,助力开发者全面评估多模态模型性能。
    438次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议 和 隐私政策
返回登录
  • 重置密码