deepeval.integrations 深度解析:10 个第三方框架统一接入 Tracing 与评估的四种机制与双传输路由
deepeval.integrations 深度解析10 个第三方框架统一接入 Tracing 与评估的四种机制与双传输路由【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval本文以 deepeval/integrations/README.md 为骨架系统讲解 deepeval 框架如何把自身的 tracing / 评估能力嵌入 OpenAI、LangChain、CrewAI、Pydantic AI 等 10 个第三方框架包括完整的集成能力矩阵、四种接入模式的选型依据、REST 与 OTLP 双传输机制以及ContextAwareSpanProcessor的核心路由逻辑。读完后你能准确判断在任意框架下应选用哪种接入方式并理解 OTel 模式集成与原生observe混合运行时 span 如何保证落到同一条 trace 上。一、集成矩阵一张表看清 10 个集成的能力边界deepeval.integrations目录下每个子包对应一个框架集成其作用是将 deepeval 的 tracing / 评估接入第三方框架。README 中给出的能力矩阵定义了四个关键能力列Bare裸调用不经过observe/with trace(...)包裹、直接调用框架 API也能在 Confident AI 中生成 trace。每个集成都会在首次活动callback 触发、OTel 根 span、内部对原生 client 的observe包装等时自动创建 traceobserve/with trace(...)被 deepeval 原生上下文包裹时集成的 span 流入原生 trace context此时update_current_trace(...)/update_current_span(...)在调用栈任意位置都能生效每条 trace 只产生一次 REST POST无需 UUID 对账evals_iterator在dataset.evals_iterator(...)内可用既支持端到端在 iterator 上配置metrics[...]也支持组件级在 span 上使用observe(metrics[...])。对 OTel 模式集成ContextAwareSpanProcessor会在trace_manager.is_evaluating为 True 时自动切换为 REST 路由使 span 走trace_manager而非 OTLPdeepeval test run在 pytest tracing-eval 入口下可用assert_test、generate_trace_json、assert_trace_json。完整矩阵继承自 README路径均已核实存在于仓库中集成模式入口Bareobserve/with trace()evals_iteratordeepeval test run源码位置OpenAI原生 client 包装from deepeval.openai import OpenAIYesYesYesYesdeepeval/openai/Anthropic原生 client 包装from deepeval.anthropic import AnthropicYesYesYesYesdeepeval/anthropic/LangChainCallback handlerCallbackHandler()YesYesYesYesdeepeval/integrations/langchain/LangGraphCallback handlerLangChain 的CallbackHandler()YesYesYesYesdeepeval/integrations/langchain/LlamaIndexEvent handlerinstrument_llama_index()YesYesYesYesdeepeval/integrations/llama_index/CrewAIEvent listener wrapper 类instrument_crewai()YesYesYesYesdeepeval/integrations/crewai/OpenAI AgentsTrace processor agent 包装add_trace_processor(DeepEvalTracingProcessor())YesYesYesYesdeepeval/openai_agents/AgentCoreOpenTelemetryinstrument_agentcore()YesYesYesYesdeepeval/integrations/agentcore/StrandsOpenTelemetryinstrument_strands()YesYesYesYesdeepeval/integrations/strands/Google ADKOpenTelemetry经 OpenInferenceinstrument_google_adk()YesYesYesYesdeepeval/integrations/google_adk/Pydantic AIOpenTelemetryDeepEvalInstrumentationSettings(...)YesYesYesYesdeepeval/integrations/pydantic_ai/两点需要注意矩阵全 Yes 的原因原生 client / callback handler / event listener / trace processor 这些集成早已通过直接访问trace_manager实现了全功能而四个 OTel 模式集成Pydantic AI、AgentCore、Google ADK、Strands在最近一轮 OTel POC 迁移中统一改用了SpanInterceptor ContextAwareSpanProcessor模式使其 span 在四个能力面上行为一致。README 也明确要求新的集成应对齐这一 parity。OpenAI / Anthropic / OpenAI Agents 的源码位置deepeval.openai、deepeval.anthropic、deepeval.openai_agents位于deepeval包的顶层而非integrations目录下矩阵中列出只是为了完整性对应 deepeval/openai/ 等目录。源码级注脚OTel 模式集成的共同行为README 脚注 [^poc] 描述的行为可从源码逐一印证每个 OTel 模式SpanInterceptor在每个 span 的生命周期内从current_trace_context按 span 读取trace 级元数据而不是在instrument_*()时固化并向current_span_context压入一个BaseSpan占位对象这样任何位置调用的update_current_span(...)最终都会落在confident.span.*属性上在on_end时生效。以 OpenInference 拦截器为例_push_span_context在on_start中按 span kind 构造AgentSpan/LlmSpan/BaseSpan占位并写入 contextvarinstrumentator.py_serialize_trace_context_to_otel_attrs在on_end时重新解析trace 属性保证运行期update_current_trace(...)的修改优先生效instrumentator.py。ContextAwareSpanProcessorcontext_aware_processor.py负责路由当存在 deepeval trace 上下文或评估正在进行时走 REST否则走 OTLP。二、四种接入模式选型依据与实现差异README 给出了四种接入机制的定义结合各集成目录的源码结构可以给出更具体的选型判断1. Native client wrapper原生 client 包装对厂商 SDK client 类的 drop-in 替换例如用deepeval.openai.OpenAI代替openai.OpenAI。span 通过trace_manager直接构造摩擦最小但只覆盖经过该 client 的调用。对应源码为 deepeval/openai/含patch.py、extractors.py与 deepeval/anthropic/。2. Callback handler / event listener回调 / 事件监听注册到框架自己的回调或事件 APILangChain 的BaseCallbackHandlercallback.py、LlamaIndex 的BaseEventHandlerhandler.py、CrewAI 的BaseEventListenersubs.py。span 同样经trace_manager直接构造。优点是覆盖框架经该表面分发的所有调用无需替换 client。3. Trace processor追踪处理器针对已有自身 tracing 流水线的框架OpenAI Agents SDK以 processor 身份接入把事件翻译成 deepeval span。实现位于 deepeval/openai_agents/含trace_processor相关模块与add_trace_processor入口。4. OpenTelemetryOTel 模式向全局TracerProvider注册 OTelSpanProcessor由框架或社区维护的 instrumentor如openinference-instrumentation-google-adk发出 OTel spandeepeval 将其翻译为 Confident span 属性并经 OTLP 上报。四个 OTel 集成分别拥有自己的 SpanInterceptorAgentCoreSpanInterceptorinstrumentator.py读取 OTel GenAI 语义约定gen_ai.*属性并带 Traceloop / AWS Bedrock 回退解析、StrandsSpanInterceptorinstrumentator.pyStrands 原生发出gen_ai.*属性、PydanticAISpanInterceptorinstrumentator.py使用其自有的 logfire 风格属性Google ADK 则复用共享的openinference/后端。四者共享同一套 processor 接线与同一个ContextAwareSpanProcessor。三、传输参考REST 与 OTLP 两条通道README 定义了两种传输通道RESTtrace_manager将完整 trace 一次性 POST 到api.confident-ai.com/v1/traces每条 trace 一次OTLPBatchSpanProcessor按定时器 / 队列阈值把 OTel span 冲刷到otel.confident-ai.com/v1/traces。OTLP 端点在源码中的拼接方式可以确认ContextAwareSpanProcessor.__init__中endpoint str(settings.CONFIDENT_OTEL_URL) v1/tracescontext_aware_processor.py。API key 以x-confident-api-key请求头附加未提供 key 时管线仍会本地运行便于调试但 Confident AI 后端会拒绝上传——源码注释明确解释了这一行为避免把None序列化为字面量字符串。四、核心机制ContextAwareSpanProcessor 的双通道路由ContextAwareSpanProcessor是 OTel 模式集成与evals_iterator、deepeval test run打通的关键源码位于 deepeval/tracing/otel/context_aware_processor.py。路由判定逻辑_should_route_to_rest()按优先级判定是否走 REST即 span 流入trace_managerL123-L148用户显式推送的 trace 上下文observe/with trace(...)——命中即走 REST拦截器为裸调用者推送的隐式trace 占位标记_is_otel_implicitTrue不算数这类调用者期望 OTLP 行为trace_manager.is_evaluating为 True评估运行中——走 REST使evals_iterator对 OTel 集成生效trace-shape 测试模式trace_testing_manager.test_name已设置——强制 REST。源码注释解释了原因trace_testing_manager.test_dict的唯一写入者是trace_manager.end_trace只会在 REST 路径触发若不强制assert_trace_json会静默超时并用{}对{}做平凡比较掩盖裸agent.run(...)流程的真实 trace-shape 回归。单委托导出与冲刷语义on_start同时转发给两个委托 processorREST 的SimpleSpanProcessor(ConfidentSpanExporter())与 OTLP 的BatchSpanProcessor(OTLPSpanExporter(...))SDK 将on_start视为 no-op开销可忽略on_end只选择其中一个委托导出避免 span 双重上报force_flush显式排空 REST exporter因为SimpleSpanProcessor.force_flush是 no-op 且不会触达 exporter若不显式排空会在 trace 仍排在工作线程队列时误报成功。ConfidentSpanExporterexporter.py负责把带confident.*属性的 OTel span 重建为 deepevalBaseSpan并经trace_manager上报其 REST 端点即api.confident-ai.com/v1/traces。五、OpenInference社区 instrumentor 的通用 OTel 后端deepeval/integrations/openinference/ 是 Google ADK 与任何其他社区维护的 OpenInference instrumentor 共享的 SpanInterceptor processor 接线配置TracerProvider注册OpenInferenceSpanInterceptor翻译 OpenInference 语义约定属性——openinference.span.kind、llm.input_messages.{idx}、llm.output_messages.{idx}、tool.name、llm.token_count.*——到confident.span.*通过ContextAwareSpanProcessor路由 spanREST 或 OTLP。从源码看span kind 的映射规则是AGENT/CHAIN→ agentLLM→ llmTOOL→ toolRETRIEVER→ retriever_get_span_kind消息内容提取优先走扁平化的llm.input_messages.{idx}.message.role/content属性回退到未扁平化的 JSON blob 及通用input.value/output.value_extract_messages工具调用则从llm.output_messages.{idx}.message.tool_calls.{tc_idx}.tool_call.function或 tool span 的tool.name/tool.parameters中还原为ToolCall对象。顶层入口deepeval.instrument(...)该能力在顶层以deepeval.instrument(...)暴露可与任意 OpenInference instrumentor 直接配对使用import deepeval from openinference.instrumentation.google_adk import GoogleADKInstrumentor deepeval.instrument(namemy-app, environmentdevelopment) GoogleADKInstrumentor().instrument()顶层实现位于 deepeval/init.pyinstrument是惰性定义的函数委托给 instrument_openinference并接受与后者相同的 trace 级 kwargsapi_key、name、thread_id、user_id、metadata、tags、environment、metric_collection、test_case_id、turn_idspan 级配置则通过with next_*_span(...)/update_current_span(...)完成。instrument_google_adk(...)只是一个便捷包装先调用GoogleADKInstrumentor().instrument()再调用deepeval.instrument(...)。两个值得注意的实现细节幂等性instrument_openinference对同一个TracerProvider幂等——重复调用会原地修改 settings 而不是叠加 processor因为社区 OpenInference instrumentor 安装在全局 provider 上叠加会破坏 contextvars 并泄漏 settingsotel.py 的模块 docstring 与_attached_processors注册表已移除的 span 级 kwargsis_test_mode、agent_metric_collection、llm_metric_collection、tool_metric_collection_map、trace_metric_collection、agent_metrics、confident_prompt在 OTel POC 迁移中已移除传入会抛出带迁移指引的TypeErrorinstrumentator.py。需要强调AgentCore、Strands、Pydantic AI不经由这里——它们各自拥有独立的 SpanInterceptor但共享同一套 processor 接线与同一个ContextAwareSpanProcessor。六、OTel 模式与observe混合运行同一条 trace 如何保证当 OTel 模式集成运行在活跃的observe/with trace(...)上下文中时机制由两部分配合完成trace UUID 同步OTel span 拦截器同步 trace UUIDcurrent_trace_context.uuid OTel trace_id使两种传输在服务端落到同一条 trace。以 OpenInference 拦截器为例_maybe_bridge_otel_root_to_deepeval_parent会把落在observe内部的 OTel 根 span 通过confident.span.parent_uuid重新挂接到外层 deepeval span 之下避免二者成为平级兄弟instrumentator.py自动 REST 路由ContextAwareSpanProcessor在 deepeval trace 上下文活跃或评估运行时自动把 OTel span 经ConfidentSpanExporterREST发出——混合 trace 因此只产生一次 REST POST且任意位置的update_current_trace(...)/update_current_span(...)都能落到正确的 span 上。README 指出 Pydantic AI 是该混合路径的参考实现AgentCore、Strands 以及经共享openinference/后端的 Google ADK 均遵循同一模式从源码结构看四者的拦截器模块 docstring 都明确标注“mirrors the Pydantic AI POC pattern”印证了这一实现谱系。七、源码索引从哪里继续深入关注点文件顶层instrument()/flush_traces()公共 APIdeepeval/init.py双通道路由 processordeepeval/tracing/otel/context_aware_processor.pyREST exporterOTel span → deepeval BaseSpandeepeval/tracing/otel/exporter.pyconfident.*属性常量deepeval/tracing/otel/attributes.pyOpenInference 拦截器与instrument_openinferencedeepeval/integrations/openinference/instrumentator.py、deepeval/integrations/openinference/otel.py四个 OTel 集成的 SpanInterceptordeepeval/integrations/pydantic_ai/、deepeval/integrations/agentcore/、deepeval/integrations/strands/、deepeval/integrations/google_adk/各集成的验收测试含大量 trace 形状 JSON 断言样例tests/test_integrations/如果你要为 deepeval 新增一个框架集成README 给出的对齐目标很明确让新集成在 Bare、observe/with trace(...)、evals_iterator、deepeval test run四个能力面上都达到矩阵中现有的全 Yes 水平OTel 类框架优先复用 SpanInterceptor ContextAwareSpanProcessor这一已被四个集成验证的模式。【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考