Введение в AI-агентов и продакшн-подход

Что такое AI-агент и чем он отличается от чат-бота

Содержание курса

0 / 1 баллов

Соберите цикл агента

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

Задание

Реализуйте функцию run_agent(model, tools, task, max_steps).

Начните диалог с одного сообщения — запроса пользователя task. Дальше повторяйте: вызовите model.invoke(messages), добавьте полученный ответ в диалог, а затем разберите его заявки на вызовы. Если заявок нет, прогон закончен — верните текст ответа. Если есть, исполните каждую по очереди и добавьте её результат в диалог отдельным сообщением, после чего вызовите модель снова.

Число обращений к модели ограничено значением max_steps. Если лимит израсходован, а модель так и не ответила без заявок, верните строку "LIMIT_REACHED".

Что приходит в аргументах

model — объект с методом invoke(messages), принимающим текущий список сообщений. Возвращает ответ с двумя полями: text — обычный текст, и tool_calls — список заявок. Каждая заявка это словарь с ключами name (имя инструмента), args (словарь аргументов) и id.

tools — словарь: имя инструмента → функция. Функцию вызывают именованными аргументами из args, возвращает она строку.

Пример

def count_clients(threshold: int) -> str:
    return "2"

# Модель просит инструмент, получает результат и отвечает текстом.
run_agent(model, {"count_clients": count_clients}, "Сколько клиентов?", 12)
# "Клиентов с балансом выше 1000 — двое."

# Модель на каждом шаге снова просит инструмент, лимит равен двум.
run_agent(model, {"count_clients": count_clients}, "Сколько клиентов?", 2)
# "LIMIT_REACHED"

Примечание

Формат сообщений в списке произвольный — проверяется только их количество. Важно, что после ответа модели с двумя заявками диалог вырастает на три сообщения: сам ответ и два результата. Если что-то из этого потерять, заглушка модели прервёт прогон с ошибкой.

Инструменты не бросают исключений и всегда возвращают строку, так что оборачивать их в try здесь не нужно. Ответ модели может содержать несколько заявок сразу — исполняйте их в том порядке, в каком они лежат в tool_calls.

model и tools приходят готовыми — создавать их не нужно. Разрешена только стандартная библиотека Python 3.12.

О данных в ответах

Используйте учебные данные. Не вставляйте пароли, токены, ключи доступа, паспортные и банковские данные, а также персональные данные других людей. Политика обработки данных.

Проверяется тестами (1)
  • Примеры из условия
    def _count_clients(threshold: int) -> str:
        return "2"
    
    
    _TOOLS = {"count_clients": _count_clients}
    
    # Модель просит инструмент, получает результат и отвечает текстом.
    _model = ScriptedModel([
        ModelReply(tool_calls=[
            {"name": "count_clients", "args": {"threshold": 1000}, "id": "c1"},
        ]),
        ModelReply(text="Клиентов с балансом выше 1000 — двое."),
    ])
    assert run_agent(_model, _TOOLS, "Сколько клиентов?", 12) == \
        "Клиентов с балансом выше 1000 — двое.", "ожидался финальный текст модели"
    assert _model.seen_lengths == [1, 3], \
        "второй вызов должен видеть запрос, ответ модели и результат инструмента"
    
    # Модель на каждом шаге снова просит инструмент — срабатывает лимит.
    _looping = ScriptedModel([
        ModelReply(tool_calls=[
            {"name": "count_clients", "args": {"threshold": 1000}, "id": "c1"},
        ])
        for _ in range(5)
    ])
    assert run_agent(_looping, _TOOLS, "Сколько клиентов?", 2) == "LIMIT_REACHED", \
        "лимит исчерпан, обычного ответа не было"
    assert len(_looping.seen_lengths) == 2, \
        "модель должна быть вызвана ровно max_steps раз"
РешениеPython · Python 3.12 (basic)
Как проверяется решение

Проверяются функции и их результаты. Собственный запуск выполняет ваш код без авторских тестов. Интерактивный запуск не влияет на оценку. Лимит сессии — 5 минут, процессорного времени — 10 секунд.

Отправьте решение, чтобы увидеть результаты тестов.

Начать заново?

Помощник начнёт новый диалог по этой задаче. Текущая переписка останется в истории до конца срока хранения.

О переписке

Можно приложить до трёх фото PNG, JPEG или WebP по 5 МБ.

Переписка и фото хранятся 90 дней после последнего принятого сообщения. Преподаватель получит доступ к диалогу, когда вы попросите его помочь.

Проверка решения остаётся отдельным действием.