fix(embedding): use chatModel field for protocol routing instead of providerId matching (#170)

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.
This commit is contained in:
倪程伟 2026-05-20 09:22:06 +08:00 committed by GitHub
parent af3e68d271
commit 8e00613e69
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 13 additions and 4 deletions

View File

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

View File

@ -10,7 +10,9 @@ package vip.mate.llm.model;
* <li>OpenAI 兼容协议的 embedding 统一走 /v1/embeddings</li>
* </ul>
* <p>
* 通过 {@link #fromProviderId} providerId 推断协议新增 provider 时只需扩展这里
* <b>注意</b>{@link EmbeddingModelFactory} 现在优先通过 {@code chatModel} 列判断协议
* {@link ModelProtocol#fromChatModel} 保持一致{@link #fromProviderId} 已不再使用
* 保留该方法仅作参考不要在新代码中调用它
*
* @author MateClaw Team
*/