Ищете Open AI embeddings API? Конечная точка эмбеддингов OpenAI преобразует текст в числовые векторы, чтобы приложение могло находить связанные фрагменты. Запрос — это лишь первый шаг: полезной функции поиска также нужны стабильные идентификаторы документов, согласованное векторное пространство и тест, показывающий, улучшился ли поиск.
В этом руководстве создаётся небольшой пример поиска на Python, показано, что хранить вместе с каждым вектором, и приведён контрольный список для переноса эксперимента в продукт. В нём OpenAI используется напрямую. Совместимость со шлюзами и доступность моделей необходимо отдельно проверять для каждого поставщика.
Open AI embeddings API: необходимый запрос
Отправьте текст на POST https://api.openai.com/v1/embeddings, указав модель эмбеддингов и API-ключ. Выберите encoding_format="float", если ваше приложение ожидает числовые массивы. Для пакета используйте index каждого элемента ответа, чтобы сопоставить вектор с его входными данными. Ответ также включает информацию об использовании токенов. Параметр dimensions поддерживается моделями эмбеддингов третьего поколения. Справочник OpenAI API.
Эмбеддинг не является сгенерированным ответом. В приложении с дополненной поиском генерацией поиск сначала выбирает исходные фрагменты; затем отдельный вызов генерации может сформировать ответ, используя эти фрагменты. Разделение этапов позволяет диагностировать плохой результат: поиск нашёл неверные доказательства или модель ответов неправильно использовала хорошие доказательства?
Выберите модель и зафиксируйте её конфигурацию
Документированные стандартные длины векторов составляют 1 536 для text-embedding-3-small и 3 072 для text-embedding-3-large. Эти модели поддерживают более короткие выходные векторы с помощью dimensions. Более короткий вектор меняет компромиссы между хранением и поиском; это не повод пропускать оценку. Руководство по эмбеддингам OpenAI.
Начните с одной конфигурации и небольшого набора репрезентативных запросов. Сохраняйте вместе с индексом модель, запрошенное число измерений и версию обработки текста. Одинаковая длина двух векторов не доказывает, что они получены совместимой моделью. При изменении моделей или правил обработки создайте отдельный индекс и сравните его, прежде чем переключать рабочий трафик.
Минимальный пример семантического поиска на Python
Установите openai в своё окружение Python и предоставьте OPENAI_API_KEY через обычный менеджер секретов или конфигурацию окружения. Не храните ключ в системе контроля версий и в коде браузера. Официальный Python SDK считывает эту переменную при создании OpenAI().
Сохраните следующий код как search_demo.py. В нём используются три вымышленных документа службы поддержки, создаются эмбеддинги для корпуса и запроса, а документы ранжируются по косинусному сходству. При запуске выполняются платные API-запросы. Результат зависит от ответа сервиса; пример не гарантирует конкретный балл или порядок ранжирования.
import math
from openai import OpenAI
client = OpenAI(timeout=30.0, max_retries=2)
model = "text-embedding-3-small"
dimensions = 1536
documents = [
{"id": "key-rotation", "text": "Replace an exposed API key and revoke the old credential."},
{"id": "invoice-export", "text": "Download a monthly invoice from the billing workspace."},
{"id": "request-timeout", "text": "Record the request ID and retry temporary upstream timeouts."},
]
query = "What should I do after accidentally sharing a secret key?"
def embed(texts):
response = client.embeddings.create(
model=model, input=texts,
dimensions=dimensions, encoding_format="float",
)
ordered = sorted(response.data, key=lambda item: item.index)
if [item.index for item in ordered] != list(range(len(texts))):
raise ValueError("Unexpected embedding response indices")
vectors = [item.embedding for item in ordered]
if any(len(vector) != dimensions for vector in vectors):
raise ValueError("Unexpected vector dimensions")
print("Input tokens:", response.usage.prompt_tokens)
return vectors
def cosine(a, b):
if len(a) != len(b):
raise ValueError("Vector dimensions do not match")
denominator = math.sqrt(sum(x*x for x in a) * sum(y*y for y in b))
if not denominator:
raise ValueError("Cannot compare a zero vector")
return sum(x*y for x, y in zip(a, b)) / denominator
vectors = embed([document["text"] for document in documents])
query_vector = embed([query])[0]
ranked = sorted(
((cosine(query_vector, vector), document["id"])
for document, vector in zip(documents, vectors)),
reverse=True,
)
for score, document_id in ranked:
print(document_id, round(score, 4))
Запустите python search_demo.py. Убедитесь, что все три идентификатора появляются по одному разу и что каждый эмбеддинг имеет настроенную длину. Затем измените запрос, чтобы он касался счетов. Это дымовой тест потока данных, а не доказательство готовности системы к реальному трафику службы поддержки. Для наглядности пример повторно создаёт эмбеддинги корпуса при каждом запуске; развёрнутый сервис обычно должен сохранять векторы документов и создавать эмбеддинги только для нового или изменённого содержимого.
Превратите демонстрацию в надёжный индекс документов
Следующая структура записи — практичная отправная точка. Это пример проектирования приложения, а не схема полей, требуемая OpenAI.
| Хранить с каждым фрагментом | Почему это важно |
|---|---|
document_id и chunk_id | Обновляйте или удаляйте нужный контент, не полагаясь на порядок в массиве. |
| URL источника, заголовок раздела и редакция источника | Отображайте полезную ссылку на источник и отслеживайте устаревшие ответы. |
| Хеш контента и версия обработки | Определяйте, какие фрагменты действительно нужно создать заново. |
| Модель и количество измерений | Предотвращайте случайное смешивание несовместимых конфигураций векторов. |
| Метаданные арендатора и контроля доступа | Ограничивайте извлечение документами, к которым запрашивающий пользователь может получить доступ. |
| Текст и эмбеддинг | Возвращайте исходный отрывок после выбора его вектора. |
Разбивайте документы по смысловым границам, затем проверяйте длину в токенах. Раздел, содержащий ответ на вопрос, должен оставаться понятным при извлечении сам по себе. Осознанно оценивайте перекрытие: чрезмерное перекрытие может заполнить набор результатов повторяющимися версиями одного и того же отрывка.
Для первого эксперимента достаточно приведенного выше цикла в памяти. По мере роста корпуса используйте индекс или векторное хранилище, поддерживающее требуемые операции фильтрации, удаления и извлечения. Протестируйте эти операции, прежде чем полагаться на оценки сходства. Отрывок с высоким сходством, но от другого клиента, никогда не должен возвращаться лишь потому, что он занимает первое место.
Проверяйте ограничения ввода и пакетов отдельно
В текущей справке по endpoint OpenAI указан максимум 8 192 токена на один вход и совокупный максимум 300 000 токенов для входов в одном запросе; также документирован максимум в 2 048 входов в пакете. Пустой текст недопустим. Считайте токены, а не символы, и оставляйте запас относительно ограничений при формировании пакетов. Ограничения endpoint.
Если вы используете Azure OpenAI, конфигурация endpoint, аутентификация и именование развертываний требуют отдельной настройки. Следуйте инструкциям по эмбеддингам Azure для этого сервиса вместо предположения, что прямой запрос OpenAI можно скопировать без изменений. Соблюдайте такое же разделение при использовании шлюза: сначала проверьте его endpoint, доступ к моделям, поддерживаемые параметры и платежный аккаунт.
Оценивайте стоимость, не скрывая перестроение индекса
Стоимость эмбеддингов зависит от входных токенов, поэтому отдельно считайте загрузку документов, измененные фрагменты и эмбеддинги запросов. Используйте актуальную цену со страницы соответствующей модели, например text-embedding-3-small, и подтвердите, что указанная ставка применяется к вашему режиму запросов.
Для примера планирования пусть P — подтвержденная цена за миллион входных токенов:
Первичная загрузка: 50 000 фрагментов × 400 токенов = 20 миллионов токенов
Ежемесячные изменения: 5 000 фрагментов × 400 токенов = 2 миллиона токенов
Ежемесячные запросы: 200 000 запросов × 20 токенов = 4 миллиона токенов
Стоимость первичного создания эмбеддингов = 20 × P
Регулярная стоимость эмбеддингов = (2 + 4) × P = 6 × P
Это иллюстративные предположения о нагрузке, а не цены Flatkey или OpenAI. Отдельно добавьте стоимость векторного хранилища, поисковой инфраструктуры и любых вызовов генерации ответов. Если вы меняете модель эмбеддингов, включите полный повторный расчет эмбеддингов в бюджет миграции. Конвейер, который повторно создает эмбеддинги для неизменившихся документов, может потратить больше, чем та же нагрузка с более крупной, но правильно кешируемой моделью.
Диагностируйте ошибки перед добавлением повторных попыток
| Симптом | Первая полезная проверка |
|---|---|
| Ошибка аутентификации | Подтвердите, что ключ действителен для endpoint и аккаунта, к которым вы обращаетесь. |
| Недопустимый запрос | Проверьте тело ошибки, пустые строки, количество токенов и поддерживаемые параметры. |
| Ошибка ограничения скорости или квоты | Отличайте нагрузку на частоту запросов от исчерпанной квоты аккаунта. |
| Временная ошибка сервера или тайм-аут | Сохраняйте идентификаторы запросов и используйте ограниченное число повторных попыток. |
| Ошибка размерности векторного хранилища | Сравните конфигурацию коллекции с фактической длиной возвращенного вектора. |
| Правдоподобные, но нерелевантные результаты | Проверьте текст фрагментов, согласованность модели и примеры запросов, прежде чем обвинять сеть. |
Первые четыре проверки следуют руководству OpenAI по ошибкам. Последние две относятся к вашему приложению и индексу. Соблюдайте рекомендации сервера по повторным попыткам и учитывайте повторы SDK, прежде чем добавлять еще один цикл повторных попыток. Журналируйте операционные метаданные, не записывая учетные данные или ненужный приватный текст документов.
Оценивайте извлечение до выбора модели ответов
Создайте небольшой размеченный набор из реальных вопросов пользователей, включая перефразировки, точные названия продуктов, неоднозначные вопросы и вопросы, на которые ваш корпус не может ответить. До настройки системы запишите ожидаемый исходный документ для каждого запроса, на который можно ответить.
Для каждой конфигурации-кандидата фиксируйте, появляется ли приемлемый источник среди первых нескольких результатов, сколько возвращается дублирующегося материала, задержку извлечения и стоимость одного запроса. Рассматривайте сбои по отдельности. Если запрос требует точный код ошибки, сопоставление по ключевым словам может дополнить семантическое сходство. Если источника нет, изменение размерности эмбеддингов не сможет его создать.
Сохраните отложенную часть вопросов для финального сравнения. Не выбирайте порог сходства по демонстрации из трех документов и не считайте его универсальной оценкой уверенности. Полезный приемочный тест отражает последствия неверного извлечения в вашем собственном приложении.
Место Flatkey в приложении
Flatkey предоставляет маршрутизатор моделей, совместимый с OpenAI, и актуальный каталог моделей. Используйте документацию по интеграции Flatkey, чтобы оценить сторону вашего приложения, связанную с генерацией моделями. В приведённых выше примерах OpenAI вызывается напрямую; они не подтверждают, что модель эмбеддингов или все параметры эмбеддингов доступны через Flatkey.
Для приложения с несколькими поставщиками сохраняйте конфигурацию поиска независимой от конфигурации модели для ответов. Это позволяет сравнивать модели ответов без пересборки индекса документов для каждого эксперимента. При планировании маршрутизации, контроля учётных записей и операционных проверок ознакомьтесь с руководствами Flatkey по архитектуре API.
Часто задаваемые вопросы
Отвечает ли API эмбеддингов на вопросы самостоятельно?
Он возвращает векторы. Ваше приложение использует их для выбора связанного контента; если вам нужен письменный ответ, модель для ответов является отдельным компонентом.
Можно ли сравнивать векторы из разных моделей эмбеддингов?
Не следует предполагать, что они используют общее осмысленное координатное пространство, даже если их размерности совпадают. Ведите отдельные индексы для каждой модели и оценивайте миграции, используя одни и те же вопросы и исходные документы.
Стоит ли сразу выбрать самую большую модель эмбеддингов?
Начните с конфигурации, которую можно измерить. Сравните качество поиска, задержку, объём хранилища и стоимость на собственных запросах, прежде чем соглашаться на более крупный индекс или другую модель.
Что следует создать в первую очередь?
Используйте Open AI embeddings API, чтобы преобразовать в эмбеддинги небольшой корпус с безопасными с точки зрения разрешений данными, проверить соответствие документов векторам и протестировать поиск с помощью размеченных вопросов. Расширяйте корпус после того, как этот цикл даст надёжные доказательства.



