向量嵌入(Embeddings)
向量嵌入(Embeddings)是将文本转换为高维向量的技术,常用于语义搜索、RAG(检索增强生成)、文本分类和相似度计算。RouteAPI 提供标准的 OpenAI 兼容 Embeddings 接口,支持多个嵌入模型。
Endpoint
Section titled “Endpoint”POST /v1/embeddings完整地址:
https://api.routeapi.ai/v1/embeddings| 场景 | 说明 |
|---|---|
| 语义搜索 | 将文档和查询转为向量,通过相似度检索相关内容 |
| RAG | 检索相关文档片段作为上下文,增强大模型生成质量 |
| 文本分类 | 将文本向量化后用于聚类或分类任务 |
| 推荐系统 | 计算文本相似度用于内容推荐 |
| 去重检测 | 通过向量相似度识别重复或近似内容 |
curl https://api.routeapi.ai/v1/embeddings \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": "RouteAPI 是一个统一的 AI API 网关" }'curl https://api.routeapi.ai/v1/embeddings \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": [ "第一段文本", "第二段文本", "第三段文本" ] }'| 字段 | 类型 | 必填 | 说明 |
| --- | --- | --- |
| model | string | 是 | 嵌入模型 ID |
| input | string/array | 是 | 单个文本字符串或文本数组 |
| encoding_format | string | 否 | 向量编码格式,float 或 base64,默认 float |
| dimensions | number | 否 | 返回向量维度(部分模型支持),用于降维 |
| user | string | 否 | 终端用户标识,用于追踪和滥用监控 |
{ "object": "list", "data": [ { "object": "embedding", "index": 0, "embedding": [ 0.0023064255, -0.009327292, 0.015797347, ... ] } ], "model": "text-embedding-3-small", "usage": { "prompt_tokens": 8, "total_tokens": 8 }}响应字段说明
Section titled “响应字段说明”| 字段 | 说明 |
|---|---|
object | 固定为 list |
data | 嵌入结果数组 |
data[].embedding | 浮点数向量数组 |
data[].index | 输入文本的索引位置 |
model | 实际使用的模型 ID |
usage.prompt_tokens | 输入消耗的 token 数 |
usage.total_tokens | 总 token 数 |
支持的嵌入模型
Section titled “支持的嵌入模型”OpenAI 模型
Section titled “OpenAI 模型”| 模型 ID | 默认维度 | 性能 | 适用场景 |
|---|---|---|---|
text-embedding-3-small | 1536 | 高性价比 | 通用语义搜索、RAG |
text-embedding-3-large | 3072 | 高精度 | 复杂语义任务 |
text-embedding-ada-002 | 1536 | 稳定经典 | 向后兼容 |
Google 模型
Section titled “Google 模型”| 模型 ID | 默认维度 | 说明 |
|---|---|---|
text-embedding-004 | 768 | Google 最新嵌入模型 |
gemini-embedding-001 | 768 | Gemini 系列嵌入模型 |
| 模型 ID | 默认维度 | 供应商 |
|---|---|---|
text-embedding-v1 | 1024 | 百度文心 |
embedding-bert-512-v1 | 512 | 智谱 AI |
bge-large-zh | 1024 | 智源 BGE(中文) |
bge-large-en | 1024 | 智源 BGE(英文) |
模型可用性以控制台模型列表为准,不同账户可用模型可能不同。
批量大小限制
Section titled “批量大小限制”- 单次请求最多处理的文本数量取决于具体模型和服务配置。
- 建议单次请求不超过 100 条文本。
- 单个文本的 token 数通常不应超过模型的最大输入限制(通常为 8192 tokens)。
批量优化建议
Section titled “批量优化建议”- 合并请求:将多个短文本合并到一次请求中,减少网络往返。
- 并发控制:大批量任务可分批并发,建议并发数不超过 5。
- 错误处理:批量中某个文本失败时,整个请求可能失败,需要做好重试和错误处理。
Python(OpenAI SDK)
Section titled “Python(OpenAI SDK)”from openai import OpenAI
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# 单个文本response = client.embeddings.create( model="text-embedding-3-small", input="RouteAPI 是一个统一的 AI API 网关")embedding = response.data[0].embeddingprint(f"向量维度: {len(embedding)}")print(f"前 5 个值: {embedding[:5]}")
# 批量文本texts = [ "人工智能正在改变世界", "机器学习是 AI 的核心技术", "深度学习推动了 AI 的发展"]response = client.embeddings.create( model="text-embedding-3-small", input=texts)for i, data in enumerate(response.data): print(f"文本 {i}: 维度 {len(data.embedding)}")Node.js(OpenAI SDK)
Section titled “Node.js(OpenAI SDK)”import OpenAI from 'openai';
const client = new OpenAI({ apiKey: 'sk-your-routeapi-token', baseURL: 'https://api.routeapi.ai/v1'});
async function getEmbedding() { // 单个文本 const response = await client.embeddings.create({ model: 'text-embedding-3-small', input: 'RouteAPI 是一个统一的 AI API 网关' });
const embedding = response.data[0].embedding; console.log(`向量维度: ${embedding.length}`); console.log(`前 5 个值: ${embedding.slice(0, 5)}`);
// 批量文本 const texts = [ '人工智能正在改变世界', '机器学习是 AI 的核心技术', '深度学习推动了 AI 的发展' ];
const batchResponse = await client.embeddings.create({ model: 'text-embedding-3-small', input: texts });
batchResponse.data.forEach((item, i) => { console.log(`文本 ${i}: 维度 ${item.embedding.length}`); });}
getEmbedding();curl https://api.routeapi.ai/v1/embeddings \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": ["文本1", "文本2", "文本3"] }'语义相似度计算
Section titled “语义相似度计算”Python(使用 NumPy)
Section titled “Python(使用 NumPy)”import numpy as npfrom openai import OpenAI
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
def cosine_similarity(vec1, vec2): """计算余弦相似度""" return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
# 获取两段文本的嵌入向量texts = [ "RouteAPI 是一个 AI API 网关", "RouteAPI 提供统一的模型接入服务", "今天天气很好"]
response = client.embeddings.create( model="text-embedding-3-small", input=texts)
embeddings = [data.embedding for data in response.data]
# 计算相似度sim_0_1 = cosine_similarity(embeddings[0], embeddings[1])sim_0_2 = cosine_similarity(embeddings[0], embeddings[2])
print(f"文本0 和 文本1 的相似度: {sim_0_1:.4f}") # 高相似度print(f"文本0 和 文本2 的相似度: {sim_0_2:.4f}") # 低相似度Node.js(使用数学库)
Section titled “Node.js(使用数学库)”import OpenAI from 'openai';
const client = new OpenAI({ apiKey: 'sk-your-routeapi-token', baseURL: 'https://api.routeapi.ai/v1'});
function cosineSimilarity(vec1, vec2) { const dotProduct = vec1.reduce((sum, val, i) => sum + val * vec2[i], 0); const mag1 = Math.sqrt(vec1.reduce((sum, val) => sum + val * val, 0)); const mag2 = Math.sqrt(vec2.reduce((sum, val) => sum + val * val, 0)); return dotProduct / (mag1 * mag2);}
async function computeSimilarity() { const texts = [ 'RouteAPI 是一个 AI API 网关', 'RouteAPI 提供统一的模型接入服务', '今天天气很好' ];
const response = await client.embeddings.create({ model: 'text-embedding-3-small', input: texts });
const embeddings = response.data.map(d => d.embedding);
const sim_0_1 = cosineSimilarity(embeddings[0], embeddings[1]); const sim_0_2 = cosineSimilarity(embeddings[0], embeddings[2]);
console.log(`文本0 和 文本1 的相似度: ${sim_0_1.toFixed(4)}`); console.log(`文本0 和 文本2 的相似度: ${sim_0_2.toFixed(4)}`);}
computeSimilarity();向量数据库集成
Section titled “向量数据库集成”Pinecone 示例
Section titled “Pinecone 示例”from openai import OpenAIimport pinecone
# 初始化 RouteAPI 客户端client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# 初始化 Pineconepinecone.init(api_key="your-pinecone-key", environment="your-env")index = pinecone.Index("your-index-name")
# 生成嵌入并存储documents = [ {"id": "doc1", "text": "RouteAPI 是一个 AI API 网关"}, {"id": "doc2", "text": "支持多家 AI 模型供应商"}, {"id": "doc3", "text": "提供统一的接口和计费"}]
for doc in documents: # 生成嵌入 response = client.embeddings.create( model="text-embedding-3-small", input=doc["text"] ) embedding = response.data[0].embedding
# 存储到 Pinecone index.upsert([(doc["id"], embedding, {"text": doc["text"]})])
# 查询query = "什么是 RouteAPI"query_response = client.embeddings.create( model="text-embedding-3-small", input=query)query_embedding = query_response.data[0].embedding
# 搜索相似文档results = index.query(query_embedding, top_k=3, include_metadata=True)for match in results["matches"]: print(f"相似度: {match['score']:.4f}, 文本: {match['metadata']['text']}")Weaviate 示例
Section titled “Weaviate 示例”import weaviatefrom openai import OpenAI
# 初始化 RouteAPI 客户端client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# 连接 Weaviateweaviate_client = weaviate.Client("http://localhost:8080")
# 创建 schema(如果不存在)schema = { "class": "Document", "vectorizer": "none", # 我们自己提供向量 "properties": [ {"name": "text", "dataType": ["text"]} ]}
# 插入文档documents = [ "RouteAPI 是一个 AI API 网关", "支持多家 AI 模型供应商", "提供统一的接口和计费"]
for doc_text in documents: # 生成嵌入 response = client.embeddings.create( model="text-embedding-3-small", input=doc_text ) embedding = response.data[0].embedding
# 存储到 Weaviate weaviate_client.data_object.create( data_object={"text": doc_text}, class_name="Document", vector=embedding )
# 查询query = "什么是 RouteAPI"query_response = client.embeddings.create( model="text-embedding-3-small", input=query)query_embedding = query_response.data[0].embedding
# 向量搜索results = weaviate_client.query.get("Document", ["text"]) \ .with_near_vector({"vector": query_embedding}) \ .with_limit(3) \ .with_additional(["distance"]) \ .do()
for item in results["data"]["Get"]["Document"]: print(f"距离: {item['_additional']['distance']:.4f}, 文本: {item['text']}")RAG 应用示例
Section titled “RAG 应用示例”from openai import OpenAI
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# 知识库文档knowledge_base = [ "RouteAPI 是一个统一的 AI API 网关,聚合了 OpenAI、Claude、Gemini 等多家供应商。", "RouteAPI 提供统一的认证、计费和监控能力。", "RouteAPI 支持流式输出、工具调用和多模态输入。", "用户可以通过控制台管理 API Token、查看用量日志和充值余额。"]
# 为知识库生成嵌入kb_embeddings_response = client.embeddings.create( model="text-embedding-3-small", input=knowledge_base)kb_embeddings = [data.embedding for data in kb_embeddings_response.data]
# 用户问题user_query = "RouteAPI 有哪些功能?"
# 为问题生成嵌入query_response = client.embeddings.create( model="text-embedding-3-small", input=user_query)query_embedding = query_response.data[0].embedding
# 计算相似度并检索最相关的文档import numpy as np
def cosine_similarity(vec1, vec2): return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
similarities = [cosine_similarity(query_embedding, kb_emb) for kb_emb in kb_embeddings]top_k = 2top_indices = np.argsort(similarities)[-top_k:][::-1]
# 构建上下文context = "\n".join([knowledge_base[i] for i in top_indices])
# 调用 Chat Completions 生成回答chat_response = client.chat.completions.create( model="gpt-5.5", messages=[ {"role": "system", "content": "你是一个 RouteAPI 助手。请根据提供的上下文回答用户问题。"}, {"role": "user", "content": f"上下文:\n{context}\n\n问题:{user_query}"} ])
print(chat_response.choices[0].message.content)1. 选择合适的嵌入模型
Section titled “1. 选择合适的嵌入模型”| 考虑因素 | 建议 |
|---|---|
| 通用场景 | 使用 text-embedding-3-small,性价比高 |
| 高精度需求 | 使用 text-embedding-3-large,维度更高 |
| 中文语义 | 考虑 bge-large-zh 等中文优化模型 |
| 成本优先 | 选择维度较低的模型或使用 dimensions 参数降维 |
2. 文本预处理
Section titled “2. 文本预处理”def preprocess_text(text): """文本预处理""" # 去除多余空白 text = " ".join(text.split()) # 限制长度(避免超过模型限制) max_tokens = 8000 # 预留一些空间 if len(text.split()) > max_tokens: text = " ".join(text.split()[:max_tokens]) return text
# 使用clean_text = preprocess_text(raw_text)response = client.embeddings.create( model="text-embedding-3-small", input=clean_text)3. 维度选择
Section titled “3. 维度选择”部分模型(如 text-embedding-3-small 和 text-embedding-3-large)支持通过 dimensions 参数自定义输出维度:
# 降低维度以节省存储和计算成本response = client.embeddings.create( model="text-embedding-3-small", input="RouteAPI 是一个 AI API 网关", dimensions=512 # 从默认 1536 降至 512)降维会略微损失精度,但可以显著降低存储成本和查询延迟。建议在开发阶段测试不同维度对业务指标的影响。
4. 成本优化
Section titled “4. 成本优化”- 批量处理:将多个文本合并到一次请求中。
- 缓存嵌入:对静态文档,生成一次嵌入后缓存起来重复使用。
- 选择合适模型:不要盲目使用最大的模型,
text-embedding-3-small对多数场景已足够。 - 降维:使用
dimensions参数降低向量维度。
5. 错误处理
Section titled “5. 错误处理”from openai import OpenAI, OpenAIError
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
def get_embedding_with_retry(text, max_retries=3): """带重试的嵌入生成""" for attempt in range(max_retries): try: response = client.embeddings.create( model="text-embedding-3-small", input=text ) return response.data[0].embedding except OpenAIError as e: if attempt == max_retries - 1: raise print(f"请求失败,重试 {attempt + 1}/{max_retries}: {e}") time.sleep(2 ** attempt) # 指数退避 return None6. 性能优化
Section titled “6. 性能优化”import asynciofrom openai import AsyncOpenAI
async_client = AsyncOpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
async def get_embeddings_batch(texts, batch_size=50): """异步批量获取嵌入""" results = [] for i in range(0, len(texts), batch_size): batch = texts[i:i + batch_size] response = await async_client.embeddings.create( model="text-embedding-3-small", input=batch ) results.extend([data.embedding for data in response.data]) return results
# 使用texts = ["文本1", "文本2", ..., "文本1000"]embeddings = asyncio.run(get_embeddings_batch(texts))Q: 嵌入向量可以跨模型使用吗?
不可以。不同模型生成的向量维度和语义空间不同,必须使用同一个模型生成查询向量和文档向量。
Q: 如何选择相似度阈值?
余弦相似度范围是 -1 到 1。一般:
- > 0.8:高度相关
- 0.6-0.8:相关
- < 0.6:弱相关或不相关
具体阈值需要根据业务场景测试调优。
Q: 嵌入生成失败常见原因?
| 错误 | 原因 | 解决方案 |
|---|---|---|
invalid_api_key | Token 无效 | 检查 Authorization header |
model_not_found | 模型 ID 错误或不可用 | 检查模型 ID 和账户权限 |
context_length_exceeded | 输入文本过长 | 缩短文本或分段处理 |
rate_limit_exceeded | 请求过于频繁 | 降低并发或增加间隔 |
Q: 如何处理多语言文本?
多数嵌入模型(如 text-embedding-3-small)支持多语言,但跨语言语义匹配效果取决于模型训练。对中文场景,可优先考虑 bge-large-zh 等中文优化模型。
Q: 嵌入向量可以存储多久?
嵌入向量是确定性的(相同输入生成相同向量),可以长期存储和复用,直到更换模型或模型版本更新。