最近 Spring AI 迭代很快,从原来的 ChatModel 转向了更易用的 ChatClient API。如果你看到这串名词:ChatClientdefaultOptionsFunctionsToolsSystem&UserAdvisors,肯定会说好多名词啊。

不急,慢慢来。

一、先搞懂:ChatClient 到底是什么?

我的思考

我最早用 Spring AI 时,写代码是这样的:

ChatModel chatModel = ...;
Prompt prompt = new Prompt(...);
ChatResponse response = chatModel.call(prompt);

感觉有点啰嗦,每次都要手动拼 Prompt

后来 Spring AI 推出了 ChatClient,我才发现:它就是一个更高级、更流畅的「聊天客户端」,用 Builder 模式把所有配置、提示、工具都串起来,代码可读性直接拉满。

通俗一句话

ChatClient = 你和 AI 对话的「专属聊天框」,比旧的 ChatModel 更顺手、更强大。

最经典写法

// 1. 注入 ChatClient(Spring Boot 自动配置)
@Autowired
private ChatClient chatClient;

// 2. 一句话调用 AI
String answer = chatClient.prompt()
    .user("解释一下 Kafka 增量聚合是什么")
    .call()
    .content();

你看,不用再手动创建 PromptChatResponse 了,一行流到底,爽不爽?

二、default —— 给 ChatClient 设「默认值」

我的思考

我在想:如果我所有请求都要加同一个系统提示,或者都用同一个模型参数,难道每次都要写一遍吗?

default 就是解决这个问题的:给 ChatClient 提前设好默认配置,后面所有请求都自动继承,不用重复写。

代码示例

// 提前构建一个带默认配置的 ChatClient
@Bean
public ChatClient chatClient(ChatClient.Builder builder) {
    return builder
        // 默认系统提示:所有对话都以这个角色开始
        .defaultSystem("你是一个专业的Java后端工程师,回答要简洁通俗")
        // 默认温度:控制输出随机性
        .defaultOptions(ChatOptions.builder().temperature(0.7).build())
        .build();
}

之后你再调用 chatClient.prompt(),就自动带上了这些默认值,不用每次都重复配置。

通俗比喻

default = 给你的聊天框预设「常用话术」和「脾气」,每次打开都不用重新调。

三、Options —— 控制 AI 的「行为参数」

我的思考

我想让 AI 更有创意一点,或者更严谨一点,怎么控制?

Options 就是用来精细控制 AI 生成行为的,比如:

  • 温度(temperature):0 更严谨,1 更随机
  • 最大 token 数(maxTokens):限制回答长度
  • 模型名称(model):切换底层模型
  • 采样方法(topP):控制多样性

代码示例

String answer = chatClient.prompt()
    .user("写一首关于春天的诗")
    // 临时覆盖默认配置,让诗更有创意
    .options(ChatOptions.builder()
        .temperature(0.9)  // 高温度,更有想象力
        .maxTokens(500)    // 最多 500 token
        .build())
    .call()
    .content();

通俗一句话

Options = 给 AI 调「控制面板」,想让它怎么说话就怎么调。

四、Functions —— 让 AI 会「用工具」

我的思考

AI 本身是个 “纸上谈兵” 的家伙,怎么让它帮我查天气、查订单、算数学?

这就是 FunctionsTools 的作用:给 AI 注册外部工具,让它能调用真实世界的接口。

注意:在 Spring AI 里,Functions 是旧版,Tools 是新版更通用的叫法,本质都是让 AI 调用你写的 Java 方法。

代码示例(给 AI 一个查天气的工具)

// 1. 定义一个工具方法(普通 Spring Bean)
@Component
public class WeatherService {
    public String getWeather(String city) {
        return "今天" + city + "天气晴朗,25℃";
    }
}

// 2. 把工具注册给 ChatClient
@Bean
public Function<WeatherRequest, String> weatherFunction(WeatherService weatherService) {
    return new Function<>() {
        @Override
        public String apply(WeatherRequest request) {
            return weatherService.getWeather(request.city());
        }
    };
}

// 3. 让 AI 调用这个工具
String answer = chatClient.prompt()
    .user("北京今天天气怎么样?")
    // 告诉 AI 可以用这个工具
    .tools(weatherFunction())
    .call()
    .content();

AI 会自动分析问题,发现需要查天气,就会调用你写的 WeatherService,拿到结果后再整理成自然语言回答你。

通俗比喻

Functions/Tools = 给 AI 装了个「插件市场」,让它能调用你写的代码,变成真正的 “万能助手”。

五、System&User —— 对话的「角色与内容」

我的思考

我想让 AI 扮演一个特定角色,比如 “英语老师” 或 “产品经理”,同时还要问它具体问题,怎么写?

System&User 就是对话的核心结构:

  • System:给 AI 设定身份、规则、语气(比如 “你是一个严厉的英语老师”)
  • User:你真正的问题或指令

代码示例

String answer = chatClient.prompt()
    // 设定角色:System 消息
    .system("你是一个温柔的英语老师,专门纠正学生的语法错误")
    // 学生的问题:User 消息
    .user("I am go to school every day. 这句话对吗?")
    .call()
    .content();

AI 会先记住自己是 “温柔的英语老师”,再去回答你的问题。

通俗一句话

System = 给 AI 定人设,User = 你对它说的话。

六、Advisors —— 给对话加「智能拦截器」

我的思考

我想给所有对话都加 RAG 检索,或者统一做内容审核,难道要每个请求都写一遍吗?

Advisors 就是 Spring AI 里的 「AOP 切面」,可以在对话前后插入自定义逻辑,比如:

  • 自动检索知识库(RAG)
  • 内容安全审核
  • 日志记录
  • 响应后处理

代码示例(给对话加 RAG 检索)

// 1. 定义一个 RAG Advisor
@Bean
public Advisor ragAdvisor(VectorStore vectorStore) {
    return QuestionAnswerAdvisor.builder()
        .vectorStore(vectorStore)
        .build();
}

// 2. 把 Advisor 注册给 ChatClient
String answer = chatClient.prompt()
    .user("Spring AI 的 ChatClient 是什么?")
    // 自动触发 RAG 检索,把知识库相关内容喂给 AI
    .advisors(ragAdvisor())
    .call()
    .content();

你不用在代码里写检索逻辑,Advisor 会自动帮你查向量库,把结果注入到 Prompt 里,AI 就能基于你的知识库回答问题了。

通俗比喻

Advisors = 给你的聊天框装了个「智能助理」,自动帮你查资料、做审核,你只需要专心提问。

七、我把全家桶串起来:一段完整实战代码

下面是我在真实项目里最常用的写法,把上面所有概念都串起来了:

@Service
public class SpringAiAdvancedService {

    @Autowired
    private ChatClient chatClient;

    @Autowired
    private Function<WeatherRequest, String> weatherFunction;

    @Autowired
    private Advisor ragAdvisor;

    public String askAI(String question) {
        return chatClient.prompt()
            // 1. 人设:System 消息
            .system("你是一个专业的Java技术顾问,会用工具查资料,回答要通俗、准确、有逻辑")
            // 2. 用户问题
            .user(question)
            // 3. 精细控制 AI 行为
            .options(ChatOptions.builder()
                .temperature(0.6)
                .maxTokens(1000)
                .build())
            // 4. 给 AI 工具(查天气)
            .tools(weatherFunction)
            // 5. 给对话加 RAG 检索(自动查知识库)
            .advisors(ragAdvisor)
            // 6. 发送请求,拿结果
            .call()
            .content();
    }
}

我写这段代码时的思考过程

  1. 先给 AI 定人设(System),让它知道自己是谁
  2. 再把用户问题抛出去(User)
  3. 调一下参数(Options),控制输出风格
  4. 给它装工具(Tools),让它能查天气
  5. 加个 Advisor,让它自动查我的知识库(RAG)
  6. 最后调用,拿到答案

八、最后总结:一张图记住所有概念

概念 作用 通俗比喻
ChatClient 核心聊天入口,Builder 模式流式调用 专属聊天框
default 给 ChatClient 设默认配置,避免重复代码 预设常用话术
Options 精细控制 AI 生成行为(温度、token 等) AI 控制面板
Functions/Tools 让 AI 调用外部 Java 方法(查天气、算数学等) 插件市场
System&User 对话的核心结构:人设 + 问题 定人设 + 提问
Advisors 对话前后的拦截器(RAG、审核、日志等) 智能助理

一句话记忆:

ChatClient 打开聊天框,default 预设配置,System&User 定人设和问题,Options 调参数,Tools 装插件,Advisors 加智能辅助,最后拿到 AI 回答。

Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐