Files
common_agent/docs/MODEL_PROVIDER_DESIGN.md

27 KiB
Raw Blame History

模型服务商配置与路由设计文档

1. 文档信息

项目 内容
所属项目 Common Agent
文档类型 设计文档
编写日期 2026-05-25
对应需求 docs/MODEL_PROVIDER_REQUIREMENTS.md
目标阶段 RAG 向量导入与模型网关基础能力

2. 设计目标

本设计用于在 Common Agent 中新增模型服务商配置与模型路由能力,使系统可以统一接入 Ollama、硅基流动、百炼、OpenAI 等模型服务,并为 RAG 和后续 Agent 运行时提供统一模型调用入口。

核心设计目标:

  1. 业务模块只依赖平台内部模型网关,不直接依赖具体服务商。
  2. 首期优先支持 OpenAI-compatible 协议,减少多服务商适配成本。
  3. 支持本地模型和云端模型混用,实现成本控制。
  4. 支持 RAG Embedding 模型配置化,并保证同一知识库向量模型一致。
  5. 支持调用日志,为排障、统计和后续成本分析打基础。

3. 总体架构

flowchart TD
    Admin["管理控制台"] --> ProviderApi["模型配置 API"]
    Rag["RAG 模块"] --> ModelGateway["ModelGateway"]
    Agent["Agent 模块"] --> ModelGateway
    ModelGateway --> Router["ModelRouteService"]
    Router --> Config["模型配置与路由表"]
    ModelGateway --> ClientFactory["ModelClientFactory"]
    ClientFactory --> Ollama["Ollama OpenAI-compatible"]
    ClientFactory --> SiliconFlow["SiliconFlow OpenAI-compatible"]
    ClientFactory --> DashScope["DashScope OpenAI-compatible"]
    ClientFactory --> Other["其他 OpenAI-compatible 服务"]
    ModelGateway --> Log["ModelCallLogService"]
    Rag --> RagChunk["rag_chunk"]
    Rag --> RagEmbedding["rag_chunk_embedding"]

设计上将模型平台能力拆成四层:

层级 职责
配置层 管理服务商、模型、路由规则和知识库模型绑定
路由层 根据任务类型、范围和策略选择具体模型
调用层 通过统一客户端调用 Chat、Embedding、Rerank 等能力
观测层 记录调用日志、耗时、token、费用估算和错误信息

4. 包结构设计

建议新增后端包:

src/main/java/com/bruce/modelprovider
├── controller
├── dto
│   ├── request
│   └── response
├── entity
├── enums
├── mapper
├── service
│   └── impl
├── gateway
├── client
└── config

各包职责:

职责
controller 对外暴露服务商、模型、路由规则、日志查询接口
dto 请求和响应对象,不直接暴露实体
entity 数据库实体,继承 BaseEntity
enums 服务商类型、模型类型、任务类型、路由策略、调用状态
mapper MyBatis-Plus BaseMapper
service 配置管理、路由选择、调用日志
gateway 面向业务模块的模型调用入口
client 具体协议客户端,例如 OpenAI-compatible 客户端
config 模型平台配置,例如默认超时、批量大小、密钥加密开关

5. 核心数据模型

5.1 model_provider 模型服务商表

用于保存服务商基础配置。

CREATE TABLE model_provider (
    id BIGSERIAL PRIMARY KEY,
    provider_code VARCHAR(64) NOT NULL,
    provider_name VARCHAR(100) NOT NULL,
    provider_type VARCHAR(50) NOT NULL,
    protocol_type VARCHAR(50) NOT NULL DEFAULT 'OPENAI_COMPATIBLE',
    base_url VARCHAR(500) NOT NULL,
    auth_type VARCHAR(50) NOT NULL DEFAULT 'BEARER_TOKEN',
    secret_ref VARCHAR(200),
    api_key_cipher TEXT,
    timeout_ms INTEGER NOT NULL DEFAULT 60000,
    priority INTEGER NOT NULL DEFAULT 100,
    enabled BOOLEAN NOT NULL DEFAULT TRUE,
    health_status VARCHAR(50) NOT NULL DEFAULT 'UNKNOWN',
    last_health_check_time TIMESTAMP,
    version INTEGER NOT NULL DEFAULT 1,
    create_time TIMESTAMP,
    update_time TIMESTAMP,
    remark VARCHAR(500) DEFAULT '',
    create_by VARCHAR(64),
    update_by VARCHAR(64),
    CONSTRAINT uk_model_provider_code UNIQUE (provider_code)
);

字段说明:

字段 说明
provider_code 服务商编码,例如 ollama-mainsiliconflow
provider_type 服务商类型,例如 OLLAMASILICONFLOWDASHSCOPEOPENAICUSTOM
protocol_type 协议类型,首期使用 OPENAI_COMPATIBLE
base_url API 基础地址,例如 https://api.siliconflow.cn/v1
secret_ref 密钥引用,例如环境变量名或配置中心键
api_key_cipher 可选的加密密钥内容,前端不返回
health_status 健康检查状态

5.2 model_config 模型配置表

用于保存服务商下的具体模型。

CREATE TABLE model_config (
    id BIGSERIAL PRIMARY KEY,
    provider_id BIGINT NOT NULL,
    model_code VARCHAR(100) NOT NULL,
    model_name VARCHAR(200) NOT NULL,
    upstream_model VARCHAR(200) NOT NULL,
    model_type VARCHAR(50) NOT NULL,
    context_window INTEGER,
    max_output_tokens INTEGER,
    embedding_dimension INTEGER,
    input_price_per_1k NUMERIC(12, 8),
    output_price_per_1k NUMERIC(12, 8),
    local_model BOOLEAN NOT NULL DEFAULT FALSE,
    default_model BOOLEAN NOT NULL DEFAULT FALSE,
    capabilities_json JSONB NOT NULL DEFAULT '{}'::jsonb,
    options_json JSONB NOT NULL DEFAULT '{}'::jsonb,
    enabled BOOLEAN NOT NULL DEFAULT TRUE,
    version INTEGER NOT NULL DEFAULT 1,
    create_time TIMESTAMP,
    update_time TIMESTAMP,
    remark VARCHAR(500) DEFAULT '',
    create_by VARCHAR(64),
    update_by VARCHAR(64),
    CONSTRAINT uk_model_config_provider_code UNIQUE (provider_id, model_code),
    CONSTRAINT fk_model_config_provider_id FOREIGN KEY (provider_id) REFERENCES model_provider (id)
);

字段说明:

字段 说明
model_code 平台内部模型编码
model_name 展示名称
upstream_model 上游真实模型名,例如 Qwen/Qwen3-Embedding-0.6Bqwen2.5:7b
model_type CHATEMBEDDINGRERANKMULTIMODAL
embedding_dimension Embedding 输出维度RAG 首期使用 1024
capabilities_json 能力标签例如是否支持工具调用、视觉、JSON 输出
options_json 模型调用默认参数,例如 temperaturetopPdimensions

5.3 model_route_rule 模型路由规则表

用于根据任务类型和范围选择模型。

CREATE TABLE model_route_rule (
    id BIGSERIAL PRIMARY KEY,
    route_code VARCHAR(100) NOT NULL,
    route_name VARCHAR(100) NOT NULL,
    task_type VARCHAR(50) NOT NULL,
    match_scope VARCHAR(50) NOT NULL DEFAULT 'GLOBAL',
    scope_id BIGINT,
    primary_model_id BIGINT NOT NULL,
    fallback_model_ids_json JSONB NOT NULL DEFAULT '[]'::jsonb,
    route_strategy VARCHAR(50) NOT NULL DEFAULT 'MANUAL',
    max_latency_ms INTEGER,
    enabled BOOLEAN NOT NULL DEFAULT TRUE,
    version INTEGER NOT NULL DEFAULT 1,
    create_time TIMESTAMP,
    update_time TIMESTAMP,
    remark VARCHAR(500) DEFAULT '',
    create_by VARCHAR(64),
    update_by VARCHAR(64),
    CONSTRAINT uk_model_route_rule_code UNIQUE (route_code),
    CONSTRAINT fk_model_route_primary_model_id FOREIGN KEY (primary_model_id) REFERENCES model_config (id)
);

字段说明:

字段 说明
task_type 任务类型,例如 RAG_EMBEDDINGCHAT_SIMPLEAGENT_PLANNING
match_scope 匹配范围,例如 GLOBALRAG_STOREAGENT
scope_id 范围 ID例如知识库 ID 或 Agent ID
primary_model_id 主模型
fallback_model_ids_json 备用模型 ID 列表
route_strategy LOCAL_FIRSTCOST_FIRSTQUALITY_FIRSTMANUAL

5.4 rag_store_model_config 知识库模型绑定表

用于固定知识库的 Embedding 模型和维度,避免同一知识库混用向量空间。

CREATE TABLE rag_store_model_config (
    id BIGSERIAL PRIMARY KEY,
    store_id BIGINT NOT NULL,
    embedding_model_id BIGINT NOT NULL,
    embedding_dimension INTEGER NOT NULL DEFAULT 1024,
    chunk_strategy INTEGER,
    chunk_size INTEGER,
    chunk_overlap INTEGER,
    delimiter VARCHAR(50),
    active BOOLEAN NOT NULL DEFAULT TRUE,
    index_version INTEGER NOT NULL DEFAULT 1,
    version INTEGER NOT NULL DEFAULT 1,
    create_time TIMESTAMP,
    update_time TIMESTAMP,
    remark VARCHAR(500) DEFAULT '',
    create_by VARCHAR(64),
    update_by VARCHAR(64),
    CONSTRAINT uk_rag_store_model_config_store_active UNIQUE (store_id, active),
    CONSTRAINT fk_rag_store_model_config_store_id FOREIGN KEY (store_id) REFERENCES rag_store (id),
    CONSTRAINT fk_rag_store_model_config_embedding_model_id FOREIGN KEY (embedding_model_id) REFERENCES model_config (id)
);

设计约束:

  • 首期每个知识库只有一个生效配置。
  • 更换 Embedding 模型或维度时,index_version 增加,并触发重建索引。
  • 检索时只使用当前生效配置对应的向量。

5.5 model_call_log 模型调用日志表

用于记录模型调用行为。

CREATE TABLE model_call_log (
    id BIGSERIAL PRIMARY KEY,
    request_id VARCHAR(64) NOT NULL,
    provider_id BIGINT,
    model_id BIGINT,
    task_type VARCHAR(50) NOT NULL,
    biz_type VARCHAR(50),
    biz_id VARCHAR(100),
    call_type VARCHAR(50) NOT NULL,
    status VARCHAR(50) NOT NULL,
    prompt_tokens INTEGER,
    completion_tokens INTEGER,
    total_tokens INTEGER,
    estimated_cost NUMERIC(14, 8),
    duration_ms INTEGER,
    request_hash VARCHAR(64),
    error_code VARCHAR(100),
    error_message VARCHAR(1000),
    create_time TIMESTAMP,
    remark VARCHAR(500) DEFAULT '',
    CONSTRAINT uk_model_call_log_request_id UNIQUE (request_id)
);

字段说明:

字段 说明
request_id 单次模型调用请求 ID
task_type 任务类型
biz_type 业务类型,例如 RAG_DOCUMENT_INDEX
biz_id 业务 ID例如文档 ID
call_type CHATEMBEDDINGRERANK
status SUCCESSFAILEDTIMEOUTFALLBACK_SUCCESS
request_hash 请求内容哈希,用于排障和幂等分析,不保存完整敏感内容

6. 枚举设计

新增枚举应实现现有 PersistableSysEnumDefinition,并同步到 sys_enum

枚举
ModelProviderTypeEnum OLLAMASILICONFLOWDASHSCOPEOPENAICUSTOM
ModelProtocolTypeEnum OPENAI_COMPATIBLE
ModelTypeEnum CHATEMBEDDINGRERANKMULTIMODAL
ModelTaskTypeEnum RAG_EMBEDDINGRAG_QUERY_EMBEDDINGRAG_ANSWERCHAT_SIMPLECHAT_COMPLEXAGENT_PLANNINGRERANK
ModelRouteStrategyEnum LOCAL_FIRSTCOST_FIRSTQUALITY_FIRSTMANUAL
ModelCallStatusEnum SUCCESSFAILEDTIMEOUTFALLBACK_SUCCESS
ModelHealthStatusEnum UNKNOWNHEALTHYUNHEALTHY

7. 服务接口设计

7.1 配置管理服务

public interface IModelProviderService extends IService<ModelProvider> {
    List<ModelProviderResponse> query(ModelProviderQueryRequest request);
    ModelProviderResponse getResponseById(Long id);
    boolean saveOrUpdate(ModelProviderSaveRequest request);
    boolean checkHealth(Long id);
}
public interface IModelConfigService extends IService<ModelConfig> {
    List<ModelConfigResponse> query(ModelConfigQueryRequest request);
    ModelConfigResponse getResponseById(Long id);
    boolean saveOrUpdate(ModelConfigSaveRequest request);
    ModelConfig getEnabledModel(Long modelId);
}

7.2 路由服务

public interface IModelRouteService {
    ModelRouteDecision route(ModelRouteContext context);
}

ModelRouteContext 应包含:

  • taskType
  • matchScope
  • scopeId
  • requiredModelType
  • preferredLocal
  • requiredEmbeddingDimension
  • bizType
  • bizId

ModelRouteDecision 应包含:

  • 主模型。
  • 备用模型列表。
  • 路由策略。
  • 决策原因。

7.3 模型网关

public interface EmbeddingModelGateway {
    EmbeddingResult embed(EmbeddingRequest request);
}
public interface ChatModelGateway {
    ChatResult chat(ChatRequest request);
}

EmbeddingRequest 应包含:

  • 文本列表。
  • 任务类型。
  • 匹配范围。
  • 范围 ID。
  • 业务类型。
  • 业务 ID。
  • 期望维度。

EmbeddingResult 应包含:

  • 模型 ID。
  • 模型名称。
  • 维度。
  • 向量列表。
  • 调用日志 ID。

8. 客户端设计

首期优先实现 OpenAiCompatibleModelClient,统一调用以下接口:

  • POST /v1/embeddings
  • POST /v1/chat/completions

OpenAI-compatible 客户端输入来自数据库配置:

配置来源 字段
model_provider.base_url 服务基础地址
model_provider.secret_ref / api_key_cipher 鉴权信息
model_config.upstream_model 上游模型名
model_config.options_json 调用参数
model_config.embedding_dimension Embedding 维度

8.1 Spring AI 使用方式

项目可以在两个阶段使用 Spring AI

第一阶段:使用项目自定义 ModelGateway 和 OpenAI-compatible HTTP 客户端,优先解决多服务商动态配置问题。

第二阶段:在稳定后引入 Spring AI 的 EmbeddingModelChatModel 抽象或适配器,将动态客户端包装为平台内部统一接口。

这样设计的原因是 Spring Boot 自动配置更适合单默认服务商,而本项目需要从数据库动态选择多个 provider。业务层保持 ModelGateway 抽象,后续替换底层实现不会影响 RAG 和 Agent。

8.2 Ollama 适配

Ollama 使用 OpenAI-compatible 地址:

http://<ollama-host>:11434/v1

配置示例:

字段 示例
provider_code ollama-main
provider_type OLLAMA
protocol_type OPENAI_COMPATIBLE
base_url http://10.0.0.10:11434/v1
auth_type NONEBEARER_TOKEN
model_config.upstream_model qwen2.5:7b

部署建议:

  • 开发环境可以通过内网访问。
  • 生产环境不要直接开放 11434 到公网。
  • 推荐使用 VPN、Tailscale、Cloudflare Tunnel、Nginx 鉴权反向代理或安全网关。
  • 如果必须公网访问,需要 HTTPS、鉴权、IP 白名单和访问日志。

8.3 硅基流动适配

配置示例:

字段 示例
provider_code siliconflow
provider_type SILICONFLOW
protocol_type OPENAI_COMPATIBLE
base_url https://api.siliconflow.cn/v1
secret_ref SILICONFLOW_API_KEY
model_config.upstream_model Qwen/Qwen3-Embedding-0.6B
embedding_dimension 1024

RAG 首期推荐使用 1024 维 Embedding匹配当前 rag_chunk_embedding.embedding VECTOR(1024)

8.4 百炼适配

百炼 OpenAI-compatible 配置示例:

字段 示例
provider_code dashscope
provider_type DASHSCOPE
protocol_type OPENAI_COMPATIBLE
base_url https://dashscope.aliyuncs.com/compatible-mode/v1
secret_ref DASHSCOPE_API_KEY
model_config.upstream_model text-embedding-v4
embedding_dimension 1024

9. 路由策略设计

9.1 路由优先级

模型路由按以下顺序匹配:

  1. 业务范围精确规则,例如某个知识库或某个 Agent。
  2. 任务类型规则,例如 RAG_EMBEDDING
  3. 全局默认规则。
  4. 模型类型默认模型。

如果没有匹配到模型,应返回清晰错误,不隐式选择不确定模型。

9.2 策略说明

策略 行为
MANUAL 使用规则中指定的主模型
LOCAL_FIRST 优先选择本地模型,失败后使用备用云端模型
COST_FIRST 在可用模型中优先选择成本低的模型
QUALITY_FIRST 优先选择质量更高或优先级更高的模型

首期可以只实现 MANUALLOCAL_FIRST,其余策略先完成数据结构和枚举。

9.3 失败兜底

主模型调用失败时:

  1. 记录主模型失败日志。
  2. 判断是否存在备用模型。
  3. 按备用模型顺序重试。
  4. 若备用模型成功,返回结果并记录 FALLBACK_SUCCESS
  5. 若全部失败,返回最后一次错误,并将业务状态更新为失败。

RAG 向量导入首期应谨慎使用 fallback。Embedding 模型 fallback 只有在维度和语义模型族一致时才允许自动切换,否则应失败并提示重建或重新配置。

10. RAG 向量导入设计

10.1 当前 RAG 状态

当前项目已有:

  • rag_document
  • rag_document_parse_result
  • rag_chunk
  • rag_chunk_embedding
  • RagDocumentParseServiceImpl
  • RagDocumentChunkServiceImpl
  • FixedLengthChunker
  • DelimiterChunker

下一步需要把切片服务和 Embedding 网关串起来。

10.2 目标流程

sequenceDiagram
    participant User as 用户/后台
    participant Doc as RagDocumentService
    participant Parse as RagDocumentParseService
    participant Chunk as RagDocumentChunkService
    participant Gateway as EmbeddingModelGateway
    participant Provider as 上游模型服务
    participant DB as PostgreSQL

    User->>Doc: 上传文档
    Doc->>Parse: 自动解析
    Parse->>DB: 保存解析快照
    Parse->>DB: 更新 parseStatus=PARSED
    Doc->>Chunk: 提交切片索引任务
    Chunk->>DB: 更新 indexStatus=INDEXING
    Chunk->>DB: 读取解析快照
    Chunk->>DB: 删除旧切片和旧向量
    Chunk->>DB: 写入 rag_chunk
    Chunk->>Gateway: 批量生成 Embedding
    Gateway->>Provider: POST /v1/embeddings
    Provider-->>Gateway: 返回向量
    Gateway->>DB: 记录 model_call_log
    Chunk->>DB: 写入 rag_chunk_embedding
    Chunk->>DB: 更新 indexStatus=INDEXED

10.3 状态流转

rag_document.index_status 流转:

PENDING -> INDEXING -> INDEXED
PENDING -> INDEXING -> FAILED
INDEXED -> INDEXING -> INDEXED
INDEXED -> INDEXING -> FAILED

失败时应写入 rag_document.error_message

10.4 切片与向量写入规则

  1. 生成新切片前,先删除当前文档旧向量,再删除旧切片。
  2. 新切片保存成功后,再批量调用 Embedding。
  3. Embedding 成功后写入 rag_chunk_embedding
  4. 每条 embedding 记录保存 embedding_modelembedding_dimensioncontent_hash
  5. embedding 字段以 pgvector 可接受的字符串格式保存,例如 [0.1,0.2,0.3]
  6. 向量数量必须等于切片数量,否则本次索引失败。

10.5 知识库模型绑定

RAG 索引选择模型的优先级:

  1. rag_store_model_config 中该知识库绑定的 Embedding 模型。
  2. model_route_rulematch_scope=RAG_STORE 的规则。
  3. model_route_ruletask_type=RAG_EMBEDDING 的全局规则。
  4. 全局默认 Embedding 模型。

如果以上都不存在,索引任务失败并提示需要配置 Embedding 模型。

11. API 设计

11.1 服务商接口

方法 路径 说明
POST /api/model/providers/query 查询服务商
GET /api/model/providers/detail 服务商详情
POST /api/model/providers/save 新增或修改服务商
POST /api/model/providers/delete 删除服务商
POST /api/model/providers/checkHealth 健康检查

服务商详情接口不返回 apiKeyCipher 明文。

11.2 模型接口

方法 路径 说明
POST /api/model/configs/query 查询模型
GET /api/model/configs/detail 模型详情
POST /api/model/configs/save 新增或修改模型
POST /api/model/configs/delete 删除模型

11.3 路由规则接口

方法 路径 说明
POST /api/model/routes/query 查询路由规则
GET /api/model/routes/detail 路由规则详情
POST /api/model/routes/save 新增或修改路由规则
POST /api/model/routes/delete 删除路由规则

11.4 调用日志接口

方法 路径 说明
POST /api/model/call-logs/query 查询调用日志
GET /api/model/call-logs/detail 调用日志详情

11.5 RAG 模型配置接口

方法 路径 说明
GET /api/rag/store/modelConfig 查询知识库模型配置
POST /api/rag/store/modelConfig/save 保存知识库模型配置
POST /api/rag/store/rebuildIndex 重建知识库索引

12. DTO 设计要点

所有 API 保持现有项目规范:

  • Controller 返回 RequestResult<T>
  • 请求对象使用业务语义明确的 Request 类,例如 ModelProviderSaveRequest
  • 响应对象使用业务语义明确的 Response 类,例如 ModelProviderResponse
  • 响应 DTO 提供 fromEntity() 静态转换。
  • Long ID 输出给前端时使用 ToStringSerializer

ModelProviderResponse 不包含完整密钥,只包含:

  • secretRef
  • hasApiKey
  • authType

13. 密钥处理设计

13.1 推荐方式

首期推荐使用 secret_ref

model_provider.secret_ref = SILICONFLOW_API_KEY

运行时从环境变量读取:

SILICONFLOW_API_KEY=sk-***

优点:

  • 数据库不保存密钥。
  • 本地、测试、生产可以使用不同环境变量。
  • 实现简单,风险较低。

13.2 可选加密方式

如需在数据库中保存密钥,应保存 api_key_cipher,并使用环境变量中的主密钥加解密:

COMMON_AGENT_SECRET_KEY=<secret-from-environment>

约束:

  • 主密钥不入库。
  • 前端不返回密钥明文。
  • 修改密钥时只允许写入,不允许读取原文。

14. 调用日志与费用估算

调用日志记录在 model_call_log

费用估算规则:

estimatedCost = promptTokens / 1000 * inputPricePer1k
              + completionTokens / 1000 * outputPricePer1k

Embedding 模型通常只使用输入 token 费用。若上游不返回 token 信息,首期可以记录空值,后续通过本地 tokenizer 或文本长度估算。

日志脱敏规则:

  • 不记录完整 API Key。
  • 不默认记录完整 prompt。
  • 可记录请求哈希。
  • 错误信息截断到 1000 字以内。

15. 健康检查设计

健康检查目标是判断服务商是否可用。

首期检查方式:

  • OpenAI-compatible 服务调用 /v1/models
  • Ollama 同样可通过 OpenAI-compatible /v1/models 检查。
  • 如果服务商不支持 /v1/models,可配置跳过健康检查或使用轻量模型调用。

健康状态:

状态 说明
UNKNOWN 尚未检查
HEALTHY 最近一次检查成功
UNHEALTHY 最近一次检查失败

16. 异常处理设计

常见异常:

场景 处理方式
服务商停用 路由阶段直接失败
模型停用 路由阶段跳过或失败
缺少 API Key 调用前失败,提示密钥未配置
上游超时 记录 TIMEOUT,尝试备用模型
上游返回错误 记录 FAILED,保留错误码和摘要
Embedding 维度不匹配 RAG 索引失败,不写入向量
向量数量不匹配 RAG 索引失败,清理本次中间数据

17. 前端页面设计

前端延续当前后台风格,保持信息密度和可扫描性。

建议新增页面:

页面 功能
模型服务商 服务商列表、启停用、健康检查、编辑
模型配置 模型列表、类型筛选、价格和能力配置
路由规则 按任务类型配置主模型和备用模型
调用日志 查询调用状态、耗时、服务商、模型、错误
知识库模型配置 在知识库详情中配置 Embedding 模型和重建索引

首期后端优先,前端可以在 RAG 最小闭环完成后接入。

18. 测试设计

18.1 单元测试

需要覆盖:

  • 实体字段结构。
  • Mapper 和 Service 继承结构。
  • DTO 转换。
  • 服务商编码唯一校验。
  • 模型编码唯一校验。
  • 路由优先级。
  • 密钥引用解析。
  • Embedding 维度校验。

18.2 RAG 集成测试

需要覆盖:

  • 文档解析快照转切片。
  • 切片批量调用 Embedding 网关。
  • 向量数量与切片数量一致。
  • 向量写入 rag_chunk_embedding
  • 索引状态成功流转。
  • Embedding 失败时索引状态为 FAILED

18.3 客户端测试

OpenAI-compatible 客户端使用 Mock Web Server 或类似方式测试:

  • /v1/embeddings 成功响应。
  • /v1/chat/completions 成功响应。
  • 401 鉴权失败。
  • 429 限流。
  • 5xx 上游错误。
  • 超时。

19. 实施计划

19.1 第一阶段:配置数据结构

  1. 新增 SQL 脚本。
  2. 新增实体、Mapper、Service、Controller。
  3. 新增枚举并同步 sys_enum 测试。
  4. 新增结构稳定性测试。

19.2 第二阶段Embedding 网关

  1. 新增 EmbeddingModelGateway
  2. 新增 OpenAI-compatible Embedding 客户端。
  3. 新增密钥解析器。
  4. 新增调用日志服务。
  5. 完成 Mock 单元测试。

19.3 第三阶段RAG 向量导入

  1. 扩展 RagDocumentChunkServiceImpl
  2. 切片后调用 Embedding 网关。
  3. 写入 rag_chunk_embedding
  4. 更新 indexStatus
  5. 完成失败回滚和日志记录。

19.4 第四阶段:路由与前端

  1. 新增路由规则服务。
  2. RAG 按知识库配置或路由规则选择模型。
  3. 接入前端模型配置页面。
  4. 接入调用日志查询页面。

20. 配置示例

20.1 Ollama 服务商

{
  "providerCode": "ollama-main",
  "providerName": "远程 Ollama",
  "providerType": "OLLAMA",
  "protocolType": "OPENAI_COMPATIBLE",
  "baseUrl": "http://10.0.0.10:11434/v1",
  "authType": "NONE",
  "timeoutMs": 120000,
  "enabled": true
}

20.2 硅基流动 Embedding 模型

{
  "providerId": "1001",
  "modelCode": "siliconflow-qwen3-embedding-0_6b",
  "modelName": "硅基流动 Qwen3 Embedding 0.6B",
  "upstreamModel": "Qwen/Qwen3-Embedding-0.6B",
  "modelType": "EMBEDDING",
  "embeddingDimension": 1024,
  "localModel": false,
  "enabled": true,
  "optionsJson": {
    "dimensions": 1024,
    "encoding_format": "float"
  }
}

20.3 RAG Embedding 路由规则

{
  "routeCode": "global-rag-embedding",
  "routeName": "全局 RAG 向量模型",
  "taskType": "RAG_EMBEDDING",
  "matchScope": "GLOBAL",
  "primaryModelId": "2001",
  "fallbackModelIds": [],
  "routeStrategy": "MANUAL",
  "enabled": true
}

21. 风险与对策

风险 对策
动态多服务商与 Spring AI 自动配置存在差异 先用项目内部 ModelGateway 隔离,后续逐步适配 Spring AI
Ollama 远程服务暴露风险 文档和配置中明确生产环境必须通过安全通道访问
Embedding 模型混用导致检索漂移 知识库绑定模型和维度,变更时重建索引
云端 API 费用不可控 路由策略、调用日志和费用估算逐步完善
上游接口返回格式差异 首期只承诺 OpenAI-compatible特殊服务商后续单独适配
大批量向量化超时 支持批量大小配置、异步任务和失败重试

22. 后续扩展

后续可以扩展:

  • Rerank 模型网关。
  • Agent 级模型配置。
  • 用户级额度和限流。
  • 模型质量评测。
  • 模型调用缓存。
  • Prompt 模板与模型绑定。
  • 多索引版本并存。
  • 调用日志聚合报表。

23. 参考资料