Java 接入大模型:直接调 API、框架,还是 MCP
「LangChain4j 和 MCP 选哪个」其实是个假问题——前者是 Java 侧的开发框架,后者是工具暴露给模型的协议,它们处在不同的层。真正要选的是:对话状态、工具调用、重试和可观测这几件事,由谁来负责。
本文按这个角度梳理三条接入路径,以及 MCP 在其中的位置。事实以官方文档为准(MCP 规范 2026-07-28 修订,LangChain4j 1.x)。
一、先说结论
- 三条路径:直接调用 HTTP API、用 LangChain4j 或 Spring AI 这类框架、自建编排层。差别在于「框架替你做了多少」,不在于性能。
- MCP 是工具侧的协议,不是客户端框架的替代品。 它让工具以独立进程的形式暴露给任何支持 MCP 的宿主,三条路径都能消费同一批 MCP 工具。
- 简单场景直接调 API 就够:一次问答、一次分类、一次摘要,用 HTTP 客户端加一个 DTO,比引入框架更好维护。
- 需要对话记忆、工具调用、RAG 检索链路时,框架的收益才显现:LangChain4j 与 Spring AI 都提供了这些抽象。
- 无论走哪条路,可控性都要自己做:权限、超时、审计、幂等,框架不会替你决定「这个工具能不能删数据」。
二、三条路径
2.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();适合:单轮调用、结构化输出、批处理任务。优点是依赖最少、行为完全可控、升级模型只改配置。代价是对话历史、工具调用、流式解析都要自己实现。
2.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 的差异。
2.3 自建编排层
当业务流程复杂到框架的抽象反而碍事时(比如需要自定义的多阶段审批、与工作流引擎结合),可以只用最底层的模型客户端,自己编排。代价是所有细节都要自己维护,通常是团队在框架上踩够坑之后的选择。
三、MCP 在哪一层
MCP(Model Context Protocol)解决的是「工具怎么被复用」。 它用 JSON-RPC 定义了宿主(Host)、客户端(Client)、服务端(Server)三者的交互,服务端可以提供三类能力:
| 能力 | 说明 |
|---|---|
| Tools | 模型可以调用的函数,比如「查询订单」「发送邮件」 |
| Resources | 供模型或用户读取的上下文数据 |
| Prompts | 模板化的提示词与工作流 |
客户端侧则可以提供 Elicitation(服务端反过来向用户索要补充信息)。规范还定义了可选扩展,比如 Tasks(长任务的异步执行与轮询)、MCP Apps(在对话中内联渲染交互界面)。
3.1 它和框架的关系
同一个 MCP 服务端,可以同时被你的 Java 应用、IDE、桌面客户端使用。这就是它相对「把工具写成框架里的一个 @Tool 方法」的核心优势:工具的实现与消费方解耦。
LangChain4j 提供了 MCP 客户端模块,也提供了 stdio 方式的服务端模块;Java 生态还有官方的 MCP Java SDK。
3.2 什么时候值得用 MCP
| 场景 | 建议 |
|---|---|
| 工具只在一个应用内使用,数量少 | 直接用框架的工具注解,不必引入 MCP |
| 同一批工具要被多个应用或客户端使用 | 用 MCP,避免每个消费方各实现一遍 |
| 需要把工具做成独立进程、独立发布与授权 | 用 MCP |
| 工具由另一个团队维护 | 用 MCP,接口即契约 |
3.3 传输方式
MCP 定义了两种常见传输:stdio(本地子进程,适合桌面与 CLI 场景)和基于 HTTP 的流式传输(适合远程服务)。选择取决于工具进程和宿主是否在同一台机器上。
四、无论选哪条路,都要自己做的事
这部分是框架和协议都不会替你决定的,也是线上事故的主要来源:
- 权限边界:哪些工具只读、哪些能写、写操作要不要人工确认。模型会「自信地」调用任何你暴露的工具。
- 参数校验:把模型输出当作不可信输入。SQL 拼接、文件路径、金额参数都要校验。
- 超时与重试:模型调用的 p99 可能是几十秒,重试要考虑幂等——重复调用「创建工单」会真的创建两次。
- 成本控制:按 token 计费,要有配额、限流和降级;把输入长度和最大输出长度都设上限。
- 可观测:记录每次调用的模型、token 数、耗时、工具调用序列。出问题时没有这些记录几乎无法排查。
- 提示注入防护:工具返回的内容、检索到的文档都可能包含恶意指令,不要让它们直接驱动后续的工具调用。
这些内容在 给 Java 服务接一个可控的 Agent 里有具体做法。
五、常见误区
- 「LangChain4j 和 MCP 二选一」:一个是客户端框架,一个是工具协议,可以同时用。
- 「用了框架就不用管重试和超时」:框架提供了钩子,策略仍然要自己定。
- 「MCP 工具越多越好」:工具列表会占用上下文,也会增加模型选错工具的概率。
- 「模型输出是可信的」:它是不可信输入,尤其在会触发副作用的场景。
- 「选型要看基准跑分」:接入层的性能瓶颈几乎总在模型推理本身,不在 Java 侧的框架开销。
小结
先判断需求的复杂度:单轮调用直接写 HTTP 客户端;需要对话、工具、检索就用 LangChain4j 或 Spring AI(按是否 Spring 项目来选);工具需要跨应用复用时再引入 MCP。选型之外,把权限、校验、超时、成本、审计这五件事做实,比选哪个框架重要得多。
参考资料