01.3
Модуль 1 · Технический минимум: читать, понимать, коммитить

Урок 3. API и чтение кода

Урок 3

Прямо сейчас: откройте PowerShell. Выполните: Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/todos/1". Видите таблицу с данными? Это ваш первый API-запрос. 30 секунд.

Зачем это L&D-специалисту

Все AI-модели, с которыми вы работаете (Claude, ChatGPT, OpenRouter), живут не в интерфейсе чата, а за API. API — это дверь, через которую одна программа общается с другой. AI-агент, которого вы запускаете, не «думает» сам — он отправляет запрос к модели через API и получает ответ.

Если вы понимаете, как устроен такой запрос, вы можете: прочитать документацию любой AI-модели, понять, что делает чужой код, объяснить разработчику задачу на его языке и — при желании — собрать простого AI-агента без конструктора. Это последний кирпич технического минимума перед погружением в AI.

Пример из жизни: когда вы пишете вопрос в ChatGPT, браузер отправляет API-запрос к серверу OpenAI. Текст вопроса улетает туда, модель обрабатывает его и возвращает ответ. Всё, что вы видите в интерфейсе — это красивая обёртка над API-запросами.

Что такое API

API (Application Programming Interface) — это способ, которым одна программа просит что-то у другой программы. Проще всего представить официанта в ресторане:

Метафора. Кухня — это сервер (там обрабатывают данные, запускают модели). Официант — это API (принимает заказ, относит на кухню, приносит результат). Меню — это документация API (что можно заказать и как). Вы — это ваш код (клиент, который отправляет запрос).

Вы не идёте на кухню, не знаете, как работает плита. Вы говорите официанту: «Мне пасту карбонара». Он передаёт заказ на кухню и приносит тарелку. Так же работает API: вы отправляете запрос в понятном формате, сервер обрабатывает и возвращает ответ.

HTTP-методы: GET и POST

Когда вы заходите на сайт, ваш браузер отправляет HTTP-запросы. Два основных типа:

Метод Что делает Аналогия
GET Запрашивает данные (чтение) «Принесите меню, пожалуйста»
POST Отправляет данные на сервер (создание) «Я хочу заказать пасту, вот мой заказ»

GET — вы не меняете ничего на сервере, просто читаете. POST — вы отправляете данные, и сервер что-то с ними делает (создаёт, считает, генерирует). Все запросы к AI-моделям — это POST: вы посылаете промпт, модель возвращает ответ. Есть и другие методы (PUT, DELETE, PATCH), но в 80% случаев вы встретите GET и POST.

API-ключ: ваш пропуск

Большинство AI-API требуют ключ — длинную строку символов, которую вы прикрепляете к запросу. Это как билет на концерт: без него вас не пустят, с ним — вы свой.

Ключ передаётся в заголовке запроса (headers):

Authorization: Bearer sk-or-v1-ваш-длинный-ключ

Правила безопасности:

JSON: язык API

JSON (JavaScript Object Notation) — это формат, на котором программы общаются друг с другом. Способ записать данные так, чтобы их легко читал и человек, и машина.

Пример JSON-запроса к AI-модели:

{
  "model": "openai/gpt-4o",
  "messages": [
    {"role": "user", "content": "Привет, как дела?"}
  ],
  "temperature": 0.7
}

Правила JSON:

Как читать JSON. Представьте матрёшку. Открываете внешнюю — внутри объект. Открываете объект — внутри поле choices. Открываете choices — внутри список. Первый элемент списка — ещё объект с полем message. А внутри message — поле content с текстом ответа. Научиться читать JSON — как научиться читать квитанцию: сначала кажется китайской грамотой, через неделю — привычно.

В ответ модель тоже пришлёт JSON — с результатом внутри поля choices[0].message.content. Почти каждый API-ответ выглядит как JSON.

Статус-коды

Когда сервер отвечает на запрос, он всегда присылает код — трёхзначное число, которое говорит, что случилось:

Код Значение Когда
200 OK Всё хорошо, данные в ответе
201 Created Что-то создано (обычно после POST)
400 Bad Request Вы отправили кривой запрос (опечатка в JSON)
401 Unauthorized Нет ключа или ключ неверный
403 Forbidden Ключ есть, но доступа нет (чужая модель)
404 Not Found Такого адреса нет
429 Too Many Requests Слишком много запросов, подождите
500 Internal Server Error Сервер упал, не ваша вина
2xx = успех, 4xx = ваша ошибка, 5xx = ошибка сервера

Как читать чужой код

Вы не будете писать код с нуля. Но вы будете его читать: скрипт коллеги, пример из документации, AI-сгенерированный файл. Чтение кода — это навык отличать лес от деревьев.

При встрече с незнакомым файлом задайте себе три вопроса:

  1. Что на входе? — Какие данные получает программа: аргументы командной строки? Файл? Запрос от пользователя? Ищите input(), sys.argv, open(), requests.get().
  2. Что внутри? — Что она делает с данными: циклы, условия, вызовы других функций. Читайте сверху вниз, как рецепт.
  3. Что на выходе? — Что программа возвращает: печатает в консоль? Сохраняет в файл? Отправляет ответ? Ищите print(), return, write(), requests.post().
Метафора. Чтение кода — как чтение рецепта на незнакомом языке. Вы не знаете всех слов, но понимаете: «взять X, смешать с Y, поставить в духовку на Z минут». Импорты — список ингредиентов, функции — шаги рецепта, вызов — «духовку включить».

Не надо понимать каждую строчку. Вам нужно понимать логику: что заходит, что делается, что выходит. Остальное — детали, которые вы нагуглите.

Промежуточный итог

API — универсальный язык программ. GET читает. POST отправляет. JSON — формат. Статус-коды — обратная связь.

Понимать API — как знать английский в IT

Вы не обязаны писать код, но обязаны понимать о чём говорят разработчики. API, JSON, статус-коды, эндпоинты — это базовый словарь. Без него вы слышите шум. С ним — участвуете в разговоре на равных.

Шпаргалка

API-запросы в PowerShell

Действие Команда
GET-запрос Invoke-RestMethod -Uri "https://api.example.com/data"
GET с параметрами Invoke-RestMethod -Uri "https://api.example.com/search?q=термин"
POST-запрос с JSON Invoke-RestMethod -Method Post -Uri "..." -Body (ConvertTo-Json @{key="val"}) -ContentType "application/json"
POST с заголовком (ключ) Добавить -Headers @{"Authorization"="Bearer sk-key"}
Сохранить ответ в переменную $ответ = Invoke-RestMethod -Uri "..."
Посмотреть поле ответа $ответ.поле или $ответ[0].поле
Сохранить ответ в файл ... | ConvertTo-Json -Depth 10 | Out-File -FilePath "ответ.json"

Статус-коды

Диапазон Смысл Пример
2xx Успех 200 OK, 201 Created
3xx Перенаправление 301 Moved Permanently
4xx Ошибка на вашей стороне 400 Bad Request, 401 Unauthorized, 404 Not Found
5xx Ошибка на стороне сервера 500 Internal Server Error, 503 Service Unavailable

Структура кода

Элемент Python JavaScript Что делает
Импорт библиотек import requests const fetch = require('node-fetch') Подключает готовый код, чтоб не писать с нуля
Функция def send_prompt(text): function sendPrompt(text) { } Блок действий, который можно вызвать по имени
Переменная api_key = "sk-..." const apiKey = "sk-..." Хранит данные (строку, число, список)
Условие if status == 200: if (status === 200) { } «Если это правда — делай это, иначе — то»
Цикл for item in items: for (let item of items) { } Повторить действие для каждого элемента
Вызов API requests.get(url, headers=...) fetch(url, { method: 'POST', ... }) Отправить HTTP-запрос к серверу

Практика

Упражнение 1. Первый GET-запрос (10 мин)

Откройте PowerShell. Мы отправим запрос к бесплатному тестовому API jsonplaceholder — это «песочница» для тренировки запросов (не требует ключа).

Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/todos/1"

Вы увидите таблицу с полями userId, id, title, completed. PowerShell распознал JSON и показал его таблицей.

Теперь запросите все задачи и посчитайте их количество:

$todos = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/todos"
$todos.Count

Сколько вернулось? Должно быть 200. Переменная $todos — это коробка, куда мы сложили ответ, чтобы потом с ним работать.

Посмотрите первую и последнюю задачу:

$todos[0]
$todos[-1]

Вы только что сделали то же, что и AI-скрипт: отправили запрос, получили JSON, достали поле из ответа.

Упражнение 2. API с параметрами (10 мин)

API могут принимать параметры — как фильтр в интернет-магазине. Параметры идут после знака ?:

Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/todos?userId=1"

Вы получили задачи только пользователя с ID=1. Попробуйте userId=2, userId=3.

Теперь попробуйте другой публичный API — поиск книг:

$books = Invoke-RestMethod -Uri "https://openlibrary.org/search.json?q=learning+design"
$books.docs.Count
$books.docs[0].title

Вы получили список книг по запросу "learning design" и посмотрели название первой. Символ ? отделяет адрес от параметров, = — название параметра от значения, + заменяет пробел.

Упражнение 3. Чтение документации OpenRouter (20 мин)

OpenRouter — это сервис, через который можно обращаться к сотням AI-моделей по единому API. Нам он понадобится в следующем модуле.

Откройте в браузере: openrouter.ai/docs/quick-start

Ваша задача — не понять всё, а найти ответы на три вопроса (запишите в блокнот):

  1. Какой URL для отправки запроса? (Подсказка: ищите POST и api/v1/)
  2. Какое поле в ответе содержит текст, который сгенерировала модель? (Подсказка: ищите choices и content)
  3. Как называется заголовок для передачи API-ключа? (Подсказка: ищите слово Authorization)

Теперь откройте раздел Models: openrouter.ai/models

Найдите одну бесплатную модель (с пометкой "Free") и запишите её полное название (например, google/gemini-2.0-flash-001).

Это тренировка навыка «читать документацию» — самого важного для разработчика. Не бойтесь, если непонятно: ваша цель — найти три конкретных факта, а не понять всё.

Упражнение 4. POST-запрос: отправляем данные (15 мин)

GET-запросы просто читают. POST — отправляют данные на сервер. Попробуем на тестовом API:

$body = @{
    title  = "Моя тестовая задача"
    body   = "Учусь отправлять POST-запросы"
    userId = 1
} | ConvertTo-Json

$response = Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Method Post -Body $body -ContentType "application/json"
$response

Вы увидите созданный объект с полем id: 101 — сервер подтвердил создание.

Разбор команды по частям:

  • @{ ... } — создали хеш-таблицу (словарь) с данными
  • | ConvertTo-Json — превратили в JSON-строку
  • -Method Post — указали метод
  • -Body $body — передали данные
  • -ContentType "application/json" — сказали серверу: «Я посылаю JSON»
Упражнение 5. Статус-коды на практике (10 мин)

Специально сделаем неправильные запросы, чтобы увидеть статус-коды:

1. Несуществующая страница (404):

try { Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/ne-postoi" } catch { $_.Exception.Message }

2. Битый JSON (400):

try { Invoke-RestMethod -Uri "https://jsonplaceholder.typicode.com/posts" -Method Post -Body '{"title": "oops' -ContentType "application/json" } catch { $_.Exception.Message }

Конструкция try { ... } catch { ... } — это «попробуй выполнить, а если ошибка — покажи сообщение, но не падай».

Запомните: если пришёл 4xx — проверьте свой запрос. Если 5xx — подождите и попробуйте позже, проблема не у вас.

Упражнение 6. Чтение чужого кода (25 мин)

Ниже — скрипт на Python, который обращается к AI-модели через OpenRouter API. Ваша задача — не написать такой же, а прочитать и объяснить, что он делает.

import os
import requests
import json

# --- 1. Настройки ---
API_KEY = os.environ.get("OPENROUTER_API_KEY")
MODEL = "google/gemini-2.0-flash-001"
API_URL = "https://openrouter.ai/api/v1/chat/completions"

# --- 2. Запрос ---
system_prompt = "Ты — L&D-методист. Отвечай коротко, по делу."
user_question = "Объясни разницу между RAG и fine-tuning одной фразой."

headers = {
    "Authorization": f"Bearer {API_KEY}",
    "Content-Type": "application/json"
}

payload = {
    "model": MODEL,
    "messages": [
        {"role": "system", "content": system_prompt},
        {"role": "user", "content": user_question}
    ],
    "temperature": 0.3,
    "max_tokens": 100
}

# --- 3. Отправка ---
response = requests.post(API_URL, headers=headers, json=payload)

# --- 4. Обработка ответа ---
if response.status_code == 200:
    answer = response.json()
    print(answer["choices"][0]["message"]["content"])
else:
    print(f"Ошибка {response.status_code}: {response.text}")

Задание: откройте Блокнот и напишите ответы на вопросы в свободной форме:

  1. Что на входе? — Какие данные получает скрипт перед запуском?
  2. Что внутри? — Перечислите основные блоки (1–4), которые вы видите. Опишите назначение каждого блока своими словами.
  3. Что на выходе? — Что произойдёт, если скрипт выполнится успешно? Что — если ключ не указан?
  4. Какие строчки вам непонятны? — Выпишите 1–3 строки. Попробуйте догадаться из контекста.
  5. Что такое temperature в payload? — Догадайтесь из контекста.

Не подсматривайте ответы, пока не напишете свои. Дальше — разбор.

Разбор (откройте после того, как ответили сами)

1. Что на входе: API-ключ из переменной окружения OPENROUTER_API_KEY, название модели, URL для запроса, системный промпт, вопрос пользователя.

2. Блоки:

  • Блок 1 (строки 1–3): Импорт. Подключаем библиотеки для работы с переменными окружения, HTTP-запросами и JSON.
  • Блок 2 (строки 5–7): Конфигурация. Задаём ключ, модель и адрес. Ключ берётся не из кода (опасно), а из переменной окружения.
  • Блок 3 (строки 9–27): Формируем текст запроса — системный промпт, вопрос пользователя, заголовки с ключом, тело запроса (payload) с моделью, сообщениями, температурой и лимитом токенов.
  • Блок 4 (строки 29–35): Отправка и обработка. POST-запрос с заголовками и телом. Если код 200 — печатаем ответ модели. Если нет — печатаем ошибку.

3. Что на выходе: Успех — в терминале появится ответ модели (одна фраза про RAG vs fine-tuning). Нет ключа — ошибка 401 (Unauthorized).

4. Непонятные строки: os.environ.get("OPENROUTER_API_KEY") — берёт значение из переменной окружения, чтобы не хранить ключ в коде. f"Bearer {API_KEY}" — f-строка подставляет значение переменной внутрь текста. response.json() — превращает JSON-ответ сервера в объект Python.

5. Temperature: Число от 0 до 2. 0 = модель отвечает строго, как по учебнику. 1 = творчески, с вариациями. 0.3 — почти строго, но с лёгкой свободой.

Упражнение 7. Создание артефакта (15 мин)

Вернитесь в папку вашего учебного проекта. Создайте папку api-demo и внутри — файл openrouter-test.md:

mkdir api-demo
ni api-demo\openrouter-test.md

Откройте файл в редакторе и запишите:

  1. Свой первый GET-запрос — URL и что вернулось.
  2. Свой первый POST-запрос — какой JSON отправили и какой id присвоил сервер.
  3. Ответы на пять вопросов из Упражнения 6 (чтение кода).
  4. Три факта, которые вы нашли в документации OpenRouter.
  5. 2–3 предложения своими словами: что я понял(а) про API.

Сохраните, закройте. Проверьте через терминал:

cat api-demo\openrouter-test.md
Упражнение 8. Бонус: реальный запрос к OpenRouter (15 мин)

Если у вас есть желание и 15 минут — выполните бонусное упражнение. Оно не обязательно, но даст вам первый реальный опыт общения с AI-моделью через API.

Что нужно:

  1. Зайдите на openrouter.ai/keys, зарегистрируйтесь (бесплатно) и создайте API-ключ.
  2. Положите немного денег на баланс ($1–2, этого хватит на десятки запросов).
  3. Вернитесь в PowerShell. НЕ вставляйте ключ в код — задайте переменную окружения:
$env:OPENROUTER_API_KEY = "ваш-ключ-сюда"

Теперь отправьте запрос к бесплатной модели:

$headers = @{
    "Authorization" = "Bearer $env:OPENROUTER_API_KEY"
    "Content-Type"  = "application/json"
}

$body = @{
    model    = "google/gemini-2.0-flash-001"
    messages = @(
        @{ role = "user"; content = "Привет! Напиши хайку про осень." }
    )
} | ConvertTo-Json -Depth 3

$response = Invoke-RestMethod -Uri "https://openrouter.ai/api/v1/chat/completions" -Method Post -Headers $headers -Body $body
$response.choices[0].message.content

Если всё получилось — вы только что отправили свой первый запрос к AI-модели не через чат-интерфейс, а напрямую через API.

Если что-то пошло не так — проверьте:

  • Правильно ли скопирован ключ (весь, без пробелов в начале/конце)
  • Есть ли деньги на балансе OpenRouter
  • Доступна ли модель google/gemini-2.0-flash-001 (бесплатная, но иногда с задержкой)

Важно: после эксперимента закройте PowerShell (ключ удалится из переменной окружения) и никогда не публикуйте ключ в Git.

После практики

Чек-лист готовности

Артефакт урока

После урока в вашем проекте должна появиться структура:

ваш-проект/
└── api-demo/
    └── openrouter-test.md    # Описание запроса к OpenRouter + разбор кода

Челлендж на завтра

Откройте DevTools в браузере (F12) → вкладка Network → обновите любую страницу. Вы увидите все API-запросы, которые делает сайт. Ваш браузер — это клиент, который постоянно общается с серверами через API. Найдите один GET-запрос, один POST-запрос и посмотрите на их статус-коды. Это займёт 5 минут, но закрепит понимание на практике.

Что дальше

Вы завершили Модуль 1. Технический минимум. Теперь вы умеете:

Следующий модуль: AI — от промпта до продукта. Вы узнаете, как работают LLM на самом деле, что такое RAG и эмбеддинги, и соберёте своего первого AI-агента. Всё, что вы освоили в этом модуле, — база, на которой это строится.

Итоговая проверка Модуля 1

Ответьте себе (можно устно):

  1. Как создать папку и файл из терминала?
  2. Как сделать коммит и отправить его на GitHub?
  3. Чем GET отличается от POST?
  4. Что означает статус-код 401?
  5. Из чего состоит API-запрос к AI-модели? (метод, URL, заголовки, тело)

Если на все 5 вопросов отвечаете без подсказок — Модуль 1 пройден.

Дополнительно (необязательно, но полезно)

Проверь себя

1. Что такое API?

2. Какой HTTP-метод используется для получения данных?

3. Что такое API-ключ?

4. В каком формате API обычно возвращает данные?