Solon v3.0.9

chat - 聊天模型接口方言及定制

</> markdown

框架已内置:OllamaChatDialect、OpenaiChatDialect 两种方言,自动支持 Ollama 提供的模型接口与 Openai 规范的模型接口。

1、方言接口

public interface ChatDialect {
    //匹配检测
    boolean matched(ChatConfig config);

    //构建请求数据
    String buildRequestJson(ChatConfig config, ChatOptions options, List<ChatMessage> messages, boolean stream);

    //分析响应数据
    boolean parseResponseJson(ChatConfig config, ChatResponseDefault resp, String respJson);
}

2、OllamaChatDialect 定制参考

如果方言有组件注解,会自动注册。否则,需要手动注册:

ChatDialectManager.register(new OllamaChatDialect());

方言定制:

//@Component
public class OllamaChatDialect extends AbstractChatDialect {
    private static OllamaChatDialect instance = new OllamaChatDialect();

    public static OllamaChatDialect getInstance() {
        return instance;
    }

    /**
     * 匹配检测
     *
     * @param config 聊天配置
     */
    @Override
    public boolean matched(ChatConfig config) {
        return "ollama".equals(config.getProvider());
    }

    @Override
    public boolean parseResponseJson(ChatConfig config, ChatResponseDefault resp, String json) {
        //解析
        ONode oResp = ONode.load(json);

        if (oResp.isObject() == false) {
            return false;
        }

        if (oResp.contains("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);
            AssistantMessage message1 = parseAssistantMessage(resp, oResp.get("message"));
            resp.addChoice(new ChatChoice(0, created, done_reason, message1));

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

        return true;
    }
}