Объяснение агентов: инструменты, системные промпты и цикл мышления-действия
Пошаговое руководство для начинающих о том, как работают ИИ-агенты: почему модели чата забывают, как описываются инструменты для ЯЗЫКОВ, системные промпты, метод ReAct, кодовые агенты и наблюдения.
Современные ИИ-агенты основаны на небольшом числе ключевых элементов: инструментах, системном промпте и цикле мышления, действий и наблюдения. Как только эти компоненты согласованно работают вместе, большинство фреймворков для агентов представляют собой вариации одной и той же концепции. В следующих разделах мы постепенно раскроем суть агентов, начиная с того, что они на самом деле такое.
Что такое агент
Агент — это система, в которой модель ИИ взаимодействует со своей средой для выполнения определенной задачи. Она объединяет в себе рассуждения, планирование и выполнение действий, обычно с помощью внешних инструментов. Большинство агентов управляются большими языковыми моделями, хотя модели визуального понимания языка также могут выполнять аналогичную функцию.
Ваше приложение для чатов забывает всё
Вот факт, который удивляет многих людей: при общении с ChatGPT или похожим ассистентом внутри модели не происходит никакого диалога. Она ничего не хранит, не отслеживает текущее состояние и не сохраняет ничего между вашими сообщениями. Каждый раз, когда вы нажимаете на кнопку отправки, весь прошедший обмен объединяется в один длинный блок текста, и модель читает этот блок с самого начала.
Представьте себе такой обмен:
conversation = [
{"role": "user", "content": "I need help with my order"},
{"role": "assistant", "content": "Could you provide your order number?"},
{"role": "user", "content": "It's ORDER-123"},
]
Вы видите аккуратный список этапов с указанием ролей, которым занимаются разработчики в коде. Однако сама модель никогда не получает такого списка. Прежде чем что-либо дойдёт до неё, этапы сглаживаются и объединяются в одну последовательность текста, а её единственная задача, как и всегда, — предсказать следующий токен на основе всего, что было до него.
Не существует специального шага «запомнить это». Когда кажется, что модель вспоминает ваш номер заказа, это не память. Этот номер просто всё ещё находится в тексте, который она сейчас читает.
Инструменты
Инструмент — это функция, желательно с одной чёткой целью, которая передаётся большой языковой модели. Типичные примеры включают:
- поиск в интернете
- генерация изображений
- загрузка документов
- обращение к API
Хороший инструмент расширяет возможности модели. Он должен содержать следующие элементы:
- текстовое описание того, что делает функция
Как на самом деле вызывается инструмент
Ключевой момент заключается в том, что JLM не может напрямую использовать какие-либо внешние инструменты. Текст поступает внутрь, и текст выходит наружу — больше ничего. Утверждение о том, что модель «имеет доступ к инструментам», на самом деле означает, что она научилась записывать запрос к инструменту в текстовом виде. Если спросить о погоде в Париже, модель не получает прогноз; она выдает структурированное сообщение с указанием на необходимость запуска инструмента погоды.
Слой агента находится между пользователем и моделью. Он обнаруживает сообщение, запускает соответствующий инструмент, собирает результат и добавляет его в разговор, прежде чем отправить всё обратно модели. Благодаря этому дополнительному контексту модель формирует обычный ответ. Пользователю кажется, что модель напрямую обращалась в службу погоды, хотя на самом деле всю организацию работы выполнял агент.
Небольшой пример
Для иллюстрации рассмотрим калькулятор, который выполняет лишь одну функцию — умножение двух целых чисел:
def multiply(a:int, b:int):
"Multiply two integers"
return a * b
Преобразование функции в инструмент
Библиотека Hugging Face transformers предоставляет декоратор @tool, который оборачивает обычную функцию на Python, чтобы агент мог её понять. Сначала необходимо импортировать библиотеку:
from transformers import tool
Затем функция с оформлением:
@tool
def multiply(a: int, b: int):
"""Multiply two integers."""
return a * b
На этапе обработки в фоновом режиме декоратор собирает метаданные:
- имя функции
- ее описание
- имена аргументов
- типы аргументов
- тип возвращаемого значения
Эти метаданные затем включаются в инструкцию, которая указывает модели, как правильно использовать инструмент.
Рассмотрим инструмент
После декорирования инструмент может описать себя в текстовом виде:
print(multiply.to_string())
В отпечатанном результате приводятся сведения примерно в следующем виде:
Tool Name: multiply
Description:
Multiply two integers.Arguments:
- a (int)
- b (int)
Это структурированное описание — именно то, что агент показывает модели. ЯЗЫК больших моделей читает его как любой другой текст и определяет, поможет ли инструмент выполнить запрос пользователя.
Рабочий процесс агента
Агент работает в цикле, состоящем из мышления (Thought), действия (Action) и наблюдения (Observation).
- Thought. Часть агента, представляющая собой ЯЗЫК больших моделей, решает, что делать дальше.
- Action. Агент вызывает инструменты с выбранными аргументами.
- Observation. Модель рассматривает результат, возвращенный инструментом.
Агент остается в этом цикле мышления, действия и наблюдения до тех пор, пока не достигнет своей цели.
Системное указание
Системное указание — это набор инструкций, передаваемых модели до любого сообщения пользователя. Оно определяет поведение, роль, ограничения и цели всего диалога.
Когда пользователь пишет что-то, модель видит не только этот текст. Обычно она получает информацию примерно в таком виде:
<System Prompt>
You are a helpful programming assistant.
Always explain concepts before showing code.
If the user asks for unsafe code, refuse politely.
<User>
Explain binary search.
Приоритет у системного запроса выше, чем у запроса пользователя. Предположим, в системном запросе указано отвечать всегда на английском, а пользователь просит ответ на французском. Модель обычно будет следовать системному запросу, если только приложение не предусматривает возможность отмены его пользовательскими запросами.
Системный запрос агента содержит дополнительную информацию, описывающую инструменты и сам цикл обработки запросов:
You are an AI assistant that can answer user questions.
You have access to the following tools:
Tool: search_web
Description:
Searches the web for up-to-date information.
Arguments:
- query (string)
Tool: calculator
Description:
Evaluates mathematical expressions.
Arguments:
- expression (string)
If a user's question requires current information, use search_web.
If a calculation is required, use calculator.
Otherwise, answer directly.
В этом сообщении системы определены три аспекта:
- как должен вести себя агент
- какие инструменты он может использовать, описанные так же, как показано в предыдущем разделе
- цикл мышления, действия и наблюдения, встроенный в инструкции модели
Каждый из этих трех этапов заслуживает более детального рассмотрения.
Мышление
Мысли отражают внутренние рассуждения и планирование агента в процессе выполнения задачи. Существуют два распространенных стиля:
- chain-of-thought (CoT)
- ReAct (рассуждения плюс действия)
Chain-of-thought — это метод формулировки запросов, побуждающий модель пошагово решать проблему перед тем, как дать окончательный ответ. Рассуждения остаются внутренними, что подходит для логических и математических задач, не требующих внешних инструментов.
ReAct — это метод, который также требует пошагового мышления, но включает действия, такие как вызовы инструментов, между этапами рассуждений.
Оба подхода позволяют большим языковым моделям постепенно решать проблемы. Разница заключается в том, что CoT зависит только от того, что уже известно модели, в то время как ReAct сочетает рассуждения с действиями. Это позволяет модели использовать внешние инструменты, собирать свежую информацию и основываться на результатах действий при дальнейших рассуждениях, что лучше подходит для динамичной работы в реальном мире, связанной с внешними системами.
Действия: от мышления к действию
Действия — это шаги, которые выполняет агент для взаимодействия со своей средой. Сотрудник службы поддержки может загрузить данные клиента, предложить статьи с рекомендациями или передать дело человеку.
Генератор текста способен запускать реальные инструменты с помощью простой схемы, называемой остановкой и парсингом. Сама модель ничего не выполняет — она формирует структурированный запрос с описанием необходимых действий, после чего агент выполняет их от её имени.
По сути это тот же цикл, что и раньше: модель анализирует задачу, формирует команду, например запрос к API погоды, и останавливается. Агент обнаруживает эту команду, запускает соответствующий инструмент и возвращает результат в виде наблюдения. Используя этот результат, модель либо продолжает анализировать ситуацию, либо принимает новую действие, либо выдает окончательный ответ.
Исторически действия выражались в виде вызовов функций или JSON-объектов, в которых указывались инструмент и его аргументы. Этот подход срабатывает, но становится неудобным, когда в рабочем процессе требуется множество вызовов инструментов. Код-агенты используют другой подход: вместо описания действий в JSON модель генерирует исполняемый Python-код. Таким образом циклы, условия, переменные и несколько вызовов инструментов могут разделить один блок кода, что делает его более выразительным и эффективным для сложных задач.
Традиционный формат JSON выглядит следующим образом:
{
"tool": "get_weather",
"arguments": {"location": "Tokyo"}
}
Вместо этого агент кода пишет исполняемый фрагмент:
# The agent writes actual Python code as its action
cities = ["Tokyo", "Paris", "New York", "London", "Sydney"]
temps = [get_weather(city) for city in cities]
avg_temp = sum(temps) / len(temps)
print(f"Average temperature: {avg_temp}")
Наблюдения: обратная связь от каждого действия
Логические рассуждения и действия — это лишь половина картинки. После выполнения действия агент должен понять его результат, и именно для этого существуют наблюдения: обратная связь, получаемая после завершения действия. Это может быть результат поиска в интернете, ответ API, вывод программы на Python или даже сообщение об ошибке. Чем бы это ни было, это становится новой информацией для выбора следующего шага.
Процесс прост: агент выполняет действие, фреймворк его исполняет, а результат добавляется в диалог в качестве наблюдения. Язык больших моделей читает обновлённый контекст и продолжает работу. При наличии достаточно информации он даёт окончательный ответ. В противном случае он планирует другое действие.
Наблюдения не обязательно должны быть успешными. Когда запрос терпит неудачу — из-за сообщения 404 Not Found от конечной точки или ошибки в Python в генерируемом коде — эта неудача всё равно имеет ценность. Сообщение об ошибке показывает агенту, что пошло не так, чтобы его следующее действие могло исправить ситуацию вместо того, чтобы повторить ошибку.
Именно этот постоянный цикл делает агентов адаптивными. Вместо того чтобы полагаться только на заранее полученные знания, они собирают новые факты, учатся на результатах и совершенствуют свой подход до завершения задачи.
Собирание элементов воедино
Агенты могут казаться совершенно новой парадигмой, но на самом деле они возникают в результате сочетания нескольких простых идей. Модель языка анализирует проблему, системные указания формируют её поведение, инструменты расширяют её функционал за пределы текста, действия связывают её с внешним миром, а наблюдения предоставляют обратную связь для адаптации.
Понимание этих основных элементов и осознание того, насколько мало «магии» содержится в каждом из них, являются первым шагом к созданию собственных агентов. Помощники-программисты, коллеги-исследователи и автономные рабочие процессы все опираются на один и тот же цикл «Мышление — Действие — Наблюдение». Следующим логичным шагом становится создание первого агента с использованием экосистемы Hugging Face.