跳转到内容

把文本变成向量

Embedding 不是“另一种聊天模型”,它解决的是另一类问题:
如何把文本变成可计算相似度的向量表示。

如果你没有要做检索、RAG、去重、聚类或语义搜索,就不用急着看这一页。

  • 你要做 RAG
  • 你要做语义检索
  • 你要做文本去重或聚类

如果你现在只是想调模型输出文本,先停在 配置对话模型并处理流式输出

EmbeddingDemo.java
import tech.smartboot.feat.ai.FeatAI;
import tech.smartboot.feat.ai.embedding.EmbeddingModel;
import tech.smartboot.feat.ai.embedding.EmbeddingModelVendor;
import java.util.Arrays;
public class EmbeddingDemo {
public static void main(String[] args) {
EmbeddingModel model = FeatAI.embedding(opt ->
opt.model(EmbeddingModelVendor.GiteeAI.bce_embedding_base_v1)
);
float[] vector = model.embed("你好!");
System.out.println(Arrays.toString(vector));
}
}

这里最重要的不是打印出来的向量长什么样,而是你开始接受这件事:

  • 一段文本会被映射成一组数值
  • 后续检索和相似度计算都基于这组数值

实际项目里更常见的是一次处理一批文本:

List<String> texts = Arrays.asList("Hello World", "你好");
List<float[]> vectors = model.embed(texts);

这通常比一条一条请求更实用,也更接近真实索引构建场景。

和对话模型一样,这里通常也有两类来源:

  • 云端模型
  • 本地模型(例如 Ollama)

示例里可以直接用:

EmbeddingModelVendor.GiteeAI.bce_embedding_base_v1
EmbeddingModelVendor.Ollama.nomic_embed_text

如果你只是先验证能力有没有打通,选任何一个你当前最容易连上的来源即可。

这一页不要求你马上写出完整向量检索系统。
你只需要先接受两件事:

  1. 不同文本会变成不同向量
  2. 相近语义通常会对应更接近的向量空间位置

这也是为什么 Embedding 能用来做:

  • 语义搜索
  • 相似问题召回
  • 文档块检索

很多人第一次看 Embedding,就是因为想做 RAG。
可以把它们的关系理解成:

  • Embedding 负责把问题和文档都变成向量
  • 向量检索负责找出最相关的文档块
  • ChatModel 再基于这些文档块生成最终答案

所以 Embedding 不是 RAG 的全部,但它通常是入口之一。

我已经有 ChatModel,为什么还要 Embedding

Section titled “我已经有 ChatModel,为什么还要 Embedding”

因为这两者解决的问题不同。

  • ChatModel:生成文本
  • Embedding:表示文本

向量维度和数值范围为什么不一样

Section titled “向量维度和数值范围为什么不一样”

因为不同模型的向量空间不同。
所以不同 Embedding 模型生成的向量一般不要混用。

我是不是应该一开始就接向量库

Section titled “我是不是应该一开始就接向量库”

不一定。
如果你只是验证 Embedding 能力,先完成单条和批量向量化就够了。等你真正开始做检索链路时,再引入向量库。