Усі уроки · 44
Шлях 3 · Дорожня карта AI-інженера·Урок 7 з 33

API та SDK: як код розмовляє з моделями

Стандарт, сумісний з OpenAI, Claude Messages API, Gemini API та екосистема Hugging Face — з робочим кодом, який можна скопіювати й запустити.

РівеньСереднійЧас~15 хв

Один випадковий стандарт

Спершу три слова, які ви зустрічатимете повсюдно, — простими словами:

  • 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 OpenAI
2 
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-ключ — це довгий секретний рядок, за яким провайдер вас упізнає: почасти логін, почасти банківська картка. Його передає кожен запит, а провайдер виставляє рахунок тому, кому ключ належить. Ось і весь механізм.

З цього прямо випливають два правила:

  1. Ключ — це гроші. Будь-хто, у кого він є, може витратити ваш баланс. Боти цілодобово сканують публічні репозиторії GitHub у пошуках випадково закомічених ключів; ключ, що витік, зазвичай починають використовувати протягом кількох хвилин.
  2. Не зберігайте його в коді. Покладіть його в змінну середовища — значення, яке зберігається на самій машині, поза вашими файлами, а програма читає його під час запуску. Тому в прикладах вище клієнт створюється без видимого ключа: SDK сам бере OPENAI_API_KEY із середовища. Кодом можна ділитися, а секрет разом із ним не йде.

Де ключу не місце

Ніколи не вставляйте ключ ані у файл, який ви комітите, ані в чат, ані на скриншот у посібнику. Якщо ключ усе ж витік, спочатку відкличте його в панелі керування провайдера, а вже потім розбирайтеся, як це сталося.

Як запит іде й повертається

Код вище гарний, але що саме передається мережею? Натискайте «надіслати →»: це один цикл «запит — відповідь», той самий, який ваш код виконує щоразу. Перший рядок, POST /v1/chat/completions, — це просто адреса (endpoint) плюс тип запиту: POST означає «створи щось за цими даними» — це дієслово ваш код використовує, коли просить модель згенерувати відповідь. Нічого схожого на чат у людському розумінні тут немає: модель гадки не має, що раніше був якийсь інший запит.

Simulated conversation
press the button below to send the first message
sent to the modelnothing yet — every message is sent in full

Зверніть увагу на дві речі, які часто пропускають:

  • Системне повідомлення — це просто елемент списку, а не особливе налаштування (окрім Claude, де це окремий параметр).
  • usage показує, за що саме ви щойно заплатили. Це найкорисніше поле в усій відповіді — і те, яке найлегше проігнорувати.

Потокова передача в Node

Для інтерактивних інтерфейсів потрібна потокова передача (див. попередній урок). Ось як буденно вона виглядає в JavaScript:

streaming.js
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». Який порядок дій правильний?