Embedding 适配器与向量维度
查阅 Embedding 适配器分派、上游 Token 计量、动态维度检测与 Qdrant 集合映射
Clouisle 的文本嵌入(Embedding)体系为知识库检索增强(RAG)和会话长期记忆提供向量化基础。系统采用分层适配器架构,支持多供应商无缝接入、运行时动态维度检测与多维度向量隔离存储。
适配器分派架构
Embedding 模型通过 backend/app/llm/adapters/embedding/ 统一调度。调用方无需关心上游协议差异,适配器工厂依据模型的 provider 自动分派到最佳实现:
| 适配器类 | 匹配供应商 | 工作机制 | Token 计量策略 |
|---|---|---|---|
OpenAICompatibleEmbeddingAdapter | openai、openai_responses、deepseek、moonshot、zhipu、qwen、baichuan、minimax、volcengine、siliconflow、xai、ollama、custom | 直接通过 HTTP POST 请求目标 Base URL 的 /embeddings 端点(标准 OpenAI 协议) | 读取响应体 usage(取 prompt_tokens,缺失时回退 total_tokens);若供应商未返回,降级使用 tiktoken 准确分词计数 |
FallbackEmbeddingAdapter | google、azure_openai(其余供应商不支持 embedding,创建时即被拒绝) | 调用 LangChain 专用封装(如 GoogleGenerativeAIEmbeddings、AzureOpenAIEmbeddings)通过 aembed_documents 获取向量 | 适配器返回空的 Usage,由外层 team_embedding 统一调用本地 tiktoken 计算实际 Token 消耗 |
不支持的供应商
model_type: embedding 只在 EMBEDDING_SUPPORTED_PROVIDERS(即上表两条路径覆盖的 15 个供应商)内可用;为 anthropic、typesafe、runway、pika、luma、kling、stability、midjourney 等供应商创建 embedding 模型会在校验阶段被直接拒绝(model_type_not_supported)。
Anthropic 官方不提供独立的 Text Embedding API;即便绕过校验,运行时也会抛出 ValueError: Unsupported provider for embedding: anthropic。
容错与降级机制
OpenAICompatibleEmbeddingAdapter 在发起直接 HTTP 调用时:
- 请求超时时间固定为
60.0秒(DEFAULT_EMBEDDING_REQUEST_TIMEOUT),最大重试次数为2次。 - 若直接 HTTP 请求因网络波动、协议微小差异或非 200 响应失败,适配器会自动在
except块中捕获异常,并无缝降级到底层 LangChainOpenAIEmbeddings实例执行补救重试。
团队配额检查与 Token 计量链路
当工作流或知识库索引触发 team_embedding(team_id, texts, model_id) 时,系统执行严格的三步链路:
- 授权与配额前置拦截:
- 检验团队是否拥有该模型的有效使用授权。
- 调用
usage_tracker.check_quota_with_model()核查团队每日与月度的 Token 和请求配额,超额即时抛出LLMQuotaExceededError(业务错误码6103)。
- 生成向量与 Token 统计:
- 适配器执行文本嵌入。
- 若上游返回了
usage.total_tokens,直接采纳;否则调用count_tokens(text, model_id, provider)进行本地tiktoken兜底统计(至少计为 1 Token)。
- 后置用量扣减与入库:
- 将确切的 Token 消耗异步计入团队使用量账本(
team_model_usages表),支持按日与按月实时追踪。
- 将确切的 Token 消耗异步计入团队使用量账本(
动态维度检测与不可变性
不同的 Embedding 模型产出的向量维度各异(如 OpenAI text-embedding-3-small 为 1536 维,text-embedding-3-large 为 3072 维,开源 BGE 模型常见 768 或 1024 维)。Clouisle 支持全自动动态维度适配:
1. 维度自适应生命周期
- 创建知识库:管理员创建知识库时指定
embedding_model_id,此时知识库数据库记录的embedding_dimension允许为null。 - 首次索引绑定:当知识库处理第一批文档切片时,系统调用模型生成第一批向量并测量其长度
len(embedding[0])。 - 固化维度:系统调用
set_kb_embedding_dimension(kb_id, dimension)将该维度持久化到knowledge_bases表。
2. 维度与模型的不可变性约束
- 模型不可变:知识库一旦创建,
embedding_model_id即被永久锁定。更新知识库接口(PATCH /knowledge-bases/{id})检测到变更embedding_model_id时会拒绝并返回校验错误(embedding_model_locked_after_kb_creation)。 - 维度严格匹配:后续导入的任何文档切片向量,均须经过
_validate_embeddings校验。若向量维度与知识库已固化的embedding_dimension不一致,系统抛出DimensionMismatchError并阻断入库。
Qdrant 多维度集合隔离架构
Clouisle 的向量数据库默认采用 Qdrant。为支持多模型共存,系统根据向量维度对集合进行水平分区:
Qdrant 实例 (http://localhost:6333)
├── kb_dim_768 (针对 768 维模型,如 BGE-base)
├── kb_dim_1024 (针对 1024 维模型,如 BGE-large)
├── kb_dim_1536 (针对 1536 维模型,如 text-embedding-3-small)
└── kb_dim_3072 (针对 3072 维模型,如 text-embedding-3-large)集合与索引规则
- 集合命名规范:
${QDRANT_COLLECTION_PREFIX}_${dimension}(默认前缀为kb_dim,即kb_dim_1536)。 - 距离度量:默认为余弦相似度
Cosine(支持在环境变量中配置Dot或Euclid)。 - 自动建表:首次向某维度写入向量时,系统自动在 Qdrant 中创建对应集合,并自动为
kb_id和document_id建立有效载荷索引(Payload Index),确保基于知识库 ID 的检索过滤拥有最高性能。
批处理规格与超时参数
| 参数项 | 设定值 | 说明 |
|---|---|---|
| 文档向量化切片批次 | 25(默认) | store_chunks_with_progress 每批处理 25 个文档切片,逐批生成嵌入、持久化并更新进度 |
| 适配器单次请求超时 | 60.0 秒 | DEFAULT_EMBEDDING_REQUEST_TIMEOUT,用于 HTTPX 与 LangChain 客户端请求 |
| 向量存储操作超时 | 120.0 秒 | EMBEDDING_REQUEST_TIMEOUT_SECONDS,用于包含重试在内的端到端入库或密集查询 |
| 适配器最大重试次数 | 2 次 | DEFAULT_EMBEDDING_MAX_RETRIES |
这篇文章对你有帮助吗?