W7D2 学习手册 1.Tool概览2.@Tool3.注册4.流程5.Memory 6.实现7.关系W2/W48.Advisor配合9.生产注意10.会话状态 资源达标①达标②自测速记

FDE W7D2 学习手册 · Spring AI Tool Calling 与 Chat Memory

W7 周级拆解 Day2 · A 级(必须掌握,面试核心)· 约 4h · 学完能讲清"Java 侧如何让模型调本地方法、以及如何管理多轮会话记忆"

本日定位:W2 我们讲了"Tool Calling 原理 + 自研 Agent 工具调度";W7D2 进入 Spring AI 的生产级实现:用 @Tool 声明工具、自动注册到 ChatClient,让模型在 Java 侧调用你的方法;以及 ChatMemory 抽象管理会话记忆(InMemory/Redis/JDBC)。这是把 W2/W4 Agent 能力落到 Java 企业平台的关键。
学完能回答:① Spring AI Tool Calling 怎么定义、怎么注册到 ChatClient、完整执行流程;② Chat Memory 怎么接不同存储、和 W3 会话状态的关系。
使用方法:通读原理 → 重点看「🔧 工程含义」「🎤 面试话术」「⚠ 易错点」→ 做末尾自测清单 → 配合《FDE-W7D2-评测题.md》。候选人背景:36 岁,Java + 大数据 + 医疗保险,回答落到"Java 企业 AI 平台"能力,场景用保险知识库 / 特药理赔 Agent。

一、Tool Calling 概览:让模型调你的 Java 方法

1.1 是什么

Tool Calling(工具调用)让 LLM 在对话中"决定调用哪个本地函数、填什么参数",Spring AI 负责把你的 Java 方法暴露成工具描述(JSON Schema)发给模型,模型返回调用请求后,框架本地执行并把结果回灌模型。

模型 → 决定调 tool + 参数 → Spring AI 本地执行 Java 方法 → 结果回灌 → 模型继续生成

1.2 在 Java 企业平台的典型用途

Tool Calling 是 Agent 的"手"——模型负责"想调什么",Spring AI 负责"安全执行 Java 方法并把结果喂回去"。对保险场景意味着:模型可以实时查真实系统,而不是凭记忆编保单号。
Tool Calling 让模型在对话中调用本地 Java 方法:框架把方法暴露成工具描述,模型决定调哪个、填什么参,框架执行后把结果回灌。它是 Agent 的"手",让模型能查真实系统而非瞎编。
① 工具方法有副作用要小心(如创建工单、扣款),模型可能误调,必须加确认/权限/幂等保护。② 工具描述(description)写不好,模型会错误选择工具或填错参数。③ 工具执行结果要裁剪,过长会撑爆上下文(见 s9)。

二、@Tool 注解定义工具

2.1 定义方式

@Service
public class PolicyTools {

    @Tool(description = "根据保单号查询保单基本信息:投保人、险种、生效日、状态")
    public String queryPolicy(@ToolParam(description = "保单号,如 PA2024XXXX") String policyNo) {
        return policyService.getPolicy(policyNo).toJson();
    }

    @Tool(description = "校验某药品是否在特药目录,返回是否覆盖及自付比例")
    public String checkSpecialDrug(@ToolParam(description = "药品通用名") String drugName) {
        return drugCatalogService.check(drugName).toJson();
    }
}

2.2 关键注解

注解作用建议
@Tool标记方法为工具description 写清"何时用、返回什么"
@ToolParam标记参数description 写清格式/示例
@ToolResult给返回值加描述说明结果含义与结构
工具 description 质量直接决定调用准确率——把它当"给模型看的产品文档"写:何时调用、参数格式、返回结构都说清。可用 @JsonClassDescription 给返回 Bean 加描述。
@Tool 标记方法、@ToolParam 描述参数,框架自动把方法签名+描述转成工具 JSON Schema。工具 description 是"给模型看的产品文档",写得好调用才准。

三、ToolCallback 与自动注册到 ChatClient

3.1 ToolCallback

每个 @Tool 方法会被扫描成一个 ToolCallback(含工具名、schema、可执行引用)。Spring AI 提供 MethodToolCallback.builder() 或自动扫描 @Bean 工具类。

3.2 注册方式

// 方式A:自动扫描(@Tool 的 Spring Bean 自动注册)
ChatClient client = ChatClient.builder(chatModel)
        .defaultTools(policyTools, drugTools)  // 直接传工具对象
        .build();

// 方式B:显式 ToolCallback
ToolCallback[] callbacks = ToolCallbacks.from(policyTools, drugTools);
ChatClient client2 = ChatClient.builder(chatModel).defaultTools(callbacks).build();

// 调用时也可临时指定
String r = client.prompt().user("查一下保单 PA2024XXXX").tools(policyTools).call().content();
生产推荐把工具做成独立 Tool 类(职责清晰、可测),用 defaultTools 全局注册通用工具,特定场景用 .tools(...) 临时叠加。注意工具数量别太多(schema 占 token、模型选择困难)。
每个 @Tool 方法被转成 ToolCallback;可用 defaultTools(...) 全局注册或 .tools(...) 临时叠加。工具类独立、职责清晰,工具数量别太多以免占 token 和干扰选择。
① 工具数量爆炸会让模型选错工具且 schema 吃掉大量 token,建议按场景分组、按需注入。② 同名工具/重复注册会冲突,注意 bean 命名。③ 工具抛异常要被框架捕获并转成可回灌的"错误结果",别让异常直接炸掉对话链路。

四、工具调用完整执行流程

  1. 注入:ChatClient 携带工具 schema 请求模型。
  2. 决策:模型返回 tool_calls(工具名 + 参数 JSON),不生成最终文本。
  3. 执行:Spring AI 按名字找到 ToolCallback,本地反射执行 Java 方法。
  4. 回灌:把执行结果作为 tool 角色消息追加进对话历史。
  5. 续生成:模型拿到结果继续生成,直到不再请求工具、输出最终答案。
Prompt+tools → 模型返回 tool_calls → 框架执行 Java 方法 → 结果追加为 tool message → 模型续生成 → 最终答案
这正对应 W2 自研 Agent 的"模型给 action → 执行器执行 → observation 回灌 → 继续思考"。Spring AI 把 W2 要手写的 tool 调度循环封装成了框架能力。
流程里"回灌"这一步框架自动做,但结果可能被截断/脱敏,否则敏感保单数据进模型上下文有合规风险。保险场景建议工具结果只回灌"必要字段"。
完整流程:请求带工具 schema → 模型返回 tool_calls → Spring AI 本地执行 Java 方法 → 结果作为 tool 消息回灌 → 模型续生成。和 W2 自研 Agent 的"action→observation→thought"循环完全对应。

五、ChatMemory:会话记忆抽象

5.1 是什么

ChatMemory 是 Spring AI 对"多轮对话历史存储"的抽象接口,负责按 conversationId 存取 Message 列表。模型本身无状态,记忆靠外部存储维持。

用户消息 + ChatMemory(按 conversationId) → 拼成多轮上下文 → 模型 → 回复存入 ChatMemory

5.2 核心方法

ChatMemory 是"会话状态外置"的标准做法——模型无状态,记忆由平台托管。对保险客服意味着:同一用户的多轮对话能连续,且会话可跨服务实例(用 Redis/JDBC 实现)。
ChatMemory 是 Spring AI 对多轮对话历史存储的抽象接口,按 conversationId 存取 Message 列表。模型无状态,记忆靠外部存储维持,是"会话状态外置"的标准做法。

六、ChatMemory 多种实现(InMemory / Redis / JDBC)

实现存储介质适用注意
InMemoryChatMemoryJVM 内存单机 demo、单实例重启丢失、不跨实例
RedisChatMemoryRedis分布式、多实例生产需设过期、序列化
JdbcChatMemory关系库需持久化审计量大时查询慢、需裁剪
Neo4j/Cassandra各类存储特定需求按生态选

6.1 代码示例

// Redis 实现(生产推荐)
ChatMemory redisMem = RedisChatMemory.builder(redisConnectionFactory).build();
ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(MessageChatMemoryAdvisor.builder(redisMem).build())
    .build();
// 调用时带 conversationId
client.prompt().advisors(a -> a.param(ChatMemory.CONVERSATION_ID, "user-7788"))
       .user("我上次问的特药能报多少?").call().content();
生产几乎都用 Redis/JDBC(跨实例、可持久化、可审计)。InMemory 仅本地调试。选存储要同时考虑:过期策略(防无限增长)、序列化、成本(长会话占 token)。
ChatMemory 有 InMemory(单机 demo)、Redis(分布式生产)、JDBC(审计持久化)等实现。生产用 Redis/JDBC 跨实例,InMemory 只本地调试。要通过 conversationId 关联会话。
① 用 InMemory 部署到多实例会"会话串台/丢失"——生产必须外部存储。② 记忆无限增长会撑爆 token 与成本,必须做窗口裁剪(只取最近 n 条)或摘要压缩。③ 不同用户的 conversationId 必须隔离,否则串号泄露隐私(保险大忌)。

七、与 W2 Tool Calling、W4 Agent 的关系

阶段做了什么W7D2 的位置
W2 Tool Calling讲原理 + 自研工具调度循环Spring AI 是 W2 的"生产级封装"
W4 Agent讲 Agent 架构、Trace 字段、工具编排Spring AI Tool + Memory 是 Agent 的 Java 落地
W7D2用 Spring AI 跑通 Tool + MemoryJava 侧生产实现
W2 我们手写"模型返回 action → 执行器执行 → observation 回灌"循环;Spring AI 把这套循环内建在 ChatClient 里,还解决了"工具有多少个、怎么注册、记忆存哪"的工程问题。W4 的 Agent 架构(Planner/Executor/Memory/Trace)在 Java 侧正是 ChatClient + Tool + ChatMemory + Advisor(Trace) 的组合。
面试链路要串起来:W2 懂原理 → W4 懂 Agent 架构 → W7D2 能落地成 Spring AI 生产代码。这就是"从原理到工程"的完整叙事,对 36 岁平台岗候选人极加分。
W2 讲 Tool Calling 原理 + 自研循环;W4 讲 Agent 架构;W7D2 用 Spring AI 把两者做成了生产级 Java 落地——ChatClient+Tool+ChatMemory+Advisor 组合对应 W4 的 Agent 组件。

八、Advisor 与 Memory 配合(MessageChatMemoryAdvisor)

8.1 如何接

MessageChatMemoryAdvisor 在调用前从 ChatMemory 取出历史注入 prompt,调用后把本轮消息写回。它是 s4 讲过的 Advisor 链的一员。

ChatClient client = ChatClient.builder(chatModel)
    .defaultAdvisors(
        MessageChatMemoryAdvisor.builder(redisMem).build(),  // 记忆注入
        new AuditAdvisor(meterRegistry)                      // Trace 埋点
    ).build();

8.2 顺序

把记忆、RAG、日志、Trace 都做成 Advisor 链,业务方法只写"用户问了什么",治理全在 Advisor。这正是 W7D1 强调的"治理内建"。
用 MessageChatMemoryAdvisor 把 ChatMemory 接进 Advisor 链,调用前注入历史、调用后写回。记忆 Advisor 顺序要在改写/RAG 之前,Trace Advisor 可放最外层。

九、生产注意事项(状态隔离 / 过期 / 成本)

① 别把整段无限历史每次全发——成本爆炸且模型后期"记不住前面"(长上下文也有有效窗口)。② 工具结果回灌别带全量敏感字段,要脱敏/裁剪。③ 记忆和工具结果是两回事:记忆是"对话历史",工具结果是"本轮执行产出",都进上下文但要分别管理。
生产三件事:conversationId 强隔离防串号、记忆设过期+TTL 防无限增长、窗口裁剪控成本。保险场景记忆含隐私要加密存储 + 审计访问。

十、与 W3 会话状态的关系

W3 我们从"会话状态管理"角度讲过多轮对话要保持上下文、状态可能跨多 Agent 步骤、需要持久化。W7D2 的 ChatMemory 是 W3 理念的 Spring AI 落地:W3 谈"为什么需要状态外置 + 怎么隔离",W7D2 给出 ChatMemory 接口和 Redis/JDBC 具体实现。两者一脉相承——W3 是设计原则,W7D2 是 Java 实现。
面试这么串:W3 讲"会话状态的设计原则(外置/隔离/持久化/过期)",W7D2 用 ChatMemory(InMemory/Redis/JDBC)把这些原则变成可插拔实现。评测时若被问"W3 和今天关系",答"W3 是 why + 设计,W7D2 是 how + 实现,ChatMemory 是那个抽象接口"。
W3 讲会话状态的设计原则(外置/隔离/持久化/过期),W7D2 的 ChatMemory 是它的 Java 落地实现。W3 是 why+设计,W7D2 是 how+实现,ChatMemory 就是那个抽象接口。

十一、学习资源(中文 / 官方)

十二、面试达标线①:Spring AI Tool Calling 怎么定义和注册

步骤做法要点
定义@Tool + @ToolParam 注解方法description 写清何时用/参数格式
注册defaultTools(...).tools(...)全局注册 vs 临时叠加
执行框架自动 ToolCallback 执行 + 结果回灌异常要转可回灌错误结果
取结果call().content()模型续生成最终答案
达标线①核心:用 @Tool 定义工具(写清 description/参数)、用 defaultTools 注册到 ChatClient、框架自动执行并回灌结果。工具数量别太多,description 决定调用准确率。

十三、面试达标线②:Chat Memory 接不同存储、与 W3 会话状态的关系

  1. 接不同存储:ChatMemory 是接口,InMemory(单机 demo)、Redis(分布式生产)、Jdbc(审计持久化)都是实现;通过 MessageChatMemoryAdvisor 接进 Advisor 链;调用时用 conversationId 关联。选型看是否跨实例、是否需持久化、成本。
  2. 与 W3 会话状态关系:W3 讲会话状态的"外置/隔离/持久化/过期"设计原则,W7D2 的 ChatMemory 是这些原则的 Java 落地——ChatMemory 接口 = W3 的抽象,Redis/JDBC 实现 = W3 的持久化方案。一脉相承。
  3. 生产要点:conversationId 强隔离防串号、设过期 TTL、窗口裁剪控成本、敏感数据加密存储。

十四、W7D2 自测清单

十五、高频面试题速记卡

Q:@Tool 的 description 有什么用?
框架把它转成工具 JSON Schema 给模型看,决定"何时调、填什么参"。写不清模型会选错工具或填错参。
Q:工具怎么注册到 ChatClient?
defaultTools(...) 全局注册,或 .tools(...) 单次叠加;每个 @Tool 方法被转成 ToolCallback。
Q:工具调用完整流程?
带 schema 请求 → 模型返回 tool_calls → 框架本地执行 Java 方法 → 结果作 tool 消息回灌 → 模型续生成最终答案。
Q:有副作用的工具要注意什么?
模型可能误调,必须加权限校验、幂等保护、人工确认;异常要转成可回灌错误结果而非炸链路。
Q:ChatMemory 为什么需要?
模型无状态,多轮对话历史靠外部存储维持(按 conversationId 存取 Message 列表),是会话状态外置。
Q:InMemory / Redis / Jdbc 怎么选?
InMemory 单机 demo;Redis 分布式生产;Jdbc 需审计持久化。生产用外部存储,且要设过期+裁剪。
Q:W7D2 和 W3 会话状态什么关系?
W3 讲设计原则(外置/隔离/持久化/过期),W7D2 的 ChatMemory 是 Java 落地实现,接口对应抽象、Redis/Jdbc 对应持久化。
Q:记忆无限增长会怎样?
token 成本线性涨、超长丢上下文、隐私堆积。要窗口裁剪(取最近 n 条)+ 过期 TTL + 摘要压缩。
Q:W2 和 W7D2 的关系?
W2 讲 Tool Calling 原理 + 自研调度循环;W7D2 用 Spring AI 把循环内建成框架能力,是生产级封装。
Q:conversationId 为什么必须强隔离?
防不同用户串号泄露隐私(保险大忌),且多实例下必须用外部存储按 id 关联会话。
FDE W7D2 学习手册 · Spring AI Tool Calling 与 Chat Memory(面试级)· 配合《FDE-W7D2-评测题.md》自测
📌 待查★ 重要