news 2026/10/7 15:32:52

LangSmith实战:Agent与RAG链路追踪与自动化评估

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangSmith实战:Agent与RAG链路追踪与自动化评估

做过 LangGraph Agent 或 RAG 之后,很快就会遇到两个问题:程序能跑,但内部到底发生了什么?以及,这个 Agent 到底好不好?LangSmith 主要解决的就是这两类问题。本文默认你已熟悉 LangChain、LangGraph 和 RAG,直接以一个现成的 RAG Agent 为对象,串起 Trace、Monitoring、Dataset、Evaluator、Experiment 五个核心能力。

一、接入 LangSmith

进入 smith.langchain.com 创建 API Key,然后在.env中加入:

LANGCHAIN_API_KEY=你的_LangSmith_API_Key LANGCHAIN_PROJECT=langsmith-test LANGCHAIN_TRACING_V2=true

三者分别表示身份认证、Trace 归属项目、开启链路追踪。注意区分:LANGCHAIN_API_KEY用于 LangSmith,OPENAI_API_KEY用于模型服务。LangSmith 本身不负责调用业务模型,只负责记录和分析调用过程。配置完成后,LangChain / LangGraph 运行时即可自动上报 Trace。

二、Trace:看清一次 Agent 执行

先看一个最小 LangGraph:

import "dotenv/config"; import { Annotation, START, END, StateGraph } from "@langchain/langgraph"; const StateAnnotation = Annotation.Root({ text: Annotation({ reducer: (_prev, next) => next, default: () => "" }) }); const stepOk = (state) => ({ text: `${state.text}[ok]` }); const stepThrow = () => { throw new Error("DemoError: 节点内故意抛出异常"); }; const graph = new StateGraph(StateAnnotation) .addNode("step_ok", stepOk) .addNode("step_throw", stepThrow) .addEdge(START, "step_ok") .addEdge("step_ok", "step_throw") .addEdge("step_throw", END) .compile(); try { await graph.invoke({ text: "start" }); } catch (error) { console.error(error.message); }

运行后进入Tracing → langsmith-test,可以看到LangGraph → step_ok → step_throw的调用树。这里要理解两个概念:Trace表示一次完整调用,Run表示 Trace 中的某一个具体执行单元。点开任意 Run,可以看到 Input、Output、Error、Attributes、Latency;节点报错时还能看到完整异常堆栈。与传统日志最大的区别是:日志是按时间输出的字符串,而 Trace 是有父子关系的执行树。

三、在真实 RAG 中看 Trace

假设已有START → retrieve → generate → END的 LangGraph RAG,其中 retrieve 调用retriever.invoke(state.question),generate 把context拼接后调用 chain。运行node src/cli.mjs "无理由退货要在几天内?",终端只看到最终答案,但 LangSmith 中能看到完整调用树:LangGraph → retrieve → VectorStoreRetriever,以及generate → qwen-plus。

点击VectorStoreRetriever可以看到用户问题与实际召回的文档;点击generate可以看到它收到的 question 和 context;继续点击模型 Run,可以看到真正发送给模型的 System Prompt、User Message、模型输出与耗时。因此当 RAG 回答异常时,可以快速判断:是 Retriever 召回错了?还是 Context 正确但模型回答错了?还是 Prompt 拼接出了问题?还是某一步耗时异常?

四、Monitoring:从单次请求看向整体

Trace 解决“这一条请求发生了什么”,Monitoring 解决“这段时间整个 Agent 运行得怎么样”。LangSmith Monitoring 中可以观察 Trace Count、成功与失败情况、Latency,以及 LLM Calls、Cost & Tokens、Tools、Run Types 等统计信息。简单区分:调试具体问题看 Trace,观察线上整体健康状态看 Monitoring。

五、Dataset:建立固定测试集

从“可观测”进入“可评估”,需要 Dataset、Evaluator、Experiment 三者配合:Dataset 是测试数据,Evaluator 是评分规则,Experiment 让 Agent 批量执行 Dataset 并用 Evaluator 打分。

安装pnpm install langsmith,创建src/evals/build_dataset.mjs:

import "dotenv/config"; import { Client } from "langsmith"; const DATASET_NAME = "rag-eval-v1"; const EXAMPLES = [ { inputs: { question: "无理由退货要在几天内申请?" }, outputs: { answer: "自签收之日起 7 天内支持无理由退货。" } }, { inputs: { question: "满多少元包邮?" }, outputs: { answer: "满 99 元包邮,部分大件商品和冷链商品除外。" } }, { inputs: { question: "手机保修多久?" }, outputs: { answer: "手机、平板和耳机全国联保 1 年。" } } ]; async function main() { const client = new Client({ apiKey: process.env.LANGCHAIN_API_KEY }); let dataset; try { dataset = await client.readDataset({ datasetName: DATASET_NAME }); } catch { dataset = await client.createDataset(DATASET_NAME, { description: "RAG Agent 回归评估集" }); } await client.createExamples(EXAMPLES.map(e => ({ dataset_id: dataset.id, inputs: e.inputs, outputs: e.outputs }))); } main();

运行后进入Datasets & Experiments,可以看到 Inputs 与 Reference Outputs。Dataset 的价值在于把零散的人工测试问题变成固定回归测试集,以后修改 Prompt、Retriever、模型或 RAG 参数,都可以重跑同一批数据。

六、Evaluator:给 RAG 定义评分维度

本文使用 OpenEvals 内置的三个 RAG 指标:Groundedness(答案是否被检索上下文支撑)、Helpfulness(回答是否切题、是否解决用户问题)、Retrieval Relevance(检索内容是否与问题相关)。安装pnpm install openevals,创建src/evals/evaluators.mjs:

import { createLLMAsJudge, RAG_GROUNDEDNESS_PROMPT, RAG_HELPFULNESS_PROMPT, RAG_RETRIEVAL_RELEVANCE_PROMPT } from "openevals"; import { ChatOpenAI } from "@langchain/openai"; const judge = new ChatOpenAI({ apiKey: process.env.OPENAI_API_KEY, configuration: { baseURL: process.env.OPENAI_BASE_URL }, model: process.env.MODEL_NAME ?? "qwen-plus", temperature: 0 }); const ragGroundednessJudge = createLLMAsJudge({ prompt: RAG_GROUNDEDNESS_PROMPT, feedbackKey: "rag_groundedness", judge, continuous: true }); const ragHelpfulnessJudge = createLLMAsJudge({ prompt: RAG_HELPFULNESS_PROMPT, feedbackKey: "rag_helpfulness", judge, continuous: true }); const ragRetrievalRelevanceJudge = createLLMAsJudge({ prompt: RAG_RETRIEVAL_RELEVANCE_PROMPT, feedbackKey: "rag_retrieval_relevance", judge, continuous: true }); export async function ragGroundednessEvaluator({ outputs }) { return ragGroundednessJudge({ context: { documents: outputs.context }, outputs: { answer: outputs.answer } }); } export async function ragHelpfulnessEvaluator({ inputs, outputs }) { return ragHelpfulnessJudge({ inputs, outputs: { answer: outputs.answer } }); } export async function ragRetrievalRelevanceEvaluator({ inputs, outputs }) { return ragRetrievalRelevanceJudge({ inputs, context: { documents: outputs.context } }); } export const ragEvaluators = [ ragGroundednessEvaluator, ragHelpfulnessEvaluator, ragRetrievalRelevanceEvaluator ];

三个指标到底在比较什么?Groundedness 比较 Answer 与 Context,关注模型说的内容是否有检索材料支撑;Helpfulness 比较 Answer 与 Question,关注是否答非所问;Retrieval Relevance 比较 Context 与 Question,关注 Retriever 返回的文档是否相关。于是一个 RAG 问题可以被拆成:检索对不对 → 检索正确后回答有没有依据 → 有依据后回答是否真正有用。这比单独给一个“总分”更容易定位问题。

七、Reference Output 与三个指标的关系

这里有一个容易误解的地方:Dataset 中虽然保存了 Reference Outputs,但上述三个 Evaluator 并没有直接使用它,因为它们分别比较的是 Answer vs Context、Answer vs Question、Context vs Question。比如 Reference Output 是“金卡会员享 95 折,同时拥有专属客服和每月优惠券”,而 Agent 只回答“金卡会员享 95 折”,某些指标依然可能给高分,因为这个回答没有脱离 Context,也确实回答了 Question。如果业务还希望评价 Actual Answer 与 Reference Answer 的差异,应再增加答案 Correctness 一类的 Evaluator。Dataset 可以保存标准答案,但最终哪些字段参与评分,由 Evaluator 决定。

八、Experiment:跑一次完整评估

创建src/evals/run_eval.mjs,先把 RAG 包装成评测目标,再调用evaluate():

import "dotenv/config"; import { Client } from "langsmith"; import { evaluate } from "langsmith/evaluation"; import { ask } from "../rag_agent.mjs"; import { ragEvaluators } from "./evaluators.mjs"; const DATASET_NAME = "rag-eval-v1"; const client = new Client({ apiKey: process.env.LANGCHAIN_API_KEY }); async function runRagAgent(inputs) { const { answer, context } = await ask(inputs.question); return { answer, context: context.map(doc => doc.pageContent) }; } async function main() { const result = await evaluate(runRagAgent, { data: DATASET_NAME, evaluators: ragEvaluators, client, experimentPrefix: `rag-openevals-${process.env.MODEL_NAME ?? "qwen"}`, maxConcurrency: 2 }); for await (const _row of result) { /* 等待所有样例完成 */ } console.log("✅ 评测完成"); console.log("实验名:", result.experimentName); } main();

运行node src/evals/run_eval.mjs,LangSmith 会创建一次新的 Experiment。进入Datasets & Experiments → rag-eval-v1 → Experiments,可以看到 Inputs、Reference Outputs、Outputs,以及rag_groundedness、rag_helpfulness、rag_retrieval_relevance等评分字段。评估不再是“感觉回答还不错”,而变成可量化的分数。

Experiment 的真正价值在比较:Experiment A 用原 Prompt,Experiment B 用新 Prompt;或者 Retriever k=4 对比 k=2;或者模型 A 对比模型 B。因为测试集没有变化,可以观察修改究竟让哪些指标变好、哪些变差。这才是 Dataset + Experiment 最核心的工程意义:修改前跑一次,修改后再跑一次,用数据判断修改是否真的有效。

九、把完整逻辑串起来

LangSmith 可以理解成两部分。第一部分是 Observability:Agent → Trace → Run(Input / Output / Error / Latency / Token / Tool Call / LLM Call),再向上汇总为 Monitoring(整体调用量、错误情况、耗时趋势、Token / Cost)。第二部分是 Evaluation:Dataset → Agent → Outputs → Evaluator → Scores → Experiment。它不是单纯的 Trace Viewer,而是把调试、监控、评估串成一套完整工作流。

五个核心概念可以记成一张表:Trace 是一次 Agent 调用的完整链路;Monitoring 是多次调用形成的整体运行统计;Dataset 是固定的测试样本集合;Evaluator 是自动评分规则;Experiment 是在 Dataset 上批量运行并评分的一次实验。对于已经能开发 LangGraph Agent 或 RAG 的工程师来说,LangSmith 真正解决的不是“怎么让 Agent 跑起来”,而是“跑起来以后怎么知道内部发生了什么”,以及“修改一版后怎么证明它真的比上一版更好”。前者由 Trace 和 Monitoring 解决,后者由 Dataset、Evaluator 和 Experiment 解决。当 Agent 从 Demo 走向真实项目,可观测与可评估往往比继续增加更多节点、更多工具调用更重要。

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

西源江河颂

遥溯江源雪岳雄,灵豹巡岩倚昊空。 来瞻金城波澹荡,沧流润彻皋兰崇。 滩头稚子嬉沙渚,筏上游人趁晚风。 画舫凌澜观浩渺,共揽烟波意自融。 奔流历涧携沙逝,远泻铺畴厚壤隆。 江河共铸神州野,沃壤丰穰四海雍。…

作者头像 李华
网站建设 2026/10/7 15:29:38

【专知智库】让数据变成零件,让零件变成资产,让资产驱动增长

让数据变成零件,让零件变成资产,让资产驱动增长专知智库,上市公司研发价值增长操作系统一、数据,为什么没有变成资产?每家公司都有大量数据。研发数据、专利数据、软著数据、合规数据、实验记录、技术方案、人员工时、…

作者头像 李华
网站建设 2026/10/7 15:29:10

挖到一款AI漫剧生成新项目|个人实测体验,一起来玩

最近一直在体验市面上各类AI视频漫剧工具,偶然拿到了新项目的小规模内测机会。 ⏰内测时间:10月13日‑10月19日 项目暂未对外公开,进入平台需要邀请码。 👉扫码进群即可领取内测邀请码:扫码进群即可获得邀请码 http…

作者头像 李华