
1. Java 开发者做 AI Agent为什么总卡在“跑不起来”你可能已经看过不少 AI Agent 的科普知道它由大模型、工具调用、记忆、检索几块拼起来。但真到动手Java 开发者面对的第一个问题往往不是原理而是Spring AI 的依赖怎么配、MCP 工具怎么暴露、RAG 的向量库怎么接、本地启动后接口怎么验证。这些环节任何一个报错都会让“8 周从入门到产品”变成“8 周还在配环境”。这篇内容聚焦一个可运行的最小骨架用 Spring AI 作为底座把 MCP 工具调用和 RAG 检索增强串起来产出一个能本地启动、能用 curl 验证的 Agent 骨架。它适合有 Java/Spring Boot 基础、想按周推进 AI Agent 学习路径的开发者。你不需要先成为算法工程师只要会写 Controller、会看 application.yml就能跟着把骨架跑通。我试过把 MCP 和 RAG 拆成两个独立 Demo 再合并结果发现工具注册和检索上下文经常互相干扰。后来改成先固定一个 ChatClient 配置再分别挂载工具 Advisor 和检索 Advisor问题就清晰了。下面按“前置准备 → 可复制配置 → 启动验证 → 排障”的顺序展开每一步都给出可粘贴的代码和命令。2. TaoToken 前置模型接入与 Key 管理Agent 骨架要跑起来第一步是让 Spring AI 能调到大模型。这里用 TaoToken 作为模型接入层它提供 OpenAI 兼容的 API 形态Spring AI 的 openai starter 可以直接对接不需要改代码结构。你需要先拿到一个 API Key。访问控制台创建密钥控制台入口https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentconsoleAPI Keys 管理https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys创建后把 Key 存到环境变量不要写进代码仓库。Linux/macOS 下export TAOTOKEN_API_KEYsk-你的密钥Windows PowerShell$env:TAOTOKEN_API_KEYsk-你的密钥TaoToken 的 API 基地址是https://taotoken.net/api注意这个地址不带查询参数直接作为 base-url 使用。模型对话调试可以在模型对话页先验证 Key 是否可用模型对话https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat如果你后续要做长期编码或 Agent 任务可以了解 Coding PlanCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan接入文档在接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc注意Key 只放在环境变量或配置中心不要提交到 Git。Spring AI 读取的是spring.ai.openai.api-key我们用占位符引用环境变量即可。3. 可复制配置pom、application.yml 与 MCP 骨架3.1 pom.xml 依赖Spring AI 的版本要和 Spring Boot 对齐。下面用 Spring Boot 3.x 加 Spring AI 1.0.x 的组合这是目前稳定可用的搭配。MCP 部分用 Spring AI 的 MCP Server starter。parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.5/version relativePath/ /parent properties java.version21/java.version spring-ai.version1.0.0/spring-ai.version /properties dependencies !-- Web 接口验证 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency !-- Spring AI OpenAI 兼容模型接入 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency !-- 向量库先用内存版跑通 RAG后续换 Milvus -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-vector-store-simple/artifactId /dependency !-- MCP ServerWebMVC 传输 -- dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-mcp-server-webmvc/artifactId /dependency !-- 可观测性方便看调用链 -- dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-actuator/artifactId /dependency /dependencies dependencyManagement dependencies dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-bom/artifactId version${spring-ai.version}/version typepom/type scopeimport/scope /dependency /dependencies /dependencyManagement如果拉不到依赖检查 Maven 仓库是否配置了 Spring 的里程碑仓库。Spring AI 1.0.0 GA 之后已进入中央仓库一般不需要额外配置。3.2 application.yml这里把模型、向量库、MCP 三块配置放在一起。注意 base-url 指向 TaoToken 的 API 地址。server: port: 8080 spring: application: name: java-agent-skeleton ai: openai: api-key: ${TAOTOKEN_API_KEY} base-url: https://taotoken.net/api chat: options: model: gpt-4o-mini temperature: 0.3 embedding: options: model: text-embedding-3-small vectorstore: simple: initialize-schema: true mcp: server: name: infra-agent-mcp version: 1.0.0 protocol: STREAMABLE type: SYNC management: endpoints: web: exposure: include: health,info,metrics tracing: sampling: probability: 1.0模型名按你账号下可用的模型填写。embedding 模型用于 RAG 向量化如果暂时不做 RAG可以先注释掉 embedding 相关配置但向量库 starter 会要求一个 EmbeddingModel所以建议保留。3.3 ChatClient 与 Advisor 链配置把 ChatClient 的构建集中到一个配置类工具 Advisor 和检索 Advisor 都挂在这里。这样后续加功能只改一处。Configuration public class AgentConfig { Bean public ChatClient chatClient(ChatClient.Builder builder, VectorStore vectorStore, InfraTools infraTools) { return builder .defaultSystem(你是 Infra 运维助手回答要具体、可执行。) .defaultTools(infraTools) .defaultAdvisors( new QuestionAnswerAdvisor(vectorStore) ) .build(); } }QuestionAnswerAdvisor是 Spring AI 自带的 RAG Advisor它会自动把用户问题拿去向量库检索再把检索结果拼进上下文。defaultTools注册的是带Tool注解的方法。3.4 MCP 工具骨架MCP 工具用注解声明一个方法就是一个工具。下面给两个示例查磁盘、查服务状态。Component public class InfraTools { Tool(description 查询指定路径的磁盘使用率) public String checkDiskUsage( ToolParam(description 路径如 /data) String path) { return 路径 path 磁盘使用率 78%; } Tool(description 查询指定服务的运行状态) public String checkServiceStatus( ToolParam(description 服务名如 mysql) String service) { return service 状态: running, 连接数 150/200; } }如果要把这些工具通过 MCP 协议暴露给外部客户端再加一个 MCP 配置类把工具注册为 MCP 工具。Spring AI 的 MCP Server starter 会自动扫描Tool方法并暴露具体取决于版本建议先用下面的 Controller 验证工具调用再验证 MCP 端点。3.5 RAG 文档入库启动时把几段运维文档灌进向量库这样检索 Advisor 才有内容可查。Component public class DocIngestor implements CommandLineRunner { private final VectorStore vectorStore; public DocIngestor(VectorStore vectorStore) { this.vectorStore vectorStore; } Override public void run(String... args) { ListDocument docs List.of( new Document(MySQL 连接数过高时先查 Sleep 连接再考虑临时调高 max_connections。), new Document(Nginx 502 通常检查后端服务是否存活以及 upstream 配置是否正确。), new Document(Redis 内存溢出时检查 maxmemory 策略和大 key 分布。) ); vectorStore.add(docs); } }4. 验证请求本地启动与接口测试4.1 启动应用./mvnw spring-boot:run看到Started AgentApplication且端口 8080 监听说明启动成功。如果报api-key为空检查环境变量是否在当前终端生效。4.2 验证模型对话写一个最简单的 ControllerRestController public class ChatController { private final ChatClient chatClient; public ChatController(ChatClient chatClient) { this.chatClient chatClient; } GetMapping(/chat) public String chat(RequestParam String q) { return chatClient.prompt().user(q).call().content(); } }用 curl 验证curl http://localhost:8080/chat?q你好介绍一下你自己返回一段模型生成的文本说明模型接入通了。4.3 验证工具调用提问一个会触发工具的问题curl http://localhost:8080/chat?q帮我查一下 /data 的磁盘使用率如果返回内容里包含“78%”说明模型正确选择了checkDiskUsage工具并使用了返回值。这一步是 Agent 骨架的关键验证点。4.4 验证 RAG 检索提问一个只有文档里才有答案的问题curl http://localhost:8080/chat?qMySQL 连接数过高先查什么期望返回里提到“Sleep 连接”。如果模型回答的是通用知识而不是文档内容说明检索 Advisor 没生效检查向量库是否入库成功。4.5 验证 MCP 端点MCP Server 启动后一般会暴露一个 HTTP 端点具体路径看 starter 版本。可以用curl http://localhost:8080/actuator/health确认应用健康。MCP 的详细端点验证建议参考接入文档里的 MCP 章节不同版本路径有差异。5. 本篇常见错排查5.1 启动报 api-key 为空现象OpenAI API key must be set。原因是环境变量没生效或 yaml 占位符写错。检查echo $TAOTOKEN_API_KEY是否有值yaml 里必须是${TAOTOKEN_API_KEY}不要加默认值空字符串。5.2 工具不被调用现象模型直接回答没有触发Tool方法。常见原因有三个一是defaultTools没注册二是工具方法所在类没加Component三是模型本身不支持工具调用。换一个支持 function calling 的模型再试。5.3 RAG 检索不到内容现象提问文档里的问题模型答非所问。先确认DocIngestor是否执行可以在vectorStore.add后打日志。再确认QuestionAnswerAdvisor是否挂到了 ChatClient 上。如果向量库是 simple 版重启后数据会丢需要每次启动重新入库。5.4 MCP 端点 404现象访问 MCP 路径返回 404。不同 starter 版本的端点路径不同有的在/mcp有的在/sse。先看启动日志里打印的 MCP 端点再按日志路径访问。如果用的是 STREAMABLE 协议注意请求方法可能是 POST。5.5 依赖冲突现象NoSuchMethodError或ClassNotFoundException。多半是 Spring AI 版本和 Spring Boot 版本不匹配。Spring AI 1.0.x 对应 Spring Boot 3.3不要混用 3.2。用mvn dependency:tree看是否有旧版本被传递进来。5.6 向量维度不一致现象入库时报维度错误。原因是 embedding 模型换了但向量库 schema 没重建。simple 向量库重启即清空Milvus 需要删 collection 重建。换 embedding 模型时务必同步重建索引。6. 按周推进与下一步这个骨架对应 8 周路径的前两周第一周把模型接入和工具调用跑通第二周把 RAG 检索接上。后面几周可以在这个骨架上逐步加东西第三周加多工具编排第四周加多 Agent 协作第五周把工具通过 MCP 暴露给外部客户端第六周加可观测性和安全护栏第七八周做产品化整合。如果你在验证模型对话时遇到问题可以回到模型对话页单独测 Key模型对话https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentmodel-chat如果卡在接入配置或 MCP 端点先看接入文档接入文档https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentdoc需要新建或轮换 Key去 API Keys 页API Keyshttps://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentapi-keys长期做编码类 Agent 任务可以看 Coding PlanCoding Planhttps://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_contentcoding-plan骨架跑通之后建议你做的第一件事是把DocIngestor里的三行文档换成你自己领域的真实文档然后提一个只有你的文档才能回答的问题。这一步能同时验证 RAG 和工具调用两条链路比任何理论都直观。