Spring AI 解决了 AI 集成的根本难题:将企业数据和 API 与 AI 模型连接起来。

聊天客户端 API (ChatClient )
发起对模型的调用和响应
- 创建:其中可以通过bean来注入创建好的chatClient
可以使用@Qualifier注解,使用多模型,创建多chatClient - ChatClient 响应
-
- 多种格式,包括flux
- 提示模板
TemplateRenderer 作为模板引擎 - call返回值: 返回相应对象或字符串
- stream返回值:多种flux对象
- advisor
-
- Advisor API 为 Spring 应用中的 AI 驱动交互提供灵活强大的拦截、修改和增强能力。
interface AdvisorSpec {
AdvisorSpec param(String k, Object v);
AdvisorSpec params(Map<String, Object> p);
AdvisorSpec advisors(Advisor... advisors);
AdvisorSpec advisors(List<Advisor> advisors);
}ChatClient.builder(chatModel)
.build()
.prompt()
.advisors(
MessageChatMemoryAdvisor.builder(chatMemory).build(),
QuestionAnswerAdvisor.builder(vectorStore).build()
)
.user(userText)
.call()
.content(); -
聊天记忆:
ChatMemory 接口定义了聊天对话存储机制,当前内置实现MessageWindowChatMemory, 包括jdbc在内的多种存储方案
Advisor API
执行流程


-
实现示例,定义一个LoggerAdvisor
public class SimpleLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
@Override public AdvisedResponse aroundCall(AdvisedRequest advisedRequest, CallAroundAdvisorChain chain) { logger.debug("BEFORE: {}", advisedRequest); AdvisedResponse advisedResponse = chain.nextAroundCall(advisedRequest); logger.debug("AFTER: {}", advisedResponse); return advisedResponse; } @Override public Flux<AdvisedResponse> aroundStream(AdvisedRequest advisedRequest, StreamAroundAdvisorChain chain) { logger.debug("BEFORE: {}", advisedRequest); Flux<AdvisedResponse> advisedResponses = chain.nextAroundStream(advisedRequest); return new MessageAggregator().aggregateAdvisedResponse(advisedResponses, advisedResponse -> logger.debug("AFTER: {}", advisedResponse)); }
}
Prompt

-
主要角色
System 角色:指导 AI 的行为和响应风格,设定 AI 解释和回复输入的参数或规则,类似于在开始对话前向 AI 提供指令。
User 角色:代表用户的输入 --- 包括问题、命令或对 AI 的陈述。该角色构成 AI 响应的基础,具有根本重要性。
Assistant 角色:AI 对用户输入的响应,不仅是答案或反应,更对维持对话流至关重要。通过追踪 AI 之前的响应(其 "Assistant Role" 消息),系统确保连贯且上下文相关的交互。助手消息也可能包含函数工具调用请求信息 --- 这是 AI 的特殊功能,在需要时执行计算、获取数据等超越对话的特定任务。
Tool/Function 角色:专注于响应工具调用类助手消息,返回附加信息。
PromptTemplate
PromptTemplate promptTemplate = PromptTemplate.builder()
.renderer(StTemplateRenderer.builder().startDelimiterToken('<').endDelimiterToken('>').build())
.template("""
Tell me the names of 5 movies whose soundtrack was composed by <composer>.
""")
.build();
String prompt = promptTemplate.render(Map.of("composer", "John Williams"));
PromptTemplate promptTemplate = new PromptTemplate("Tell me a {adjective} joke about {topic}");
Prompt prompt = promptTemplate.create(Map.of("adjective", adjective, "topic", topic));
return chatModel.call(prompt).getResult();
TOOlS
-
示例
class DateTimeTools {
@Tool(description = "Get the current date and time in the user's timezone") String getCurrentDateTime() { return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString(); } @Tool(description = "Set a user alarm for the given time, provided in ISO-8601 format") void setAlarm(String time) { LocalDateTime alarmTime = LocalDateTime.parse(time, DateTimeFormatter.ISO_DATE_TIME); System.out.println("Alarm set for " + alarmTime); }
}
ChatModel chatModel = ...
String response = ChatClient.create(chatModel)
.prompt("Can you set an alarm 10 minutes from now?")
.tools(new DateTimeTools())
.call()
.content();System.out.println(response);

- 创建tools的两种方式, tools注解,和通过MethodToolCallback的编程式配置
MCP

-
mcp client
-
mcp server