Spring AI 全模块 API 字典一览(1.1.0 版)

定位 :这是一份全量字典 ------§1~§12 按模块收录实战项目用到的(和它依赖的)全部 Spring AI API:方法签名、传参、返回值、真实用例。

用法 :写代码卡住 → Ctrl+F12 看类全貌 → 翻本文对签名;每条尽量附实战用例(以类名标注),没标的是官方通用 API。

版本 :Spring AI 1.1.0 + Spring AI Alibaba 1.1.2.0 + Boot 3.5.6 + Java 21;模型接入走 spring-ai-starter-model-openai(DashScope 兼容模式)。


§1 模型接入:ChatModel 层

配置入口 (application.yml):spring.ai.openai.api-key / base-url / chat.options.model → starter 自动装配 ChatModel Bean,任何组件 @Autowired 直用。

ChatModel 方法 传什么 返回什么 实战用例
call(String message) 一句话 String 纯文本 PlanExecuteAgent
call(Message... messages) 若干条消息 String ---(少用)
call(Prompt prompt) Prompt 对象 ChatResponse ContextCompactor
stream(Prompt prompt) Prompt Flux<ChatResponse> ---
stream(String message) 一句话 Flux<ChatResponse> ---

ChatResponse 内部字段解剖(响应侧其实只有两层包装):

text 复制代码
ChatResponse
├─ generations : List<Generation>      一般只取第一个 → getResult()
│    └─ Generation
│         ├─ output  : AssistantMessage   ← 模型本轮说的话
│         │    ├─ text      : String            正文(getText())
│         │    └─ toolCalls : List<ToolCall>    想调的工具getToolCalls(),可为 null/空
│         └─ metadata : ChatGenerationMetadata
└─ metadata : ChatResponseMetadata      token 用量(usage)、id 等
  • 快捷链:response.getResult().getOutput().getText()(见 TemplateStrategy)
  • getResults() 返回 List<Generation>(多候选时用,一般只用 getResult)
  • 判空三连 :chunk / getResult() / getOutput() 都可能为 null(WebSearchReactAgent 里就是这么防的;流式里另加 .filter(Objects::nonNull))

§2 Prompt 与 Message 家族

请求侧内部字段解剖 ------先纠正一个常见误解:Prompt 没有单独的 system/user/assistant 字段 。它只有两个字段:一个消息列表 + 一个参数对象;System/User/Assistant 是列表里每个元素的角色类型:

text 复制代码
Prompt
├─ instructions : List<Message>     ← 字段1:消息列表,顺序 = 模型看到的顺序
│    ├─ [0] SystemMessage        (MessageType.SYSTEM)    人设/规则 ------ 通常一条,放最前
│    ├─ [1] UserMessage          (MessageType.USER)      用户说的话
│    ├─ [2] AssistantMessage     (MessageType.ASSISTANT) 模型上一轮的回答(多轮时)
│    └─ [3] ToolResponseMessage  (MessageType.TOOL)      工具执行结果(ReAct 时)
└─ options : ChatOptions            ← 字段2:参数,可为 null(温度/工具都藏在这)
  • Message 是接口,只有 4 个实现类 ;每个实现用 getMessageType() 报告自己的角色,枚举 MessageType = SYSTEM / USER / ASSISTANT / TOOL
  • 判断一条消息是谁的:instanceof 或 getMessageType()(TokenEstimator 里用的是 instanceof)
  • 发给模型时,每条消息序列化成 {"role":"system|user|assistant|tool", "content":"..."}------curl/F12 里看到的 JSON 就是这么来的;"角色"只是消息上的一个标注字段
  • 多轮对话的真相:所谓记忆,就是每次把 0~n 全量重放、只追加本轮新消息,2 那种 AssistantMessage 就是从 ChatMemory 里回灌的历史回答
类 怎么创建 角色 实战用例
SystemMessage new SystemMessage(String) 人设与规则,每轮单独加、不进记忆 WebSearchReactAgent
UserMessage new UserMessage(String) 或 builder().text(...).build() 用户输入 FileReactAgent
AssistantMessage new AssistantMessage(String);带工具时 builder().toolCalls(...).build() 模型回复(读取或回填) SimpleReactAgent / WebSearchReactAgent
ToolResponseMessage builder().responses(List<ToolResponse>).build() 工具执行结果回填 WebSearchReactAgent
Prompt 见下方构造器全表 消息+选项的打包 PlanExecuteAgent

Prompt 构造器全表(5 个重载) ------它内部只有两个字段:instructions(消息列表)和 options(参数,可为 null),所以所有写法殊途同归:

构造器 说明
new Prompt(String contents) 一句话,内部自动包成单条 UserMessage
new Prompt(String contents, ChatOptions options) 一句话 + 参数
new Prompt(Message... messages) 可变参数 ≡ new Prompt(List.of(m1, m2))
new Prompt(List<Message> messages) 消息列表(实战项目最常用,见 PlanExecuteAgent)
new Prompt(List<Message> messages, ChatOptions options) 列表 + 参数------工具、温度都从这进

读回:prompt.getInstructions() → List<Message>;prompt.getOptions() → ChatOptions(可能为 null)。

三种"发消息"最终汇成同一个 Prompt :

chatModel.call("你好") ≡ chatModel.call(new Prompt("你好")) ≡ chatClient.prompt().user("你好").call().content()。

区别只在谁帮你包装:ChatClient 帮你包消息;要塞 options 就走 Prompt 双参构造或 .options()。

两个关键 record(不可变数据载体):

java 复制代码
AssistantMessage.ToolCall(id, type, name, arguments)   // 访问器 id() / name() / arguments()
// arguments 是 JSON 字符串,流式下会跨 chunk 分片(见 §5)
ToolResponseMessage.ToolResponse(id, name, responseData) // id 必须原样回流配对(WebSearchReactAgent)
  • 多模态 :UserMessage.builder() 挂 Media(图片理解,见 FileManageService)
  • 实战惯例 :XML 风格标签包裹字段,帮模型识别边界:"<question>" + q + "</question>"、<fileid>(见 FileReactAgent)

§3 ChatOptions:每次调用的旋钮

类型 适用 备注
ChatOptions 通用参数 model / temperature / topP / maxTokens / stopSequences
ToolCallingChatOptions 通用参数 + 工具四件套 实战项目全 Agent 用它(见 WebSearchReactAgent)
OpenAiChatOptions 等 厂商专用参数 示例项目未直接用

ToolCallingChatOptions.builder() 全方法:

工具相关(放链式前面) 通用参数(放后面)
toolCallbacks(ToolCallback...) model(String)
toolNames(String...) temperature(Double)
internalToolExecutionEnabled(Boolean) maxTokens(Integer)
toolContext(Map) topP / topK / stopSequences
  • 链式顺序坑 :工具方法返回工具 Builder,通用方法返回通用 Builder------先工具后通用怎么写都不断,反过来可能断
  • 唯一传入口 :new Prompt(messages, options) 第二参数------忘传 = 全白设
  • internalToolExecutionEnabled(false) 是实战项目的灵魂开关:关掉框架自动执行工具,自己接管循环(§5)

§4 ChatClient:高层流式 API

获取 ChatClient 的三种方式:

方式 签名 场景
快速创建 ChatClient.create(chatModel) 不需要预设任何默认值
Builder(实战项目主用) ChatClient.builder(chatModel) → 返回 ChatClient.Builder 预设默认 system/选项/工具后 build()
派生 existing.mutate() → 返回 ChatClient.Builder 保留现有默认值、微调后重建(见 EmbeddingService)

ChatClient.Builder 全方法 (每个都返回 Builder 本身,可任意链式,build() 收口):

方法 作用
defaultSystem(String) 全局系统提示(另有 Consumer 重载:s -> s.text(...).param(...))
defaultUser(String) 全局用户消息模板
defaultOptions(ChatOptions) 默认参数------实战项目在这塞了 ToolCallingChatOptions
defaultToolCallbacks(ToolCallback...) / (List<ToolCallback>) / (ToolCallbackProvider) 默认工具
defaultToolNames(String...) 只放行指定名字的工具
defaultAdvisors(Advisor...) / (List<Advisor>) 默认拦截器
build() 产出 ChatClient 实例

prompt() 返回的请求 spec ------每次请求可覆盖默认值,不传就用 Builder 预设(WebSearchReactAgent 用了 .messages):

方法 作用
.messages(List<Message>) 直接塞消息列表(实战项目主链路)
.system(String) / .user(String) 临时设一条 system / user 消息
.options(ChatOptions) 本次请求参数(覆盖 defaultOptions)
.toolCallbacks(...) / .toolNames(...) 本次请求的工具
.toolContext(Map<String, Object>) 给工具透传上下文
.advisors(Advisor...) 本次请求的拦截器

请求-终端两段式:

java 复制代码
chatClient.prompt()                 // 开始一次请求(进入请求 spec)
    .messages(messages)             // 组装本次请求
    .stream()                       // 或 .call() ------ 进入终端 spec
    .chatResponse()                 // → Flux<ChatResponse>
终端调用 返回 场景
.call().content() String 一次性拿文本
.call().entity(Class) Java 对象 结构化输出一步到位(§7)
.call().chatResponse() ChatResponse 要元数据时
.stream().content() Flux<String> 流式纯文本
.stream().chatResponse() Flux<ChatResponse> 实战主链路:要拿工具调用(见 WebSearchReactAgent)
  • chatClient.mutate():从现有 client 派生新 client,不重建默认配置(见 EmbeddingService)
  • 两套怎么选:一次性调用用 ChatModel 直调(简单);Agent 主链路用 ChatClient(可挂默认选项/工具/Advisor)

§5 工具调用(Tool Calling)

四步全链路:

步骤 API 实战用例
① 声明工具 方法上 @Tool(description="...") + 参数 @ToolParam(description="...") ---
② 注册 ToolCallbacks.from(Object... sources) → ToolCallback[](扫 @Tool 方法) AgentController
③ 交给模型 ToolCallingChatOptions.builder().toolCallbacks(tools).internalToolExecutionEnabled(false) WebSearchReactAgent
④ 手动执行 callback.call(argsJson) → String(重载带 ToolContext) WebSearchReactAgent

手动执行全套 API(以下用例均出自 WebSearchReactAgent 的手动 ReAct 循环):

API 作用
output.getToolCalls() 模型要用的工具列表
AssistantMessage.builder().toolCalls(list).build() 先回填模型意图
callback.call(tc.arguments()) 执行(参数就是 JSON 串,别自己再解析)
new ToolResponse(id, name, result) 结果按 id 配对
ToolResponseMessage.builder().responses(list).build() 再回填结果 → 下一轮
callback.getToolDefinition().name() 按名字找工具

流式特有坑 :工具参数 JSON 会跨 chunk 分片 ,必须按 id() 合并拼接(WebSearchReactAgent 的 mergeToolCall);阻塞版循环用 call() 没这个问题。

错误处理铁律 :工具抛异常也要回填同 id 的错误 ToolResponse,否则下一轮可能被模型接口拒绝。

外部工具(MCP) :Tavily 搜索经 MCP 协议接入,转换成同一套 ToolCallback(§10),与本地工具无差别合并(示例项目自写 ToolMergeUtils.mergeTools,见 AgentController)。

§6 ChatMemory:跨请求记忆

API 作用 实战用例
MessageWindowChatMemory.builder().maxMessages(n).build() 滑动窗口记忆 BaseAgent
add(String conversationId, Message) 追加一条 BaseAgent
add(String, List<Message>) 批量追加 ---
get(String conversationId) 取窗口内全部历史 BaseAgent
clear(String conversationId) 清空会话 ---

MessageWindowChatMemory 内部结构 :一个 ChatMemoryRepository(默认 InMemoryChatMemoryRepository------本质是个内存 Map,存所有会话的全部消息)+ maxMessages(读取时只裁最近 n 条返回)。这解释了"跨请求但不跨重启"这个结论:会话数据住在内存 Map 里,应用一停就没了。想要跨重启:换 JdbcChatMemoryRepository,或像示例项目一样自己从 MySQL 回灌(见 BaseAgent)。Builder 链只有两步:MessageWindowChatMemory.builder().maxMessages(30).build()。

  • conversationId 是隔离键:不同会话互不可见
  • 两层分工 :内存 ChatMemory 管"喂模型的上下文",跨重启靠示例项目手写的 MySQL 回灌------createPersistentChatMemory 从会话表把历史 add 回去(BaseAgent 实现,AgentController 调用)

§7 结构化输出

API 作用 实战用例
new BeanOutputConverter<T>(Class) 简单类型 PptIntentRecognizer
new BeanOutputConverter<T>(new ParameterizedTypeReference<List<T>>() {}) 泛型集合必须用这个 PlanExecuteAgent / BaseAgent
.getFormat() 生成 JSON 格式约束,拼进提示词 PlanExecuteAgent
.convert(String json) 模型输出 → Java 对象 PptIntentRecognizer
MapOutputConverter / ListOutputConverter 简单结构 ---
chatClient.call().entity(Class) ChatClient 一步到位(内部就是 BeanOutputConverter) ---

实战项目用到的转换类型:List<PlanTask>(计划)、CritiqueResult(自评)、PptIntentResult(意图)、PptSchema(PPT 结构)。

§8 流式三件套:Flux / Sinks / Schedulers

Flux 操作符(按实战项目出场频率):

操作符 一句话 实战用例
map 逐元素转换 取文本
filter 丢弃 null 块 ---
doOnNext 旁路观察(累积/解析) WebSearchReactAgent
doOnComplete 正常结束收尾(存记忆在这) WebSearchReactAgent
doOnError / doOnCancel 出错 / 用户点停止 WebSearchReactAgent
doFinally 无论怎么结束都执行(存库) WebSearchReactAgent
subscribeOn(Schedulers.boundedElastic()) 切换执行线程------阻塞代码必须挪到弹性线程 ---
publishOn(Schedulers.boundedElastic()) 切换下游处理线程 WebSearchReactAgent
collectList() / block() 收齐/阻塞------只允许在 boundedElastic 上 ---

Sinks(手动往流里塞数据):

java 复制代码
Sinks.Many<String> sink = Sinks.many().unicast().onBackpressureBuffer();
sink.tryEmitNext(event);    // 逐条塞事件
sink.tryEmitComplete();     // 收口
return sink.asFlux();       // 交给 controller

SSE 产出口 :@GetMapping(produces = "text/event-stream;charset=UTF-8") 返回 Flux<String> → Spring 自动把每个元素包成一条 data:... 事件(见 AgentController)。忘写 produces = 不再是流。

§9 RAG 向量库(PGVector)

建库(按表名动态建库的工厂):

java 复制代码
PgVectorStore.builder(jdbcTemplate, embeddingModel)
    .distanceType(PgVectorStore.PgDistanceType.COSINE_DISTANCE)   // 余弦距离
    .indexType(PgVectorStore.PgIndexType.HNSW)                    // 索引类型
    .removeExistingVectorStoreTable(false)
    .build()
    .afterPropertiesSet();   // 触发表/索引初始化(不存在则自动建)

检索四件套(EmbeddingService,文件问答的向量检索路径):

API 作用
vectorStore.similaritySearch(SearchRequest) 相似检索 → List<Document>
SearchRequest.builder().query(q).topK(5).filterExpression(f).build() 查询条件;SearchRequest 只有 4 个字段:query / topK / similarityThreshold(0~1,越低召回越多) / filterExpression,示例项目用了其中 3 个
new FilterExpressionBuilder().eq("fileid", fileId).build() 元数据过滤(只搜本文件)
Document.getId() / getText() / getScore() 取内容(id 去重)

写入 :vectorStore.add(List<Document>)(上传文件时入库)。

查询扩展 (进阶,Multi-Query):chatClientBuilder(chatClient.mutate()).numberOfQueries(3).includeOriginal(true).build() → expand(query) → List<Query>,一个问题变三个检索视角(见 EmbeddingService)。

EmbeddingModel :embed(String) / embed(Document)------通常被 VectorStore 内部自动调用,业务代码不直调。

配置键 :embeddings.store.host / port / database / user / password(application.yml)。

§10 MCP 客户端(接外部工具)

Tavily 搜索接入三件套(AgentController,MCP 客户端侧):

步骤 API
传输层 HttpClientStreamableHttpTransport.builder(url).requestBuilder(带 Authorization 头).build()
客户端 McpClient.sync(transport).requestTimeout(Duration.ofSeconds(300)).build() → McpSyncClient
握手 client.initialize()
变成本地工具 SyncMcpToolCallbackProvider.builder().mcpClients(List.of(tavilyMcp)).build().getToolCallbacks() → ToolCallback[]

转换后与本地工具完全同构 ------这就是"工具统一抽象"的价值。MCP 服务端的搭建不在本文范围(常见传输方式:stdio / SSE / Streamable HTTP)。

§11 Advisor 扩展点

  • 概念:挂在 ChatClient 调用链上的拦截器,可改请求、改响应、加记忆、打日志
  • 接口:org.springframework.ai.chat.client.advisor.api.Advisor
  • 挂载:ChatClient.Builder.defaultAdvisors(advisors)------示例项目当前传空列表,纯扩展位 ;细粒度挂载用 .prompt().advisors(...)
  • 常见内置:SimpleLoggerAdvisor(请求日志)、MessageChatMemoryAdvisor(记忆托管给 ChatClient)------示例项目选择手动管理记忆,没有启用

§12 application.yml 配置键总表(示例项目)

键 管什么
spring.ai.openai.api-key / base-url / chat.options.model 模型接入(DashScope 兼容模式)
tavily.api-key / tavily.mcp-url 搜索工具(MCP)
grsai.nanobanana.api-key 图像生成
embeddings.store.* PGVector 向量库连接
minio.* 文件存储
skills.directory 技能目录
spring.datasource.* / spring.data.redis.* MySQL / Redis 基础设施
相关推荐
程序员果子1 小时前
Ontology
大数据·人工智能·智能体·ontology·本体
用户24101505702081 小时前
6岁小朋友一句话,一个dsh智能体,一个deepseek4.1大模型,一款水浒游戏
人工智能
AI小百科1 小时前
AI 音乐生成:不会乐器也能出一首歌
人工智能
老马识码1 小时前
WorkBuddy 的专家和专家团是怎么组织的
人工智能·agent
呆萌很1 小时前
深度学习中检测、识别、感知区别
人工智能·深度学习
像风一样自由20201 小时前
3.Dockerfile如何构建一个Python算法镜像
开发语言·人工智能·python·大模型
宝哥聊编程2 小时前
主流 Agent 平台对比:Coze、Dify、飞书、扣子、OpenClaw 落地实操手册
前端·人工智能·飞书
sunzy_泽阳2 小时前
《Spring Ai 2.1 + LangGraph4j》系列教程(上):从零建项目到可恢复的 Java Graph
人工智能·agent
武天旭2 小时前
AI安全--AI大模型的关键技术组成
人工智能·深度学习·安全·机器学习