Spring AI中的ChatClient和ChatModel在功能和用途上存在显著的区别。以下是对两者的详细比较:
ChatModel
- 定义与功能:
- ChatModel是Spring AI中用于处理自然语言对话的组件,它提供了与大型语言模型(LLM)交互的接口。
- ChatModel支持调用大模型,包括朴素的调用方式(通过Call方法)和流式调用方式(通过Stream方法)。
- ChatModel通常针对聊天对话进行了优化,使用格式化的聊天消息作为输入和输出。
- 应用场景:
- ChatModel适用于需要处理自然语言对话的场景,如聊天机器人、对话系统等。
- 代码:
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");
}
}
ChatClient
- 定义与功能:
- ChatClient是Spring AI中提供的一个高级客户端接口,用于与AI模型进行通信。
- ChatClient隐藏了与LLM及其他组件交互的复杂性,为开发者提供了流畅的API来构建和发送提示(Prompt)给AI模型,并接收模型的响应。
- ChatClient支持同步和反应式(Reactive)编程模型,允许开发者以异步方式获取模型响应。
- 应用场景与功能拓展:
- ChatClient适用于需要快速集成AI模型并提供AI服务的场景。
- ChatClient提供了多种方法来格式化AI模型的响应,包括返回ChatResponse对象(包含元数据和多个子响应)和将模型响应映射到Java Bean的转换。
- ChatClient还支持聊天记忆(Chat Memory)和工具/函数调用(Function Calling)等高级功能,进一步增强了与AI模型的交互能力。
- 代码:
/**
* Client to perform stateless requests to an AI Model, using a fluent API.
*
* Use {@link ChatClient#builder(ChatModel)} to prepare an instance.
*
* @author Mark Pollack
* @author Christian Tzolov
* @author Josh Long
* @author Arjen Poutsma
* @author Thomas Vitale
* @since 1.0.0
*/
public interface ChatClient {
static ChatClient create(ChatModel chatModel) {
return create(chatModel, ObservationRegistry.NOOP);
}
static ChatClient create(ChatModel chatModel, ObservationRegistry observationRegistry) {
return create(chatModel, observationRegistry, null);
}
static ChatClient create(ChatModel chatModel, ObservationRegistry observationRegistry,
@Nullable ChatClientObservationConvention observationConvention) {
Assert.notNull(chatModel, "chatModel cannot be null");
Assert.notNull(observationRegistry, "observationRegistry cannot be null");
return builder(chatModel, observationRegistry, observationConvention).build();
}
static Builder builder(ChatModel chatModel) {
return builder(chatModel, ObservationRegistry.NOOP, null);
}
static Builder builder(ChatModel chatModel, ObservationRegistry observationRegistry,
@Nullable ChatClientObservationConvention customObservationConvention) {
Assert.notNull(chatModel, "chatModel cannot be null");
Assert.notNull(observationRegistry, "observationRegistry cannot be null");
return new DefaultChatClientBuilder(chatModel, observationRegistry, customObservationConvention);
}
ChatClientRequestSpec prompt();
ChatClientRequestSpec prompt(String content);
ChatClientRequestSpec prompt(Prompt prompt);
/**
* Return a {@link ChatClient.Builder} to create a new {@link ChatClient} whose
* settings are replicated from the default {@link ChatClientRequestSpec} of this
* client.
*/
Builder mutate();
interface PromptUserSpec {
PromptUserSpec text(String text);
PromptUserSpec text(Resource text, Charset charset);
PromptUserSpec text(Resource text);
PromptUserSpec params(Map<String, Object> p);
PromptUserSpec param(String k, Object v);
PromptUserSpec media(Media... media);
PromptUserSpec media(MimeType mimeType, URL url);
PromptUserSpec media(MimeType mimeType, Resource resource);
}
/**
* Specification for a prompt system.
*/
interface PromptSystemSpec {
PromptSystemSpec text(String text);
PromptSystemSpec text(Resource text, Charset charset);
PromptSystemSpec text(Resource text);
PromptSystemSpec params(Map<String, Object> p);
PromptSystemSpec param(String k, Object v);
}
interface AdvisorSpec {
AdvisorSpec param(String k, Object v);
AdvisorSpec params(Map<String, Object> p);
AdvisorSpec advisors(Advisor... advisors);
AdvisorSpec advisors(List<Advisor> advisors);
}
interface CallResponseSpec {
@Nullable
<T> T entity(ParameterizedTypeReference<T> type);
@Nullable
<T> T entity(StructuredOutputConverter<T> structuredOutputConverter);
@Nullable
<T> T entity(Class<T> type);
@Nullable
ChatResponse chatResponse();
@Nullable
String content();
<T> ResponseEntity<ChatResponse, T> responseEntity(Class<T> type);
<T> ResponseEntity<ChatResponse, T> responseEntity(ParameterizedTypeReference<T> type);
<T> ResponseEntity<ChatResponse, T> responseEntity(StructuredOutputConverter<T> structuredOutputConverter);
}
interface StreamResponseSpec {
Flux<ChatResponse> chatResponse();
Flux<String> content();
}
interface CallPromptResponseSpec {
String content();
List<String> contents();
ChatResponse chatResponse();
}
interface StreamPromptResponseSpec {
Flux<ChatResponse> chatResponse();
Flux<String> content();
}
interface ChatClientRequestSpec {
/**
* Return a {@code ChatClient.Builder} to create a new {@code ChatClient} whose
* settings are replicated from this {@code ChatClientRequest}.
*/
Builder mutate();
ChatClientRequestSpec advisors(Consumer<AdvisorSpec> consumer);
ChatClientRequestSpec advisors(Advisor... advisors);
ChatClientRequestSpec advisors(List<Advisor> advisors);
ChatClientRequestSpec messages(Message... messages);
ChatClientRequestSpec messages(List<Message> messages);
<T extends ChatOptions> ChatClientRequestSpec options(T options);
ChatClientRequestSpec tools(String... toolNames);
ChatClientRequestSpec tools(Object... toolObjects);
ChatClientRequestSpec toolCallbacks(FunctionCallback... toolCallbacks);
/**
* @deprecated use {@link #functions(FunctionCallback...)} instead.
*/
@Deprecated
<I, O> ChatClientRequestSpec function(String name, String description,
java.util.function.Function<I, O> function);
/**
* @deprecated use {@link #functions(FunctionCallback...)} instead.
*/
@Deprecated
<I, O> ChatClientRequestSpec function(String name, String description,
java.util.function.BiFunction<I, ToolContext, O> function);
<I, O> ChatClientRequestSpec functions(FunctionCallback... functionCallbacks);
/**
* @deprecated use {@link #functions(FunctionCallback...)} instead.
*/
@Deprecated
<I, O> ChatClientRequestSpec function(String name, String description, Class<I> inputType,
java.util.function.Function<I, O> function);
ChatClientRequestSpec functions(String... functionBeanNames);
ChatClientRequestSpec toolContext(Map<String, Object> toolContext);
ChatClientRequestSpec system(String text);
ChatClientRequestSpec system(Resource textResource, Charset charset);
ChatClientRequestSpec system(Resource text);
ChatClientRequestSpec system(Consumer<PromptSystemSpec> consumer);
ChatClientRequestSpec user(String text);
ChatClientRequestSpec user(Resource text, Charset charset);
ChatClientRequestSpec user(Resource text);
ChatClientRequestSpec user(Consumer<PromptUserSpec> consumer);
CallResponseSpec call();
StreamResponseSpec stream();
}
/**
* A mutable builder for creating a {@link ChatClient}.
*/
interface Builder {
Builder defaultAdvisors(Advisor... advisor);
Builder defaultAdvisors(Consumer<AdvisorSpec> advisorSpecConsumer);
Builder defaultAdvisors(List<Advisor> advisors);
Builder defaultOptions(ChatOptions chatOptions);
Builder defaultUser(String text);
Builder defaultUser(Resource text, Charset charset);
Builder defaultUser(Resource text);
Builder defaultUser(Consumer<PromptUserSpec> userSpecConsumer);
Builder defaultSystem(String text);
Builder defaultSystem(Resource text, Charset charset);
Builder defaultSystem(Resource text);
Builder defaultSystem(Consumer<PromptSystemSpec> systemSpecConsumer);
Builder defaultTools(String... toolNames);
Builder defaultTools(Object... toolObjects);
Builder defaultToolCallbacks(FunctionCallback... toolCallbacks);
/**
* @deprecated use {@link #defaultFunctions(FunctionCallback...)} instead.
*/
@Deprecated
<I, O> Builder defaultFunction(String name, String description, java.util.function.Function<I, O> function);
/**
* @deprecated use {@link #defaultFunctions(FunctionCallback...)} instead.
*/
@Deprecated
<I, O> Builder defaultFunction(String name, String description,
java.util.function.BiFunction<I, ToolContext, O> function);
Builder defaultFunctions(String... functionNames);
Builder defaultFunctions(FunctionCallback... functionCallbacks);
Builder defaultToolContext(Map<String, Object> toolContext);
Builder clone();
ChatClient build();
}
}
二者区别
- 抽象层次:ChatModel更偏向于底层,提供了与大型语言模型交互的接口;而ChatClient则更偏向于高层,为开发者提供了更简洁、更易于使用的API。
- 功能差异:ChatModel主要关注于调用大模型和处理自然语言对话;而ChatClient则提供了更多高级功能,如格式化响应、聊天记忆和函数调用等。
- 使用场景:ChatModel更适合用于构建需要处理自然语言对话的组件或系统;而ChatClient则更适合用于快速集成AI模型并提供AI服务的场景。
综上所述,Spring AI中的ChatClient和ChatModel在抽象层次、功能差异和使用场景等方面存在显著区别。开发者可以根据具体需求选择合适的组件来构建AI应用。