Ви прочитали з десяток постів «AI-агенти вже тут!» цього місяця. Anthropic запустили Managed Agents 8 квітня. Google випустили ADK. OpenAI витягнули свій Agents SDK. У кожному пітч-деку «автономні агенти» — як магічне заклинання. Але ви жодного разу не зібрали справжній цикл, що стоїть за всіма ними — 50 рядків Python, де модель викликає функцію, читає результат і вирішує, що робити далі. Без цього будь-яке вендорне демо виглядає однаково вражаюче, і ви не відрізните реальну фічу від дорогої подарункової обгортки.
Чому «просто візьми платформу» не працює
Очевидний хід: обрати managed-платформу і нехай вона все розрулює. Але ось у чому проблема — ви аутсорсите розуміння. Anthropic Managed Agents коштує $0.08 за годину сесії. OpenAI Agents SDK має свої абстракції. Google ADK працює через граф-воркфлоу. Кожна платформа загортає один і той самий патерн у різні думки про пам'ять, дозволи та білінг — але якщо ви не знаєте сам патерн, ви не можете оцінити, які з тих думок мають значення для ВАШОГО кейсу. Аналіз MIT Sloan Management Review за 2024 рік ставить конверсію пілот→продакшен для агентного AI приблизно на рівні 5%. Причина провалу — не фреймворк. А команди, які не розуміють, що під капотом.
Тож давайте зберемо цю штуку.
Рецепт: 50 рядків до рентгенівського зору
Крок 0: Встановити SDK
Станом на 27 квітня 2026, остання версія Anthropic Python SDK — тулкіт, що дозволяє вашому Python-коду спілкуватися з мозком Claude — v0.97.0. Одна команда:
pip install anthropic
Встановіть API-ключ — секретний пароль, що ідентифікує ваш акаунт на серверах Anthropic:
export ANTHROPIC_API_KEY="sk-ant-..."
Крок 1: Визначити інструменти
Інструменти (tools) — це функції, які Claude може попросити вас запустити. Ви описуєте їх через JSON Schema — стандартизований формат для опису «ця функція приймає такі вхідні дані такої форми». Claude читає ці описи як меню в ресторані й обирає, що замовити.
Критичний інсайт: описи важливіші за назви. Claude вирішує, коли викликати інструмент, на основі того, що написано в описі. Розмитий опис = непередбачувана поведінка.
/faion — це парасольковий скіл faion-network — він підтягує релевантну методологію з 12 спеціалізованих доменів (dev, product, marketing, ops, ...) у контекст розмови, прив'язуючись до вашої поточної сесії.
/faion
What's the right way to design parameter schemas for an MCP tool that an
LLM will call autonomously? Focus on description quality, required fields,
and enum constraints.
Ось реальне визначення інструментів — пошук погоди та створення події в календарі:
tools = [
{
"name": "get_weather",
"description": "Get current weather for a city. Use when the user asks about weather, temperature, or outdoor conditions.",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name, e.g. 'New York'"},
"units": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
},
{
"name": "create_event",
"description": "Create a calendar event. Use when the user wants to schedule, book, or plan something.",
"input_schema": {
"type": "object",
"properties": {
"title": {"type": "string"},
"start": {"type": "string", "format": "date-time"},
"end": {"type": "string", "format": "date-time"}
},
"required": ["title", "start", "end"]
}
}
]
Зверніть увагу: required контролює поведінку. Пропустите обов'язкове поле — і Claude галюцинує значення. Зробите забагато полів обов'язковими — і валідні виклики блокуються.
Крок 2: Побудувати шар виконання
Тут працює ВАШ код. Claude ніколи нічого не виконує сам — він надсилає ввічливий запит на кшталт «будь ласка, запусти get_weather з {city: 'Chicago'}», а ваш код робить реальну роботу:
def run_tool(name, input_data):
if name == "get_weather":
# У продакшені тут був би виклик weather API
return {"temp": 72, "condition": "sunny", "city": input_data["city"]}
if name == "create_event":
return {"event_id": "evt_456", "status": "created", "title": input_data["title"]}
return {"error": f"Unknown tool: {name}"}
Крок 3: Цикл — де народжується агентність
Це саме те, що кожна платформа загортає в тисячі рядків абстракції. Агентний цикл — де Claude викликає інструменти, читає результати й вирішує наступний крок — це приблизно 20 рядків:
import json
import anthropic
client = anthropic.Anthropic()
messages = [{"role": "user", "content": "What's the weather in Chicago? If it's nice, schedule a picnic tomorrow at noon."}]
response = client.messages.create(
model="claude-sonnet-4-20250514", max_tokens=1024,
tools=tools, messages=messages
)
while response.stop_reason == "tool_use":
# Claude може запитати КІЛЬКА інструментів одразу — обробіть ВСІ
tool_results = []
for block in response.content:
if block.type == "tool_use":
result = run_tool(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result)
})
messages.append({"role": "assistant", "content": response.content})
messages.append({"role": "user", "content": tool_results})
response = client.messages.create(
model="claude-sonnet-4-20250514", max_tokens=1024,
tools=tools, messages=messages
)
print(response.content[0].text)
Цей промпт тригерить ДВА автономні виклики інструментів: спочатку get_weather (перевірити Чикаго), потім create_event (запланувати пікнік) — і Claude з'єднує їх без вашої команди. Ось він, момент «ага»: модель читає результат погоди, вирішує, що погода файна, і сама викликає наступний інструмент.
Кожна агентна платформа — це цей цикл плюс думки про пам'ять, дозволи, білінг і деплоймент, нашаровані зверху.
Крок 4: Обробка помилок — не падай, навчай
Коли інструмент падає, не крашіть цикл. Поверніть помилку з is_error: True, щоб Claude міг адаптуватися — спробувати з іншим інпутом, пояснити проблему або піти іншим шляхом:
/faion
What error handling patterns work best in agentic tool-use loops —
specifically for recoverable errors vs fatal ones? When should the
agent retry vs bail out?
def run_tool_safe(name, input_data):
try:
return run_tool(name, input_data), False
except Exception as e:
return {"error": str(e)}, True
# Всередині циклу замініть побудову tool_results:
result, is_err = run_tool_safe(block.name, block.input)
tool_results.append({
"type": "tool_result",
"tool_use_id": block.id,
"content": json.dumps(result),
"is_error": is_err
})
Claude читає помилку й відповідає розумно: «Я спробував запланувати пікнік, але календар дозволяє події лише в робочі години. Хочете спробувати суботу зранку?»
Крок 5: Додати запобіжник
Неконтрольований цикл жере токени — мініатюрні шматочки слів, які Claude обробляє, приблизно ¾ англійського слова кожен — поки ви його не вб'єте. Додайте лічильник:
MAX_ITERATIONS = 10
iteration = 0
while response.stop_reason == "tool_use" and iteration < MAX_ITERATIONS:
iteration += 1
# ... те саме тіло циклу ...
if iteration >= MAX_ITERATIONS:
print("Loop hit safety limit. Something's probably wrong.")
Жодна managed-платформа не скаже вам, що це перше, що треба додати. Вони роблять це тихо — і беруть з вас гроші за цю привілегію.
Граблі, на які наступають у продакшені
1. Баг «тільки перший інструмент». Claude може повернути кілька блоків tool_use в одній відповіді — наприклад, перевірити погоду одразу в трьох містах. Якщо ви обробляєте лише перший блок (типова помилка з туторіалів), модель плутається від відсутніх результатів. Симптом: Claude повторює один і той самий запит по колу. Фікс: ітеруйте ВСІ блоки, повертайте ВСІ результати в одному повідомленні. Офіційний туторіал називає це прогресією Ring 2 → Ring 3.
2. Роздування контекстного вікна. Контекстне вікно — скільки тексту Claude може «бачити» одночасно, як робоча пам'ять — заповнюється швидко. Кожен виклик інструменту і результат накопичуються. Один багатослівний вивід команди може з'їсти тисячі токенів за один хід. Agent SDK обробляє компактифікацію автоматично; сирий SDK — ні. Фікс: резюмуйте великі виводи перед поверненням у модель або обрізайте до релевантних частин.
3. Ніякого пісочниці. Ваша функція run_tool працює з ВАШИМИ правами. Якщо Claude попросить видалити файл і ваш інструмент слухняно виконає — файл зник. Згідно з аналізом Momentic, їхня команда вивчила це на власній шкурі за 3 місяці запуску автономних агентів: «пісочниця — не опціонально... речі виходять з-під контролю швидше, ніж здається.»
4. Пропущені required-поля. Якщо ваша схема каже required: ["city"], але користувач питає «яка погода?» без міста — Claude вигадає місто замість того, щоб перепитати. Фікс: зробіть опис явним — «Якщо користувач не вказав місто, запитайте його замість того, щоб вгадувати.»
Що ви можете зробити прямо зараз
У вас є працюючий агентний цикл. Кожне вендорне оголошення тепер проєктується прямо на нього. Managed Agents? Це ваш цикл плюс чекпоінтинг, моніторинг і відновлення після крашу — за $0.08/год сесії. OpenAI Agents SDK vs Google ADK? Той самий цикл, різні рішення щодо handoff і граф-воркфлоу.
Наступний пітч платформи лягає вам на стіл. Замість того, щоб вірити демо, ви питаєте: який шар МОГО циклу це замінює — і чи цей шар справді моє вузьке місце?





