---
title: "chat - 支持哪些模型？及方言定制"
---

### 1、支持哪些聊天模型？

支持聊天模型，其实是支持“接口风格”。比如 DeepSeek 官网的就支持“三种”接口： openai、openai-response、anthropic；同样是 DeepSeek 在 ollama 平台是“另一种”接口风格；在阿里百炼则有“两种”接口风格，一种兼容 openai，另一种则是百炼专属风格；在模力方舟（ai.gitee）则是兼容 openai。


聊天模型的这种“接口风格”，称为聊天方言（简称，方言）。ChatConfig 通过 `standard` 或 `apiUrl`识别模型服务是用哪种“接口风格”的。并自动选择对应的聊天方言适配。

目前服务平台有常见的两种配置信息：

* 方言类型 + bsaeUrl
  * 例：`base_url (OpenAI)` = `https://api.deepseek.com`
  * 对应过来是：`standard=openai, apiUrl=https://api.deepseek.com`
* fullUrl（curl 完整地址）
  * 例：`curl https://api.deepseek.com/v1/chat/completions`
  * 对应过来是：`apiUrl=https://api.deepseek.com/v1/chat/completions`（通过 endsWit 自动识别）


框架内置的方言适配有：

| 言方               | 配置要求 | 描述 |
| ----------- | ------------------ | -------- |
| openai                   |   默认 <br/>或者<br/> `apiUrl=.../chat/completions`                                | 兼容 openai 的接口规范（默认）     |
| openai-responses   | `standard=openai-responses` <br/>或者<br/> `apiUrl=.../v1/responses`         | 兼容 openai-responses 的接口规范      |
| ollama                   | `standard=ollama`          | 兼容 ollama 的接口规范      |
| gemini                   | `standard=gemini` <br/>或者<br/> `apiUrl=.../v1beta/models/*`         | 兼容 google gemini 的接口规范（v3.8.1 后可试用）      |
| gemini                   | `standard=gemini-interactions` <br/>或者<br/> `apiUrl=.../v1beta/interactions/*`         | 兼容 google gemini-interactions 的接口规范（v4.0.3 后可试用）      |
| anthropic               | `standard=anthropic` <br/>或者<br/> `apiUrl=.../v1/messages`         | 兼容 anthropic claude 的接口规范（v3.9.1 后可试用）。<br/><mark>claude 还有个 openai 的兼容模式（使用 openai 方言）<mark/>      |
| dashscope     |  `standard=dashscope` <br/>或者<br/> `apiUrl=.../v1/services/*`                                  | 兼容 dashscope （阿里云的平台百炼）的接口规范。<br/><mark>dashscope 还有个 openai 的兼容模式（使用 openai 方言）</mark>    |


重要提醒：

* solon-ai 支持 `apiUrl` 为完整地址（curl 地址）形式，自动通过尾段识别方言。
* solon-ai 支持 `apiUrl` 为基地址（baseUrl）形式 + `standard`（声明接口规范），识别方言并“自动补全”地址。
* 部分内网部署的地址，可能不需要自动补全，请以 "`#`"结尾（表示完整地址，不需要自动补全）。

那支持哪些聊天模型？

* 所有兼容 openai 的模型或平台服务（比如："DeepSeek"、"QWen"、"GLM"、"Kimi"、"MiniMax"、“Claude（openai 兼容模式）”、"Gemini（openai 兼容模式）"、"DashScope（openai 兼容模式）"、"GPT"、“模力方舟”、“硅基流动”、“魔搭社区（魔力空间）”、“Xinference”、“火山引擎”、“智谱”、“讯飞星火”、“百度千帆”、“阿里百炼”、"MiniMax" 等），都兼容
* 所有兼容 anthropic 的模型或平台服务，都兼容
* 所有 ollama 平台上的模型，都兼容 
* 所有 gemini 相关模型，都兼容 
* 所有 阿里百炼 平台上的模型（同时提供有 “百炼” 和 “openai” 两套接口），都兼容




构建示例：

```java
ChatModel chatModel = ChatModel.of("http://127.0.0.1:11434/api/chat") //使用完整地址（而不是 api_base）
                .headerSet("x-demo", "demo1")
                .standard("ollama")
                .model("llama3.2")
                .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 的方言包                        | 
| org.noear:solon-ai-dialect-gemini          | 兼容 gemini 的方言包                        | 

提醒：一般匹配不到方言时？要么是 standard 配置有问题，要么是 pom 缺少相关的依赖包。


### 3、聊天方言接口定义

当前版本方言解析的唯一入口是 `parseResponseJson(ChatStreamContext, String)`；正文、思考和工具调用等内容主干应写入累积器，由核心统一生成事件。以下接口代码与当前 `ChatDialect.java` 一致：

```java
package org.noear.solon.ai.chat.dialect;

import org.noear.snack4.ONode;
import org.noear.solon.ai.AiModelDialect;
import org.noear.solon.ai.chat.ChatConfig;
import org.noear.solon.ai.chat.ChatAccumulator;
import org.noear.solon.ai.chat.event.ChatStreamContext;
import org.noear.solon.ai.chat.message.ToolMessage;
import org.noear.solon.ai.chat.tool.ToolCallBuilder;
import org.noear.solon.ai.chat.message.AssistantMessage;
import org.noear.solon.ai.chat.message.ChatMessage;
import org.noear.solon.ai.chat.ChatOptions;
import org.noear.solon.lang.Preview;
import org.noear.solon.net.http.HttpUtils;

import java.util.List;
import java.util.Map;

@Preview("3.1")
public interface ChatDialect extends AiModelDialect {
    /**
     * 是否为默认
     */
    default boolean isDefault() {
        return false;
    }

    /**
     * 匹配检测
     *
     * @param config 聊天配置
     */
    boolean matched(ChatConfig config);

    /**
     * 创建 http 工具
     *
     * @param config   聊天配置
     * @param isStream 是否流式获取
     */
    HttpUtils createHttpUtils(ChatConfig config, boolean isStream);

    /**
     * 准备输出架构
     */
    void prepareOutputSchemaInstruction(String outputSchema, StringBuilder instructionBuilder);

    void prepareOutputFormatOptions(ChatOptions options);

    /**
     * 构建请求数据
     *
     * @param config   聊天配置
     * @param options  聊天选项
     * @param messages 消息
     * @param isStream 是否流式获取
     */
    ONode buildRequestJson(ChatConfig config, ChatOptions options, List<ChatMessage> messages, boolean isStream);

    /**
     * 构建助理消息节点
     *
     * @param toolCallBuilders 工具调用构建器集合
     */
    ONode buildAssistantToolCallMessageNode(ChatAccumulator acc, Map<String, ToolCallBuilder> toolCallBuilders);

    /**
     * 构建助理消息根据直接返回的工具消息
     *
     * @param toolMessages 直接返回的工具消息
     */
    AssistantMessage buildAssistantMessageByToolMessages(AssistantMessage toolCallMessage, List<ToolMessage> toolMessages);

    /**
     * 分析响应数据（事件形态）
     *
     * @param ctx      流上下文
     * @param respJson 响应数据
     */
    void parseResponseJson(ChatStreamContext ctx, String respJson);

    /**
     * 分析工具调用
     *
     * @param acc      响应累积器
     * @param oMessage 消息节点
     */
    List<AssistantMessage> parseAssistantMessage(ChatAccumulator acc, ONode oMessage);
}
```

### 4、OllamaChatDialect 定制参考

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

```java
ChatDialectManager.register(new OllamaChatDialect());
```

以下是迁移到当前 `ChatStreamContext` / `ChatAccumulator` API 的示意代码（不是完整的方言实现）；不要将旧版的 `boolean parseResponseJson(...)`、`ChatResponseDefault` 或旧的 `parseAssistantMessage(...)` 签名混用：

```java
package org.noear.solon.ai.llm.dialect.ollama;

import org.noear.snack4.ONode;
import org.noear.solon.ai.chat.ChatException;
import org.noear.solon.ai.chat.event.ChatStreamContext;
import org.noear.solon.ai.chat.message.AssistantMessage;
import org.noear.solon.ai.chat.dialect.AbstractChatDialect;

/**
 * Ollama 聊天模型方言（示意）
 */
public class OllamaChatDialect extends AbstractChatDialect {
    @Override
    public void parseResponseJson(ChatStreamContext ctx, String json) {
        ONode oResp = ONode.ofJson(json);
        if (!oResp.isObject()) {
            return;
        }

        ONode message = oResp.get("message");
        if (message != null && message.isObject()) {
            ONode contentNode = message.get("content");
            String content = contentNode == null ? null : contentNode.getString();
            if (content != null && !content.isEmpty()) {
                ctx.getAccumulator().addContentItem(new AssistantMessage(content));
            }
        }

        if (oResp.hasKey("error")) {
            ctx.getAccumulator().setError(new ChatException(oResp.get("error").getString()));
        }
    }
}
```

方言不要同时把同一份正文、思考或工具调用既写入内容项又通过 `ctx.emit(...)` 发射。内容主干应选择内容项这一条路径，否则订阅方可能收到重复增量，终态聚合也会重复。核心会将内容项转换为 `TEXT_DELTA`、`THINKING_DELTA` 或工具调用事件，并统一补齐边界。
