写在前面

ChatClient API为开发者提供了将人工智能驱动的聊天补全功能集成到其应用程序中的能力。它利用预训练的语言模型(如GPT,即生成式预训练转换器),以自然语言生成类人化的用户输入响应。

API的工作原理通常是向AI模型发送提示或部分对话,然后AI模型会根据其训练数据和对自然语言模式的理解生成对话的补全或延续内容。之后,生成的完整响应会返回给应用程序,应用程序可以将其呈现给用户,或用于进一步处理。

<font style="color:rgb(25, 30, 30);">Spring AI ChatModel API</font> 旨在成为一个简单且可移植的接口,用于与各种 AI 模型 交互,使开发人员能够以最少的代码更改在不同模型之间切换。这种设计符合 Spring 的模块化和可互换性理念。

此外,借助诸如用于输入封装的<font style="color:rgb(25, 30, 30);">Prompt</font>和用于输出处理的<font style="color:rgb(25, 30, 30);">ChatResponse</font>等配套类,聊天模型API统一了与AI模型的通信。它管理着请求准备和响应解析的复杂性,提供了直接且简化的API交互方式。

API概述

接下来我们开始学习Spring AI聊天模型API接口及相关类的说明。

聊天模型(ChatModel)

以下是ChatModel接口的定义:

1
2
3
4
5
6
7
public interface ChatModel extends Model<Prompt, ChatResponse>, StreamingChatModel {

default String call(String message) {...}

@Override
ChatResponse call(Prompt prompt);
}

带有String参数的call()方法简化了初始使用,避免了更复杂的PromptChatResponse类的复杂性。在实际应用中,更常见的是使用接收Prompt实例并返回ChatResponsecall()方法。

流式聊天模型(StreamingChatModel)

下是StreamingChatModel接口的定义:

1
2
3
4
5
6
7
public interface StreamingChatModel extends StreamingModel<Prompt, ChatResponse> {

default Flux<String> stream(String message) {...}

@Override
Flux<ChatResponse> stream(Prompt prompt);
}

<font style="color:rgb(25, 30, 30);">stream()</font>方法接受与<font style="color:rgb(25, 30, 30);">ChatModel</font>类似的<font style="color:rgb(25, 30, 30);">String</font><font style="color:rgb(25, 30, 30);">Prompt</font>参数,但它使用响应式Flux API来流式传输响应。

提示词(Prompt)

提示词

Prompt是一种<font style="color:rgb(25, 30, 30);">ModelRequest</font>,它封装了一个消息对象列表和可选的模型请求选项。以下列表展示了<font style="color:rgb(25, 30, 30);">Prompt</font>类的简化版本,不包含构造函数和其他实用方法:

1
2
3
4
5
6
7
8
9
10
11
12
public class Prompt implements ModelRequest<List<Message>> {

private final List<Message> messages;

private ChatOptions modelOptions;

@Override
public ChatOptions getOptions() {...}

@Override
public List<Message> getInstructions() {...}
}

消息

<font style="color:rgb(25, 30, 30);">Message</font>接口封装了<font style="color:rgb(25, 30, 30);">Prompt</font>文本内容、一组元数据属性以及一种称为<font style="color:rgb(25, 30, 30);">MessageType</font>的分类。该接口的定义如下:

1
2
3
4
5
6
7
8
9
public interface Content {
String getText();
Map<String, Object> getMetadata();
}


public interface Message extends Content {
MessageType getMessageType();
}

多模态消息类型还实现了<font style="color:rgb(25, 30, 30);">MediaContent</font>接口,该接口提供了一个<font style="color:rgb(25, 30, 30);">Media</font>内容对象列表:

1
2
3
public interface MediaContent extends Content {
Collection<Media> getMedia();
}

<font style="color:rgb(25, 30, 30);">Message</font>接口有多种实现,对应AI模型可以处理的消息类别:

聊天补全端点会根据对话角色区分消息类别,这通过<font style="color:rgb(25, 30, 30);">MessageType</font>得到有效映射。

举个例子,OpenAI识别了不同对话角色的消息类别,如<font style="color:rgb(25, 30, 30);">system</font><font style="color:rgb(25, 30, 30);">user</font><font style="color:rgb(25, 30, 30);">function</font><font style="color:rgb(25, 30, 30);">assistant</font>。虽然“MessageType”一词可能暗示特定的消息格式,但在此语境中,它实际上指的是消息在对话中所扮演的角色。对于不使用特定角色的AI模型,<font style="color:rgb(25, 30, 30);">UserMessage</font>的实现充当标准类别,通常代表用户生成的查询或指令。要了解<font style="color:rgb(25, 30, 30);">Prompt</font><font style="color:rgb(25, 30, 30);">Message</font>的实际应用及其关系,尤其是在这些角色或消息类别的背景下,需要参阅提示词(Prompts)部分的详细解释。

聊天选项(chat Options)

所谓的聊天选项,其实就是可以传递给AI模型的选项。<font style="color:rgb(25, 30, 30);">ChatOptions</font>类是<font style="color:rgb(25, 30, 30);">ModelOptions</font>的子类,用于定义可传递给AI模型的少量可移植选项。<font style="color:rgb(25, 30, 30);">ChatOptions</font>类的定义如下:

1
2
3
4
5
6
7
8
9
10
11
public interface ChatOptions extends ModelOptions {
String getModel();
Float getFrequencyPenalty();
Integer getMaxTokens();
Float getPresencePenalty();
List<String> getStopSequences();
Float getTemperature();
Integer getTopK();
Float getTopP();
ChatOptions copy();
}

此外,每个特定于模型的ChatModel/StreamingChatModel实现都可以有自己的选项,这些选项可以传递给AI模型。例如,OpenAI聊天补全模型有其自身的选项,如<font style="color:rgb(25, 30, 30);">logitBias</font><font style="color:rgb(25, 30, 30);">seed</font><font style="color:rgb(25, 30, 30);">user</font>

这是一项强大的功能,允许开发人员在启动应用程序时使用特定于模型的选项,然后在运行时通过<font style="color:rgb(25, 30, 30);">Prompt</font>请求覆盖这些选项。

Spring AI 提供了一个复杂的系统,用于配置和使用聊天模型。它允许在启动时设置默认配置,同时也能灵活地在每个请求的基础上覆盖这些设置。这种方法使开发人员能够轻松使用不同的人工智能模型,并根据需要调整参数,所有这些都在 Spring AI 框架提供的统一接口内完成。

以下流程图展示了Spring AI如何处理聊天模型的配置和执行,它结合了启动和运行时选项:

  1. 启动配置 - ChatModel/StreamingChatModel 会使用“启动”聊天选项进行初始化。这些选项在 ChatModel 初始化期间设置,旨在提供默认配置。
  2. 运行时配置 - 对于每个请求,提示词可以包含运行时聊天选项:这些选项可以覆盖启动选项。
  3. 选项合并过程 - “合并选项”步骤会将启动选项和运行时选项结合起来。如果提供了运行时选项,它们的优先级高于启动选项。
  4. 输入处理——“转换输入”步骤将输入指令转换为原生的、特定于模型的格式。
  5. 输出处理——“转换输出”步骤将模型的响应转换为标准化的<font style="color:rgb(25, 30, 30);">ChatResponse</font>格式。

将启动选项和运行时选项分开,既可以进行全局配置,也能针对特定请求进行调整。

聊天响应(ChatResponse)

<font style="color:rgb(25, 30, 30);">ChatResponse</font>类的源码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class ChatResponse implements ModelResponse<Generation> {

private final ChatResponseMetadata chatResponseMetadata;
private final List<Generation> generations;

@Override
public ChatResponseMetadata getMetadata() {...}

@Override
public List<Generation> getResults() {...}

// other methods omitted
}

ChatResponse 类包含AI模型的输出,每个<font style="color:rgb(25, 30, 30);">Generation</font>实例包含单个提示可能产生的多个输出之一,同时还包含关于AI模型响应的<font style="color:rgb(25, 30, 30);">ChatResponseMe</font><font style="color:rgb(25, 30, 30);">tadata</font>元数据。

生成结果(Generation)

最后,Generation 类继承自<font style="color:rgb(25, 30, 30);">ModelResult</font>,用于表示模型输出(助手消息)及相关元数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
public class Generation implements ModelResult<AssistantMessage> {

private final AssistantMessage assistantMessage;
private ChatGenerationMetadata chatGenerationMetadata;

@Override
public AssistantMessage getOutput() {...}

@Override
public ChatGenerationMetadata getMetadata() {...}

// other methods omitted
}

可用实现

下图展示了统一接口,即<font style="color:rgb(25, 30, 30);">ChatModel</font><font style="color:rgb(25, 30, 30);">StreamingChatModel</font>,这些接口用于与来自不同提供商的各种人工智能聊天模型进行交互,能够轻松集成和切换不同的人工智能服务,同时为客户端应用程序保持一致的应用程序编程接口:

  • OpenAI Chat Completion(支持流式传输、多模态和函数调用)
  • Microsoft Azure Open AI Chat Completion(支持流式传输和函数调用)
  • Ollama Chat Completion(支持流式传输、多模态和函数调用)
  • Hugging Face Chat Completion(不支持流式传输)
  • Google Vertex AI Gemini Chat Completion(支持流式传输、多模态和函数调用)
  • Amazon Bedrock
    • Cohere Chat Completion
    • Llama Chat Completion
    • Titan Chat Completion
    • Anthropic Chat Completion
    • Jurassic2 Chat Completion
  • Mistral AI Chat Completion(支持流式传输和函数调用)
  • Anthropic Chat Completion(支持流式传输和函数调用)

ChatModel API

Spring AI Chat Model API 建立在 Spring AI 通用模型 API 之上,提供聊天特定的抽象和实现。这允许轻松集成和切换不同的 AI 服务,同时保持客户端应用程序的一致 API。以下类图说明了 Spring AI Chat Model API 的主要类和接口:

ChatModels Comparison

下图比较了 Spring AI 支持的各种 Chat Models,详细说明了它们的能力:

  • 多模态:模型可以处理的输入类型(例如,文本、图像、音频、视频)。
  • 工具/功能:模型是否支持函数调用或工具使用。
  • 流式传输:模型是否提供流式响应。
  • 重试:对重试机制的支持。
  • 可观测性:监控和调试的功能。
  • 内置 JSON:对 JSON 输出的原生支持。
  • 本地部署:模型是否可以在本地运行。
  • 与 OpenAI API 兼容:模型是否与 OpenAI 的 API 兼容。
提供商 多模态 工具/功能 流式传输 重试 可观测性 内置JSON 本地 与OpenAI API 兼容
Anthropic Claude text, pdf, image
Azure OpenAI text, image
Google VertexAI Gemini text, pdf, image, audio, video
Groq (OpenAI-proxy) text, image
HuggingFace text
Mistral AI text
MiniMax text
Moonshot AI text
NVIDIA (OpenAI-proxy) text, image
OCI GenAI/Cohere text
Ollama text, image
OpenAI In: text, image Out: text, audio
Perplexity (OpenAI-proxy) text
QianFan text
ZhiPu AI text
Watsonx.AI text
Amazon Bedrock Converse text, image, video, docs (pdf, html, md, docx …)
Amazon Bedrock/Cohere
(已弃用,转而使用 Bedrock Converse)
text
Amazon Bedrock/Jurassic
(已弃用,转而使用 Bedrock Converse)
text
Amazon Bedrock/Llama
(已弃用,转而使用 Bedrock Converse)
text
Amazon Bedrock/Titan
(已弃用,转而使用 Bedrock Converse)
text
Amazon Bedrock/Anthropic 3
(已弃用,转而使用 Bedrock Converse)
text

请注意,表格中的“已弃用,转而使用 Bedrock Converse”表示该服务已被 Amazon Bedrock Converse 替代。这个表格为您提供了不同 Chat Models 的功能对比,方便您根据需求选择合适的模型。