这次我们不看概念墙。很多团队一提到 LangChain 就想到写 Prompt,一提到 Agent 就以为模型能自己出结果,结果工具调用顺序错了、参数传错了、上下文越拉越长,最后只能归咎于“模型不够聪明”。实际上,大模型只是决策层,真正决定一个 Agent 项目能不能落地的,是工具接入方式和编排边界。
MCP(Model Context Protocol)的出现,把“给模型接工具”这件事从写死函数变成了标准协议。而 LangChain 负责的是 Agent 编排,也就是决定模型在什么时候调用工具、怎么把工具返回结果回填到对话里、多轮任务如何保持状态。两者结合之后,开发一个能真正干活的 Agent,复杂度会明显下降——前提是你会正确使用它们。
这篇文章会直接进入实操:先梳理 LangChain、MCP、Agent 的职责边界,再给出一个最小可运行的 MCP Server 和 LangChain Agent 示例,然后重点讲调试技巧、接口与批量任务、生产级部署建议,最后附上面试真题速答。如果你正准备把 Agent 从 Demo 推向项目,这篇文章可以先收藏。
1. 核心能力速览
| 能力项 | 说明 |
|---|---|
| 项目性质 | 工程架构实践:LangChain 做编排,MCP 做工具协议,Agent 做决策与执行 |
| 核心组件 | LangChain、langchain-mcp-adapters、MCP Python SDK |
| 主要功能 | MCP 工具接入、Agent 工具调用、多工具场景、接口封装、批量任务处理 |
| 硬件门槛 | 如果只接云端大模型 API,普通 CPU 机器即可;如果使用本地大模型,需要根据模型规模配置 GPU |
| 启动方式 | Python 脚本启动、MCP Server 独立进程、HTTP/SSE 服务模式 |
| 是否支持 API | 支持,MCP 服务本身有 stdio/HTTP/SSE 传输方式,Agent 也可封装成 Web API |
| 是否支持批量任务 | 可以通过异步任务队列或外部调度实现批量处理 |
| 可调试性 | 支持 verbose 日志、Agent 轨迹输出、MCP 日志分级、断点排查 |
| 适合场景 | 企业内部工具调用、数据库查询 Agent、业务系统助手、文档处理流水线 |
| 需要特别注意 | 工具权限、敏感数据、模型上下文长度、调用失败重试策略 |
这里先给一个结论:这种架构不是某个特定模型独占的。只要模型支持函数调用(Function Calling / Tool Calling),就可以用 LangChain 的统一抽象把它和 MCP 接起来。
2. LangChain、MCP、Agent 分别解决什么问题
很多人第一次接触 LangChain,会被它一长串模块名吓到。链、记忆、回调、输出解析器、向量存储、Agent,每个概念都能拆出好几个子模块。但如果只做 Agent 工具调用,我们只需要关注其中一条主线:模型决定调用什么工具,程序执行工具并把结果返回模型,模型根据返回结果继续推理或者直接给出答案。
2.1 LangChain 负责什么
LangChain 是一个编排层,它本身不是模型,也不提供推理能力。它要做的是把大模型 API、Prompt 模板、工具函数、记忆、输出解析这些东西组装在一起。在 LangChain 生态里,Agent 接收用户输入后,会调用一个可执行循环,模型输出结构化的 Tool Call,LangChain 根据这个 Tool Call 查找对应工具,执行后把结果再喂给模型。
如果你只是调用一次模型,那么用 LangChain 的价值不大。真正有价值的是多轮工具调用场景,因为模型往往不会一次就拿到所有答案,它需要先查询、再计算、再判断,整个过程需要循环控制。
2.2 MCP 负责什么
MCP 是模型上下文协议,目标是把工具调用做成标准协议。以前如果你想给 Agent 接一个数据库查询函数,可能要写“把函数转成 JSON Schema,再绑定到模型”的代码。如果接入第二个系统,又要重复一遍。MCP 相当于给工具接入做了一层抽象:MCP Server 暴露工具,MCP Client 负责和 Server 通信,LangChain 只需要读取 Client 返回的工具列表,再绑定给模型。
MCP 支持多种传输方式:
- stdio:通过标准输入输出传输 JSON-RPC。
- SSE:通过 Server-Sent Events 传输。
- HTTP:以 HTTP 请求方式访问工具服务。
在不同部署环境下,可以选择不同传输方式。本地开发时用 stdio 最简单,服务化之后用 SSE 或 HTTP 更方便。
2.3 Agent 决定“怎么做”
Agent 的核心不是自动化执行一个固定流程,而是让模型根据用户目标动态选择工具和参数。比如用户问“查一下用户 1001 的订单情况,如果超过 200 元就走高级审批”,Agent 就需要判断先调用用户查询还是订单查询,拿到订单金额后再判断是否需要走审批工具。
这个动态决策过程就是 Agent。LangChain 中的 AgentExecutor、LangGraph 中的 StateGraph,都是用来承载这个循环的组件。
2.4 LangChain 和 LangGraph 的区别
面试题里经常出现这个问题。简单理解:
- LangChain 是一套工具集和开发范式,包含模型调用、工具封装、记忆、检索等。
- LangGraph 是为复杂 Agent 流程设计的图编排框架,核心是有状态图,节点和边是显式定义的。
- 如果任务比较简单,一条 AgentExecutor 就能跑通。
- 如果任务需要人工审核、多分支、状态回滚、长期记忆,LangGraph 更合适。
MCP 负责解决工具供给,LangChain 负责模型与工具的胶水层,LangGraph 负责复杂状态机。三者并不冲突。
3. 适用场景与使用边界
LangChain + MCP + Agent 最擅长的场景,是“模型需要查实时数据或操作业务系统”的工具型任务。例如:
- 企业内部工单查询与状态变更。
- 数据库只读查询助手。
- 运维人员用自然语言查看监控指标。
- 办公系统里的文档归档、日程查询。
- 多系统内容聚合问答。
这些场景都有一个共同点:模型不能凭记忆回答,必须通过 MCP Server 提供的工具获取真实数据,或者调用业务接口完成任务。
但它也有明显不适用的场景:高并发、低延迟、强一致的交易链路并不适合把所有逻辑交给 LLM Agent 自由发挥。模型生成 Tool Call 有时间开销,工具返回结果后模型还要再推理一轮,整体延迟会比直接调业务接口高很多。稳定性和解释性也不像传统程序那样可控。
合规和边界问题也必须在设计阶段就考虑清楚:
- MCP Server 如果暴露数据库操作工具,必须对使用者做身份鉴权和权限隔离。
- 涉及用户隐私、企业敏感信息、人脸声音等数据,必须经过授权。
- Agent 调用外部写操作时,应该默认 dry-run 或二次确认。
- 不要在生产环境直接给 Agent 一个“执行任意代码”的黑洞工具。
4. 环境准备与前置条件
这一节给出一套通用环境清单。实际版本会持续更新,建议以官方文档为准。
4.1 系统与 Python 环境
本地开发建议使用 Linux 或 macOS,Windows 也能跑通大部分 stdio 模式,但要注意进程通信差异。MCP Python SDK 要求 Python 3.10 及以上版本。如果你的机器里 Python 版本比较混乱,推荐用虚拟环境隔离。
# 创建并激活虚拟环境 python3 -m venv .venv source .venv/bin/activateWindows PowerShell 下激活命令是:
.\.venv\Scripts\Activate.ps14.2 安装依赖
最小示例需要安装这些包:
- langchain
- langchain-openai
- langchain-mcp-adapters
- mcp
- openai
命令如下:
pip install --upgrade langchain langchain-openai langchain-mcp-adapters mcp openai如果你的模型来自本地 Ollama 或 Azure OpenAI,需要替换对应的 LangChain 模型包装包。这里的示例统一用 ChatOpenAI。
4.3 配置模型 API
以 OpenAI 兼容接口为例,在环境变量里写入 API Key 和 Base URL:
export OPENAI_API_KEY="你的 API Key" export OPENAI_API_BASE="https://api.openai.com/v1"如果是本地服务,可以将 Base URL 改成局域网内地址,再指定本地模型。重点是 LangChain 只认模型包装层,不关心远端模型到底部署在哪台机器。
4.4 目录安排
建议从一开始就按目录划分项目结构,避免后续维护混乱。
langchain-mcp-agent/ ├── mcp_servers/ │ └── order_server.py ├── agent/ │ └── main.py ├── logs/ ├── config/ └── requirement.txtMCP Server 和 Agent 主程序分开目录,后续加服务时会更清晰。
5. LangChain 最小闭环代码
下面我们实现一个最简单的闭环:用户用自然语言询问订单金额,Agent 通过 MCP Server 调用一个模拟订单查询工具,最终返回结果。为了让例子聚焦在集成逻辑上,代码里的业务数据是模拟的,真实环境需要替换成数据库或接口查询。
5.1 编写一个 MCP 工具服务
先用 MCP Python SDK 写一个订单查询工具服务。文件命名为order_server.py。
from mcp.server.fastmcp import FastMCP mcp = FastMCP("order-tool") # 这里只是模拟数据 ORDER_DATA = { "1001": {"amount": 128.50, "status": "paid"}, "1002": {"amount": 76.00, "status": "pending"}, } @mcp.tool() def get_order_amount(user_id: str) -> str: """根据用户 ID 获取订单金额和状态。""" order = ORDER_DATA.get(user_id) if order is None: return f"用户 {user_id} 没有订单" return f"用户 {user_id} 的订单金额是 {order['amount']} 元,状态是 {order['status']}" if __name__ == "__main__": mcp.run()这个服务在本地启动时会通过 stdio 方式监听来自 MCP Client 的 JSON-RPC 请求。注意,MCP Server 的工具描述会直接影响到模型判断,所以 docstring 要写清楚函数用途。
5.2 用 LangChain Agent 连接 MCP
我们使用langchain-mcp-adapters把 MCP Server 注册进来。需要用到 LangChain 的 Agent Executor。
import asyncio from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate async def main(): async with MultiServerMCPClient( { "order-mcp": { "transport": "stdio", "command": "python", "args": ["order_server.py"], "encoding": "utf-8", } } ) as client: tools = await client.get_tools() print("可用的工具:", tools) # 这里根据实际模型选择,支持工具调用的模型均可 model = ChatOpenAI(model="gpt-4o-mini", temperature=0) prompt = ChatPromptTemplate.from_messages( [ ("system", "你是一个订单助手,请依赖工具获取信息,不要编造数据。"), ("human", "{input}"), ("placeholder", "{agent_scratchpad}"), ] ) agent = create_tool_calling_agent(model, tools, prompt) executor = AgentExecutor(agent=agent, tools=tools, verbose=True) result = await executor.ainvoke({"input": "请查询用户 1001 的订单金额"}) print("最终结果:", result["output"]) if __name__ == "__main__": asyncio.run(main())如果你的模型接口支持 functions 而不是 tool calls,可以把create_tool_calling_agent换成create_openai_functions_agent。不同模型厂商的接口参数略有差异,但在 LangChain 层的使用方式比较接近。
5.3 运行与验证
先启动 MCP Server 本身看看能不能正常工作:
python mcp_servers/order_server.py如果代码没有语法错误,MCP Server 会进入等待状态,屏幕上不会输出太多内容。这是因为 stdio 模式必须保持标准输出干净,服务日志不能随便打印。
确认 Server 没有报错后,回到 Agent 主程序目录运行:
python agent/main.py如果 Agent 调用成功,你会看到类似下面的输出:
> Entering new AgentExecutor chain... Invoking: `get_order_amount` with `{'user_id': '1001'}` 用户 1001 的订单金额是 128.5 元,状态是 paid > Finished chain.只要日志中出现Invoking和Finished chain,就说明 MCP 工具已经被 LangChain Agent 正确识别并执行了。如果执行报错,第一时间看报错发生在哪个环节。
6. 功能测试:从单工具到多工具链
单工具跑通是第一步,但实际 Agent 往往需要多个工具配合。建议从下面几个维度做功能验证。
6.1 工具列表探测
在 Agent 主程序里加上工具打印,能快速确认 MCP Client 是否成功从 Server 拉到了工具列表。如果工具列表为空,后面调用链一定跑到模型的幻觉回答上。打印结果通常能看到工具名、描述、参数 JSON Schema。
6.2 参数缺少与参数类型错误
模型存在生成参数不完整的概率。例如工具定义需要user_id和start_date,模型可能只输出user_id。解决办法是在工具 docstring 中写清楚参数含义和缺省规则,同时在 MCP Server 内做参数校验,返回明确错误信息。
如果你希望模型自动询问用户补充参数,可以让 Agent 在工具失败或参数缺失时把错误信息返回给模型,让模型判断下一步怎么做。
6.3 多工具串联
增加第二个 MCP Server,例如一个“库存查询服务”。Agent 可能需要先查订单,再根据商品 ID 查库存。实际效果往往取决于模型对工具描述的理解,所以工具描述要像接口文档一样准确,避免抽象。
6.4 错误重试
在 LangChain Agent 中,工具本身抛出异常会被 AgentExecutor 捕获。你可以给工具调用加一层包装,将异常转为可读消息。例如:
try: result = execute_db_query(sql=user_sql) return result except Exception as e: return f"查询失败,原因:{e}"把错误信息返回给模型,让模型调整 SQL 或提示用户,这种方式比直接抛异常更自然。
6.5 显式状态测试
如果场景是有状态的多轮对话,要验证 Agent 在第二轮是否还能记住第一轮的工具结果。标准 AgentExecutor 并不擅长长期记忆,复杂状态优先考虑 LangGraph。
7. 调试技巧
调试 LangChain + MCP + Agent 时,最大的困难是“不知道当前是哪一层出了问题”。可能是 MCP Server 没启动,可能是工具没被加载,可能是模型没生成 Tool Call,也可能是执行工具时报错。下面这些技巧能快速缩小范围。
7.1 开启 verbose
AgentExecutor 构造参数里加入verbose=True,就能看到每一步的动作。这是最直接的调试方式。
executor = AgentExecutor(agent=agent, tools=tools, verbose=True)如果这条 Agent 链路没有输出Invoking,说明模型没有打算调用工具。这时要检查模型是否支持工具调用,以及工具是否真的绑定到了 agent。
7.2 确认 MCP Server 的 stdout 不被污染
stdio 模式下,MCP Server 通过标准输出和客户端通信。此时开发者如果为了调试在 Server 里执行print("xxx"),会把 JSON-RPC 协议打乱,LangChain 端会报解析错误。
正确做法是:开发期日志写 stderr,或者写入日志文件。在 Python 里可以用 logging 模块,配置 stderr handler;部署环境里用 systemd 或 Docker 收集标准错误输出。
7.3 MCP 工具没有出现在 tools 列表
如果await client.get_tools()返回空列表,优先检查 Server 是否启动成功,以及 transport 路径是否正确。如果StdioServerParameters里的command或args写错,服务进程会起不来。
从工程经验来看,最常见原因是 Python 虚拟环境路径不对。例如 Agent 进程里python指向系统 Python,而 MCP SDK 只安装在虚拟环境里,导致子进程找不到模块。解决办法是把 command 改写为绝对路径:
# 例如使用虚拟环境内 python "command": "/path/to/project/.venv/bin/python"7.4 模型一直不调用工具
模型不调用工具可能有两个原因:一是当前模型本身不支持 Tool Calling;二是工具的描述和当前问题关联度不高。
可以尝试把输入改成非常明确的“请使用 get_order_amount 工具查询用户 1001 的订单金额”。如果改成强制指令后模型仍然不调用,说明工具绑定环节有问题。
7.5 工具调用成功但模型回答错误
工具调用的输出格式很重要。有些工具返回的是纯 dict,有些返回的是 Markdown 表格。模型不是解析器,如果返回结构过于复杂,会让模型产生误读。建议 MCP Server 统一把输出转成简短、结构化的字符串,例如:
{"user_id": "1001", "amount": 128.5, "status": "paid"}或者直接给模型可读句子。不要返回几万字的 JSON,模型上下文会被浪费,推理也容易失控。
7.6 使用回调追踪轨迹
LangChain 支持 Callback,可以拿到 LLM 输入输出和 Agent 的中间环节。在复杂项目中,可以把ConsoleCallbackHandler接进来,或自定义 Handler 输出追踪日志。这一步在调试生产问题时非常有用。
8. 接口 API 与批量任务
Demo 能跑通之后,下一步是想办法把能力暴露出去,让其他系统调用。
8.1 MCP Server 以 HTTP/SSE 方式暴露
开发阶段用 stdio 很方便,但生产环境需要跨机器调用时,一般要把 MCP Server 部署为独立服务。具体写法取决于框架版本。例如在 MCP SDK 中,可以把transport从默认 stdio 切换成 HTTP/SSE 模式。
如果要保持代码可迁移,建议把 MCP Server 按“业务处理逻辑”和“传输层”拆开。业务逻辑就是一个普通函数,测试时可以直接调用函数,部署时通过 MCP Server 暴露。
8.2 Agent 服务化封装
你可以把 Agent AgentExecutor 包成一个 FastAPI 接口。请求进来后,异步调用 Agent,返回最终结果。这里给一个基本模板:
from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class QueryRequest(BaseModel): input: str class QueryResponse(BaseModel): output: str @app.post("/agent/query") async def agent_query(req: QueryRequest): # 真实项目中,需要在这里创建或复用会话 result = await executor.ainvoke({"input": req.input}) return QueryResponse(output=result["output"])注意:Agent Executor 是有状态的运行时对象,不要每个请求都新建 MCP Client 和 Agent,否则会非常浪费资源。建议在应用启动时初始化一次,并发请求时通过线程锁或异步队列复用。
8.3 批量任务处理方案
如果你的业务是处理一批文件或一批用户,接口调用不推荐同步请求直接打到并发模型 API。一方面模型限流,另一方面失败重试很难管理。
比较实用的批量方案是:任务先入队,Worker 从队列里取任务,逐条调用 Agent,并把结果写入输出目录。如果某条任务失败,记录错误并跳过或重试,而不是让整批任务中断。
import asyncio async def process_one_input(text: str) -> str: # 假设这里执行 Agent 调用 result = await executor.ainvoke({"input": text}) return result["output"] async def batch_process(inputs: list[str], limit: int = 5): semaphore = asyncio.Semaphore(limit) async def wrapped(text: str): async with semaphore: try: return await process_one_input(text) except Exception as e: return f"处理失败:{e}" tasks = [wrapped(text) for text in inputs] return await asyncio.gather(*tasks)批量任务需要关注三个指标:成功率、平均耗时、最大耗时。如果某个任务的工具调用次数明显超长,要设置超时上限,避免单条任务拖死整个队列。
9. 生产级部署建议
从 Demo 到生产,不是把python main.py放到服务器就结束。下面这些问题必须在部署前想清楚。
9.1 进程模型
LangChain Agent 主进程和 MCP Server 子进程是强耦合的。主进程退出,子进程也会退出。在单机部署时,可以用 systemd 或 supervisord 守护 Agent 进程,保证崩溃自动拉起。
如果团队有容器化能力,优先用 Docker Compose。将 MCP Server 作为独立容器,Agent 服务作为另一个容器,通过网络调用。这样多个 Agent 服务可以复用同一个 MCP Server。
9.2 环境变量与密钥管理
不要把 API Key、数据库密码写死在代码仓库里。正确做法是放到环境变量或密钥管理服务里,部署时注入。
LLM API Key 建议做独立账号管理,配置调用限额,防止某个 Agent 工具被不当使用导致费用飙升。
9.3 安全边界
Agent 通过工具调用的权限,决定了系统的安全边界。推荐采用最小权限原则:
- 数据库工具默认只读,写操作必须走审批流程。
- 不允许 MCP Server 暴露执行任意 shell 命令的能力。
- 文件操作工具限制在指定目录内。
- 涉及内网系统的 API 要加访问鉴权。
如果你正在做内部系统对接,最好先让安全团队评审工具清单,不要只图开发快。
9.4 观测与监控
生产环境里,模型输出的 Tool Call 内容必须被记录下来。建议日志结构包含:
- 用户输入原文。
- LLM 生成的工具调用名和参数。
- 工具实际执行结果(脱敏后)。
- 最终输出。
- 每个阶段的耗时。
这样后续出现问题时,才能根据日志还原当时调用链,而不是靠猜。
9.5 模型与上下文管理
Agent 一次任务会产生多轮工具调用,每一轮都会消耗 token。长任务背景下,可以用摘要或向量数据库保存历史,而不是把所有中间结果全部塞回 Prompt。上下文一旦超过模型窗口,系统就会报错或直接丢失信息。
10. 常见问题与排查方法
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| Agent 启动后找不到任何工具 | MCP Server 未启动或 stdout 路径错误 | 先单独运行 Server,再打印get_tools()结果 | 修正 command/args,使用 Python 绝对路径 |
| MCP Server 报 JSON 解析错误 | Server 里用了 print,污染 stdout | 查看错误日志,确认输出内容 | 日志改写到 stderr 或日志文件 |
| 模型收到问题但不调用工具 | 模型不支持 Tool Calling 或工具描述不明显 | 开启 verbose 查看 LLM 输出 | 换用支持 tool calling 的模型,强化问题描述 |
| 工具返回结果后模型继续乱答 | 工具返回结构复杂、过长 | 查看工具返回内容 | 格式化输出,精简返回内容 |
| Agent 调用工具超时 | MCP Server 内部请求过慢或进程卡死 | 观察耗时分布,确认是否卡在数据库或网络 | 给工具调用加超时,异步化慢任务 |
| 批量任务中途失败 | 单条任务触发限流或模型异常 | 查看任务日志中的异常类型 | 加信号量限流,失败任务自动重试并记录 |
| 上下文超限 | 多轮工具调用中间结果过多 | 监控 token 消耗 | 截断历史,用摘要或向量库记忆 |
| 多个 Agent 实例竞争同一个 MCP Server | 使用了不安全的全局状态 | 检查 MCP Server 是否无状态 | 设计无状态工具,会话状态交给上层管理 |
| 对话中用户身份混乱 | 多用户复用同一个会话 | 检查会话隔离逻辑 | 按用户 ID 建立独立 Session 或工具参数 |
| 工具执行了危险写操作 | 工具暴露了未受控的写接口 | 检查工具权限 | 默认只读,写操作二次确认 |
11. 最佳实践
基于实际工程经验,总结几条建议。
第一,第一次跑最小闭环时不要贪多。先跑通一个 MCP Server 和一个工具,确认模型能正确调用,再往上面加更多工具。否则报错时很难定位是哪一步出的问题。
第二,工具函数要么返回十分规范的数据,要么返回人类可读的短文本。不要直接丢一个大对象给模型。LangChain 可以通过工具结果适配器转换,但过度复杂依然是 Agent 不可靠的根源。
第三,Agent 不是万能的编排器。能用普通代码写清楚的固定流程,就别交给 Agent。Agent 适合动态选择工具的场景,固定流程使用 LangGraph 或普通代码会更可控。
第四,MCP Server 的业务逻辑建议独立可测。开发任务时先直接调用函数验证数据,再验证 MCP 协议封装层是否正常。不要一上来就追求“自然语言到数据库查询”一步到位。
第五,生产环境必须做敏感信息脱敏。日志中不要出现真实用户手机号、身份证号、密钥等字段。
第六,批量任务要有幂等设计。如果同一个输入被重试两次,工具调用不能出现重复扣款、重复发消息等情况。写操作要加 request_id 去重。
12. 面试真题速答
最后把面试中常见的问题整理成速答,供复盘使用。
12.1 LangChain 是如何调用工具的呢?
LangChain 将工具转换成模型可识别的结构化描述。当用户输入传到模型时,模型根据问题决定是否返回 Tool Call。LangChain 的 AgentExecutor 拿到 Tool Call 后,根据工具名找到对应工具并执行,随后把执行结果返回给模型,模型再生成最终回答或继续调用工具。这个过程可以抽象成一个循环。
12.2 MCP 和普通函数调用有什么区别?
普通函数需要开发者自己写工具给模型使用的胶水层,例如手动构建参数 Schema 和解析结果。MCP 定义了一套统一的客户端-服务器协议,工具可以跨框架复用。换句话说,MCP 工具不只为 LangChain 存在,也可以被其他 MCP Client 的 Agent 调用。
12.3 LangChain 和 LangGraph 的区别在哪里?
LangChain 更偏重组件集成,LangGraph 更偏重有状态的流程编排。LangGraph 把 Agent 建模成图,节点负责执行动作,边负责决定跳转条件,适合需要人工审核、分支跳转和状态回滚的场景。
12.4 Agent 工具调用失败如何调试?
第一看模型是否生成了 Tool Call,第二看工具是否存在,第三看参数是否匹配,第四看工具执行是否抛出异常,第五看工具返回结果是否被模型正确理解。每一步都可以通过 verbose 或日志定位。
12.5 如何保证 Agent 生产环境的稳定性?
主要手段是控制工具权限、增加超时、记录完整链路日志、做输入输出校验、限制模型上下文长度、对写操作二次确认,并给批量任务增加重试和幂等机制。
写在最后
LangChain + MCP + Agent 现阶段已经具备工程落地能力。先用最小闭环跑通工具调用,再逐步补充多工具、状态管理、服务封装和监控体系,是风险最低的推进路径。
最容易踩的坑并不是 LangChain API 不熟练,而是没有把工具边界定义清楚:工具描述模糊、返回结构过大、权限没有隔离、日志没有记录。先把这些问题解决,Agent 的可靠性会明显提升。建议收藏这篇文章,开发时对照检查清单一步一步来。