Embeddings (Nhúng văn bản)
Embeddings (nhúng văn bản) là công nghệ chuyển đổi văn bản thành vector đa chiều, thường được sử dụng cho tìm kiếm ngữ nghĩa, RAG (tạo nội dung tăng cường truy xuất), phân loại văn bản và tính toán độ tương đồng. RouteAPI cung cấp giao diện Embeddings tương thích với OpenAI tiêu chuẩn, hỗ trợ nhiều mô hình nhúng.
Endpoint
Phần tiêu đề “Endpoint”POST /v1/embeddingsURL đầy đủ:
https://api.routeapi.ai/v1/embeddingsTrường hợp sử dụng
Phần tiêu đề “Trường hợp sử dụng”| Kịch bản | Mô tả |
|---|---|
| Tìm kiếm ngữ nghĩa | Chuyển đổi tài liệu và truy vấn thành vector, truy xuất nội dung liên quan qua độ tương đồng |
| RAG | Truy xuất các đoạn tài liệu liên quan làm ngữ cảnh để cải thiện chất lượng tạo nội dung của LLM |
| Phân loại văn bản | Vector hóa văn bản cho các tác vụ phân cụm hoặc phân loại |
| Hệ thống đề xuất | Tính toán độ tương đồng văn bản cho đề xuất nội dung |
| Phát hiện trùng lặp | Nhận diện nội dung trùng lặp hoặc tương tự qua độ tương đồng vector |
Ví dụ yêu cầu
Phần tiêu đề “Ví dụ yêu cầu”Văn bản đơn
Phần tiêu đề “Văn bản đơn”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 网关" }'Văn bản hàng loạt
Phần tiêu đề “Văn bản hàng loạt”curl https://api.routeapi.ai/v1/embeddings \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": [ "第一段文本", "第二段文本", "第三段文本" ] }'Tham số yêu cầu
Phần tiêu đề “Tham số yêu cầu”| Trường | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|
model | string | Có | ID mô hình nhúng |
input | string/array | Có | Chuỗi văn bản đơn hoặc mảng văn bản |
encoding_format | string | Không | Định dạng mã hóa vector, float hoặc base64, mặc định float |
dimensions | number | Không | Số chiều vector trả về (được hỗ trợ bởi một số mô hình), dùng để giảm chiều |
user | string | Không | Định danh người dùng cuối, dùng để theo dõi và giám sát lạm dụng |
Ví dụ phản hồi
Phần tiêu đề “Ví dụ phản hồi”{ "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 }}Các trường phản hồi
Phần tiêu đề “Các trường phản hồi”| Trường | Mô tả |
|---|---|
object | Cố định là list |
data | Mảng kết quả nhúng |
data[].embedding | Mảng vector số thực |
data[].index | Vị trí chỉ mục của văn bản đầu vào |
model | ID mô hình thực sự được sử dụng |
usage.prompt_tokens | Số token được tiêu thụ bởi đầu vào |
usage.total_tokens | Tổng số token |
Các mô hình nhúng được hỗ trợ
Phần tiêu đề “Các mô hình nhúng được hỗ trợ”Mô hình OpenAI
Phần tiêu đề “Mô hình OpenAI”| ID mô hình | Số chiều mặc định | Hiệu suất | Trường hợp sử dụng |
|---|---|---|---|
text-embedding-3-small | 1536 | Hiệu quả chi phí | Tìm kiếm ngữ nghĩa chung, RAG |
text-embedding-3-large | 3072 | Độ chính xác cao | Tác vụ ngữ nghĩa phức tạp |
text-embedding-ada-002 | 1536 | Ổn định cổ điển | Tương thích ngược |
Mô hình Google
Phần tiêu đề “Mô hình Google”| ID mô hình | Số chiều mặc định | Mô tả |
|---|---|---|
text-embedding-004 | 768 | Mô hình nhúng mới nhất của Google |
gemini-embedding-001 | 768 | Mô hình nhúng dòng Gemini |
Nhà cung cấp khác
Phần tiêu đề “Nhà cung cấp khác”| ID mô hình | Số chiều mặc định | Nhà cung cấp |
|---|---|---|
text-embedding-v1 | 1024 | Baidu Wenxin |
embedding-bert-512-v1 | 512 | Zhipu AI |
bge-large-zh | 1024 | BAAI BGE (Tiếng Trung) |
bge-large-en | 1024 | BAAI BGE (Tiếng Anh) |
Tính khả dụng của mô hình phụ thuộc vào danh sách mô hình trong console, các tài khoản khác nhau có thể có các mô hình khả dụng khác nhau.
Xử lý hàng loạt
Phần tiêu đề “Xử lý hàng loạt”Giới hạn kích thước lô
Phần tiêu đề “Giới hạn kích thước lô”- Số lượng văn bản tối đa được xử lý trong một yêu cầu phụ thuộc vào mô hình cụ thể và cấu hình dịch vụ.
- Khuyến nghị không vượt quá 100 văn bản mỗi yêu cầu.
- Số token của một văn bản đơn thường không nên vượt quá giới hạn đầu vào tối đa của mô hình (thường là 8192 token).
Mẹo tối ưu hóa hàng loạt
Phần tiêu đề “Mẹo tối ưu hóa hàng loạt”- Gộp yêu cầu: Kết hợp nhiều văn bản ngắn vào một yêu cầu để giảm số lần gửi/nhận mạng.
- Kiểm soát đồng thời: Tác vụ lô lớn có thể được chia nhỏ và xử lý đồng thời, khuyến nghị đồng thời không quá 5.
- Xử lý lỗi: Khi một văn bản trong lô thất bại, toàn bộ yêu cầu có thể thất bại, cần có cơ chế thử lại và xử lý lỗi phù hợp.
Ví dụ mã
Phần tiêu đề “Ví dụ mã”Python (SDK OpenAI)
Phần tiêu đề “Python (SDK OpenAI)”from openai import OpenAI
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# Văn bản đơnresponse = 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]}")
# Văn bản hàng loạttexts = [ "人工智能正在改变世界", "机器学习是 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 (SDK OpenAI)
Phần tiêu đề “Node.js (SDK OpenAI)”import OpenAI from 'openai';
const client = new OpenAI({ apiKey: 'sk-your-routeapi-token', baseURL: 'https://api.routeapi.ai/v1'});
async function getEmbedding() { // Văn bản đơn 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)}`);
// Văn bản hàng loạt 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"] }'Tính toán độ tương đồng ngữ nghĩa
Phần tiêu đề “Tính toán độ tương đồng ngữ nghĩa”Python (sử dụng NumPy)
Phần tiêu đề “Python (sử dụng 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): """Tính độ tương đồng cosine""" return np.dot(vec1, vec2) / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
# Lấy vector nhúng của hai văn bảntexts = [ "RouteAPI 是一个 AI API 网关", "RouteAPI 提供统一的模型接入服务", "今天天气很好"]
response = client.embeddings.create( model="text-embedding-3-small", input=texts)
embeddings = [data.embedding for data in response.data]
# Tính độ tương đồngsim_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}") # Độ tương đồng caoprint(f"文本0 和 文本2 的相似度: {sim_0_2:.4f}") # Độ tương đồng thấpNode.js (sử dụng thư viện toán học)
Phần tiêu đề “Node.js (sử dụng thư viện toán học)”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();Tích hợp cơ sở dữ liệu vector
Phần tiêu đề “Tích hợp cơ sở dữ liệu vector”Ví dụ Pinecone
Phần tiêu đề “Ví dụ Pinecone”from openai import OpenAIimport pinecone
# Khởi tạo client RouteAPIclient = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# Khởi tạo Pineconepinecone.init(api_key="your-pinecone-key", environment="your-env")index = pinecone.Index("your-index-name")
# Tạo embedding và lưu trữdocuments = [ {"id": "doc1", "text": "RouteAPI 是一个 AI API 网关"}, {"id": "doc2", "text": "支持多家 AI 模型供应商"}, {"id": "doc3", "text": "提供统一的接口和计费"}]
for doc in documents: # Tạo embedding response = client.embeddings.create( model="text-embedding-3-small", input=doc["text"] ) embedding = response.data[0].embedding
# Lưu vào Pinecone index.upsert([(doc["id"], embedding, {"text": doc["text"]})])
# Truy vấnquery = "什么是 RouteAPI"query_response = client.embeddings.create( model="text-embedding-3-small", input=query)query_embedding = query_response.data[0].embedding
# Tìm kiếm tài liệu tương tựresults = index.query(query_embedding, top_k=3, include_metadata=True)for match in results["matches"]: print(f"相似度: {match['score']:.4f}, 文本: {match['metadata']['text']}")Ví dụ Weaviate
Phần tiêu đề “Ví dụ Weaviate”import weaviatefrom openai import OpenAI
# Khởi tạo client RouteAPIclient = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# Kết nối Weaviateweaviate_client = weaviate.Client("http://localhost:8080")
# Tạo schema (nếu chưa tồn tại)schema = { "class": "Document", "vectorizer": "none", # Chúng ta tự cung cấp vector "properties": [ {"name": "text", "dataType": ["text"]} ]}
# Chèn tài liệudocuments = [ "RouteAPI 是一个 AI API 网关", "支持多家 AI 模型供应商", "提供统一的接口和计费"]
for doc_text in documents: # Tạo embedding response = client.embeddings.create( model="text-embedding-3-small", input=doc_text ) embedding = response.data[0].embedding
# Lưu vào Weaviate weaviate_client.data_object.create( data_object={"text": doc_text}, class_name="Document", vector=embedding )
# Truy vấnquery = "什么是 RouteAPI"query_response = client.embeddings.create( model="text-embedding-3-small", input=query)query_embedding = query_response.data[0].embedding
# Tìm kiếm vectorresults = 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']}")Ví dụ ứng dụng RAG
Phần tiêu đề “Ví dụ ứng dụng RAG”from openai import OpenAI
client = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# Tài liệu cơ sở kiến thứcknowledge_base = [ "RouteAPI 是一个统一的 AI API 网关,聚合了 OpenAI、Claude、Gemini 等多家供应商。", "RouteAPI 提供统一的认证、计费和监控能力。", "RouteAPI 支持流式输出、工具调用和多模态输入。", "用户可以通过控制台管理 API Token、查看用量日志和充值余额。"]
# Tạo embedding cho cơ sở kiến thứckb_embeddings_response = client.embeddings.create( model="text-embedding-3-small", input=knowledge_base)kb_embeddings = [data.embedding for data in kb_embeddings_response.data]
# Câu hỏi của người dùnguser_query = "RouteAPI 有哪些功能?"
# Tạo embedding cho câu hỏiquery_response = client.embeddings.create( model="text-embedding-3-small", input=user_query)query_embedding = query_response.data[0].embedding
# Tính độ tương đồng và truy xuất tài liệu liên quan nhấtimport 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]
# Xây dựng ngữ cảnhcontext = "\n".join([knowledge_base[i] for i in top_indices])
# Gọi Chat Completions để tạo câu trả lờichat_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)Thực hành tốt nhất
Phần tiêu đề “Thực hành tốt nhất”1. Chọn mô hình nhúng phù hợp
Phần tiêu đề “1. Chọn mô hình nhúng phù hợp”| Cân nhắc | Khuyến nghị |
|---|---|
| Kịch bản chung | Sử dụng text-embedding-3-small, hiệu quả chi phí |
| Nhu cầu độ chính xác cao | Sử dụng text-embedding-3-large, số chiều cao hơn |
| Ngữ nghĩa tiếng Trung | Cân nhắc bge-large-zh và các mô hình tối ưu hóa tiếng Trung khác |
| Ưu tiên chi phí | Chọn mô hình số chiều thấp hơn hoặc sử dụng tham số dimensions để giảm |
2. Tiền xử lý văn bản
Phần tiêu đề “2. Tiền xử lý văn bản”def preprocess_text(text): """Tiền xử lý văn bản""" # Loại bỏ khoảng trắng thừa text = " ".join(text.split()) # Giới hạn độ dài (tránh vượt quá giới hạn mô hình) max_tokens = 8000 # Dự trữ một chút không gian if len(text.split()) > max_tokens: text = " ".join(text.split()[:max_tokens]) return text
# Sử dụngclean_text = preprocess_text(raw_text)response = client.embeddings.create( model="text-embedding-3-small", input=clean_text)3. Lựa chọn số chiều
Phần tiêu đề “3. Lựa chọn số chiều”Một số mô hình (như text-embedding-3-small và text-embedding-3-large) hỗ trợ tùy chỉnh số chiều đầu ra qua tham số dimensions.
# Giảm số chiều để tiết kiệm chi phí lưu trữ và tính toánresponse = client.embeddings.create( model="text-embedding-3-small", input="RouteAPI 是一个 AI API 网关", dimensions=512 # Giảm từ 1536 mặc định xuống 512)Giảm số chiều sẽ làm giảm nhẹ độ chính xác nhưng có thể giảm đáng kể chi phí lưu trữ và độ trễ truy vấn. Khuyến nghị thử nghiệm tác động của các số chiều khác nhau đến các chỉ số kinh doanh trong giai đoạn phát triển.
4. Tối ưu hóa chi phí
Phần tiêu đề “4. Tối ưu hóa chi phí”- Xử lý hàng loạt: Kết hợp nhiều văn bản vào một yêu cầu.
- Bộ nhớ cache embedding: Đối với tài liệu tĩnh, tạo embedding một lần và cache để tái sử dụng.
- Chọn mô hình phù hợp: Đừng sử dụng mô hình lớn nhất một cách mù quáng,
text-embedding-3-smallđủ cho hầu hết các kịch bản. - Giảm số chiều: Sử dụng tham số
dimensionsđể giảm số chiều vector.
5. Xử lý lỗi
Phần tiêu đề “5. Xử lý lỗi”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): """Tạo embedding với cơ chế thử lại""" 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"Yêu cầu thất bại, thử lại {attempt + 1}/{max_retries}: {e}") time.sleep(2 ** attempt) # Backoff theo cấp số nhân return None6. Tối ưu hóa hiệu suất
Phần tiêu đề “6. Tối ưu hóa hiệu suất”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): """Lấy embedding hàng loạt bất đồng bộ""" 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
# Sử dụngtexts = ["Văn bản 1", "Văn bản 2", ..., "Văn bản 1000"]embeddings = asyncio.run(get_embeddings_batch(texts))Câu hỏi thường gặp
Phần tiêu đề “Câu hỏi thường gặp”Hỏi: Vector nhúng có thể sử dụng xuyên suốt các mô hình không?
Không. Các mô hình khác nhau tạo ra vector với số chiều và không gian ngữ nghĩa khác nhau, bạn phải sử dụng cùng một mô hình để tạo cả vector truy vấn và vector tài liệu.
Hỏi: Làm thế nào để chọn ngưỡng độ tương đồng?
Độ tương đồng cosine dao động từ -1 đến 1. Thông thường:
-
0.8: Rất liên quan
- 0.6-0.8: Liên quan
- < 0.6: Liên quan yếu hoặc không liên quan
Ngưỡng cụ thể cần được kiểm tra và điều chỉnh dựa trên các kịch bản kinh doanh.
Hỏi: Nguyên nhân phổ biến của việc tạo embedding thất bại?
| Lỗi | Nguyên nhân | Giải pháp |
|---|---|---|
invalid_api_key | Token không hợp lệ | Kiểm tra header Authorization |
model_not_found | ID mô hình sai hoặc không khả dụng | Kiểm tra ID mô hình và quyền tài khoản |
context_length_exceeded | Văn bản đầu vào quá dài | Rút ngắn văn bản hoặc xử lý theo đoạn |
rate_limit_exceeded | Yêu cầu quá thường xuyên | Giảm đồng thời hoặc tăng khoảng cách |
Hỏi: Làm thế nào để xử lý văn bản đa ngôn ngữ?
Hầu hết các mô hình nhúng (như text-embedding-3-small) hỗ trợ nhiều ngôn ngữ, nhưng hiệu quả khớp ngữ nghĩa xuyên ngôn ngữ phụ thuộc vào việc huấn luyện mô hình. Đối với các kịch bản tiếng Trung, hãy cân nhắc bge-large-zh và các mô hình tối ưu hóa tiếng Trung khác trước.
Hỏi: Vector nhúng có thể lưu trữ trong bao lâu?
Vector nhúng có tính xác định (cùng đầu vào tạo ra cùng vector), có thể lưu trữ và tái sử dụng lâu dài, cho đến khi bạn chuyển mô hình hoặc phiên bản mô hình được cập nhật.