概述
功能:
- 跨AI提供商的可移植API:用于聊天、文本到图像和嵌入模型。
- 支持同步和流API选项。还支持下拉访问模型特定功能。
- 跨Vector Store提供商的可移植API,包括同样可移植的新颖的类似SQL的元数据过滤器API。支持8个矢量数据库
- 函数调用。Spring AI使AI模型可以轻松调用
java.util.Function
POJO对象 - AI模型和向量存储的Spring Boot自动配置和启动器
- 数据工程的ETL框架。这为将数据加载到矢量数据库提供了基础,有助于实现检索增强生成模式。
如需使用SNAPSHOT版本,Maven配置添加以下仓库:
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<releases><enabled>false</enabled></releases>
</repository>
<repository>
<id>central-portal-snapshots</id>
<name>Central Portal Snapshots</name>
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
<releases><enabled>false</enabled></releases>
<snapshots><enabled>true</enabled></snapshots>
</repository>
</repositories>
Spring Initializr:https://start.spring.io/
application.yml
配置文件:
spring:
ai:
chat:
memory:
repository:
jdbc:
initialize-schema: nerver
openai:
api-key:
embedding:
options:
model: text-embedding-v4
base-url: https://dashscope.aliyuncs.com/compatible-mode/
chat:
options:
model: qwen-max
vectorstore:
pgvector:
enabled: true
indexType: HNSW
redis:
initialize-schema: true
index-name: custom-index
prefix: custom-prefix
zhipuai:
api-key: ${ZHIPUAI_API_KEY}
mcp:
server:
name: webflux-mcp-server
version: 1.0.0
type: ASYNC
sse-message-endpoint: /mcp/messages
client:
request-timeout: 30s
sse:
connections:
server1:
url: https://mcp.amap.com
sse-endpoint: /sse?key=?
server2:
url: https://mcp-pan/baidu.com
sse-endpoint: /sse?access_token=?
server3:
url: https://mcp-youxuan.baidu.com
sse-endpoint: /mcp/sse?key=?
toolcallback:
enabled: true
stdio:
servers-configuration: classpath:/mcp-servers-config.json
amap:
key: ${AMAP_API_KEY}
代码片段
PromptTemplate template = new PromptTemplate("请用{style}风格解释:{topic}");
Prompt prompt = template.create(Map.of("style", "幽默", "topic", "量子力学"));
@Bean
VectorStore vectorStore(EmbeddingClient embeddingClient) {
return new SimpleVectorStore(embeddingClient);
}
@Resource
private SyncMcpToolCallbackProvider toolCallbackProvider;
var chatClient = chatClientBuilder
.defaultTools(toolCallbackProvider)
.build();
// 实现Tool
@Service
public class WeatherService {
@Tool(description = "Get weather information by city name")
public String getWeather(String cityName) {
}
}
// 注册Tool
@Bean
public ToolCallbackProvider weatherTools(WeatherService weatherService) {
return MethodToolCallbackProvider.builder().toolObjects(weatherService).build();
}
Chat Client,用于简化与AI模型的交互过程,支持同步和反应式编程模型,隐藏诸多底层细节:
- 提示词管理:定制和组装模型的输入(Prompt)
- 响应处理:格式化解析模型的输出(Structured Output)
- 参数选项:调整模型交互参数(ChatOptions)
- 高级功能:整合聊天记忆、函数调用、RAG等能力
Spring AI提供两种方式创建ChatClient:使用自动配置的Builder或编程方式。
@RestController
public class ChatController {
private final ChatClient chatClient;
public ChatController(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
@GetMapping("/chat")
public String chat(String input) {
return this.chatClient.prompt()
.user(input)
.call()
.content();
}
}
禁用自动配置:spring.ai.chat.client.enabled=false
// 通常通过自动装配获取ChatModel实例
ChatModel myChatModel =
// 使用Builder
ChatClient chatClient = ChatClient.builder(myChatModel).build();
// 直接create
ChatClient chatClient = ChatClient.create(myChatModel);
ChatClient的流畅API通过prompt
方法提供三种不同的方式来创建Prompt:
prompt()
:无参方法,允许从头开始构建提示,后续可添加用户消息、系统消息等。chatClient.prompt().user("你好").call().content();
prompt(Prompt prompt)
:接受Prompt
对象参数,允许传入使用非流畅API创建的Prompt
实例。
Prompt myPrompt = new Prompt(List.of(new UserMessage("你好")));
chatClient.prompt(myPrompt).call().content();
prompt(String content)
:便捷方法,直接接受用户文本内容作为参数。
chatClient.prompt("你好").call().content();
ChatResponse
包含完整的响应数据和元数据,如Token使用情况。
entity()
方法还提供一个重载版本,允许传入自定义参数来指导实体转换过程:
record Product(String name, String description, Double price) {}
Product product = chatClient.prompt()
.user("创建一个价格在100元以内的产品")
.call()
.entity(Product.class, EntityPreference.create()
.withFormat(EntityFormat.JSON)
.build());
ChatClient提供两个核心方法来获取响应:
call
:用于同步响应,返回ResponseWithChatClient
对象;stream()
:用于流式响应,返回StreamWithChatClient`对象。
Flux<String> responseStream = chatClient.prompt()
.user("给我讲一个长故事")
.stream()
.content();
默认值:
ChatClient chatClient = ChatClient.builder(chatModel)
.defaultSystem("你是一位专业的Java开发助手,擅长使用Spring框架")
.defaultUser("默认用户消息")
.defaultOptions(options -> options.withTemperature(0.7f))
.defaultResponseFormat(new StructuredResponseFormat<>(MyResponseType.class))
.build();
ToolCallback
之前叫FunctionCallback,升级:
- 术语更准确:从"函数"改为"工具",更符合行业通用术语
- 架构更清晰:分离工具定义与实现,提高复用性
- 功能更强大:支持更灵活的工具注册和调用方式
- 注解驱动:新增
@Tool
注解,开发更便捷
FunctionToolCallback.builder("getWeather", service)
.description("获取天气")
结构化输出
如JSON格式优势:
- 便于程序解析和处理
- 确保数据格式一致性
- 方便与前端或其他服务集成
StructuredOutputConverter
- 在LLM调用前:转换器会向提示词追加格式指令,为模型生成目标输出结构提供明确指导。
- 在LLM调用后:转换器将模型的原始文本输出转换为结构化类型,将其映射为对应的结构化JSON特定的数据结。
StructuredOutputConverter实现类型:接口允许您从基于文本的AI模型输出中获取结构化数据,默认BeanOutConverter实现类
public News generateAsString(String message) {
News news = this.chatClient.prompt()
.user(promptUserSpec -> promptUserSpec.text(message))
.call()
.entity(News.class);
}
@Data
public class News {
private String entity;
private String time;
private String summary;
}
RAG
添加依赖:
implementation 'org.springframework.ai:spring-ai-starter-vector-store-redis:1.0.1'
private final VectorStore vectorStore;
public String similaritySearch(String query) {
SearchRequest request = SearchRequest.builder().query(query).topK(1).build();
List<Document> results = this.vectorStore.similaritySearch(request);
return JSONObject.valueToString(results);
}
或其他向量数据库。
模型
CogView-4:智谱开源文生图模型,支持任意长度的中英双语输入,能够生成在给定范围内的任意分辨率图像。
implementation ‘org.springframework.ai:spring-ai-starter-model-zhipuai:1.0.1’
private final ZhiPuAiImageModel zhiPuAiImageModel;
public String getImage(String imageName) {
ImageResponse response = zhiPuAiImageModel.call(new ImagePrompt(imageName, ZhiPuAiImageOptions.builder().build()));
return response.getResult().getOutput().getUrl();
}
Chat Memory
ChatMemory接口,支持实现不同类型的内存策略,默认MessageWindowChatMemory类
ChatMemoryRepository:专责消息的存储与检索,底层消息存储实现默认实现 InMemoryChatMemoryRepository 类
引入依赖:implementation 'org.springframework.ai:spring-ai-starter-model-chat-memory-repository-jdbc:1.0.1'
,JdbcChatMemoryRepository
配置:
spring.ai.chat.memory.repository.jdbc.initialize-schema=nerver
public ChatClientService(ChatClient.Builder builder,JdbcChatMemoryRepository chatMemoryRepository)
ChatMemory chatMemory = MessageWindowChatMemory.builder()
.chatMemoryRepository(chatMemoryRepository)
.maxMessages(10)
.build();
ChatClient chatClient = builider.defaultAdvisors(MessageChatMemoryAdvisor.builder(chatMemory).build()).build();
chatClient.prompt()
.user("你好")
.advisors(a -> a.param(ChatMemory.CONVERSATION_ID, conversationId))
.call().content();
Advisors
用于拦截、修改和增强AI驱动的交互,封装常见的生成式AI模式,转换发送到和接收自LLMs的数据,在各种模型和用例之间提供可移植性。
优势:
- 封装常见模式:将RAG、内容安全检查等模式封装为可重用组件
- 数据转换:在请求发送前和响应接收后修改和增强数据
- 跨模型可移植性:编写一次Advisor,可用于多种AI模型和用例
- 可观测性:Advisors参与可观测性堆栈,支持指标和跟踪功能
工作原理类似于AOP:
- 在AI交互的请求和响应阶段拦截处理流程
- 可以访问和修改请求内容和上下文
- 可以访问和修改响应内容和上下文
- 多个Advisors可以组成处理链,按特定顺序执行
API
- Advisor:基础接口,定义名称和顺序等基本特性
- CallAdvisor:用于非流式场景的接口
- StreamAdvisor:用于流式场景的接口
- BaseAdvisor:同时继承CallAdvisor和StreamAdvisor的接口
- BaseChatMemoryAdvisor:继承BaseAdvisor的接口
- MessageChatMemoryAdvisor:将记忆作为消息集合添加到prompt
- PromptChatMemoryAdvisor:将记忆整合到prompt的系统文本中
- SafeGuardAdvisor:用于防止模型生成有害或不适当的内容
- ChatModelCallAdvisor:
- ChatModelStreamAdvisor:
- SimpleLoggerAdvisor:日志记录
继承关系图
其他相关API:
- ChatClientRequest:请求
- ChatClientResponse:响应
- CallAdvisorChain:
- StreamAdvisorChain:
Advisors的执行顺序由getOrder()
方法决定:
- 较低的order值优先执行
- Advisor链按照栈的方式工作:第一个加入链的Advisor最先处理请求;也是最后处理响应的Advisor
- 高优先级的Advisor先执行请求处理,后执行响应处理
- 如果多个Advisor具有相同的order值,它们的执行顺序不保证
Advisors支持两种处理模式:
- 非流式处理:处理完整的请求和响应,实现
CallAdvisor
接口,重写adviseCall()
方法; - 流式处理:处理连续的请求和响应流,实现
StreamAdvisor
接口,重写adviseStream()
方法,使用响应式编程概念(如Flux)。
示例:
// 创建带有Advisors的ChatClient
var chatClient= ChatClient.builder(chatModel)
.defaultAdvisors(
MessageChatMemoryAdvisor.builder(chatMemory).build(), // 聊天记忆顾问
QuestionAnswerAdvisor.builder(vectorStore).build() // RAG顾问
)
.build();
// 设置运行时参数
String response= chatClient.prompt()
.advisors(advisor -> advisor.param(ChatMemory.CONVERSATION_ID, "678"))
.user(userText)
.call()
.content();
Prompt Engineering
几个参数:
Temperature:控制模型响应的随机性或创造力
- 较低的值:
0.0-0.3
,更具确定性、更集中的响应。适用于事实类问题、分类或对一致性要求严格的任务; - 中等值:
0.4-0.7
,在确定性和创造力之间取得平衡。适用于一般用例; - 较高值:
0.8-1.0
,更具创造力、多样化且可能带来惊喜的响应。适用于创意写作、头脑风暴或生成多样化选项。
- 较低的值:
MaxTokens:限制模型在其响应中可生成Token数量
- 较低值:适用于单个词、短语或分类标签。
- 中等值:适用于段落或简短解释。
- 较高值:适用于长篇内容、故事或复杂解释。
采样控制:两个参数,允许对生成过程中的Token选择进行细粒度控制。
- Top-K:将Token选择限制在K个最有可能的下一个Token中。较高值(如40-50)会引入更多多样性
- Top-P:核采样,从累积概率超过P的最小Token集合中动态选择。常见的值如 0.8-0.95。
Role Prompting
public void rolePrompting(ChatClient chatClient) {
String result = chatClient
.prompt()
.system(s -> s.text("你是一位经验丰富的Java开发专家,专注于Spring框架。请以简洁、专业的方式回答问题,并提供代码示例。"))
.user(u -> u.text("如何在Spring Boot应用中实现基本的认证功能?"))
.call()
.content();
}
Self-Consistency通过生成多个独立的推理路径,然后选择最一致的答案来提高复杂推理任务的准确性。
public void selfConsistencyPrompting(ChatClient chatClient) {
// 生成多个推理路径
List<String> responses = newArrayList<>();
for (int i = 0; i < 3; i++) {
String response = chatClient
.prompt()
.user(u -> u.text("""
问题: 小明有5个苹果,他给了小红2个,又从小华那里得到3个,然后他又吃了1个。小明现在有多少个苹果?
让我们一步步思考得出答案。
"""))
.options(ChatOptions.builder().temperature(0.7).build()) // 使用较高温度以获得多样化的推理路径
.call()
.content();
responses.add(response);
}
}
解读:上面的让我们一步步思考得出答案
正体现Chain-of-Thought Prompting。
MCP
MCP能力:
- 标准化交互协议:统一AI模型与外部工具的通信方式
- 多传输支持:STDIO/HTTP/SSE全兼容,适应本地或云端部署
- 会话管理:v0.8.0全新升级的会话架构
MCP Java SDK采用清晰的三层设计,可轻松集成到现有系统:
- 客户端/服务端层
McpClient
:搞定协议协商、工具调用McpServer
:暴露工具接口,管理资源URI- 支持同步/异步调用,兼容HTTP长连接和进程间通信
- 会话层:通过
McpSession
管理对话状态,多轮交互不再丢上下文 - 传输层:JSON-RPC消息一键序列化,三种传输任选:
- STDIO:本地进程间通信
- HTTP SSE:Servlet/WebFlux双版本支持
- Reactive流:WebFlux实现高并发
server模块引入依赖:
implementation 'org.springframework.ai:spring-ai-starter-mcp-server-webflux:1.0.1'
implementation 'org.springframework.ai:spring-ai-starter-mcp-server:1.0.1'
implementation 'org.springframework.ai:spring-ai-starter-mcp-server-webmvc:1.0.1'
client引入依赖:
implementation 'org.springframework.ai:spring-ai-starter-mcp-client:1.0.1'
implementation 'org.springframework.ai:spring-ai-starter-mcp-client-webflux:1.0.1'
MCP Server
诸如:
- 高德MCP Server:提供全场景覆盖的地图服务,包括地理编码、逆地理编码、IP定位、天气查询、骑行路径规划、步行路径规划、驾车路径规划、公交路径规划、距离测量、关键词搜索、周边搜索、详情搜索等。
- 百度网盘MCP:核心API现已全面兼容MCP协议。涵盖用户信息、获取文件信息、文件上传、文件管理、文件搜索等。 开发者仅需简单配置,即可快速接入百度网盘服务,实现文件上传、文件管理等能力,大幅降低开发者调用网盘服务门槛,显著提升开发者的开发效率。
- 百度优选MCP:提供MCP工具列表包含8个核心API,涵盖参数对比、品牌排行、商品检索、交易等。为用户提供全维度对比决策助手,实时品牌天梯榜单,轻松获取全网相关SPU与优质低价商品链接等能力。
- Playwright MCP:微软推出的现代化跨浏览器自动化测试工具,支持Chromium、Firefox和WebKit,提供高速、可靠的端到端测试能力,适用于Web应用开发和持续集成。结合LLM能够无障碍与网页进行交互,从而实现智能浏览器页面操作。
- Office-Word-MCP:用于创建、读取、编辑和格式化Microsoft Word文档。主要操作能力如下:创建表格、添加不同级别的标题、插入段落可选样式;格式化加粗、斜体、下划线、颜色和字体属性、搜索和替换;边框和样式格式化表格、格式表头行、应用单元格阴影和自定义边框。
- antvis/mcp-server-chart:用于生成可视化图表的,目前支持 15+ 种图表:
- 条形图、饼图、 柱形图、 折线图
- 鱼骨图、思维导图、流程图、
- 直方图、线型图、树形图、网络图
- 雷达图、二维散点图、词语图、区域图表
- MySQL MCP:提供SQL语句查询数据库的能力:
- execute_query :支持select查询、show展示、describe描述;
- get_table_info:获取数据表的详细结构信息;
- list_tables:列出数据库中的所有数据表。
- Excel-MCP:基于MCP的文件处理服务器,提供读取、写入和分析Excel文件的功能:
- 读取Excel文件:获取工作表列表,读取特定工作表的数据,读取所有工作表的数据;
- 写入Excel文件:创建新的Excel文件,向特定工作表写入数据,支持多工作表;
- 分析Excel结构:分析工作表结构,将结构导出到新文件
- Nacos MCP Router:一个基于MCP官方标准SDK实现的的MCP Server,提供一组工具,提供推荐、分发、安装及代理其他MCP Server的功能,帮助用户更方便地使用MCP Server服务。
安装较新版Nacos,打开管理后台,MCP管理,创建MCP Server。 - @Joooook/12306-mcp:提供简单的API接口,允许用户搜索12306的车票。
- HowToCooke MCP,让AI助手能够为你推荐菜谱、规划膳食,解决"今天吃什么"的世纪难题!
- 查询全部菜谱:获取所有可用菜谱数据,做菜百科全书
- 根据分类查询菜谱:按照分类筛选菜谱,想吃水产?早餐?荤菜?主食?一键搞定!
- 智能推荐膳食:根据你的忌口、过敏原和用餐人数,为你规划整整一周的美味佳肴
- 不知道吃什么:选择困难症福音!根据人数直接推荐今日菜单,再也不用纠结了
- mcp-server-weread:支持将微信读书的书籍、笔记和划线数据提供给支持MCP的LLM:
- 从微信读书获取书架信息;
- 搜索书架中的图书;
- 获取图书的笔记和划线;
- 支持按章节组织笔记和划线。
- Fetch MCP:从互联网上抓取URL并将其内容作为Markdown文件,接口参数:
url
: 要抓取的URLmax_length
:返回的最大字符数,默认5000start_index
:字符索引开始提取内容,默认0raw
:获取未经MarkDown转换的原始内容,默认false
{
"mcpServers": {
"playwright": {
"command": "npx.cmd",
"args": [
"@playwright/mcp@latest"
]
},
"nacos-mcp-router": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"--network",
"host",
"-e",
"NACOS_ADDR=localhost:8848",
"-e",
"NACOS_USERNAME=nacos",
"-e",
"NACOS_PASSWORD=nacos",
"-e",
"TRANSPORT_TYPE=stdio",
"nacos/nacos-mcp-router:latest"
]
},
"amap-maps": {
"command": "npx",
"args": [
"-y",
"@amap/amap-maps-mcp-server"
],
"env": {
"AMAP_MAPS_API_KEY": ""
}
},
"mysql": {
"command": "npx",
"args": [
"mysql-mcp-server"
],
"env": {
"MYSQL_HOST": "127.0.0.1",
"MYSQL_PORT": "3306",
"MYSQL_USER": "root",
"MYSQL_PASSWORD": "root",
"MYSQL_DB": "demo"
}
},
"excel": {
"command": "npx",
"args": [
"--yes",
"@zhiweixu/excel-mcp-server"
],
"env": {
"fileAbsolutePath": "D:\data\excel"
}
},
"12306-mcp": {
"command": "npx",
"args": [
"-y",
"12306-mcp"
]
},
"word-document-server": {
"command": "uvx",
"args": [
"--from",
"office-word-mcp-server",
"word_mcp_server"
]
},
"fetch": {
"command": "uvx",
"args": [
"mcp-server-fetch"
]
},
"mcp-server-chart": {
"command": "npx.cmd",
"args": [
"-y",
"@antv/mcp-server-chart"
]
}
}
}