Наприкінці 2023 року один мій знайомий написав скрипт. Простий Python, 80 рядків. Скрипт щоранку заходив на три сайти з вакансіями, збирав позиції під його профіль, порівнював з його резюме і надсилав у Telegram список із позначками: «добре підходиш», «потрібно підтягнути оце», «не витрачай час».

Як створити AI-агента: покрокове керівництво - 1

За місяць він отримав офер. Сам скрипт відпрацював 29 днів і знайшов ту саму вакансію, яку він навряд чи помітив би вручну.

Я тоді подумав: ось це агент. Не в сенсі шпигун. В сенсі — програма, яка діє сама, по ланцюжку, з інструментами в руках. Без того, щоб ти сидів поруч і натискав кнопки.

З тих пір AI-агенти з лабораторної екзотики перетворились на робочий інструмент. Cursor пише код за тебе. Devin закриває задачі в GitHub. Компанії будують на агентах цілі продукти — і наймають людей, які вміють їх створювати.

У цій статті розберемо, як агент влаштований зсередини, і напишемо свого з нуля. Робочий код, зрозумілі пояснення. І наприкінці — дещо важливе про те, чому більшість перших агентів ламаються в найнепідходящий момент.

Чат-бот і AI-агент: у чому різниця

Спочатку про термінологію, бо плутанина тут постійна — і вона реально заважає зрозуміти, що будувати.

Уяви: тобі потрібно знайти три вакансії Python-розробника, перевірити кожну на відповідність твоїм навичкам і написати під кожну окремий супровідний лист.

Ти відкриваєш ChatGPT і пишеш: «Знайди три вакансії Python-розробника у Варшаві». Він скаже, що не має доступу до інтернету. Або, що гірше, щось вигадає. Ти йдеш на сайт, копіюєш вакансію, вставляєш назад у чат, просиш лист. Потім знову. Потім знову. Ти — оператор при чат-боті.

Чат-бот знає і відповідає. Агент отримує задачу — і робить.

AI-агент із тими самими інструментами сам зайде на сайти з вакансіями, знайде підходящі, проаналізує їх і напише три листи. Ти в цей час п'єш каву.

Різниця не в розумності моделі. Різниця в архітектурі.

Чат-ботAI-агент
Що отримуєПитанняЗадачу
Що повертаєВідповідьРезультат дій
ІнструментиНемаєПошук, код, файли, API — все що напишеш
Пам'ятьТільки поточний діалогМоже накопичувати між сесіями
Наступний крокРобить користувачВирішує сам агент
Приклад«Поясни що таке Docker»«Знайди три вакансії DevOps, перевір вимоги, склади план підготовки»

З чого складається агент: чотири блоки

Будь-який AI-агент — і простий скрипт на 100 рядків, і складна корпоративна система — збирається з однакових частин. Уяви менеджера проєкту в маленькій команді: це допоможе.

LLM — мозок. GPT-4o, Claude, Gemini — не принципово. Це менеджер: він не копає сам, але знає, кому зателефонувати і що попросити. Модель не вміє запускати код або ходити в інтернет — вона вміє лише міркувати і давати інструкції. Всю «магію» робить архітектура навколо неї.

Tools — руки. Інструменти — це функції, які ти пишеш сам. Пошук в інтернеті, запуск коду, читання файлів, відправка листа — це підрядники менеджера: кожен вміє одне, але робить добре. LLM не викликає їх напряму — він каже «хочу викликати функцію X з аргументом Y», твій код це читає і викликає.

Пам'ять — контекст. Агент повинен пам'ятати, що вже зробив, інакше ходитиме по колу — як менеджер без блокнота, який перепитує одне й те саме на кожному дзвінку. У простому варіанті це список повідомлень. У складному — зовнішня векторна база даних.

Петля — оркестратор. Головний цикл: отримали задачу → запитали LLM → LLM сказав викликати інструмент → викликали → результат віддали назад → LLM вирішив що далі. Повторюється, поки задача не виконана.

Все. Більше нічого немає. З цих чотирьох блоків будується і скрипт на 80 рядків, який знайшов моєму знайомому роботу, і Devin.

Пишемо агента: робочий код

Беремо Python — найдоступніша мова для цієї задачі. Одна бібліотека:

pip install openai

API-ключ OpenAI — на platform.openai.com. Є стартовий кредит.

Наш агент вміє дві речі: шукати інформацію і рахувати. Це звучить скромно — але саме з таких примітивів будуються серйозні системи.

Крок 1. Описуємо інструменти

Інструменти передаються моделі як JSON-схеми. LLM читає описи і розуміє, що вміє робити. Зверни увагу на поле description — це не коментар для тебе, це інструкція для моделі. Чим точніше опишеш — тим розумнішим буде вибір інструменту.

from openai import OpenAI
import json

client = OpenAI(api_key="YOUR_API_KEY")

tools = [
    {
        "type": "function",
        "function": {
            "name": "search_web",
            "description": "Шукає актуальну інформацію в інтернеті. Використовуй коли потрібні свіжі дані, яких може не бути у навчальній вибірці.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Пошуковий запит українською або англійською"
                    }
                },
                "required": ["query"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate",
            "description": "Обчислює математичний вираз. Використовуй для точних розрахунків — LLM погано рахує в умі.",
            "parameters": {
                "type": "object",
                "properties": {
                    "expression": {
                        "type": "string",
                        "description": "Математичний вираз, наприклад: '112000 * 1.3'"
                    }
                },
                "required": ["expression"]
            }
        }
    }
]

Крок 2. Пишемо функції-інструменти

def search_web(query: str) -> str:
    # У реальному агенті тут — запит до Tavily API або SerpAPI.
    # Для прикладу — заглушка з реальними даними.
    results = {
        "python developer salary 2026": "Медіанна зарплата Python-розробника у США — $112 000. Діапазон $98k–$188k.",
        "go developer salary": "Go-розробники у США заробляють $120k–$175k. Високий попит у cloud і DevOps.",
    }
    for key in results:
        if key.lower() in query.lower():
            return results[key]
    return f"За запитом '{query}': дані отримано, інформація актуальна на 2026 рік."


def calculate(expression: str) -> str:
    try:
        # У продакшні використовуй ast.literal_eval або бібліотеку numexpr
        result = eval(expression)
        return f"Результат обчислення {expression} = {result}"
    except Exception as e:
        return f"Помилка: {e}"

Крок 3. Петля агента

Ось серце всього — цикл, який перетворює скрипт на агента:

def run_agent(user_task: str):
    print(f"\n Задача: {user_task}")
    print("─" * 50)

    messages = [
        {
            "role": "system",
            "content": (
                "Ти корисний AI-агент. У тебе є інструменти: пошук і калькулятор. "
                "Використовуй пошук для актуальних даних. Використовуй калькулятор для точних обчислень. "
                "Відповідай тільки після того, як отримав усі потрібні дані."
            )
        },
        {"role": "user", "content": user_task}
    ]

    step = 1

    while True:
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"  # LLM сам вирішує: викликати інструмент або відповісти
        )

        message = response.choices[0].message

        # LLM хоче викликати інструмент
        if message.tool_calls:
            messages.append(message)

            for tool_call in message.tool_calls:
                fn_name = tool_call.function.name
                fn_args = json.loads(tool_call.function.arguments)

                print(f"\n  Крок {step}: викликаю {fn_name}")
                print(f"   Аргументи: {fn_args}")

                if fn_name == "search_web":
                    result = search_web(**fn_args)
                elif fn_name == "calculate":
                    result = calculate(**fn_args)
                else:
                    result = f"Інструмент '{fn_name}' не знайдено"

                print(f"   Результат: {result}")
                step += 1

                # Повертаємо результат назад у LLM
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "content": result
                })

        # LLM готовий дати фінальну відповідь
        else:
            print(f"\n Відповідь агента:\n{message.content}")
            return message.content


# Запускаємо
run_agent("Скільки на рік коштуватиме найняти Python-розробника, якщо платити медіанну зарплату з урахуванням усіх податків?")

Що відбувається при запуску

Задача: Скільки на рік коштуватиме найняти Python-розробника?
──────────────────────────────────────────────────

  Крок 1: викликаю search_web
   Аргументи: {'query': 'python developer salary 2026'}
   Результат: Медіанна зарплата Python-розробника — $112 000.

  Крок 2: викликаю calculate
   Аргументи: {'expression': '112000 * 1.3'}
   Результат: Результат обчислення 112000 * 1.3 = 145600.0

 Відповідь агента:
Медіанна зарплата Python-розробника у США — $112 000 на рік.
З урахуванням податків і внесків (~30%) реальна вартість для
роботодавця складе близько $145 600 на рік.

Агент сам вирішив: спочатку потрібні дані — пошук. Потім потрібно порахувати — калькулятор. Ми не говорили йому робити саме це. Він вирішив самостійно.

Ось за що люди захоплюються агентами. Не за те, що вони розумні — за те, що вони діють.

Чому це працює: механіка function calling

Найчастіше питання після першого запуску: «Зачекай, а як LLM взагалі викликає функцію? Він що, запускає Python?»

Ні. Ось що відбувається насправді.

Коли модель вирішує, що потрібен інструмент, вона повертає не текст, а структурований JSON:

{
  "name": "search_web",
  "arguments": "{\"query\": \"python developer salary 2026\"}"
}

Твій код читає цей JSON, викликає потрібну Python-функцію, бере результат і відправляє назад у модель як нове повідомлення. Модель продовжує думати вже з цією інформацією.

LLM не знає, як працює пошук. Він знає тільки опис інструменту — і вирішує, чи потрібен він у даній ситуації.

Це принципово важливо зрозуміти: ти контролюєш інструменти, LLM контролює логіку. Хочеш навчити агента відправляти листи — напиши функцію send_email і додай її до списку. Хочеш, щоб агент міг працювати з базою даних — напиши query_database. Можливості обмежені тільки тим, що вміє Python.

Часті граблі — читай до того, як запустиш

Це найважливіший розділ статті. Всі помилки нижче — класичні, кожен перший на них наступає. Краще наступити зараз, читаючи текст, ніж о другій ночі, дивлячись у консоль.

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

if step > 10:
    print("Досягнуто ліміт кроків")
    break

Це не хак, це обов'язковий захист.

Галюцинації аргументів. LLM може передати у функцію аргумент не того типу або з друкарською помилкою. Функція calculate отримає рядок «сто двадцять» замість «120» і впаде. Завжди валідуй вхідні дані й огортай функції в try/except.

Немає tool_call_id. Коли повертаєш результат інструменту, tool_call_id обов'язковий — інакше модель не зрозуміє, відповідь на який саме виклик ти повернув. Це найчастіша помилка у новачків, вона не кидається в очі в трейсбеку, і дебажити її неприємно.

Дорогі петлі. Кожен крок — це запит до API, а кожен запит коштує грошей. Агент, який робить 30 кроків заради простої задачі — це діра в бюджеті. Чим точніше і конкретніше description у інструменту, тим рідше модель викликає зайве.

Поганий system prompt. Агент — це не просто код, це ще й інструкція в system. Якщо написати «ти корисний асистент» — отримаєш непередбачувану поведінку. Пиши конкретно: що агент має робити, коли використовувати кожен інструмент, в якому форматі відповідати.

Куди рости далі

Базовий агент готовий. Це не іграшка — це робоча архітектура, від якої будуються серйозні продукти.

Реальні інструменти. Заміни заглушку пошуку на Tavily API або SerpAPI — буквально 10 рядків коду. Додай send_email, read_file, query_database. Той самий скрипт з початку статті — це агент з інструментом пошуку вакансій і інструментом порівняння з резюме. 80 рядків, знайшов роботу.

Довготривала пам'ять. Зараз агент забуває все між запусками — як Гай Пірс у «Пам'ятай». Додай векторну базу (Chroma, Pinecone) — і агент почне накопичувати контекст, пам'ятати минулі розмови, ставати кориснішим з часом.

Кілька агентів. Один агент-оркестратор делегує задачі спеціалізованим: один шукає, інший аналізує, третій пише звіти. Саме так влаштовані Devin, AutoGPT і серйозні корпоративні AI-продукти. Архітектура — та сама, просто масштаб більший.

Складність росте лінійно. Принципи — не змінюються.

Часті запитання

Що таке AI-агент простими словами?

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

Чим AI-агент відрізняється від ChatGPT?

ChatGPT — це чат-бот: він відповідає на питання в рамках діалогу. AI-агент побудований поверх таких самих мовних моделей (GPT-4o, Claude та ін.), але доповнений інструментами і петлею виконання задач. ChatGPT не може сам зайти на сайт, запустити код або відправити лист — агент може.

Якою мовою краще писати AI-агентів?

Python — стандарт де-факто. Бібліотека openai, фреймворки LangChain і LlamaIndex, інструменти для роботи з векторними базами (Chroma, Pinecone) — все це нативно під Python. Для продакшн-систем з високим навантаженням використовують Go або TypeScript, але для старту й прототипів Python — очевидний вибір.

Що таке function calling в OpenAI API?

Механізм, який дозволяє LLM «викликати» зовнішні функції. Насправді модель не запускає код — вона повертає структурований JSON з назвою функції та аргументами. Твій код читає цей JSON, викликає потрібну функцію і повертає результат назад у модель. Саме на цьому механізмі будуються всі AI-агенти з інструментами.

Скільки коштує запустити AI-агента через OpenAI API?

Залежить від моделі і кількості кроків. GPT-4o: ~$2.50 за 1 млн вхідних токенів, ~$10 за 1 млн вихідних. Простий агент на 3–5 кроків обходиться в частки цента за запит. Дорого стає тільки при погано написаних петлях, які роблять десятки зайвих викликів — саме тому важливо ставити ліміт кроків.

Які фреймворки використовують для створення AI-агентів?

Найпопулярніші: LangChain (універсальний, велика екосистема), LlamaIndex (фокус на роботі з даними та RAG), AutoGen від Microsoft (мультиагентні системи), CrewAI (агенти з ролями). Для простих задач фреймворк не потрібен — достатньо openai SDK, як у цій статті.

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

javarush.com/ua/courses/python