ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

从提示词到RAG再到Agent:LangChain全链路实战指南

从提示词到RAG再到Agent:LangChain全链路实战指南 先说个现象我这两年接触了不少做后端、前端、甚至刚转型 AI 的开发者大家最困惑的点出奇一致——大模型单个能聊得挺好但一放到真实业务里就露馅回答私域问题时没数据、靠编想让模型按流程调用接口和工具又不知道从哪下手更不用提知识库问答、智能客服、自动化办公这类需求工具链一个接一个根本学不完。这些问题的答案其实都落在同一条主线上提示词 Prompt 打底RAG 解决知识来源Agent 解决任务执行而 LangChain 恰好是把这三件事串起来的主力框架。这篇文章想做的不是把 LangChain 的 API 文档翻译一遍而是按我实际项目的推进顺序讲清楚「为什么先学提示词、再上 RAG、最后做 Agent」以及从零到一个能跑起来的实战项目整条链路上哪些地方最容易翻车、怎么调最有效。无论你是刚接触大模型开发的入门者还是已经写过几个 Demo、想系统梳理知识体系的同学这条路径都值得按顺序走一遍。1. 为什么是 LangChain从提示词、RAG 到 Agent 的技术选型脉络1.1 大模型能力边界决定了应用层必须有一层胶水先从根上说大模型本身很强但它有几个与生俱来的短板。第一知识新鲜度不足训练数据有截止日期拿它问公司内部新制度、新项目的进展它完全不知道。第二它天然存在幻觉尤其在缺少上下文或上下文模糊的时候它会用概率生成一段听起来合理但不真实的回答。第三它只是一个文本生成器不主动执行动作你问它帮我查一下订单状态并退款它顶多给你写一段代码教你手动做而不会真的发起 HTTP 调用。这几个短板单靠模型本身没法解决需要在外围加一层胶水把模型和真实世界连接起来。LangChain 在 2022 年末到 2023 年之间迅速流行靠的就是它把这些外围能力做了统一抽象对模型的封装、对提示词的管理、对文档和检索的抽象、对工具调用的支持、对多步骤流程的编排。这套抽象让你可以用相对统一的方式组合出提示词、RAG 和 Agent 三类应用不需要从零去对接各个模型的 API、自己管理向量库、自己实现工具调用的 Socket 逻辑。1.2 LangChain 的架构分层和你要完成的业务目标一一对应很多初学者第一次看 LangChain 的官方文档感觉模块非常多容易头晕。其实它主要分这几块每一块都能对应到一个具体业务问题LangChain 模块对应业务需求核心作用Models模型封装让不同大模型统一接入屏蔽各家 API 差异方便替换Prompts提示词管理控制模型输出质量模板化、结构化地组织输入Chains链组合固定流程把检索知识 → 拼装上下文 → 生成回答串起来Retrievers检索器从私有知识里找到相关信息RAG 的核心抽象Tools工具让模型调用外部能力查询数据库、调用接口、执行代码Agents智能体让模型自己决策做什么基于大模型自动规划任务步骤Memory记忆保存多轮对话状态让应用拥有上下文记忆这类比一下Chains 相当于写死的流水线适合流程明确、不需要变化的场景Agents 相当于让流水线工人看情况决定先做哪一步适合任务不固定、需要临场决策的场景。RAG 则是给这个流水线加了一个外接资料库让系统在回答之前先去查资料而不是只靠模型脑内知识。我实际用下来的感受是Chains 和 Agents 不是非此即彼的关系。一个复杂的智能体系统往往内部就是由多条 Chain 组成的Agent 负责调度Chain 负责执行某个具体的确定性步骤。LangChain 把两者统一在同一套抽象里切换起来非常顺。1.3 LangChain 与 LangGraph编排能力的两代方案讨论 LangChain 时绕不开 LangGraph。官方在 2024 年推出 LangGraph初衷就是解决 LangChain 在复杂流程编排上的短板——尤其是循环和状态的精细控制。我用一个真实场景来说明它们的区别。假设要实现一个 RAG 客服机器人用户问完问题、系统检索、模型回答这一步用 LangChain 的链式调用就够了因为流程是线性的。但如果要做的是一个能自我纠错的 Agent它先拆解任务调用搜索工具发现结果不够再改写查询词重新搜索最后汇总答案——这里就有循环有分支有中间状态的多次读写用传统的 Chain 写非常别扭。LangGraph 把它建模成一个图结构节点Node代表一次计算边Edge代表流转逻辑循环、条件分支、人工介入都很好表达。所以我的选型建议是标准 RAG、简单的顺序调用、工具数量少的 Agent直接用 LangChain 的 LCELLangChain Expression Language或传统的 Chain 就够学习成本低代码也好维护。多工具、长流程、需要人工确认、需要失败重试、需要过程可观测的 Agent优先上 LangGraph。两者并不冲突LangGraph 运行在 LangChain 的模型、检索器、工具抽象之上。先掌握 LangChain 核心再上手 LangGraph切过去不会很难。后面我讲实战时会在 RAG 部分用类似 Chain 的写法在 Agent 部分提到 LangGraph 的思路正好覆盖两种主流写法。2. 提示词工程大模型应用的地基别急着直接写 RAG2.1 提示词质量决定 RAG、Agent 效果的上限有个观点我觉得需要先纠正很多新手一上来就急着接大模型、搞向量库、做知识库问答。结果做完发现回答很烂然后归咎于RAG 没用、向量检索不准。但实际情况往往是他在生成那一步给模型的提示词太简陋了模型根本不知道自己该以什么身份、用什么规则、基于哪部分资料来回答。提示词看起来只是给模型写几句话但它的质量直接决定下游所有环节的上限。RAG 检索到再好的知识最后还是要靠提示词引导模型正确使用这些知识Agent 买到再好的工具还是要靠提示词让模型理解什么情况调用哪个工具、参数怎么传。我把提示词工程放在第一步就是因为后面每一个项目能跑多好都建立在它上面。一个合格的答案生成提示词至少需要写清楚四件事角色、任务、约束、输入数据的位置。拿一个企业制度问答机器人举例不达标的提示词可能是请回答以下问题{question}。而达标的提示词应该是你是一名企业内部制度问答助手。你只能基于「员工手册」中的内容回答严禁编造事实。 回答要求 1. 如果资料中有明确答案请引用原文后简要解释。 2. 如果资料中没有相关信息直接回复“该问题无法在企业制度中找到对应答案”不要尝试脑补。 3. 回答控制在200字以内用通俗易懂的语言说明。 4. 遇到涉及报销、请假、加班等高频问题优先给出一二三步骤。 以下是参考资料 {context} 员工的问题是{question}对比就能看出差别第二版给了模型明确的身份、明确的范围、明确的兜底策略、明确的输出格式模型犯错的概率会小很多。这不是玄学而是大模型本质是概率补全器你给它越清晰的框架它越不容易自己发挥。2.2 LangChain 的提示词模板与输出解析让提示词工程工程化在 LangChain 里提示词管理不是一个简单的字符串拼接它提供了 Prompt Template 机制把提示词模板和运行时变量分离。模板里用大括号占位符运行时传入实际值很方便做复用和版本管理。你写一个模板可以在知识库问答、Agent 对话、AI 客服等多个场景里复用只要替换对应的{question}、{context}、{history}变量。另外一块容易被低估的是输出解析Output Parser。大模型输出的是文本但业务系统往往需要结构化数据比如 JSON、Markdown 表格、Python 字典。LangChain 的 PydanticOutputParser 可以先定义返回的数据结构然后在提示词里让模型按这个结构输出再自动解析成对象。这在构建 Agent 时尤其关键——模型决定调用哪个工具需要通过程序读取出工具名和参数而不是靠人去人肉提取。我用 LangChain 写过不少这类代码你会发现提示词工程做扎实后后面接 RAG 和 Agent 都会意外地顺利。因为模型输出的稳定性和可解析性提升了排错的精力会大幅减少。2.3 提示词的评测方法不要靠感觉调优提示词工程最容易踩的坑是感觉派调优改几个字测一两个 case感觉变好了就上线。这种做法的风险在于个别 case 好不代表整体稳定。我给团队定的方法是建一组固定的评测集里面有标准答案和期望行为每次改完提示词跑完整组测试集比较通过率和回答质量。评测集怎么建从真实或模拟的用户问题里抽出50~100条有代表性的覆盖高频问题、边界问题比如资料里没有、诱导性问题比如制度里没写你觉得该不该报销。每条标注期望行为分成应该直接回答应该拒绝回答应该引导用户提供更多信息等几类。然后每次调提示词看这组问题的通过率变化。这个习惯坚持下来效果比任何玄学调优都可靠。3. RAG 知识库实战从文档加载到检索增强生成3.1 RAG 为什么能解决幻觉但又不是银弹RAGRetrieval-Augmented Generation检索增强生成的核心逻辑不复杂在大模型回答之前先从外部知识库里检索出与用户问题最相关的片段把片段作为上下文塞进提示词再让模型基于这些片段生成答案。它的本质是不改变模型本身的参数只改变模型拿到的那一张写满上下文的纸。这套机制在解决私域知识问答上非常有效。因为大模型本身不具备你的企业内部知识但只要你把资料喂给它它就能照着资料说话。而且它的幻觉比纯靠模型记忆要小因为模型不再是自由发挥而是在给定资料约束下做摘要和改写。但我必须说清楚RAG 不是万能药常见的问题有四类检索召回不准相关片段没被找回模型拿不到有效信息只能胡编。上下文过长导致关键信息被淹没找回来太多片段模型找不到重点。多个文档之间内容冲突模型不知道信谁回答自相矛盾或干脆各说各话。检索到了相关信息但模型理解错了用户意图比如用户问的是 A 产品的退换货政策检索系统召回的是 B 产品的格式对但内容不对模型也不知道纠正。这四类问题有一半是检索链路的问题有一半是提示词和模型使用方式的问题。所以做 RAG检索链路和生成链路要一起调不能只盯一头。3.2 文档加载与切片RAG 的第一个关键决策RAG 流程的第一步是把文档变成模型能理解的格式。常见操作是用 LangChain 的 Document Loader 加载 PDF、Word、Markdown 等格式的文档然后做切片Splitting。切片看起来简单实际上是最容易犯错的地方。常见错误是直接把整个文件当一个片段传给模型超长内容超出上下文窗口是一回事就算没超出模型也很难在一大堆文字里精准找到答案这个现象我一般叫针在大海捞。正确的切片策略需要结合文档结构来定结构化文档先按标题、段落、表格切分保持语义完整。再配合 RecursiveCharacterTextSplitter 设定 chunk_size 和 chunk_overlap。chunk_size 我常用 400800 个 token 之间chunk_overlap 50100既能保留上下文衔接又不会让每一个片段太臃肿。表格类内容要单独处理直接转纯文本会破坏行列关系建议先转成 Markdown 表格再分割。代码类文档不要用通用切分器建议用代码语言对应的分割器避免把函数体拦腰截断。切片前做一次清洗也很重要比如去掉页眉页脚、去掉无关的换行和空格、标准化全半角符号。这些脏数据看着不起眼但嵌入之后会显著拉低检索准确率实测过太多项目栽在这上面。3.3 嵌入模型与向量库选型没有最好的只有最合适的文档切片后要把每段文字转成向量Embedding存进向量数据库。这一步有两个选型问题嵌入模型选什么、向量库选什么。嵌入模型决定语义相似的判别标准。不同语言、不同领域向量化效果差别很大。通用场景用 OpenAI 的 text-embedding-3 或国内的通义、文心等云服务嵌入接口对中文私有数据BGE 系列、M3E 系列在本地部署场景很常用对代码和英文混合数据代码模型专用嵌入也比通用嵌入更准。我见过不少项目的检索不准根源不是向量库有问题而是嵌入模型和语料语言不匹配。向量库选型要看数据规模、访问量和部署条件场景推荐方案优缺点原型 Demo、小规模数据Chroma、FAISS部署简单轻量适合单机跑通中等规模、需要持久化Milvus Lite / Qdrant支持集合管理检索性能稳定大规模生产集群Milvus、Weaviate支持分布式、高可用、多租户已有关系型数据库基础设施pgvector不用引入额外组件SQL 一把梭这里有个容易被忽视的点选型时别只看向量检索快不快也要看数据管理方不方便。项目上线后免不了增删改文档是管理文档元数据来源、更新时间、权限、做过滤条件查询这些功能向量库之间的差距比检索性能还大。3.4 检索增强从简单相似度到混合检索与重排序文档存进向量库后检索环节是 RAG 效果最明显的提升点。很多入门教程就一句vector_store.similarity_search(query)但实际项目里单独用语义相似度召回远远不够。语义检索的优点是对同义改写、模糊表达效果好但它对专有名词、精确 ID、人名、缩写往往会失准。比如用户问HR-2024-001 号文件出了什么问题这串编号直接做向量相似度召回结果可能完全不对。这时候就需要做混合检索向量检索负责召回语义相近片段同时跑一层关键词/全文检索用 BM25再把两路结果合并。LangChain 的 EnsembleRetriever 可以把向量检索和 BM25 检索的结果做加权合并这一招在实际项目里经常能涨点。检索结果回来之后还有最后一道提升利器重排序Rerank。第一轮召回可能拿到 20 甚至 50 个片段把它们全塞给模型既浪费 tokens 又稀释注意力。更聪明的做法是第一轮先用低成本的快速检索召回一个比较大的候选集再让一个专门的重排序模型比如 Cohere Rerank、BGE-Reranker对这些片段逐条打分取 top 3~5 送去生成答案。这样最后的上下文更聚焦回答质量也会更稳定。3.5 生成环节与提示词结合知识、问题、历史的组合拳RAG 的最后一步是生成这一步往往被新手当成直接把 context 和 question 拼进去就完事。实际上生成提示词的质量能直接决定模型是用知识库好好回答还是开始自由发挥。生成提示词至少需要做到三点明确告诉模型只能基于上述资料回答并交代如果资料里没有相关内容该怎样回应。给一个提问前置判断比如先判断用户意图是查询制度、查询流程还是闲聊涉及不同意图走不同的回答策略。把多轮对话历史拼接进去让模型在追问场景下能理解指代比如用户上一轮问了请假流程这一轮说那需要提前几天报备模型知道这里的那指什么。我在 LangChain 里通常会用 Chain 的方式把这部分组装好先加载文档并切片然后用 retriever 检索再把这个回答模板传给 LLM。整条链路用 LCEL 的retriever | prompt | llm | parser写法非常清晰也方便后续加日志和监控。4. Agent 智能体构建让大模型学会使用工具4.1 Agent 的核心机制从推理到行动再到观察如果说 RAG 解决的是让大模型知道更多那 Agent 解决的是让大模型能做更多。Agent 的核心机制可以总结为一个循环推理Reason → 行动Act → 观察Observe → 再推理……这个范式叫 ReAct也是 LangChain Agent 底层的经典实现。它的原理可以这么理解你给大模型一个个工具每个工具都有名字和描述告诉它这个工具能干什么。用户提问后模型不是直接回答而是先判断要回答这个问题我需要调用哪个工具、传入什么参数然后生成一个工具调用指令。程序拿到这个指令后帮它调用真的函数或 API拿到结果后再把结果反馈给模型模型基于这个结果决定下一步是继续调用其他工具还是整理最终答案。这个设计解决了一个大问题把知识问答和动作执行统一在了一起。举个例子用户问我现在可以请几天年假普通 RAG 只能查到年假制度但 Agent 可以拆解成两步第一步查制度中的年假天数规则第二步调用内部系统的 API 查这个员工已休天数最后算出差值给出结论。单靠一条 RAG 链是做不到这种多步推理和工具调用的。4.2 用 LangChain 组装一个带工具的 Agent手写可复现的骨架在 LangChain 里组装一个 Agent核心分四步定义模型、定义工具、创建提示词、绑定执行器。先把工具定义清楚。LangChain 支持用tool装饰器快速把一个函数变成模型可调用的工具from langchain_core.tools import tool tool def get_employee_leave_days(employee_id: str) - str: 查询指定员工已休年假天数单位天输入员工工号。 # 这里实际开发时替换成真实数据库/API 调用 return f员工 {employee_id} 已休年假 7.5 天这里有个很容易踩的坑工具的描述docstring写得好不好直接影响模型会不会正确调用它。描述越明确模型越知道什么情况下该用这个工具、输入的参数是什么格式、输出代表什么。我见过太多人工具写好了但 docstring 乱写结果模型要么不调用要么乱传参数。再定义模型和绑定工具from langchain_openai import ChatOpenAI from langchain.agents import create_tool_calling_agent, AgentExecutor llm ChatOpenAI(modelgpt-4o-mini, temperature0) tools [get_employee_leave_days] prompt 你是一个企业行政助手。请根据用户问题选择合适的工具并完成回答。 如果一次调用不足以回答可以继续调用其他工具或基于上一次工具的结果再次分析。 可用工具 {tools} 注意 - 当需要查询员工已休年假时必须调用 get_employee_leave_days。 - 当工具返回结果与用户预期不一致时如实回答不要编造。 - 不要试图使用未提供的工具。 用户问题{input} 运行过程记录{agent_scratchpad} agent create_tool_calling_agent(llm, tools, promptprompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue) result agent_executor.invoke({input: 工号A1024的同事今年还能请几天年假})这个例子里agent_scratchpad是 LangChain 用来记录模型思考过程、已调用工具以及工具返回结果的地方相当于给模型一张看得见过去步骤的草稿纸这是 Agent 维持多步推理的关键。没有它模型会忘记自己已经查过什么。LangGraph 的做法稍微不同它会显式地把模型节点、工具节点、条件边画成一个图循环由图结构表达。实话说 LangGraph 初学比 LangChain 直接用 AgentExecutor 陡峭但对于正式的工业生产级 Agent我会更推荐 LangGraph因为它天然适合插入人工审批、异常重试等复杂控制逻辑。4.3 Agent 的常见陷阱死循环、错误恢复、上下文失控Agent 听起来美好但实际跑起来问题并不少。我自己踩过并帮别人排查过的典型问题主要有四个。第一个是死循环。模型反复调用同一个工具得到相同或相似结果又不结束对话。原因往往出在工具输出让模型不满意而模型又没有足够的能力判断该收手了。解法有几个方向一是给 Agent 执行设置最大迭代次数超了就强制结束二是在提示词里写清楚当工具结果不足以继续推理时基于已有信息做答或向用户澄清三是工具返回内容设计得更有决策信息量比如返回空结果时带上没有查到记录的明确标识减少模型继续无效重试的可能。第二个是工具参数幻觉。模型把一个不存在的工具名或者错误参数传给了调度层导致调用失败。这个在强工具调用模型function calling上少一些但本地部署的小模型特别常见。稳妥做法是工具绑定后在程序侧做好参数校验解析不通过就先反馈给模型重新生成而不是直接抛异常。第三个是上下文失控。Agent 每走一步agent_scratchpad就会累积一轮思考 工具结果跑几步之后上下文直接翻倍又慢又容易让模型忽略关键信息。优化方式是精简工具输出、限制思考过程长度长任务落地用 LangGraph 时还可以做总结和裁剪中间步骤。第四个是安全与权限边界。Agent 能调用工具就意味着它有机会执行破坏性操作比如发外呼短信、删除数据、改数据库配置。在真实项目里给 Agent 分配一套最小权限凭证对高危操作加人工审批节点是必须做的不是可选项。这一条我每次做 Agent 系统都会当成硬性要求写进设计文档。5. 从提示词到 RAG 再到 Agent把整条链路串成一个项目5.1 实战项目目标设定别一上来就想做通用智能体我建议的实战切入点是做一个企业私域知识库 自动工单处理的一体化助手。这个项目横跨提示词、RAG、Agent 三大模块任务量适中又能在不动用太多外部资源的情况下完整跑通。具体需求可以拆成两块第一块问答中枢员工可以问报销流程是什么今年中秋节放假几天系统基于知识库检索回答。第二块任务执行员工可以说帮我查一下我目前还有几天年假Agent 检索制度后还要调用一个虚构的员工系统接口给出个性化结果。这个项目的意义在于它逼着你把 RAG 的检索与生成、Agent 的工具调度与多步推理、提示词的结构化设计全部串起来。做完之后你会对一个看起来像智能助手的系统是如何从模型 API 一步步组装出来有真正的体感。5.2 模块职责边界RAG 管知识Agent 管动作模块拆分上我的原则是RAG 只负责知识侧Agent 负责决策侧。RAG 模块处理的问题通常是某文档里写的是什么、规定如何。它适合静态知识、流程制度、FAQ 等有明确资料支撑的内容。这个模块的输入是文档输出是回答。Agent 模块处理的问题是根据已知信息我该做什么。它会把用户请求拆解成多个子任务其中可能包含查知识库这个子任务也可能包含调接口、查数据、进行某种计算等。Agent 不关心知识从哪来它只关心下一步该做什么、用什么工具做。两个模块之间通过工具Tool连通Agent 把查制度当成一个 Tool 来调用这个 Tool 内部就去执行 RAG 链路切片 → 嵌入 → 检索 → 重排序 → 调用模型生成回答。这种设计既保留了 RAG 在知识问答上的精度又让 Agent 有了调度和执行能力职责清晰后期也好分别优化。5.3 上线后的评测与迭代方向RAG 的 recall 与 Agent 的 task success项目能跑起来之后一定不要停下来不加评测。我给一套实用的评测方案不需要专门团队也能执行。RAG 侧重点看两个指标召回率Recallk真实答案对应的文档片段是否出现在检索返回的前 k 条里。答案命中率最终模型回答里是否包含了正确答案信息。具体做法是准备一组 QA 测试集每条测试问题关联一个或多个正确答案片段跑一遍检索链路统计命中情况。低于 80% 就要回查切片策略和嵌入模型。Agent 侧重点看任务成功率给每个测试场景定义明确的成功标准比如查询后准确说出剩余年假天数、对未授权操作明确拒绝。跑完整条 Agent 链路统计成功次数/总次数。失败样例回查时注意区分是模型决策错没选对工具工具参数错传错数据还是 RAG 召回错没给到知识。三类错误各自的修复路径完全不同不要混在一起调。另外建议给系统加核心日志用户问题、检索结果 top5、RAG 最终回答、Agent 的完整推理步骤和每次工具调用参数。日志是调优的依据没有日志的 RAG/Agent 项目出了问题就是抓瞎。再说一个我个人的心得做这类系统宁可先小范围跑通也不要追求一步到位。先做单条制度问答再做多文档混合问答最后再加 Agent 工具调度。每加一层能力就重新跑一遍评测集确保前面没做坏再加新功能。这个节奏看起来慢但实际项目里反而是最快能稳定上线的路径。
返回列表