资讯详情 大模型Agent开发全栈指南:从ReAct原理到LangChain、RAG与MCP落地
📅 2026/10/22 2:38:37
最近团队在推进大模型应用落地时我反复被问到同一个问题想从零开始做 Agent 开发到底应该先学什么LangChain、LangGraph、RAG、MCP、多智能体这些名词铺天盖地但网上资料大多只讲单个点很少有人把“底层原理 → 框架封装 → 企业级落地”这条完整链路串起来讲清楚。这篇文章就以一条全栈项目线为主线从大模型底层推理逻辑出发一步步拆解 Agent 的构建方式。你会看到工具调用的原理、LangChain 的封装方式、RAG 知识库接入、LangGraph 的状态编排、MCP 的外部系统连接以及多智能体在企业场景里的真实协作模式。无论你是刚入门的新手还是已经写过几个 Demo 想深入落地的开发者这套内容都能直接复用。1. Agent 大模型开发全景为什么现在需要系统学习先说一个共识大模型本身并不是 Agent。GPT、Qwen、Llama 这些模型的核心能力是“根据上下文生成下一个 Token”它们擅长对话、总结、翻译、写代码但它们不会主动去查数据库、不会调用外部 API、不会记住用户的长期状态。Agent 的本质是在大模型的基础上补上“感知环境、做出决策、调用工具、观察结果、修正行动”这套完整循环。举一个最典型的业务场景。用户问“帮我查一下上周订单里金额超过 5000 的订单然后给这些客户生成一封回访邮件。”如果只用 Prompt 写死规则模型会因为根本没有订单数据而胡编。如果只做 RAG 检索模型能把知识库内容捞出来但它不会去调用订单查询接口。只有 Agent 才能完成这件事模型先识别意图决定调用订单查询工具拿到真实数据后再调用邮件生成工具最终产出结果。这就是为什么企业级落地一定绕不开 Agent。它解决的不是“模型会不会答”而是“模型能不能办事”。从学习路径来看Agent 全栈需要掌握的能力可以分为五层分层核心内容典型技术选型第一层 底层原理Token 推理、上下文窗口、函数调用机制OpenAI 兼容接口、Ollama 本地模型第二层 编排框架提示词模板、工具注册、Agent 执行循环LangChain、LangGraph第三层 知识接入文档加载、切片、向量化、检索增强Chroma、FAISS、Elasticsearch第四层 系统集成让 Agent 调用外部服务、协议标准化MCP、OpenAPI、自定义 HTTP 工具第五层 工程落地多智能体协作、监控、安全、成本控制LangGraph、LangSmith、Langfuse这篇文章不会只停留在概念层。下面从环境准备开始逐步带你写出真正可运行的代码。2. 环境准备从 Python 到本地大模型开发 Agent 之前先确认运行环境。我的建议是本地开发阶段优先使用兼容 OpenAI 接口的本地模型服务例如通过 Ollama 加载开源模型。这样既能跑通全流程数据也留在本地不涉及模型 API 的费用和网络问题。2.1 安装 Python 与虚拟环境Agent 开发目前主流还是 Python 生态。推荐使用 Python 3.10 或 3.11这两个版本对 LangChain、LangGraph 的兼容性最稳定。python -m venv agent-env source agent-env/bin/activate # Windows 下使用 agent-env\Scripts\activate pip install --upgrade pip有一个容易踩的坑尽量不要直接在全局环境安装。LangChain 生态依赖非常多pydantic、typing 这类底层库版本一变经常出现“明明代码没问题但就是跑不起来”的情况。独立虚拟环境是第一道防线。2.2 安装核心依赖本文示例核心依赖如下版本需要根据你的项目实际情况调整pip install langchain langchain-core langchain-community pip install langchain-ollama langchain-openai pip install langgraph pip install langchain-chroma chromadb pip install langchain-text-splitters pip install mcp langchain-mcp-adapters pip install python-dotenv这里提醒一点LangChain 历史上有过比较混乱的包名时期。老教程里的langchain.llms.OpenAI、langchain.chains可能在新的 1.x 版本中已经迁移。遇到 ImportError 时优先去官方文档确认包名不要盲目复制旧代码。2.3 启动本地模型如果使用 Ollama先安装并拉取模型ollama pull qwen2.5:7b ollama serve然后在代码里用langchain_ollama.ChatOllama连接。如果你公司里有统一的模型网关或云端模型服务只需要把 Base URL 和 API Key 换成实际配置即可代码结构是一样的。2.4 示例项目结构为了让后续的代码组织清晰建议先建立下面的目录结构agent-fullstack/ ├── agent_env/ # Python 虚拟环境 ├── data/ # 本地知识库原始文档 ├── src/ │ ├── agent_basic.py # LangChain 基础 Agent │ ├── rag_pipeline.py # RAG 检索增强 │ ├── langgraph_flow.py # LangGraph 状态编排 │ └── mcp_server_demo.py # MCP 服务端示例 ├── .env # 环境变量 └── requirements.txt后续每个章节的代码都可以落在这个结构里运行。3. Agent 底层原理模型推理、工具调用与 ReAct 模式很多初学者直接把 Agent 等同于“调一次模型接口”。这是个很大的误解。要理解 Agent首先要理解大模型是如何决定调用工具的。3.1 什么是函数调用Function Calling大模型本身不能真正执行代码但模型在训练过程中学习了“工具该如何被描述”的规范。当我们在请求里附带一个工具列表例如{ name: get_order_status, description: 根据订单号查询订单状态, parameters: { type: object, properties: { order_id: { type: string, description: 订单号 } }, required: [order_id] } }模型在生成回复时会先判断“用户的问题是否与某个工具匹配”如果匹配它不会直接输出自然语言答案而是输出一段结构化的工具调用请求例如{action: get_order_status, action_input: {order_id: SO20240001}}这段输出不是给人看的而是给程序看的。程序解析后去调用真实接口拿到结果再把结果回填给模型。整个循环被称为 ReAct 模式Reasoning Acting即思考 → 行动 → 观察 → 再思考。3.2 ReAct 循环的核心拆解一个完整的 ReAct 循环包含五个阶段模型接收用户输入。模型判断是否需要工具。如果不需要直接回答。模型输出一个结构化“行动计划”例如调用search_order。程序执行工具把结果作为 Observation 返回给模型。模型基于 Observation 继续推理输出下一步动作或最终答案。这个循环可以重复多轮直到模型认为信息足够输出最终答案。从实践角度看决定循环质量的关键有三个变量工具描述是否清晰。工具描述越明确模型越不容易选错工具。模型能力是否足够强。小参数模型容易出现“幻觉式工具调用”即模型调用了不存在的工具或参数格式错误。上下文窗口是否够用。每轮循环都会堆积思考过程超出窗口后需要做截断或摘要。理解了这个循环再看 LangChain 和 LangGraph 就容易多了。LangChain 是把工具注册、解析、循环封装成了现成的 AgentExecutorLangGraph 则是将循环的阶段拆成显式的节点让开发者能精确控制每一步。4. LangChain 实战第一个可运行的 AgentLangChain 是当前最流行的 Agent 编排框架之一。它最大的价值是统一了“模型层、工具层、记忆层”的接口。下面我们从零实现一个能够调用本地工具的 Agent。4.1 注册一个自定义工具先来看工具的定义。在 LangChain 中工具本质上是一个带有描述的函数。# 文件路径src/agent_basic.py from langchain_core.tools import tool tool def get_order_status(order_id: str) - str: 根据订单号查询订单状态例如 get_order_status(order_idSO20240001) # 实际项目中这里应该调用真实的订单服务接口 if order_id.startswith(SO2024): return f订单 {order_id} 的状态已发货预计 3 天内送达。 return f订单 {order_id} 未查询到请确认订单号是否正确。关键是tool装饰器。它会读取函数的签名、类型注解和 docstring自动生成模型可理解的工具描述。这意味着你不需要手写 JSON SchemaLangChain 会帮你完成。为了让示例可以快速演示这里再注册一个计算工具from datetime import date tool def get_today() - str: 获取今天的日期格式为 YYYY-MM-DD return date.today().isoformat()4.2 创建模型并绑定工具连接 Ollama 本地模型from langchain_ollama import ChatOllama model ChatOllama( modelqwen2.5:7b, temperature0, )temperature0在 Agent 场景中几乎必选。Agent 需要尽可能稳定地输出结构化的工具调用过高的温度会让模型“发挥不稳定”出现乱编工具名的情况。4.3 构建 AgentLangChain 提供了一个高层封装create_react_agent。from langchain.agents import create_react_agent, AgentExecutor from langchain_core.prompts import PromptTemplate prompt PromptTemplate.from_template( 你是一个智能助手可以调用工具解决用户的问题。 可用工具 {tools} 工具名称列表{tool_names} 请严格按以下格式输出 Question: 用户的问题 Thought: 接下来需要做什么 Action: 工具名称必须来自 [{tool_names}] Action Input: 传入工具的参数如果是多个参数请使用 JSON 格式 Observation: 工具返回的结果 Thought/Action/Action Input/Observation 可以循环多轮 Thought: 我现在知道答案了 Final Answer: 给用户的最终答复 {agent_scratchpad} Question: {input} ) agent create_react_agent(model, [get_order_status, get_today], prompt) agent_executor AgentExecutor(agentagent, tools[get_order_status, get_today], verboseTrue)这里出现了一个新手最容易困惑的概念agent_scratchpad和tool_names。它们不是你自己填写的变量而是 LangChain 在执行过程中动态填充的占位符。tool_names会变成工具列表中的名字agent_scratchpad会承载之前多轮思考与观察的历史。4.4 运行与验证if __name__ __main__: result agent_executor.invoke({input: 帮我查一下订单 SO20240088 的状态顺便告诉我今天的日期。}) print(result[output])预期运行流程如下模型识别出两个问题分别对应两个工具。先生成一次 Action 调用get_order_status。观察结果后再生成 Action 调用get_today。最后汇总自然语言输出。虽然这个示例逻辑很简单但它已经具备了一个真实 Agent 的完整骨架意图识别、工具选择、参数生成、结果观察、多轮推理。你后续做的所有复杂 Agent底层都是这个循环。5. RAG 实战为 Agent 接入动态知识库单纯的 Agent 只有工具调用能力但它仍然缺少“知识”。如果模型没有见过你的企业内部资料你问它任何内部制度它都答不上来。RAGRetrieval-Augmented Generation检索增强生成解决的就是这个问题。RAG 的思路是不把全部知识塞进 Prompt而是先把文档向量化存入向量库每次提问时只检索最相关的几个片段拼到 Prompt 里交给模型。这样既控制成本又能保证回答基于最新资料。5.1 文档加载与切片假设data/employee_manual.md是员工手册。# 文件路径src/rag_pipeline.py from langchain_community.document_loaders import TextLoader from langchain_text_splitters import RecursiveCharacterTextSplitter loader TextLoader(data/employee_manual.md, encodingutf-8) documents loader.load() splitter RecursiveCharacterTextSplitter( chunk_size500, chunk_overlap80, ) chunks splitter.split_documents(documents) print(f原始文档被切分为 {len(chunks)} 个片段)切片参数值得多说两句。chunk_size500表示每段大约 500 个字符chunk_overlap80表示相邻两段之间保留 80 个字符的重叠。重叠的目的是避免一个完整语义恰好被切断到两段里导致检索时匹配不全。这个参数没有绝对标准需要根据文档类型和经验调整企业文档一般建议 300 到 800 之间。5.2 向量化与写入向量库使用 Ollama 的本地 Embedding 模型将文本切片转成向量from langchain_ollama import OllamaEmbeddings from langchain_chroma import Chroma embeddings OllamaEmbeddings(modelnomic-embed-text) vector_store Chroma.from_documents( documentschunks, embeddingembeddings, persist_directory./chroma_db, ) print(向量库构建完成)第一次运行前需要先拉取 Embedding 模型ollama pull nomic-embed-text5.3 检索并拼接 Prompt检索的核心是按语义相似度召回 Top-K 片段retriever vector_store.as_retriever(search_kwargs{k: 3}) query 公司对年假有什么规定 docs retriever.invoke(query) for i, doc in enumerate(docs): print(f候选片段 {i1}: {doc.page_content[:80]}...)之后将检索到的片段填充进提示词模板from langchain_core.prompts import ChatPromptTemplate template ChatPromptTemplate.from_template( 基于以下资料回答用户问题。如果资料中没有相关信息请直接说明不知道不要编造。 【资料】 {context} 【用户问题】 {question} ) prompt template.format(context\n\n.join([d.page_content for d in docs]), questionquery) print(prompt)5.4 Agent RAG 的完整形态真正生产环境中RAG 通常以工具的形式嵌入 Agent。也就是说Agent 判断用户问题涉及企业内部知识时再触发检索工具而不是一开始就把整个知识库拼进上下文。tool def search_employee_manual(query: str) - str: 当用户询问公司制度、请假流程、员工手册相关内容时使用该工具检索知识库。 docs retriever.invoke(query) if not docs: return 没有检索到相关资料 return \n\n.join([d.page_content for d in docs])这种设计有个明显好处Agent 平时不需要携带巨大的知识库只在真正需要时查询极大降低上下文消耗。6. LangGraph 实战用状态图编排复杂流程LangChain 的 AgentExecutor 虽然开箱即用但它是一个“黑盒”开发者很难精确控制中间状态。而 LangGraph 把 Agent 的执行过程建模成一张图图里的每个节点都是明确的一步边代表状态流转。这让复杂的业务规则可以被显式编排。6.1 核心概念State 与 NodeLangGraph 的核心模型是状态机。一个StateGraph由节点和边组成节点一个函数输入当前状态输出更新后的状态。状态一个可变的字典在节点之间传递。边定义节点的执行顺序和条件分支。以客户投诉处理为例传统写法是 if-else 嵌套。使用 LangGraph 后每个处理环节都是一个独立节点流程清晰也方便在任意节点插入人工审批。6.2 一个最小可运行示例来看一个简化的客户投诉处理流程先分类再决定是否需要人工介入。# 文件路径src/langgraph_flow.py from typing import TypedDict, Literal from langgraph.graph import StateGraph, END class ComplaintState(TypedDict): content: str # 用户投诉内容 category: str # 自动分类结果 need_human: bool # 是否需要人工 def classify(state: ComplaintState) - ComplaintState: content state[content] if 退款 in content or 退货 in content: state[category] 售后 elif 态度 in content or 客服 in content: state[category] 服务投诉 else: state[category] 其他 state[need_human] state[category] in (服务投诉, 其他) return state def auto_handle(state: ComplaintState) - ComplaintState: print(自动处理已经为用户生成退款/退货指引) return state def human_handle(state: ComplaintState) - ComplaintState: print(转人工工单已分配给客服主管) return state def route(state: ComplaintState) - Literal[auto_handle, human_handle]: return human_handle if state[need_human] else auto_handle graph StateGraph(ComplaintState) graph.add_node(classify, classify) graph.add_node(auto_handle, auto_handle) graph.add_node(human_handle, human_handle) graph.set_entry_point(classify) graph.add_edge(classify, human_handle, conditionroute) graph.add_edge(classify, auto_handle, conditionroute) graph.add_edge(auto_handle, END) graph.add_edge(human_handle, END) app graph.compile() result app.invoke({content: 我收到的商品破损了申请退款, category: , need_human: False}) print(result)这个示例没有调用大模型但它展示了 LangGraph 最核心的价值条件分支和状态流转。生产环境中最常见的 Agent 编排本质上就是对这类流程图的放大和复杂化。6.3 用 LangGraph 构建 ReAct AgentLangGraph 也内置了 ReAct Agent 的 prebuilt 实现from langgraph.prebuilt import create_react_agent graph_agent create_react_agent( model, tools[get_order_status, get_today], promptprompt, ) graph_result graph_agent.invoke({messages: [{role: user, content: 查询订单 SO20240088 的状态}]}) print(graph_result)两者的区别在于AgentExecutor 内部是隐藏的固定循环而 LangGraph 版本可以让你看到完整的节点流转。企业级应用如果需要对过程做审计、断点续跑、人工复核LangGraph 是更合适的选择。7. MCP 实战让 Agent 连接外部系统如果说 RAG 解决的是“知识从哪里来”那 MCPModel Context Protocol模型上下文协议解决的就是“能力从哪里来”。MCP 是一套开放协议它把文件系统、数据库、第三方 API、业务系统统一封装成标准化的工具服务。Agent 只要实现了 MCP 客户端就能通过统一格式调用任何 MCP 服务端的工具而不需要为每个系统单独写一套集成代码。7.1 MCP 的基本架构MCP 的架构分为三层角色职责MCP Server暴露工具能力例如数据库查询、订单服务MCP Client运行在 Agent 侧负责发现和调用远端工具Transport客户端与服务端的通信方式常见是 stdio 或 HTTP这有点像“AI 世界的 USB 接口”。一个工具只要实现了 MCP Server所有支持 MCP 的 Agent 可以直接使用它无需定制适配。7.2 定义一个 MCP Server使用 Python 的 MCP SDK 创建一个简单服务端# 文件路径src/mcp_server_demo.py from mcp.server.fastmcp import FastMCP mcp FastMCP(order-service) mcp.tool() def get_order_status(order_id: str) - str: 根据订单号查询订单状态 # 模拟数据实际项目可以在这里查询数据库 return f订单 {order_id} 状态已发货 mcp.tool() def get_user_orders(user_id: str) - list: 查询用户的最近订单列表 return [ {order_id: SO20240001, status: 已签收}, {order_id: SO20240002, status: 运输中}, ] if __name__ __main__: mcp.run(transportstdio)7.3 在 LangChain Agent 中接入 MCP 工具客户端侧使用langchain-mcp-adapters来加载远程工具# 文件路径src/mcp_client_demo.py from langchain_mcp_adapters.tools import load_mcp_tools from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client server_params StdioServerParameters( commandpython, args[src/mcp_server_demo.py], ) async def load_tools(): async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await load_mcp_tools(session) print(f加载到 {len(tools)} 个 MCP 工具) return tools这段代码虽然是异步示例但核心思想很明确Agent 通过网络或本地进程连接 MCP Server拿到工具列表后与本地工具一样交给 ReAct 循环调用。7.4 MCP 的企业落地价值在企业内部落地 MCP 后工具管理开始变得标准化。数据团队封装好订单查询服务风控团队封装好风控校验服务Agent 团队不需要关心每个服务底层用的什么语言、什么协议只需要通过 MCP 发现并调用。这让 Agent 开发与业务系统解耦是当前大模型工程化里非常重要的方向。需要提醒的是MCP 协议还在快速演进不同版本之间可能存在兼容性差异。在企业项目中使用时要固定 SDK 版本并且搭建测试环境先验证再推广。8. 多智能体协作与企业级落地单个 Agent 的能力再强也难以覆盖复杂业务全链路。多智能体Multi-Agent把任务拆分成多个独立 Agent每个 Agent 负责一个专业方向相互协作完成整体目标。8.1 多智能体协作的三种模式模式说明适用场景多人协作模式多个 Agent 共享上下文共同完成任务文档联合编辑、多角色讨论主管-下属模式一个 Manager Agent 负责拆解任务并分发给 Worker Agent企业客服工单、复杂流程审批流水线模式任务按固定顺序在 Agent 之间流动数据清洗 → 分析 → 报告生成实际项目中最常见的是第二种。例如一个“售后服务主管 Agent”收到投诉后拆分成“情绪安抚 Agent”“物流核查 Agent”“退款处理 Agent”每个 Agent 调用不同的工具最终由主管汇总结果。8.2 用工具嵌套实现多智能体在没有复杂状态需求时可以通过把 Agent 包装成工具实现轻量级多智能体协作。# 文件路径src/multi_agent_demo.py from langchain.agents import create_react_agent, AgentExecutor refund_agent create_react_agent(model, [get_order_status], prompt) refund_executor AgentExecutor(agentrefund_agent, tools[get_order_status]) tool def refund_service_agent(order_id: str) - str: 当用户需要查询退款进度或退货流程时使用此工具。 result refund_executor.invoke({input: f用户询问订单 {order_id} 的退款进度请给出清晰答复}) return result[output]通过这种方式主 Agent 把“退款领域专家”当作一个工具来调度。虽然代码简单但已经形成了一层 Agent 之间的分工。对于更复杂的协作推荐用 LangGraph 构建 Supervisor 架构主管节点负责判断任务类型然后把任务路由给不同的子 Agent等待所有子任务完成后汇总。这是当前企业级多智能体的主流实现方式。8.3 企业级落地要关注的四个问题第一可观测性。生产环境的 Agent 必须能监控每一步的思考、工具调用和上下文变化。建议接入 LangSmith 或 Langfuse 这类链路追踪工具否则一旦出问题根本没法定位。第二权限与安全。Agent 能调用工具意味着它拥有了操作业务系统的能力。必须在工具层增加权限校验遵循最小权限原则。例如普通客服 Agent 只能查询订单不能修改订单涉及退款、加价等敏感操作必须走人工审批。第三成本控制。Agent 多轮推理和长上下文会明显增加 Token 消耗。要设置单次会话的 Token 上限、工具调用次数上限并且对核心链路做缓存。第四数据边界。企业私域知识不能随便发送到公有模型服务。本地部署模型加私有向量库是目前企业数据合规的主要方案。模型网关负责路由内网服务负责数据存储。9. 高频踩坑与排查思路所有写 Agent 的人都会遇到下面这几类问题。这里汇总成一张排查表问题现象常见原因解决思路模型不调用工具直接编答案工具描述不够清晰或模型本身工具调用能力弱优化工具描述换更强模型检查 Prompt 中是否明确要求先思考再行动Agent 循环卡死反复调用同一个工具模型陷入死循环或没有终止条件设置最大迭代次数让工具返回“无更多信息”类信号参数解析错误模型输出的工具参数不是合法 JSON检查工具签名尽量使用简单参数用 pydantic 做输入校验pydantic 或 typing 版本冲突LangChain 生态各包版本不一致固定 requirements 版本统一使用虚拟环境避免混合安装RAG 检索不到相关内容切片过碎、Embedding 模型能力不够调整 chunk 大小和重叠参数更换更大的 Embedding 模型清洗文档格式上下文超限多轮 ReAct 循环堆积大量历史增加历史摘要节点限制工具返回长度使用 LangGraph 做消息裁剪MCP 工具加载失败服务端未启动或协议版本不匹配先单独运行 MCP Server 验证固定 SDK 版本这里挑两个最典型的细说。第一个是“模型不调用工具”。出现这个问题时先不要急着换模型先检查你给模型的工具描述是否足够具体。例如 “查询订单” 这种描述就太模糊改成 “当用户询问物流进度、发货状态、订单配送情况时使用该工具按订单号查询” 效果会好很多。第二个是“循环卡死”。使用 AgentExecutor 时一定要设置max_iterations参数agent_executor AgentExecutor( agentagent, toolstools, max_iterations5, early_stopping_methodgenerate, )这样即使模型进入无效循环系统也会在第五轮强制结束避免资源和成本浪费。10. 总结与学习建议到这里一条从底层原理到企业落地的完整链路已经梳理完了。你掌握了 Agent 的本质是 ReAct 循环知道了 LangChain 如何封装工具调用会通过 RAG 给 Agent 接入知识库能用 LangGraph 对流程做可控编排理解了 MCP 如何打通外部系统也看到了多智能体在企业中的协作模式与落地风险。如果你准备进入实际项目我给你的建议是按下面的顺序推进第一步先把本地 Ollama 模型跑通用最简单的工具 Agent 理解循环过程不要急着上 LangGraph 和 MCP。第二步给 Agent 加一个 RAG 工具把一个内部手册接进来这是企业需求最高频的场景。第三步把流程中的条件分支迁移到 LangGraph确保每一步都可监控。第四步用 MCP 把真实业务系统接进来同时做好权限与审计。最后再考虑多智能体协同和监控体系。Agent 开发的能力栈很宽但本质上都是围绕“模型如何决策、工具如何调用、知识如何获取、流程如何编排”这四个核心问题。把这四个问题逐个打通你就已经具备从零到一搭建企业级 Agent 应用的真实能力了。后续的进阶方向可以继续深入研究模型微调、评估体系建设、多智能体框架的源码实现以及大模型应用的性能调优。希望这套学习路径能帮你少走弯路。如果文章里某个模块正好卡住了你的开发进度可以直接按对应章节的代码先跑起来再根据你的业务场景做替换。动手调试永远是学 Agent 开发最快的路径。