Петля агента: решить → сделать → посмотреть

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

ReAct: мысль, действие, наблюдение

Схема из вводного занятия превращается в код. ReAct (reasoning + acting) — название паттерна, придуманное ещё в 2022 году: модель чередует рассуждение и действие, а между ними стоит наблюдение — текст, который возвращает вам мир. Один оборот цикла — шаг:

java
Шаг 1:  [мысль] чтобы ответить, надо посмотреть файл   → [действие] read_file config.py
        [наблюдение] DEBUG = False, HOST = "localhost"
Шаг 2:  [мысль] вот он, ответ                           → [действие] DONE

Всё, что модель «знает» о прогрессе, — это текст, который вы ей подкладываете: задача (неизменно, первым куском) и накопленные наблюдения. Промпт каждого шага — это задача плюс история наблюдений. Забыть подложить наблюдение — и модель спросит то же самое ещё раз; так выглядят агенты, которые «ходят по кругу».

Протокол шага

Модель должна как-то сказать вам, что делать. Для учебного агента мы используем простейший текстовый протокол — одна строка на шаг:

java
ACT: read_file config.py      ← действие: имя инструмента и аргумент
DONE: порт берётся из config  ← задача решена, вот ответ

Префикс парсится тремя строками кода, а значит, вы увидите петлю насквозь, без библиотек. Позже (в этом же модуле, обзорно) посмотрим на function calling — тот же смысл, но схему вызова модель возвращает структурированно, по описанию инструментов.

Обратите внимание, что происходит при ошибке: неизвестное имя инструмента или упавший вызов — это не исключение для агента, а очередное наблюдение: ошибка: неизвестный инструмент rm. Модель прочитает, поймёт и попробует иначе. Исключение внутри петли убивает весь запуск; наблюдение учит петлю. Граница простая: падать можно только на том, что не исправить следующим шагом.

Стоп-условия: их всегда два

Петля без тормозов — деньги на ветер. Первое условие — воля самой модели: строка DONE: означает «задача решена, вот ответ». Второе, обязательное — лимит шагов: счётчик, который вы проверяете сами, потому что модель в потоке вдохновения способна исследовать репозиторий вечность. Сколько ставить? Для разведчика по маленькому репо хватает трёх-пяти; правило такое: средняя задача должна решаться за треть лимита, иначе агент «гуляет» и это симптом плохих инструментов или промпта.

Отдельный стоп-кейс — мусор вместо протокола: модель ответила прозой вместо ACT:/DONE:. Правильная реакция — исключение с текстом ответа в сообщении: чинить это будут промптом (few-shot пример из первого модуля — ровно про это), а не молчаливым проглатыванием.

ScriptedLLM: петля без модели

Как тестировать цикл, в центре которого LLM? Той же подменой, что и в первом модуле, только чуть умнее: FakeLLM отвечал одной заготовкой, а петле нужен сценарий — последовательность ответов. Заглушка со списком реплик, каждая выдаётся один раз, и все собранные промпты сохраняются:

python
class ScriptedLLM:
    """Модель по сценарию: реплики по очереди, промпты на record."""

    def __init__(self, replies: list[str]) -> None:
        self.replies = list(replies)
        self.prompts: list[str] = []

    def ask(self, prompt: str) -> str:
        self.prompts.append(prompt)
        return self.replies.pop(0)

С ней тесты петли становятся детерминированными и честными сразу в двух смыслах: вы проверяете и логику цикла, и — по сохранённым промптам — что наблюдения действительно доезжают до модели на следующем шаге. Именно этот класс останется в devbuddy до финала: каждый новый кусок агента будет тестироваться через сценарий, а живая модель подключается последним, необязательным слоем.

Что запомнить:

  • Петля = ask() в цикле: задача + накопленные наблюдения на каждом шаге; ReAct — чередование мысли и действия.

  • Ошибки инструментов — наблюдения, а не исключения. Падает только нечинимое следующим шагом.

  • Стоп-условий два: DONE от модели и ваш лимит шагов. Мусор вместо протокола — исключение с внятным текстом.

  • ScriptedLLM (реплики по очереди + запись промптов) делает петлю тестируемой без сети — это ваш главный инструмент модуля.

Дальше — про инструменты: откуда петле браться за мир.

  • theory icon

    Петля агента: решить → сделать → посмотреть

    5 мин

  • homework icon

    Домашка: агент с одним инструментом

    3 мин

  • quiz icon

    Квиз: Петля агента: решить → сделать → посмотреть

    6 мин

  • theory icon

    Инструменты: руки агента

    5 мин

  • homework icon

    Домашка: набор разведчика

    3 мин

  • quiz icon

    Квиз: Инструменты: руки агента

    5 мин

  • theory icon

    Память и контекст: что тащим, что выбрасываем

    5 мин

  • homework icon

    Домашка: сжатие истории

    3 мин

  • quiz icon

    Квиз: Память и контекст: что тащим, что выбрасываем

    6 мин

  • theory icon

    Свой цикл против LangChain и LlamaIndex

    4 мин

  • homework icon

    HARD-задача: прятки в репозитории

    3 мин

  • quiz icon

    Квиз: Свой цикл против LangChain и LlamaIndex

    5 мин

  • project icon

    Проект «Разведчик»: агент, который знает ваш репозиторий

    3 мин

🎯
Тренажёр собеседованияЗакрепите знания перед интервью