Embedding 模型选型与配置

本文面向:需要为语义搜索选择合适 Embedding 模型的开发者。

预计阅读时间:7 分钟


Embedding 模型是干什么的

一句话:把文本变成向量(一组浮点数),让计算机能「理解」文本的语义相似度。

搜「CORS 跨域问题」时,Embedding 模型把这个查询转成向量,然后在知识库里找语义最接近的笔记。这就是为什么搜「跨域报错」也能匹配到标题是「CORS 配置」的笔记------它们的向量距离很近。

选型标准

选 Embedding 模型主要看三个维度:

维度 说明 重要性
质量 语义理解能力,决定搜索精准度 ★★★★★
速度 单次 Embedding 延迟 ★★★
成本 API 费用或本地资源占用 ★★★

推荐模型

本地模型(Ollama)

模型 大小 维度 质量 说明
nomic-embed-text 274MB 768 ★★★★ 首选推荐,专为 Embedding 设计
mxbai-embed-large 670MB 1024 ★★★★ 更大模型,精度略高
bash 复制代码
# 安装推荐模型
ollama pull nomic-embed-text

本地模型的优势:免费、隐私、离线可用。nomic-embed-text 是目前 Ollama 生态里最成熟的 Embedding 模型,274MB 对任何机器都不是负担。

云端模型

Provider 模型 维度 质量 价格
OpenAI text-embedding-3-small 1536 ★★★★ $0.02/1M tokens
OpenAI text-embedding-3-large 3072 ★★★★★ $0.13/1M tokens
Google text-embedding-004 768 ★★★★ 免费额度内

云端模型质量更好,特别是 OpenAI 的 text-embedding-3-large,维度 3072,语义区分能力最强。但需要 API Key 和网络。

配置方法

方式一:设置页面

打开 ChatCrystal 设置页面,在 Embedding 部分填写:

字段
Embedding Provider ollama / openai / google
Embedding Model nomic-embed-text / text-embedding-3-small / ...
Embedding Base URL http://localhost:11434(Ollama 需要)
Embedding API Key 你的 API Key(云端需要)

方式二:CLI

bash 复制代码
# Ollama
crystal config set embedding.provider ollama
crystal config set embedding.model nomic-embed-text

# OpenAI
crystal config set embedding.provider openai
crystal config set embedding.model text-embedding-3-small
crystal config set embedding.apiKey sk-...

# Google
crystal config set embedding.provider google
crystal config set embedding.model text-embedding-004
crystal config set embedding.apiKey AIza...

方式三:环境变量

env 复制代码
EMBEDDING_PROVIDER=openai
EMBEDDING_MODEL=text-embedding-3-small
EMBEDDING_API_KEY=sk-your-key

验证配置

bash 复制代码
crystal config test

输出:

复制代码
LLM: connected (response: "OK")
Embedding: connected

如果报错,常见原因:

错误 原因 解决
404 Not Found 模型名拼错 检查模型名称
model not found Ollama 没拉取 ollama pull 模型名
unauthorized API Key 错误 检查 Key
ECONNREFUSED Ollama 没运行 ollama serve

ChatCrystal 的 Embedding 流程

了解内部流程有助于理解搜索质量的影响因素:

复制代码
笔记内容
    ↓ buildNoteEmbeddingText()
拼接:标题 + 摘要 + 结论 + 标签 + 代码描述
    ↓ chunkText()
按 500 字符分段(段落边界优先)
    ↓ embed() × N 段
每段生成一个向量
    ↓ vectra LocalIndex
存入本地向量索引

搜索时:

复制代码
查询文本
    ↓ embed()
查询向量
    ↓ vectra.queryItems()
与所有笔记向量计算相似度
    ↓ 按 score 排序
返回 Top K 结果

分块策略

ChatCrystal 按 500 字符分块,优先在段落边界切分:

typescript 复制代码
const CHUNK_SIZE = 500;

function chunkText(text: string): string[] {
  if (text.length <= CHUNK_SIZE) return [text];

  const chunks: string[] = [];
  const paragraphs = text.split(/\n\n+/);
  let current = '';

  for (const para of paragraphs) {
    if (current.length + para.length + 2 > CHUNK_SIZE && current.length > 0) {
      chunks.push(current.trim());
      current = para;
    } else {
      current += (current ? '\n\n' : '') + para;
    }
  }
  if (current.trim()) chunks.push(current.trim());

  return chunks;
}

为什么要分块?因为 Embedding 模型对输入长度有限制,而且太长的文本 Embedding 质量会下降。500 字符是一个经验性的平衡点。

Embedding 文本构建

ChatCrystal 不是直接把笔记原文做 Embedding,而是提取关键信息拼接:

  • 标题
  • 摘要
  • 关键结论(逐条)
  • 标签
  • 代码片段的描述(不含代码本身)

这样做的好处是向量更聚焦于语义信息,不会被代码细节稀释。

维度和质量的关系

维度越高,向量能表达的语义信息越丰富:

维度 能力 模型
768 够用,大部分场景没问题 nomic-embed-text, text-embedding-004
1024 更好,细微语义区分更强 mxbai-embed-large
1536 很好,适合大量专业内容 text-embedding-3-small
3072 最强,但资源消耗也最大 text-embedding-3-large

对 ChatCrystal 的使用场景(搜索 AI 对话笔记),768 维已经够用。除非你的笔记数量上千条且内容高度专业,否则不需要追求 3072 维。

混合搭配建议

Embedding 可以和 LLM 用不同的 Provider:

LLM 推荐 Embedding 理由
Ollama (qwen2.5:7b) Ollama (nomic-embed-text) 全免费,全本地
OpenAI (gpt-4o) OpenAI (text-embedding-3-small) 同一 Provider,统一计费
Anthropic (claude) OpenAI (text-embedding-3-small) Anthropic 无 Embedding 模型
Google (gemini) Google (text-embedding-004) 免费额度慷慨
DeepSeek (custom) Ollama (nomic-embed-text) LLM 便宜 + Embedding 免费

切换模型后需要重新生成

更换 Embedding 模型后,已有的向量索引需要重建。因为不同模型生成的向量维度和分布不同,不能混用。

bash 复制代码
# 1. 删除旧的向量索引
rm -rf <dataDir>/vectra-index

# 2. 用新模型批量重建所有笔记的 Embedding
curl -X POST http://localhost:3721/api/embeddings/batch

笔记数量多的话需要一些时间。

注意crystal summarize --all 只会为状态为 'imported'、'error' 或 'summarizing' 的对话排队摘要生成,不会重建 Embedding。如果只是切换了 Embedding 模型而笔记内容不需要重新生成,应该删除 vectra-index 目录后调用 POST /api/embeddings/batch 来重建向量索引。


项目地址:github.com/ZengLiangYi/ChatCrystal

相关推荐
小江的记录本2 小时前
【Java基础】核心关键字:final、static、volatile、synchronized、transient(附《思维导图》+《面试高频考点清单》)
java·前端·数据结构·后端·ai·面试·ai编程
JavaPub-rodert2 小时前
Codex + cc-switch + GPT-5.5 国内使用教程:从注册 API 到接入 VS Code / Cursor,一篇讲清楚
人工智能·gpt·开源·codex·ccswitch
怕浪猫3 小时前
AI 3D 大模型创作
aigc·openai·ai编程
孟健3 小时前
我把多 Agent 协作搬进 Hermes Kanban,才发现群聊派活真的不够用了
ai编程
constCpp3 小时前
大模型是怎么“思考”的?
ai编程
haibindev4 小时前
别让AI再从零写一堆优美的屎山了
c++·ai编程·claude·流媒体·codex·代码复用
小碗细面4 小时前
Agents 编排工具 - OMC 和 Ruflo,到底该怎么选?
ai编程·claude
名不经传的养虾人5 小时前
从0到1:企业级AI项目迭代日记 Vol.28|企业AI的交付不是给工具,而是给搭好的能力
大数据·人工智能·ai编程·ai工作流·企业ai·多agent协作
DisonTangor5 小时前
【SIGGRAPH 2026】Pixal3D: 基于图像的像素对齐三维生成
人工智能·3d·开源·aigc