mirror of
				https://gitee.com/hhyykk/ipms-sjy.git
				synced 2025-10-31 10:18:42 +08:00 
			
		
		
		
	百度 文心一言 适配chatOptions
This commit is contained in:
		| @@ -1,10 +1,8 @@ | |||||||
| package cn.iocoder.yudao.framework.ai.chatyiyan; | package cn.iocoder.yudao.framework.ai.chatyiyan; | ||||||
|  |  | ||||||
| import cn.iocoder.yudao.framework.ai.chat.ChatClient; | import cn.hutool.core.bean.BeanUtil; | ||||||
| import cn.iocoder.yudao.framework.ai.chat.ChatResponse; | import cn.iocoder.yudao.framework.ai.chat.*; | ||||||
| import cn.iocoder.yudao.framework.ai.chat.Generation; | import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; | ||||||
| import cn.iocoder.yudao.framework.ai.chat.StreamingChatClient; |  | ||||||
| import cn.iocoder.yudao.framework.ai.chat.messages.Message; |  | ||||||
| import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | ||||||
| import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanChatCompletion; | import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanChatCompletion; | ||||||
| import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanChatCompletionRequest; | import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanChatCompletionRequest; | ||||||
| @@ -18,7 +16,6 @@ import org.springframework.retry.support.RetryTemplate; | |||||||
| import reactor.core.publisher.Flux; | import reactor.core.publisher.Flux; | ||||||
|  |  | ||||||
| import java.time.Duration; | import java.time.Duration; | ||||||
| import java.util.ArrayList; |  | ||||||
| import java.util.List; | import java.util.List; | ||||||
|  |  | ||||||
| /** | /** | ||||||
| @@ -32,10 +29,17 @@ public class YiYanChatClient implements ChatClient, StreamingChatClient { | |||||||
|  |  | ||||||
|     private YiYanApi yiYanApi; |     private YiYanApi yiYanApi; | ||||||
|  |  | ||||||
|  |     private YiYanOptions yiYanOptions; | ||||||
|  |  | ||||||
|     public YiYanChatClient(YiYanApi yiYanApi) { |     public YiYanChatClient(YiYanApi yiYanApi) { | ||||||
|         this.yiYanApi = yiYanApi; |         this.yiYanApi = yiYanApi; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     public YiYanChatClient(YiYanApi yiYanApi, YiYanOptions yiYanOptions) { | ||||||
|  |         this.yiYanApi = yiYanApi; | ||||||
|  |         this.yiYanOptions = yiYanOptions; | ||||||
|  |     } | ||||||
|  |  | ||||||
|     public final RetryTemplate retryTemplate = RetryTemplate.builder() |     public final RetryTemplate retryTemplate = RetryTemplate.builder() | ||||||
|             // 最大重试次数 10 |             // 最大重试次数 10 | ||||||
|             .maxAttempts(10) |             .maxAttempts(10) | ||||||
| @@ -70,20 +74,6 @@ public class YiYanChatClient implements ChatClient, StreamingChatClient { | |||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     private YiYanChatCompletionRequest createRequest(Prompt prompt, boolean stream) { |  | ||||||
|         List<YiYanChatCompletionRequest.Message> messages = new ArrayList<>(); |  | ||||||
|         List<Message> instructions = prompt.getInstructions(); |  | ||||||
|         for (Message instruction : instructions) { |  | ||||||
|             YiYanChatCompletionRequest.Message message = new YiYanChatCompletionRequest.Message(); |  | ||||||
|             message.setContent(instruction.getContent()); |  | ||||||
|             message.setRole(instruction.getMessageType().getValue()); |  | ||||||
|             messages.add(message); |  | ||||||
|         } |  | ||||||
|         YiYanChatCompletionRequest request = new YiYanChatCompletionRequest(messages); |  | ||||||
|         request.setStream(stream); |  | ||||||
|         return request; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     @Override |     @Override | ||||||
|     public Flux<ChatResponse> stream(Prompt prompt) { |     public Flux<ChatResponse> stream(Prompt prompt) { | ||||||
|         // ctx 会有重试的信息 |         // ctx 会有重试的信息 | ||||||
| @@ -93,4 +83,35 @@ public class YiYanChatClient implements ChatClient, StreamingChatClient { | |||||||
|         Flux<YiYanChatCompletion> response = this.yiYanApi.chatCompletionStream(request); |         Flux<YiYanChatCompletion> response = this.yiYanApi.chatCompletionStream(request); | ||||||
|         return response.map(res -> new ChatResponse(List.of(new Generation(res.getResult())))); |         return response.map(res -> new ChatResponse(List.of(new Generation(res.getResult())))); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     private YiYanChatCompletionRequest createRequest(Prompt prompt, boolean stream) { | ||||||
|  |         // 两个都为null 则没有配置文件 | ||||||
|  |         if (yiYanOptions == null && prompt.getOptions() == null) { | ||||||
|  |             throw new ChatException("ChatOptions 未配置参数!"); | ||||||
|  |         } | ||||||
|  |         // 优先使用 Prompt 里面的 ChatOptions | ||||||
|  |         ChatOptions options = yiYanOptions; | ||||||
|  |         if (prompt.getOptions() != null) { | ||||||
|  |             options = (ChatOptions) prompt.getOptions(); | ||||||
|  |         } | ||||||
|  |         // Prompt 里面是一个 ChatOptions,用户可以随意传入,这里做一下判断 | ||||||
|  |         if (!(options instanceof YiYanOptions)) { | ||||||
|  |             throw new ChatException("Prompt 传入的不是 YiYanOptions!"); | ||||||
|  |         } | ||||||
|  |         // 转换 YiYanOptions | ||||||
|  |         YiYanOptions qianWenOptions = (YiYanOptions) options; | ||||||
|  |         // 创建 request | ||||||
|  |         List<YiYanChatCompletionRequest.Message> messageList = prompt.getInstructions().stream().map( | ||||||
|  |                 msg -> new YiYanChatCompletionRequest.Message() | ||||||
|  |                         .setRole(msg.getMessageType().getValue()) | ||||||
|  |                         .setContent(msg.getContent()) | ||||||
|  |         ).toList(); | ||||||
|  |         YiYanChatCompletionRequest request = new YiYanChatCompletionRequest(messageList); | ||||||
|  |         // 复制 qianWenOptions 属性取 request(这里 options 属性和 request 基本保持一致) | ||||||
|  |         // top: 由于遵循 spring-ai规范,支持在构建client的时候传入默认的 chatOptions | ||||||
|  |         BeanUtil.copyProperties(qianWenOptions, request); | ||||||
|  |         // 设置 stream | ||||||
|  |         request.setStream(stream); | ||||||
|  |         return request; | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -0,0 +1,144 @@ | |||||||
|  | package cn.iocoder.yudao.framework.ai.chatyiyan; | ||||||
|  |  | ||||||
|  | import cn.iocoder.yudao.framework.ai.chat.prompt.ChatOptions; | ||||||
|  | import cn.iocoder.yudao.framework.ai.chatyiyan.api.YiYanChatCompletionRequest; | ||||||
|  | import com.fasterxml.jackson.annotation.JsonProperty; | ||||||
|  | import lombok.Data; | ||||||
|  | import lombok.experimental.Accessors; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
|  | /** | ||||||
|  |  * 百度 问心一言 | ||||||
|  |  * | ||||||
|  |  * 文档地址:https://cloud.baidu.com/doc/WENXINWORKSHOP/s/clntwmv7t | ||||||
|  |  * | ||||||
|  |  * author: fansili | ||||||
|  |  * time: 2024/3/16 19:33 | ||||||
|  |  */ | ||||||
|  | @Data | ||||||
|  | @Accessors(chain = true) | ||||||
|  | public class YiYanOptions implements ChatOptions { | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * 一个可触发函数的描述列表,说明: | ||||||
|  |      * (1)支持的function数量无限制 | ||||||
|  |      * (2)长度限制,最后一个message的content长度(即此轮对话的问题)、functions和system字段总内容不能超过20480 个字符,且不能超过5120 tokens | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private List<YiYanChatCompletionRequest.Function> functions; | ||||||
|  |     /** | ||||||
|  |      * 说明: | ||||||
|  |      * (1)较高的数值会使输出更加随机,而较低的数值会使其更加集中和确定 | ||||||
|  |      * (2)默认0.8,范围 (0, 1.0],不能为0 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Float temperature; | ||||||
|  |     /** | ||||||
|  |      * 说明: | ||||||
|  |      * (1)影响输出文本的多样性,取值越大,生成文本的多样性越强 | ||||||
|  |      * (2)默认0.8,取值范围 [0, 1.0] | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Float top_p; | ||||||
|  |     /** | ||||||
|  |      * 通过对已生成的token增加惩罚,减少重复生成的现象。说明: | ||||||
|  |      * (1)值越大表示惩罚越大 | ||||||
|  |      * (2)默认1.0,取值范围:[1.0, 2.0] | ||||||
|  |      * | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Float penalty_score; | ||||||
|  |     /** | ||||||
|  |      * 是否以流式接口的形式返回数据,默认false | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Boolean stream; | ||||||
|  |     /** | ||||||
|  |      * 模型人设,主要用于人设设定,例如,你是xxx公司制作的AI助手,说明: | ||||||
|  |      * (1)长度限制,最后一个message的content长度(即此轮对话的问题)、functions和system字段总内容不能超过20480 个字符,且不能超过5120 tokens | ||||||
|  |      * (2)如果同时使用system和functions,可能暂无法保证使用效果,持续进行优化 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private String system; | ||||||
|  |     /** | ||||||
|  |      * 生成停止标识,当模型生成结果以stop中某个元素结尾时,停止文本生成。说明: | ||||||
|  |      * (1)每个元素长度不超过20字符 | ||||||
|  |      * (2)最多4个元素 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private List<String> stop; | ||||||
|  |     /** | ||||||
|  |      * 是否强制关闭实时搜索功能,默认false,表示不关闭 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Boolean disable_search; | ||||||
|  |     /** | ||||||
|  |      * 是否开启上角标返回,说明: | ||||||
|  |      * (1)开启后,有概率触发搜索溯源信息search_info,search_info内容见响应参数介绍 | ||||||
|  |      * (2)默认false,不开启 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Boolean enable_citation; | ||||||
|  |     /** | ||||||
|  |      * 指定模型最大输出token数,范围[2, 2048] | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private Integer max_output_tokens; | ||||||
|  |     /** | ||||||
|  |      * 指定响应内容的格式,说明: | ||||||
|  |      * (1)可选值: | ||||||
|  |      * · json_object:以json格式返回,可能出现不满足效果情况 | ||||||
|  |      * · text:以文本格式返回 | ||||||
|  |      * (2)如果不填写参数response_format值,默认为text | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private String response_format; | ||||||
|  |     /** | ||||||
|  |      * 表示最终用户的唯一标识符 | ||||||
|  |      * 必填:否 | ||||||
|  |      */ | ||||||
|  |     private String user_id; | ||||||
|  |     /** | ||||||
|  |      * 在函数调用场景下,提示大模型选择指定的函数(非强制),说明:指定的函数名必须在functions中存在 | ||||||
|  |      * 必填:否 | ||||||
|  |      * | ||||||
|  |      * ERNIE-4.0-8K 模型没有这个字段 | ||||||
|  |      */ | ||||||
|  |     private String tool_choice; | ||||||
|  |  | ||||||
|  |     // | ||||||
|  |     // 以下兼容 spring-ai ChatOptions 暂时没有其他地方用到 | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Float getTemperature() { | ||||||
|  |         return this.temperature; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setTemperature(Float temperature) { | ||||||
|  |         this.temperature = temperature; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Float getTopP() { | ||||||
|  |         return top_p; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setTopP(Float topP) { | ||||||
|  |         this.top_p = topP; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // 百度么有 topK | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public Integer getTopK() { | ||||||
|  |         return null; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Override | ||||||
|  |     public void setTopK(Integer topK) { | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -37,14 +37,14 @@ public class YiYanChatCompletionRequest { | |||||||
|      * (2)默认0.8,范围 (0, 1.0],不能为0 |      * (2)默认0.8,范围 (0, 1.0],不能为0 | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
|      */ |      */ | ||||||
|     private String temperature; |     private Float temperature; | ||||||
|     /** |     /** | ||||||
|      * 说明: |      * 说明: | ||||||
|      * (1)影响输出文本的多样性,取值越大,生成文本的多样性越强 |      * (1)影响输出文本的多样性,取值越大,生成文本的多样性越强 | ||||||
|      * (2)默认0.8,取值范围 [0, 1.0] |      * (2)默认0.8,取值范围 [0, 1.0] | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
|      */ |      */ | ||||||
|     private String top_p; |     private Float top_p; | ||||||
|     /** |     /** | ||||||
|      * 通过对已生成的token增加惩罚,减少重复生成的现象。说明: |      * 通过对已生成的token增加惩罚,减少重复生成的现象。说明: | ||||||
|      * (1)值越大表示惩罚越大 |      * (1)值越大表示惩罚越大 | ||||||
| @@ -52,7 +52,7 @@ public class YiYanChatCompletionRequest { | |||||||
|      * |      * | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
|      */ |      */ | ||||||
|     private String penalty_score; |     private Float penalty_score; | ||||||
|     /** |     /** | ||||||
|      * 是否以流式接口的形式返回数据,默认false |      * 是否以流式接口的形式返回数据,默认false | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
| @@ -71,7 +71,7 @@ public class YiYanChatCompletionRequest { | |||||||
|      * (2)最多4个元素 |      * (2)最多4个元素 | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
|      */ |      */ | ||||||
|     private String stop; |     private List<String> stop; | ||||||
|     /** |     /** | ||||||
|      * 是否强制关闭实时搜索功能,默认false,表示不关闭 |      * 是否强制关闭实时搜索功能,默认false,表示不关闭 | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
| @@ -106,6 +106,8 @@ public class YiYanChatCompletionRequest { | |||||||
|     /** |     /** | ||||||
|      * 在函数调用场景下,提示大模型选择指定的函数(非强制),说明:指定的函数名必须在functions中存在 |      * 在函数调用场景下,提示大模型选择指定的函数(非强制),说明:指定的函数名必须在functions中存在 | ||||||
|      * 必填:否 |      * 必填:否 | ||||||
|  |      * | ||||||
|  |      * ERNIE-4.0-8K 模型没有这个字段 | ||||||
|      */ |      */ | ||||||
|     private String tool_choice; |     private String tool_choice; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -23,9 +23,9 @@ public class QianWenChatClientTests { | |||||||
|     @Before |     @Before | ||||||
|     public void setup() { |     public void setup() { | ||||||
|         QianWenApi qianWenApi = new QianWenApi( |         QianWenApi qianWenApi = new QianWenApi( | ||||||
|                 "", |                 "LTAI5tNTVhXW4fLKUjMrr98z", | ||||||
|                 "", |                 "ZJ0JQeyjzxxm5CfeTV6k1wNE9UsvZP", | ||||||
|                 "", |                 "f0c1088824594f589c8f10567ccd929f_p_efm", | ||||||
|                 null |                 null | ||||||
|         ); |         ); | ||||||
|         qianWenChatClient = new QianWenChatClient( |         qianWenChatClient = new QianWenChatClient( | ||||||
|   | |||||||
| @@ -4,12 +4,12 @@ import cn.iocoder.yudao.framework.ai.chat.prompt.Prompt; | |||||||
| import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanApi; | import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanApi; | ||||||
| import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatClient; | import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatClient; | ||||||
| import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel; | import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanChatModel; | ||||||
|  | import cn.iocoder.yudao.framework.ai.chatyiyan.YiYanOptions; | ||||||
| import org.junit.Before; | import org.junit.Before; | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| import reactor.core.publisher.Flux; | import reactor.core.publisher.Flux; | ||||||
|  |  | ||||||
| import java.util.Scanner; | import java.util.Scanner; | ||||||
| import java.util.function.Consumer; |  | ||||||
|  |  | ||||||
| /** | /** | ||||||
|  * chat 文心一言 |  * chat 文心一言 | ||||||
| @@ -29,7 +29,7 @@ public class YiYanChatTests { | |||||||
|                 YiYanChatModel.ERNIE4_3_5_8K, |                 YiYanChatModel.ERNIE4_3_5_8K, | ||||||
|                 86400 |                 86400 | ||||||
|         ); |         ); | ||||||
|         yiYanChatClient = new YiYanChatClient(yiYanApi); |         yiYanChatClient = new YiYanChatClient(yiYanApi, new YiYanOptions().setMax_output_tokens(2048)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     @Test |     @Test | ||||||
| @@ -41,12 +41,7 @@ public class YiYanChatTests { | |||||||
|     @Test |     @Test | ||||||
|     public void streamTest() { |     public void streamTest() { | ||||||
|         Flux<ChatResponse> fluxResponse = yiYanChatClient.stream(new Prompt("用java帮我写一个快排算法?")); |         Flux<ChatResponse> fluxResponse = yiYanChatClient.stream(new Prompt("用java帮我写一个快排算法?")); | ||||||
|         fluxResponse.subscribe(new Consumer<ChatResponse>() { |         fluxResponse.subscribe(chatResponse -> System.err.print(chatResponse.getResult().getOutput().getContent())); | ||||||
|             @Override |  | ||||||
|             public void accept(ChatResponse chatResponse) { |  | ||||||
|                 System.err.print(chatResponse.getResult().getOutput().getContent()); |  | ||||||
|             } |  | ||||||
|         }); |  | ||||||
|         // 阻止退出 |         // 阻止退出 | ||||||
|         Scanner scanner = new Scanner(System.in); |         Scanner scanner = new Scanner(System.in); | ||||||
|         scanner.nextLine(); |         scanner.nextLine(); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 cherishsince
					cherishsince