[控场AI]
· 9 分钟阅读· 4,686 字

Spring AI + MCP 实战:用 Java 构建生产级 AI Agent

Spring AI + MCP 实战:用 Java 构建生产级 AI Agent

用 Spring AI + MCP 协议在 Java 生态中搭建可连接真实企业数据的生产级 AI Agent。

本文系统梳理了如何在 Java 生态中借助 Spring AI 与 MCP(模型上下文协议)构建具备生产级架构的 AI Agent。文章首先厘清 AI Agent 与 LLM 的本质区别——前者能基于 LLM 的推理结果自主执行动作,而非仅生成文本;随后介绍 MCP 作为标准化中介协议的角色,使 AI 应用能以统一方式发现并调用数据库、REST API、Kafka 等外部系统。在代码层面,文章拆解了 Controller/Service/Tool 的分层设计,重点说明 ChatClient 与 ToolContext 的配合方式。最后,文章覆盖了部署安全的核心要点:分环境配置、密钥不入 yaml、Docker 化、以及 MCP Server 遵循最小权限原则以防止数据越权访问。整套方案的运行基础是 Java 21 + Maven 3.9 + 有效的 OpenAI Key。

在 Java 生态里构建能"自主干活"的 AI Agent,正在成为后端与全栈开发者绕不开的能力。本文基于一期 YouTube 技术教程,梳理如何用 Spring AI + MCP(Model Context Protocol,模型上下文协议) 搭建一个具备生产级架构的 AI Agent,涵盖核心概念、架构设计、关键代码与部署安全要点。

AI Agent 到底是什么

很多人把 AI Agent 和 LLM(大语言模型)混为一谈,但两者的职责完全不同。LLM 的工作是生成答案,而 AI Agent 则是用 LLM 来决策并执行动作——它能理解目标、判断需要采取哪些行动、观察结果,并持续工作直到目标完成。

换句话说,Agent 更像是一个"数字同事"。你把任务交给它,它会自主推进。举个教程里反复提到的例子:当你问"订单 12345 为什么失败了",普通聊天机器人只能基于 LLM 已有的知识回答,而 LLM 并不知道你内部系统里这笔订单的真实状态,所以它要么答非所问,要么从互联网上抓一个不相干的结果。

订单查询场景:若订单信息仅存在于互联网,Agent 无法给出准确答案

要让 Agent 给出准确回答,就必须让它能连接到外部系统——数据库、日志、业务 API——把真实数据取回来再做分析。这正是 MCP 发挥作用的地方。

MCP 与传统 REST API 的区别

教程给出了一个很直观的对比:REST API 解决的是应用与应用之间的通信,而 MCP 是一套标准化协议,专门让 AI 应用去发现并使用工具(tool)和上下文(context),再通过这些工具去连接外部的数据库或 API。

MCP 的架构里有几个关键角色:

  • MCP Client:发起请求的一端
  • Tool / Resource / Template:Agent 可调用的能力单元
  • MCP Server(中介服务器):核心枢纽,负责把 LLM 的决策翻译成对外部系统的实际调用

AI 模型本身不会直接和数据库、日志或 API 对话,中间必须有一个"中介服务器",也就是 MCP Server。

LLM 生成决策后,由 MCP 负责向外部系统发起调用

完整链路是这样的:用户提出"订单 12345 为什么失败"→ LLM 发现自己回答不了 → 转交给 MCP 协议 → MCP Server 连接数据库查订单、翻日志、调用 API 端点 → 汇总结果 → 返回一个有理有据的失败原因。整个过程对用户是透明的,但背后是 Spring AI 与 MCP 的协同。

MCP(Model Context Protocol)由 Anthropic 于 2024 年底提出并开源,目标是为 AI 应用提供一套统一的"工具调用"规范,类似于 USB 接口之于硬件外设——无论底层是数据库、文件系统还是第三方 API,AI 模型都通过同一套协议去"插拔"这些能力。在 MCP 出现之前,每个 AI 应用都需要自行实现与外部系统的集成逻辑,格式、鉴权、错误处理各自为政,难以复用。MCP 将这些能力抽象为三类标准对象:Tool(可执行的函数/动作)、Resource(可读取的数据源)和 Prompt Template(预定义的提示词模板),并规定了 Client 与 Server 之间基于 JSON-RPC 的通信格式。这样,同一个 MCP Server 可以被不同的 AI 应用复用,而同一个 AI 应用也可以同时挂载多个 MCP Server 来扩展能力边界。Spring AI 从 1.0 版本起内置了 MCP Client 支持,开发者只需引入对应依赖并配置端点,即可让 Spring Boot 应用直接与任意符合规范的 MCP Server 通信。

生产级架构设计

从单机 Demo 走向生产,架构会更完整。教程描述的典型拓扑如下:

用户 → Spring Boot AI Agent → Spring AI + LLM → MCP Server → MCP Tool → 外部系统

其中 MCP Tool(本质是加了注解的 Java 方法)可以根据配置连接到不同目标:

  • 连接数据库,执行查询
  • 调用外部 REST API(可带安全特性)
  • 对接 Kafka Server,分析流式数据并生成报告

具体连接哪几个系统,完全取决于你给 MCP 的配置。这种"配置驱动"的设计让 Agent 的能力边界可以灵活扩展。

关键代码解析

Controller 层

教程中的 AgentController 用 @RequestMapping 定义了 AI Agent 的入口,produces = application/json,并通过 @PostMapping("/chat") 接收 AgentRequest 请求体。请求体里携带两样关键信息:conversation ID 和要连接的服务详情。

Service 层

AgentService 内部注入了 ChatClient 和 Clock(UTC 时钟)。处理逻辑大致是:

  1. 从请求中取 conversationId,若为空则随机生成 UUID
  2. 构造一个 Map 作为 ToolContext,放入 conversationId 和 request context
  3. 调用 chatClient.prompt(userMessage).toolContext(...) 发起请求
  4. 返回包含 conversationId、answer 和创建时间的响应

这里用 Map 承载上下文很关键:context 里可以包含 API 的 URL、用户 ID、密码、Header 等全部信息,Tool 据此连接具体的外部 API 并分析数据。

Agent 汇总外部系统数据后,返回带 conversationId 的结构化响应

配置与 Tool

配置部分通过 ToolCallbackProvider 注册工具、设置系统提示词(system prompt),并通过 McpClientCustomizer 设定请求超时——比如 30 秒内拿不到响应,MCP Server 会自动断开连接。

教程还演示了一个 RuntimeTool 示例:返回 UTC 当前服务器时间、可用处理器数、内存字节数等运行时健康信息。顺着这个思路,你可以为数据库查询、API 健康检查等场景分别写专用 Tool。

通过 AI Agent 监控服务器与系统健康状态

ChatClient 是 Spring AI 对各家 LLM 提供商(OpenAI、Anthropic、Azure OpenAI 等)的统一抽象层,类似于 Spring Data 对数据库的屏蔽作用。开发者通过 ChatClient.Builder 构造实例,并在调用链上依次挂载系统提示词、工具回调(ToolCallbackProvider)和上下文(ToolContext),最终以流式或阻塞方式拿到 LLM 的回复。ToolContext 是一个在本次请求生命周期内共享的键值容器,Tool 方法可通过方法参数直接注入它,从而读取 URL、Token 等运行时动态参数,而无需把这些敏感信息硬编码到配置文件里。这种设计使得同一套 Tool 代码可以在多租户场景下服务不同用户的不同后端系统,只需在请求体里切换上下文内容即可,大幅提升了代码复用性与安全性。

部署与安全要点

走到生产环境,有几件事必须做好:

配置分环境:application.yml 中区分 local 与 production 的 MCP 端点 URL;本地用 local.yaml,生产用对应 profile。

模型与密钥:教程使用 OpenAI 模型(GPT-4.1 mini),temperature 设为 0.2 以保证回答稳定。API Key 绝不能写进 application.yaml,应放在密钥管理服务中。

Docker 化:编写 Dockerfile 打包 fat jar,可定义内存百分比;pom.xml 需引入 starter-web、starter-model-openai、starter-mcp-client-webflux 等依赖,并配合 Actuator 做健康监控(可导出到 Prometheus)。

最小权限原则:把 MCP Server 限制到最小的文件系统、网络和账户权限;连接前务必审查工具行为;对端口和可访问的 API 做严格限制。

这最后一点尤为重要——如果你做的是一个通用 Agent,MCP 可能会被诱导去查询其他用户的敏感数据。因此在实现时必须加入访问控制与权限边界。

"Prompt Injection"(提示词注入)是 AI Agent 生产部署中最值得警惕的安全威胁之一。攻击者可以在用户输入或外部数据源(如数据库字段、API 响应)中嵌入恶意指令,诱导 LLM 绕过预设的系统提示词,执行越权操作——例如查询其他用户的订单、调用不应暴露的内部端点。在 MCP 架构下,这一风险被放大:因为 Tool 拥有真实的系统访问权限,一旦 LLM 被"说服"调用错误的 Tool 或传入错误的参数,后果可能远比聊天机器人给出错误答案严重得多。缓解措施包括:在 Tool 内部做参数合法性校验(而非只依赖 LLM 的判断)、对每个 Tool 的可访问资源做范围限定、在 MCP Server 层面记录完整的调用审计日志,以及对敏感操作引入人工确认环节(Human-in-the-loop)。这与文中提到的"最小权限原则"是同一逻辑的延伸。

运行所需环境

按照教程,跑通这套 Spring AI + MCP Agent 的基础要求是:

  • Java 21
  • Maven 3.9
  • 一个有效的 OpenAI Key

启动后通过 REST 的 POST /ai-agent/chat 接口调用,请求体传入 message 和要使用的工具上下文即可。

小结

Spring AI + MCP 的组合,核心价值在于把 LLM 的推理能力和企业内部真实数据打通。LLM 负责理解和决策,MCP 作为标准化中介把决策落到对数据库、API、消息队列的实际操作上。对于 Java + AI 方向的开发者,掌握 Controller/Service/Tool 的分层写法、配置驱动的工具注册,以及生产环境的密钥与权限管理,是把 Demo 推向生产的关键一步。

#Spring AI#MCP#模型上下文协议#AI Agent#Java AI 开发#生产级 AI Agent#Model Context Protocol#LLM 工具调用
分享:

相关推荐