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

输出:

vbnet 复制代码
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 流程

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

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

搜索时:

scss 复制代码
查询文本
    ↓ 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...

相关推荐
程序员辉哥3 小时前
深入 OpenSpec 源码,我发现了控制 AI 行为的三层架构
openai·ai编程·claude
Mr_hwt_1233 小时前
Windows安装Claude Code详细教程(含apikey配置)
windows·ai编程·claude code
_大学牲4 小时前
从零实现自己的agent第五期:子代理实现
github·agent·ai编程
JavaGuide4 小时前
Claude Code + BrowserAct,夯爆了!一句话让 AI 帮你操控浏览器。
前端·后端·ai编程
程序员老刘4 小时前
为什么AI不会淘汰Flutter,反而让它更吃香了
flutter·ai编程·客户端
JavaEdge在掘金5 小时前
07-LangChain Toolkit 实战:从工具函数到 Python Agent,再到 SQL Agent
ai编程
来一斤小鲜肉6 小时前
Claude Code的Hooks操作
ai编程
shuangrenlong7 小时前
claude插件Superpowers安装
ai编程
ZZH_AI项目交付7 小时前
AI 改完代码后,下一轮不能只看它改了哪些文件
aigc·ai编程