LangChain Agent与MCP实战:构建能调用工具的大模型应用
1. 先搞清楚 LangChain Agent、MCP 和 Skills 到底能帮你解决什么如果你正在用 Claude、GPT 这类大模型但总觉得它们像个“万事通万事松”——什么都知道一点但一到具体操作比如查数据库、调 API、操作本地文件就只会说“我无法直接操作”那你现在遇到的问题LangChain Agent 加上 MCP 和 Skills 这套组合就是目前最主流的工程化解决方案。简单来说它的核心价值是让大模型从一个“聊天顾问”变成一个能真正“动手执行”的智能助手。你不再需要手动复制模型输出的代码或命令去执行而是告诉 Agent 你的目标它就能自主规划、调用工具Skills、完成任务并把最终结果返回给你。这里涉及三个关键角色LangChain Agent 你可以把它理解为一个“大脑”或“调度中心”。它负责理解你的指令比如“帮我分析一下上个月的销售数据”然后决定先做什么、后做什么调用哪个工具并解析工具返回的结果。MCP 全称是 Model Context Protocol你可以把它看作一套“工具接入标准”或“通信协议”。它定义了工具Skills如何以一种统一、标准化的方式把自己“能干什么”、“需要什么参数”告诉给 Agent。有了 MCPAgent 就能动态发现和调用各种工具而无需为每个工具写死代码。Skills 这就是具体的“工具”或“技能”。一个 Skill 就是一个具体的能力比如“读取数据库”、“发送邮件”、“查询天气”、“操作 Excel 文件”。通过 MCP 协议这些 Skills 被封装成 Agent 可以理解和调用的格式。所以当有人讨论“Claude 接入 Skills”、“Agent 开发”时他们本质上是在做同一件事构建一个能自动使用外部工具的大模型应用。这对于需要将 AI 能力嵌入到具体工作流如数据分析、自动化办公、智能客服的场景来说是效率提升的关键。2. 环境准备与核心依赖别在第一步就卡住在开始写代码之前先把环境理顺。很多“跑不起来”的问题都出在环境配置和依赖版本上。这里我按实际落地的顺序带你过一遍。2.1 基础 Python 环境与关键包首先你需要一个 Python 环境建议 3.8 以上。我强烈建议使用虚拟环境venv或conda来隔离项目依赖。核心的 Python 包主要有以下几个pip install langchain langchain-communitylangchain是核心框架langchain-community包含了大量社区贡献的工具、集成和工具。版本注意LangChain 迭代很快API 可能有变动。如果遇到某些类或函数找不到第一反应是去查对应版本的官方文档而不是盲目搜索。这是新手最容易踩的坑。2.2 大模型 API 密钥Agent 的“大脑”需要一个大模型来驱动。你需要准备一个 LLM 提供商的 API Key。OpenAI / Azure OpenAI 最常用生态最成熟。你需要OPENAI_API_KEY。Anthropic Claude 在长上下文和复杂指令遵循上表现很好。你需要ANTHROPIC_API_KEY。其他如DeepSeek、智谱、月之暗面等国内外的模型只要 LangChain 支持都可以。将 API Key 设置为环境变量这是最安全、最方便的做法# Linux/macOS export OPENAI_API_KEYyour-api-key-here # Windows (PowerShell) $env:OPENAI_API_KEYyour-api-key-here或者在代码中通过os.environ[“OPENAI_API_KEY”] “your-key”设置不推荐用于生产环境。2.3 关于 MCP Server 和 Skills这是概念上最容易混淆的地方。MCP 是一个协议要实现它你需要一个MCP Server。这个 Server 负责管理一个或多个Skills并以标准格式向 Agent 暴露这些 Skills 的功能。目前你有几种选择来获得 MCP Server 和 Skills使用现成的 MCP Server 一些项目或公司提供了开箱即用的 MCP Server里面集成了很多常用 Skills如文件操作、SQL查询等。你需要运行这个 Server。自己实现 MCP Server 如果你有自定义的工具需要接入就需要按照 MCP 协议规范自己编写 Server 端代码。这涉及到定义工具Tools的 Schema名称、描述、参数。使用 LangChain 内置工具 对于快速验证LangChain 的langchain.tools和langchain-community中已经有很多预定义的工具如WikipediaQueryRun,ShellTool。你可以先用这些工具构建一个简单的 Agent理解流程再考虑接入更复杂的 MCP。对于初次尝试我建议路线是先忽略“纯 MCP”的实现复杂度直接用 LangChain 内置工具跑通一个 Agent。这能让你快速建立对 Agent 工作流的直觉。理解了 Agent 如何调用 Tools 之后再去研究 MCP Server 的部署和连接会顺畅很多。3. 从零构建你的第一个 LangChain Agent我们从一个最简单的例子开始创建一个能使用搜索引擎和计算器的 Agent。这个例子不涉及 MCP Server但完整展示了 Agent 的核心工作流。3.1 定义工具Skills首先我们创建两个工具一个用于网络搜索一个用于数学计算。from langchain.tools import Tool, DuckDuckGoSearchRun from langchain.utilities import ArxivAPIWrapper import math # 工具1 网络搜索使用 DuckDuckGo search DuckDuckGoSearchRun() search_tool Tool( nameWeb Search, funcsearch.run, descriptionUseful for when you need to answer questions about current events or general knowledge. Input should be a search query. ) # 工具2 计算器 def calculator_func(expression: str) - str: Evaluate a mathematical expression. Use only , -, *, /, **, ( ). try: # 警告直接使用 eval 有安全风险仅用于演示。生产环境应使用安全评估库如 asteval。 result eval(expression, {__builtins__: None}, {math: math}) return str(result) except Exception as e: return fError evaluating expression: {e} calc_tool Tool( nameCalculator, funccalculator_func, descriptionUseful for performing arithmetic calculations. Input should be a valid mathematical expression as a string, e.g., 3 * 4 5. ) # 将工具放入列表 tools [search_tool, calc_tool]关键点每个Tool对象都必须有清晰的name、func执行函数和description。description至关重要因为 Agent大模型就是靠阅读这些描述来决定在什么情况下使用哪个工具。3.2 初始化大模型和 Agent接下来我们选择一个 LLM并用它和工具列表来创建 Agent。from langchain_openai import ChatOpenAI from langchain.agents import create_react_agent, AgentExecutor from langchain import hub # 1. 初始化 LLM llm ChatOpenAI(modelgpt-4o, temperature0) # 使用 gpt-4o温度设为0保证稳定性 # 2. 获取一个预设的提示词模板。ReAct 是一个经典的 Agent 推理框架。 prompt hub.pull(hwchase17/react) # 3. 创建 Agent agent create_react_agent(llm, tools, prompt) # 4. 创建 Agent 执行器它负责运行 Agent 的循环思考 - 选择工具 - 执行 - 观察 - 再思考... agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue)verboseTrue会让整个执行过程打印出来非常适合调试和学习。handle_parsing_errorsTrue很重要当模型输出格式不符合 Agent 预期时它能防止程序直接崩溃而是尝试让模型重试。3.3 运行并观察 Agent 思考过程现在让我们问一个需要结合搜索和计算的问题。question “What was the GDP of the United States in 2023? If it grew by 2.5% in 2024, what would the projected GDP be?” result agent_executor.invoke({input: question}) print(f\n最终答案: {result[output]})当你运行这段代码时在控制台会看到类似以下的输出verboseTrue的效果 Entering new AgentExecutor chain... I need to find the US GDP for 2023 first, then calculate the projected GDP for 2024 with a 2.5% growth. Action: Web Search Action Input: “United States GDP 2023” Observation: [Search result: The GDP of the United States in 2023 was approximately $27.36 trillion.] Thought: Now I have the 2023 GDP. I need to calculate 2.5% of that and add it to get the 2024 projection. Action: Calculator Action Input: “27360 * 0.025” Observation: 684 Thought: So the growth is $684 billion. Now add it to the 2023 GDP. Action: Calculator Action Input: “27360 684” Observation: 28044 Thought: The projected GDP for 2024 would be approximately $28.044 trillion. Final Answer: The GDP of the United States in 2023 was about $27.36 trillion. With a 2.5% growth in 2024, the projected GDP would be approximately $28.044 trillion. Finished chain. 最终答案: The GDP of the United States in 2023 was about $27.36 trillion. With a 2.5% growth in 2024, the projected GDP would be approximately $28.044 trillion.这就是 Agent 的核心魔力它自动完成了“规划-执行-推理”的循环。你不需要告诉它先去搜索再去计算。你只给了最终目标它自己拆解了步骤。4. 进阶接入真正的 MCP Server 与自定义 Skills当你理解了基础 Agent 的工作流后就可以探索更工程化的 MCP 模式了。这里的核心变化是工具Skills不再直接写在 Python 代码里而是由一个独立的 MCP Server 提供。4.1 理解 MCP 通信模型在 MCP 架构下你的应用Client通常是 LangChain Agent和工具提供方Server是分离的。它们通过标准化的 JSON-RPC 消息进行通信。Client 初始化 连接到 MCP Server。Server 宣告 Server 向 Client 发送它提供的所有 Tools 的列表及其 Schema。Agent 工作 当 Agent 决定使用某个工具时Client 会向 Server 发送一个call_tool请求。Server 执行 Server 执行对应的工具函数并将结果返回给 Client。Client 接收 Client 将结果交给 Agent 进行下一步推理。这种分离的好处是解耦 Skill 的开发者后端和 Agent 的开发者前端/应用层可以独立工作。安全 敏感操作如数据库访问、服务器命令可以封装在受控的 Server 环境中而不是在调用 LLM 的客户端环境中。动态性 Server 可以随时更新或添加新的 SkillsClient 无需修改代码即可发现和使用。4.2 部署并连接一个简单的 MCP Server假设我们已经有一个运行在http://localhost:8080的 MCP Server它提供了一个read_file的技能。我们需要让 LangChain Agent 能调用它。LangChain 社区通常通过MCPClient来桥接。虽然 LangChain 核心库对 MCP 的原生支持在演进中但一个常见的实践模式是将 MCP Server 提供的工具“转换”为 LangChain 能识别的Tool对象。下面是一个概念性的代码示例展示了如何连接并封装 MCP 工具# 假设我们有一个能与 MCP Server 通信的客户端类 # 注意以下是一个示意流程具体实现取决于你使用的 MCP 客户端库。 import requests import json class SimpleMCPClient: def __init__(self, server_urlhttp://localhost:8080): self.server_url server_url self.tools self._list_tools() def _list_tools(self): 向 MCP Server 请求可用的工具列表 response requests.post(f{self.server_url}/list_tools) # MCP 协议有标准端点 return response.json() # 返回工具 schema 列表 def call_tool(self, tool_name, arguments): 调用指定的 MCP 工具 payload { jsonrpc: 2.0, method: call_tool, params: {name: tool_name, arguments: arguments}, id: 1 } response requests.post(f{self.server_url}/rpc, jsonpayload) result response.json() if error in result: raise Exception(fMCP Tool error: {result[error]}) return result[result] # 使用这个客户端创建 LangChain Tool mcp_client SimpleMCPClient() def read_file_wrapper(file_path: str) - str: Wrapper function that calls the MCP servers read_file tool. return mcp_client.call_tool(read_file, {path: file_path}) mcp_file_tool Tool( nameread_file, funcread_file_wrapper, descriptionReads the contents of a file from the local filesystem. Input should be a valid file path string. ) # 现在你可以像使用普通工具一样将 mcp_file_tool 加入到你的 Agent 工具列表中 tools.append(mcp_file_tool) # 然后用新的 tools 列表重新创建 agent_executor关键点 你需要一个实际的 MCP Server 在运行。你可以寻找开源实现例如一些项目提供的示例 Server或者根据 MCP 协议规范自己实现一个。连接的核心是将 MCP Server 的 RPC 调用封装成 LangChainTool对象。4.3 开发一个自定义 SkillMCP Server 端如果你想自己提供 Skill就需要实现 MCP Server。这通常涉及以下步骤以 Python 为例选择 MCP SDK 使用官方或社区提供的 MCP SDK例如mcp-sdk-python来简化协议通信。定义工具函数 编写实际执行操作的函数如数据库查询、调用外部 API。注册工具 使用 SDK 将你的函数注册为 MCP 工具并定义好输入输出的 JSON Schema。启动 Server 启动一个 HTTP 或 stdio 服务器等待 Client 连接。一个极简的伪代码示例# server.py (概念示例) from mcp_sdk import Server, Tool server Server(my-skills-server) server.tool( nameget_weather, descriptionGet current weather for a city., args_schema{“city”: {“type”: “string”, “description”: “City name”}} ) async def get_weather(city: str) - str: # 这里实现真正的天气 API 调用 return f“The weather in {city} is sunny.” if __name__ __main__: server.run(transportstdio) # 或 “http”端口 8080运行这个 Server 后任何兼容 MCP 的 Client包括未来可能直接支持 MCP 的 Claude Desktop 等应用都能发现并调用get_weather这个技能。5. 生产环境实践稳定性、成本与调试当你的 Agent 从 Demo 走向实际应用时以下几个点必须重点关注。5.1 控制成本与稳定性Token 消耗Agent 的“思考”过程ReAct 格式会产生大量的 Token 消耗尤其是它反复输出Thought、Action、Observation时。选择性价比模型 对于工具调用逻辑简单的任务可以考虑使用gpt-3.5-turbo而非gpt-4来驱动 Agent以大幅降低成本。复杂任务再切换回更强的模型。设置最大迭代次数AgentExecutor可以设置max_iterations和max_execution_time参数防止 Agent 陷入无限循环或处理过于复杂的任务。agent_executor AgentExecutor( agentagent, toolstools, verboseTrue, max_iterations10, early_stopping_methodgenerate, # 当达到限制时让模型直接给出最终答案 handle_parsing_errorsTrue )优化工具描述 工具的description要精准、简洁。模糊的描述会导致模型错误调用或需要更多轮次来理解。5.2 错误处理与鲁棒性工具调用失败 网络超时、API 限流、文件不存在等都会导致工具调用失败。确保你的工具函数有良好的异常捕获并返回对 Agent 友好的错误信息例如“Failed to fetch data: Network timeout”而不是让程序崩溃。解析错误handle_parsing_errorsTrue是基础。你还可以自定义一个output_parser来更优雅地处理模型输出格式不符合预期的情况。验证输入 在工具函数内部对输入参数进行验证。例如文件路径工具要检查路径是否在允许的目录内防止路径遍历攻击。5.3 调试与监控充分利用verboseTrue 开发阶段一定要打开这是理解 Agent 决策过程的最直接窗口。记录日志 将AgentExecutor的运行日志包括所有的 Thoughts, Actions, Observations结构化的记录到文件或日志系统便于事后分析。使用 LangSmith 如果你在开发严肃的应用强烈建议集成 LangSmith。它能可视化追踪每一次 Agent 运行的完整链条精确看到每个步骤的输入输出、耗时和 Token 使用量是调试和优化的神器。5.4 与 LangGraph 的区别与选择搜索热词中出现了langgraph。简单来说LangChain Agent 更适合单一目标、线性或简单分支的任务流程。你给一个指令它自动规划执行。LangGraph 是一个基于图状态机的框架用于构建复杂、有状态、多轮、循环或并行的工作流。例如一个客服机器人需要管理多轮对话状态并根据不同状态跳转到不同的处理节点。如何选 如果你的任务主要是“调用工具完成一件事”用 Agent。如果你的任务涉及复杂的业务流程、状态维护和节点路由比如一个涵盖用户查询、数据库检索、生成报告、发送邮件、等待用户反馈的完整自动化流程则应该用 LangGraph。两者可以结合例如在 LangGraph 的一个节点里运行一个 Agent。6. 典型应用场景与避坑指南最后结合常见搜索词看看这套技术能用在哪儿以及有哪些“坑”。6.1 应用场景智能数据分析助手 用户用自然语言提问“上个月销售额最高的产品是什么”Agent 自动调用“数据库查询”Skill 获取数据再调用“图表生成”Skill 画出趋势图最后总结。自动化办公 “将本周项目会议纪要的关键任务提取出来生成一个TODO列表发到我的邮箱。” Agent 调用“读取文档”Skill - “文本摘要/提取”Skill - “发送邮件”Skill。内部知识库问答 结合 RAG检索增强生成Agent 可以先调用“向量库搜索”Skill 找到相关文档片段再让 LLM 生成精准答案。代码生成与操作 “在src/utils/目录下帮我创建一个名为formatDate.js的函数文件内容是按‘YYYY-MM-DD’格式化日期。” Agent 需要调用“文件系统操作”Skill。6.2 常见“坑”与解决方案坑1Agent 乱用或不用工具现象 模型要么不调用工具直接瞎猜要么调用错误的工具。排查检查工具description是否清晰、无歧义。用人类能看懂的话描述工具的功能和适用场景。检查给模型的系统提示词prompt。hwchase17/react这个 prompt 是经过优化的。如果你自定义 prompt必须包含清晰的工具使用说明。尝试换用更强的模型如从 gpt-3.5 切换到 gpt-4推理能力更强的模型在工具选择上更准确。坑2任务陷入循环或超时现象 Agent 反复调用同一个工具或者一直在“思考”不出结果。排查首先设置max_iterations如5-10次。检查工具返回的结果是否清晰。如果工具返回“未找到”或错误信息Agent 可能无法理解并陷入困惑。确保工具返回对后续决策有用的信息。在 prompt 中强调“如果你无法通过现有工具完成任务请直接告知用户并停止尝试”。坑3处理复杂、多步骤任务效果差现象 任务稍微复杂点Agent 的规划就乱了。解决方案 这可能是单一 Agent 的局限。考虑使用Plan-and-Execute模式或LangGraph。即先用一个“规划者”LLM 将大任务拆解成明确的子任务列表再由一个“执行者”Agent 或工作流依次执行每个子任务。这比让一个 Agent 自己动态规划要稳定得多。坑4MCP Server 连接或调用失败现象 Client 无法连接到 Server或调用工具时超时。排查网络与端口 确认 Server 进程是否在运行ps aux | grep mcp端口是否被占用或被防火墙拦截。协议兼容性 确认 Client 和 Server 使用的 MCP 协议版本是否兼容。查看 Server 日志。参数格式 确保调用工具时传入的参数严格符合 Server 端定义的 JSON Schema。一个字段类型不匹配就可能导致调用失败。最后的核心建议 不要一开始就追求接入复杂的 MCP 和一大堆 Skills。从最简单的 LangChain Agent 两个内置工具开始彻底理解Thought - Action - Observation这个循环。然后尝试为自己写一个自定义的 Python Tool比如一个查询数据库的函数。当你能熟练驾驭这个流程后再去研究如何将你的工具改造成 MCP Server或者如何连接别人提供的 MCP Server。这样由简入繁的路径能帮你避开大部分概念和工程上的陷阱。