Java 接入大模型:直接调 API、框架,还是 MCP
「LangChain4j 和 MCP 选哪个」其实是个假问题——前者是 Java 侧的开发框架,后者是工具暴露给模型的协议,它们处在不同的层。真正要选的是:对话状态、工具调用、重试和可观测这几件事,由谁来负责。
本文按这个角度梳理三条接入路径,以及 MCP 在其中的位置。事实以官方文档为准(MCP 规范 2026-07-28 修订,LangChain4j 1.x)。先判断需求的复杂度:单轮调用直接写 HTTP 客户端;需要对话、工具、检索就用 LangChain4j 或 Spring AI(按是否 Spring 项目来选);工具需要跨应用复用时再引入 MCP。选型也不必看基准跑分,接入层的性能瓶颈几乎总在模型推理本身,不在 Java 侧的框架开销。
一、三条路径
1.1 直接调用 HTTP API
主流模型服务都提供 OpenAI 兼容的 HTTP 接口,Java 侧用 HttpClient 加 Jackson 就能完成:
record ChatRequest(String model, List<Message> messages, double temperature) {}
record Message(String role, String content) {}
HttpRequest request = HttpRequest.newBuilder(URI.create(endpoint + "/v1/chat/completions"))
.header("Authorization", "Bearer " + apiKey)
.header("Content-Type", "application/json")
.timeout(Duration.ofSeconds(30))
.POST(HttpRequest.BodyPublishers.ofString(mapper.writeValueAsString(body)))
.build();适合:单轮调用、结构化输出、批处理任务。优点是依赖最少、行为完全可控、升级模型只改配置。代价是对话历史、工具调用、流式解析都要自己实现。
1.2 用框架:LangChain4j 或 Spring AI
两者都在 2025 年进入 1.x,能力大致覆盖:统一的模型抽象、对话记忆、工具(函数)调用、RAG 检索链路、向量库集成、流式响应。
| LangChain4j | Spring AI | |
|---|---|---|
| 定位 | 框架无关,可在任意 JVM 项目中使用 | 深度集成 Spring Boot 生态 |
| 配置风格 | 显式构建对象,或用 Quarkus / Spring Boot starter | 自动配置 + application.yml |
| 适合 | 非 Spring 项目、需要更细的控制 | 已经全栈 Spring、希望配置即用 |
选择依据很简单:项目已经是 Spring Boot 就先看 Spring AI,否则看 LangChain4j。两者的核心抽象高度相似,迁移成本不高。
框架的真实价值在于省掉这些重复工作:消息历史的裁剪与 token 预算、工具调用的参数校验与回填、流式响应的分块解析、多个供应商 API 的差异。
1.3 自建编排层
当业务流程复杂到框架的抽象反而碍事时(比如需要自定义的多阶段审批、与工作流引擎结合),可以只用最底层的模型客户端,自己编排。代价是所有细节都要自己维护,通常是团队在框架上踩够坑之后的选择。
二、MCP 在哪一层
MCP(Model Context Protocol)解决的是「工具怎么被复用」。 它用 JSON-RPC 定义了宿主(Host)、客户端(Client)、服务端(Server)三者的交互,服务端可以提供三类能力:
| 能力 | 说明 |
|---|---|
| Tools | 模型可以调用的函数,比如「查询订单」「发送邮件」 |
| Resources | 供模型或用户读取的上下文数据 |
| Prompts | 模板化的提示词与工作流 |
客户端侧则可以提供 Elicitation(服务端反过来向用户索要补充信息)。规范还定义了可选扩展,比如 Tasks(长任务的异步执行与轮询)、MCP Apps(在对话中内联渲染交互界面)。
2.1 它和框架的关系
同一个 MCP 服务端,可以同时被你的 Java 应用、IDE、桌面客户端使用。这就是它相对「把工具写成框架里的一个 @Tool 方法」的核心优势:工具的实现与消费方解耦。
LangChain4j 提供了 MCP 客户端模块,也提供了 stdio 方式的服务端模块;Java 生态还有官方的 MCP Java SDK。
2.2 什么时候值得用 MCP
| 场景 | 建议 |
|---|---|
| 工具只在一个应用内使用,数量少 | 直接用框架的工具注解,不必引入 MCP |
| 同一批工具要被多个应用或客户端使用 | 用 MCP,避免每个消费方各实现一遍 |
| 需要把工具做成独立进程、独立发布与授权 | 用 MCP |
| 工具由另一个团队维护 | 用 MCP,接口即契约 |
MCP 工具也不是越多越好:工具列表会占用上下文,也会增加模型选错工具的概率。
2.3 传输方式
MCP 定义了两种常见传输:stdio(本地子进程,适合桌面与 CLI 场景)和基于 HTTP 的流式传输(适合远程服务)。选择取决于工具进程和宿主是否在同一台机器上。
三、无论选哪条路,都要自己做的事
这部分是框架和协议都不会替你决定的,也是线上事故的主要来源:
- 权限边界:哪些工具只读、哪些能写、写操作要不要人工确认。模型会「自信地」调用任何你暴露的工具。
- 参数校验:把模型输出当作不可信输入。SQL 拼接、文件路径、金额参数都要校验。
- 超时与重试:模型调用的 p99 可能是几十秒,重试要考虑幂等——重复调用「创建工单」会真的创建两次。
- 成本控制:按 token 计费,要有配额、限流和降级;把输入长度和最大输出长度都设上限。
- 可观测:记录每次调用的模型、token 数、耗时、工具调用序列。出问题时没有这些记录几乎无法排查。
- 提示注入防护:工具返回的内容、检索到的文档都可能包含恶意指令,不要让它们直接驱动后续的工具调用。
这些内容在 给 Java 服务接一个可控的 Agent 里有具体做法。
参考资料