> 技术文档 > Spring AI 中 ChatClient常用方法_springai chatclient

Spring AI 中 ChatClient常用方法_springai chatclient


1、ChatClient是什么?

ChatClient 是 Spring AI 中一个简洁高效的组件,它能让你仅用几行代码就轻松对接 Deepseek、Qwen等主流 AI 大模型。其核心定位是一个流畅的 API 客户端,专为解决复杂AI交互场景而生,尤其擅长应对诸如提示词模板拼接、聊天记忆管理、输出解析等常见痛点。

ChatClient 通过链式调用将用户输入、系统提示及模型参数(如温度、最大 Token 数)组装成 Prompt 对象,完成请求的构建与参数传递。随后,ChatModel 调用底层 AI 服务接口(如火山引擎的流式 API),获取分块返回的原始响应数据流。最终,ChatClient 将这些流式响应统一封装为 ChatResponse 对象,或映射为自定义实体类(如 POJO),实现结构化输出,从而完成从请求构建、模型推理到结果解析的完整闭环。

举个🌰:

当你想与 AI 进行对话时,通常需要经历以下步骤:

  • 拼接提示词模板;

  • 维护和管理历史对话记录;

  • 解析返回的 JSON 数据;

  • 支持流式响应处理

而有了 ChatClient,这些繁琐操作将被封装成一条简洁的链式调用,一气呵成!从内部机制来看,ChatClient 就像是一位经验丰富的导演,协调多个“演员”协同演出:

  • 提示词模板引擎:自动拼接系统指令与用户输入;
  • HTTP通信模块:负责向 OpenAI 等模型接口发起请求;
  • 响应解析器:将返回的 JSON 转化为字符串、对象或流式数据;
  • 组件集成中心:整合聊天记忆(ChatMemory)、函数调用(Function Calling)等高级功能。

ChatClient 的链式调用基于 Fluent API 设计模式,通过方法链简化与 AI 模型的交互流程。以下是其核心方法及作用详解:


2、背景知识:系统提示词(System Prompt)

(1)在与大语言模型(LLM)交互时,通常有三种类型的输入内容:

  • System Prompt(系统提示)

    • 定义了模型的行为方式、角色设定或全局规则。

    • 比如:“你是一个乐于助人的助手。” 或 “你是一名精通Java的软件工程师。”

    • 在对话中一般只发送一次,用于初始化模型的角色认知。

  • User Prompt(用户提示)

    • 用户发出的具体请求或问题。

  • Assistant Response(助手回复)

    • 模型对用户请求的回答。

(2)defaultSystem(...) 的作用

此方法用于指定一个默认的 system prompt。这个 system prompt 将会在每次会话开始时自动应用,无需手动重复设置。如果你不调用这个方法,可能会使用空值或模型默认的 system prompt(通常是通用助手行为)。

ChatClient chatClient = ChatClient .builder(model) .defaultSystem(\"你是一个专业的法律顾问。\") .build();

在这个例子中,所有通过此 chatClient 发起的对话都会以“你是一个专业的法律顾问”作为系统指令开始。

(3) 使用场景

  • 你想让模型始终扮演某个特定角色(客服、教师、医生等)。

  • 需要统一模型输出风格或遵循某些规范。

  • 多次对话中避免重复设置 system prompt。


3、ChatClient链式调用—基础配置方法

(1)prompt() 方法

prompt() 是 ChatClient 中 链式调用的核心入口方法,用于启动 Fluent API 构建 AI 模型请求。作为方法链的起点,后续可串联 .user().system() 等方法设置用户输入、系统提示等内容。

    prompt() 方法通过 Fluent API 设计简化了请求构建流程,并支持动态参数、多模态输入、异步处理等高级功能。开发者可通过链式调用灵活控制模型行为,适用于从简单问答到复杂多模态交互的多样化场景

    prompt()

    这个无参数方法让您开始使用流畅 API,允许您构建用户、系统和其他提示部分。

    prompt(Prompt prompt)

    这个方法接受 Prompt 参数,让您传入使用 Prompt 的非流畅 API 创建的 Prompt 实例。

    prompt(String content)

    这是一个类似于前一个重载的便捷方法。它接受用户的文本内容。

    (2)defaultSystem(String prompt)

    • 作用:设置默认系统提示语,用于引导模型行为(如角色定义、回复风格)。

    • 示例

      ChatClient.builder().defaultSystem(\" 你是一个幽默的助手\").build();
    • 特性:支持动态变量替换(如 {{变量名}}

    (3)model(String modelName)

    • 作用:指定调用的 AI 模型(如 \"gpt-4\"\"chatglm3-6b\")。


    4、ChatClient链式调用—请求配置方法

    (1)user(String message)

    • 作用:添加用户输入消息,标识为 USER 角色。

    示例

    client.prompt().user(\" 如何学习编程?\");

    (2)system(String message)

    • 作用:添加系统级提示,覆盖默认配置(如临时调整回复规则)。

    示例

    client.prompt().system(\" 用简短的句子回答\");

    (3)param(String key, Object value)

    • 作用:动态注入参数至提示语变量,用于模板化提示。
    • 示例
      client.prompt().user(\" 写一个{{style}}的笑话\").param(\"style\", \"冷笑话\");

    5、ChatClient链式调用—执行与响应方法

    (1)call()

    作用:发起同步请求,返回 ChatResponse 对象(包含完整响应内容)。

    示例

    ChatResponse response = client.prompt().user(\" 你好\").call();

    (2)stream()

    作用:发起流式请求,返回 Flux 对象(适用于实时逐块输出)。

    示例

    Flux stream = client.prompt().user(\" 讲一个故事\").stream();

    (3)entity(Class type)

    作用:将模型输出解析为结构化对象(需响应内容符合目标类格式)。

    示例

    MovieInfo info = client.prompt().user(\" 推荐一部科幻电影\").call().entity(MovieInfo.class);

     (4) ChatResponse

    Spring AI 框架中,ChatResponse 是一个非常核心的类,用于封装从大语言模型(LLM)返回的聊天响应结果。它不仅仅是一个简单的文本回复容器,还包含了丰富的元数据信息

    • 实际的模型输出内容

    • 使用的模型名称

    • 生成过程中的 token 统计(输入、输出、总消耗)

    • 响应状态和错误信息(如果有)

    ①ChatResponse 的作用总结
    功能 描述 封装模型输出 包含完整的回复内容(如文本、图片等),通常以 Generation 列表形式存在 提供上下文信息 包括模型名、调用参数等,便于调试和日志记录 支持多轮对话 可结合 MessageHistory 等对象实现复杂对话逻辑 统计与分析 提供 token 数量统计,帮助优化成本和性能 统一接口设计 所有 LLM(如 OpenAI、Azure、Alibaba Qwen、Ollama 等)都返回统一结构
    ②ChatResponse 的典型结构(简化版)
    public class ChatResponse { private String model; // 使用的模型名称,如 \"qwen-max\" private List generations; // 生成的内容列表 private Map metadata; // 元数据,如 token 使用情况、调用耗时等}

    其中,Generation 是实际的生成内容,结构如下:

    public class Generation { private String content; // 模型生成的内容 private String role; // 角色,如 \"assistant\"}
    ③使用 Spring AI 调用模型并处理 ChatResponse

    假设你已经配置好了 ChatClient(例如基于 OpenAI 或 Qwen),你可以这样调用并解析响应:

    import org.springframework.ai.chat.client.ChatClient;import org.springframework.ai.chat.model.ChatResponse;import org.springframework.ai.chat.prompt.Prompt;import org.springframework.stereotype.Service;@Servicepublic class ChatService { private final ChatClient chatClient; public ChatService(ChatClient chatClient) { this.chatClient = chatClient; } public void askQuestion(String userMessage) { Prompt prompt = new Prompt(userMessage); ChatResponse response = chatClient.call(prompt); // 输出模型名称 System.out.println(\"Model used: \" + response.getMetadata().get(\"model\")); // 输出生成内容 response.getGenerations().forEach(gen -> { System.out.println(\"Assistant: \" + gen.getContent()); }); // 输出 token 统计(如果支持) if (response.getMetadata().containsKey(\"usage\")) { System.out.println(\"Usage: \" + response.getMetadata().get(\"usage\")); } }}
    ④ChatResponse 的关键应用场景
    场景 使用方式 获取回复内容 response.getGenerations().get(0).getContent() 获取模型名称 response.getMetadata().get(\"model\") 获取 token 消耗 response.getMetadata().get(\"usage\") 构建对话历史 将 content 和 role 添加到下一次请求中 日志记录与监控 记录 modelpromptcontentusage 等用于审计或计费
    ⑤Spring AI 支持的 LLM 类型

    Spring AI 目前支持多种 LLM 后端,包括:

    • OpenAI / Azure OpenAI

    • Amazon Bedrock

    • Google Vertex AI

    • Alibaba Cloud Qwen

    • Ollama(本地模型)

    • HuggingFace Inference API

    • 自定义模型(通过 SPI 接口)

     下面通过调用 call() 方法后的 chatResponse() 方法展示了返回包含元数据的 ChatResponse 对象的示例:

    ChatResponse chatResponse = chatClient.prompt() .user(\"给我讲个笑话\") .call() .chatResponse();

    无论你使用哪种模型,它们都会返回统一格式的 ChatResponse,极大提升了代码的可移植性和可维护性。

    { \"result\": { \"metadata\": { \"finishReason\": \"STOP\", \"contentFilterMetadata\": null }, \"output\": { \"messageType\": \"ASSISTANT\", \"media\": [], \"metadata\": { \"finishReason\": \"STOP\", \"role\": \"ASSISTANT\", \"id\": \"endpoint_common_28\", \"messageType\": \"ASSISTANT\" }, \"content\": \"我是Qwen,由阿里云开发的大型语言模型。我被设计用来协助人们进行各种任务,包括编写文档、创作故事、表达观点等。有什么我可以帮助你的吗?\" } }, \"metadata\": {}, \"results\": [ { \"metadata\": { \"finishReason\": \"STOP\", \"contentFilterMetadata\": null }, \"output\": { \"messageType\": \"ASSISTANT\", \"media\": [], \"metadata\": {  \"finishReason\": \"STOP\",  \"role\": \"ASSISTANT\",  \"id\": \"endpoint_common_28\",  \"messageType\": \"ASSISTANT\" }, \"content\": \"我是Qwen,由阿里云开发的大型语言模型。我被设计用来协助人们进行各种任务,包括编写文档、创作故事、表达观点等。有什么我可以帮助你的吗?\" } } ]}
    ⑥ 总结
    特性 描述 作用 封装模型响应内容、元数据、token 使用等 主要字段 generationsmodelmetadata 用途 获取回复内容、模型信息、token 统计等 适用场景 单次问答、多轮对话、日志记录、成本控制等

    AI 模型的响应是一个由 ChatResponse 类型定义的丰富结构。 它包括有关如何生成响应的元数据,还可以包含多个响应,称为 Generations,每个都有自己的元数据。 元数据包括用于创建响应的令牌数量(每个令牌大约是一个单词的 3/4)。 这些信息很重要,因为托管 AI 模型根据每个请求使用的令牌数量收费。


    6、ChatClient链式调用—控制模型生成行为

    通过链式方法设置温度值(.temperature())、最大 Token 数(.maxTokens())等,控制输出的随机性及长度。‌大模型中的Temperature参数主要用于调节生成文本的随机性和多样性‌,温度系数越大,模型输出越倾向于给出较高的概率值,表现为“热情”;温度系数越小,模型输出越倾向于给出较低的概率值,表现为“冷静”

    (1)temperature(double value)

    作用:设置模型生成温度值(控制随机性,范围 0.0-1.0)。

    示例

    client.prompt().user(\" 写诗\").temperature(0.7).call();

    (2)maxTokens(int value)

    作用:限制生成的最大 Token 数,防止过长响应。

    示例

    client.prompt().user(\" 总结这篇文章\").maxTokens(500).call();

    (3)onError(Consumer handler)

    作用:自定义异常处理逻辑(如网络错误、参数校验失败)。

    示例

    client.prompt().user(\" 提问\").onError(e -> log.error(\" 请求失败\", e)).call();

    7、ChatClient链式调用—控制模型生成行为

    (1)media(MediaData data)

    作用:添加图像、音频等多媒体输入(需模型支持多模态)。

    示例

    client.prompt().user(\" 描述这张图\").media(imageData).call();

    (2)withMemory(ChatMemory memory)

    作用:绑定对话记忆组件,自动附加历史上下文。

    示例

    client.withMemory(redisChatMemory).prompt().user(\" 继续刚才的话题\").call();

    8、ChatClient典型链式调用示例

    ChatResponse response = ChatClient.builder() . model(\"gpt-4\") . defaultSystem(\"你是一名技术顾问\") . build() .prompt() .user(\"解释区块链原理\") .temperature(0.5) .maxTokens(300) .call();

    关键设计优势

    • 代码简洁性:通过链式调用替代多层嵌套代码

    • 类型安全:编译时检查参数类型,减少运行时错误

    • 可扩展性:支持自定义方法扩展(如添加领域特定参数)


    9、在单次请求中临时覆盖模型名称

    如果未显式设置模型名称,ChatClient会使用默认模型(通常取决于底层ChatModel的配置)。您可以在运行时覆盖默认设置,例如:

     ChatResponse response = chatClient.prompt() .options(OpenAiChatOptions.builder().withModel(\"gpt-3.5-turbo\").build()) .user(\"What\'s the weather today?\") .call();

    10、使用ChatOptions对象设置模型名称(如使用OpenAI的模型)

    创建一个包含模型名称的ChatOptions 选项对象,并在创建ChatClient实例时传递给它。这是推荐的方法,因为它支持其他参数(如温度、随机性控制),并确保代码可读性高 

    import org.springframework.ai.chat.client.ChatClient; import org.springframework.ai.chat.model.ChatModel; import org.springframework.ai.openai.OpenAiChatOptions; // 导入选项类 // 创建ChatClient实例并指定模型名称 ChatClient chatClient = ChatClient.builder() .chatModel(chatModel) // 注入ChatModel Bean(如OpenAI的GPT模型) .defaultOptions( // 设置默认选项,包括模型名称 OpenAiChatOptions.builder() .withModel(\"gpt-4-1106-preview\") // 指定模型名称 .withTemperature(0.7f) // 可选:其他参数 .build() ) .build(); // 使用ChatClient发送请求String response = chatClient.prompt() .user(\"Hello, how are you?\") .call() .content();

    参考链接:

    Spring AI ChatClient API 使用指南:从基础到实战(附完整代码示例)_spring ai client api-CSDN博客

    增强器 API - 零基础入门Java AI

    Spring AI中的ChatClient:从入门到精通,一篇搞定!

    Spring AI 隐藏杀器:参数这样调,效果立竿见影