付公司网站费用怎么做分录,小游戏秒玩入口,私域电商平台排名,中国最厉害的网站建设公司、支持哪些聊天模型#xff1f;支持聊天模型#xff0c;其实是支持接口风格。比如 DeepSeek-V3 官网的接口兼容 openai#xff1b;在 ollama 平台是另一种接口风格#xff1b;在阿里百炼则有两种接口风格#xff0c;一种兼容 openai#xff0c;另一种则是百炼专属风格支持聊天模型其实是支持接口风格。比如 DeepSeek-V3 官网的接口兼容 openai在 ollama 平台是另一种接口风格在阿里百炼则有两种接口风格一种兼容 openai另一种则是百炼专属风格在模力方舟ai.gitee则是兼容 openai。聊天模型的这种接口风格称为聊天方言简称方言。ChatConfig 通过 provider 或 apiUrl识别模型服务是由谁提供的。并自动选择对应的聊天方言适配。框架内置的方言适配有言方 配置要求 描述openai 兼容 openai 的接口规范默认ollama providerollama 兼容 ollama 的接口规范dashscope providerdashscope 兼容 dashscope 阿里云的平台百炼的接口规范v3.5.1 后基于 apiUrl 自动识别不要配置 provider那支持哪些聊天模型所有兼容 openai 的平台服务比如“模力方舟”、“硅基流动”、“魔搭社区魔力空间”、“Xinference”、“火山引擎”、“智谱”、“讯飞火星”、“百度千帆”、“阿里百炼” 等都兼容所有 ollama 平台上的模型都兼容所有 阿里百炼 平台上的模型同时提供有 “百炼” 和 “openai” 两套接口都兼容构建示例ChatModel chatModel ChatModel.of(http://127.0.0.1:11434/api/chat) //使用完整地址而不是 api_base.provider(ollama).model(llama3.2).headerSet(x-demo, demo1).build();2、自带的方言依赖包方言依赖包 描述org.noear:solon-ai 包含 solon-ai-core 和下面所有的方言包。一般引用这个org.noear:solon-ai-dialect-openai 兼容 openai 的方言包org.noear:solon-ai-dialect-ollama 兼容 ollama 的方言包org.noear:solon-ai-dialect-dashscope 兼容 dashscope 的方言包提醒一般匹配不到方言时要么是 provider 配置有问题要么是 pom 缺少相关的依赖包。3、聊天方言接口定义public interface ChatDialect extends AiModelDialect {//是否为默认default boolean isDefault() {return false;}//匹配检测boolean matched(ChatConfig config);//构建请求数据String buildRequestJson(ChatConfig config, ChatOptions options, ListChatMessage messages, boolean isStream);//构建助理消息节点ONode buildAssistantMessageNode(MapInteger, ToolCallBuilder toolCallBuilders);//构建助理消息根据直接返回的工具消息AssistantMessage buildAssistantMessageByToolMessages(ListToolMessage toolMessages);//分析响应数据boolean parseResponseJson(ChatConfig config, ChatResponseDefault resp, String respJson);//分析工具调用ListAssistantMessage parseAssistantMessage(ChatResponseDefault resp, ONode oMessage);}3、OllamaChatDialect 定制参考如果方言有组件注解会自动注册。否则需要手动注册ChatDialectManager.register(new OllamaChatDialect());方言定制参考import org.noear.snack4.ONode;import org.noear.solon.Utils;import org.noear.solon.ai.AiMedia;import org.noear.solon.ai.AiUsage;import org.noear.solon.ai.media.Audio;import org.noear.solon.ai.chat.ChatChoice;import org.noear.solon.ai.chat.ChatConfig;import org.noear.solon.ai.chat.ChatException;import org.noear.solon.ai.chat.ChatResponseDefault;import org.noear.solon.ai.chat.dialect.AbstractChatDialect;import org.noear.solon.ai.chat.message.AssistantMessage;import org.noear.solon.ai.chat.message.UserMessage;import org.noear.solon.ai.chat.tool.ToolCall;import org.noear.solon.ai.chat.tool.ToolCallBuilder;import org.noear.solon.ai.media.Image;import org.noear.solon.ai.media.Video;import org.noear.solon.core.util.DateUtil;import java.util.Date;import java.util.List;import java.util.Map;import java.util.stream.Collectors;/*** Ollama 聊天模型方言** author noear* since 3.1*///Componentpublic class OllamaChatDialect extends AbstractChatDialect {private static OllamaChatDialect instance new OllamaChatDialect();public static OllamaChatDialect getInstance() {return instance;}/*** 匹配检测** param config 聊天配置*/Overridepublic boolean matched(ChatConfig config) {return ollama.equals(config.getProvider());}Overrideprotected void buildChatMessageNodeDo(ONode oNode, UserMessage msg) {oNode.set(role, msg.getRole().name().toLowerCase());if (Utils.isEmpty(msg.getMedias())) {oNode.set(content, msg.getContent());} else {oNode.set(content, msg.getContent());AiMedia demo msg.getMedias().get(0);if (demo instanceof Image) {oNode.set(images, msg.getMedias().stream().map(i - i.toDataString(false)).collect(Collectors.toList()));} else if (demo instanceof Audio) {oNode.set(audios, msg.getMedias().stream().map(i - i.toDataString(false)).collect(Collectors.toList()));} else if (demo instanceof Video) {oNode.set(videos, msg.getMedias().stream().map(i - i.toDataString(false)).collect(Collectors.toList()));}}}Overridepublic ONode buildAssistantMessageNode(MapInteger, ToolCallBuilder toolCallBuilders) {ONode oNode new ONode();oNode.set(role, assistant);oNode.set(content, );oNode.getOrNew(tool_calls).asArray().then(n1 - {for (Map.EntryInteger, ToolCallBuilder kv : toolCallBuilders.entrySet()) {//有可能没有n1.addNew().set(id, kv.getValue().idBuilder.toString()).set(type, function).getOrNew(function).then(n2 - {n2.set(name, kv.getValue().nameBuilder.toString());n2.set(arguments, ONode.ofJson(kv.getValue().argumentsBuilder.toString()));});}});return oNode;}Overridepublic boolean parseResponseJson(ChatConfig config, ChatResponseDefault resp, String json) {//解析ONode oResp ONode.ofJson(json);if (oResp.isObject() false) {return false;}if (oResp.hasKey(error)) {resp.setError(new ChatException(oResp.get(error).getString()));} else {resp.setModel(oResp.get(model).getString());resp.setFinished(oResp.get(done).getBoolean());String done_reason oResp.get(done_reason).getString();String createdStr oResp.get(created_at).getString();if (createdStr ! null) {createdStr createdStr.substring(0, createdStr.indexOf(.) 4);}Date created DateUtil.parseTry(createdStr);ListAssistantMessage messageList parseAssistantMessage(resp, oResp.get(message));for (AssistantMessage msg1 : messageList) {resp.addChoice(new ChatChoice(0, created, done_reason, msg1));}if (resp.isFinished()) {long promptTokens oResp.get(prompt_eval_count).getLong();long completionTokens oResp.get(eval_count).getLong();long totalTokens promptTokens completionTokens;resp.setUsage(new AiUsage(promptTokens, completionTokens, totalTokens, oResp));if(resp.hasChoices() false) {resp.addChoice(new ChatChoice(0, created, stop, new AssistantMessage()));}}}return true;}Overrideprotected ToolCall parseToolCall(ONode n1) {int index -1; //n1.get(index).getInt();它是没有值的String callId n1.get(id).getString();ONode n1f n1.get(function);String name n1f.get(name).getString();ONode n1fArgs n1f.get(arguments);String argStr n1fArgs.getString();index name.hashCode();if (n1fArgs.isValue()) {//有可能是 json stringn1fArgs ONode.ofJson(argStr);}MapString, Object argMap null;if (n1fArgs.isObject()) {argMap n1fArgs.toBean(Map.class);}return new ToolCall(index, callId, name, argStr, argMap);}}