AI для початківцівПосібник
Як працює AI-агент: цикл, запущений без API-ключа
AI-агент — це цикл: модель просить інструмент, ваш код запускає його, результат повертається. Запустіть демо на Python без ключа, а потім націльте його на справжню модель.

На цій сторінці
Ви просите агента для кодування виправити одну друкарську помилку і спостерігаєте, як прокручується журнал: прочитати файл, пошукати, прочитати інший файл, відредагувати, запустити тести. Один маленький запит — десяток викликів моделі. Звідки вони беруться?
AI-агент — це цикл. Ваша програма надсилає розмову моделі; модель або відповідає, або просить інструмент ("прочитай цей файл"); ваша програма запускає інструмент, додає результат до розмови і знову викликає модель. Це повторюється, доки модель не відповість звичайним текстом. Агенти для кодування, такі як Claude Code, Codex і режим агента в Cursor, побудовані навколо цього самого циклу, з більшою кількістю інструментів і більшою обережністю. Нижче ви запустите версію на 40 рядків взагалі без ключа, а потім націлите її на справжню модель.
Цикл в одній картині#
Уявіть менеджера, який не може нічого торкатися. Менеджер лише пише записки: "будь ласка, принеси мені todo.txt". Помічник (ваша програма) йде до полиці, приносить файл і кладе його на стіл. Менеджер читає його і пише наступну записку або остаточну відповідь.
Ось і весь трюк. Модель ніколи не відкриває файл і не запускає команду. Вона пише текст, у якому вказано, який інструмент викликати і з якими аргументами. Ваш код виконує роботу і доповідає назад. Якщо ви бачили function calling, це той самий механізм, що повторюється, доки роботу не буде виконано.

Чи можете ви розставити один оберт циклу в правильному порядку?
Розставте по порядку
Розставте один оберт циклу агента по порядку
Перетягніть елементи або скористайтеся стрілками
- Надіслати завдання та список інструментів моделі
- Модель відповідає викликом інструменту, а не текстом
- Ваша програма сама запускає цей інструмент
- Результат додається до повідомлень як повідомлення "tool"
- Модель викликається знову з результатом, доки не відповість звичайним текстом
Запустіть без ключа#
Скажімо, завдання таке: "Скільки елементів у todo.txt?". Інструмент — це функція read_file, яка шукає у маленькому словнику замість диска. А замість справжньої моделі є сценарна, яка завжди робить ті самі дві речі: просить файл, потім відповідає. Цього достатньо, щоб побачити кожну рухому частину. Збережіть це як agent_loop.py (Python 3.10+, лише стандартна бібліотека):
import json, os, urllib.request
NOTES = {"todo.txt": "buy milk\ncall Anna\nsend invoice"}
def read_file(name):
return NOTES.get(name, "no such file")
TOOLS = {"read_file": read_file}
TOOL_SPECS = [{"type": "function", "function": {
"name": "read_file", "description": "Read a note by file name",
"parameters": {"type": "object",
"properties": {"name": {"type": "string"}},
"required": ["name"]}}}]
def scripted_model(messages):
if messages[-1]["role"] == "user": # first lap: ask for the file
return {"role": "assistant", "content": None, "tool_calls": [{
"id": "call_1", "type": "function",
"function": {"name": "read_file",
"arguments": "{\"name\": \"todo.txt\"}"}}]}
return {"role": "assistant", "content": "The file has 3 items."}
def real_model(messages):
body = {"model": os.environ["LLM_MODEL"], "messages": messages,
"tools": TOOL_SPECS}
req = urllib.request.Request(
os.environ["LLM_BASE_URL"] + "/chat/completions",
data=json.dumps(body).encode(),
headers={"Content-Type": "application/json",
"User-Agent": "agent-loop-demo/1.0",
"Authorization": "Bearer " + os.environ["LLM_API_KEY"]})
with urllib.request.urlopen(req) as resp:
data = json.load(resp)
u = data["usage"]
print(" usage: in", u["prompt_tokens"], "out", u["completion_tokens"])
return data["choices"][0]["message"]
def run(task, model, max_steps=8):
messages = [{"role": "user", "content": task}]
for step in range(1, max_steps + 1):
reply = model(messages)
messages.append(reply) # keep the model's turn in history
calls = reply.get("tool_calls")
if not calls:
print(f"step {step}: answer -> {reply['content']}")
return
for call in calls:
name = call["function"]["name"]
args = json.loads(call["function"]["arguments"])
result = TOOLS[name](**args) # YOUR code does the work
print(f"step {step}: tool {name}({args}) -> {result!r}")
messages.append({"role": "tool", "tool_call_id": call["id"],
"content": result})
print("stopped: max_steps reached")
model = real_model if os.environ.get("LLM_API_KEY") else scripted_model
run("How many items are in todo.txt?", model)Запустіть python agent_. Без LLM_API_KEY у вашому середовищі ви отримаєте сценарну модель, і екран покаже рівно два оберти:

Подивіться на три рядки, бо в них уся ідея:
messages.зберігає власний хід моделі. Пропустіть його, і наступний виклик міститиме результат інструменту, що відповідає на запит, якого API ніколи не бачив; більшість API відхилять це з помилкою 400.append(reply) argumentsнадходить як JSON рядок, тому він проходить черезjson.loads, перш ніж ви викличете функцію.max_steps— це аварійне гальмо. Модель може нескінченно просити інструменти, тому кожен справжній агент має такий ліміт.
Націльте той самий цикл на справжню модель#
Змінюється лише одне: хто грає роль моделі. Скрипт читає три змінні середовища, і якщо ключ присутній, він надсилає той самий messages на сумісну з OpenAI кінцеву точку. Адреса CheapTokens — https:/ (сумісна з OpenAI Chat Completions та Anthropic Messages), а ідентифікатор моделі має бути повним з документації: deepseek-.
Запустіть цикл трьома способами
Без ключа
python agent_loop.pyСценарна модель грає обидва оберти. Нічого не залишає вашу машину.
DeepSeek-V4-Flash
export LLM_BASE_URL=https://api.cheaptokens.dev/v1
export LLM_API_KEY=<your key>
export LLM_MODEL=deepseek-ai/DeepSeek-V4-Flash-0731
python agent_loop.pyВікно контексту 380K і до 32 768 вихідних токенів на відповідь: місце для довгого циклу.
GLM-5.3-Flash
export LLM_BASE_URL=https://api.cheaptokens.dev/v1
export LLM_API_KEY=<your key>
export LLM_MODEL=zai-org/GLM-5.3-Flash
python agent_loop.pyЛегка модель із вікном контексту 390K для першого запуску багатокрокового циклу.
Ви повинні побачити ту саму форму, що й раніше: step 1: tool read_, потім step 2: answer -, з рядком usage: під кожним викликом моделі. Формулювання відповіді відрізнятиметься від сценарного, і балакуча модель може зробити додатковий оберт. Це нормально: модель вирішує, цикл лише підкоряється. Тримайте ключ поза самим скриптом; змінна середовища — безпечне місце (ось як його зберігати).
Рядки usage: — це корисна частина. Додайте числа in довшого запуску, і ви побачите, куди йдуть гроші.
Чому кожен оберт коштує більше за попередній#
Модель нічого не пам'ятає між викликами. Кожен оберт знову надсилає весь список messages: завдання, кожен попередній виклик інструменту, кожен результат інструменту. (Те саме правило робить довгий чат дорогим; багатоходовий чат показує це на звичайній розмові.)
Оберт 1 надсилає одне повідомлення. Якщо цикл продовжується, оберт 6 надсилає одинадцять.

Скажімо, справжнє завдання займає 10 обертів. Воно починається з приблизно 2 000 токенів (інструкції, список інструментів, ваш запит), кожен оберт додає близько 1 500 (результат інструменту плюс нотатка моделі), і модель пише близько 300 токенів за оберт. Оберт 1 надсилає 2 000, оберт 2 надсилає 3 500, оберт 10 надсилає 15 500. Сума першої частини — 10 × 2 000 = 20 000 токенів; приріст додає 1 500 × 45 = 67 500 (45 — це 0+1+…+9), тож вхідні дані за завданням становлять 20 000 + 67 500 = 87 500 токенів. Вихідні дані — 10 × 300 = 3 000 токенів.
Сам текст завдання — це кілька речень, але вхідна частина — 87 500 токенів. За $0.015 за 1M вхідних токенів усе завдання на DeepSeek-V4-Flash коштує $0.0016. Ось те саме навантаження по моделях, з OpenRouter для порівняння. Загалом, з урахуванням входу і виходу разом, CheapTokens виходить дешевше за OpenRouter на цьому навантаженні:
| Модель | Вхід $/1М | Вихід $/1М | Вартість | OpenRouter |
|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.0019 | $0.0038 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.0016 | $0.0046 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.0048 | $0.0299 |
87 500 вхідних і 3 000 вихідних токенів загалом. Ціни за 1 млн токенів актуальні та змінюються разом із нашими тарифами; стовпець OpenRouter показує довідкові ціни для того самого навантаження.
Одна ціна в будь-який час доби також допомагає тут: агент, який працює всю ніч, коштує стільки ж, скільки опівдні, і ви можете побачити всі ціни на сторінці цін. Для дня таких завдань посувайте повзунки:
Калькулятор вартості
Один день: 20 завдань по 10 обертів кожне
Вхідні токени на запит: 8 750 · Вихідні токени на запит: 300 · Запитів на день: 200
| Модель | За день | За місяць |
|---|---|---|
| GLM-5.3-Flash$0.02$0.04 | $0.0374 | $1.12 |
| DeepSeek-V4-Flash$0.015$0.10 | $0.0323 | $0.968 |
| MiniMax-M2.7$0.05$0.15 | $0.0965 | $2.90 |
Поля вказуються на виклик моделі: 8 750 — це середній вхід одного оберту з прикладу вище (87 500 ÷ 10), а 200 викликів — це 20 завдань × 10 обертів. Ось чому рахунки агентів стосуються історії, а не питання. Приклад на 20 кроків заглиблюється в той самий ефект.
Швидка перевірка
Оберт 3 циклу агента коштує більше за оберт 1, хоча ви нічого нового не питали. Чому?
Показати відповідь
Відповідь: Список повідомлень тепер містить два виклики інструментів і два результати, і все це надсилається знову
API не має стану. Кожен виклик несе повну історію, тому вхідні токени зростають з кожним обертом, тоді як вихідні залишаються приблизно тими самими.
Куди рухатися від 40 рядків#
Скрипт вище — це начерк для навчання. Якщо ви хочете довшу версію, є відкритий курс на GitHub, justxor/agent-harness-course (README російською, перевірено 31 жовтня 2026 року). Це чистий Python 3.10+ без залежностей, код під ліцензією MIT, текст під CC BY 4.0. Після клонування python examples/ запускає цикл офлайн зі сценарною моделлю, а python - запускає його 19 тестів без мережі. Курс продовжується ущільненням контексту, пам'яттю, субагентами, схваленням ризикованих дій людиною та відстеженням витрат. Для справжньої моделі він читає LLM_PROVIDER, LLM_MODEL, LLM_API_KEY і, для сумісних з OpenAI кінцевих точок, LLM_BASE_URL: візьміть точне значення LLM_PROVIDER з його README.
Коли цикл працює, наступний крок — справжній ключ і справжнє завдання: у документації є перший запит за хвилину, а DeepSeek-V4-Flash — гарна модель для запуску циклу.



