LangChain 接入 MCP 实战指南:解锁模型上下文管理新范式

在构建基于大语言模型(LLM)的复杂应用时,开发者常常面临一个核心挑战:如何高效、可靠地管理不断增长的对话或文档上下文?传统的上下文拼接方法不仅容易触及模型的令牌限制,还可能导致关键信息丢失或成本激增。Model Context Protocol (MCP) 的出现,为解决这一难题提供了标准化的思路。而当 MCP 遇上强大的 AI 应用编排框架 LangChain 时,又能碰撞出怎样的火花?本文将带你从零开始,深入探索 LangChain 接入 MCP 的完整流程。

什么是 MCP?为何需要它?

MCP (Model Context Protocol) 是一个开放的协议,旨在为大语言模型应用提供标准化的上下文管理接口。它的核心思想是将“上下文管理”作为一个独立的服务层,与具体的模型推理逻辑解耦。

MCP 的核心优势:

  1. 标准化:为不同的模型提供商(如 OpenAI, Anthropic, Cohere)提供统一的上下文操作接口。
  2. 高效性:通过智能的上下文压缩、摘要、优先级排序和向量检索等技术,在有限的令牌窗口内保留最相关的信息。
  3. 可观测性:提供对上下文使用情况的清晰洞察,便于调试和优化。
  4. 成本控制:通过减少不必要的令牌使用,直接降低 API 调用成本。

对于 LangChain 开发者而言,集成 MCP 意味着可以将繁琐的上下文窗口管理、历史消息处理等“脏活累活”外包给专业的 MCP 服务器,从而更专注于应用本身的业务逻辑和链式编排。

LangChain 与 MCP 集成的典型场景

在实际项目中,LangChain + MCP 的组合大有用武之地:

  • 长文档问答系统:处理远超模型上下文长度的 PDF、研究报告,MCP 可以动态检索最相关的片段供 LLM 参考。
  • 多轮复杂对话助手:在持续的对话中,智能地维护对话历史,总结过往回合,确保模型始终拥有“记忆”。
  • Agent 的长期记忆:为 LangChain Agent 提供持久的、可查询的记忆存储,使其在多次运行中都能记住关键信息。
  • 降低 API 调用成本:通过压缩冗余或次要的上下文,确保每次请求的令牌数都在最优范围内。

实战:一步步将 MCP 接入 LangChain

下面我们将通过一个完整的示例,演示如何搭建一个简单的 MCP 服务器,并在 LangChain 链中使用它。

步骤 1:环境准备与依赖安装

首先,确保你已安装 Python 3.8+。然后安装必要的库。我们将使用 mcp 库来创建服务器,并使用 LangChain 的社区集成包。

pip install langchain langchain-community mcp openai

步骤 2:创建一个简单的 MCP 服务器

MCP 服务器负责实际的上下文管理逻辑。我们创建一个名为 simple_mcp_server.py 的文件。

# simple_mcp_server.py
import asyncio
from typing import List, Optional
from mcp import Server, ClientSession
from mcp.shared.models import ContextItem, ListContextItemsResult

class SimpleContextManager:
    """一个简单的内存上下文管理器示例"""
    def __init__(self):
        self.contexts: List[ContextItem] = []

    async def list_items(self) -> ListContextItemsResult:
        """列出所有上下文项"""
        return ListContextItemsResult(items=self.contexts)

    async def add_item(self, item: ContextItem):
        """添加上下文项(这里实现简单的去重)"""
        # 简单示例:如果存在同名的项,则替换内容
        for i, ctx in enumerate(self.contexts):
            if ctx.name == item.name:
                self.contexts[i] = item
                return
        self.contexts.append(item)

    async def get_relevant_context(self, query: str, limit: int = 2) -> List[ContextItem]:
        """根据查询返回最相关的上下文(这里实现简单的关键词匹配)"""
        # 这是一个非常简化的“检索”逻辑。生产环境应使用向量数据库。
        relevant = []
        query_lower = query.lower()
        for ctx in self.contexts:
            if query_lower in ctx.content.lower():
                relevant.append(ctx)
                if len(relevant) >= limit:
                    break
        return relevant

# 创建 MCP 服务器实例
server = Server()
context_manager = SimpleContextManager()

@server.list_context_items()
async def handle_list_items(session: ClientSession) -> ListContextItemsResult:
    return await context_manager.list_items()

@server.add_context_item()
async def handle_add_item(session: ClientSession, item: ContextItem) -> None:
    await context_manager.add_item(item)

@server.get_context()
async def handle_get_context(session: ClientSession, query: str) -> List[ContextItem]:
    # 在实际协议中,可能需要更复杂的请求体,这里做了简化
    return await context_manager.get_relevant_context(query)

async def main():
    # 启动服务器,监听本地端口 8000
    async with await server.run_tcp_server("localhost", 8000) as server_handle:
        print("MCP 服务器已在 localhost:8000 启动")
        await server_handle.serve_forever()

if __name__ == "__main__":
    asyncio.run(main())

步骤 3:在 LangChain 中创建 MCP 工具并集成到链中

现在,我们在另一个文件中创建 LangChain 应用,并通过 MCPClient 连接到我们刚创建的服务器。

# langchain_mcp_client.py
import asyncio
from langchain.agents import AgentExecutor, create_tool_calling_agent
from langchain_core.prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from langchain_community.tools.mcp import MCPClient, create_mcp_tool

async def main():
    # 1. 初始化 MCP 客户端,连接到我们的服务器
    # 注意:`langchain-community` 中的 MCP 集成可能仍在演进,以下为示例性代码。
    # 实际使用时请查阅最新文档。
    async with MCPClient(server_url="http://localhost:8000") as client:
        # 2. 基于 MCP 客户端的能力创建 LangChain Tool
        # 假设我们的服务器提供了 `add_context` 和 `query_context` 工具
        tools = []
        
        # 创建“添加上下文”的工具
        add_context_tool = create_mcp_tool(
            client,
            tool_name="add_knowledge",
            description="添加一段知识或信息到上下文库中。输入应为要存储的文本内容。"
        )
        tools.append(add_context_tool)
        
        # 创建“查询上下文”的工具
        query_context_tool = create_mcp_tool(
            client,
            tool_name="search_knowledge",
            description="从上下文库中搜索与问题相关的知识。输入应为你的问题。"
        )
        tools.append(query_context_tool)
        
        # 3. 初始化 LLM
        llm = ChatOpenAI(model="gpt-4o", temperature=0)
        
        # 4. 创建提示词模板
        prompt = ChatPromptTemplate.from_messages([
            ("system", "你是一个拥有外部知识库的助手。你可以使用工具来存储或查找信息。在回答用户问题时,请先尝试从知识库中搜索相关信息。"),
            ("placeholder", "{chat_history}"),
            ("human", "{input}"),
            ("placeholder", "{agent_scratchpad}"),
        ])
        
        # 5. 创建 Agent 和执行器
        agent = create_tool_calling_agent(llm=llm, tools=tools, prompt=prompt)
        agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
        
        # 6. 运行示例对话
        print("=== 示例 1:存储信息 ===")
        result1 = await agent_executor.ainvoke({
            "input": "请记住,我们公司的产品‘AI助手’的核心优势是实时翻译和代码生成。",
            "chat_history": []
        })
        print(f"结果: {result1['output']}\n")
        
        print("=== 示例 2:基于存储的信息回答问题 ===")
        result2 = await agent_executor.ainvoke({
            "input": "你们公司的‘AI助手’有什么特点?",
            "chat_history": [] # 在实际多轮对话中,这里应包含历史消息
        })
        print(f"结果: {result2['output']}")

if __name__ == "__main__":
    asyncio.run(main())

运行步骤:

  1. 在终端 A 运行 python simple_mcp_server.py,启动 MCP 服务器。
  2. 在终端 B 运行 python langchain_mcp_client.py,启动 LangChain 客户端并与之交互。

常见问题与解决方案

  1. 连接失败:确保 MCP 服务器地址和端口正确,且防火墙未阻止连接。检查 langchain-communityMCPClient 的实际参数。
  2. 协议不匹配:MCP 协议本身可能更新。确保你使用的 mcp 库和 LangChain 集成包的版本兼容。关注 LangChain 官方文档和 langchain-community 的更新。
  3. 性能瓶颈:示例中的内存存储和简单关键词检索不适合生产环境。对于生产级应用,应将 MCP 服务器中的 SimpleContextManager 替换为使用向量数据库(如 Chroma, Pinecone, Weaviate) 的检索器,并实现更智能的上下文压缩算法。
  4. 错误处理:在生产代码中,务必为 MCP 客户端的调用添加完善的错误处理(try-catch)和重试逻辑。

最佳实践建议

  • 生产级 MCP 服务器:使用成熟的框架(如 FastMCP)或云服务来部署高性能、可扩展的 MCP 服务器,而不是自建简易版本。
  • 上下文策略:在 MCP 服务器中定义清晰的上下文管理策略,例如:不同来源(对话历史、文档、网络搜索)的优先级、摘要的触发条件、过期信息的清理规则。
  • 与 LangChain 生态结合:除了创建 Tool,还可以探索将 MCP 作为 BaseRetrieverBaseMemory 的实现,使其能更无缝地融入现有的 LangChain 链(RAG)或 Agent 模式中。
  • 监控与评估:记录每次上下文检索的结果和使用的令牌数,评估 MCP 策略的有效性,并持续优化。

总结

通过本文的探索,我们看到了 LangChain 与 MCP 结合的巨大潜力。MCP 将上下文管理这一复杂任务标准化和外部化,而 LangChain 则以其强大的编排能力,轻松地将这种标准化服务集成到复杂的 AI 应用流水线中。从简单的内存服务器到基于向量数据库的智能检索,MCP 的灵活性为开发者提供了从原型到生产的不同选择。

尽管目前 LangChain 对 MCP 的原生支持仍在社区集成阶段,但其代表的方向非常明确:专业化分工和标准化接口是构建复杂、可靠 AI 应用的未来。现在就开始尝试将 MCP 接入你的下一个 LangChain 项目,为你的大语言模型应用装上高效、智能的“记忆中枢”吧。