LangChain Agent 接入 MCP 与 Skills:构建可插拔 AI 智能体的核心架构与实践

发布时间:2026/8/25 1:29:16
LangChain Agent 接入 MCP 与 Skills:构建可插拔 AI 智能体的核心架构与实践 1. 先搞清楚 LangChain Agent 接入 MCP 和 Skills 到底解决了什么核心问题如果你正在用 LangChain 开发 AI Agent大概率遇到过两个头疼的问题一是想让 Agent 调用外部工具比如查数据库、操作文件、调用 API时得自己写一堆适配代码流程繁琐且不易复用二是当你想给 Agent 增加新能力时要么得改核心逻辑要么得等社区或官方更新。LangChain Agent 接入MCP和Skills就是为了解决这两个核心痛点。简单来说MCP是一个标准化的“工具接入协议”它让 Agent 能像插拔 USB 设备一样动态地发现和使用各种外部工具Server而无需修改 Agent 本身的代码。Skills则可以理解为封装好的、更高级的“能力包”或“工作流”它可能基于一个或多个 MCP 工具组合成解决特定复杂任务如数据分析、内容生成的完整方案。所以这个组合带来的最直接价值是解耦与扩展性。你的 Agent 核心逻辑可以保持稳定而通过 MCP 接入的工具和 Skills 定义的能力可以随时增减、替换。这特别适合需要快速迭代、整合多种外部服务的场景比如企业内部的知识问答助手、自动化流程机器人等。对于开发者而言这意味着你不用再重复造轮子去为每个 API 写包装器也不用担心工具链变动导致 Agent 大改。你只需要关注 Agent 的“大脑”LLM 的提示词和推理逻辑而“手脚”工具和“技能组合”Skills可以通过标准协议动态配置。接下来我会从原理、环境搭建、实战接入和避坑指南四个部分带你完整走一遍。2. 理解 MCP 与 Skills 的核心原理协议层与能力层的分工在动手之前必须理清 MCP 和 Skills 各自扮演的角色以及它们如何与 LangChain Agent 协同工作。很多人容易把它们混为一谈导致配置时思路混乱。2.1 MCP标准化的工具通信协议MCP的核心思想是定义了一套 Client-Server 通信规范。MCP Server 这是工具的提供方。任何一个能通过 HTTP 或 stdio 对外提供服务的程序只要按照 MCP 协议格式通常是 JSON-RPC暴露工具列表和调用接口就可以成为一个 MCP Server。例如一个查询数据库的微服务、一个文件操作脚本甚至一个调用 Claude API 的封装程序都可以包装成 MCP Server。MCP Client 这是工具的使用方。LangChain Agent 通过一个 MCP Client 来与一个或多个 MCP Server 通信。Client 负责向 Server 查询“你有什么工具可用”并在 Agent 决策需要时按照协议格式调用指定的工具。这种架构的好处是屏蔽了异构性。无论后端工具是用 Python、Go、Node.js 写的部署在本地还是远程只要它遵循 MCP 协议你的 Agent 就能用统一的方式调用它。这极大地降低了集成成本。2.2 Skills面向任务的高级能力封装如果说 MCP 提供了“原子操作”如读文件、执行 SQL那么Skills就是由这些原子操作组合而成的“分子”或“工作流”。一个 Skill 描述了一个解决特定问题所需的一系列步骤、工具调用逻辑和数据处理流程。例如一个“生成周报”的 Skill其内部可能依次调用MCP Tool A: 从数据库查询本周任务数据。MCP Tool B: 从文件系统读取上周报告模板。内部逻辑 将数据填充进模板并调用 LLM 进行润色总结。MCP Tool C: 将最终报告保存到指定位置并发送通知。在 LangChain 的语境下Skills 可以通过Chain或AgentExecutor来实现其核心是预定义的提示词Prompt和工具调用顺序。它让 Agent 不必每次都从零开始规划如何解决一个复杂问题而是可以直接启用一个现成的、优化过的解决方案。2.3 三者协同工作流一个典型的增强型 Agent 工作流如下初始化 LangChain Agent 启动并加载配置好的 MCP Client。该 Client 连接到若干个 MCP Server如数据库 Server、文件操作 Server、网络搜索 Server。能力发现 Agent 通过 MCP Client 获取所有可用工具的列表和描述。这些描述会被自动整合到给 LLM如 Claude的提示词中告诉 LLM“你现在拥有这些工具”。任务规划与执行对于简单或通用任务Agent 的 LLM 大脑根据当前对话和工具描述自主决定调用哪个 MCP 工具。对于复杂或特定任务用户可以指示 Agent“使用那个‘生成周报’的 Skill”。Agent 则会转入该 Skill 预定义的工作流按步骤调用一系列 MCP 工具和 LLM。结果整合 工具或 Skill 执行的结果返回给 AgentAgent 再组织语言回复给用户。理解了这个分层架构你在设计系统时就能做出更清晰的决策什么功能应该下沉为 MCP Tool什么应该抽象为 Skill。3. 从零搭建实战环境以 Claude 为大脑的 Agent 为例理论清楚了我们进入实战。我会以一个相对通用的环境为例演示如何搭建一个以 Claude 模型为推理核心并能通过 MCP 使用工具和 Skills 的 LangChain Agent。3.1 基础环境与依赖准备首先确保你的开发环境已经就绪。我建议使用 Python 3.10 或以上版本并创建独立的虚拟环境。# 创建并激活虚拟环境以 conda 为例 conda create -n langchain-mcp-demo python3.10 conda activate langchain-mcp-demo # 安装核心依赖 pip install langchain langchain-community langchain-core关键点langchain是主框架langchain-community包含大量社区贡献的集成包括很多 MCP 相关组件langchain-core是核心接口。接下来安装 MCP 相关的核心库。目前 LangChain 对 MCP 的支持主要通过langchain-mcp-adapters等包实现但生态在快速演进。一个更直接的方式是使用mcp客户端库。# 安装 MCP 客户端库和 Claude SDK pip install mcp anthropic同时你需要一个可用的Claude API 密钥。前往 Anthropic 官网注册并获取。将其设置为环境变量# Linux/macOS export ANTHROPIC_API_KEYyour-api-key-here # Windows (PowerShell) $env:ANTHROPIC_API_KEYyour-api-key-here3.2 启动你的第一个 MCP Server一个计算器工具MCP Server 可以用任何语言编写。为了快速演示我们用 Python 写一个最简单的“计算器” Server。它提供一个add工具。创建一个文件calculator_server.py# calculator_server.py import asyncio from mcp import Server, stdio import json # 创建 Server 实例 server Server(calculator-server) # 定义工具 server.tool() def add(a: float, b: float) - float: Add two numbers. return a b # 运行 Server使用 stdio 传输 async def main(): async with stdio.stdio_server() as (read, write): await server.run(read, write, server.create_initialization_options()) if __name__ __main__: asyncio.run(main())这个 Server 通过标准输入输出stdio与 Client 通信这是本地进程间通信的常见方式。在另一个终端窗口运行这个 Server它会保持运行等待连接python calculator_server.py3.3 构建 LangChain Agent 并连接 MCP现在构建我们的 Agent。创建一个agent_demo.py文件# agent_demo.py import asyncio import os from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_anthropic import ChatAnthropic from langchain_core.prompts import ChatPromptTemplate from mcp import ClientSession, stdio from langchain_mcp_adapters.tools import MCPTool async def main(): # 1. 初始化 Claude 模型 llm ChatAnthropic( modelclaude-3-5-sonnet-20241022, # 或其他 Claude 3 模型 temperature0, api_keyos.environ.get(ANTHROPIC_API_KEY) ) # 2. 连接 MCP Server 并创建 LangChain Tool # 启动与 calculator_server.py 的通信 proc await asyncio.create_subprocess_exec( python, calculator_server.py, stdinasyncio.subprocess.PIPE, stdoutasyncio.subprocess.PIPE, ) stdio_transport stdio.StandardIO(proc.stdin, proc.stdout) async with ClientSession(stdio_transport) as session: # 初始化会话获取工具列表 await session.initialize() # 将 MCP 工具转换为 LangChain 可识别的 Tool 对象 mcp_tools await MCPTool.from_mcp_client_session(session) # 3. 定义 Agent 的提示词 prompt ChatPromptTemplate.from_messages([ (system, You are a helpful assistant with access to tools. Use them when needed.), (placeholder, {chat_history}), (human, {input}), (placeholder, {agent_scratchpad}), ]) # 4. 创建 Agent agent create_tool_calling_agent( llmllm, toolsmcp_tools, # 传入从 MCP 获取的工具 promptprompt, ) # 5. 创建执行器并运行 agent_executor AgentExecutor(agentagent, toolsmcp_tools, verboseTrue) # 测试让 Agent 使用计算器 result await agent_executor.ainvoke({input: 请计算 123.45 加上 678.9 等于多少}) print(\n--- Agent 回复 ---) print(result[output]) # 可以继续更多对话... # result2 await agent_executor.ainvoke({input: 刚才两数之和再乘以 2 是多少}, result) if __name__ __main__: asyncio.run(main())关键步骤解析初始化 LLM 使用ChatAnthropic封装 Claude 模型。temperature0使输出更确定适合工具调用。连接 MCP Server 通过asyncio.create_subprocess_exec启动我们刚才写的计算器 Server 进程并建立 stdio 通信管道。然后通过MCPTool.from_mcp_client_session这个适配器将 MCP 协议下的工具自动转换成 LangChainTool对象列表。这是最关键的一步实现了协议的桥接。构建 Agent 使用create_tool_calling_agent这是 LangChain 新版推荐的方式比旧的initialize_agent更清晰来创建 Agent。它将 LLM、工具列表和提示词模板组合在一起。执行与测试AgentExecutor负责运行 Agent 的思考-行动循环。设置verboseTrue可以看到 Agent 内部调用工具的思考过程。运行这个脚本python agent_demo.py如果一切正常你将看到详细的日志显示 Agent 识别出需要调用add工具传入参数得到结果并最终给出回答。至此一个最基本的、能通过 MCP 使用外部工具的 LangChain Agent 就跑通了。4. 进阶应用集成多 Server、定义 Skills 与生产化考量基础流程跑通只是第一步。在实际项目中你需要处理更复杂的情况。4.1 集成多个 MCP Server 和复杂工具一个实用的 Agent 往往需要连接多个数据源和服务。你可以同时连接多个 MCP Server。假设我们还有一个提供“天气查询”的 MCP Server假设已实现。我们可以同时连接它和计算器 Server。关键在于管理多个 ClientSession 和工具列表。# 片段连接多个 MCP Server async def load_tools_from_servers(): all_tools [] # 连接计算器 Server calc_proc await asyncio.create_subprocess_exec(...) # 同上 calc_transport stdio.StandardIO(calc_proc.stdin, calc_proc.stdout) async with ClientSession(calc_transport) as calc_session: await calc_session.initialize() calc_tools await MCPTool.from_mcp_client_session(calc_session) all_tools.extend(calc_tools) # 注意这里 session 不能立即关闭需要在整个 Agent 生命周期内保持 # 实际项目中需要更精细的生命周期管理 # 连接天气 Server (假设通过 HTTP) # 有些 MCP Server 可能通过 HTTP 而非 stdio 暴露需要使用对应的客户端连接方式 # async with ClientSession(http_transport) as weather_session: # ... return all_tools # 然后将 all_tools 传入 create_tool_calling_agent避坑点工具命名冲突。如果两个 Server 都提供了同名工具需要在 LangChain 层面进行重命名或命名空间隔离避免 Agent 混淆。4.2 将常用工作流封装为 Skills当某些任务模式固定时将其封装为 Skill 能大幅提升效率和可靠性。在 LangChain 中Skill 通常就是一个预设好提示词和工具调用逻辑的Chain。例如封装一个“获取天气并给出穿衣建议”的 Skillfrom langchain.chains import LLMChain from langchain.prompts import PromptTemplate # 假设我们已经有一个叫 get_weather 的 MCP Tool class WeatherAdviceSkill: def __init__(self, llm, tools): self.get_weather_tool next(t for t in tools if t.name get_weather) self.llm llm # 定义 Skill 专用的提示词 self.prompt PromptTemplate.from_template( 你是一个生活助手。请根据以下天气信息给出简洁的穿衣和出行建议。 天气信息{weather_info} 建议 ) self.chain LLMChain(llmself.llm, promptself.prompt) async def run(self, location: str): # 1. 调用 MCP 工具获取原始数据 weather_raw await self.get_weather_tool.ainvoke({location: location}) # 2. 将结果交给 LLM 加工成建议 advice await self.chain.ainvoke({weather_info: weather_raw}) return advice[text] # 在 Agent 中可以这样使用 Skill # 判断用户意图如果是问穿衣建议直接调用 skill.run(location) # 否则走默认的 Agent 工具调用流程。更高级的做法是利用LangGraph来编排包含多步判断、循环的复杂 Skills。LangGraph适合定义有状态、多分支的工作流而简单的线性链用LLMChain或SequentialChain即可。4.3 生产环境部署的注意事项在开发环境玩得转不代表能直接上生产。你需要考虑以下几点MCP Server 管理生命周期 Agent 进程和 MCP Server 进程的生命周期需要妥善管理。通常采用 Supervisor、Docker Compose 或 Kubernetes 来统一管理。资源隔离 每个 MCP Server 应有独立的资源限制避免一个故障 Server 拖垮整个 Agent。健康检查与重连 实现 MCP Client 对 Server 的健康检查机制并在连接断开时尝试重连或故障转移。工具描述优化MCP Server 提供的工具描述description至关重要它直接作为提示词的一部分影响 LLM 的选择。描述必须清晰、无歧义、说明输入输出格式。模糊的描述会导致 LLM 错误调用。示例差的描述“处理数据”。好的描述“根据用户ID查询其最近30天的订单列表返回一个JSON数组每个订单包含 order_id, amount, status, create_time 字段。”错误处理与稳定性Agent 调用工具可能失败网络超时、参数错误、服务异常。需要在AgentExecutor层面或自定义Chain中增加重试、降级和友好的错误信息反馈逻辑。对工具返回的结果进行有效性校验避免脏数据导致后续步骤或 LLM 解析出错。性能与成本每次工具调用都涉及 LLM 思考Claude API 调用有成本和延迟。对于高频、固定的操作考虑将其下沉为一个更复杂的 MCP Tool 或 Skill减少与 LLM 的交互次数。使用verbose模式调试但生产环境务必关闭并接入结构化日志系统如 JSON Logger方便监控和追踪每次工具调用。安全性MCP Server 可能具有高权限如数据库写操作、文件删除。必须在 Server 端实现严格的权限校验和操作审计。对用户输入传递给工具的参数进行清洗和校验防止注入攻击。谨慎暴露工具。不是所有 MCP Server 的工具都需要给每个 Agent 使用。5. 常见问题排查与调试技巧即使按照步骤操作你也可能会遇到问题。以下是几个常见坑点和排查思路。5.1 Agent 不调用工具总是直接回答现象 你问“计算11”Agent 直接说“11等于2”而不是去调用add工具。排查顺序检查工具描述 这是最常见的原因。打开verboseTrue的日志看 LLM 收到的提示词里是否包含了你的工具描述。描述是否足够清晰LLM 可能认为它自己就能算不需要调用工具。尝试将工具描述改得更强制例如“你必须使用此工具进行任何数学计算不可自行心算。”检查提示词模板 你的ChatPromptTemplate中是否包含了{agent_scratchpad}这个 placeholder这是 Agent 记录其思考过程包括工具调用所必需的。缺少它会导致 Agent 无法正常工作。检查 LLM 温度temperature参数过高可能导致输出随机性太大不遵循调用工具的指令。在工具调用场景通常设为 0 或接近 0。检查工具定义 通过print(mcp_tools)确认工具列表被正确加载且每个工具的name和description属性正常。5.2 连接 MCP Server 失败或超时现象ClientSession.initialize()报错或长时间无响应。排查顺序确认 Server 进程 首先确保你的 MCP Server 脚本如calculator_server.py正在独立运行并且没有报错退出。检查传输方式 确认 Client 和 Server 使用了相同的传输方式stdio/HTTP。示例中是 stdio确保create_subprocess_exec的命令和路径正确。查看原始日志 在 Server 和 Client 代码中增加基础日志打印出建立连接时收发的原始数据对照 MCP 协议格式检查。版本兼容性 检查mcp客户端和服务器端库的版本是否兼容。协议可能仍在演进中。5.3 工具调用结果解析错误现象 Agent 调用了工具但后续处理结果时出错或者 LLM 无法理解工具返回的内容。排查顺序检查工具返回格式 MCP 工具应返回结构化的数据如字符串、数字、字典、列表。如果返回了复杂的 Python 对象需要先序列化为 JSON 等通用格式。确保返回的数据类型与工具声明的一致。观察agent_scratchpad 在verbose日志中仔细查看agent_scratchpad的内容。它会完整记录“Thought”LLM 思考、“Action”调用哪个工具及参数、“Observation”工具返回结果。观察 “Observation” 是否是你期望的数据。简化测试 先绕过 Agent直接写代码调用MCPTool.ainvoke()看返回什么。确保工具本身工作正常。5.4 如何处理需要复杂参数的工具有些工具需要复杂的输入对象。MCP 协议和 LangChain 都支持通过 JSON Schema 定义参数。在 MCP Server 定义工具时使用server.tool()装饰器并配好参数类型提示库通常会帮你生成 Schema。在 LangChain 侧MCPTool会自动获取这个 Schema。LLM 会根据 Schema 来生成调用参数。关键 确保你的 LLM 模型如 Claude具备较强的 JSON 模式理解和生成能力。Claude 3 系列在这方面表现很好。6. 总结从原理到生产的实践路径将 LangChain Agent 与 MCP、Skills 结合本质上是在构建一个可插拔、可编排的智能体系统。MCP 解决了“能力接入”的标准化问题Skills 解决了“能力复用与组合”的效率问题。对于个人开发者或小团队我建议的实践路径是从小处着手 先像本文示例一样用一个极简的 MCP Server如计算器、时间查询和 Claude 模型把整个调用链路跑通。理解数据是如何在 Agent、MCP Client、MCP Server 之间流动的。封装核心工具 将你业务中最关键、最稳定的数据源或 API 封装成 MCP Server。优先选择“只读”或低风险的操作开始。设计提示词与工具描述 这是影响 Agent 表现最关键的“软”因素。花时间精心打磨工具的描述和系统提示词让 LLM 能准确理解何时以及如何使用工具。构建初级 Skill 针对你业务中频率高、步骤固定的任务尝试将其封装为 Skill。初期可以用简单的LLMChain实现。引入运维与监控 在考虑上生产前务必加入日志、错误处理、超时控制、性能监控等非功能性代码。考虑复杂编排 当单个 Agent 或 Chain 无法满足复杂业务流程时再考虑引入LangGraph进行有状态、多角色的工作流编排。最后保持对生态的关注。LangChain 和 MCP 的集成方式、社区提供的现成 Server 和 Skills 都在快速发展。但无论工具如何变化其核心思想——通过标准化协议解耦智能体的“思考”与“执行”通过预定义模式提升复杂问题解决效率——将是构建强大、可维护 AI Agent 应用的坚实基础。