公司动态

Spring AI 2.0企业级Agent开发全链路:从多模型到工具与记忆的实战指南

📅 2026/9/1 10:51:16
Spring AI 2.0企业级Agent开发全链路:从多模型到工具与记忆的实战指南
过去几年里Java 开发者接触 AI 应用大多还停留在“把模型 API 包一层 HTTP 接口”的阶段。真正进入企业级场景后会发现AI 应用最难的部分从来不是调通模型而是把模型、业务工具、外部系统、会话上下文、团队技能沉淀串成一条稳定可控的生产链路。业务方要的也不是一个能闲聊的 Demo而是一个能处理航班查询、票务变更、值机提醒、异常退改这种真实任务的 Agent 服务。Spring AI 2.0 正好在这一层做文章。它没有去重新发明模型调用方式而是为 Java 生态提供了一个标准的 Agent 开发框架多模型可以做统一抽象Tools 解决模型与业务系统的交互MCP 协议把外部服务变成可编排的工具多层记忆补上无状态模型的短板Skills 则让团队把经验沉淀成可复用的能力。这套组合恰好覆盖了企业级 AI Agent 从 0 到 1 的完整链路。这篇文章以智能航空项目为实战场景完整拆解 Spring AI 2.0 下的 Agent 开发全链路。你会看到多模型接入的统一配置方式、Tools 与 MCP 的边界和用法、会话与长期记忆的落地方式、Skills 的封装思路以及一个可运行的航空客服 Agent 示例。读完你得到的不是零散 API 抄录而是一套能直接指导项目落地的工程方法论。1. 这篇文章真正要解决的问题先说结论企业级 AI Agent 项目的复杂度不在模型选择而在工程化组织。如果你只是写一个单轮问答工具调用 OpenAI 或 DeepSeek 都很快。但一旦进入真实业务你会立刻碰到一连串问题模型提供方变了代码是不是要大面积改Agent 说“我要查航班”谁来真正执行查询动作现有订单系统、天气服务、机场信息平台怎么接入多轮对话里用户说了“刚才那班”模型怎么知道“刚才”指什么团队做了多个 Agent 功能同类能力怎么复用而不是每个项目重写一遍这些问题单独看都不难组合在一起就会变成“胶水代码地狱”。Spring AI 2.0 的核心价值就是用一套 Java 开发者熟悉的编程模型把上面这些问题标准化。多模型有统一的 ChatModel 抽象Tools 用注解就能暴露业务方法MCP 让外部系统接入不再需要每个服务写一套私有协议记忆用 advisor 机制平滑注入对话链路Skills 则把高频场景沉淀成可复用单元。这篇文章适合三类读者有 Spring Boot 基础想把 AI 能力接入企业项目的开发者正在做 Agent 项目但发现工具调用、记忆管理越来越乱的团队刚开始接触 Spring AI想了解它到底能解决什么问题的架构师。如果你的项目还在用“注入 API Key 拼接 Prompt”的方式做 AI 应用这篇文章正好可以帮你把工程层次提升到 Agent 级别。2. 核心概念Agent、Tools、MCP、Skills、多层记忆在进入代码之前需要先统一几个概念。很多混乱都来自概念边界不清楚。2.1 Agent 是什么Agent智能体是一个由大模型驱动的决策单元。它不只是生成文本而是根据用户目标自主决定调用哪些工具、需要哪些上下文、最终返回什么结果。一个典型的 Agent 循环是接收用户请求 → 理解意图 → 选择工具 → 执行工具 → 整理结果 → 返回给用户。在 Spring AI 里Agent 不是某个单独的类而是一种组合能力。你可以通过ChatClient配合工具、记忆、模型切换来实现 Agent 行为。这也是 Spring AI 设计上比较克制的地方不引入过多黑盒概念而是让你用可组合的组件搭出 Agent。2.2 Tools、MCP、Skills 有什么区别Tools工具是 Agent 可以执行的函数单元。模型在推理时根据函数描述决定是否调用某个 ToolSpring AI 通过Tool注解或ToolCallback接口把 Java 方法暴露给模型。MCPModel Context Protocol模型上下文协议是 Anthropic 在 2024 年底提出的开放协议目的是统一大模型与外部数据源、工具之间的连接方式。可以把 MCP 看成“AI 世界的 USB-C 接口”只要服务方实现了 MCP Server任何 MCP Client 都能以标准方式调用它。Spring AI 2.0 全面支持 MCP Client 和 MCP Server意味着你可以用统一方式接入数据库、GitHub、设计稿、内部系统等外部能力。Skills技能则是一个容易被误解的概念。它不是一个新的协议而是把 Prompt、工具、上下文策略打包成的高层复用单元。一个 Skill 可以包含触发该技能的指令描述执行该技能所需的工具集合给模型的上下文提示结果处理逻辑。简单来说Tools 是“原子操作”MCP 是“连接外部系统的统一协议”Skills 是“面向业务场景的操作手册”。2.3 多层记忆是什么大模型本身没有记忆每个请求都是独立事件。多层记忆就是通过工程手段在对话层、业务层、知识层分别补充上下文。短期记忆保存当前会话多轮对话内容让 Agent 理解“刚才那班”。业务记忆保存用户偏好、历史订单比如“用户上次订过靠窗座位”。长期知识通过向量数据库保存企业文档、政策、产品手册让 Agent 能回答专业问题。Spring AI 2.0 通过 advisor 机制统一处理这些记忆注入后面会在第 6 章详细展开。3. 智能航空场景设计Agent 的能力边界现在把概念落到具体场景。假设我们要构建一个航空公司智能客服 Agent它需要解决以下真实业务问题用户查询航班查出发时间、到达时间、准点率用户查询天气航班目的地天气是否影响出行用户申请退改查询退改规则计算退改费用用户咨询政策例如行李额、登机口变更、无陪儿童服务用户要求预订搜索可选航班协助下单。这不是一个“对话机器人”而是一个需要和真实业务系统打交道的 Agent。在传统开发模式下这类功能通常靠一堆脚本规则和人工客服系统实现。用户输入被解析规则匹配然后走固定流程。缺点是意图覆盖不全、维护成本高、无法处理组合需求。在 Agent 模式下流程变成了这样用户说“帮我查一下明天上海到北京早上的航班顺便看看北京天气。”Agent 将需求拆解为两个子任务查询航班列表、查询北京市天气Agent 调用航班查询 Tool获取航班数据Agent 调用天气查询 Tool获取天气数据Agent 将两部分结果整理成自然语言回复。这个过程中模型负责“理解与决策”Tools 负责“执行与获取数据”记忆负责“记住用户是在哪天问的、什么偏好”。三者缺一不可。从业务角度这个 Agent 的能力边界可以归纳为能力层对应组件典型动作意图理解与生成ChatModel Prompt识别用户意图组织回复业务操作Tools / MCP查询航班、生成订单、查询退改规则外部系统接入MCP接入机场信息平台、天气服务、内部订单系统上下文保持会话记忆 长期记忆多轮对话、用户偏好、历史订单团队沉淀复用Skills退改流程、航班查询模板、客服话术明确了这些后续每个技术点都能对号入座。4. 环境准备与多模型接入管理从这一章开始进入实操。建议先跑通最小工程再逐步叠加功能。4.1 技术选型与环境要求Spring AI 2.0 是基于 Spring Boot 3.x 的模块化框架建议使用以下环境JDK 17 及以上Spring Boot 3.2 或更高版本Maven 3.8一个兼容 OpenAI API 的大模型服务例如 OpenAI、DeepSeek、通义千问、本地 Ollama 等。Spring AI 2.0 仍处于快速迭代阶段不同版本的 API 可能微调。本文代码中的类名和配置基于当前通用稳定写法具体版本请以项目实际依赖为准。4.2 初始化 Spring Boot 项目并引入依赖创建一个 Spring Boot 项目后在pom.xml中引入 Spring AI BOM 和核心依赖parent groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-parent/artifactId version3.3.5/version relativePath/ /parent properties java.version17/java.version spring-ai.version2.0.0/spring-ai.version /properties dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-openai/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-ollama/artifactId /dependency dependency groupIdorg.springframework.ai/groupId artifactIdspring-ai-starter-model-mcp-server/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-test/artifactId scopetest/scope /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如果实际情况中spring-ai.version使用的不是 2.0.0不要照抄要以官方发布版本为准。这里的关键在于 BOM 机制统一了 Spring AI 各模块版本。4.3 配置多模型企业级项目通常不会只绑定一个模型。原因很现实不同模型在中文理解、数学计算、价格、延迟上差异很大生产中需要根据场景选择模型。在application.yml中配置两个模型spring: application: name: aviation-agent ai: openai: base-url: https://api.openai.com api-key: ${OPENAI_API_KEY} chat: options: model: gpt-4o-mini temperature: 0.7 ollama: base-url: http://localhost:11434 chat: options: model: qwen2.5:7b需要注意的是DeepSeek 等第三方模型服务通常兼容 OpenAI 协议。如果使用 DeepSeek可以设置spring.ai.openai.base-url为 DeepSeek 的接口地址并填写对应 API Key。不同服务的接口地址和模型名称不能混用。4.4 多模型切换的工程做法Spring AI 2.0 中每个模型对应一个ChatModelBean。当配置了多个模型时推荐使用一个统一的ModelRouter来管理路由Component public class ModelRouter { private final MapString, ChatModel modelMap; public ModelRouter(ChatModel openAiChatModel, ChatModel ollamaChatModel) { modelMap new HashMap(); modelMap.put(openai, openAiChatModel); modelMap.put(ollama, ollamaChatModel); } public ChatModel getModel(String modelName) { return modelMap.getOrDefault(modelName, modelMap.get(openai)); } public ChatClient getChatClient(String modelName, String systemPrompt) { ChatModel model getModel(modelName); return ChatClient.builder(model) .defaultSystem(systemPrompt) .build(); } }这样设计后业务代码无需直接依赖具体模型实现。上线后如果发现某个模型不适合当前场景只需调整路由规则改动范围被限制在一个类中。这种多模型管理方式是 Spring AI 相比直接调用 SDK 的核心优势之一不同模型的接入成本被抽象成相同的ChatModel接口切换模型不再是重构级变更。5. Tools 与 MCP把外部能力变成 Agent 的工具Agent 和普通聊天机器人最大的区别就是能执行动作。Spring AI 2.0 提供了两条工具化路径本地 Tools 和标准化 MCP。5.1 用 Tool 暴露业务方法假设航班查询是内部系统已有能力我们只需要暴露一个 Java 方法。使用Tool注解即可import org.springframework.ai.tool.annotation.Tool; import org.springframework.stereotype.Component; import java.util.List; Component public class FlightQueryTool { Tool(description 查询指定日期、出发地、目的地的航班列表) public ListFlightInfo queryFlights(String date, String from, String to) { // 实际项目在这里调用订单系统或航班数据库 return FlightDataCenter.search(date, from, to); } Tool(description 查询指定航班号的实时状态包括延误、取消、登机口) public FlightStatus queryFlightStatus(String flightNo) { return FlightDataCenter.fetchStatus(flightNo); } } record FlightInfo(String flightNo, String departure, String arrival, String takeoffTime, String arriveTime, double price) { } record FlightStatus(String flightNo, String status, String gate, String delayReason) { }Tool注解的关键是description字段。模型并不理解 Java 代码它要根据描述来判断“什么时候应该调用这个工具”。描述写得越准确模型误调用的概率越低。5.2 为 ChatClient 注册 Tools接下来在构建ChatClient时注册工具Component public class AgentConfig { private final FlightQueryTool flightQueryTool; public AgentConfig(FlightQueryTool flightQueryTool) { this.flightQueryTool flightQueryTool; } Bean public ChatClient aviationChatClient(ChatModel chatModel) { return ChatClient.builder(chatModel) .defaultSystem( 你是航空公司的智能客服助手。 你可以查询航班信息、航班状态和机场天气。 回答要简洁、准确、友好。 ) .defaultTools(flightQueryTool) .build(); } }配置完成后用户提问“明天上海到北京有哪些航班”模型会先调用queryFlights拿到结果后再组织回答。这就是函数调用的完整链路。5.3 用 MCP 接入外部服务Tools 解决的是“本地方法如何暴露给模型”但如果要接入天气服务、数据库、设计稿平台、内部系统总不能为每个系统都写一套私有 SDK 和协议转换。MCP 的引入改变了这一点。Spring AI 2.0 中你可以通过 MCP Client 连接任意 MCP Server并把 Server 提供的工具自动注册给 Agent。一个常见的接入方式是使用 Spring AI 的 MCP Server 模块把当前服务本身变成一个 MCP Server或者通过 MCP Client 连接远程服务。以连接远程天气 MCP Server 为例在application.yml中配置spring: ai: model: mcp: client: connections: weather-server: type: SSE url: https://mcp.example-weather-service.com/sse api-key: ${MCP_API_KEY}代码中通过ToolCallbackProvider批量导入 MCP 工具Configuration public class McpToolsConfig { Bean public ToolCallbackProvider weatherTools(ListMcpClient mcpClients) { return new MethodToolCallbackProvider(); } }更稳妥的方式是在ChatClient构建时使用 Spring AI 提供的McpToolCallbackProvider或ToolCallbackProvider将 MCP 工具和本地Tool一起注册Bean public ChatClient mcpAviationChatClient(ChatModel chatModel, ToolCallbackProvider mcpToolCallbackProvider) { return ChatClient.builder(chatModel) .defaultSystem(你是智能航空助手可使用 MCP 提供的天气和航班外部服务。) .defaultTools(mcpToolCallbackProvider) .build(); }如果运行时发现 MCP 工具没有生效优先检查 MCP Server 地址是否可达、SSE 连接是否正常、API Key 是否有权限。5.4 Tools 与 MCP 如何选择对比维度ToolsMCP接入成本直接在 Java 方法上加注解成本最低服务方需要实现 MCP Server或使用现成 Server适用场景内部业务方法、单体应用多系统协作、异构技术栈、外部 SaaS通用性仅对当前 Agent 暴露协议标准任何 MCP Client 都可调用生态价值只需维护本地方法对接开源生态例如数据库、文件、浏览器等管理复杂度简单但工具多了会杂乱需要管理连接、鉴权、状态实际项目中两者不是互斥关系。内部简单操作优先用Tool跨团队、跨系统能力优先走 MCP。很多企业会把“航班查询”做成本地 Tool把“机场贵宾室预约”通过 MCP 接入第三方服务。6. 多层记忆从会话上下文到企业知识Agent 如果没有记忆用户每句话都像第一次对话。“帮我改签刚才那班航班”里的“刚才”必须靠上下文记忆来还原。6.1 会话级记忆Spring AI 的 advisor 机制可以方便地注入会话记忆。使用MessageChatMemoryAdvisor配合InMemoryChatMemoryimport org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.client.advisor.MessageChatMemoryAdvisor; import org.springframework.ai.chat.memory.InMemoryChatMemory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; Configuration public class MemoryConfig { Bean public ChatClient memoryChatClient(ChatModel chatModel) { var memory new InMemoryChatMemory(); return ChatClient.builder(chatModel) .defaultSystem(你是智能航空助手。记住用户在对话中提供的信息。) .defaultAdvisors(new MessageChatMemoryAdvisor(memory)) .build(); } }这里InMemoryChatMemory适合单机测试。生产环境建议实现ChatMemory接口把消息存储到 Redis 或数据库这样多实例部署时仍能共享会话上下文。6.2 业务级记忆业务记忆不只是对话内容还包括用户偏好和历史订单。例如用户历史订单中全是“靠窗座位”Agent 在推荐座位时可以优先考虑这个偏好。实现方式是把用户画像作为系统上下文的一部分在请求进入模型前注入。可以结合 Spring AI 的 advisor 自定义实现public class UserProfileAdvisor implements CallableAdvisor { private final UserProfileService userProfileService; public UserProfileAdvisor(UserProfileService userProfileService) { this.userProfileService userProfileService; } Override public String getName() { return user-profile-advisor; } }在实际工程中可以更简单地通过defaultSystem动态拼接用户画像但要注意不要超过模型上下文窗口。6.3 长期知识库与向量检索要回答“退改签手续费怎么算”这种政策类问题直接把 pdf 文本塞进 Prompt 不现实。更规范的方案是向量化存储 检索增强生成RAG。Spring AI 提供了统一的VectorStore抽象。以 Redis 作为向量库为例配置如下spring: ai: vectorstore: redis: index: aviation-policy-index代码中先构建向量存储再把检索结果注入 PromptComponent public class PolicyKnowledgeService { private final VectorStore vectorStore; private final EmbeddingModel embeddingModel; public PolicyKnowledgeService(VectorStore vectorStore, EmbeddingModel embeddingModel) { this.vectorStore vectorStore; this.embeddingModel embeddingModel; } public String searchPolicy(String question) { var query org.springframework.ai.vectorstore.SearchRequest.builder() .query(question) .topK(3) .build(); ListDocument docs vectorStore.similaritySearch(query); return docs.stream() .map(Document::getText) .reduce(, (a, b) - a \n b); } }然后在构建客户端时注入检索结果Bean public ChatClient policyChatClient(ChatModel chatModel, PolicyKnowledgeService policyKnowledgeService) { return ChatClient.builder(chatModel) .defaultSystem(advice - advice .text(你是航空政策助手请根据以下知识回答用户的问题\n{knowledge}) .param(knowledge, policyKnowledgeService::searchPolicy)) .build(); }这种“先检索、再回答”的模式能显著减少模型幻觉也能让回答基于企业自定义知识。需要注意的是向量库版本和 Embedding 模型需要匹配否则检索效果会大打折扣。7. Skills 技能封装沉淀可复用的 Agent 能力当航班查询、退改签、天气查询这些能力都实现后问题变成了如何把它们组合成一个业务技能让其他 Agent 也能复用Skills 就是解决这个问题的高层封装。一个 Skill 不是单纯的一个类而是一个完整的“指令 工具 处理流程”包。7.1 Skill 的组成以“航班退改签”技能为例它至少包含技能描述什么时候用这个技能触发条件用户表达退改意图时所需工具订单查询、退改规则查询、费用计算输出格式报价、耗时、政策提示。在 Spring AI 中可以用一个普通 Java 类来组织 Skill。它负责持有工具调用逻辑和 Prompt 模板Component public class FlightChangeSkill { private final OrderQueryTool orderQueryTool; private final ChangeRuleTool changeRuleTool; public FlightChangeSkill(OrderQueryTool orderQueryTool, ChangeRuleTool changeRuleTool) { this.orderQueryTool orderQueryTool; this.changeRuleTool changeRuleTool; } public String apply(String userSentence) { // 1. 从用户话语中识别订单号 String orderNo extractOrderNo(userSentence); // 2. 查询订单 var order orderQueryTool.queryOrder(orderNo); // 3. 查询退改规则 var rule changeRuleTool.queryRule(order.flightNo()); // 4. 计算费用 double fee rule.calculateFee(order.payAmount()); return String.format(您的订单 %s 可以退改预估手续费 %.2f 元剩余退款 %.2f 元。, orderNo, fee, order.payAmount() - fee); } private String extractOrderNo(String text) { // 实际项目用 NLP 或正则也可以交给模型抽取 return text.replaceAll(.*(\\d{10}).*, $1); } }7.2 把 Skill 暴露给 Agent为了让模型知道何时调用这个技能可以把 Skill 也包装成 Tool或者通过系统 Prompt 告知模型可用技能列表。推荐方式是把 Skill 中暴露给模型的方法加上Tool注解Component public class FlightChangeSkill { private final OrderQueryTool orderQueryTool; private final ChangeRuleTool changeRuleTool; // 构造函数省略 Tool(description 执行航班退改签查询输入用户原话返回退改金额和建议) public String handleChangeRequest(String userSentence) { return apply(userSentence); } }这样 Agent 在理解用户意图后会调用handleChangeRequest内部再串联多个子工具。从模型视角看这是一个完整技能从工程视角看内部实现细节被封装了。7.3 Skill 与 MCP 的区别结合开头提到的概念可以有一个更清晰的理解MCP 是传输层标准解决“工具如何被安全发现和调用”。Skill 是应用层组织解决“哪些工具和指令组合起来能完成一项业务”。MCP Server 可以对外发布一个“退改签服务”但服务里的业务编排、规则判断、异常兜底仍然要写在 Skill 层。两者不是替代关系而是不同抽象层次。团队内部沉淀 Skills跨团队协作通过 MCP 暴露能力是比较合理的架构。8. 综合实战航空 Agent 全链路编排与验证现在把前文所有内容串起来构建一个能处理“查询航班 → 查天气 → 回答退改政策”的完整航空 Agent。8.1 核心组件总览项目中最核心的组件有三个模型层支持多个 ChatModel通过ModelRouter路由工具层FlightQueryTool、WeatherTool、MCP 外部工具技能层FlightChangeSkill等业务封装。8.2 Agent 服务代码创建一个AviationAgentServiceService public class AviationAgentService { private final ChatClient chatClient; public AviationAgentService(ChatClient chatClient) { this.chatClient chatClient; } public String chat(String userMessage, String sessionId) { return chatClient.prompt() .user(userMessage) .advisors(advisor - advisor.param(chatId, sessionId)) .call() .content(); } }会话 ID 的存在是为了让 advisor 在长期记忆场景下为不同的用户维护独立的上下文。8.3 创建 Agent 配置综合配置Configuration public class AviationAgentConfiguration { Bean public ChatClient aviationAgentChatClient(ChatModel chatModel, FlightQueryTool flightQueryTool, WeatherTool weatherTool, ToolCallbackProvider mcpTools, ChatMemory chatMemory) { return ChatClient.builder(chatModel) .defaultSystem( 你是航空智能助手。你可以查询航班、查询机场天气、处理退改签。 请始终使用工具获取最新数据不要凭记忆编造航班信息。 回答使用中文简洁友好。 ) .defaultTools(flightQueryTool, weatherTool) .defaultTools(mcpTools) .defaultAdvisors(new MessageChatMemoryAdvisor(chatMemory)) .build(); } }其中ChatMemory可以是 Redis 实现也可以先使用内存实现。生产环境建议使用JdbcChatMemory或自定义 Redis 实现。8.4 提供 HTTP 接口RestController RequestMapping(/api/agent) public class AgentController { private final AviationAgentService agentService; public AgentController(AviationAgentService agentService) { this.agentService agentService; } PostMapping(/chat) public MapString, String chat(RequestBody ChatRequest request) { String answer agentService.chat(request.message(), request.sessionId()); return Map.of(reply, answer); } public record ChatRequest(String sessionId, String message) { } }8.5 运行与验证启动项目后通过 HTTP 接口发送请求curl -X POST http://localhost:8080/api/agent/chat \ -H Content-Type: application/json \ -d { sessionId: user-001, message: 帮我查一下明天上午从上海到北京的航班再看看北京天气怎么样 }预期的执行流程是Agent 收到请求判断需要查询航班和天气调用FlightQueryTool.queryFlights返回航班列表调用WeatherTool查询北京天气模型整合结果返回一段自然语言回答。如果日志中能看到模型先发起工具调用、再生成最终回答说明链路已经打通。如果没有出现工具调用可能是 Tool 描述不够清晰或模型能力不支持复杂函数调用。8.6 验证多层记忆同一会话中再发送一条消息curl -X POST http://localhost:8080/api/agent/chat \ -H Content-Type: application/json \ -d { sessionId: user-001, message: 第一班几点起飞 }由于MessageChatMemoryAdvisor已经把前一轮的航班列表放进了上下文模型应能回答“第一班”具体指哪一班。如果不能说明会话记忆没有生效优先检查 advisor 是否注册成功以及会话 ID 是否每次相同。9. 常见问题与最佳实践9.1 常见问题排查问题现象可能原因排查方式解决方案调用 DeepSeek 后不回 content模型名称配置错误、响应格式不兼容、流式处理未处理空 content查看原始响应日志确认模型返回的解析状态核对模型名称检查 Spring AI 版本对第三方兼容性必要时关闭流式输出Agent 不调用任何工具Tool 描述不清、模型不支持函数调用、工具未注册查看对话日志确认系统 Prompt 是否包含工具说明优化Tooldescription确认defaultTools已注册MCP 工具无法加载MCP Server 地址不可达、鉴权失败、SSE 断开查看 MCP 连接日志手动调用 Server 测试连通性检查 URL、API Key 和网络策略多轮对话答非所问会话 ID 不一致、记忆 advisor 未生效检查请求参数 sessionId 是否相同确保同用户每次请求传入稳定 ID向量检索结果很差Embedding 模型与向量库维度不匹配文档切分不合理检查索引维度打印检索 topK 结果统一 Embedding 模型优化文档切分策略生产环境频繁超时外部工具响应慢、模型上下文太长查看链路追踪统计各环节耗时为 Tools 增加超时控制压缩 Prompt 历史9.2 工程最佳实践配置与环境隔离所有 API Key、MCP 地址、模型名称不要写死在代码里统一放入配置中心或环境变量。工具治理工具数量增多后建立工具命名规范建议按“业务域 动作”命名例如flight.query、order.change。权限隔离用户通过 Agent 调用工具时必须进行用户级权限校验。不要在工具内部跳过鉴权。日志与审计记录每次 Agent 的完整调用链包括用户输入、模型回复、工具入参出参、耗时和 token 数。这是排查问题最关键的数据。服务降级当外部工具不可用时Agent 应向用户说明“当前无法查询”而不是编造数据。版本兼容Spring AI 2.0 仍处在快速演进期升级 Minor 版本前先看 Release Notes尤其是 ToolCallback 和 Advisor API 的变化。Security 边界MCP Server 只暴露最小必要权限不要给 Agent 分配数据库删除、批量更新等高危权限。总结与后续学习方向这篇文章从企业级 AI Agent 的工程痛点出发围绕 Spring AI 2.0 拆解了智能航空项目的全链路实现。核心观点是AI Agent 的真正门槛在于将模型、工具、外部系统、记忆和技能进行标准化的编排而 Spring AI 2.0 的贡献正是把这条链路的工程成本降到了一个 Java 团队能稳定掌控的程度。如果你正在团队里实践 Agent下一步可以沿着这几个方向继续深入把本地Tool逐步替换或补充为 MCP 协议观察跨系统接入的成本变化设计并实现一套基于 Redis 的会话记忆方案解决多实例部署下的上下文共享把高频航空业务拆成独立 Skill并以 MCP Server 的形式暴露给其他团队引入完整的观测体系跟踪模型调用、工具调用、token 消耗和错误率用数据指导模型替换和 Prompt 优化。建议从最小可运行项目开始先把多模型 一个 Tool 会话记忆跑通再逐步接入 MCP 和 Skills。每一步都验证一次运行结果比一次性把所有能力堆上去要稳妥得多。当你把“调用模型”变成“编排能力”之后Spring AI 2.0 在企业级项目中的价值才会真正显现出来。