ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

LangChain4j + MCP:让你的 AI 轻松调用外部工具(内附GitHub-MCP实战)

LangChain4j + MCP:让你的 AI 轻松调用外部工具(内附GitHub-MCP实战) 1. 为什么 Java 开发者需要 LangChain4j 接入 MCP 调用 GitHub 工具如果你用 Java 写 AI 应用大概率遇到过这个尴尬模型能聊天但一让它「查一下某个仓库最近的提交」就歇菜。原因很简单大模型本身只有训练时冻结的知识它没法主动去访问 GitHub 的实时数据。过去我们只能自己写一堆 HTTP 客户端、拼 REST 请求、解析 JSON再手动塞回提示词里代码又臭又长。MCPModel Context Protocol模型上下文协议就是来解决这个问题的。你可以把它理解成「AI 世界的 USB-C 接口」只要外部工具按 MCP 标准暴露自己的能力任何支持 MCP 的客户端都能即插即用。LangChain4j 作为 Java 生态里最成熟的 LLM 应用框架已经原生支持 MCP支持 stdio 和 HTTP(SSE) 两种通信方式。这意味着你不需要为每个工具单独写适配层注册一个 MCP 工具提供者模型就能自动发现并调用 GitHub 的查询、建 issue、读文件等能力。这篇文章面向的是有 Java 基础、想把 AI 应用真正落地到工程里的开发者。我会带你走完一条完整链路用 Docker 跑起 GitHub MCP Server在 LangChain4j 里注册工具配好 GitHub Token最后发一次真实请求让模型总结 LangChain4j 仓库最近三次提交。全程可复制踩过的坑我也会标出来。核心检索词先明确LangChain4j MCP 接入 GitHub 工具链本质是「Java AI 应用通过 MCP 协议调用外部工具」的落地实践。适合谁适合正在做智能客服、代码助手、DevOps 自动化又不想被 Python 绑死的 Java 团队。在动手前你需要准备三样东西JDK 17、Maven 或 Gradle、Docker。模型侧可以本地跑 Ollama也可以走云端 API。我下面会用一个兼容 OpenAI 协议的网关来演示这样你换模型时只改 Base URL 和 Model ID代码不用动。2. TaoToken 前置准备拿到 Base URL、API Key 和 Model IDLangChain4j 本身不绑定任何模型厂商它通过ChatLanguageModel接口对接。实际项目里我建议用一个统一的网关来管理模型调用好处是切换模型、做额度控制、看调用日志都方便。这里我用 TaoToken 作为示例网关它的接口兼容 OpenAI 协议LangChain4j 的OpenAiChatModel可以直接对接。你需要准备三件套缺一不可第一Base URL。TaoToken 的 API 地址是https://taotoken.net/api注意这里不要加任何多余路径LangChain4j 会自动拼接/v1/chat/completions。如果你用的是其他兼容网关逻辑一样把域名换成对应的即可。第二API Key。登录后在控制台的 API Keys 页面创建格式通常是sk-开头的一串字符。这个 Key 只显示一次创建后立刻复制保存。我试过忘记保存然后重新建白白浪费一个额度。第三Model ID。这个取决于你想用哪个模型。比如你要用支持工具调用的模型就填对应的模型名像gpt-4o-mini、claude-3-5-sonnet这类。注意MCP 工具调用要求模型本身支持 function calling / tool use不是所有模型都行。如果你选的模型不支持工具调用后面会看到模型「假装」调用了工具但实际没执行这是最常见的坑之一。把这三个值放进环境变量别硬编码在代码里export TAOTOKEN_BASE_URLhttps://taotoken.net/api export TAOTOKEN_API_KEYsk-你的key export GITHUB_PERSONAL_ACCESS_TOKENgithub_pat_你的tokenGitHub Token 的获取路径是https://github.com/settings/personal-access-tokens/new创建一个 fine-grained token权限至少给public_repo的读权限。如果你只查公开仓库其实不传 Token 也能跑但 GitHub 有速率限制传了更稳。这里有个细节LangChain4j 的OpenAiChatModel默认会去请求{baseUrl}/v1/chat/completions。如果你填的 Base URL 末尾带了/v1就会变成/v1/v1/...导致 404。所以记住Base URL 只填到域名加/api这一层。另外如果你打算长期跑编码类 Agent可以了解下 Coding Plan它针对高频代码场景做了额度优化只是临时验证模型能力用模型对话页面手动测几次就够了。这两个入口在 TaoToken 官网都能找到按需选。3. 可复制配置Docker 启动 GitHub MCP Server 与 LangChain4j 工具注册这一节是全文的核心我给你两段可直接复制的配置一段是 Docker 启动命令一段是 LangChain4j 的 Java 代码。先说 Docker。GitHub 官方提供了 MCP Server 的镜像你可以直接拉取也可以自己构建。自己构建的好处是版本可控git clone https://github.com/github/github-mcp-server.git cd github-mcp-server docker build -t mcp/github -f Dockerfile .构建完成后确认镜像存在docker image ls | grep mcp/github预期输出类似mcp/github latest b141704170b1 173MB然后启动容器。注意MCP 的 stdio 模式要求容器以交互方式运行所以-i参数不能少docker run --rm -d \ --name mcp-github-server \ -e GITHUB_PERSONAL_ACCESS_TOKEN$GITHUB_PERSONAL_ACCESS_TOKEN \ mcp/github如果你用 stdio 模式让 LangChain4j 直接拉起容器其实不需要提前docker run客户端会用docker run -i自己启动子进程。两种方式选一种即可我下面代码里用的是后者更省事。接下来是 Java 侧。先加依赖Maven 的pom.xmldependency groupIddev.langchain4j/groupId artifactIdlangchain4j/artifactId version0.36.2/version /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-mcp/artifactId version0.36.2/version /dependency dependency groupIddev.langchain4j/groupId artifactIdlangchain4j-open-ai/artifactId version0.36.2/version /dependency然后是完整的工具注册代码。这段代码做了四件事建模型、建 MCP 传输、建 MCP 客户端、把工具提供者绑到 AI 服务上。import dev.langchain4j.mcp.McpToolProvider; import dev.langchain4j.mcp.client.DefaultMcpClient; import dev.langchain4j.mcp.client.McpClient; import dev.langchain4j.mcp.client.transport.McpTransport; import dev.langchain4j.mcp.client.transport.stdio.StdioMcpTransport; import dev.langchain4j.model.openai.OpenAiChatModel; import dev.langchain4j.service.AiServices; import dev.langchain4j.service.tool.ToolProvider; import java.util.List; public class GithubMcpDemo { interface Bot { String chat(String message); } public static void main(String[] args) throws Exception { var model OpenAiChatModel.builder() .baseUrl(System.getenv(TAOTOKEN_BASE_URL)) .apiKey(System.getenv(TAOTOKEN_API_KEY)) .modelName(gpt-4o-mini) .logRequests(true) .logResponses(true) .build(); McpTransport transport new StdioMcpTransport.Builder() .command(List.of( docker, run, -i, --rm, -e, GITHUB_PERSONAL_ACCESS_TOKEN, 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) .chatModel(model) .toolProvider(toolProvider) .build(); try { String response bot.chat( Summarize the last 3 commits of the langchain4j/langchain4j GitHub repository); System.out.println(RESPONSE: response); } finally { mcpClient.close(); } } }几个关键点解释一下。StdioMcpTransport的command里-e GITHUB_PERSONAL_ACCESS_TOKEN这种写法是把宿主机的环境变量透传进容器不需要写值Docker 会自动读取当前 shell 的同名变量。logEvents(true)会打印 MCP 协议层的交互日志调试时非常有用生产环境可以关掉。McpToolProvider.builder().failIfOneServerFails(false)是默认行为意思是某个 MCP Server 挂了不影响其他 Server。如果你只有一个 Server 且希望它挂了就报错可以设成true。AiServices把toolProvider绑进去后模型在对话时就能看到 GitHub MCP Server 暴露的所有工具比如get_commit、list_commits、search_repositories等。模型会根据你的自然语言指令自己决定调哪个工具、传什么参数。4. 验证请求一次完整的工具调用链路与预期返回代码写完了跑起来看结果。执行main方法你会先看到一堆 MCP 协议日志然后是模型请求日志最后是响应。先看 MCP 初始化阶段的日志正常长这样MCP transport: starting process: docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN mcp/github MCP client: initialized, server info: namegithub-mcp-server, version0.1.0 MCP client: tools listed: [get_commit, list_commits, search_repositories, ...]看到tools listed就说明工具注册成功了。如果这一步卡住或者报错多半是 Docker 没启动、镜像名写错、或者 Token 环境变量没传进去。然后是模型请求日志你会看到 LangChain4j 把工具定义一起发给了模型Request: { model: gpt-4o-mini, messages: [{role: user, content: Summarize the last 3 commits...}], tools: [{type: function, function: {name: list_commits, ...}}] }模型返回的第一次响应通常是一个tool_calls表示它决定调用list_commitsResponse: { choices: [{ message: { tool_calls: [{ function: { name: list_commits, arguments: {\owner\:\langchain4j\,\repo\:\langchain4j\,\per_page\:3} } }] } }] }LangChain4j 收到这个后会通过 MCP 客户端把调用转发给 GitHub MCP ServerServer 去请求 GitHub API拿到结果再回传。最后模型基于工具返回的真实数据生成总结。预期输出类似RESPONSE: 以下是 langchain4j/langchain4j 仓库最近三次提交的摘要 1. 提交 36951f92025-02-05作者 Dmytro Liubarskyi更新 upload-pages-artifact 至 v3。 2. 提交 6fcd19f2025-02-05作者 Dmytro Liubarskyi升级 checkout、deploy-pages 等 Action 至 v4。 3. 提交 2e740492025-02-05作者 Dmytro Liubarskyi更新 setup-node 和 configure-pages 至 v4。 这三次提交均由同一作者完成主要内容是 GitHub Actions 版本升级。看到这个结果说明整条链路通了自然语言 → 模型决策 → MCP 工具调用 → GitHub API → 结果回传 → 模型总结。这就是 MCP 的价值你只写了几十行 Java就获得了一个能实时访问 GitHub 的 AI 助手。如果你想验证其他工具比如让模型「列出 langchain4j 仓库最近的 open issues」模型会自动换成list_issues工具参数也会相应变化。你可以多试几个指令观察日志里工具名的变化。5. 本篇常见错误排查401、local proxy failed、reading choices、OAuth这一节我按真实报错来整理都是我在接入过程中实际撞过的。错误一401 Unauthorizeddev.langchain4j.exception.AuthenticationException: 401 Unauthorized原因通常是 API Key 没传对。检查TAOTOKEN_API_KEY环境变量是否真的被 Java 进程读到了。有个隐蔽的坑如果你在 IDE 里配了环境变量但用的是「Run」而不是「Debug」某些 IDE 不会加载。最稳的办法是在代码里临时打印一下System.getenv(TAOTOKEN_API_KEY)的前几位确认。另一个可能是 Base URL 写错了。如果你填了https://taotoken.net/api/v1就会请求到/api/v1/v1/chat/completions返回 404 而不是 401但有些人会混淆。记住 Base URL 只到/api。错误二local proxy failed / Connection refusedjava.net.ConnectException: Connection refused MCP transport: process exited with code 1这个多半是 Docker 没跑起来或者docker命令不在 PATH 里。先在终端手动执行一遍docker run -i --rm -e GITHUB_PERSONAL_ACCESS_TOKEN mcp/github看能不能正常启动。如果报Cannot connect to the Docker daemon说明 Docker Desktop 没开。还有一种情况是 stdio 模式下command列表里第一个参数写的是/usr/local/bin/docker但你的 Docker 装在别的位置。用which docker确认实际路径或者直接写docker让它走 PATH。错误三reading choices 相关空指针java.lang.NullPointerException: Cannot invoke java.util.List.get(int) because choices is null这个报错说明模型返回的 JSON 里没有choices字段。常见原因是模型不支持工具调用网关返回了一个错误结构但 LangChain4j 按正常结构解析就炸了。解决办法是换一个明确支持 function calling 的模型。另外有些网关在额度不足时也会返回非标准结构检查一下账户余额。错误四OAuth / Token 权限不足MCP tool call failed: 403 Forbidden Resource not accessible by personal access tokenGitHub Token 权限不够。fine-grained token 需要显式勾选仓库读取权限。如果你要访问私有仓库还得把对应仓库加进 token 的授权列表。经典 tokenclassic则要勾repo或public_repo。改完权限后Token 不用重新生成但容器要重启才能读到新权限。错误五工具调用死循环有时候模型会反复调用同一个工具日志里看到tool_calls出现好几次。这通常是模型能力问题或者你的指令太模糊。解决办法是在AiServices里设置最大工具调用轮数或者换一个工具调用能力更强的模型。LangChain4j 默认会限制轮数但不同版本行为有差异建议显式配置。排查时记住一个原则先看 MCP 日志确认工具注册成功再看模型请求日志确认工具定义发出去了最后看响应日志确认模型有没有返回tool_calls。三段日志一对照问题基本定位。6. 语义一致 CTA把这条链路用到你的项目里走到这里你已经有了一个能跑通的 LangChain4j MCP GitHub 的最小闭环。接下来怎么用到实际项目我给你三个方向。第一把它嵌进你的 CI/CD 流程。比如每次发版前让 AI 自动总结本次提交、生成 changelog、甚至检查有没有遗漏的 issue 关联。你只需要把上面的Bot接口暴露成一个 HTTP 端点用 Spring Boot 包一层就行。第二扩展更多 MCP Server。GitHub 只是其中一个MCP 生态里还有文件系统、数据库、Slack、Notion 等 Server。LangChain4j 的McpToolProvider支持同时挂多个客户端你可以让一个 AI 助手同时操作 GitHub 和本地文件。第三做代码审查助手。把 GitHub MCP 的get_pull_request、list_pull_request_files工具接进来让模型自动读 PR diff 并给出审查意见。这个场景对 Java 团队特别实用。如果你在接入过程中卡在 Key 或模型配置上可以直接去 API Keys 页面重新生成一个配合接入文档对照检查。想先手动验证模型是否支持工具调用用模型对话页面发一句「调用 list_commits 查一下 langchain4j 仓库」就能看出来。长期跑编码类 Agent 的话Coding Plan 在额度上更划算。最后留一个实用技巧把logRequests和logResponses在开发阶段打开生产环境关掉避免日志里泄露 Token 和业务数据。MCP 客户端的close()一定要放在finally里否则 Docker 子进程会残留跑几次就把内存吃满了。
返回列表