Embeddings (Векторные представления)
Embeddings (векторные представления) — это технология преобразования текста в высокоразмерные векторы, обычно используемая для семантического поиска, RAG (генерация с дополненным поиском), классификации текста и вычисления сходства. RouteAPI предоставляет стандартный интерфейс Embeddings, совместимый с OpenAI, поддерживающий несколько моделей векторных представлений.
Endpoint
Section titled “Endpoint”POST /v1/embeddingsПолный URL:
https://api.routeapi.ai/v1/embeddingsСценарии использования
Section titled “Сценарии использования”| Сценарий | Описание |
|---|---|
| Семантический поиск | Преобразование документов и запросов в векторы, извлечение релевантного контента через сходство |
| RAG | Извлечение релевантных фрагментов документов в качестве контекста для улучшения качества генерации LLM |
| Классификация текста | Векторизация текста для задач кластеризации или классификации |
| Рекомендательные системы | Вычисление сходства текста для рекомендаций контента |
| Обнаружение дубликатов | Идентификация дублирующегося или похожего контента через векторное сходство |
Примеры запросов
Section titled “Примеры запросов”Один текст
Section titled “Один текст”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 网关" }'Пакетные тексты
Section titled “Пакетные тексты”curl https://api.routeapi.ai/v1/embeddings \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "text-embedding-3-small", "input": [ "第一段文本", "第二段文本", "第三段文本" ] }'Параметры запроса
Section titled “Параметры запроса”| Поле | Тип | Обязательно | Описание |
|---|---|---|---|
model | string | Да | ID модели векторных представлений |
input | string/array | Да | Одна текстовая строка или массив текстов |
encoding_format | string | Нет | Формат кодирования вектора, float или base64, по умолчанию float |
dimensions | number | Нет | Возвращаемые размерности вектора (поддерживается некоторыми моделями), используется для уменьшения размерности |
user | string | Нет | Идентификатор конечного пользователя для отслеживания и мониторинга злоупотреблений |
Пример ответа
Section titled “Пример ответа”{ "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 | Количество токенов, потребленных входными данными |
usage.total_tokens | Общее количество токенов |
Поддерживаемые модели векторных представлений
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 |
Другие провайдеры
Section titled “Другие провайдеры”| ID модели | Размерность по умолчанию | Провайдер |
|---|---|---|
text-embedding-v1 | 1024 | Baidu Wenxin |
embedding-bert-512-v1 | 512 | Zhipu AI |
bge-large-zh | 1024 | BAAI BGE (китайский) |
bge-large-en | 1024 | BAAI BGE (английский) |
Доступность моделей зависит от списка моделей в консоли, разные аккаунты могут иметь разные доступные модели.
Пакетная обработка
Section titled “Пакетная обработка”Ограничения размера пакета
Section titled “Ограничения размера пакета”- Максимальное количество текстов, обрабатываемых в одном запросе, зависит от конкретной модели и конфигурации сервиса.
- Рекомендуется не превышать 100 текстов за запрос.
- Количество токенов одного текста обычно не должно превышать максимальный входной лимит модели (обычно 8192 токенов).
Советы по оптимизации пакетной обработки
Section titled “Советы по оптимизации пакетной обработки”- Объединение запросов: Объедините несколько коротких текстов в один запрос для сокращения сетевых обменов.
- Контроль параллелизма: Большие пакетные задачи можно разделить и обрабатывать параллельно, рекомендуемый параллелизм не должен превышать 5.
- Обработка ошибок: Когда один текст в пакете терпит неудачу, весь запрос может завершиться неудачей, необходима правильная повторная попытка и обработка ошибок.
Примеры кода
Section titled “Примеры кода”Python (SDK OpenAI)
Section titled “Python (SDK OpenAI)”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 (SDK OpenAI)
Section titled “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() { // Один текст 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
# Инициализация клиента RouteAPIclient = 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
# Инициализация клиента RouteAPIclient = OpenAI( api_key="sk-your-routeapi-token", base_url="https://api.routeapi.ai/v1")
# Подключение к Weaviateweaviate_client = weaviate.Client("http://localhost:8080")
# Создание схемы (если не существует)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)Лучшие практики
Section titled “Лучшие практики”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))Часто задаваемые вопросы
Section titled “Часто задаваемые вопросы”Вопрос: Можно ли использовать векторные представления между моделями?
Нет. Разные модели генерируют векторы с разными размерностями и семантическими пространствами, вы должны использовать одну и ту же модель для генерации как векторов запросов, так и векторов документов.
Вопрос: Как выбрать порог сходства?
Косинусное сходство варьируется от -1 до 1. Обычно:
-
0.8: Высоко релевантно
- 0.6-0.8: Релевантно
- < 0.6: Слабо релевантно или нерелевантно
Конкретные пороги необходимо тестировать и настраивать в зависимости от бизнес-сценариев.
Вопрос: Распространенные причины неудачной генерации векторных представлений?
| Ошибка | Причина | Решение |
|---|---|---|
invalid_api_key | Недействительный токен | Проверить заголовок Authorization |
model_not_found | Неправильный ID модели или недоступна | Проверить ID модели и права аккаунта |
context_length_exceeded | Входной текст слишком длинный | Укоротить текст или обработать сегментами |
rate_limit_exceeded | Слишком частые запросы | Уменьшить параллелизм или увеличить интервалы |
Вопрос: Как обрабатывать многоязычный текст?
Большинство моделей векторных представлений (таких как text-embedding-3-small) поддерживают несколько языков, но эффективность межъязыкового семантического сопоставления зависит от обучения модели. Для китайских сценариев рассмотрите bge-large-zh и другие модели, оптимизированные для китайского языка.
Вопрос: Как долго можно хранить векторные представления?
Векторные представления детерминированы (один и тот же вход генерирует один и тот же вектор), могут храниться и повторно использоваться в долгосрочной перспективе, пока вы не смените модель или не обновите версии модели.