向量化 (Embedding)
文本切分完成后,我们需要将文本转化为计算机能理解的数值向量。这个过程叫 Embedding。
什么是 Embedding?
Embedding 是一个将离散变量(如单词、句子)映射到连续向量空间的技术。
- 语义相似度:在向量空间中,语义相近的文本,距离越近(Cosine Similarity 越大)。
- 维度:通常是 768, 1024, 1536 (OpenAI text-embedding-3-small) 等固定维度。
Golang 调用 Embedding 模型
1. 使用 OpenAI API
这是最简单、效果最好的方案之一。
go
package main
import (
"context"
"fmt"
"os"
"github.com/tmc/langchaingo/embeddings"
"github.com/tmc/langchaingo/llms/openai"
)
func main() {
os.Setenv("OPENAI_API_KEY", "sk-...")
// 1. 初始化 LLM 客户端
llm, _ := openai.New()
// 2. 初始化 Embedder
embedder, _ := embeddings.NewEmbedder(llm)
// 3. 执行向量化
texts := []string{"Hello world", "Golang is great"}
vectors, err := embedder.EmbedDocuments(context.Background(), texts)
if err != nil {
panic(err)
}
fmt.Printf("生成了 %d 个向量\n", len(vectors))
fmt.Printf("第一个向量维度: %d\n", len(vectors[0])) // 通常是 1536
}2. 使用本地模型 (Ollama)
为了数据隐私和成本控制,很多企业选择私有化部署 Embedding 模型(如 bge-m3, nomic-embed-text)。Ollama 是目前运行本地模型最方便的工具。
前置:运行 ollama run nomic-embed-text
Golang 代码调用 Ollama:
go
package main
import (
"context"
"fmt"
"github.com/tmc/langchaingo/embeddings"
"github.com/tmc/langchaingo/llms/ollama"
)
func main() {
// 1. 指定使用 ollama 的 nomic-embed-text 模型
llm, _ := ollama.New(ollama.WithModel("nomic-embed-text"))
// 2. Embedder
embedder, _ := embeddings.NewEmbedder(llm)
// 3. Embed
vectors, _ := embedder.EmbedQuery(context.Background(), "本地向量化测试")
fmt.Println(vectors[:5]) // 打印前5维
}Embedding 模型的选择
- OpenAI text-embedding-3-small/large:
- 优点:多语言支持好,长度支持 8k,效果顶尖。
- 缺点:付费,数据出境。
- BGE (BAAI General Embedding):
- 优点:中文效果极佳,开源免费。
- 部署:可以通过 HuggingFace TEI 或 Ollama 部署。
- Jina Embeddings:
- 优点:支持 8k 长文本。
Golang 最佳实践
- Batch 处理:不要一条一条调 API。OpenAI 接口支持一次传多个 input。
EmbedDocuments方法内部通常会处理 Batch,提高吞吐量。 - 缓存:对于相同的文本,Embedding 结果是固定的。建议在数据库或 Redis 中做一层缓存,省钱又提速。
