
DeepEval 之 DeepEval OTel 契约详解confident.span.* 属性如何为 AI 组件 Span 建模并导出到 Confident AI【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval导读本文围绕 DeepEval 仓库中deepeval-otel技能参考文档 span-attributes.md 展开系统讲解如何仅凭原生 OpenTelemetry 的confident.span.*/confident.llm.*/confident.agent.*/confident.retriever.*/confident.tool.*属性键把 LLM 调用、Agent 循环、检索与工具调用等 AI 组件 span 标注成 Confident AI Observatory 可识别的结构化数据。读完本文你可以掌握五种 span 类型的完整属性契约、OTLP 数据类型编码规则、span 错误上报与父子嵌套机制以及仓库中 SDK 侧deepeval/tracing/otel对这些属性的实际读取与解析实现。一、Span 级属性的定位与适用范围Span 级属性描述的是单个 span——即一次 trace 中的一个组件。使用时把confident.span.*以及按类型划分的confident.llm.*、confident.agent.*、confident.retriever.*、confident.tool.*属性直接设置在该 span 上。契约中有两条前置约束值得强调confident.span.type决定哪些按类型的键生效必须最先设置。它允许的值恰好是llm、tool、agent、retriever和base五种其中base是没有任何额外类型字段的通用 span。confident.*属性只应用于系统中的 AI 部分——LLM 调用、agent 循环、检索、工具调用——不要打到 HTTP 处理器、数据库查询等基础设施 span 上。这一点在技能定义 SKILL.md 的 Scope: AI Applications Only 一节中也被列为硬性边界非 AI span 的数据在 Confident AI 中不会呈现有意义的信息。从源码结构看这些属性键在 DeepEval SDK 内部由 ConfidentAttr 常量类 统一维护各类框架集成LangChain、OpenAI、Pydantic AI、Strands、Google ADK 等通过它把同名字符串写到 OTel span 上再由ConfidentSpanExporter读回。该文件的模块注释特别指出属性键拼写错误不会报错——数据会写到一个没人读取的键上对应字段直接从 trace 中静默消失因此必须与契约表逐项对齐。二、通用 Span 属性所有类型可用以下属性对每种 span 类型都有效属性键类型说明confident.span.typestring取值之一llm、tool、agent、retriever、base。缺省时由gen_ai.*属性推断见 gen-ai-fallbacks.mdconfident.span.namestring展示名称覆盖原生 OTel span 名称confident.span.inputstringSpan 输入。透传字段若值本身不是字符串需先 JSON 编码confident.span.outputstringSpan 输出。透传字段若值本身不是字符串需先 JSON 编码confident.span.metadataJSON 字符串有助于诊断失败的组件事实。必须是 JSON 编码的对象字符串confident.span.contextlist of strings该 span 的 ground-truth 上下文confident.span.retrieval_contextlist of strings该 span 检索到的文档块confident.span.tools_calledlist of strings原生 OTLP list每个元素是 JSON 序列化后的ToolCall字符串confident.span.expected_toolslist of strings原生 OTLP list每个元素是 JSON 序列化后的ToolCall字符串confident.span.metric_collectionstringConfident AI 指标集合名称用于对该 span 执行在线服务端评估仓库内 ConfidentAttr 中可以看到这些键的 SDK 侧对应常量SPAN_CONTEXT、SPAN_INPUT、SPAN_METADATA、SPAN_TOOLS_CALLED等此外 SDK 还额外支持文档未列出的confident.span.expected_output、confident.span.integration、confident.span.parent_uuid、confident.span.prompt等内部字段它们主要服务于 DeepEval 自身的评估管线外部纯 OTLP 用户只需关注文档契约中的键即可。三、LLM Span模型、Token 与成本将confident.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 成本用于成本汇总Prompt 关联字段如果该 span 对应的是在 Confident AI 中管理的 prompt还需设置离散的 prompt 字段——且只设置实际用到的字段属性键类型说明confident.span.prompt_aliasstringPrompt 别名 / 名称confident.span.prompt_versionstringPrompt 版本标识confident.span.prompt_commit_hashstringPrompt commit 哈希confident.span.prompt_labelstringPrompt 标签这组回退关系与 gen-ai-fallbacks.md 中的属性回退表一致当confident.*键缺失时exporter 依次读取gen_ai.request.model、gen_ai.usage.input_tokens、gen_ai.usage.output_tokens两者同时存在时confident.*恒胜。对新接入的埋点文档建议直接显式设置confident.*属性把gen_ai.*回退仅作为避免重复属性的兼容手段。四、Agent / Retriever / Tool 三类组件 SpanAgent Spanconfident.span.type设为agent属性键类型说明confident.agent.namestringAgent 名称 / 标识符confident.agent.available_toolslist of strings该 Agent 可用的工具confident.agent.agent_handoffslist of strings该 Agent 可交接的其他 AgentRetriever Spanconfident.span.type设为retriever属性键类型说明confident.retriever.embedderstring嵌入模型名如text-embedding-3-smallconfident.retriever.top_kint检索返回结果数confident.retriever.chunk_sizeint文档分块大小检索到的具体文档块放在confident.span.retrieval_context通用属性而不是按类型的键里。Tool Spanconfident.span.type设为tool属性键类型说明confident.tool.namestring工具 / 函数名。回退gen_ai.tool.nameconfident.tool.descriptionstring人类可读的工具描述工具的参数放在confident.span.input执行结果放在confident.span.output。上述每个键都能在 ConfidentAttr 中找到对应常量AGENT_NAME、AGENT_AVAILABLE_TOOLS、RETRIEVER_TOP_K、TOOL_NAME等说明 SDK 的框架集成与纯 OTLP 手工埋点走的是同一套属性契约。五、Span 错误使用原生 OTel Status而非 confident.* 属性Span 错误不是confident.*属性必须用原生 OpenTelemetry 的 spanStatus表达from 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 被标记为出错。官方模板 confident_otel_setup.py 中给出了完整示范在子 LLM span 的try块捕获异常后调用set_statusrecord_exception再重抛。六、数据类型规则OTLP 只有原始类型和同质原始类型列表OpenTelemetry 属性值必须是原始类型string、bool、int、float或同质原始类型列表不存在 map/object 属性类型。编码时必须遵循以下规则trace 级属性同样适用见 trace-attributes.md对象 / dictconfident.span.metadata、confident.trace.metadata必须是JSON 编码字符串——json.dumps(...)字符串列表tags、context、retrieval_context、available_tools、agent_handoffs可以用原生 OTLP 字符串数组Python 中即str的list/tupleJSON 数组字符串也会被接受ToolCall列表tools_called、expected_tools必须是原生 OTLP list且每个元素是一个 JSON 序列化后的ToolCall字符串——即JSON 字符串的列表而不是一个 JSON 编码的列表input/output是透传字段值若还不是字符串先 JSON 编码再设置数字top_k、chunk_size、token 数、成本必须以原生 int/float 设置不要转成字符串。这些规则在仓库源码中有直接印证。ConfidentSpanExporter的解析方法 _parse_list_of_tools 遍历属性中的每个元素仅当元素是str时才对它执行ToolCall.model_validate_json(...)解析失败静默跳过——这解释了为什么列表内每个元素各自是 JSON 字符串是硬性要求而 _parse_json_string 同理只对字符串形态的 metadata 做json.loads。被解析的ToolCall模型定义于 deepeval/test_case/llm_test_case.py即 DeepEval 评估体系中的标准工具调用结构。七、Span 嵌套父子关系来自原生 OTel Span Context父 / 子关系由原生 OpenTelemetry span context决定——在父 span 的上下文内开启子 span 即可不存在任何confident.*父级属性。使用tracer.start_as_current_span(...)时在with块内开启的 span 会自动嵌套到它下面。SDK 侧也遵循同一机制ConfidentSpanExporter通过 _build_span_forest 按trace_id分组 span再依据原生 span 的 parent-child 关系重建 span 树而不是依赖任何自定义属性。八、端到端实操最小可运行埋点模板仓库提供了完整的最小化模板 confident_otel_setup.py可直接运行做连通性冒烟测试。前置条件pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http export CONFIDENT_API_KEYyour Confident AI API key模板关键片段摘自 confident_otel_setup.pywith tracer.start_as_current_span(support-agent) as root: root.set_attribute(confident.span.type, agent) root.set_attribute(confident.agent.name, support-agent) root.set_attribute(confident.span.input, Where is my order?) # trace 级属性字符串列表用原生 OTLP 数组 root.set_attribute(confident.trace.tags, [support, example]) # dict/metadata 必须是 JSON 编码字符串OTLP 没有 map 类型 root.set_attribute( confident.trace.metadata, json.dumps({app_version: 1.0.0, route: order_status}), ) with tracer.start_as_current_span(chat-completion) as llm: llm.set_attribute(confident.span.type, llm) llm.set_attribute(confident.llm.model, gpt-4o) llm.set_attribute(confident.llm.input_token_count, 42) llm.set_attribute(confident.llm.output_token_count, 18) llm.set_attribute( confident.span.metadata, json.dumps({temperature: 0.2}), )该模板同时演示了本文全部核心规则先设confident.span.type、token 数用原生 int、metadata 用json.dumps编码、tags 用原生数组、子 span 靠with块自动嵌套、异常走原生Status。端点选择confident_eu_前缀走 EU其余走默认与x-confident-api-key请求头配置在 endpoint-and-exporter.md 中有详细说明Confident AI 的 OTLP 端点仅接受 HTTP不接受 gRPC。九、小结属性键就是完整契约confident.*属性键集合构成了语言无关的完整契约——在任何语言的任意 OTel SDK 中只要按本文表格正确设置键与类型trace 就能在 Confident AI Observatory 中呈现为结构化的 AI 组件数据。实践要点回顾confident.span.type先行且只用于 AI 组件 span对象 JSON 编码、字符串列表用原生数组、ToolCall列表是JSON 字符串的列表、数字保持原生数值错误走原生Status/record_exception嵌套走原生 span context两者都没有confident.*属性属性键拼写错误不会报错字段会静默丢失——对照 span-attributes.md 与 ConfidentAttr 逐项核对是最可靠的校验方式。【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考