SpringAI中的ChatModel是啥

SpringAI中的ChatModel是啥

  • [1. ChatModel](#1. ChatModel)
  • [2. Prompt](#2. Prompt)
    • [2.1 Message](#2.1 Message)
    • [2.2 ChatOptions](#2.2 ChatOptions)
  • [3. ChatResponse](#3. ChatResponse)

在 Spring AI 的开发体系中,模型(Model) 是绝对的核心 ------ 因为我们用 Spring AI 的核心目标,就是对接和使用大模型能力。

Spring AI 兼容多种类型的大模型,并且按照功能做了清晰分类,比如常用的 Chat Model(对话模型)、Embedding Model(嵌入模型),还有 Image Model(图像模型)、Audio Model(音频模型)等。

1. ChatModel

  • ChatModel 是 Spring AI 给对话模型做的统一对接接口。它把 OpenAI、Azure OpenAI、Hugging Face 等不同厂商的对话模型都抽象成一套用法,咱们开发者不用关心每个厂商的调用细节,用起来都一样。
  • 不管你用的是 OpenAI 的 GPT-4、百炼对接的开源模型,还是本地部署的 Ollama,都能通过同一个 ChatModel 接口调用。
java 复制代码
public interface ChatModel extends Model<Prompt, ChatResponse>, StreamingChatModel {

	default String call(String message) {
		Prompt prompt = new Prompt(new UserMessage(message));
		Generation generation = call(prompt).getResult();
		return (generation != null) ? generation.getOutput().getText() : "";
	}

	default String call(Message... messages) {
		Prompt prompt = new Prompt(Arrays.asList(messages));
		Generation generation = call(prompt).getResult();
		return (generation != null) ? generation.getOutput().getText() : "";
	}

	@Override
	ChatResponse call(Prompt prompt);

	default ChatOptions getDefaultOptions() {
		return ChatOptions.builder().build();
	}

	default Flux<ChatResponse> stream(Prompt prompt) {
		throw new UnsupportedOperationException("streaming is not supported");
	}

}
  • 👆 ChatModel 接口其实继承了两个接口:一个是基础的 Model,另一个是 StreamingChatModel。StreamingChatModel 里有个 stream 方法,返回值是 Flux,这个接口就是专门用来调用大模型做流式输出的。
  • ChatModel 中还定义了两个核心对象:Prompt 是输入,ChatResponse 是输出。它的工作流程很简单:接收 Prompt 作为输入,发送给后端大模型,模型生成内容后返回 ChatResponse,应用再将结果展示给用户。
  • DashscopeChatModel(阿里云百炼)和 OllamaChatModel是ChatModel的两个具体实现

来一个简单的测试:

java 复制代码
@RestController
@RequestMapping("/test1/chatModel")
public class A4ChatModelController {

    @Resource
    private DashScopeChatModel chatModel;

    @MyQuickTestFlux(uri = "/test1/chatModel/chat/{message}", desc = "使用DashScopeChatModel的ChatModel")
    @GetMapping("/test1/{message}")
    public String test1(@PathVariable String message) {
        ChatResponse response = chatModel.call(new Prompt(message, DashScopeChatOptions.builder().model("qwen-plus").build()));

        return response.getResult().getOutput().getText();
    }
 
    /**
     * 流式输出
     *
     * @param message 用户提示词
     */
    @MyQuickTestFlux(uri = "/test1/chatModel/test2/chat/{message}", desc = "使用DashScopeChatModel的ChatModel")
    @RequestMapping("/test2/chat/{message}")
    public Flux<String> test2(HttpServletResponse response, @PathVariable String message) {
        // 设置响应头
        response.setContentType("text/event-stream");
        // 设置响应字符编码为UTF-8
        response.setCharacterEncoding("UTF-8");
        Prompt prompt = new Prompt(message, DashScopeChatOptions.builder().maxToken(100).build());

        Flux<ChatResponse> chatResponseFlux = chatModel.stream(prompt);

        return chatResponseFlux.mapNotNull(resp -> resp.getResult().getOutput().getText());
    }
}
  • 👆 这段代码是 ChatModel 的简单使用示例:test1 方法返回 String,是普通阻塞式调用:传入提示词后,等大模型生成完整结果才返回,适合不需要实时输出的场景。
  • test2 方法返回 Flux<String>,是流式输出:会逐段返回大模型的生成内容,更贴合对话场景的实时体验。
  • 重点注意:test2 必须加 2 个关键配置 ------
    ① 方法入参要加 HttpServletResponse;
    ② 方法内设置两行响应头:
    response.setContentType("text/event-stream"):告诉浏览器这是流式响应;
    response.setCharacterEncoding("UTF-8"):避免页面展示中文乱码。

2. Prompt

  • Prompt 就是 Spring AI 给大模型的统一输入载体,不管是 call 阻塞调用,还是 stream 流式调用,入参都得用它。
  • 它主要包两部分:一是你要问模型的核心提示词(比如 "解释下 Spring AI"),二是可选的模型配置(比如指定用 qwen-plus 模型、限制生成长度),不用直接传字符串,统一用 Prompt 更规范。
java 复制代码
public class Prompt implements ModelRequest<List<Message>> {
    // 对话历史+本地对话内容
    private final List<Message> messages;

    // 调用 Chat Model 时的额外参数
    @Nullable
    private ChatOptions chatOptions;
}
  • Prompt 里有两个核心参数:第一个是 List<Message> messages,就是对话的完整上下文 ------ 包含历史聊天记录 + 你这次的提问内容;
  • 第二个是 ChatOptions chatOptions(可选),就是调用大模型时的额外配置,比如指定用哪个模型、限制生成长度、调整随机性等。这两个参数分别管 "输入内容" 和 "调用规则",是 Prompt 的核心。

2.1 Message

  • Message 就是对话内容的载体,它有多个实现类,对应不同的对话角色:
    🖊 SYSTEM 是系统设定(比如 "你是 Java 讲师,回答要简洁");
    🖊 USER 是用户的输入提问;
    🖊 ASSISTANT 是大模型的回复内容;
    🖊 ToolResponse 则是工具调用后的返回结果。
  • 不同类型的 Message 组合起来,就构成了完整的对话上下文。

2.2 ChatOptions

  • ChatOptions 是个可选字段,用于指定调用 Chat Model 时的额外参数
    ① 温度(temperature)控制回答的 "creativity / 随机性"。
    数字越小:回答越稳定、准确、保守
    数字越大:回答越脑洞大、多样、天马行空
    ② 最大生成 token(max token)
    限制模型最多能输出多少字。数字设多少,模型就最多生成多长的内容,防止输出太长。
    ③ Top-k
    控制模型选词时,只从概率最高的前 k 个词里选。k 越小,回答越保守;k 越大,选择越多、越随机。

3. ChatResponse

  • 不管是用 call 普通调用,还是 stream 流式调用,返回的都是 ChatResponse,代表大模型给我们的响应。
  • 区别只在于:
    🖊 call 返回单个 ChatResponse
    🖊 stream 返回 Flux<ChatResponse>
  • 最后拿到内容,统一用这一行:resp.getResult().getOutput().getText()
相关推荐
qq_12498707531 小时前
基于springboot+vue的热门文创内容推荐平台(源码+论文+部署+安装)
vue.js·spring boot·后端·spring·毕业设计·计算机毕设
树獭叔叔3 小时前
02-大模型位置编码详解:大模型如何理解顺序?
后端·aigc·openai
UIUV3 小时前
AI Agent 开发实战:从原理到最小化实现
后端·langchain·node.js
canonical_entropy3 小时前
反直觉的软件设计洞察:为什么你可能想不到它们
后端·aigc·领域驱动设计
树獭叔叔3 小时前
01-注意力机制详解:大模型如何决定"该关注什么"?
后端·aigc·openai
what丶k4 小时前
Docker 进阶指南:从入门能用,到生产环境稳、快、安全的核心实践与底层原理
后端·docker·容器
玄〤4 小时前
个人博客网站搭建day5--MyBatis-Plus核心配置与自动填充机制详解(漫画解析)
java·后端·spring·mybatis·springboot·mybatis plus