Петля агента: решить → сделать → посмотреть
В первом модуле ваш код разговаривал с моделью: спросил — получил ответ. Настал момент собрать из этих разговоров существо, которое работает само. Никакой новой магии не будет: петля агента — это цикл while вокруг уже знакомого ask(), плюс три обязанности, которые вы возьмёте на себя: дать модели инструменты, возвращать ей результаты и вовремя сказать «хватит».
ReAct: мысль, действие, наблюдение
Схема из вводного занятия превращается в код. ReAct (reasoning + acting) — название паттерна, придуманное ещё в 2022 году: модель чередует рассуждение и действие, а между ними стоит наблюдение — текст, который возвращает вам мир. Один оборот цикла — шаг:
Шаг 1: [мысль] чтобы ответить, надо посмотреть файл → [действие] read_file config.py
[наблюдение] DEBUG = False, HOST = "localhost"
Шаг 2: [мысль] вот он, ответ → [действие] DONEВсё, что модель «знает» о прогрессе, — это текст, который вы ей подкладываете: задача (неизменно, первым куском) и накопленные наблюдения. Промпт каждого шага — это задача плюс история наблюдений. Забыть подложить наблюдение — и модель спросит то же самое ещё раз; так выглядят агенты, которые «ходят по кругу».
Протокол шага
Модель должна как-то сказать вам, что делать. Для учебного агента мы используем простейший текстовый протокол — одна строка на шаг:
ACT: read_file config.py ← действие: имя инструмента и аргумент
DONE: порт берётся из config ← задача решена, вот ответПрефикс парсится тремя строками кода, а значит, вы увидите петлю насквозь, без библиотек. Позже (в этом же модуле, обзорно) посмотрим на function calling — тот же смысл, но схему вызова модель возвращает структурированно, по описанию инструментов.
Обратите внимание, что происходит при ошибке: неизвестное имя инструмента или упавший вызов — это не исключение для агента, а очередное наблюдение: ошибка: неизвестный инструмент rm. Модель прочитает, поймёт и попробует иначе. Исключение внутри петли убивает весь запуск; наблюдение учит петлю. Граница простая: падать можно только на том, что не исправить следующим шагом.
Стоп-условия: их всегда два
Петля без тормозов — деньги на ветер. Первое условие — воля самой модели: строка DONE: означает «задача решена, вот ответ». Второе, обязательное — лимит шагов: счётчик, который вы проверяете сами, потому что модель в потоке вдохновения способна исследовать репозиторий вечность. Сколько ставить? Для разведчика по маленькому репо хватает трёх-пяти; правило такое: средняя задача должна решаться за треть лимита, иначе агент «гуляет» и это симптом плохих инструментов или промпта.
Отдельный стоп-кейс — мусор вместо протокола: модель ответила прозой вместо ACT:/DONE:. Правильная реакция — исключение с текстом ответа в сообщении: чинить это будут промптом (few-shot пример из первого модуля — ровно про это), а не молчаливым проглатыванием.
ScriptedLLM: петля без модели
Как тестировать цикл, в центре которого LLM? Той же подменой, что и в первом модуле, только чуть умнее: FakeLLM отвечал одной заготовкой, а петле нужен сценарий — последовательность ответов. Заглушка со списком реплик, каждая выдаётся один раз, и все собранные промпты сохраняются:
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 (реплики по очереди + запись промптов) делает петлю тестируемой без сети — это ваш главный инструмент модуля.
Дальше — про инструменты: откуда петле браться за мир.
Петля агента: решить → сделать → посмотреть
5 мин
Домашка: агент с одним инструментом
3 мин
Квиз: Петля агента: решить → сделать → посмотреть
6 мин
Инструменты: руки агента
5 мин
Домашка: набор разведчика
3 мин
Квиз: Инструменты: руки агента
5 мин
Память и контекст: что тащим, что выбрасываем
5 мин
Домашка: сжатие истории
3 мин
Квиз: Память и контекст: что тащим, что выбрасываем
6 мин
Свой цикл против LangChain и LlamaIndex
4 мин
HARD-задача: прятки в репозитории
3 мин
Квиз: Свой цикл против LangChain и LlamaIndex
5 мин
Проект «Разведчик»: агент, который знает ваш репозиторий
3 мин