news 2026/9/13 19:51:42

DeepEval 追踪集成选择指南:从 CallbackHandler 到 deepeval.instrument 的完整实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DeepEval 追踪集成选择指南:从 CallbackHandler 到 deepeval.instrument 的完整实践

DeepEval 追踪集成选择指南:从 CallbackHandler 到 deepeval.instrument 的完整实践

【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval

本文基于 DeepEval 官方技能参考文档 integrations.md 展开,系统讲解为 LLM 应用添加追踪(tracing)时如何挑选正确的集成方式:先识别应用使用的框架、模型供应商与向量数据库,优先使用 DeepEval 提供的原生集成(如 LangGraph 的CallbackHandler、OpenAI 的客户端补丁),仅对不受支持的组件才回退到手写@observe。读完本文,你将掌握 DeepEval 全部集成文档的索引、四种集成机制的底层差异,以及两套可直接复制的实战示例代码。

核心原则:先选原生集成,手写 @observe 只是兜底

integrations.md 开篇即给出明确的选型规则:优先使用 DeepEval 官方支持的原生集成,手动@observe仅在没有原生集成的应用代码或框架边界处作为后备。该文档给出的四步选择流程是:

  1. 识别应用中已存在的框架、模型供应商、Agent SDK、向量数据库,以及任何已有的 OpenTelemetry 设置;
  2. 如果存在对应的集成文档,先阅读该文档,再写追踪代码;
  3. 优先使用集成的原生追踪面(native tracing surface),仅在外部应用函数或不受支持的组件周围才使用手动@observe
  4. 严格遵循对应集成文档中的追踪配置方式。

文档以 LangGraph 为例做了强调:LangGraph 应用应当先使用 LangGraph/LangChain 回调集成(CallbackHandler),而不是第一选择就加手动@observe——手动@observe适合包裹外层应用函数或不支持的组件,而不是图(graph)本身。

此外,该文档还划定了一个重要的命名约定:当后续评测(eval)把指标挂到某个组件 span 上时,这些指标列表应当以它们所评估的组件/span 命名,例如RETRIEVER_SPAN_METRICSGENERATOR_LLM_SPAN_METRICS,而不是搞一个全局列表。文档同时明确职责边界:把指标挂到 span 上是评测活动(由deepeval技能负责),而本技能(deepeval-tracing)只负责产出结构良好的 trace。

集成文档全索引

integrations.md 维护了三类共 36 篇集成文档的索引,全部位于 docs/content/integrations/ 目录下。

框架集成(Frameworks)

框架集成文档
LangGraphlanggraph.mdx
LangChainlangchain.mdx
OpenAI Agentsopenai-agents.mdx
LlamaIndexllamaindex.mdx
Pydantic AIpydanticai.mdx
CrewAIcrewai.mdx
Google ADKgoogle-adk.mdx
Strandsstrands.mdx
AgentCoreagentcore.mdx
OpenAI SDKopenai.mdx
Anthropic SDKanthropic.mdx
Hugging Facehuggingface.mdx

模型供应商集成(Models)

供应商集成文档
OpenAIopenai.mdx
Azure OpenAIazure-openai.mdx
Anthropicanthropic.mdx
Geminigemini.mdx
Amazon Bedrockamazon-bedrock.mdx
Vertex AIvertex-ai.mdx
Grokgrok.mdx
OpenRouteropenrouter.mdx
LiteLLMlitellm.mdx
Ollamaollama.mdx
vLLMvllm.mdx
LM Studiolmstudio.mdx
Portkeyportkey.mdx
DeepSeekdeepseek.mdx
Moonshotmoonshot.mdx

向量数据库集成(Vector Databases)

向量库集成文档
Chromachroma.mdx
Elasticsearchelasticsearch.mdx
PGVectorpgvector.mdx
Qdrantqdrant.mdx
Weaviateweaviate.mdx
Cogneecognee.mdx

OpenTelemetry 的分工边界

integrations.md 最后专门澄清了一个容易混淆的边界:如果你想用厂商中立的 OpenTelemetry SDK(而非 DeepEval SDK)做插桩,包括非 Python 应用、裸 OTLP 导出的场景,应改用deepeval-otel技能。当前技能(deepeval-tracing)覆盖的是 DeepEval 原生@observe追踪与上述列出的所有集成。这一分工与 deepeval-tracing 技能主文档 中的三技能划分一致:

  • deepeval-tracing——用 DeepEval SDK(@observe、框架集成)给应用插桩,使 trace 进入 Confident AI;
  • deepeval——构建 pytest 评测套件(数据集、指标、traced evals、deepeval test run),对已插桩的应用跑评测;
  • deepeval-otel——用厂商中立的 OpenTelemetry SDK 插桩(裸 OTLP,含非 Python 应用)。

四种集成机制:源码视角的实现差异

integrations.md 只给出文档索引,而具体的机制实现差异在 deepeval/integrations/README.md 的集成矩阵中有完整记载。该 README 将每种集成归入四种机制之一:

  • Native client wrapper(原生客户端包装)——厂商 SDK 客户端类的即插即用替代品(如用deepeval.openai.OpenAI替换openai.OpenAI),span 直接通过trace_manager构建,摩擦最小,但只覆盖经过该客户端的调用;
  • Callback handler / event listener(回调处理器 / 事件监听器)——注册到框架自身的回调或事件 API(LangChainBaseCallbackHandler、LlamaIndexBaseEventHandler、CrewAIBaseEventListener等),覆盖框架经该面派发的所有调用,无需替换客户端;
  • Trace processor(追踪处理器)——面向本身已有追踪流水线的框架(OpenAI Agents SDK),以处理器身份接入并把事件翻译为 DeepEval span;
  • OpenTelemetry——向全局TracerProvider注册 OTelSpanProcessor,框架或社区 instrumentor 产出 OTel span,DeepEval 将其翻译为 Confident span 属性并经 OTLP 发送。

从源码结构看,README 中的能力矩阵显示所有集成在四个使用面上(Bare 直接调用、@observe/with trace(...)包裹、dataset.evals_iterator(...)deepeval test run)均已拉齐,其中 Pydantic AI、AgentCore、Google ADK、Strands 四个 OTel 模式集成走的是同一套SpanInterceptor+ContextAwareSpanProcessor模式:处理器在有 DeepEval trace 上下文激活或评测进行中时自动切到 REST 路由,其余情况走 OTLP,从而保证混合使用(OTel 集成嵌套在@observe内)时两端数据落到同一条 trace 上。

两个可从源码直接验证的机制细节:

  • LangChain/LangGraph 集成的入口是 deepeval/integrations/langchain/init.py,仅导出CallbackHandlertool两个符号——这正是文档中“每调用传一次回调”的 per-call 模式的来源;
  • OpenAI 集成在 deepeval/openai/init.py 中导入官方OpenAI/AsyncOpenAI类后调用patch_openai_classes()就地打补丁,并先检查openai包是否安装、缺失时抛出ModuleNotFoundError——说明“换一行 import”背后是运行时 monkey-patch,而非 API 重写。

实战一:LangGraph 应用用 CallbackHandler 追踪

按 integrations.md 的选型规则,LangGraph 应用应走 LangChain 回调集成。langgraph.mdx 给出了完整可复制的 Python 示例:安装pip install -U deepeval langgraph langchain-openai后,把CallbackHandler(...)传入图运行的 config 即可,每次invoke产生的 agent 节点、模型调用、工具调用都会成为可检查的 span。

from langchain.chat_models import init_chat_model from langgraph.graph import StateGraph, MessagesState, START, END from langgraph.prebuilt import ToolNode, tools_condition from deepeval.integrations.langchain import CallbackHandler from deepeval.dataset import EvaluationDataset, Golden from deepeval.metrics import TaskCompletionMetric def get_weather(city: str) -> str: """Return the weather in a city.""" return f"It's always sunny in {city}!" llm = init_chat_model("openai:gpt-4o-mini").bind_tools([get_weather]) def chatbot(state: MessagesState): return {"messages": [llm.invoke(state["messages"])]} graph = ( StateGraph(MessagesState) .add_node(chatbot) .add_node("tools", ToolNode([get_weather])) .add_edge(START, "chatbot") .add_conditional_edges("chatbot", tools_condition) .add_edge("tools", "chatbot") .compile() ) # Goldens 是你要评测的输入 dataset = EvaluationDataset(goldens=[Golden(input="What is the weather in Paris?")]) # TaskCompletionMetric 传入 evals_iterator for golden in dataset.evals_iterator(metrics=[TaskCompletionMetric()]): graph.invoke( {"messages": [{"role": "user", "content": golden.input}]}, config={"callbacks": [CallbackHandler()]}, )

该集成产生的 trace 树形结构为(引自 langgraph.mdx):

Trace ← 用户观察到的端到端单元 └── Agent: weather_graph ← 一次 graph invoke(...) 调用 ├── Node: chatbot ← 模型选择工具 │ └── LLM: gpt-4o-mini ├── Node: tools ← ToolNode 执行工具 │ └── Tool: get_weather └── Node: chatbot ← 模型写出最终答案 └── LLM: gpt-4o-mini

文档还强调CallbackHandler支持nametagsmetadatathread_iduser_id等 trace 级 kwargs,以及通过next_agent_span/next_llm_span/next_retriever_span/next_tool_span把组件级字段暂存到回调将打开的下一个 span 上;部署到 LangGraph server 时则把回调烘焙进编译后的图(.with_config(callbacks=[CallbackHandler()])),让服务端执行的每个请求都被追踪。

实战二:OpenAI 客户端补丁追踪

对于直接使用 OpenAI SDK 的应用,openai.mdx 的集成方式是替换 import:把from openai import OpenAI换成from deepeval.openai import OpenAI,之后每次client.chat.completions.create(...)client.responses.create(...)都自动成为携带输入、输出与tools_called的 LLM span,无需改写调用方式(源码机制见上文 deepeval/openai/init.py 的补丁说明)。

from deepeval.dataset import EvaluationDataset, Golden from deepeval.tracing import trace, LlmSpanContext from deepeval.metrics import AnswerRelevancyMetric from deepeval.openai import OpenAI client = OpenAI() # Goldens 是你要评测的输入 dataset = EvaluationDataset(goldens=[Golden(input="What's the capital of France?")]) for golden in dataset.evals_iterator(): with trace(llm_span_context=LlmSpanContext(metrics=[AnswerRelevancyMetric()])): client.chat.completions.create( model="gpt-4o", messages=[ {"role": "system", "content": "Be concise."}, {"role": "user", "content": golden.input}, ], )

LlmSpanContext可接受metricspromptexpected_outputexpected_toolscontextretrieval_context等字段,在下一个 LLM span 创建时被读取。多个 OpenAI 调用同属一个逻辑单元(如 planner 调用 + 回答调用)时,用with trace(name="plan_then_respond"):括起来,各 LLM span 便作为兄弟 span 挂在同一 root 下。同步与异步客户端(OpenAI/AsyncOpenAI)均受支持。

通用 OTel 后端:deepeval.instrument

对于通过 OpenInference 等社区 instrumentor 产出 OTel span 的场景,integrations/README.md 说明仓库在顶层暴露了deepeval.instrument(...),可与任意 OpenInference instrumentor 直接配对:

import deepeval from openinference.instrumentation.google_adk import GoogleADKInstrumentor deepeval.instrument(name="my-app", environment="development") GoogleADKInstrumentor().instrument()

该入口配置TracerProvider、挂载 DeepEval 的 OpenInference span interceptor(把openinference.span.kindllm.input_messages.{idx}llm.token_count.*等语义属性翻译为confident.span.*),并经ContextAwareSpanProcessor决定走 REST 还是 OTLP。instrument_google_adk(...)只是对以上两步的便捷封装;而 AgentCore、Strands、Pydantic AI 各有自己的SpanInterceptor(分别读取 OTel GenAI 语义属性或 logfire 风格属性),但共享同一套处理器路由逻辑。

与手动 @observe 的边界

integrations.md 反复强调手动@observe的定位:它服务于“没有原生集成的应用代码或框架边界”。配套的 tracing.md 规定了手动插桩的规范——用有意义的type=值(llmretrievertoolagent)帮助后续指标选择、尽量以消息数组形式捕获输入输出、不给 trace 名随意起自定义name=、以及在 trace 级用 tags/metadata 做分组而不追踪密钥与敏感数据。换句话说:集成负责框架内部组件的 span,@observe负责应用自有的外层边界,两者叠加后得到的 trace 才能既完整又干净。

最后重申职责边界:本指南所指的集成与插桩工作“到产出结构良好的 trace 为止”——把指标挂到 span 上(如RETRIEVER_SPAN_METRICSGENERATOR_LLM_SPAN_METRICS这类按组件命名的指标列表)并运行评测,属于deepeval技能的范畴;裸 OpenTelemetry/OTLP 导出则属于deepeval-otel技能。

【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 19:50:22

Archon Quick Start:5 分钟跑通你的第一个 AI 编码工作流

Archon Quick Start:5 分钟跑通你的第一个 AI 编码工作流 【免费下载链接】Archon The first open-source harness builder for AI coding. Make AI coding deterministic and repeatable. 项目地址: https://gitcode.com/GitHub_Trending/archon3/Archon 本…

作者头像 李华
网站建设 2026/9/13 19:49:46

Linux内核设备驱动开发核心原理与实战

1. 项目概述:这不是写个hello world就能交差的底层工程 “Linux设备驱动开发”这七个字,听起来像教科书目录里一个不起眼的章节,但在我带过的二十多届嵌入式团队新人里,超过七成的人在真正动手写第一个字符设备驱动前,…

作者头像 李华
网站建设 2026/9/13 19:48:29

方框不再来:用PDF补丁丁完成PDF字体嵌入

方框不再来:用PDF补丁丁完成PDF字体嵌入 【免费下载链接】PDFPatcher PDF补丁丁——PDF工具箱,可以编辑书签、剪裁旋转页面、解除限制、提取或合并文档,探查文档结构,提取图片、转成图片等等 项目地址: https://gitcode.com/Git…

作者头像 李华
网站建设 2026/9/13 19:48:26

工业级多协议远程控制中枢JY-DAM0808B深度解析

1. 这不是“智能插座”,是工业级远程控制中枢的真实面目JY-DAM0808B——光看型号,很多人第一反应是“又一个带WiFi的继电器板”。但如果你真把它当普通IoT模块用,三分钟内就会在产线上栽跟头。我去年在东莞一家汽车零部件厂做设备联网改造时&…

作者头像 李华