首页/新闻资讯/正文详情

Spring AI 高级实战:ChatMemory、Tool Calling 与 MCP 架构解析

发布时间:2026/11/3 10:41:10 来源:云帆数科 栏目:资讯中心
Spring AI 高级实战:ChatMemory、Tool Calling 与 MCP 架构解析
在大模型工程化落地中记忆State、工具调用Action与标准协议Connection构成了应用与模型交互的三驾马车。本文从底层存储到协议规范为你拆解生产级避坑指南与面试高频考点。一、 ChatMemory策略层与存储层分离Spring AI 将“记忆”优雅地拆分成了两层很多开发者只停留在第一层容易在深度面试中失分ChatMemory策略层决定留多少条、怎么裁剪。ChatMemoryRepository存储层决定存在哪、怎么序列化。1. 默认配置的“三个致命问题”默认情况下Spring AI 使用MessageWindowChatMemory配合InMemoryChatMemoryRepository基于ConcurrentHashMap存在 JVM 堆内存。这只能用于 Demo生产环境必踩以下三个坑重启即丢服务发布一次用户多轮对话全清空。多实例不共享网关负载均衡到另一台历史断层。OOM 风险conversationId只增不删内存无限膨胀。2. 配置方式一JDBC 与它的“巨坑”官方内置了 JDBC 存储方案。配置如下yamlspring: ai: chat: memory: repository: jdbc: initialize-schema: always # 自动建表生产建议 never走 DB 变更脚本 必须知道的巨坑官方默认表结构SPRING_AI_CHAT_MEMORY只存content type timestamp不存toolCalls和metadata。后果如果你的会话发生过工具调用从 JDBC 恢复出来的是“残缺”的AssistantMessage只有文本没有toolCalls后续发请求直接 400与ToolResponseMessage无法配对。解法使用了 Tool Calling 的场景要么自定义存储结构要么将工具轮次从记忆中剔除。3. 配置方式二自定义存储企业级方案Redis实现ChatMemoryRepository接口核心方法包括findByConversationId、saveAll等。javaOverride public void saveAll(String cid, ListMessage messages) { String key ai:chat:memory: cid; // 序列化必须保留完整 Message含 toolCalls、metadata不能只存纯文本 redis.opsForList().rightPushAll(key, messages.stream().map(this::toJson).toList()); redis.expire(key, Duration.ofHours(2)); // 必须设 TTL redis.opsForList().trim(key, -MAX_MESSAGES, -1); // 配合策略层做条数裁剪 }4. 挂载与最佳实践javaChatMemory memory MessageWindowChatMemory.builder() .chatMemoryRepository(redisRepository) // 替换默认内存实现 .maxMessages(20) .build(); ChatClient client ChatClient.builder(chatModel) .defaultAdvisors(MessageChatMemoryAdvisor.builder(memory).build()) .build(); client.prompt() .user(q) .advisors(a - a.param(ChatMemory.CONVERSATION_ID, orderId)) // 会话 ID 由业务决定 .call().content();Advisor 的区别MessageChatMemoryAdvisor历史作为多条 Message 插入语义最准 vsPromptChatMemoryAdvisor历史拼成一段文本塞进 system兼容性做法但损失结构。会话 ID 选择必须用业务主键如工单号、订单号绝对不要用sessionId或随机 UUID——否则刷新页面历史就断且无法做客服回溯。二、 Tool Calling明确安全边界与降级策略LLM 只输出“调用意图”从不执行。执行权在应用侧Spring AI 的ToolCallback这是核心安全边界。1. 触发时机与标准降级链调用工具不只是在“模型想调”的时候常见场景包括实时数据库存、汇率、精确计算、结构化查库、副作用操作下单。标准降级链面试重点text向量检索 → 命中则直接答 → 空/低分 → 调联网搜索工具 → 结果回填 LLM 组织答案 → 仍为空 → 明确告知“资料未覆盖”不编造2. 结果的两种去向去向实现方式适用场景回填给 LLM 二次组织默认行为框架自动再调一次模型需要模型消化、总结、多工具串联直接返回给用户配置Tool(returnDirect true)结果本身就是答案跳转链接、订单卡片、无需模型改写3. 工程落地 8 条军规description 是 Prompt写得模糊模型就会乱调、传错参。服务端强校验模型会传null、负数、超长字符串绝不信任模型参数。幂等性模型可能重复调用同一个工具。超时与熔断外部 API 设 3~5 秒超时防拖死整个对话。身份隔离使用toolContext传用户身份绝不用模型参数传userId防伪造。循环上限限制连续调用轮次如 5 次防死循环烧 Token。结果截断工具返回 10 万字会直接打爆上下文必须截断 摘要。人在环HITL下单、退款等危险操作必须拦截并让用户人工确认。三、 MCP破除误区与架构视角1. 核心纠偏MCP 不需要 Python/Node 环境错误认知“接入 MCP 需要 Python 或 Node 环境”。正确认知MCP 是协议JSON-RPC 2.0与语言无关。官方/社区 SDK 覆盖 Java、Python、TS、Go 等。之所以感觉“需要 npx / uvx”是因为部分现成的社区 Server 恰好是 Node/Python 写的。Spring AI 支持官方提供了spring-ai-starter-mcp-server-webmvc等Java 完全可以直接写 MCP Server跟现有微服务共用同一套部署和鉴权体系。2. MCP 的本质M×N 降为 MNMCP 不是“模型的协议”而是“应用 ↔ 能力提供方”的协议。类比 LSPLanguage Server Protocol之于编辑器。没有 MCPM 个 AI 应用 × N 个数据源 M×N 个定制集成。有了 MCPM 个 Client N 个 Server MN 个实现。(注MCP 并不替代 Function CallingFunction Calling 是“模型让应用调什么”MCP 是“应用去哪找工具、怎么描述工具”。)3. Server 原语与传输方式三类原语Tools可调用函数有副作用、Resources只读数据、Prompts可复用模板。传输方式stdio本地子进程通信IDE 插件常用。Streamable HTTP含旧版 SSE远程服务支持鉴权、可水平扩展企业集成首选。4. Spring AI 集成代码写 ServerJava 纯后端javaConfiguration public class McpServerConfig { Bean ToolCallbackProvider dtcTools(DtcToolService svc) { // 加了 Tool 的方法自动变成 MCP Tool return MethodToolCallbackProvider.builder().toolObjects(svc).build(); } }接 Client远程调用yamlspring.ai.mcp.client.sse.connections.ats-dtc.url: https://mcp.internal/ats/dtc连上之后MCP 的工具会自动注册成ToolCallback直接传给ChatClient使用。这就是完整的“业务能力 → MCP Server → ToolCallback → 模型调用”链路。5. MCP 的安全红线防工具投毒description也是 Prompt可能被注入。远程必须鉴权OAuth 2.1 / mTLS不能裸奔。stdio 命令防注入command绝不能由用户控制。路径穿越校验Resources读取要做../校验。能力最小化一个 Server 只暴露一类能力别做万能网关。四、 面试 60 秒高能串讲版“ChatMemory 分策略和存储两层。策略默认按条数裁剪存储默认在 JVM 堆里——重启丢、多实例不共享只能 Demo 用。生产环境我换 JDBC 或自定义 Redis 实现会话 ID 用业务主键设 TTL且必须完整序列化 Message 含 toolCalls否则工具调用恢复后请求非法。Tool Calling 里模型只输出调用意图执行在应用侧这是安全边界。触发场景常见于知识库召回为空时的联网兜底。结果默认回填模型二次组织returnDirect true则直接返回。工程上守住服务端参数校验、幂等、超时熔断、通过toolContext传身份。MCP 的本质是应用与能力提供方的标准协议JSON-RPC 2.0把 M×N 集成降成 MN。它跨语言用 Spring AI 我完全可以用 Java 写 Server走 Streamable HTTP 传输和我们现有的微服务鉴权体系无缝集成。连上后工具自动注册为 ToolCallback实现模型侧完全解耦。”

相关推荐

潮湿油污车间光电传感器选型实战:失效机理、防护指标与维护节拍设计
潮湿油污车间光电传感器选型实战:失效机理、防护指标与维护节拍设计

在机加工、清洗、淬火与涂装前处理等工序中,冷却液飞溅、油雾沉积、水汽凝结与清洗剂喷淋往往同时出现。这类复合工况对光电传感器的挑战并不止于“是否防水”,而在于光学窗口能否长期保持有效透光、密封结构能否抵御介质侵入,以及清洁与更换… · 2026/11/3 10:41:10

第98章 「静默的进步」—— 悦儿篇
第98章 「静默的进步」—— 悦儿篇

外界关于技术禁运、金融博弈和地缘紧张的消息如同永不停歇的背景噪音,透过实验室厚重的隔音墙壁,依然能感受到那份无处不在的喧嚣。然而,在悦儿位于北京北郊那座被竹林半环绕的独栋研究所内,时间却仿佛以另一种密度流淌着。这里没… · 2026/11/3 10:40:10

双11供应链大战:从顺丰自动化分拣看电商物流与供应链创新的参访价值
双11供应链大战:从顺丰自动化分拣看电商物流与供应链创新的参访价值

每年进入10月下旬,电商物流行业都会迎来一年之中压力较大的一段日子。国家邮政局监测数据显示,2025年「双11」业务周期(10月21日至11月11日)内,全国邮政快递企业共揽收快递包裹139.38亿件,日均揽收量达6.34… · 2026/11/3 10:40:10

uniapp海外游戏分发工程:PG电子集成与Switch卡带区域适配
uniapp海外游戏分发工程:PG电子集成与Switch卡带区域适配

简介:这是一套面向海外游戏业务开发者的全栈前端解决方案,基于UniApp框架实现跨平台兼容,专为构建海外游戏交易平台、手游下载站及Switch游戏卡带销售系统设计。资源包含完整可二次开发的前端源码(非编译后产物)&#… · 2026/11/4 0:00:17

Qoder NEXT:智能代码补全工具的技术解析与应用
Qoder NEXT:智能代码补全工具的技术解析与应用

1. 项目概述Qoder NEXT作为新一代智能编程辅助工具,其核心突破在于通过深度优化代码补全算法,将AI生成代码的开发者采纳率提升了65%。这个数字背后代表着编程效率的实质性飞跃——开发者不再需要花费大量时间在重复性代码编写和机械性调试上,… · 2026/11/4 0:00:17

32G统一内存跑大模型:内存账、TPS实测与端云分流
32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17

从生成Token到直接决策:Jev如何重塑AI Agent工程实践
从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17

AI辅助技术栈评估:提升研发决策效率60%
AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17

GLM-5.3-FlashX 200 tokens/s 背后:MoE架构与Infra优化实战解析
GLM-5.3-FlashX 200 tokens/s 背后:MoE架构与Infra优化实战解析

1. 从 200 tokens/s 这个数字说起:GLM-5.3-FlashX 到底在解决什么问题第一次看到“200 tokens/s”这个数字,我的反应不是“哇好快”,而是“这个速度到底是在什么条件下测出来的”。因为做 AI 应用落地的人都知道,模型推理速度这个… · 2026/11/3 23:59:16

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

AI辅助技术栈评估:提升研发决策效率60%
AI辅助技术栈评估:提升研发决策效率60%

1. 项目背景与核心价值技术决策一直是研发团队面临的重大挑战。随着技术生态的快速演进,技术栈的选择、维护和迭代变得愈发复杂。我们团队在过去两年里,先后经历了三次重大技术栈迁移,每次都需要投入大量人力进行技术评估和风险分析。直到去年… · 2026/11/4 0:00:17

从生成Token到直接决策:Jev如何重塑AI Agent工程实践
从生成Token到直接决策:Jev如何重塑AI Agent工程实践

1. 从"生成文字"到"拍板决策":Jev 到底在解决什么问题大多数人第一次接触大模型,脑子里建立的模型是"输入问题、输出文字"。你问它今天天气怎么样,它给你一段描述;你让它写个周报,它给你… · 2026/11/4 0:00:17

32G统一内存跑大模型:内存账、TPS实测与端云分流
32G统一内存跑大模型:内存账、TPS实测与端云分流

想在一台 32G 统一内存的小主机上把大模型跑成"日常可用",这件事我前后折腾了小半年。标题里说的这台 Mac mini M6,是我们这次讨论的目标平台,具体到手规格以实物为准;但下面这套推算方法和实测思路,对任何统… · 2026/11/4 0:00:17

双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28

STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24

DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码