admin管理员组

文章数量:1032252

Spring AI之ChatClient源码分析

简介

ChatClient 是一个接口,它定义了一个与聊天服务交互的客户端。这个接口主要用于创建聊天客户端对象,设置请求规范,以及发起聊天请求。以下是接口中各个方法的详细解释:

静态方法:

create(ChatModel chatModel):创建一个 ChatClient 实例,使用给定的 ChatModel 对象作为基础。 builder(ChatModel chatModel):返回一个 ChatClient.Builder,允许用户构建自定义的 ChatClient 实例,基于给定的 ChatModel。

非静态方法:

prompt():返回一个 ChatClientRequestSpec,用于设置聊天请求的规范,如提示信息等。 prompt(Prompt prompt):设置聊天请求规范中的提示信息,参数 prompt 不能为 null。

内部接口:

PromptUserSpec 和 PromptSystemSpec:分别用于配置用户提示和系统提示的详细信息,如文本、参数、媒体资源等。 AdvisorSpec:用于设置请求响应的顾问对象,可以添加参数和顾问列表。 CallResponseSpec 和 StreamResponseSpec:分别表示调用响应和流式响应的规格,提供了获取聊天响应内容的方法。

Builder 接口:

Builder:提供了一种构建 ChatClient 对象的方式,允许设置默认的顾问、选项、用户和系统提示等。 默认方法(已过时): call(String message) 和 call(Message... messages):这些方法已过时,用于发起基于单个消息或多个消息的聊天请求,返回第一代的输出内容。 call(Prompt prompt):过时的方法,用于根据 Prompt 对象发起聊天请求,返回 ChatResponse 对象。

总的来说,ChatClient 接口提供了构建和配置聊天客户端对象的灵活性,以及发起和处理聊天请求的能力。用户可以通过 ChatClient.Builder 来定制客户端的行为,然后使用 prompt() 和 prompt(Prompt prompt) 方法设置请求规范,最后通过 call() 方法发起聊天请求。

源码详解

代码语言:javascript代码运行次数:0运行复制
package org.springframework.ai.chat.client;

import java.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import reactor.core.publisher.Flux;

import org.springframework.ai.chat.messages.Media;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.converter.StructuredOutputConverter;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.Resource;
import org.springframework.util.MimeType;

/**
 * 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
 * @since 1.0.0
 */
public interface ChatClient {

    /**
     * 根据传入的ChatModel创建一个ChatClient对象
     *
     * @param chatModel ChatModel对象,用于创建ChatClient
     * @return ChatClient对象
     */
    static ChatClient create(ChatModel chatModel) {
       return builder(chatModel).build();
    }

    /**
     * 返回一个根据ChatModel对象创建的ChatClient.Builder对象
     *
     * @param chatModel ChatModel对象,用于构建ChatClient
     * @return ChatClient.Builder对象
     */
    static Builder builder(ChatModel chatModel) {
       return new DefaultChatClientBuilder(chatModel);
    }

    /**
     * 提示ChatClientRequestSpec。
     *
     * @return 返回ChatClientRequestSpec对象,用于设置请求规范。
     */
    ChatClientRequestSpec prompt();

    /**
     * 设置聊天客户端请求规范中的提示信息。
     *
     * @param prompt 聊天提示信息对象,不能为null。
     * @return 返回聊天客户端请求规范对象,用于设置聊天请求规范。
     * @throws NullPointerException 如果传入的prompt为null,则抛出NullPointerException异常。
     */
    ChatClientPromptRequestSpec prompt(Prompt prompt);

    /**
     * 返回一个用于创建新的 {@link ChatClient} 的 {@link ChatClient.Builder},其设置将复制自当前客户端的默认 {@link ChatClientRequestSpec}。
     *
     * @return 返回一个用于创建新的 {@link ChatClient} 的 {@link ChatClient.Builder}
     */
    Builder mutate();

    interface PromptUserSpec {

       /**
        * 设置文本内容并返回 PromptUserSpec 对象,用于继续配置 PromptUser。
        *
        * @param text 文本内容
        * @return PromptUserSpec 对象,用于继续配置 PromptUser
        */
       PromptUserSpec text(String text);

       /**
        * 设置提示用户时的文本内容,并返回PromptUserSpec对象以继续配置。
        *
        * @param text 文本资源
        * @param charset 文本内容的字符集
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec text(Resource text, Charset charset);

       /**
        * 设置提示用户时的文本内容,并返回PromptUserSpec对象以继续配置。
        *
        * @param text 文本资源,包含提示用户时需要显示的文本内容
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec text(Resource text);

       /**
        * 设置提示用户时的参数,并返回PromptUserSpec对象以继续配置。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec params(Map<String, Object> p);

       /**
        * 设置提示用户时的参数。
        *
        * @param k 参数名
        * @param v 参数值
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec param(String k, Object v);

       /**
        * 设置提示用户时显示的媒体资源,并返回PromptUserSpec对象以继续配置。
        *
        * @param media 一个或多个媒体资源对象,用于在提示用户时显示
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(Media... media);

       /**
        * 设置提示用户时显示的媒体资源的MIME类型和URL地址,并返回PromptUserSpec对象以继续配置。
        *
        * @param mimeType 媒体资源的MIME类型
        * @param url 媒体资源的URL地址
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(MimeType mimeType, URL url);

       /**
        * 设置提示用户时显示的媒体资源的MIME类型和资源对象,并返回PromptUserSpec对象以继续配置。
        *
        * @param mimeType 媒体资源的MIME类型
        * @param resource 媒体资源的Resource对象
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(MimeType mimeType, Resource resource);

       /**
        * 返回一个包含所有媒体对象的列表。
        *
        * @return 包含所有媒体对象的列表
        */
       List<Media> media();

    }

    interface PromptSystemSpec {

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 提示系统的文本内容
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(String text);

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 文本资源
        * @param charset 字符集
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(Resource text, Charset charset);

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 文本资源,包含提示系统需要显示的文本内容
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(Resource text);

       /**
        * 设置提示系统的参数。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec params(Map<String, Object> p);

       /**
        * 设置提示系统的参数。
        *
        * @param k 参数名
        * @param v 参数值
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec param(String k, Object v);

    }

    interface AdvisorSpec {

       /**
        * 设置参数,并返回AdvisorSpec对象,用于继续配置Advisor。
        *
        * @param k 参数名
        * @param v 参数值
        * @return 返回AdvisorSpec对象,用于继续配置Advisor
        */
       AdvisorSpec param(String k, Object v);

       /**
        * 设置Advisor的参数。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec params(Map<String, Object> p);

       /**
        * 设置请求响应的顾问对象列表。
        *
        * @param advisors 请求响应的顾问对象列表
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec advisors(RequestResponseAdvisor... advisors);

       /**
        * 设置顾问对象列表。
        *
        * @param advisors 请求响应顾问对象列表
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec advisors(List<RequestResponseAdvisor> advisors);

    }

    /**
     * 回调的响应规格
     */
    interface CallResponseSpec {

       /**
        * 根据提供的泛型类型引用将请求结果转换为指定的实体类型
        *
        * @param type 泛型类型引用,用于指定转换后的实体类型
        * @param <T>  转换后的实体类型
        * @return 转换后的实体对象
        */
       <T> T entity(ParameterizedTypeReference<T> type);

       /**
        * 将请求结果映射为指定类型的实体对象
        *
        * @param structuredOutputConverter 结构化输出转换器,用于将请求结果转换为指定类型的实体对象
        * @param <T> 实体对象泛型类型
        * @return 映射后的实体对象
        */
       <T> T entity(StructuredOutputConverter<T> structuredOutputConverter);

       /**
        * 将请求结果映射为指定类型的实体对象
        *
        * @param type 实体对象类型
        * @param <T>  实体对象泛型类型
        * @return 映射后的实体对象
        */
       <T> T entity(Class<T> type);

       /**
        * 发起聊天请求,获取聊天响应。
        *
        * @return 聊天响应对象,包含聊天结果信息。
        */
       ChatResponse chatResponse();

       /**
        * 获取内容字符串。
        *
        * @return 返回内容字符串。
        */
       String content();

       /**
        * 返回一个响应实体,包含聊天响应和泛型类型T的实体。
        *
        * @param type 泛型类型T的类对象,用于解析响应中的body内容。
        * @param <T>  泛型类型T,表示响应实体中body的内容类型。
        * @return 响应实体,包含聊天响应和泛型类型T的实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(Class<T> type);

       /**
        * 返回一个包含聊天响应和泛型类型T的实体的响应实体。
        *
        * @param type 用于指定泛型类型T的ParameterizedTypeReference引用。
        * @param <T> 泛型类型T,表示响应实体中body的内容类型。
        * @return 包含聊天响应和泛型类型T的实体的响应实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(ParameterizedTypeReference<T> type);

       /**
        * 返回一个包含聊天响应和泛型类型T的实体的响应实体。
        *
        * @param structuredOutputConverter 用于转换响应实体的结构化输出转换器。
        * @param <T> 泛型类型T,表示响应实体中body的内容类型。
        * @return 包含聊天响应和泛型类型T的实体的响应实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(StructuredOutputConverter<T> structuredOutputConverter);

    }

    /**
     * 流式响应的规格
     */
    interface StreamResponseSpec {

       /**
        * 返回一个Flux对象,其中包含ChatResponse类型的数据流。
        *
        * @return 包含ChatResponse类型数据的Flux对象
        */
       Flux<ChatResponse> chatResponse();

       /**
        * 返回一个包含字符串的Flux对象。
        *
        * @return 包含字符串的Flux对象
        */
       Flux<String> content();

    }

    /**
     * 聊天客户端的请求规格
     */
    interface ChatClientPromptRequestSpec {

       /**
        * 发起呼叫提示响应的调用请求。
        *
        * @return 返回 CallPromptResponseSpec 类型的对象,用于配置和获取呼叫提示响应的相关信息。
        */
       CallPromptResponseSpec call();

       /**
        * 发起流提示响应的调用请求。
        *
        * @return 返回StreamPromptResponseSpec类型的对象,用于配置和获取流提示响应的相关信息。
        */
       StreamPromptResponseSpec stream();

    }

    interface CallPromptResponseSpec {

       /**
        * 返回内容字符串。
        *
        * @return 内容字符串
        */
       String content();

       /**
        * 获取内容列表。
        *
        * @return List<String> 返回一个字符串列表,包含特定的内容。
        */
       List<String> contents();

       /**
        * 获得聊天响应的方法。
        *
        * 该方法用于发起一个聊天请求,并返回相应的聊天内容。
        * 设计该方法的目的是为了提供一种与聊天机器人交互的方式,
        * 使得用户可以通过调用这个方法来获取机器人生成的聊天回复。
        *
        * @return ChatResponse 返回一个ChatResponse对象,该对象包含了聊天机器人的响应内容。
        */
       ChatResponse chatResponse();

    }

    /**
     * StreamPromptResponseSpec 接口定义了流式响应规范,用于处理聊天响应的流。
     * 该接口主要面向异步编程模型,利用Reactor框架的Flux类型处理响应的序列。
     */
    interface StreamPromptResponseSpec {

        /**
         * 提供一个Flux实例,用于发布聊天响应。
         * <p>
         * 聊天响应(ChatResponse)是一个包含聊天具体内容和元数据的实体。
         * 通过这个方法,调用者可以以异步流的形式获取聊天响应。
         *
         * @return Flux<ChatResponse>,一个异步序列,发布聊天响应。
         */
        Flux<ChatResponse> chatResponse();

        /**
         * 提供一个Flux实例,用于发布聊天内容。
         * <p>
         * 这个方法专注于发布聊天内容的字符串表示,而不包括其他元数据。
         * 调用者可以通过这个流专注于聊天的文本内容。
         *
         * @return Flux<String>,一个异步序列,发布聊天内容的字符串形式。
         */
        public Flux<String> content();

    }

    /**
     * 聊天客户端请求规格接口。
     * 该接口定义了构建聊天客户端请求的各种方法,允许逐步构建请求规格,
     * 包括但不限于设置顾问、消息、选项、功能和系统及用户提示。
     */
    interface ChatClientRequestSpec {

        /**
         * 获取构建器,用于修改请求规格。
         *
         * @return 构建器实例,用于进一步定制请求规格。
         */
        Builder mutate();

        /**
         * 使用消费者回调来配置顾问规格。
         *
         * @param consumer 一个消费AdvisorSpec的Lambda表达式,用于定制顾问规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(Consumer<AdvisorSpec> consumer);

        /**
         * 添加一个或多个请求响应顾问到请求规格中。
         *
         * @param advisors 一个RequestResponseAdvisor数组,用于定制请求的处理。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(RequestResponseAdvisor... advisors);

        /**
         * 添加一个顾问列表到请求规格中。
         *
         * @param advisors 一个包含RequestResponseAdvisor的列表。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(List<RequestResponseAdvisor> advisors);

        /**
         * 添加一个或多个消息到请求规格中。
         *
         * @param messages 一个Message数组,用于在请求中发送的消息。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec messages(Message... messages);

        /**
         * 添加一个消息列表到请求规格中。
         *
         * @param messages 一个包含Message的列表。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec messages(List<Message> messages);

        /**
         * 为请求添加特定选项。
         *
         * @param options 一个实现ChatOptions接口的实例,用于定制请求选项。
         * @return 当前请求规格实例,允许链式调用。
         */
        <T extends ChatOptions> ChatClientRequestSpec options(T options);

        /**
         * 为请求添加一个功能,包括名称、描述和功能本身。
         *
         * @param name 功能名称。
         * @param description 功能描述。
         * @param function 功能的具体实现,作为一个函数接口。
         * @param <I> 输入类型。
         * @param <O> 输出类型。
         * @return 当前请求规格实例,允许链式调用。
         */
        <I, O> ChatClientRequestSpec function(String name, String description,
                java.util.function.Function<I, O> function);

        /**
         * 通过功能 bean 名称添加多个功能到请求规格中。
         *
         * @param functionBeanNames 功能 bean 的名称数组。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec functions(String... functionBeanNames);

        /**
         * 为请求添加系统文本。
         *
         * @param text 系统文本内容。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(String text);

        /**
         * 为请求添加系统文本资源,指定字符集。
         *
         * @param textResource 系统文本资源。
         * @param charset 指定的字符集。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Resource textResource, Charset charset);

        /**
         * 为请求添加系统文本资源。
         *
         * @param textResource 系统文本资源。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Resource text);

        /**
         * 使用消费者回调来配置系统规格。
         *
         * @param consumer 一个消费PromptSystemSpec的Lambda表达式,用于定制系统规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Consumer<PromptSystemSpec> consumer);

        /**
         * 为请求添加用户文本。
         *
         * @param text 用户文本内容。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(String text);

        /**
         * 为请求添加用户文本资源,指定字符集。
         *
         * @param textResource 用户文本资源。
         * @param charset 指定的字符集。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Resource text, Charset charset);

        /**
         * 为请求添加用户文本资源。
         *
         * @param textResource 用户文本资源。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Resource text);

        /**
         * 使用消费者回调来配置用户规格。
         *
         * @param consumer 一个消费PromptUserSpec的Lambda表达式,用于定制用户规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Consumer<PromptUserSpec> consumer);

        /**
         * 构建一个调用响应规格。
         *
         * @return 调用响应规格实例。
         */
        CallResponseSpec call();

        /**
         * 构建一个流式响应规格。
         *
         * @return 流式响应规格实例。
         */
        StreamResponseSpec stream();

    }

    /**
     * A mutable builder for creating a {@link ChatClient}.
     */
    interface Builder {

       Builder defaultAdvisors(RequestResponseAdvisor... advisor);

       Builder defaultAdvisors(Consumer<AdvisorSpec> advisorSpecConsumer);

       Builder defaultAdvisors(List<RequestResponseAdvisor> advisors);

       ChatClient build();

       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);

       <I, O> Builder defaultFunction(String name, String description, java.util.function.Function<I, O> function);

       Builder defaultFunctions(String... functionNames);

    }

    /**
     * Calls the underlying chat model with a prompt message and returns the output
     * content of the first generation.
     * @param message The message to be used as a prompt for the chat model.
     * @return The output content of the first generation.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method
     * builder(chatModel).build().prompt().user(message).call().content() instead
     *
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    default String call(String message) {
       var prompt = new Prompt(new UserMessage(message));
       var generation = call(prompt).getResult();
       return (generation != null) ? generation.getOutput().getContent() : "";
    }

    /**
     * Calls the underlying chat model with a prompt message and returns the output
     * content of the first generation.
     * @param messages The messages to be used as a prompt for the chat model.
     * @return The output content of the first generation.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method
     * builder(chatModel).build().prompt().messages(messages).call().content() instead.
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    default String call(Message... messages) {
       var prompt = new Prompt(Arrays.asList(messages));
       var generation = call(prompt).getResult();
       return (generation != null) ? generation.getOutput().getContent() : "";
    }

    /**
     * Calls the underlying chat model with a prompt and returns the corresponding chat
     * response.
     * @param prompt The prompt to be used for the chat model.
     * @return The chat response containing the generated messages.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method builder(chatModel).build().prompt(prompt).call()
     * instead.
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    ChatResponse call(Prompt prompt);

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-06-05,如有侵权请联系 cloudcommunity@tencent 删除源码分析spring对象配置系统

Spring AI之ChatClient源码分析

简介

ChatClient 是一个接口,它定义了一个与聊天服务交互的客户端。这个接口主要用于创建聊天客户端对象,设置请求规范,以及发起聊天请求。以下是接口中各个方法的详细解释:

静态方法:

create(ChatModel chatModel):创建一个 ChatClient 实例,使用给定的 ChatModel 对象作为基础。 builder(ChatModel chatModel):返回一个 ChatClient.Builder,允许用户构建自定义的 ChatClient 实例,基于给定的 ChatModel。

非静态方法:

prompt():返回一个 ChatClientRequestSpec,用于设置聊天请求的规范,如提示信息等。 prompt(Prompt prompt):设置聊天请求规范中的提示信息,参数 prompt 不能为 null。

内部接口:

PromptUserSpec 和 PromptSystemSpec:分别用于配置用户提示和系统提示的详细信息,如文本、参数、媒体资源等。 AdvisorSpec:用于设置请求响应的顾问对象,可以添加参数和顾问列表。 CallResponseSpec 和 StreamResponseSpec:分别表示调用响应和流式响应的规格,提供了获取聊天响应内容的方法。

Builder 接口:

Builder:提供了一种构建 ChatClient 对象的方式,允许设置默认的顾问、选项、用户和系统提示等。 默认方法(已过时): call(String message) 和 call(Message... messages):这些方法已过时,用于发起基于单个消息或多个消息的聊天请求,返回第一代的输出内容。 call(Prompt prompt):过时的方法,用于根据 Prompt 对象发起聊天请求,返回 ChatResponse 对象。

总的来说,ChatClient 接口提供了构建和配置聊天客户端对象的灵活性,以及发起和处理聊天请求的能力。用户可以通过 ChatClient.Builder 来定制客户端的行为,然后使用 prompt() 和 prompt(Prompt prompt) 方法设置请求规范,最后通过 call() 方法发起聊天请求。

源码详解

代码语言:javascript代码运行次数:0运行复制
package org.springframework.ai.chat.client;

import java.URL;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

import reactor.core.publisher.Flux;

import org.springframework.ai.chat.messages.Media;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.UserMessage;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.chat.model.ChatResponse;
import org.springframework.ai.chat.prompt.ChatOptions;
import org.springframework.ai.chat.prompt.Prompt;
import org.springframework.ai.converter.StructuredOutputConverter;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.core.io.Resource;
import org.springframework.util.MimeType;

/**
 * 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
 * @since 1.0.0
 */
public interface ChatClient {

    /**
     * 根据传入的ChatModel创建一个ChatClient对象
     *
     * @param chatModel ChatModel对象,用于创建ChatClient
     * @return ChatClient对象
     */
    static ChatClient create(ChatModel chatModel) {
       return builder(chatModel).build();
    }

    /**
     * 返回一个根据ChatModel对象创建的ChatClient.Builder对象
     *
     * @param chatModel ChatModel对象,用于构建ChatClient
     * @return ChatClient.Builder对象
     */
    static Builder builder(ChatModel chatModel) {
       return new DefaultChatClientBuilder(chatModel);
    }

    /**
     * 提示ChatClientRequestSpec。
     *
     * @return 返回ChatClientRequestSpec对象,用于设置请求规范。
     */
    ChatClientRequestSpec prompt();

    /**
     * 设置聊天客户端请求规范中的提示信息。
     *
     * @param prompt 聊天提示信息对象,不能为null。
     * @return 返回聊天客户端请求规范对象,用于设置聊天请求规范。
     * @throws NullPointerException 如果传入的prompt为null,则抛出NullPointerException异常。
     */
    ChatClientPromptRequestSpec prompt(Prompt prompt);

    /**
     * 返回一个用于创建新的 {@link ChatClient} 的 {@link ChatClient.Builder},其设置将复制自当前客户端的默认 {@link ChatClientRequestSpec}。
     *
     * @return 返回一个用于创建新的 {@link ChatClient} 的 {@link ChatClient.Builder}
     */
    Builder mutate();

    interface PromptUserSpec {

       /**
        * 设置文本内容并返回 PromptUserSpec 对象,用于继续配置 PromptUser。
        *
        * @param text 文本内容
        * @return PromptUserSpec 对象,用于继续配置 PromptUser
        */
       PromptUserSpec text(String text);

       /**
        * 设置提示用户时的文本内容,并返回PromptUserSpec对象以继续配置。
        *
        * @param text 文本资源
        * @param charset 文本内容的字符集
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec text(Resource text, Charset charset);

       /**
        * 设置提示用户时的文本内容,并返回PromptUserSpec对象以继续配置。
        *
        * @param text 文本资源,包含提示用户时需要显示的文本内容
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec text(Resource text);

       /**
        * 设置提示用户时的参数,并返回PromptUserSpec对象以继续配置。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec params(Map<String, Object> p);

       /**
        * 设置提示用户时的参数。
        *
        * @param k 参数名
        * @param v 参数值
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec param(String k, Object v);

       /**
        * 设置提示用户时显示的媒体资源,并返回PromptUserSpec对象以继续配置。
        *
        * @param media 一个或多个媒体资源对象,用于在提示用户时显示
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(Media... media);

       /**
        * 设置提示用户时显示的媒体资源的MIME类型和URL地址,并返回PromptUserSpec对象以继续配置。
        *
        * @param mimeType 媒体资源的MIME类型
        * @param url 媒体资源的URL地址
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(MimeType mimeType, URL url);

       /**
        * 设置提示用户时显示的媒体资源的MIME类型和资源对象,并返回PromptUserSpec对象以继续配置。
        *
        * @param mimeType 媒体资源的MIME类型
        * @param resource 媒体资源的Resource对象
        * @return PromptUserSpec对象,用于继续配置提示用户
        */
       PromptUserSpec media(MimeType mimeType, Resource resource);

       /**
        * 返回一个包含所有媒体对象的列表。
        *
        * @return 包含所有媒体对象的列表
        */
       List<Media> media();

    }

    interface PromptSystemSpec {

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 提示系统的文本内容
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(String text);

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 文本资源
        * @param charset 字符集
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(Resource text, Charset charset);

       /**
        * 设置提示系统的文本内容。
        *
        * @param text 文本资源,包含提示系统需要显示的文本内容
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec text(Resource text);

       /**
        * 设置提示系统的参数。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec params(Map<String, Object> p);

       /**
        * 设置提示系统的参数。
        *
        * @param k 参数名
        * @param v 参数值
        * @return 返回PromptSystemSpec对象,用于继续配置提示系统
        */
       PromptSystemSpec param(String k, Object v);

    }

    interface AdvisorSpec {

       /**
        * 设置参数,并返回AdvisorSpec对象,用于继续配置Advisor。
        *
        * @param k 参数名
        * @param v 参数值
        * @return 返回AdvisorSpec对象,用于继续配置Advisor
        */
       AdvisorSpec param(String k, Object v);

       /**
        * 设置Advisor的参数。
        *
        * @param p 包含参数的Map对象,其中key为参数名,value为参数值
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec params(Map<String, Object> p);

       /**
        * 设置请求响应的顾问对象列表。
        *
        * @param advisors 请求响应的顾问对象列表
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec advisors(RequestResponseAdvisor... advisors);

       /**
        * 设置顾问对象列表。
        *
        * @param advisors 请求响应顾问对象列表
        * @return 返回配置好的AdvisorSpec对象
        */
       AdvisorSpec advisors(List<RequestResponseAdvisor> advisors);

    }

    /**
     * 回调的响应规格
     */
    interface CallResponseSpec {

       /**
        * 根据提供的泛型类型引用将请求结果转换为指定的实体类型
        *
        * @param type 泛型类型引用,用于指定转换后的实体类型
        * @param <T>  转换后的实体类型
        * @return 转换后的实体对象
        */
       <T> T entity(ParameterizedTypeReference<T> type);

       /**
        * 将请求结果映射为指定类型的实体对象
        *
        * @param structuredOutputConverter 结构化输出转换器,用于将请求结果转换为指定类型的实体对象
        * @param <T> 实体对象泛型类型
        * @return 映射后的实体对象
        */
       <T> T entity(StructuredOutputConverter<T> structuredOutputConverter);

       /**
        * 将请求结果映射为指定类型的实体对象
        *
        * @param type 实体对象类型
        * @param <T>  实体对象泛型类型
        * @return 映射后的实体对象
        */
       <T> T entity(Class<T> type);

       /**
        * 发起聊天请求,获取聊天响应。
        *
        * @return 聊天响应对象,包含聊天结果信息。
        */
       ChatResponse chatResponse();

       /**
        * 获取内容字符串。
        *
        * @return 返回内容字符串。
        */
       String content();

       /**
        * 返回一个响应实体,包含聊天响应和泛型类型T的实体。
        *
        * @param type 泛型类型T的类对象,用于解析响应中的body内容。
        * @param <T>  泛型类型T,表示响应实体中body的内容类型。
        * @return 响应实体,包含聊天响应和泛型类型T的实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(Class<T> type);

       /**
        * 返回一个包含聊天响应和泛型类型T的实体的响应实体。
        *
        * @param type 用于指定泛型类型T的ParameterizedTypeReference引用。
        * @param <T> 泛型类型T,表示响应实体中body的内容类型。
        * @return 包含聊天响应和泛型类型T的实体的响应实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(ParameterizedTypeReference<T> type);

       /**
        * 返回一个包含聊天响应和泛型类型T的实体的响应实体。
        *
        * @param structuredOutputConverter 用于转换响应实体的结构化输出转换器。
        * @param <T> 泛型类型T,表示响应实体中body的内容类型。
        * @return 包含聊天响应和泛型类型T的实体的响应实体。
        */
       <T> ResponseEntity<ChatResponse, T> responseEntity(StructuredOutputConverter<T> structuredOutputConverter);

    }

    /**
     * 流式响应的规格
     */
    interface StreamResponseSpec {

       /**
        * 返回一个Flux对象,其中包含ChatResponse类型的数据流。
        *
        * @return 包含ChatResponse类型数据的Flux对象
        */
       Flux<ChatResponse> chatResponse();

       /**
        * 返回一个包含字符串的Flux对象。
        *
        * @return 包含字符串的Flux对象
        */
       Flux<String> content();

    }

    /**
     * 聊天客户端的请求规格
     */
    interface ChatClientPromptRequestSpec {

       /**
        * 发起呼叫提示响应的调用请求。
        *
        * @return 返回 CallPromptResponseSpec 类型的对象,用于配置和获取呼叫提示响应的相关信息。
        */
       CallPromptResponseSpec call();

       /**
        * 发起流提示响应的调用请求。
        *
        * @return 返回StreamPromptResponseSpec类型的对象,用于配置和获取流提示响应的相关信息。
        */
       StreamPromptResponseSpec stream();

    }

    interface CallPromptResponseSpec {

       /**
        * 返回内容字符串。
        *
        * @return 内容字符串
        */
       String content();

       /**
        * 获取内容列表。
        *
        * @return List<String> 返回一个字符串列表,包含特定的内容。
        */
       List<String> contents();

       /**
        * 获得聊天响应的方法。
        *
        * 该方法用于发起一个聊天请求,并返回相应的聊天内容。
        * 设计该方法的目的是为了提供一种与聊天机器人交互的方式,
        * 使得用户可以通过调用这个方法来获取机器人生成的聊天回复。
        *
        * @return ChatResponse 返回一个ChatResponse对象,该对象包含了聊天机器人的响应内容。
        */
       ChatResponse chatResponse();

    }

    /**
     * StreamPromptResponseSpec 接口定义了流式响应规范,用于处理聊天响应的流。
     * 该接口主要面向异步编程模型,利用Reactor框架的Flux类型处理响应的序列。
     */
    interface StreamPromptResponseSpec {

        /**
         * 提供一个Flux实例,用于发布聊天响应。
         * <p>
         * 聊天响应(ChatResponse)是一个包含聊天具体内容和元数据的实体。
         * 通过这个方法,调用者可以以异步流的形式获取聊天响应。
         *
         * @return Flux<ChatResponse>,一个异步序列,发布聊天响应。
         */
        Flux<ChatResponse> chatResponse();

        /**
         * 提供一个Flux实例,用于发布聊天内容。
         * <p>
         * 这个方法专注于发布聊天内容的字符串表示,而不包括其他元数据。
         * 调用者可以通过这个流专注于聊天的文本内容。
         *
         * @return Flux<String>,一个异步序列,发布聊天内容的字符串形式。
         */
        public Flux<String> content();

    }

    /**
     * 聊天客户端请求规格接口。
     * 该接口定义了构建聊天客户端请求的各种方法,允许逐步构建请求规格,
     * 包括但不限于设置顾问、消息、选项、功能和系统及用户提示。
     */
    interface ChatClientRequestSpec {

        /**
         * 获取构建器,用于修改请求规格。
         *
         * @return 构建器实例,用于进一步定制请求规格。
         */
        Builder mutate();

        /**
         * 使用消费者回调来配置顾问规格。
         *
         * @param consumer 一个消费AdvisorSpec的Lambda表达式,用于定制顾问规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(Consumer<AdvisorSpec> consumer);

        /**
         * 添加一个或多个请求响应顾问到请求规格中。
         *
         * @param advisors 一个RequestResponseAdvisor数组,用于定制请求的处理。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(RequestResponseAdvisor... advisors);

        /**
         * 添加一个顾问列表到请求规格中。
         *
         * @param advisors 一个包含RequestResponseAdvisor的列表。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec advisors(List<RequestResponseAdvisor> advisors);

        /**
         * 添加一个或多个消息到请求规格中。
         *
         * @param messages 一个Message数组,用于在请求中发送的消息。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec messages(Message... messages);

        /**
         * 添加一个消息列表到请求规格中。
         *
         * @param messages 一个包含Message的列表。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec messages(List<Message> messages);

        /**
         * 为请求添加特定选项。
         *
         * @param options 一个实现ChatOptions接口的实例,用于定制请求选项。
         * @return 当前请求规格实例,允许链式调用。
         */
        <T extends ChatOptions> ChatClientRequestSpec options(T options);

        /**
         * 为请求添加一个功能,包括名称、描述和功能本身。
         *
         * @param name 功能名称。
         * @param description 功能描述。
         * @param function 功能的具体实现,作为一个函数接口。
         * @param <I> 输入类型。
         * @param <O> 输出类型。
         * @return 当前请求规格实例,允许链式调用。
         */
        <I, O> ChatClientRequestSpec function(String name, String description,
                java.util.function.Function<I, O> function);

        /**
         * 通过功能 bean 名称添加多个功能到请求规格中。
         *
         * @param functionBeanNames 功能 bean 的名称数组。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec functions(String... functionBeanNames);

        /**
         * 为请求添加系统文本。
         *
         * @param text 系统文本内容。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(String text);

        /**
         * 为请求添加系统文本资源,指定字符集。
         *
         * @param textResource 系统文本资源。
         * @param charset 指定的字符集。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Resource textResource, Charset charset);

        /**
         * 为请求添加系统文本资源。
         *
         * @param textResource 系统文本资源。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Resource text);

        /**
         * 使用消费者回调来配置系统规格。
         *
         * @param consumer 一个消费PromptSystemSpec的Lambda表达式,用于定制系统规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec system(Consumer<PromptSystemSpec> consumer);

        /**
         * 为请求添加用户文本。
         *
         * @param text 用户文本内容。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(String text);

        /**
         * 为请求添加用户文本资源,指定字符集。
         *
         * @param textResource 用户文本资源。
         * @param charset 指定的字符集。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Resource text, Charset charset);

        /**
         * 为请求添加用户文本资源。
         *
         * @param textResource 用户文本资源。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Resource text);

        /**
         * 使用消费者回调来配置用户规格。
         *
         * @param consumer 一个消费PromptUserSpec的Lambda表达式,用于定制用户规格。
         * @return 当前请求规格实例,允许链式调用。
         */
        ChatClientRequestSpec user(Consumer<PromptUserSpec> consumer);

        /**
         * 构建一个调用响应规格。
         *
         * @return 调用响应规格实例。
         */
        CallResponseSpec call();

        /**
         * 构建一个流式响应规格。
         *
         * @return 流式响应规格实例。
         */
        StreamResponseSpec stream();

    }

    /**
     * A mutable builder for creating a {@link ChatClient}.
     */
    interface Builder {

       Builder defaultAdvisors(RequestResponseAdvisor... advisor);

       Builder defaultAdvisors(Consumer<AdvisorSpec> advisorSpecConsumer);

       Builder defaultAdvisors(List<RequestResponseAdvisor> advisors);

       ChatClient build();

       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);

       <I, O> Builder defaultFunction(String name, String description, java.util.function.Function<I, O> function);

       Builder defaultFunctions(String... functionNames);

    }

    /**
     * Calls the underlying chat model with a prompt message and returns the output
     * content of the first generation.
     * @param message The message to be used as a prompt for the chat model.
     * @return The output content of the first generation.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method
     * builder(chatModel).build().prompt().user(message).call().content() instead
     *
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    default String call(String message) {
       var prompt = new Prompt(new UserMessage(message));
       var generation = call(prompt).getResult();
       return (generation != null) ? generation.getOutput().getContent() : "";
    }

    /**
     * Calls the underlying chat model with a prompt message and returns the output
     * content of the first generation.
     * @param messages The messages to be used as a prompt for the chat model.
     * @return The output content of the first generation.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method
     * builder(chatModel).build().prompt().messages(messages).call().content() instead.
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    default String call(Message... messages) {
       var prompt = new Prompt(Arrays.asList(messages));
       var generation = call(prompt).getResult();
       return (generation != null) ? generation.getOutput().getContent() : "";
    }

    /**
     * Calls the underlying chat model with a prompt and returns the corresponding chat
     * response.
     * @param prompt The prompt to be used for the chat model.
     * @return The chat response containing the generated messages.
     * @deprecated This method is deprecated as of version 1.0.0 M1 and will be removed in
     * a future release. Use the method builder(chatModel).build().prompt(prompt).call()
     * instead.
     */
    @Deprecated(since = "1.0.0 M1", forRemoval = true)
    ChatResponse call(Prompt prompt);

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。 原始发表:2024-06-05,如有侵权请联系 cloudcommunity@tencent 删除源码分析spring对象配置系统

本文标签: Spring AI之ChatClient源码分析