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仅在没有原生集成的应用代码或框架边界处作为后备。该文档给出的四步选择流程是:
- 识别应用中已存在的框架、模型供应商、Agent SDK、向量数据库,以及任何已有的 OpenTelemetry 设置;
- 如果存在对应的集成文档,先阅读该文档,再写追踪代码;
- 优先使用集成的原生追踪面(native tracing surface),仅在外部应用函数或不受支持的组件周围才使用手动
@observe; - 严格遵循对应集成文档中的追踪配置方式。
文档以 LangGraph 为例做了强调:LangGraph 应用应当先使用 LangGraph/LangChain 回调集成(CallbackHandler),而不是第一选择就加手动@observe——手动@observe适合包裹外层应用函数或不支持的组件,而不是图(graph)本身。
此外,该文档还划定了一个重要的命名约定:当后续评测(eval)把指标挂到某个组件 span 上时,这些指标列表应当以它们所评估的组件/span 命名,例如RETRIEVER_SPAN_METRICS、GENERATOR_LLM_SPAN_METRICS,而不是搞一个全局列表。文档同时明确职责边界:把指标挂到 span 上是评测活动(由deepeval技能负责),而本技能(deepeval-tracing)只负责产出结构良好的 trace。
集成文档全索引
integrations.md 维护了三类共 36 篇集成文档的索引,全部位于 docs/content/integrations/ 目录下。
框架集成(Frameworks)
| 框架 | 集成文档 |
|---|---|
| LangGraph | langgraph.mdx |
| LangChain | langchain.mdx |
| OpenAI Agents | openai-agents.mdx |
| LlamaIndex | llamaindex.mdx |
| Pydantic AI | pydanticai.mdx |
| CrewAI | crewai.mdx |
| Google ADK | google-adk.mdx |
| Strands | strands.mdx |
| AgentCore | agentcore.mdx |
| OpenAI SDK | openai.mdx |
| Anthropic SDK | anthropic.mdx |
| Hugging Face | huggingface.mdx |
模型供应商集成(Models)
| 供应商 | 集成文档 |
|---|---|
| OpenAI | openai.mdx |
| Azure OpenAI | azure-openai.mdx |
| Anthropic | anthropic.mdx |
| Gemini | gemini.mdx |
| Amazon Bedrock | amazon-bedrock.mdx |
| Vertex AI | vertex-ai.mdx |
| Grok | grok.mdx |
| OpenRouter | openrouter.mdx |
| LiteLLM | litellm.mdx |
| Ollama | ollama.mdx |
| vLLM | vllm.mdx |
| LM Studio | lmstudio.mdx |
| Portkey | portkey.mdx |
| DeepSeek | deepseek.mdx |
| Moonshot | moonshot.mdx |
向量数据库集成(Vector Databases)
| 向量库 | 集成文档 |
|---|---|
| Chroma | chroma.mdx |
| Elasticsearch | elasticsearch.mdx |
| PGVector | pgvector.mdx |
| Qdrant | qdrant.mdx |
| Weaviate | weaviate.mdx |
| Cognee | cognee.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(LangChain
BaseCallbackHandler、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,仅导出
CallbackHandler与tool两个符号——这正是文档中“每调用传一次回调”的 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支持name、tags、metadata、thread_id、user_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可接受metrics、prompt、expected_output、expected_tools、context、retrieval_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.kind、llm.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=值(llm、retriever、tool、agent)帮助后续指标选择、尽量以消息数组形式捕获输入输出、不给 trace 名随意起自定义name=、以及在 trace 级用 tags/metadata 做分组而不追踪密钥与敏感数据。换句话说:集成负责框架内部组件的 span,@observe负责应用自有的外层边界,两者叠加后得到的 trace 才能既完整又干净。
最后重申职责边界:本指南所指的集成与插桩工作“到产出结构良好的 trace 为止”——把指标挂到 span 上(如RETRIEVER_SPAN_METRICS、GENERATOR_LLM_SPAN_METRICS这类按组件命名的指标列表)并运行评测,属于deepeval技能的范畴;裸 OpenTelemetry/OTLP 导出则属于deepeval-otel技能。
【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考