LangChain4j 中的 Model Context Protocol (MCP):实现 AI 模型与工具的高效集成

Model Context Protocol (MCP) | LangChain4j

LangChain4j 支持使用模型上下文协议 (MCP) 与 MCP 兼容服务器进行通信,这些服务器能够提供和执行工具。关于该协议的通用信息可以在 MCP 网站上找到。

协议规定了两种类型的传输方式,均得到支持:

  • HTTP:客户端请求一个服务器发送事件的 SSE 通道,然后通过 HTTP POST 请求发送命令。
  • stdio:客户端可以将 MCP 服务器作为本地子进程运行,并通过标准输入/输出直接与其通信。

要让你的聊天模型或 AI 服务运行 MCP 服务器提供的工具,需要创建一个 MCP 工具提供程序的实例。

MCP 传输

首先,需要一个 MCP 传输实例。

对于 stdio - 此示例展示如何将服务器作为子进程启动:

McpTransport transport = new StdioMcpTransport.Builder()
    .command(List.of("/usr/bin/npm", "exec", "@modelcontextprotocol/server-everything@0.6.2"))
    .logEvents(true) // 仅在希望在日志中看到流量时
    .build();

对于 HTTP,需要两个 URL,一个用于启动 SSE 通道,另一个用于通过 POST 提交命令:

McpTransport transport = new HttpMcpTransport.Builder()
    .sseUrl("http://localhost:3001/sse")
    .logRequests(true) // 如果希望在日志中看到流量
    .logResponses(true)
    .build();

MCP 客户端

从传输创建 MCP 客户端:

McpClient mcpClient = new DefaultMcpClient.Builder()
    .transport(transport)
    .build();

MCP 工具提供程序

最后,从客户端创建 MCP 工具提供程序:

ToolProvider toolProvider = McpToolProvider.builder()
    .mcpClients(List.of(mcpClient))
    .build();

注意,一个 MCP 工具提供程序可以同时使用多个客户端。如果利用这一点,还可以指定当从特定服务器检索工具失败时工具提供程序的行为 - 通过 builder.failIfOneServerFails(boolean) 方法实现。默认值为 false,意味着工具提供程序将忽略一个服务器的错误并继续使用其他服务器。如果设置为 true,任何服务器的失败都将导致工具提供程序抛出异常。

要将工具提供程序绑定到 AI 服务,只需在 AI 服务构建器中使用 toolProvider 方法:

Bot bot = AiServices.builder(Bot.class)
    .chatLanguageModel(model)
    .toolProvider(toolProvider)
    .build();

有关 LangChain4j 中工具支持的更多信息,请参见此处。

日志记录

MCP 协议还定义了服务器向客户端发送日志消息的方式。默认情况下,客户端的行为是将这些日志消息转换并使用 SLF4J 日志记录器进行记录。如果希望更改此行为,有一个名为 dev.langchain4j.mcp.client.logging.McpLogMessageHandler 的接口,作为接收日志消息的回调。如果创建自己的 McpLogMessageHandler 实现,将其传递给 MCP 客户端构建器:

McpClient mcpClient = new DefaultMcpClient.Builder()
    .transport(transport)
    .logMessageHandler(new MyLogMessageHandler())
    .build();

资源

要获取服务器上的 MCP 资源列表,使用 client.listResources(),如果是资源模板,则使用 client.listResourceTemplates()。这将返回 ResourceRef 对象列表(或 ResourceTemplateRef 对应列表)。这些对象包含资源的元数据,最重要的是 URI。

要获取资源的实际内容,使用 client.readResource(uri),提供资源的 URI。这将返回 ResourceContents 对象列表(单个 URI 上可能有更多资源内容,例如 URI 表示目录时)。每个 ResourceContents 对象表示二进制块或字符串。对于二进制块,使用 resourceContents.asBlob() 访问实际数据,对于文本,使用 resourceContents.asText()

通过 Docker 使用 GitHub MCP 服务器

现在,让我们看看如何使用模型上下文协议 (MCP) 以标准化方式将 AI 模型与外部工具桥接。以下示例将通过 LangChain4j MCP 客户端与 GitHub 交互,以获取并总结公共 GitHub 存储库的最新提交。为此,无需重新发明轮子,我们可以使用 MCP GitHub 仓库中提供的现有 GitHub MCP 服务器实现。

这个想法是构建一个 Java 应用程序,通过 Docker 连接到本地运行的 GitHub MCP 服务器,以获取并总结最新提交。该示例使用 MCP 的 stdio 传输机制在 Java 应用程序和 GitHub MCP 服务器之间进行通信。

在 Docker 中打包和执行 GitHub MCP 服务器

要与 GitHub 交互,首先需要通过 Docker 设置 GitHub MCP 服务器。GitHub MCP 服务器通过模型上下文协议提供与 GitHub 交互的标准化接口,支持文件操作、存储库管理和搜索功能。

要为 GitHub MCP 服务器构建 Docker 镜像,需要从 MCP 服务器的 GitHub 仓库获取代码,通过克隆仓库或下载代码实现。然后,导航到根目录并执行以下 Docker 命令:

docker build -t mcp/github -f src/github/Dockerfile .

Dockerfile 设置了必要的环境并安装了 GitHub MCP 服务器实现。构建完成后,镜像将作为 mcp/github 本地可用。

docker image ls

REPOSITORY   TAG         IMAGE ID        SIZE
mcp/github   latest      b141704170b1    173MB

让我们创建一个名为 McpGithubToolsExample 的 Java 类,使用 LangChain4j 连接到 GitHub MCP 服务器。这个类将:

  • 使用 Docker 命令在 Docker 容器中启动 GitHub MCP 服务器(docker 命令在 /usr/local/bin/docker 中可用)
  • 使用 stdio 传输建立连接
  • 使用 LLM 总结 LangChain4j GitHub 存储库的最后 3 次提交

注意:在下面的代码中,我们通过环境变量 GITHUB_PERSONAL_ACCESS_TOKEN 传递 GitHub 令牌。但对于某些不需要身份验证的公共存储库操作,这是可选的。

以下是实现:

public static void main(String[] args) throws Exception {

    ChatLanguageModel model = OpenAiChatModel.builder()
        .apiKey(System.getenv("OPENAI_API_KEY"))
        .modelName("gpt-4o-mini")
        .logRequests(true)
        .logResponses(true)
        .build();

    McpTransport transport = new StdioMcpTransport.Builder()
        .command(List.of("/usr/local/bin/docker", "run", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "-i", "mcp/github"))
        .logEvents(true)
        .build();

    McpClient mcpClient = new DefaultMcpClient.Builder()
        .transport(transport)
        .build();

    ToolProvider toolProvider = McpToolProvider.builder()
        .mcpClients(List.of(mcpClient))
        .build();

    Bot bot = AiServices.builder(Bot.class)
        .chatLanguageModel(model)
        .toolProvider(toolProvider)
        .build();

    try {
        String response = bot.chat("Summarize the last 3 commits of the LangChain4j GitHub repository");
        System.out.println("RESPONSE: " + response);
    } finally {
        mcpClient.close();
    }
}

注意:此示例使用 Docker,因此执行 /usr/local/bin/docker 中可用的 Docker 命令(根据操作系统更改路径)。如果希望使用 Podman 而不是 Docker,请相应更改命令。

执行代码

要运行示例,请确保系统上正在运行 Docker。同时,在环境变量 OPENAI_API_KEY 中设置 OpenAI API 密钥。

然后运行 Java 应用程序。您应该会收到总结 LangChain4j GitHub 存储库最后 3 次提交的响应,例如:

以下是 LangChain4j GitHub 存储库中最后三次提交的摘要:

1. **提交 [36951f9](https://github.com/langchain4j/langchain4j/commit/36951f9649c1beacd8b9fc2d910a2e23223e0d93)**(日期:2025 年 2 月 5 日)
   - **作者:** Dmytro Liubarskyi
   - **消息:** 更新至 `upload-pages-artifact@v3`。
   - **详情:** 此次提交将用于上传页面工件的 GitHub Action 更新至版本 3。

2. **提交 [6fcd19f](https://github.com/langchain4j/langchain4j/commit/6fcd19f50c8393729a0878d6125b0bb1967ac055)**(日期:2025 年 2 月 5 日)
   - **作者:** Dmytro Liubarskyi
   - **消息:** 更新至 `checkout@v4`、`deploy-pages@v4` 和 `upload-pages-artifact@v4`。
   - **详情:** 此次提交将多个 GitHub Actions 更新至版本 4。

3. **提交 [2e74049](https://github.com/langchain4j/langchain4j/commit/2e740495d2aa0f16ef1c05cfcc76f91aef6f6599)**(日期:2025 年 2 月 5 日)
   - **作者:** Dmytro Liubarskyi
   - **消息:** 更新至 `setup-node@v4` 和 `configure-pages@v4`。
   - **详情:** 此次提交将 `setup-node` 和 `configure-pages` GitHub Actions 更新至版本 4。

所有提交均由同一位作者 Dmytro Liubarskyi 在同一天完成,重点是将各种 GitHub Actions 更新至新版本。

相关示例

### Model Context Protocol (MCP) 和 API 的定义 #### Model Context Protocol (MCP) Model Context Protocol 是一种用于描述模型上下文交互的协议,旨在通过标准化的方式传递数据及其语义背景。它通常涉及复杂的结构化数据交换,并支持动态调整通信中的元数据和实际数据[^1]。 MCP 不仅关注数据本身,还强调数据的上下文环境以及如何解释这些数据。 #### Application Programming Interface (API) Application Programming Interface 则是一个更广泛的术语,指一组规则和工具,允许不同的软件应用程序之间相互通信。API 定义了请求和服务端响应的标准格式,使得开发者可以轻松集成不同服务的功能而不必理解其内部实现细节[^2]。 --- ### 主要区别 | 方面 | **Model Context Protocol (MCP)** | **API** | |---------------------|--------------------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------| | **核心目标** | 提供一种机制来传输带有上下文的数据,确保接收方能够正确理解和处理发送过来的信息. | 提供接口让外部程序访问特定功能或数据集,简化应用间互动过程[^2]. | | **复杂度** | 更加注重于数据的意义其关联关系,在某些情况下可能涉及到较为复杂的配置文件或者额外的消息头字段说明等内容. | 相对比之下更为简单明了;只需要遵循既定的方法签名即可完成调用操作[^2]. | | **适用场景** | 常见于机器学习框架、人工智能平台等领域当中,当需要精确表达训练样本特征向量所处的具体情境时尤为有用. | 几乎适用于任何类型的软硬件产品开发过程中——无论是移动客户端还是云端服务器都可以利用 RESTful APIs 来互相协作工作[^2]. | 值得注意的是,虽然两者都属于技术层面的概念范畴之内,但是它们各自侧重点完全不同:前者偏向理论研究方向探索未知可能性边界;后者则更多体现在工程实践上面解决现实世界里的具体需求问题上。 ```python # 示例代码展示了一个简单的 API 调用方式 import requests response = requests.get('https://api.example.com/data') data = response.json() print(data) # 对应到 MCP 中,则可能是如下形式(假设基于 JSON-RPC 实现mcp_request = { "jsonrpc": "2.0", "method": "getContextData", "params": {"context_id": 123}, "id": 1 } result = requests.post('https://mcp.example.com/', json=mcp_request).json() print(result['result']) ``` ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰山AI

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值