From 8e00613e693e7a30bf83fca29de6fabd8425a696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=80=AA=E7=A8=8B=E4=BC=9F?= Date: Wed, 20 May 2026 09:22:06 +0800 Subject: [PATCH] fix(embedding): use chatModel field for protocol routing instead of providerId matching (#170) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Closes #166 EmbeddingModelFactory used EmbeddingProtocol.fromProviderId() to pick the embedding protocol, which substring-matches 'dashscope' / 'qwen' / 'aliyun' in the providerId. The dashscope-compat provider carries 'dashscope' in its id but runs in OpenAI compatible mode (chatModel='OpenAIChatModel', baseUrl='https://dashscope.aliyuncs.com/compatible-mode/v1'). Routing it to DASHSCOPE_EMBEDDING made DashScopeApi build its native path against the compat base, producing 404s on every embedding call. Switch to the chatModel column instead — the same signal ModelProtocol .fromChatModel() uses for the chat path. chatModel='DashScopeChatModel' takes the native protocol; everything else (including dashscope-compat) takes OpenAI-compatible. EmbeddingProtocol.fromProviderId() is retained for reference but is no longer called; future callers should follow the chatModel pattern. --- .../mate/llm/embedding/EmbeddingModelFactory.java | 13 ++++++++++--- .../java/vip/mate/llm/model/EmbeddingProtocol.java | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/mateclaw-server/src/main/java/vip/mate/llm/embedding/EmbeddingModelFactory.java b/mateclaw-server/src/main/java/vip/mate/llm/embedding/EmbeddingModelFactory.java index 4d13b4ca..d47b44a8 100644 --- a/mateclaw-server/src/main/java/vip/mate/llm/embedding/EmbeddingModelFactory.java +++ b/mateclaw-server/src/main/java/vip/mate/llm/embedding/EmbeddingModelFactory.java @@ -111,9 +111,16 @@ public class EmbeddingModelFactory { "Embedding provider '" + modelConfig.getProvider() + "' not found in mate_model_provider"); } - EmbeddingProtocol protocol = EmbeddingProtocol.fromProviderId(provider.getProviderId()); - log.info("[EmbeddingFactory] Building embedding model: provider={}, model={}, protocol={}", - provider.getProviderId(), modelConfig.getModelName(), protocol); + // Use chatModel column (same signal as ModelProtocol.fromChatModel) rather than + // providerId substring matching. dashscope-compat has "dashscope" in its id but + // uses OpenAIChatModel + compatible-mode URL — routing it to DASHSCOPE_EMBEDDING + // causes DashScopeApi to construct a native path that returns 404 against the + // compat base URL. + EmbeddingProtocol protocol = "DashScopeChatModel".equals(provider.getChatModel()) + ? EmbeddingProtocol.DASHSCOPE_EMBEDDING + : EmbeddingProtocol.OPENAI_EMBEDDING; + log.info("[EmbeddingFactory] Building embedding model: provider={}, chatModel={}, model={}, protocol={}", + provider.getProviderId(), provider.getChatModel(), modelConfig.getModelName(), protocol); return switch (protocol) { case DASHSCOPE_EMBEDDING -> buildDashScope(provider, modelConfig); diff --git a/mateclaw-server/src/main/java/vip/mate/llm/model/EmbeddingProtocol.java b/mateclaw-server/src/main/java/vip/mate/llm/model/EmbeddingProtocol.java index 2a381d10..a6530f88 100644 --- a/mateclaw-server/src/main/java/vip/mate/llm/model/EmbeddingProtocol.java +++ b/mateclaw-server/src/main/java/vip/mate/llm/model/EmbeddingProtocol.java @@ -10,7 +10,9 @@ package vip.mate.llm.model; *
  • OpenAI 兼容协议的 embedding 统一走 /v1/embeddings
  • * *

    - * 通过 {@link #fromProviderId} 从 providerId 推断协议,新增 provider 时只需扩展这里。 + * 注意:{@link EmbeddingModelFactory} 现在优先通过 {@code chatModel} 列判断协议 + * (与 {@link ModelProtocol#fromChatModel} 保持一致),{@link #fromProviderId} 已不再使用。 + * 保留该方法仅作参考;不要在新代码中调用它。 * * @author MateClaw Team */