首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Spring AI系列之核心组件:ChatClient、Prompt 与 Advisor

Spring AI系列之核心组件:ChatClient、Prompt 与 Advisor

作者头像
SmileNicky
发布2026-03-15 08:27:54
发布2026-03-15 08:27:54
1590
举报
文章被收录于专栏:Nicky's blogNicky's blog

Spring AI系列之核心组件:ChatClient、Prompt 与 Advisor

一、ChatClient:流式 API 的优雅入口

ChatClient 是 Spring AI 提供的高阶客户端,采用**构建者模式(Builder Pattern)**设计,支持链式调用,极大地简化了 Prompt 构建和响应处理流程。

1.1 核心架构
Spring AI ChatClient 架构
Spring AI ChatClient 架构

*图:Spring AI ChatClient 整体架构图 *

ChatClient 位于应用层与 Chat Model 之间,封装了复杂的 HTTP 调用细节,提供了统一的 API 接口。

1.2 两种创建方式

方式一:配置类注入(推荐)

代码语言:javascript
复制
@Configuration
public class ChatClientConfig {
    
    @Bean
    ChatClient chatClient(ChatClient.Builder builder) {
        return builder
            .defaultSystem("你是专业的技术助手")  // 设置全局系统消息
            .build();
    }
}

方式二:构造函数注入

代码语言:javascript
复制
@RestController
public class ChatController {
    private final ChatClient chatClient;

    // Spring 会自动注入 Builder
    public ChatController(ChatClient.Builder builder) {
        this.chatClient = builder.build();
    }
}
1.3 基础调用示例
代码语言:javascript
复制
@GetMapping("/ai/generate")
public String generate(@RequestParam String message) {
    return chatClient.prompt()      // 1. 创建 Prompt 构建器
            .user(message)          // 2. 设置用户消息
            .call()                 // 3. 执行调用
            .content();             // 4. 提取文本内容
}
1.4 设置系统消息(System Message)

系统消息用于定义 AI 的角色和行为准则:

代码语言:javascript
复制
String response = chatClient.prompt()
        .system("你是一位资深Java工程师,回答需简洁准确")  // 设定角色
        .user("说说Springboot源码?")
        .call()
        .content();

二、Prompt:结构化消息的载体

Prompt 是 Spring AI 中消息的容器,支持多角色对话管理。

2.1 Prompt 的结构
代码语言:javascript
复制
┌─────────────────────────────────────┐
│              Prompt                 │
├─────────────────────────────────────┤
│  ┌──────────┐    ┌──────────┐      │
│  │ System   │    │ User     │      │
│  │ Message  │    │ Message  │      │
│  │ (系统指令)│    │ (用户输入)│      │
│  └──────────┘    └──────────┘      │
│  ┌──────────┐    ┌──────────┐      │
│  │ Assistant│    │  ...     │      │
│  │ Message  │    │          │      │
│  │ (AI回复) │    │          │      │
│  └──────────┘    └──────────┘      │
└─────────────────────────────────────┘
2.2 使用 PromptTemplate 实现动态模板

PromptTemplate 支持占位符替换,实现动态内容生成:

代码语言:javascript
复制
@GetMapping("/prompt/test1")
public String promptTest1() {
    // 用户消息
    String userText = "介绍一下海盗黄金时代的三位著名海盗";
    Message userMessage = new UserMessage(userText);

    // 系统消息模板(带变量)
    SystemPromptTemplate systemTemplate  = new SystemPromptTemplate("你是一个名叫{name}的助手,请以{voice}的风格回答。");

    // 填充变量
    Message systemMessage = systemTemplate.createMessage(Map.of(
            "name", "Koki",
            "voice", "幽默"
    ));

    // 组装 Prompt
    Prompt prompt = new Prompt(List.of(systemMessage, userMessage));

    // 调用模型
    return chatClient.prompt(prompt).call().content();
}
2.3 从文件加载模板(生产环境推荐)

将提示词模板外置,便于管理和热更新:

代码语言:javascript
复制
// 注入模板文件
@Value("classpath:/prompts/system-message.st")
private Resource systemResource;

@GetMapping("/prompt/test2")
public String promptTest2() {
    // 用户消息
    String userText = "你好呀,你是什么AI Agent";
    Message userMessage = new UserMessage(userText);

    // 系统消息模板(带变量)
    SystemPromptTemplate systemTemplate  = new SystemPromptTemplate(systemResource);

    // 填充变量
    Message systemMessage = systemTemplate.createMessage(Map.of(
            "name", "小助手",
            "voice", "友好"
    ));

    // 组装 Prompt
    Prompt prompt = new Prompt(List.of(systemMessage, userMessage));

    // 调用模型
    return chatClient.prompt(prompt).call().content();
}

模板文件示例 (src/main/resources/prompts/system-message.st):

代码语言:javascript
复制
你是{name},一个{voice}的 AI 助手。
请确保回答:
1. 准确可靠
2. 通俗易懂
3. 保持{voice}的风格

三、Advisor:拦截与增强机制

Advisor 是 Spring AI 的拦截器机制,允许在请求发送前后进行处理,实现横切关注点(Cross-cutting Concerns)。

3.1 Advisor 执行流程
Advisor 执行流程
Advisor 执行流程

*图:Advisor 拦截流程 - 请求和响应都会经过 Advisor 链处理 *

执行顺序说明

  1. Before Advice:请求到达模型前执行(如添加历史记录)
  2. 调用 Chat Model:发送处理后的请求
  3. After Advice:收到响应后执行(如记录日志、过滤内容)
3.2 自定义日志 Advisor

实现 CallAroundAdvisor(同步)和 StreamAroundAdvisor(流式):

代码语言:javascript
复制
@Component
public class SimpleLoggerAdvisor implements CallAroundAdvisor, StreamAroundAdvisor {
    
    @Override
    public String getName() { 
        return "simpleLoggerAdvisor"; 
    }

    @Override
    public int getOrder() { 
        return 0;  // 数字越小优先级越高
    }

    // 同步调用拦截
    @Override
    public AdvisedResponse aroundCall(
            AdvisedRequest req, 
            CallAroundAdvisorChain chain) {
        
        log.info("🚀 请求前: {}", req.userText());
        
        AdvisedResponse res = chain.nextAroundCall(req);  // 继续执行链
        
        log.info("✅ 响应后: {}", res.response());
        return res;
    }

    // 流式调用拦截
    @Override
    public Flux<AdvisedResponse> aroundStream(
            AdvisedRequest req, 
            StreamAroundAdvisorChain chain) {
        
        log.info("🌊 流式请求前: {}", req.userText());
        
        return chain.nextAroundStream(req)
                .doOnNext(res -> log.info("📝 流式响应: {}", res));
    }
}
3.3 使用 Advisor
代码语言:javascript
复制
@Autowired
private SimpleLoggerAdvisor loggerAdvisor;

@GetMapping("/ai/chat")
public String chat(@RequestParam String message) {
    return chatClient.prompt()
            .advisors(loggerAdvisor)    // 添加 Advisor
            .user(message)
            .call()
            .content();
}
3.4 内置 Advisor 一览

Advisor

功能

适用场景

MessageChatMemoryAdvisor

对话记忆管理

多轮对话保持上下文

QuestionAnswerAdvisor

RAG 检索增强

基于知识库问答

SafeGuardAdvisor

内容安全过滤

敏感词检测、合规检查

VectorStoreChatMemoryAdvisor

向量存储记忆

长期记忆持久化

使用示例

代码语言:javascript
复制
package com.example.ai.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.InMemoryChatMemory;
import org.springframework.ai.openai.OpenAiChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class ChatConfig {

    @Bean
    public ChatClient chatClient(ChatClient.Builder builder) {
        return builder.defaultSystem("你是一个AI聊天助手")
                .build();
    }

    /**
     * 配置本地内存版的ChatMemory Bean
     */
    @Bean
    public ChatMemory chatMemory() {
        // InMemoryChatMemory是ChatMemory的默认实现,基于本地内存存储对话上下文
        return new InMemoryChatMemory();
    }

}
代码语言:javascript
复制
@Autowired
private ChatMemory chatMemory;

@GetMapping("/ai/memory")
public String chatWithMemory(@RequestParam String message) {
    return chatClient.prompt()
            .advisors(new MessageChatMemoryAdvisor(chatMemory))
            .user(message)
            .call()
            .content();
}

四、动态配置覆盖机制

Spring AI 支持全局默认配置 + 运行时动态覆盖的灵活配置策略。

4.1 配置层级
代码语言:javascript
复制
┌─────────────────────────────────────┐
│      运行时动态配置 (最高优先级)      │
│   .system(sp -> sp.param(...))      │
├─────────────────────────────────────┤
│      ChatClient 实例级配置            │
│   builder.defaultSystem(...)        │
├─────────────────────────────────────┤
│      应用全局配置 (application.yml)   │
│   spring.ai.openai.chat.options...  │
├─────────────────────────────────────┤
│      模型默认配置 (最低优先级)         │
│   OpenAI GPT-4 默认参数              │
└─────────────────────────────────────┘
4.2 实战示例

步骤 1:配置全局默认值

代码语言:javascript
复制
@Bean
ChatClient chatClient(ChatClient.Builder builder) {
    return builder
            .defaultSystem("你是{language}专家,精通{language}语法和表达")
            .build();
}

步骤 2:运行时动态替换参数

代码语言:javascript
复制
@GetMapping("/ai/dynamic")
public String dynamicChat(
        @RequestParam String language,
        @RequestParam String topic) {
    
    return chatClient.prompt()
            .system(sp -> sp.param("language", language))  // 动态注入
            .user("请讲解 " + topic)
            .call()
            .content();
}

// 调用示例:/ai/dynamic?language=英语&topic=过去完成时

五、完整实战:构建智能客服

代码语言:javascript
复制
@Service
public class CustomerService {
    
    @Autowired
    private ChatClient chatClient;
    
    @Autowired
    private VectorStore vectorStore;

    public String handleQuery(String userQuery) {
        return chatClient.prompt()
                // 1. 系统角色设定
                .system("你是专业客服助手,回答需礼貌、准确")
                
                // 2. 添加 RAG Advisor(知识库检索)
                .advisors(new QuestionAnswerAdvisor(vectorStore))
                
                // 3. 添加记忆 Advisor(保持对话上下文)
                .advisors(new MessageChatMemoryAdvisor(new InMemoryChatMemory()))
                
                // 4. 用户输入
                .user(userQuery)
                
                // 5. 执行调用
                .call()
                .content();
    }
}

总结

组件

核心职责

关键特性

ChatClient

统一入口

链式 API、同步/流式双支持

Prompt

消息封装

多角色、模板化、文件加载

Advisor

横切增强

拦截链、内置丰富、可扩展

这三个组件构成了 Spring AI 的核心骨架,遵循单一职责原则,既保证了灵活性,又提供了强大的扩展能力。通过合理组合,可以快速构建企业级的 AI 应用。


参考资源

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2026-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Spring AI系列之核心组件:ChatClient、Prompt 与 Advisor
    • 一、ChatClient:流式 API 的优雅入口
      • 1.1 核心架构
      • 1.2 两种创建方式
      • 1.3 基础调用示例
      • 1.4 设置系统消息(System Message)
    • 二、Prompt:结构化消息的载体
      • 2.1 Prompt 的结构
      • 2.2 使用 PromptTemplate 实现动态模板
      • 2.3 从文件加载模板(生产环境推荐)
    • 三、Advisor:拦截与增强机制
      • 3.1 Advisor 执行流程
      • 3.2 自定义日志 Advisor
      • 3.3 使用 Advisor
      • 3.4 内置 Advisor 一览
    • 四、动态配置覆盖机制
      • 4.1 配置层级
      • 4.2 实战示例
    • 五、完整实战:构建智能客服
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档