ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

DeepEval 裸 OpenTelemetry 导出指南:用 OTLP/HTTP 与 confident.* 属性将 AI 应用 Trace 接入 Confident AI Observatory

DeepEval 裸 OpenTelemetry 导出指南:用 OTLP/HTTP 与 confident.* 属性将 AI 应用 Trace 接入 Confident AI Observatory DeepEval 裸 OpenTelemetry 导出指南用 OTLP/HTTP 与 confident.* 属性将 AI 应用 Trace 接入 Confident AI Observatory【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepevalDeepEval 提供了一条不依赖deepevalPython 包本身的观测通道任何语言的 OpenTelemetry SDK 只要把 OTLP/HTTP exporter 指向 Confident AI 的 OTLP endpoint、并在 span 上设置confident.*属性trace 就会落入 Confident AI 的 Observatory。本文基于仓库内的 Agent Skill 文档docs/public/.well-known/agent-skills/deepeval-otel/SKILL.md及其 references、templates完整讲清这套接入契约两个区域 endpoint 的选择规则、认证方式、Python 可运行模板、confident.trace.*/confident.span.*全量属性表、OTLP 数据类型规则、gen_ai.*语义约定回退行为以及如何在混有 APM/自动插桩的生产进程中只导出 AI span。Skill 定位与适用范围该文档在仓库中作为面向 AI Agent 的技能说明Agent Skill发布主入口是 SKILL.md仓库内另有一份同源副本位于 skills/deepeval-otel/。它回答的问题很具体把 AI 应用LLM 应用、Agent、RAG 管线、聊天机器人的原始 OpenTelemetry trace 导出到 Confident AI Observatory不需要安装deepeval包机制就是“OTLP 属性键 exporter endpoint”。文档明确划定了两条边界只插桩 AI 组件。confident.*属性与 span 类型agent、llm、retriever、tool描述的都是 AI 组件Observatory 也是为评估和监控 AI 行为而建。只应对 agent 循环与规划、LLM 调用、检索/向量搜索、工具调用打点不要把confident.*属性加到 Web 服务器、CRUD 后端、数据库层或基础设施 span 上——这些数据的呈现没有意义。如果目标应用没有 LLM、agent、检索或工具调用该方案不适用。与deepeval主技能互补而非替代。构建 Python pytest 评测套件、生成数据集/goldens、编写 metrics、运行deepeval test run或基于 DeepEval SDK 的observe装饰器与框架集成做插桩属于另一个技能deepeval/deepeval-tracing的职责本文讲的厂商中立 OTLP 导出与它们是叠加关系。前置条件一个 Confident AI 账号和CONFIDENT_API_KEY。应用语言对应的 OpenTelemetry SDK。Python 场景需要opentelemetry-sdk与opentelemetry-exporter-otlp-proto-http两个包后者提供 HTTP 协议 exporter。传输层限制Confident AI 的 OTLP endpoint 只接受 HTTP不接受 gRPC。这条规则在文档的多个位置被重复强调也是最容易踩的坑。工作原理Confident AI 暴露一个 OTLP/HTTP traces endpoint。把任何 OpenTelemetry span exporter 指向它并在每个请求上带x-confident-api-key头即可服务端 exporter 随后读取每个 span 上的confident.*属性来构建 trace 和 span 结构。两个关键设计决定值得注意父子嵌套来自原生 OTel span context而不是任何confident.*属性。在tracer.start_as_current_span(...)的with块内开启的子 span 会自动嵌套到父 span 之下不需要也不存在“confident 父子属性”。confident.*属性键就是完整契约所有语言、所有 SDK 下完全一致——因此语言选型对接入方式没有影响只有类和包名不同。Endpoint 选择与认证两个区域 endpointendpoint-and-exporter.md 给出的完整端点表如下RegionBase endpointTraces 实际 POST 地址Default (US/AU)https://otel.confident-ai.comhttps://otel.confident-ai.com/v1/tracesEUhttps://eu.otel.confident-ai.comhttps://eu.otel.confident-ai.com/v1/traces一个容易混淆的细节直接配置 OTLP/HTTP exporter 时endpoint值必须包含/v1/traces后缀而通过标准环境变量OTEL_EXPORTER_OTLP_ENDPOINT配置时只填 base endpointSDK 会自行追加/v1/traces。仓库源码印证了这一点。DeepEval 自身的 OTel 集成中settings.py 定义了CONFIDENT_OTEL_URL默认值为https://otel.confident-ai.com而 pydantic_ai/otel.py 中拼接最终地址的方式正是OTLP_ENDPOINT str(settings.CONFIDENT_OTEL_URL) v1/traces按 API key 前缀选择 endpointConfident AI 的 API key 带区域前缀按下表选择API key 前缀Endpointconfident_eu_…https://eu.otel.confident-ai.comconfident_us_…https://otel.confident-ai.com其他https://otel.confident-ai.com只有confident_eu_…走 EU endpoint拿不准时询问项目所属区域或使用默认 endpoint。认证与传输每个请求必须在 HTTP 头中携带 API keyx-confident-api-key: CONFIDENT_API_KEYkey 从CONFIDENT_API_KEY环境变量读取不要硬编码进源码。关于传输层的硬性要求Python使用opentelemetry.exporter.otlp.proto.http.trace_exporter中的OTLPSpanExporter包opentelemetry-exporter-otlp-proto-http不要用opentelemetry.exporter.otlp.proto.grpc变体。OpenTelemetry Collector使用otlphttpexporter而不是otlpgRPC。其他语言 SDK选 OTLP/HTTP exporterproto-http、HttpProtobuf或语言等价物。标准 OTel 环境变量由于 exporter 遵循标准 OpenTelemetry 环境变量可以不改代码完成配置export OTEL_EXPORTER_OTLP_ENDPOINThttps://otel.confident-ai.com export OTEL_EXPORTER_OTLP_HEADERSx-confident-api-keyCONFIDENT_API_KEY注意这里给的是 base endpoint/v1/traces由 SDK 自动追加。Python exporter 接线最小接线路径四步创建TracerProvider挂一个BatchSpanProcessor包裹指向endpoint/v1/traces并带x-confident-api-key头的 OTLP/HTTPOTLPSpanExporter把 provider 注册为全局 tracer provider获取 tracer、开启 span、设置confident.*属性。核心片段import os from opentelemetry import trace from opentelemetry.sdk.trace import TracerProvider from opentelemetry.sdk.trace.export import BatchSpanProcessor from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter api_key os.environ[CONFIDENT_API_KEY] endpoint ( https://eu.otel.confident-ai.com if api_key.startswith(confident_eu_) else https://otel.confident-ai.com ) provider TracerProvider() provider.add_span_processor( BatchSpanProcessor( OTLPSpanExporter( endpointf{endpoint}/v1/traces, headers{x-confident-api-key: api_key}, ) ) ) trace.set_tracer_provider(provider) tracer trace.get_tracer(__name__) with tracer.start_as_current_span(my-llm-app) as span: span.set_attribute(confident.span.type, agent) span.set_attribute(confident.trace.name, my-llm-app)完整可运行版本见 confident_otel_setup.py。该模板额外演示了用pick_endpoint(api_key)按前缀选区域缺CONFIDENT_API_KEY时直接SystemExit并提示如何 export一条“agent 根 span 包裹 llm 子 span”的示例 trace字符串列表用原生 OTLP 数组、dict 用json.dumps异常时用原生Status(StatusCode.ERROR)record_exception标记错误以及进程退出前调用trace.get_tracer_provider().shutdown()让 batch processor 完成 flush。直接运行python confident_otel_setup.py即可作为连接冒烟测试——当然模板中的示例属性值属于占位上生产前必须替换为真实应用数据。其他语言的接线方式接线形态在任何 OpenTelemetry SDK 中都相同差异仅在类名和包名构造 OTLP/HTTP span exporter把endpoint/url设为region endpoint/v1/traces添加x-confident-api-key头把它注册到 tracer provider 的 batch span processor 上。之后照常发 span、按 trace-attributes.md 和 span-attributes.md 设置confident.*属性即可。仓库内 DeepEval TypeScript SDK 对 Vercel AI SDK 的集成typescript/src/integrations/ai-sdk/index.ts就是一个现成的非 Python 参考实现其中的DeepEvalExporterWrapper与DeepEvalBatchFilterProcessor见下文“只导出 AI span”一节展示了 exporter 包装与 span 过滤的具体写法。Trace 级属性confident.trace.*Trace 级属性描述整条 trace而非单个 span。设置方式是把它作为confident.trace.*属性写到 trace 内任意span 上——最自然的位置是根 spanConfident AI 会将其聚合到 trace 层级。完整属性表属性键类型说明confident.trace.namestring人类可读的 trace 名confident.trace.inputstringtrace 输入。透传非字符串先 JSON 编码confident.trace.outputstringtrace 输出。透传非字符串先 JSON 编码confident.trace.user_idstring终端用户/客户标识confident.trace.thread_idstring会话/线程标识confident.trace.tagslist of strings分组标签。原生 OTLP 字符串数组或 JSON 数组字符串confident.trace.metadataJSON string任意键值上下文。必须是 JSON 编码的对象字符串OTLP 没有 map 类型confident.trace.environmentstring部署环境默认production见下文环境解析confident.trace.retrieval_contextlist of strings检索到的 chunk/文档。原生 OTLP 字符串数组或 JSON 数组字符串confident.trace.contextlist of strings该 trace 的 ground-truth 上下文。原生 OTLP 字符串数组或 JSON 数组字符串confident.trace.tools_calledlist of stringstrace 中调用过的工具。原生 OTLP 列表每个元素是 JSON 序列化的ToolCallconfident.trace.expected_toolslist of strings本应调用的工具。原生 OTLP 的 JSON 序列化ToolCall字符串列表confident.trace.test_case_idstring测试用例 ID 引用confident.trace.turn_idstring多轮对话的轮次标识confident.trace.metric_collectionstring指定一个 Confident AI 指标集用于对该 trace 运行在线服务端评测所有属性都是可选的只设置有意义的字段即可。环境解析environment 的两处设置点confident.trace.environment接受部署环境字符串常见取值production、staging、development、testing默认production。它可以在两个位置设置且Resource 属性优先于 span 属性作为 span 属性confident.trace.environment作为 OpenTelemetryResource属性写到TracerProvider的Resource上——这是推荐方式一次为整个进程盖章。Span 级属性confident.span.*Span 级属性描述单个 span。confident.span.type决定哪些按类型划分的键有效应首先设置它。合法取值恰为llm、tool、agent、retriever和通用base五种且同样只应用于 AI 组件不要用于 HTTP handler、数据库查询等 span。通用属性所有 span 类型有效属性键类型说明confident.span.typestringllm/tool/agent/retriever/base之一。缺省时从gen_ai.*推断见下文回退表confident.span.namestring展示名覆盖原生 OTel span 名confident.span.inputstringspan 输入。透传非字符串先 JSON 编码confident.span.outputstringspan 输出。透传非字符串先 JSON 编码confident.span.metadataJSON string有助于诊断故障的组件事实。必须是 JSON 编码的对象字符串confident.span.contextlist of strings该 span 的 ground-truth 上下文confident.span.retrieval_contextlist of strings该 span 检索到的 chunkconfident.span.tools_calledlist of strings原生 OTLP 列表每个元素是 JSON 序列化的ToolCall字符串confident.span.expected_toolslist of strings原生 OTLP 列表每个元素是 JSON 序列化的ToolCall字符串confident.span.metric_collectionstring指定一个 Confident AI 指标集对该 span 运行在线服务端评测LLM spanconfident.span.type llm属性键类型说明confident.llm.modelstring模型名如gpt-4o。回退gen_ai.request.modelconfident.span.providerstringLLM 供应商如openai、anthropic。可选——缺省时从模型名推断confident.llm.input_token_countint输入/prompt token 数。回退gen_ai.usage.input_tokensconfident.llm.output_token_countint输出/completion token 数。回退gen_ai.usage.output_tokensconfident.llm.cost_per_input_tokenfloat每输入 token 成本用于成本汇总confident.llm.cost_per_output_tokenfloat每输出 token 成本用于成本汇总若 span 引用的是在 Confident AI 中管理的 prompt可设置离散的 prompt 字段只设置适用的confident.span.prompt_alias别名/名称、confident.span.prompt_version版本标识、confident.span.prompt_commit_hashcommit hash、confident.span.prompt_label标签。Agent spanconfident.span.type agent属性键类型说明confident.agent.namestringagent 名称/标识confident.agent.available_toolslist of strings该 agent 可用的工具confident.agent.agent_handoffslist of strings可交接的其他 agentRetriever spanconfident.span.type retriever属性键类型说明confident.retriever.embedderstring嵌入模型名如text-embedding-3-smallconfident.retriever.top_kint检索到的结果数量confident.retriever.chunk_sizeint文档 chunk 大小检索到的 chunk 放到confident.span.retrieval_context。Tool spanconfident.span.type tool属性键类型说明confident.tool.namestring工具/函数名。回退gen_ai.tool.nameconfident.tool.descriptionstring人类可读的工具描述工具参数放confident.span.input工具结果放confident.span.output。OTLP 数据类型规则OpenTelemetry 属性值只能是原始类型string、bool、int、float或原始类型的同构列表不存在 map/object 属性类型。编码规则对象/dictconfident.span.metadata、confident.trace.metadata必须是JSON 编码字符串——json.dumps(...)。字符串列表tags、context、retrieval_context、available_tools、agent_handoffs可以是原生 OTLP 字符串数组Python 中的str列表/元组JSON 数组字符串也被接受。ToolCall列表tools_called、expected_tools必须是原生 OTLP 列表其中每个元素是一个 JSON 序列化的ToolCall字符串——即“JSON 字符串的列表”而不是“一个列表的 JSON 字符串”。input/output是透传。若值不是字符串先 JSON 编码再设置。数字top_k、chunk_size、token 数、成本用原生 int/float 设置不要设成字符串。Span 错误与嵌套Span 错误不是confident.*属性使用原生 OTel spanStatusfrom opentelemetry.trace import Status, StatusCode try: ... except Exception as e: span.set_status(Status(StatusCode.ERROR), str(e)) span.record_exception(e)带StatusCode.ERROR的 span 在 Observatory 中呈现为错误若它是根 span整条 trace 会被标记为出错。已有gen_ai.*埋点时的回退行为当confident.*属性缺失时Confident AI 的 exporter 会回退读取标准 OTelGenAI 语义约定属性gen_ai.*。这对已经由 GenAI-aware 库插桩、天然产出gen_ai.*span 的应用很重要这些数据无需额外confident.*属性即可进入 Confident AI。详见 gen-ai-fallbacks.md。span 类型推断confident.span.type未设置时条件推断出的confident.span.typegen_ai.operation.name为chat、generate_content或text_completionllm存在gen_ai.tool.nametool其他base属性回退表confident.*缺失时读取对应gen_ai.*confident.*属性回退到gen_ai.*confident.llm.modelgen_ai.request.modelconfident.llm.input_token_countgen_ai.usage.input_tokensconfident.llm.output_token_countgen_ai.usage.output_tokensconfident.tool.namegen_ai.tool.name使用建议两者并存时confident.*始终优先新插桩优先显式设置confident.*映射直接且无歧义回退机制只用于避免重复写已有 GenAI 集成已经产出的属性除非需要覆盖否则不要为已有的gen_ai.*属性补confident.*副本。只导出 AI span与 APM/自动插桩隔离真实应用中几乎总是存在远不止 AI 代码的 OpenTelemetry 埋点。自动插桩库和 APM agentDatadog、New Relic、Grafana、OTel auto-instrumentation 等会为 HTTP 请求、数据库查询、缓存调用、出网调用和框架内部行为发 span——这在 Node.js、Python、Java、Go 等任何运行时都会发生。如果 Confident AI exporter 与这些埋点共享 tracer provider 或 processor 管线所有这些无关 span 都会被发往 Observatory把 AI trace 淹没在非 AI 噪声里。文档给出的规则是Confident AI 导出管线必须只携带 AI span两种做法二选一方案 1专用管线可行时首选把 Confident AI exporter 注册到一个只被 AI 插桩使用的 tracer provider / processor 上与自动插桩和 APM agent 喂数据的全局 provider 分离AI span 用该专用 provider 的 tracer 创建。非 AI span 从未进入这条管线自然到不了 Confident AI exporter。方案 2管线过滤当 AI span 与其他 span 不可避免地共享 providerAI 框架把 span 发到全局 provider 时很常见时用过滤层包住发往 Confident AI 的 processor 或 exporter只转发 AI span、丢弃其余。判定一个 span 是否属于 AI满足其一即可设置了confident.span.type属性或携带gen_ai.*语义约定属性或span 名匹配已知的 AI 框架前缀例如 Vercel AI SDK 发出的 span 名为ai.*。过滤可实现为一个span processor对非 AI span 的onStart/onEnd直接 no-op只把 AI span 交给底层 Confident AI processor或一个exporter 包装器在每个 batch 送入真正的 OTLP exporter 前剔除非 AI span。仓库内有一份可工作的参考实现DeepEval TypeScript SDK 的 AI SDK 集成中的 DeepEvalBatchFilterProcessor按名缀过滤的 span-processor和 DeepEvalExporterWrapperexporter 包装器。在任何语言/SDK 中照这个形态实现即可。**过滤时务必保住 span 嵌套。**丢弃一个中间非 AI span 会让它的 AI 子 span 变成孤儿parentSpanId指向一个从未被导出的 span。过滤时要把孤儿 AI span 重新挂到最近的已导出祖先上或者剥掉悬空的父引用让其成为干净的根 span——上述DeepEvalExporterWrapper对根 span 做的正是这件事。作为对照仓库内 DeepEval 自身的 OTel 模式集成采用了类似的“处理器路由”思路从 deepeval/integrations/README.md 的传输参考可以看到OTLP 路径即BatchSpanProcessor按定时/队列阈值把 span 冲刷到otel.confident-ai.com/v1/traces其ContextAwareSpanProcessor在存在 deepeval trace 上下文或评测进行中时改走 REST 路由平时走 OTLP——与本文“先复用既有管线、必要时隔离/过滤”的原则一脉相承。核心原则与完整工作流文档把约束浓缩为八条核心原则只插桩 AI 组件——agent、LLM、retriever、tool span绝不把confident.*属性用于非 AI 软件或非 AI span。只导出 AI span。进程里有其他 OTel 埋点或 APM agent 时隔离 Confident AI 管线专用 provider 或 span 过滤器让 HTTP 请求、DB 查询、基础设施 span 永远到不了 Confident AI。优先把既有 OTLP exporter 改指到 Confident AI而不是新增一条并行管线。confident.*属性键就是整个契约——所有语言一致语言选型无关紧要。永远使用 OTLP/HTTPendpoint 不接受 gRPC。遵守 OTLP 数据类型规则属性值必须是原始类型或同构原始类型列表dict 和 metadata 做 JSON 编码。明确知道 span 类型时显式设置confident.span.type只在回退时才依赖gen_ai.*推断。永不把密钥、凭据或原始敏感数据写进 span 属性。完整工作流按顺序执行确认目标是 AI 应用有 LLM 调用、agent 循环、检索或工具调用若一项都没有停止本方案不适用。然后检查既有 OTel 设施TracerProvider、span exporter 或 OpenTelemetry Collector优先改指现有管线而非新增并行管线。按 API key 的区域前缀选择 endpoint。接线或改指一个带x-confident-api-key头的 OTLP/HTTP span exporterPython 从 confident_otel_setup.py 起步。若进程运行其他 OTel 埋点或 APM agent隔离 Confident AI 导出让只有 AI span 到达它专用管线或 span 过滤器。在 span 上设置confident.span.*属性trace 级字段设confident.trace.*。遵守 OTLP 数据类型规则dict/metadata 做 JSON 编码字符串列表用原生数组。若应用已产出 OTel GenAI 语义约定先阅读 gen-ai-fallbacks.md 再添加冗余属性。验证 trace 出现在 Confident AI Observatory。文档与参考文件索引主题文件Skill 主文档范围、原则、工作流SKILL.mdEndpoint、区域选择、认证、exporter 接线、AI span 隔离references/endpoint-and-exporter.mdTrace 级confident.trace.*属性references/trace-attributes.mdSpan 级confident.span.*属性与数据类型规则references/span-attributes.md标准 OTelgen_ai.*回退行为references/gen-ai-fallbacks.md最小 Python OTLP exporter 设置 示例 tracetemplates/confident_otel_setup.py仓库内同源副本skills/deepeval-otel/仓库侧对照实现endpoint 默认值 / exporter 拼接 / 非 Python 过滤参考settings.py、pydantic_ai/otel.py、ai-sdk/index.ts【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表