ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

RAG + Agent 项目:普通 Python、LangChain、LangGraph 三种写法对比

RAG + Agent 项目:普通 Python、LangChain、LangGraph 三种写法对比 摘要LangSmith 不是业务框架它不负责帮你写 RAG、Agent、工具调用也不负责替你检索知识库。它的定位更像是大模型应用的Trace / Debug / Evaluation / Monitoring 平台。简单说它负责把一次 AI 请求从输入到输出的完整过程记录下来让你能看到用户输入是什么最终 Prompt 长什么样模型返回了什么哪一步耗时最长有没有报错token / 成本统计RAG 检索到了哪些内容Agent 调用了哪些工具在普通 Python 项目里你通常需要用 traceable、wrap_openai 显式埋点。在 LangChain / LangGraph 项目里只要配置好环境变量LangSmith 可以通过 LangChain / LangGraph 内部的 callback tracing 机制自动监听链路。目录文章目录LangSmith 如何监听 RAG Agent 项目普通 Python、LangChain、LangGraph 三种写法对比先说结论三种项目形态下LangSmith 的使用方式不一样。项目类型业务编排方式LangSmith 接入方式适合场景普通 RAG Agent 项目自己写 Python 函数、OpenAI SDK、工具函数traceablewrap_openai没用 LangChain / LangGraph但想看清调用链LangChain 项目Runnable、Agent、Tool、ChatOpenAI环境变量自动追踪必要时加run_name/tags/metadata快速搭建 RAG / Agent想少写监控代码LangGraph 项目StateGraph、节点、边、条件跳转、ToolNode环境变量自动追踪图节点和工具调用复杂 Agent、多步骤流程、多分支状态机最核心的环境变量是export LANGSMITH_TRACINGtrue export LANGSMITH_API_KEY你的 LangSmith API Key export LANGSMITH_PROJECT你的项目名这三行配置好以后LangChain / LangGraph 项目里的模型调用、工具调用、Runnable、Graph 节点就会自动被 LangSmith 记录。LangSmith 到底监听了什么LangSmith 监听的不是某个端口也不是偷偷扫描你的代码。它监听的是一次 AI 应用运行过程中的Run / Trace 事件。一次请求可以理解成一个 Trace用户问题 - 输入校验 - RAG 检索 - Prompt 拼装 - 模型调用 - Agent 工具调用 - 模型总结 - 最终回答LangSmith 会把上面每一步记录成节点每个节点都有自己的inputoutputstart timeend timedurationerrormetadatatagstoken usage所以当线上用户说“这个 AI 又乱答了”你不用只看日志猜问题而是可以打开 LangSmith 看完整链路。普通 RAG Agent 项目中如何用 LangSmith如果你的项目没有用 LangChain也没有用 LangGraph只是普通 Python 代码例如自己写检索函数自己拼 Prompt自己调用 OpenAI / DeepSeek / 通义等模型自己写工具函数这种情况下LangSmith 不知道你的业务函数谁是谁所以你需要显式告诉它哪些函数需要被记录。3.1 安装依赖pip install -U langsmith openai3.2 配置环境变量export LANGSMITH_TRACINGtrue export LANGSMITH_API_KEY你的 LangSmith API Key export LANGSMITH_PROJECTplain-rag-agent-demo export OPENAI_API_KEY你的模型 Key3.3 普通 Python 项目示例from openai import OpenAI from langsmith import traceable from langsmith.wrappers import wrap_openai client wrap_openai(OpenAI()) traceable(nameRAG 检索) def retrieve_docs(question: str) - list[str]: 根据用户问题检索知识库文档并让 LangSmith 记录检索输入和输出。 if 退款 in question: return [会员订单支持 7 天内无理由退款超过 7 天需要人工审核。] return [没有检索到明确匹配的知识片段。] traceable(namePrompt 拼装) def build_prompt(question: str, docs: list[str]) - list[dict[str, str]]: 把用户问题和检索结果拼成最终发送给模型的 messages。 context \n.join(docs) return [ { role: system, content: 你是一个严谨的中文业务助手只能基于给定上下文回答。, }, { role: user, content: f用户问题{question}\n\n检索上下文\n{context}, }, ] traceable(nameRAG 主流程) def answer_question(question: str) - str: 执行完整 RAG 流程并让 LangSmith 串联检索、Prompt 和模型调用。 docs retrieve_docs(question) messages build_prompt(question, docs) response client.chat.completions.create( modelgpt-4o-mini, messagesmessages, temperature0, ) return response.choices[0].message.content if __name__ __main__: print(answer_question(会员订单可以退款吗))3.4 这时 LangSmith 能看到什么你关心的问题LangSmith 里看哪里用户输入是什么RAG 主流程的 inputRAG 检索到了什么RAG 检索的 outputPrompt 最终长什么样Prompt 拼装的 output模型返回了什么OpenAI 调用节点的 outputtoken / 成本统计OpenAI 调用节点哪一步耗时最长Trace 树中每个节点的 duration有没有报错出错节点会显示 error3.5 普通项目的特点优点不依赖 LangChain / LangGraph改造成本低适合已有老项目逐步接入缺点需要自己决定哪些函数加 traceable工具调用、检索、Agent 循环结构需要自己标注清楚链路复杂后埋点容易散LangChain 项目中如何用 LangSmithLangChain 本身已经有统一的 Runnable、Agent、Tool、Model 抽象。所以在 LangChain 项目里LangSmith 不一定需要你手动写 traceable。只要开启export LANGSMITH_TRACINGtrueLangChain 执行过程中的 Runnable、Agent、Tool、模型调用就会被自动记录。4.1 安装依赖pip install -U langchain langchain-openai langsmith4.2 配置环境变量export LANGSMITH_TRACINGtrue export LANGSMITH_API_KEY你的 LangSmith API Key export LANGSMITH_PROJECTlangchain-rag-agent-demo export OPENAI_API_KEY你的模型 Key4.3 LangChain 业务示例import re from langchain.agents import create_agent from langchain.tools import tool from langchain_core.runnables import RunnableLambda from langchain_openai import ChatOpenAI KNOWLEDGE_BASE [ { doc_id: doc-001, title: 退款政策, content: 会员订单支持 7 天内无理由退款超过 7 天需要人工审核。, }, { doc_id: doc-002, title: 六月销售数据, content: 2026 年 6 月 A 产品销售额 1200 元B 产品销售额 800 元。, }, ] def validate_user_input(user_input: str) - dict: 校验用户输入并转换成 LangChain Agent 接收的 messages 格式。 question user_input.strip() if not question: raise ValueError(用户问题不能为空) return {messages: [{role: user, content: question}]} tool def retrieve_docs(question: str) - list[dict]: 根据用户问题检索知识库文档LangSmith 会记录这个工具的输入和输出。 return [ doc for doc in KNOWLEDGE_BASE if any(word in question for word in [退款, 销售, 销售额]) ] tool def calculate_sum(text: str) - dict: 从文本中提取金额并计算合计LangSmith 会记录 Agent 的工具调用。 numbers [float(value) for value in re.findall(r(\d(?:\.\d)?)\s*元, text)] return {numbers: numbers, total: sum(numbers)} def extract_final_answer(agent_result: dict) - str: 从 Agent 返回结果中提取最后一条模型回答。 return agent_result[messages][-1].content model ChatOpenAI(modelgpt-4o-mini, temperature0) agent create_agent( modelmodel, tools[retrieve_docs, calculate_sum], system_prompt( 你是一个严谨的中文业务助手。 回答业务问题时必须先调用 retrieve_docs 检索知识库 如果问题涉及合计、总共、总销售额再调用 calculate_sum 做计算。 ), ) business_chain ( RunnableLambda(validate_user_input).with_config({run_name: 输入校验}) | agent.with_config({run_name: LangChain Agent 业务链路}) | RunnableLambda(extract_final_answer).with_config({run_name: 提取最终回答}) ).with_config({run_name: LangSmith 监听的 LangChain 业务请求}) if __name__ __main__: answer business_chain.invoke( 2026 年 6 月 A 产品和 B 产品总销售额是多少, config{ tags: [langsmith, langchain, rag, agent], metadata: { request_id: req-001, user_id: user-123, }, }, ) print(answer)4.4 这段代码里 LangSmith 在哪里代码里没有直接写from langsmith import Client也没有手动写client.create_run(...)LangSmith 的监听来自环境变量export LANGSMITH_TRACINGtrue export LANGSMITH_API_KEY你的 LangSmith API Key然后 LangChain 在执行business_chain.invoke(...)时会通过内部 callback tracing 机制把这些事件发给 LangSmithRunnable 开始Runnable 结束LLM 开始LLM 结束Tool 开始Tool 结束Chain 报错4.5 with_config({“run_name”: “输入校验”}) 是什么这句RunnableLambda(validate_user_input).with_config({run_name: 输入校验})不是开启 LangSmith 的关键。它的作用是给这个节点起一个更好识别的名字。没有它LangSmith 仍然能记录但页面上可能显示默认名称不方便定位。类似地config{ tags: [langsmith, langchain, rag, agent], metadata: { request_id: req-001, user_id: user-123, }, }也不是必须的。它的作用是让你在 LangSmith 后台更方便筛选和排查例如按 request_id 找某一次请求。4.6 如果不用 LangSmith可以怎么写如果不用 LangSmith但还想用 LangChain 链式语法可以去掉 with_configbusiness_chain ( RunnableLambda(validate_user_input) | agent | RunnableLambda(extract_final_answer) )注意不能直接写business_chain ( validate_user_input | agent | extract_final_answer )因为普通 Python 函数不能直接用 | 连接。需要先用 RunnableLambda 包装成 LangChain Runnable。4.7 LangChain 项目中 LangSmith 能看到什么你关心的问题LangSmith 里看哪里用户输入是什么根 Trace 的 inputPrompt 最终长什么样ChatOpenAI 模型调用节点里的 messages模型返回了什么模型调用节点 output哪一步耗时最长每个 Runnable / Tool / LLM 节点的 duration有没有报错报错节点会标红token / 成本统计ChatOpenAI 调用节点RAG 检索到了哪些内容retrieve_docs工具节点 outputAgent 调用了哪些工具Agent 节点下面的 tool callsLangGraph 项目中如何用 LangSmithLangGraph 更适合复杂 Agent。如果 LangChain Agent 更像一个封装好的 Agent 执行器那么 LangGraph 更像是你自己画一个状态机START - validate_input - llm_call - tools - llm_call - END每一个节点、每一条边、每一次条件判断都可以被清晰地组织起来。LangSmith 监听 LangGraph 时会把图节点、模型调用、工具调用都记录下来。5.1 安装依赖pip install -U langgraph langchain langchain-openai langsmith5.2 配置环境变量export LANGSMITH_TRACINGtrue export LANGSMITH_API_KEY你的 LangSmith API Key export LANGSMITH_PROJECTlanggraph-rag-agent-demo export OPENAI_API_KEY你的模型 Key5.3 LangGraph 业务示例import re from typing import Annotated, Any, Literal from langchain.tools import tool from langchain_core.messages import BaseMessage, HumanMessage, SystemMessage from langchain_openai import ChatOpenAI from langgraph.graph import END, START, StateGraph, add_messages from langgraph.prebuilt import ToolNode from typing_extensions import TypedDict class AgentState(TypedDict): 定义 LangGraph 状态messages 会在节点之间持续累加。 messages: Annotated[list[BaseMessage], add_messages] KNOWLEDGE_BASE [ { doc_id: doc-001, title: 退款政策, content: 会员订单支持 7 天内无理由退款超过 7 天需要人工审核。, }, { doc_id: doc-002, title: 六月销售数据, content: 2026 年 6 月 A 产品销售额 1200 元B 产品销售额 800 元。, }, ] tool def retrieve_docs(question: str) - list[dict[str, Any]]: 根据用户问题检索 RAG 文档LangSmith 会记录工具输入和输出。 return [ doc for doc in KNOWLEDGE_BASE if any(word in question for word in [退款, 销售, 销售额]) ] tool def calculate_sum(text: str) - dict[str, Any]: 从文本中提取金额并计算合计用于演示 Agent 工具调用。 numbers [float(value) for value in re.findall(r(\d(?:\.\d)?)\s*元, text)] return {numbers: numbers, total: sum(numbers)} TOOLS [retrieve_docs, calculate_sum] model ChatOpenAI(modelgpt-4o-mini, temperature0) model_with_tools model.bind_tools(TOOLS) SYSTEM_PROMPT ( 你是一个严谨的中文业务助手。 回答业务问题时必须先调用 retrieve_docs 检索知识库 如果问题涉及合计、总共、总销售额再调用 calculate_sum 做计算。 ) def validate_input(state: AgentState) - dict: 校验用户输入异常会被 LangSmith 标记为错误节点。 if not state[messages]: raise ValueError(messages 不能为空) first_message state[messages][0] if not str(first_message.content).strip(): raise ValueError(用户问题不能为空) return {} def call_llm(state: AgentState) - dict: 调用绑定工具后的模型由模型决定是否继续请求工具调用。 messages [ SystemMessage(contentSYSTEM_PROMPT), *state[messages], ] response model_with_tools.invoke(messages) return {messages: [response]} def should_continue(state: AgentState) - Literal[tools, __end__]: 根据最后一条模型消息是否包含 tool_calls 决定下一步。 last_message state[messages][-1] if getattr(last_message, tool_calls, None): return tools return END graph_builder StateGraph(AgentState) graph_builder.add_node(validate_input, validate_input) graph_builder.add_node(llm_call, call_llm) graph_builder.add_node(tools, ToolNode(TOOLS)) graph_builder.add_edge(START, validate_input) graph_builder.add_edge(validate_input, llm_call) graph_builder.add_conditional_edges(llm_call, should_continue, [tools, END]) graph_builder.add_edge(tools, llm_call) graph graph_builder.compile() if __name__ __main__: result graph.invoke( { messages: [ HumanMessage(content2026 年 6 月 A 产品和 B 产品总销售额是多少) ] }, config{ run_name: LangGraph RAG Agent 业务请求, tags: [langsmith, langgraph, rag, agent], metadata: { request_id: req-001, user_id: user-123, }, }, ) print(result[messages][-1].content)5.4 LangSmith 是如何监听 LangGraph 的关键还是环境变量export LANGSMITH_TRACINGtrue执行graph.invoke(...)时LangGraph 会执行这些节点validate_input llm_call tools llm_call每个节点运行时都会通过 LangChain / LangGraph 的 tracing callback 产生事件。LangSmith 接收到这些事件后就能在后台展示一棵 Trace 树。5.5 LangGraph 中 config 不写会怎样这段config{ run_name: LangGraph RAG Agent 业务请求, tags: [langsmith, langgraph, rag, agent], metadata: { request_id: req-001, user_id: user-123, }, }不写也能运行。也不会影响 LangSmith 是否监听。真正影响监听的是LANGSMITH_TRACINGtrue LANGSMITH_API_KEY...config 的作用只是run_name给这次运行起一个好认的名字tags方便在 LangSmith 后台筛选metadata记录业务上下文例如 request_id、环境、租户 ID生产环境建议至少保留 request_id这样后端日志和 LangSmith Trace 能对上。5.6 LangGraph 项目中 LangSmith 能看到什么你关心的问题LangSmith 里看哪里用户输入是什么graph.invoke的 inputPrompt 最终长什么样llm_call里的模型调用 messages模型返回了什么llm_call模型节点 output哪一步耗时最长图节点和子节点的 duration有没有报错validate_input/tools/llm_call出错时会标红token / 成本统计模型调用节点RAG 检索到了哪些内容tools节点下的retrieve_docsoutputAgent 调用了哪些工具ToolNode下的 tool calls三种写法怎么选6.1 已有普通 Python 项目如果你已经写好了业务代码只是想加观测优先用from langsmith import traceable from langsmith.wrappers import wrap_openai适合现有代码不想大改只想追踪几个关键函数项目暂时不需要 LangChain / LangGraph6.2 新项目流程不复杂如果你只是做一个常规 RAG Agent用户输入 - 检索 - Prompt - 模型 - 工具 - 回答可以优先用 LangChain。它的好处是上手快集成模型和工具方便LangSmith 自动追踪代码比纯手写 Agent 简洁6.3 复杂 Agent、多分支、多状态如果你的流程像这样用户输入 - 意图识别 - 路由到不同 Agent - 检索 - 工具调用 - 人工确认 - 再次调用模型 - 总结输出建议用 LangGraph。LangGraph 更适合多步骤工作流多 Agent 协作条件分支循环调用人工介入状态持久化LangSmith 在这种场景下特别有价值因为你可以看到复杂图结构里到底卡在哪一步。实战建议7.1 不要一上来就追求复杂评测第一次接 LangSmith建议先做 Trace。先确认你能看到输入检索结果Prompt模型输出工具调用token报错这些都看清楚以后再做 Dataset、Evaluation、Prompt 对比。7.2 生产环境一定要加 request_id建议每次请求都带上config{ metadata: { request_id: request_id, env: prod, } }这样用户反馈问题时你可以用户报错 - 后端日志查 request_id - LangSmith 查 trace - 定位问题节点7.3 不要直接记录敏感信息LangSmith 会记录输入、输出、Prompt、metadata。所以不要直接放手机号身份证邮箱明文 token内部密钥完整用户隐私文本生产环境要做脱敏或最小化记录。7.4 run_name 要有业务含义不要全叫chain node run function建议叫输入校验 知识库检索 订单工具调用 模型生成回答 客服 Agent 主流程这样在 LangSmith UI 里排查问题会快很多。7.5 LangSmith 不替代日志LangSmith 很适合看大模型调用链但它不应该完全替代后端日志。建议后端日志记录系统级错误、请求 ID、接口耗时LangSmith 记录 LLM / RAG / Agent 的内部链路两边用 request_id 打通常见误区8.1 误区一代码里没 import langsmith就说明没用 LangSmith不一定。LangChain / LangGraph 项目里LangSmith 经常是通过环境变量自动启用的。只要有LANGSMITH_TRACINGtrue并且安装了 langsmithLangChain / LangGraph 的运行过程就可以自动上报。8.2 误区二run_name 是开启监听的开关不是。run_name 只是展示名。开启监听靠LANGSMITH_TRACINGtrue LANGSMITH_API_KEY...8.3 误区三LangSmith 会自动知道你的普通 Python 函数普通 Python 函数不会天然被 LangSmith 知道。如果不用 LangChain / LangGraph建议加traceable8.4 误区四用了 LangSmith 就不用关心 Prompt 版本LangSmith 能帮你记录 Prompt但 Prompt 怎么设计、怎么版本管理、怎么评测仍然需要你自己建立流程。建议把坏案例沉淀为 Dataset然后用 Evaluation 对比不同 Prompt 和模型。最后对于正在迷茫择业、想转行提升或是刚入门的程序员、编程小白来说有一个问题几乎人人都在问未来10年什么领域的职业发展潜力最大答案只有一个人工智能尤其是大模型方向当下人工智能行业正处于爆发式增长期其中大模型相关岗位更是供不应求薪资待遇直接拉满——字节跳动作为AI领域的头部玩家给硕士毕业的优质AI人才含大模型相关方向开出的月基础工资高达5万—6万元即便是非“人才计划”的普通应聘者月基础工资也能稳定在4万元左右。再看阿里、腾讯两大互联网大厂非“人才计划”的AI相关岗位应聘者月基础工资也约有3万元远超其他行业同资历岗位的薪资水平对于程序员、小白来说无疑是绝佳的转型和提升赛道。如果你还不知道从何开始我自己整理一套全网最全最细的大模型零基础教程我也是一路自学走过来的很清楚小白前期学习的痛楚你要是没有方向还没有好的资源根本学不到东西下面是我整理的大模型学习资源希望能帮到你。扫码免费领取全部内容最后1、大模型学习路线2、从0到进阶大模型学习视频教程从入门到进阶这里都有跟着老师学习事半功倍。3、 入门必看大模型学习书籍文档.pdf书面上的技术书籍确实太多了这些是我精选出来的还有很多不在图里4、AI大模型最新行业报告2026最新行业报告针对不同行业的现状、趋势、问题、机会等进行系统地调研和评估以了解哪些行业更适合引入大模型的技术和应用以及在哪些方面可以发挥大模型的优势。5、面试试题/经验【大厂 AI 岗位面经分享107 道】【AI 大模型面试真题102 道】【LLMs 面试真题97 道】6、大模型项目实战配套源码适用人群四阶段学习规划共90天可落地执行第一阶段10天初阶应用该阶段让大家对大模型 AI有一个最前沿的认识对大模型 AI 的理解超过 95% 的人可以在相关讨论时发表高级、不跟风、又接地气的见解别人只会和 AI 聊天而你能调教 AI并能用代码将大模型和业务衔接。大模型 AI 能干什么大模型是怎样获得「智能」的用好 AI 的核心心法大模型应用业务架构大模型应用技术架构代码示例向 GPT-3.5 灌入新知识提示工程的意义和核心思想Prompt 典型构成指令调优方法论思维链和思维树Prompt 攻击和防范…第二阶段30天高阶应用该阶段我们正式进入大模型 AI 进阶实战学习学会构造私有知识库扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架抓住最新的技术进展适合 Python 和 JavaScript 程序员。为什么要做 RAG搭建一个简单的 ChatPDF检索的基础概念什么是向量表示Embeddings向量数据库与向量检索基于向量检索的 RAG搭建 RAG 系统的扩展知识混合检索与 RAG-Fusion 简介向量模型本地部署…第三阶段30天模型训练恭喜你如果学到这里你基本可以找到一份大模型 AI相关的工作自己也能训练 GPT 了通过微调训练自己的垂直大模型能独立训练开源多模态大模型掌握更多技术方案。到此为止大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗为什么要做 RAG什么是模型什么是模型训练求解器 损失函数简介小实验2手写一个简单的神经网络并训练它什么是训练/预训练/微调/轻量化微调Transformer结构简介轻量化微调实验数据集的构建…第四阶段20天商业闭环对全球大模型从性能、吞吐量、成本等方面有一定的认知可以在云端和本地等多种环境下部署大模型找到适合自己的项目/创业方向做一名被 AI 武装的产品经理。硬件选型带你了解全球大模型使用国产大模型服务搭建 OpenAI 代理热身基于阿里云 PAI 部署 Stable Diffusion在本地计算机运行大模型大模型的私有化部署基于 vLLM 部署大模型案例如何优雅地在阿里云私有部署开源大模型部署一套开源 LLM 项目内容安全互联网信息服务算法备案…扫码免费领取全部内容3、这些资料真的有用吗这份资料由我和鲁为民博士(北京清华大学学士和美国加州理工学院博士)共同整理现任上海殷泊信息科技CEO其创立的MoPaaS云平台获Forrester全球’强劲表现者’认证服务航天科工、国家电网等1000企业以第一作者在IEEE Transactions发表论文50篇获NASA JPL火星探测系统强化学习专利等35项中美专利。本套AI大模型课程由清华大学-加州理工双料博士、吴文俊人工智能奖得主鲁为民教授领衔研发。资料内容涵盖了从入门到进阶的各类视频教程和实战项目无论你是小白还是有些技术基础的技术人员这份资料都绝对能帮助你提升薪资待遇转行大模型岗位。这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】
返回列表