SEO教程

SEO教程

Products

当前位置:首页 > SEO教程 >

LangChain实现远程MCP多轮调用闭环

96SEO 2026-08-08 05:18 2


用 LangChain 连接远程 MCP:从工具发现到多轮调用闭环

第一次看到 MCP 客户端代码时很容易把它理解成“让大模型调用一个接口”。但真正写起来几个问题会立刻冒出来:

  • 工具?
  • 它返回的工具参数由谁执行?
  • 执行结果为什么还要放回消息列表?
  • HTTP MCP 和普通 HTTP API 又有什么区别?

这些正是开发者在实际项目中最常碰到的痛点:

LangChain实现远程MCP多轮调用闭环
  • 工具发现不透明,导致模型调用失败。
  • 调用结果无法正确回流,导致对话上下文缺失。
  • MCP 与传统 REST 的差异没有清晰文档,调试成本高。

这篇文章用一个可运行的 Node.js 示例完成一条最小但完整的链路:连接一个远程 MCP Server。读取它暴露的工具,把工具绑定给聊天模型,执行模型发起的工具调用,再把结果交回模型生成最终回答。

示例使用 LangChain 负责模型与消息编排,使用 @langchain/mcp-adapters 把 MCP 工具转换成 LangChain 能识别的工具。读完之后你不仅能运行代码,也能说清每一轮数据究竟流向了哪里。

MCP 在这条链路中解决了什么

大模型本身只负责使用外部能力。应用程序至少要完成三件事:

  1. 工具,还有每个工具需要哪些参数。
  2. 接收模型生成的工具调用请求,并真正执行对应工具。
  3. 把执行结果送回模型,让模型继续判断或组织答案。

MCP为工具的发现、参数描述和调用方式提供了一套统一协议。地图服务、浏览器控制器和文件程序服务可以分别实现 MCP Server;应用只要实现 MCP Client,就能用相似的方式接入它们。

使用者痛点:在没有统一协议之前。每接入一个新能力都得手写一次发现、序列化、反序列化逻辑,代码重复且易出错。MCP 把这些重复工作抽离出来让团队专注业务本身。

  • MCP 是通信协议:客户端与服务端用它交换工具列表、调用参数和结果。说起来,
  • 工具调用是模型能力:模型根据工具描述生成结构化的调用意图。但真正执行工具的仍然是我们的 Node.js 程序。

MCP 常见的传输方式包括 stdio 和 Streamable HTTP。不过,stdio 通常由客户端启动本地子进程。再通过标准输入输出通信,HTTP 则连接已经运行在某个 URL 上的服务,更适合跨机器部署。这篇文章聚焦远程 HTTP 服务,同时会说明如何切换到 stdio.

准备项目与环境变量

建议使用 Node.js v18 或更高版本,并创建一个新项目:

mkdir remote-mcp-demo
cd remote-mcp-demo
npm init -y
npm install dotenv @langchain/core @langchain/openai @langchain/mcp-adapters
mkdir src

示例文件使用 .mjs 后缀,所以 Node.js 会按 ES Module 处理。可以直接使用 和顶层 ,不必额外修改 .

在项目根目录创建 .env:

MODEL_API_KEY=your_api_key
MODEL_BASE_URL=https://your-model-provider.example/v1
MODEL_NAME=your-tool-calling-model
MCP_SERVER_URL=https://your-mcp-server.example/mcp

四个值分别表示模型密钥、OpenAI 兼容接口地址、支持工具调用的模型名,还有远程 MCP 端点。说起来,不同供应商名称和地址不同,应以实际服务为准。不要把真实 .env 提交到 Git 仓库,可在 .gitignore 中加入:

.env

` 会在程序启动时读取 .env。并把值放入 . 环境变量不存在时 JavaScript 通常只会得到

先连接 MCP Server 并发现工具

Create ,write connection and tool‑loading part first:

import "dotenv/config";import { MultiServerMCPClient } from "@langchain/mcp-adapters";不过,function requireEnv {
const value = process.env;不过,if {
throw new Error;老实说,}
return value;}
const mcpClient = new MultiServerMCPClient({
useStandardContentBlocks: true,mcpServers: {
remoteService: {
transport: "http"。url: requireEnv,},// 如需本地 stdio,只需改成下面形式:
// localService: {
// transport: "stdio",// command: "node",// args:,// },},});const tools = await mcpClient.getTools;console.log);

Pain point: 很多团队在“获取工具列表”这一步直接硬编码或手动复制 swagger,这导致维护成本爆炸。一旦后端更新,只需要重新跑一次 getTools 即可自动同步。

把工具交给模型,不等于已经执行工具

import { ChatOpenAI } from "@langchain/openai";const model = new ChatOpenAI({
model的观点是,requireEnv,apiKey: requireEnv。temperature: 0,configuration: { baseURL: requireEnv },});const modelWithTools = model.bindTools;

User pain point: 开发者经常误以为 bindTools 就会自动执行。这导致调试时看到“模型说要用 X 工具,却没有实际请求”。bindTools 仅是把“菜单”交给 LLM 看,看完后仍需自行循环调度。

用消息列表完成工具调用闭环

A single question may need multiple tools,or repeated calls to same tool . Therefore we must loop until model stops requesting tools.

import { HumanMessage } from "@langchain/core/messages";async function runAgent {
const messages =;for {
console.log;const response = await modelWithTools.invoke;其实,messages.push;const toolCalls = response.tool_calls?,;if {
// 没有 tool_calls 表示得到最终答案
return response.content;怎么说呢,}
for {
const tool = tools.find;if {
throw new Error;}
console.log})`);// 必须传入完整对象,以保留 call_id 等元信息
const toolMessage = await tool.invoke;messages.push;}
}
throw new Error;}

Pain point:

  • If you only pass 。you lose call ID and model cannot associate results with its request,causing “我没有收到结果” 的错误。
  • If you forget to push  back into ,subsequent rounds will not see tool’s output.
  • The loop guard (maxIterations) prevents runaway billing when a mis‑configured model keeps calling tools forever.

完整可运行代码

import "dotenv/config";import { MultiServerMCPClient } from "@langchain/mcp-adapters";import { ChatOpenAI } from "@langchain/openai";import { HumanMessage } from "@langchain/core/messages";function requireEnv {
const v = process.env;if throw new Error;return v,}
// ---------- 初始化 MCP 客户端 ----------
const mcpClient = new MultiServerMCPClient({
useStandardContentBlocks: true。mcpServers: {
remoteService: {
transport: "http",url: requireEnv,},},});async function run {
// ---- 步骤1:发现并转换工具 ----
const tools = await mcpClient.getTools;console.log,// ---- 步骤2:创建支持 Tool Calling 的语言模型 ----
const model = new ChatOpenAI({
再看model。requireEnv,apiKey: requireEnv,temperature: 0,configuration: { baseURL: requireEnv },});
const modelWithTools = model.bindTools;// ---- 步骤3:进入 Agent 循环 ----
const answer = await runAgent(
"请告诉我这个 MCP 服务提供了哪些能力,并选择合适的工具验证其中一项。",tools,modelWithTools。/* maxIterations */5
);console.log,}
// ---------- Agent Loop ----------
async function runAgent {
const messages =;老实说,for {
console.log;const aiResp = await modelWithTools.invoke;messages.push;const calls = aiResp.tool_calls?,;if return aiResp.content;for {
const tool = tools.find;if throw new Error;console.log);const resultMsg = await tool.invoke;// 保留 call_id 等元信息
messages.push;console.log);}
}
throw new Error 已达,但仍未产生最终答案`);}
// ---------- 执行入口 ----------
run
.catch)
.finally => mcpClient.close);

程序从启动到结束发生了什么

  1. .env 加载:`dotenv/config` 把配置注入 `process.env`。
  2. MCP 客户端实例化:`MultiServerMCPClient` 创建但尚未发起网络请求。
  3. #1 工具发现:`getTools` 向远程 HTTP MCP Server 发起握手,请求并解析 `` 为 LangChain 可识别对象。
  4. #2 模型创建 & bind:`ChatOpenAI` 配置好兼容 OpenAI 的 endpoint,接下来 `bindTools` 把每个 Tool 的 name/description/schema 注入后续请求 payload 中。
  5. #3 第一次推理:`modelWithTools.invoke` 将使用者问题 + Tool schema 发给 LLM;LLM 若需要外部信息,会返回 `tool_calls` 数组。此响应也被记录进 `messages` 历史。
  6. #4 工具执行:`tool.invoke` 使用 MCP 协议通过 HTTP/STDIO 实际调用远端服务;返回值被包装成 `ToolMessage`,随后追加到 `messages`。
  7. #5 循环迭代:LMM 看到完整历史,决定是否继续调取其他 Tool 或直接给出答案。如果 `tool_calls` 为,循环终止并返回最终 `content`。
  8. #6 清理资源:`finally` 块里统一调用 `mcpClient.close`。关闭 HTTP 长连或子进程句柄,以防进程悬挂或泄漏句柄导致超时计费。

常见错误与排查方法

1️⃣ 工具结果为空或模型提示“没有收到结果” 🚩

  • Pain point:开发者往往只取 `toolCall.args` 手动请求后返回字符串。而忘记把关联 ID 包装回 `ToolMessage`,导致 LLM 无法匹配结果来源。
  • SOLUTION:始终使用完整对象 `await tool.invoke`;若自行实现自定义适配器,请确保返回对象包含 `{content。tool_call_id}` 字段。
  • TROUBLESHOOTING:
    1. 检查控制台是否打印 “执行 Tool …” 日志,若没有说明 `tool_calls` 本身为空。
    2. 确认 Remote Service 返回的是标准化 ContentBlock,而不是随意打印日志到 stdout。
    3. If using HTTP,inspect raw response via curl – you should see a JSON envelope with `content_blocks`.

2️⃣ Remote 地址浏览器可访问。但 MCP 连不上 ❌

  • Pain point:很多人误以为任意公开 URL 都是有效 MCP endpoint,仅凭浏览器能打开就认为配置正确,从而浪费时间定位网络层错误。
  • SOLUTION:
    • - 确认 URL 包含完整方法,如 `/mcp/v1/stream` 而非根域名。
    • - 检查服务器是否实现 *Streamable* HTTP,而非普通 REST 响应。如果是旧式 SSE,需要将 client 配置改为 `{transport:"sse"}`。
    • - 如需鉴权,在 client 配置里加入 `{headers:{Authorization:`Bearer ${token}`}}`。
    • - 本地网络防火墙 / 公司代理 是否阻断了 Node.js 对该域名的 outbound 请求?可尝试 telnet / curl 验证。不过,

3️⃣ 模型一直不触发 Tool 调用 🔄

  • Pain point:开发者经常忘记确认所选 LLM 真正支持 “function calling / tool calling”。或者 Prompt 没有明确引导需求,使得 LLM 给出直接答案而不需要外部信息。"​"
  • SOLUTION:
    • - 打印已加载 Tools 列表 `),确保描述足够明确且符合业务场景。
    • - 在 Prompt 中加入 “如果需要获取 X。请使用 Y 工具”,或者使用程序指令强制开启函数模式。
    • - 若使用 OpenAI‑compatible 服务。请确认 API 文档中标明支持 `"tools"` 参数,否则接口会忽略并返回纯文本。

4️⃣ 本地 stdio 服务报 “Cannot find module …老实说,” 📁

  • Pain point:相对方法经常因启动目录不同而失效。使得子进程根本没法启动,从而导致客户端一直等待超时。
  • SOLUTION:
    • - 使用绝对方法 `) 填入 `args`.
    • - 在终端单独运行 `node /abs/path/to/server.mjs` 确认脚本本身可以正常启动且不向 stdout 输出除 error 外的信息。

5️⃣ 程序异常后进程不退出 ⚙️

  • Pain point:HTTP 长链接或子进程仍保持打开状态。使得 Node.js event loop 永久活跃,即使主逻辑已经抛错退出也看不到 exit code。
  • SOLUTION:
    • - 将所有资源释放写在 `finally { await mcpClient.close;}`.
    • - 对于 stdio 子进程,可显式调用 `.kill` 或监听 `'exit'` 回调确保已结束。

从演示走向真实生产环境 🚀

  • A. 限制可用 Tool 列表: 不要盲目暴露所有服务器实现的功能,只让业务需要的几项通过白名单方式注册到 LangChain。这能防止恶意 Prompt 调用危险操作。
  • B. 超时、重试与输出上限: 网络 I/O 与搜索类 Service 常有长尾延迟,为每次 invoke 设置 `timeoutMs ` 并限制最大重试次数;对返回内容做大小截断或摘要,以免占满 LLM。不过,
  • | 场景 | 推荐配置 | |------|----------| | 搜索 API | timeoutMs=5000。retry=2 | | 文件读取 | maxBytes=200KB | | 图片生成 | maxTokens=300 |
  • C. 完整日志与追踪 ID: 为每次使用者查询生成唯一 traceId,将其随每轮消息、Tool 调用还有响应一起记录。日志中 **不要** 打印 API 密钥或原始使用者隐私数据,只保留摘要信息供运维排查。怎么说呢,
  • D. 参数复核 & 安全校验: 即便 Schema 限定了类型。也不能直接信任,例如方法字段合法但可能指向受保护目录;URL 参数合法却可能触发 SSRF。建议在实际执行前再走一遍业务白名单检查或人工批准流程。

🎯

MCP 并不是某个神奇函数,而是一套"发现‑描述‑调用‑回流" 的闭环机制。从在这套机制里来看,

  • Discovery —— 用统一协议拿到远端 Service 暴露出的 Tools;

  • Binding —— 把 Tools Schema 注入 LLM,让它能够生成结构化调用意图;

  • 标签: 闭环

    SEO优化服务概述

    作为专业的SEO优化服务提供商,我们致力于通过科学、系统的搜索引擎优化策略,帮助企业在百度、Google等搜索引擎中获得更高的排名和流量。我们的服务涵盖网站结构优化、内容优化、技术SEO和链接建设等多个维度。

    百度官方合作伙伴 白帽SEO技术 数据驱动优化 效果长期稳定

    SEO优化核心服务

    网站技术SEO

    • 网站结构优化 - 提升网站爬虫可访问性
    • 页面速度优化 - 缩短加载时间,提高用户体验
    • 移动端适配 - 确保移动设备友好性
    • HTTPS安全协议 - 提升网站安全性与信任度
    • 结构化数据标记 - 增强搜索结果显示效果

    内容优化服务

    • 关键词研究与布局 - 精准定位目标关键词
    • 高质量内容创作 - 原创、专业、有价值的内容
    • Meta标签优化 - 提升点击率和相关性
    • 内容更新策略 - 保持网站内容新鲜度
    • 多媒体内容优化 - 图片、视频SEO优化

    外链建设策略

    • 高质量外链获取 - 权威网站链接建设
    • 品牌提及监控 - 追踪品牌在线曝光
    • 行业目录提交 - 提升网站基础权威
    • 社交媒体整合 - 增强内容传播力
    • 链接质量分析 - 避免低质量链接风险

    SEO服务方案对比

    服务项目 基础套餐 标准套餐 高级定制
    关键词优化数量 10-20个核心词 30-50个核心词+长尾词 80-150个全方位覆盖
    内容优化 基础页面优化 全站内容优化+每月5篇原创 个性化内容策略+每月15篇原创
    技术SEO 基本技术检查 全面技术优化+移动适配 深度技术重构+性能优化
    外链建设 每月5-10条 每月20-30条高质量外链 每月50+条多渠道外链
    数据报告 月度基础报告 双周详细报告+分析 每周深度报告+策略调整
    效果保障 3-6个月见效 2-4个月见效 1-3个月快速见效

    SEO优化实施流程

    我们的SEO优化服务遵循科学严谨的流程,确保每一步都基于数据分析和行业最佳实践:

    1

    网站诊断分析

    全面检测网站技术问题、内容质量、竞争对手情况,制定个性化优化方案。

    2

    关键词策略制定

    基于用户搜索意图和商业目标,制定全面的关键词矩阵和布局策略。

    3

    技术优化实施

    解决网站技术问题,优化网站结构,提升页面速度和移动端体验。

    4

    内容优化建设

    创作高质量原创内容,优化现有页面,建立内容更新机制。

    5

    外链建设推广

    获取高质量外部链接,建立品牌在线影响力,提升网站权威度。

    6

    数据监控调整

    持续监控排名、流量和转化数据,根据效果调整优化策略。

    SEO优化常见问题

    SEO优化一般需要多长时间才能看到效果?
    SEO是一个渐进的过程,通常需要3-6个月才能看到明显效果。具体时间取决于网站现状、竞争程度和优化强度。我们的标准套餐一般在2-4个月内开始显现效果,高级定制方案可能在1-3个月内就能看到初步成果。
    你们使用白帽SEO技术还是黑帽技术?
    我们始终坚持使用白帽SEO技术,遵循搜索引擎的官方指南。我们的优化策略注重长期效果和可持续性,绝不使用任何可能导致网站被惩罚的违规手段。作为百度官方合作伙伴,我们承诺提供安全、合规的SEO服务。
    SEO优化后效果能持续多久?
    通过我们的白帽SEO策略获得的排名和流量具有长期稳定性。一旦网站达到理想排名,只需适当的维护和更新,效果可以持续数年。我们提供优化后维护服务,确保您的网站长期保持竞争优势。
    你们提供SEO优化效果保障吗?
    我们提供基于数据的SEO效果承诺。根据服务套餐不同,我们承诺在约定时间内将核心关键词优化到指定排名位置,或实现约定的自然流量增长目标。所有承诺都会在服务合同中明确约定,并提供详细的KPI衡量标准。

    SEO优化效果数据

    基于我们服务的客户数据统计,平均优化效果如下:

    +85%
    自然搜索流量提升
    +120%
    关键词排名数量
    +60%
    网站转化率提升
    3-6月
    平均见效周期

    行业案例 - 制造业

    • 优化前:日均自然流量120,核心词无排名
    • 优化6个月后:日均自然流量950,15个核心词首页排名
    • 效果提升:流量增长692%,询盘量增加320%

    行业案例 - 电商

    • 优化前:月均自然订单50单,转化率1.2%
    • 优化4个月后:月均自然订单210单,转化率2.8%
    • 效果提升:订单增长320%,转化率提升133%

    行业案例 - 教育

    • 优化前:月均咨询量35个,主要依赖付费广告
    • 优化5个月后:月均咨询量180个,自然流量占比65%
    • 效果提升:咨询量增长414%,营销成本降低57%

    为什么选择我们的SEO服务

    专业团队

    • 10年以上SEO经验专家带队
    • 百度、Google认证工程师
    • 内容创作、技术开发、数据分析多领域团队
    • 持续培训保持技术领先

    数据驱动

    • 自主研发SEO分析工具
    • 实时排名监控系统
    • 竞争对手深度分析
    • 效果可视化报告

    透明合作

    • 清晰的服务内容和价格
    • 定期进展汇报和沟通
    • 效果数据实时可查
    • 灵活的合同条款

    我们的SEO服务理念

    我们坚信,真正的SEO优化不仅仅是追求排名,而是通过提供优质内容、优化用户体验、建立网站权威,最终实现可持续的业务增长。我们的目标是与客户建立长期合作关系,共同成长。

    提交需求或反馈

    Demand feedback