如何把 LangGraph 应用接入 DeepEval 追踪并给节点和工具调用打分?
发布时间:2026/9/15 11:48:45来源:尧图网络
如何把 LangGraph 应用接入 DeepEval 追踪并给节点和工具调用打分【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval假设你已经用 LangGraph 的StateGraph搭好了一个带工具的图例如chatbot节点 ToolNode现在要完成两件事把每次图运行的节点、模型调用、工具调用全部抓成可检查的 trace并用 DeepEval 的指标对整条轨迹或其中单个组件打分。本文以 Python 为主路径内容来自 LangGraph 集成文档TypeScript 侧有等价 API文中在相关位置单独标出。安装依赖pip install -U deepeval langgraph langchain-openaiLangGraph 走的是 LangChain 的 callback 系统所以 DeepEval 的接入是按调用生效的你在哪次invoke的 config 里传入CallbackHandler()哪次运行就被追踪不需要改动图本身的代码。TypeScript 项目对应安装npm install -D deepeval langchain/langgraph langchain/core langchain/openai zod方式相同传入new DeepEvalCallbackHandler({})即可。给图加上追踪把 CallbackHandler 传入 graph config下面是文档中的完整示例一个chatbot节点加一个ToolNode的最小天气图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 fIts 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 are the inputs you want to evaluate. dataset EvaluationDataset(goldens[Golden(inputWhat is the weather in Paris?)]) # The TaskCompletionMetric is passed into the evals_iterator. for golden in dataset.evals_iterator(metrics[TaskCompletionMetric()]): graph.invoke( {messages: [{role: user, content: golden.input}]}, config{callbacks: [CallbackHandler()]}, )模型用的是文档示例中的openai:gpt-4o-mini你可以把init_chat_model(...)的参数换成自己能调用的模型。接入追踪的关键只有一行config{callbacks: [CallbackHandler()]}。追踪出来的 span 结构每次接收到 callback 的 LangGraph 运行会产生一个trace用户视角的端到端单元里面是 LangChain 回调发出的各类组件 spanAgent span— 编译后StateGraph的invoke(...)调用span 树的根嵌套的子图节点保持为自定义 spanLLM spans— 节点内的 chat model / completion 调用Tool spans— 由ToolNode或你自己的节点执行的工具调用Retriever spans— 如果你的图用到检索。文档给出的示例结构如下文档示例Trace ← what the user observes └── Agent: weather_graph ← one graph invoke(...) call ├── Node: chatbot ← model picks a tool │ └── LLM: gpt-4o-mini ├── Node: tools ← ToolNode runs the tool │ └── Tool: get_weather └── Node: chatbot ← model writes the final answer └── LLM: gpt-4o-miniTrace 和它的每个组件 span 都可以独立参与评估。验证追踪是否生效不需要登录任何平台两种本地检查方式deepeval inspectTUIevals_iterator的每次运行都会把结果快照落盘直接运行deepeval inspect就能打开 trace 树查看每个 span 的分数、metric reason、输入/输出和工具调用。也可以显式指定文件或目录目录方式会取其中最新的test_run_*.jsondeepeval inspect deepeval inspect ./experiments/test_run_20260512_174200.json deepeval inspect ./experiments # 取目录内最新的 test_run_*.json需要 TUI 时CLI 文档给出的安装方式是pip install deepeval[inspect]见 command-line-interface。代码里取原始 tracetrace 在内存中捕获可以直接当 Python 字典读取见 Tracing AI Agentsfrom deepeval.tracing import trace_manager travel_graph_result graph.invoke( {messages: [{role: user, content: Whats the weather in Paris?}]}, config{callbacks: [CallbackHandler()]}, ) traces trace_manager.get_all_traces_dict() for trace in traces: for span_type in [agentSpans, llmSpans, toolSpans]: for span in trace.get(span_type, []): print(f [{span_type}] {span.get(name)}: {span.get(input)} - {span.get(output)})遍历llmSpans和toolSpans可以逐个确认每个工具收到的参数和返回结果。长驻脚本里可以在两次运行之间调用trace_manager.clear_traces()避免 trace 在内存里累积。给整条轨迹打分trajectory metrics把轨迹类指标传给evals_iterator每个 golden 触发一次带追踪的图运行指标在 trace 作用域上对整个有序轨迹打分——包括图的路由决策、模型调用、工具使用自定义的图/节点 span 也属于这条有序轨迹的一部分from deepeval.metrics import TaskCompletionMetric, StepEfficiencyMetric, PlanAdherenceMetric from deepeval.integrations.langchain import CallbackHandler from deepeval.dataset import EvaluationDataset, Golden dataset EvaluationDataset(goldens[Golden(inputWhat is the weather in Paris?)]) metrics [TaskCompletionMetric(), StepEfficiencyMetric(), PlanAdherenceMetric()] for golden in dataset.evals_iterator(metricsmetrics): graph.invoke( {messages: [{role: user, content: golden.input}]}, config{callbacks: [CallbackHandler()]}, )迭代器为每个 golden 捕获一条 trace并在图运行结束后评估完整轨迹每个指标的分数和 reason 与该 trace 一起存储失败可以定位到具体执行路径。更多指标选择见 trajectory-based evaluation。运行后终端会打印每个 span 的打分文档展示的示例输出文档示例数值不是固定预期$ deepeval test run test_langgraph_agent.py ● test_langgraph_agent │ └─ weather_graph Task Completion 0.94 190ms ✓ ├─ chatbot · gpt-4o-mini G-Eval 0.42 72ms ✗ ├─ get_weather(cityParis) 32ms └─ chatbot · gpt-4o-mini Faithfulness 0.95 78ms ✓ Trace score 0.77 · 2/3 metrics passed给单个节点或 LLM 调用打分传给evals_iterator的指标作用在整条 trace 上。要评估组件就先把指标“暂存”到 callback 下一个要打开的 span 上再执行图Agent span用next_agent_span包住graph.invoke(...)指标落到invoke(...)打开的根 agent span 上——适合只给图这次运行本身一个 span 级分数而不评整条 trace。from deepeval.metrics import TaskCompletionMetric from deepeval.tracing import next_agent_span for golden in dataset.evals_iterator(): with next_agent_span(metrics[TaskCompletionMetric()]): graph.invoke( {messages: [{role: user, content: golden.input}]}, config{callbacks: [CallbackHandler()]}, )评估子图/子 agent 节点时也是这个套路staging 的指标会落到图运行期间 callback 打开的下一个匹配的 agent span 上。LLM 调用用next_llm_span包住 invoke指标落到图发出的第一个LLM span 上from deepeval.metrics import AnswerRelevancyMetric from deepeval.tracing import next_llm_span for golden in dataset.evals_iterator(): with next_llm_span(metrics[AnswerRelevancyMetric()]): graph.invoke( {messages: [{role: user, content: golden.input}]}, config{callbacks: [CallbackHandler()]}, )注意这是one-shot语义next_llm_span只覆盖块内第一个 LLM span循环里后续经过chatbot节点的 LLM 调用不会拿到该指标。要给每次 LLM 调用都打分文档给出的替代路径是使用 scope 级上下文trace(...)或者干脆用evals_iterator的 trace 级指标端到端评分。工具调用集成文档的明确建议是——对确定性的工具调用用 tool span 记录可追溯性、输入、输出和元数据避免把指标直接挂到 tool span 上。也就是说工具 span 负责把“调了什么工具、传了什么参数、返回了什么”完整留痕工具使用质量的分数由轨迹级指标如TaskCompletionMetric、StepEfficiencyMetric在整条轨迹上体现。TypeScript 侧对应的 staging 辅助是nextAgentSpan/nextLlmSpan来自deepeval/tracing例如import { AnswerRelevancyMetric } from deepeval/metrics; import { nextLlmSpan } from deepeval/tracing; for await (const golden of dataset.evalsIterator()) { await nextLlmSpan({ metrics: [new AnswerRelevancyMetric()] }, () ask((golden as Golden).input), ); }在 CI/CD 中打分把同样的数据集、带追踪的图和指标放进 pytest 测试每次参数化调用就是一次 LangGraph 运行指标不达标时测试失败测试失败即构建失败import pytest 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 import assert_test 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 fIts 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() ) dataset EvaluationDataset(goldens[ Golden(inputWhat is the weather in Paris?), Golden(inputWhat is the weather in London?), ]) pytest.mark.parametrize(golden, dataset.goldens) def test_langgraph_agent(golden: Golden): graph.invoke( {messages: [{role: user, content: golden.input}]}, config{callbacks: [CallbackHandler()]}, ) assert_test(goldengolden, metrics[TaskCompletionMetric()])运行deepeval test run test_langgraph_agent.py这就是验证方式退出前你会得到每个 golden 的 pass/fail任何轨迹指标低于阈值deepeval test run就会失败。TypeScript 侧用 vitest 的toPass()匹配器expect(golden).toPass([...], { task: (g) ask(g.input) })命令为npx deepeval test run langgraph-agent.test.ts。如果指标是通过next_agent_span这类 staging 挂在组件 span 上的测试里就不需要再传 trace 级指标调用run_graph(golden.input)后直接assert_test(goldengolden)即可。可选分支与边界LangGraph server 部署部署到 LangGraph server 时是 server 在调用你的图没有自己的invoke可以塞 callback。改成在编译图时把 handler 烘焙进去——.compile().with_config(callbacks[CallbackHandler()])——再把langgraph.json指到导出的graph然后langgraph dev启动server 执行的每个请求都被追踪。注意烘焙进去的 handler 属性thread_id、user_id等是per-handler的所有请求共用同一份要按请求变化的值仍然用 per-call 传 callback。trace 元数据CallbackHandler接受name、tags、metadata、thread_id、user_id、metrics、metric_collection、test_case_id、turn_id等 kwarg作为使用该 callback 的运行的默认值。例如CallbackHandler(nameweather-graph, tags[langgraph, weather], metadata{team: support}, user_iduser-123)。组件级评估目前是 single-turn only见 component-level evaluation多轮组件级评估在路线图里。metrics参数是同步执行 LLM-as-a-judge 评估的会给运行增加延迟文档建议仅用于开发和测试生产环境改用metric_collection做异步评估需要 Confident AI。登录 Confident AIdeepeval login可以可视化完整图 trace——每个节点、模型调用、工具调用都以嵌套 span 展示并带分数——这一步是可选的本地脚本、CI 和deepeval inspect都不依赖它。完成判定接入完成的标准按文档可核对deepeval test run或脚本 evals_iterator跑完后终端输出中每个 span 带有指标分数和 pass/faildeepeval inspect打开的 trace 树里能看到Agent / Node / LLM / Tool的完整层级工具 span 带参数和返回内容CI 中指标不达标时deepeval test run返回失败从而阻断构建。【免费下载链接】deepevalThe LLM Evaluation Framework项目地址: https://gitcode.com/GitHub_Trending/de/deepeval创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网