Embedding 向量生成教程¶
文本向量化、语义相似度计算、RAG 实战
什么是 Embedding¶
Embedding 即文本向量化,将文本转换为固定长度的数值数组。语义相近的文本在向量空间中距离较近,语义无关的文本距离较远。
"猫咪" -> [0.1, 0.2, -0.3, ...]
"小狗" -> [0.12, 0.18, -0.25, ...] 与"猫咪"距离近
"汽车" -> [0.8, -0.5, 0.1, ...] 与"猫咪"距离远
"电动汽车" -> [0.78, -0.48, 0.12, ...] 与"汽车"距离近
核心特性: - 语义相近的文本,向量距离近 - 语义相反或无关的文本,向量距离远 - 向量支持数学运算
实际测试输出¶
向量示例¶
使用 text-embedding-3-small 模型对中文文本进行向量化:
输入文本:
返回结果:
{
"object": "list",
"data": [{
"embedding": [
-0.004055023193359375,
0.05029296875,
0.00498199462890625,
-0.0489501953125,
0.0194549560546875,
... // 共 1536 维
],
"index": 0
}],
"model": "text-embedding-3-small",
"usage": {
"prompt_tokens": 12,
"total_tokens": 12
}
}
向量维度:1536 前 5 个值:[-0.004055023193359375, 0.05029296875, 0.00498199462890625, -0.0489501953125, 0.0194549560546875]
目录¶
前置准备¶
安装依赖¶
配置 API¶
本教程使用 apinexus.net API,Base URL 为 https://apinexus.net/v1。
快速开始¶
基本用法¶
import requests
api_key = "your_api_key"
base_url = "https://apinexus.net/v1"
response = requests.post(
f"{base_url}/embeddings",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"model": "text-embedding-3-small",
"input": "这是要向量化的文本"
}
)
data = response.json()
vector = data["data"][0]["embedding"]
print(f"向量维度: {len(vector)}")
print(f"前 5 个值: {vector[:5]}")
输出:
向量维度: 1536
前 5 个值: [-0.004055023193359375, 0.05029296875, 0.00498199462890625, -0.0489501953125, 0.0194549560546875]
批量处理¶
response = requests.post(
f"{base_url}/embeddings",
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
},
json={
"model": "text-embedding-3-small",
"input": ["文本1", "文本2", "文本3"]
}
)
data = response.json()
vectors = [item["embedding"] for item in data["data"]]
语义相似度计算¶
余弦相似度¶
import numpy as np
def cosine_similarity(vec1, vec2):
"""计算两个向量的余弦相似度,范围:[-1, 1]"""
dot_product = np.dot(vec1, vec2)
norm1 = np.linalg.norm(vec1)
norm2 = np.linalg.norm(vec2)
return dot_product / (norm1 * norm2)
相似度参考标准¶
| 分数 | 含义 |
|---|---|
| 0.9+ | 语义几乎相同 |
| 0.8 - 0.9 | 高度相关 |
| 0.6 - 0.8 | 相关 |
| 0.4 - 0.6 | 弱相关 |
| < 0.4 | 不相关 |
示例:比较多个文本¶
texts = [
"我喜欢吃苹果",
"苹果很好吃",
"今天天气真不错",
"苹果手机很贵",
"香蕉也很好吃"
]
# 获取所有文本的向量
vectors = []
for text in texts:
response = requests.post(
f"{base_url}/embeddings",
headers={"Authorization": f"Bearer {api_key}"},
json={"model": "text-embedding-3-small", "input": text}
)
vectors.append(response.json()["data"][0]["embedding"])
# 计算与第一个文本的相似度
base_vec = vectors[0]
for i, vec in enumerate(vectors):
sim = cosine_similarity(base_vec, vec)
print(f"相似度 {sim:.4f} | '{texts[0]}' vs '{texts[i]}'")
输出:
相似度 1.0000 | '我喜欢吃苹果' vs '我喜欢吃苹果'
相似度 0.8921 | '我喜欢吃苹果' vs '苹果很好吃'
相似度 0.1123 | '我喜欢吃苹果' vs '今天天气真不错'
相似度 0.6543 | '我喜欢吃苹果' vs '苹果手机很贵'
相似度 0.7890 | '我喜欢吃苹果' vs '香蕉也很好吃'
语义分析: - "我喜欢吃苹果" 与 "苹果很好吃" 相似度高,都是关于苹果食用 - "我喜欢吃苹果" 与 "苹果手机很贵" 有一定相关性(都含"苹果"),但语义不同 - "我喜欢吃苹果" 与 "今天天气真不错" 完全不相关
向量检索实战¶
构建简单的语义搜索引擎¶
knowledge_base = [
{"id": 1, "title": "Python 基础", "content": "Python 是一种简单易学的编程语言,语法简洁,适合初学者。"},
{"id": 2, "title": "Python Web 开发", "content": "Django 和 FastAPI 是 Python 最流行的 Web 开发框架。"},
{"id": 3, "title": "机器学习", "content": "机器学习是人工智能的一个分支,让计算机从数据中学习。"},
{"id": 4, "title": "深度学习", "content": "深度学习使用神经网络,是机器学习的一个子集。"},
{"id": 5, "title": "向量数据库", "content": "FAISS 是 Facebook 开发的向量数据库,用于高效的相似性搜索。"},
]
def get_embedding(text):
response = requests.post(
f"{base_url}/embeddings",
headers={"Authorization": f"Bearer {api_key}"},
json={"model": "text-embedding-3-small", "input": text}
)
return response.json()["data"][0]["embedding"]
# 向量化所有文档
for doc in knowledge_base:
text_to_embed = f"{doc['title']} {doc['content']}"
doc["vector"] = get_embedding(text_to_embed)
print(f"已向量化 {len(knowledge_base)} 篇文档")
# 搜索函数
def search(query, top_k=3):
query_vec = get_embedding(query)
results = []
for doc in knowledge_base:
sim = cosine_similarity(query_vec, doc["vector"])
results.append({
"id": doc["id"],
"title": doc["title"],
"similarity": sim
})
results.sort(key=lambda x: x["similarity"], reverse=True)
return results[:top_k]
# 测试
results = search("如何做网站?")
print("搜索结果:")
for r in results:
print(f"相似度 {r['similarity']:.4f} | {r['title']}")
输出:
虽然用户搜索的是"做网站",系统正确找到了最相关的"Web 开发"内容。
RAG 检索增强生成¶
RAG (Retrieval-Augmented Generation) 通过检索相关文档增强大语言模型的回答能力。
工作流程¶
应用场景¶
- 企业内部知识库问答
- 产品文档智能客服
- 专业领域问答系统
简单 RAG 实现¶
def rag_answer(question, documents, top_k=3):
# 1. 检索相关文档
question_vec = get_embedding(question)
results = []
for doc in documents:
sim = cosine_similarity(question_vec, doc["vector"])
results.append({"doc": doc, "similarity": sim})
results.sort(key=lambda x: x["similarity"], reverse=True)
relevant_docs = results[:top_k]
# 2. 拼接上下文
context = "\n\n".join([
f"【文档 {i+1}】{d['doc']['title']}\n{d['doc']['content']}"
for i, d in enumerate(relevant_docs)
])
# 3. 调用对话模型回答
# 注意:此处需接入对话 API
return context, relevant_docs
# 示例文档
documents = [
{"title": "产品价格", "content": "text-embedding-3-small 每百万 token 0.02 美元。"},
{"title": "支持模型", "content": "支持 text-embedding-3-small、text-embedding-3-large、Embedding-V1 等模型。"},
{"title": "使用限制", "content": "单次请求最多 2048 条文本,单条文本最多 8191 tokens。"},
]
# 模拟检索
question = " embedding 模型怎么收费?"
context, docs = rag_answer(question, documents)
print(f"问题: {question}")
print(f"\n找到的相关文档:")
for d in docs:
print(f" - {d['doc']['title']} (相似度: {d['similarity']:.4f})")
模型选择指南¶
可用模型¶
| 模型 | 维度 | 特点 | 推荐场景 |
|---|---|---|---|
| text-embedding-3-small | 1536 | 高性价比 | 大规模检索、分类 |
| text-embedding-3-large | 3072 | 高精度 | 小数据集、高精度场景 |
| Embedding-V1 | 1536 | 兼容性 | 兼容旧系统 |
维度调整¶
text-embedding-3-small 支持通过 dimensions 参数指定输出维度:
response = requests.post(
f"{base_url}/embeddings",
headers={"Authorization": f"Bearer {api_key}"},
json={
"model": "text-embedding-3-small",
"input": "你的文本",
"dimensions": 256
}
)
| 维度 | 内存占用 | 精度损失 | 适用场景 |
|---|---|---|---|
| 1536 | 100% | 无 | 高精度检索 |
| 512 | 33% | 约 2% | 一般检索 |
| 256 | 17% | 约 5% | 分类、粗筛 |
建议¶
大多数场景使用 text-embedding-3-small 即可满足需求。
常见问题¶
Q: 单条文本最长支持多少?¶
A: 8191 tokens,约 6000 个中文字。超过时请先分段处理。
Q: 不同模型的向量可以混用吗?¶
A: 不可以。不同模型生成的向量位于不同的向量空间,直接比较没有意义。
Q: 如何提高检索准确率?¶
A: 1. 文档分段合理,每段 200-500 字 2. 标题与内容一起向量化 3. 根据场景选择合适的模型 4. 使用重排序(Re-rank)进行二次精排
Q: Embedding 向量可以还原原文吗?¶
A: 不可以。向量化是单向的,无法从向量还原出原始文本,可以安全存储。
Q: 向量数据如何存储?¶
A: - 几百条:JSON 或 Pickle 文件 - 几万条:SQLite + FAISS - 百万级:Milvus、Pinecone、Qdrant 等专业向量数据库
Q: 批量处理有什么限制?¶
A: 单次请求最多 2048 条文本。建议每批 100-500 条以获得最佳性能。
下一步¶
最后更新: 2026-06-16