【SpringAIAlibaba新手村系列】(3)ChatModel 与 ChatClient 的深度对比

简介: 本章深度解析 Spring AI 中 `ChatModel`(底层接口)与 `ChatClient`(高级封装)的本质区别:前者如“手动挡”,精准控制但需写大量样板代码;后者似“智能点餐机”,链式调用、支持系统提示、模板、工具调用等,开发高效。初学者推荐优先使用 `ChatClient`。

第三章 ChatModel 与 ChatClient 的深度对比

版本标注

  • Spring AI: 1.1.2
  • Spring AI Alibaba: 1.1.2.0

章节定位

  • ChatModelChatClient 依然是最重要的基础抽象。
  • 但在 Spring AI Alibaba 1.1.2.x 中,它们往往作为 ReactAgent、Workflow、Graph 节点内部的基础能力来使用,而不是最终应用层的最高抽象。

s01 > s02 > [ s03 ] s04 > s05 > s06 > s07 > s08 > s09 > s10 > s11 > s12 > s13 > s14 > s15 > s16 > s17 > s18

"底层看 ChatModel, 开发多用 ChatClient" -- 一个偏原始能力, 一个偏工程效率。


一、为什么需要两个 API?

1.1 初学者的困惑

很多初学者看到 Spring AI 同时提供了 ChatModelChatClient 都会问:

  • "这两个不都是用来调用 AI 的吗?"
  • "到底该用哪一个?"
  • "他们有什么区别?"

这一章我们就来彻底搞清楚这个问题!

1.2 比喻理解

让我用一个生活化的比喻来解释:

ChatModel(对话模型) 就相当于手机的「原始电话功能」

  • 只能打电话(调用 send/receive)
  • 功能简单直接
  • 需要自己处理各种细节

ChatClient(对话客户端) 相当于「智能手机」

  • 在电话基础上,增加了:
    • 通讯录管理(系统提示词)
    • 短信应用(Prompt 模板)
    • 语音助手(工具调用)
    • 智能外设(向量存储、记忆功能)
  • 功能更丰富,使用更便捷

二、ChatModel 详解

2.1 什么是 ChatModel?

ChatModel 是 Spring AI 的核心底层接口,它直接封装了与 AI 模型的通信。

大白话解释:把 ChatModel 想象成"AI 模型的翻译官",你给它发中文,它能听懂;AI 返回的内容,它也能翻译成 Java 对象给你。

public interface ChatModel extends Model, ChatOptionsDesktop {
   
    // 核心方法就两个:

    // 方法1:一次性返回完整结果
    ChatResponse call(Prompt prompt);

    // 方法2:流式返回(一个字一个字吐出来)
    Flux<ChatResponse> stream(Prompt prompt);
}

2.2 ChatModel 的特点

特点 说明
底层接口 直接与 AI 服务商通信
功能单一 只负责发送消息、接收回复
灵活度高 可以精确控制请求的每个细节
使用难度 需要了解 Prompt、Message 等概念

2.3 代码示例

// 使用 ChatModel 调用 AI
@RestController
public class ChatModelController
{
   
    @Resource
    private ChatModel chatModel;

    @GetMapping("/chatmodel/hello")
    public String hello(String msg)
    {
   
        // ChatModel 的调用方式:直接传入字符串
        String result = chatModel.call(msg);
        return result;
    }
}

三、ChatClient 详解

3.1 什么是 ChatClient?

ChatClient 是构建在 ChatModel 之上的高级 API,它提供了链式调用(Builder模式)的便捷写法。

大白话解释ChatClient 就像一个"智能点餐机",不仅能帮你叫外卖,还支持:

  • 定义口味偏好(系统提示词)
  • 选择优惠券(模板变量)
  • 凑单推荐(RAG 检索)
  • 会员积分(对话记忆)

3.2 ChatClient 的链式调用

// ChatClient 的经典使用方式:链式调用
String result = chatClient.prompt()           // 第一步:创建提示词
    .system("你是一个Java助手")                // 第二步:设置系统提示词
    .user("什么是反射?")                      // 第三步:设置用户问题
    .call()                                    // 第四步:执行调用
    .content();                                // 第五步:获取结果

这种链式写法比原生 ChatModel 更加直观易读。

3.3 代码示例

// 使用 ChatClient 调用 AI
@RestController
public class ChatClientController
{
   
    // 注意:ChatClient 不能直接注入,需要通过 Builder 构建
    private final ChatClient dashScopeChatClient;

    // 构造函数注入,并构建 ChatClient
    public ChatClientController(ChatModel dashScopeChatModel)
    {
   
        // 通过 ChatModel 创建 ChatClient
        this.dashScopeChatClient = ChatClient.builder(dashScopeChatModel).build();
    }

    @GetMapping("/chatclient/hello")
    public String hello(String msg)
    {
   
        // 链式调用,语义清晰
        String result = dashScopeChatClient.prompt()
            .user(msg)      // 设置用户消息
            .call()         // 调用 AI
            .content();    // 获取文本内容
        return result;
    }
}

四、两者对比

4.1 功能对比表

特性 ChatModel ChatClient
层级 底层接口 高级封装
API 风格 直接调用 链式 Builder
系统提示词 需手动构造 Prompt 对象 .system() 方法直接设置
模板变量 不支持 支持 .param() 替换占位符
结构化输出 需额外配置 .entity() 方法直接映射
对话记忆 不支持 支持 Advisor 扩展
工具调用 需手动配置 支持 .tools() 方法
适用场景 需要精确控制的底层开发 快速构建 AI 功能

4.2 如何选择?

使用 ChatModel 的场景

  1. 你需要精确控制请求的每个参数
  2. 你是库/框架开发者,需要底层能力
  3. 你需要实现自定义的 AI 逻辑

使用 ChatClient 的场景

  1. 日常的 AI 对话开发(推荐)
  2. 需要快速构建原型
  3. 需要用到系统提示词、模板、工具调用等高级功能

4.3 ChatModel 也能实现 ChatClient 的功能(但代码更多)

很多初学者误以为 ChatModel 功能太简单,做不到 ChatClient 的那些高级功能。其实 ChatModel 通过手写样板代码完全可以实现相同的功能,只不过代码量会多一些。

让我们对比一下两者的实现方式:

场景:让 AI 扮演 Java 助手,回答技术问题

ChatClient 的写法(简洁)

String result = chatClient.prompt()
    .system("你是一个专业的Java工程师")  // 系统提示词
    .user("什么是反射?")                 // 用户问题
    .call()
    .content();

ChatModel 的写法(样板代码多)

// ChatModel 需要手动构造 Prompt 对象
// 第一步:创建系统消息
SystemPromptTemplate systemPromptTemplate = new SystemPromptTemplate(
    "你是一个专业的%s", "Java工程师"      // 模板变量
);
Message systemMessage = systemPromptTemplate.createMessage(
    Map.of("role", "professional", "specialty", "Java工程师")
);

// 第二步:创建用户消息
UserMessage userMessage = new UserMessage("什么是反射?");

// 第三步:组合成对话消息列表
List<Message> messages = new ArrayList<>();
messages.add(systemMessage);
messages.add(userMessage);

// 第四步:创建 Prompt 对象
Prompt prompt = new Prompt(messages);

// 第五步:调用并获取结果
ChatResponse response = chatModel.call(prompt);
String result = response.getResult().getOutput().getText();

从上面的对比可以看出:

  • ChatClient:3 行代码搞定(链式调用)
  • ChatModel:需要 10+ 行样板代码(手动构造)

那 ChatModel 还有什么用?

虽然 ChatModel 代码多,但它给了你最大的控制权

  • 可以自定义消息类型
  • 可以精确控制每个参数
  • 可以在发送前对消息进行任意处理

💡 总结:ChatModel 就像 "手动挡汽车",功能全但需要自己换挡;ChatClient 像 "自动挡汽车",开起来简单但牺牲了一些灵活性。

💡 初学者建议:90% 的情况下,使用 ChatClient 就够了。除非你有特殊需求,否则不需要直接使用 ChatModel


五、项目代码详解

5.1 项目结构

SAA-03ChatModelChatClient/
├── pom.xml                                    # 依赖配置
├── src/main/java/com/atguigu/study/
│   ├── config/
│   │   └── SaaLLMConfig.java                  # 配置文件
│   ├── controller/
│   │   ├── ChatClientController.java          # ChatClient 示例
│   │   ├── ChatClientControllerV2.java        # ChatClient V2写法
│   │   └── ChatModelController.java           # ChatModel 示例
│   └── Saa03ChatModelChatClientApplication.java

5.2 配置类

package com.atguigu.study.config;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 配置类:基于自动注入的 ChatModel 构建 ChatClient
 */
@Configuration
public class SaaLLMConfig
{
   
    /**
     * 创建一个命名的 ChatClient(基于 dashScopeChatModel)
     * 名称为 "dashScopeChatClient"
     */
    @Bean("dashScopeChatClient")
    public ChatClient dashScopeChatClient(ChatModel dashScopeChatModel)
    {
   
        return ChatClient.builder(dashScopeChatModel).build();
    }
}

💡 提示:实际上,这些配置大部分由 Spring AI 的自动配置(Auto Configuration)完成了,我们只需要了解原理即可。

5.3 ChatClientController V2 写法(推荐)

package com.atguigu.study.controller;

import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * 使用 @Autowired 注入 ChatClient
 */
@RestController
public class ChatClientControllerV2
{
   
    // 直接注入已注册的 ChatClient Bean
    @Autowired
    private ChatClient chatClient;

    @GetMapping("/chatclientv2/dochat")
    public String doChat(@RequestParam(name = "msg", defaultValue = "2加9等于几") String msg)
    {
   
        // 简洁的链式调用
        return chatClient.prompt()
            .user(msg)          // 设置用户消息
            .call()             // 调用
            .content();        // 获取文本内容
    }
}

六、进阶:ChatClient 的多种用法

6.1 返回 Flux 流式响应

@GetMapping("/stream")
public Flux<String> stream(String msg)
{
   
    return chatClient.prompt()
        .user(msg)
        .stream()              // 开启流式模式
        .content();
}

6.2 方法引用写法

// 更加简洁的 Lambda 写法
@GetMapping("/chat")
public String chat(String msg)
{
   
    return chatClient.prompt(msg).call().content();
}

// 或者更复杂点
ChatResponse response = chatClient.prompt()
    .system("你是一个专业的%s", "Java工程师")
    .user(msg)
    .call()
    .chatResponse();

String result = response.getResult().getOutput().getText();

七、本章小结

7.1 核心知识点

概念 说明
ChatModel 底层AI调用接口,直接与模型通信
ChatClient 高级封装,提供链式调用的便捷API
@Bean Spring 中用于注册组件的注解
链式调用 通过 Builder 模式实现的方法链

7.2 选择建议

┌─────────────────────────────────────────────────┐
│                  选择决策树                       │
│                                                  │
│  需要精细控制底层请求? ──YES──→ 使用 ChatModel   │
│         │                                       │
│         NO                                      │
│         ↓                                       │
│  直接开发AI应用功能? ──YES──→ 使用 ChatClient   │
│                                                  │
└─────────────────────────────────────────────────┘

本章重点

  1. 理解 ChatModel 与 ChatClient 的定位差异
  2. 掌握 ChatClient 的链式调用写法
  3. 能够根据场景选择合适的 API

下章剧透(s04):

了解了两种 API 的使用后,下一章我们将学习流式输出的高级用法,体验"打字机"效果的实现原理。


📝 编辑者:Flittly
📅 更新时间:2026年3月
🔗 相关资源Spring AI ChatClient 官方文档

目录
相关文章
|
7天前
|
云安全 人工智能 运维
阿里云联动百位企业安全专家,共识Agent防御最佳实践
当Agent成为新员工,你的安全边界在哪里?
1922 6
阿里云联动百位企业安全专家,共识Agent防御最佳实践
|
5天前
|
存储 人工智能 关系型数据库
阿里云AI产品与云产品最新组合套餐:Token Plan、AI coding及云服务器和建站等组合优惠价
阿里云推出全新“算力+模型+应用”一站式云与AI组合套餐活动,覆盖从个人开发者到中大型企业的全场景需求。核心亮点为分三档定价的Token Plan订阅服务,支持Qwen3.8-Max-Preview大模型调用,错峰时段最低可享0.2折优惠。活动同步推出AI Coding、智能体部署、云电脑托管、0代码建站等十余类场景化组合,搭配99元/年的普惠云服务器、88元/年的入门数据库等经典特惠产品,还为企业提供1V1定制化AI转型方案,大幅降低了不同用户群体拥抱AI的技术门槛与采购成本。
652 111
|
15天前
|
人工智能 JSON 安全
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
阿里云AI安全产品联动防御Fastjson攻击
2556 13
Fastjson远程代码执行漏洞,阿里云AI安全为您保驾护航
|
7天前
|
人工智能 弹性计算 数据库
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
2026年阿里云构建了覆盖全用户的七类优惠券,本文逐一拆解了每类优惠券的核心规则、适用人群与使用技巧:大促限定的阶梯满减券分个人、企业双通道,最高可减800元;学生专属300元无门槛券支持全品类通用;按量付费用户可参与消费达标返券形成循环优惠;新用户有低门槛专享满减券尝鲜;老用户可领取系统自动发放的随机福利券;中大型企业迁云可申请最高100万元的专项补贴;云产品通用券还能在活动价基础上实现折上折。不同身份、不同采购场景的用户均可通过精准匹配对应优惠券,最大化享受优惠力度。
462 110
阿里云优惠券种类解析:主要券种区别和适用群体及领取和使用指南
|
13天前
|
人工智能 前端开发 Linux
Codex 桌面版安装 + CC Switch 接入第三方 API 完整教程(2026 最新)
2026最新教程:手把手教你安装Codex桌面版,通过CC Switch v3.17.0一键接入Fenno等国产API(兼容OpenAI Responses格式),跳过账号登录,完整启用代码审查、多步任务与上下文感知功能。零基础友好,全程图文实操。(239字)
1617 2
|
15天前
|
人工智能 自然语言处理 数据挖掘
Qwen3.8-Max-Preview深度全解析:2.4万亿参数旗舰MoE模型+Token Plan限时优惠完整落地指南
2026年7月,全新旗舰级混合专家大模型Qwen3.8-Max-Preview正式开放抢先体验,作为通义千问Qwen3系列规格最高、综合推理能力顶尖的新一代模型,该模型总参数量达到2.4万亿(2.4T),是当前线上可调用的原生多模态旗舰模型,综合推理水准对标海外顶级Fable 5模型,在复杂工程开发、长文档深度分析、多步骤智能体自治、跨境多语言创作、海量数据挖掘五大高难度业务场景实现跨越式性能提升。
1428 2
|
17天前
|
人工智能
Qwen3.8抢先体验!正式版即将发布并开源!
千问Qwen3.8即将开源,参数达2.4T,进化速度以“天”计,实力媲美Fable 5。预览版Qwen3.8-Max已上线阿里Token Plan等平台,限时优惠:日间Credits低至1折,夜间更优,个人/团队版月付仅35元起!
1499 55
|
2天前
Qoder 一周年 × Qwen3.8-Max 正式上线,多重好礼限时领
8月3日,Qwen3.8-Max 正式上线Qoder,迎来Qoder一周年。新老用户可领800次免费调用,下单再赠2000次;夜间(22:00–08:00)调用5折;邀请好友双方得积分与调用额度。
248 0

热门文章

最新文章