Все уроки · 44
API и SDK: как код разговаривает с моделями
Стандарт, совместимый с OpenAI, Claude Messages API, Gemini API и экосистема Hugging Face — с рабочим кодом, который можно скопировать и запустить.
Один случайный стандарт
Сначала три слова, которые вы будете встречать повсюду, — простым языком:
- API — способ, которым ваш код может попросить что-то у другого компьютера и получить ответ. Вы отправляете запрос — получаете ответ. Как форма на сайте, только заполняет её ваша программа.
- Endpoint (конечная точка) — конкретный адрес, на который отправляется запрос, вроде URL.
- SDK — готовая библиотека для вашего языка программирования, которая
скрывает «сырую» работу с HTTP. Без SDK вы собираете запрос вручную; с ним вы
пишете
client.chat.completions.create(...), а остальное библиотека делает сама.
Больше за этими словами ничего нет. Всё дальнейшее строится на них.
В 2023 году OpenAI выпустила свой чат-API, и формат запроса оказался настолько удобным, что его переняла почти вся индустрия. Сегодня множество провайдеров — включая серверы открытых моделей вроде Ollama и vLLM — предоставляют OpenAI-совместимый endpoint: адрес, который принимает запросы в том же виде.
Для вас это значит: выучите один формат запроса — и сможете общаться с десятками моделей. Вот этот формат:
- название модели (
model), - список сообщений (
messages), у каждого из которых есть роль (role: system, user, assistant, tool) и содержимое (content), - необязательные параметры сэмплирования (temperature, max tokens — всё из предыдущего урока),
- ответ, в котором есть сообщение и объект
usageс количеством токенов.
Ещё одно слово, прежде чем перейти к коду: этот формат обычно записывают в
JSON — текстовом формате для структурированных данных. В фигурных скобках
находится «объект» (набор именованных полей), в квадратных — список, а каждое
поле записывается как "name": "value". Это выглядит как код, но это
просто форма, заполненная текстом, — намеренно скучная, чтобы её мог прочитать
любой язык программирования и любой сервер. Когда ниже вы увидите
{"role": "user", "content": "..."}, это JSON: крошечная форма с двумя полями —
role и content.
Запрос такого вида и есть тот самый единственный вызов, на котором строится всё остальное. Один POST-запрос: на входе текст, в ответ — одно продолжение; никакого второго вида запросов нет. Окно чата, агент, RAG-пайплайн — всё это программы, которые снова и снова делают один и тот же вызов с разным текстом. SDK — всего лишь обёртка, которая собирает этот текст и запускает цикл за вас. Вся идея в одном месте: Один вызов: как на самом деле работают все ИИ-продукты.
OpenAI-совместимый API на практике
1from openai import OpenAI2 3client = OpenAI() # читает OPENAI_API_KEY из переменной окружения4 5response = client.chat.completions.create(6 model=#98c379">"gpt-4o-mini",7 messages=[8 {#98c379">"role": "system", "content": "You are a concise assistant."},9 {#98c379">"role": "user", "content": "Explain prompt caching in 2 sentences."}10 ],11 temperature=0.7,12 max_tokens=200,13)14 15print(response.choices[0].message.content)16print(response.usage.total_tokens, #98c379">"tokens")Не обращайте внимания на синтаксис и посмотрите на общий скелет: модель,
сообщения (messages или contents), несколько параметров, ответ с текстом и
данными об использовании (usage). Различия, которые стоит запомнить:
- Claude: системный промпт — отдельный параметр верхнего уровня, а не
сообщение с ролью. Параметр
max_tokensнужно передавать всегда. - Gemini: более плоский стиль — в простых случаях
contentsможет быть обычной строкой; параметры передаются вconfig. - OpenAI-совместимый формат:
system— просто первое сообщение. На этом «диалекте» говорит большинство сторонних провайдеров.
Что такое API-ключ
API-ключ — это длинная секретная строка, по которой провайдер вас узнаёт: отчасти логин, отчасти банковская карта. Её передаёт каждый запрос, а провайдер выставляет счёт тому, кому ключ принадлежит. Вот и весь механизм.
Из этого прямо следуют два правила:
- Ключ — это деньги. Любой, у кого он есть, может потратить ваш баланс. Боты круглосуточно сканируют публичные репозитории GitHub в поисках случайно закоммиченных ключей; утёкший ключ обычно начинают использовать в течение нескольких минут.
- Не храните его в коде. Положите его в переменную окружения — значение,
которое хранится на самой машине, вне ваших файлов, и которое программа
читает при запуске. Поэтому в примерах выше клиент создаётся без видимого
ключа: SDK сам берёт
OPENAI_API_KEYиз окружения. Кодом можно делиться, а секрет вместе с ним не уходит.
Где ключу не место
Никогда не вставляйте ключ ни в файл, который вы коммитите, ни в чат, ни на скриншот в руководстве. Если ключ всё же утёк, сначала отзовите его в панели управления провайдера, а уже потом разбирайтесь, как это произошло.
Как запрос уходит и возвращается
Код выше хорош, но что именно передаётся по сети? Нажимайте «отправить →»:
это один цикл «запрос — ответ», тот самый, который ваш код выполняет каждый раз.
Первая строка, POST /v1/chat/completions, — это просто адрес (endpoint) плюс
тип запроса: POST означает «создай что-то по этим данным» — этот глагол ваш код
использует, когда просит модель сгенерировать ответ. Ничего похожего на чат в
человеческом смысле здесь нет: модель понятия не имеет, что раньше был какой-то
другой запрос.
Обратите внимание на две вещи, которые часто упускают:
- Системное сообщение — это просто элемент списка, а не особая настройка (кроме Claude, где это отдельный параметр).
usageпоказывает, за что именно вы только что заплатили. Это самое полезное поле во всём ответе — и то, которое проще всего проигнорировать.
Потоковая передача в Node
Для интерактивных интерфейсов нужна потоковая передача (см. предыдущий урок). Вот как буднично она выглядит в JavaScript:
import OpenAI from "openai";
const client = new OpenAI();
const stream = await client.chat.completions.create({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Write a haiku about tokens." }],
stream: true,
});
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta?.content ?? "";
process.stdout.write(delta); // выводит токен за токеном
}Весь секрет эффекта «ИИ печатает» — в этом цикле: каждый фрагмент содержит несколько токенов, и интерфейс дописывает их по мере поступления.
Экосистема Hugging Face
Hugging Face для открытых моделей — то же, что GitHub для кода. AI-инженеру важны три части:
- Hub — больше миллиона наборов весов моделей, датасетов и демо. Llama, Mistral, DeepSeek, дообученные версии всего подряд: если веса опубликованы, они есть здесь.
- Inference — запуск открытых моделей прямо на платформе через простой API
(клиент
huggingface_hubили endpoint в формате чата): модели можно пробовать, ничего не скачивая. - Transformers / Transformers.js — библиотека, которая загружает модель локально и запускает её на Python. Transformers.js даже запускает небольшие модели прямо в браузере через WebGPU — вообще без сервера.
Когда стоит обратиться к Hugging Face
Когда вам нужны открытые веса: эксперименты перед self-hosting, локальный запуск небольшой модели эмбеддингов или ранжирования (reranking), либо функция, которая должна работать офлайн прямо в браузере. Для повседневной работы с API обычно проще описанный выше OpenAI-совместимый путь.
Минимум для выживания при работе с API
У какого бы провайдера вы ни работали, в каждом реальном проекте возникают одни и те же четыре заботы:
- Лимиты запросов — предел того, сколько можно отправить за минуту. Вы обязательно на них наткнётесь. С первого дня реализуйте повторные попытки с экспоненциальной задержкой (exponential backoff): если вызов не удался, подождите 1 с, затем 2 с, затем 4 с, вместо того чтобы забрасывать сервер запросами. Официальные SDK часто делают это за вас.
- Ошибки и тайм-ауты — до моделей добираются по сети. Исходите из того, что любой вызов может не удаться, и заранее решите, что покажет интерфейс, если генерация не сработала.
- Учёт токенов — читайте поле
usage, записывайте его в лог, суммируйте. Неожиданные расходы — одна из главных причин, по которым проекты на LLM закрывают. - Фиксация версии — названия моделей меняются, а сами модели снимают с
поддержки. Указывайте в конфигурации точную версию модели (название с датой
вроде
gpt-4o-mini-2024-07-18, а не «плавающую» метку) и заранее продумайте, как будете переходить на другую модель, пока не пришло уведомление о снятии с поддержки.
Проверьте себя
Почему «OpenAI-совместимый endpoint» так важен на практике?
Вы случайно закоммитили свой API-ключ в публичный репозиторий, а потом удалили файл. Что делать?
В день запуска ваше приложение получает ошибку «rate limit exceeded». Какой порядок действий правильный?