Архитектура AI-агента
Из чего состоит агент, как работает цикл принятия решений и почему оркестрация — это главный навык.
← AI-агенты · Паттерны → · 🇬🇧 English
Содержание
1. Компоненты агента
Любой AI-агент, независимо от сложности, состоит из четырёх обязательных компонентов:
┌──────────────────────────────────────────────────────────┐
│ AI-АГЕНТ │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌────────────────┐ │
│ │ LLM │ │ Инструменты │ │ Оркестратор │ │
│ │ (мозг) │ │ (руки) │ │ (управление) │ │
│ └──────┬───────┘ └──────┬───────┘ └───────┬─────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ Принимает Вызывает функции, Управляет │
│ решения API, читает файлы, циклом, │
│ ищет в интернете state, память │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ Память (state) │ │
│ │ История шагов · Контекст · Результаты │ │
│ └──────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────┘
1.1 LLM — модель принятия решений
Модель — это «мозг» агента. Она не генерирует ответ пользователю напрямую — она решает, что делать дальше.
У агента модель выполняет три роли:
| Роль | Что делает | Пример решения |
|---|---|---|
| Reasoner | Анализирует ситуацию и планирует | «Пользователь спросил про погоду. Нужно вызвать API погоды» |
| Decider | Выбирает следующий шаг | «У меня есть результат из API — можно ответить» |
| Generator | Формулирует финальный ответ | «Сейчас в Токио +22°C, ясно» |
Для локальных агентов используются те же модели, что и для чата, но есть нюансы:
- Tool calling — модель должна поддерживать function calling (Qwen 3.5+, Llama 3.1+)
- Structured output — модель должна уметь возвращать JSON по схеме
- Длинный контекст — цикл агента быстро заполняет контекст, нужно 32K+ токенов
Как настроить model для агента: ollama-for-agents.md
1.2 Инструменты (Tools)
Инструменты — это функции, которые модель может вызывать. Они расширяют возможности модели за пределы её знаний.
Типы инструментов:
| Тип | Пример | Для чего агенту |
|---|---|---|
| Поиск | Web search, векторный поиск | Найти актуальную информацию |
| Чтение | Чтение файлов, PDF, сайтов | Получить данные для анализа |
| Запись | Создание файлов, отправка писем | Действовать в системе |
| Вычисления | Калькулятор, код Python | Точные расчёты |
| API | Вызов внешних сервисов | Интеграция с другими системами |
| Коммуникация | Telegram, Slack, email | Общение с людьми |
Каждый инструмент описывается JSON Schema — модель «читает» описание и решает, когда и с какими аргументами его вызвать.
tool = {
"type": "function",
"function": {
"name": "search_web",
"description": "Поиск информации в интернете",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "Поисковый запрос"}
},
"required": ["query"]
}
}
}
1.3 Оркестратор (цикл управления)
Оркестратор — это код, который управляет последовательностью: отправить запрос модели → получить решение → выполнить инструмент → вернуть результат модели → повторить.
Это и есть моя работа как Sisyphus. Оркестратор решает:
- Когда передать управление инструменту
- Когда вернуть ответ пользователю
- Когда остановиться (лимит шагов, времени, токенов)
- Что делать при ошибке (retry, fallback, сообщить пользователю)
- Как организовать параллельную работу нескольких агентов
1.4 Память (State)
Агент должен помнить, что он уже сделал, чтобы не ходить по кругу. Подробно — в memory.ru.md, но кратко:
| Тип памяти | Хранит | Пример |
|---|---|---|
| Short-term | Текущий диалог с моделью | Все сообщения в цикле |
| Long-term | Информацию между сессиями | Векторная БД с проектами |
| Working | Текущее состояние задачи | Какой шаг выполняется сейчас |
2. Цикл агента (Agent Loop)
Это самое важное. Понимание цикла — это понимание агентов.
Базовый цикл
┌──────────┐
│ НАЧАЛО │
└────┬─────┘
│
▼
┌──────────┐ ┌─────────────┐
│ LLM │────▶│ Нужен │
│ решает │ │ инструмент? │
└──────────┘ └──────┬──────┘
▲ │ ┌──────────┐
│ ┌──────┤ ДА ───▶│ Вызов │
│ │ │ │ инструм. │
│ │ │ └────┬─────┘
│ │ │ │
│ │ │ ▼
│ │ │ ┌──────────┐
│ │ │ │ Результат│
│ │ │ └────┬─────┘
│ │ │ │
│ │ └──────────────┘
│ │
│ ┌────┴────┐
│ │ НЕТ │
│ ▼ │
│ ┌────────┐ │
└──┤ ОТВЕТ │◄───┘
│ польз. │
└────────┘
Пошагово:
- Пользователь отправляет запрос → система добавляет его в историю
- LLM получает всю историю (системный промпт + все предыдущие шаги)
- LLM решает: ответить текстом ИЛИ вызвать инструмент
- Если инструмент:
- Система выполняет функцию с аргументами от LLM
- Результат добавляется в историю как observation
- Возврат к шагу 2
- Если ответ: текст возвращается пользователю
Реализация цикла на Python (без фреймворков)
import requests
import json
def agent_loop(model: str, user_input: str, tools: list, max_steps: int = 10):
"""
Простейший цикл агента.
model — имя модели в Ollama
tools — список инструментов в формате JSON Schema
"""
messages = [
{"role": "system", "content": "Ты — полезный ассистент. Используй инструменты когда нужно."},
{"role": "user", "content": user_input}
]
for step in range(max_steps):
# Шаг 1: спросить модель
response = requests.post("http://localhost:11434/api/chat", json={
"model": model,
"messages": messages,
"tools": tools,
"stream": False
})
data = response.json()
msg = data["message"]
messages.append(msg)
# Шаг 2: модель хочет вызвать инструмент?
if msg.get("tool_calls"):
for tc in msg["tool_calls"]:
func_name = tc["function"]["name"]
args = tc["function"]["arguments"]
print(f" ▶ Шаг {step+1}: вызываю {func_name}({args})")
# Шаг 3: выполняем функцию (в реальности — lookup по имени)
result = execute_tool(func_name, args)
# Шаг 4: результат → в историю
messages.append({
"role": "tool",
"name": func_name,
"content": json.dumps(result)
})
else:
# Модель решила ответить
return msg["content"]
return "Достигнут лимит шагов"
Этот код — буквально ядро любого агента. LangGraph, CrewAI, Agno — все они внутри делают то же самое, но с дополнительными плюшками (графы, память, параллелизм).
Почему без фреймворка?
Написать цикл вручную хотя бы раз критически важно, потому что:
- Вы понимаете, что происходит «под капотом» фреймворка
- Можете отлаживать, когда что-то идёт не так
- Не зависите от абстракций, которые скрывают важные детали
- Можете добавить свою логику (паузы, условия, логирование)
3. State и память
Состояние (state) агента — это вся информация, которая накоплена за время его работы.
Что входит в state
agent_state = {
"messages": [], # Вся переписка с LLM
"step": 0, # Текущий шаг цикла
"max_steps": 10, # Лимит шагов
"tools_used": [], # История вызовов инструментов
"errors": [], # Ошибки
"intermediate_results": {}, # Промежуточные результаты
"plan": [], # План (если есть)
"user_intent": "", # Исходный запрос пользователя
}
Как фреймворки управляют state
LangGraph — StateGraph с типизированным состоянием:
class AgentState(TypedDict):
messages: Annotated[list, add_messages] # автоматическое добавление
next_agent: str
CrewAI — каждый агент имеет внутреннее состояние (роль, цель, память).
Agno — session_state для хранения данных между запусками.
Проблемы с состоянием
| Проблема | Почему возникает | Решение |
|---|---|---|
| Контекст переполняется | Каждый шаг добавляет токены | Лимит шагов, компрессия |
| Потеря контекста | Модель «забывает» начало диалога | Суммаризировать историю |
| Противоречивые решения | Модель видит слишком много данных | Чистить контекст, держать фокус |
| Утечка данных | State хранит чувствительную информацию | Scoping, очистка после завершения |
4. Контекстное окно
Контекстное окно — главное ограничение агента. Каждый шаг цикла добавляет токены, и окно быстро заполняется.
Сколько токенов съедает цикл
| Действие | Токенов (примерно) |
|---|---|
| Системный промпт | 200–500 |
| Запрос пользователя | 50–200 |
| Решение модели (reasoning) | 200–1000 |
| Вызов инструмента (JSON) | 100–300 |
| + Результат инструмента | 200–5000 |
| Один шаг цикла | ~500–5000 токенов |
| 10 шагов | ~5000–50000 токенов |
На M1 16 GB с num_ctx: 4096 вы упрётесь в лимит уже на 3–5 шагах.
Решения
- Увеличить
num_ctx— если влезает в RAM (см. memory-and-context.ru.md) - Ограничить шаги —
max_steps=5для большинства задач хватает - Компрессия контекста — суммаризировать историю, когда она становится слишком длинной
- KV cache квантизация —
OLLAMA_KV_CACHE_TYPE=q4_0даёт 4× больше места
# Компрессия контекста: когда сообщений слишком много — суммаризируем
def compress_if_needed(messages, max_messages=20):
if len(messages) > max_messages:
# Берём системный промпт + последние N сообщений
system = messages[0]
recent = messages[-(max_messages-1):]
return [system] + recent
return messages
5. Оркестрация
Оркестрация — это то, чем я занимаюсь как Sisyphus. Один агент — это просто цикл. Несколько агентов, которые работают вместе — это оркестрация.
Уровни оркестрации
┌─────────────────────────────────────────────────────┐
│ ОРКЕСТРАТОР │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────────────┐ │
│ │ Агент 1 │ │ Агент 2 │ │ Агент 3 │ │
│ │ PM │ │ Аналитик │ │ Программист │ │
│ └────┬─────┘ └────┬─────┘ └───────┬──────────┘ │
│ │ │ │ │
│ └──────────────┴────────────────┘ │
│ │ │
│ Решают задачи, │
│ обмениваются результатами │
└─────────────────────────────────────────────────────┘
Что решает оркестратор:
- Кто из агентов берёт задачу
- В каком порядке работают агенты (последовательно / параллельно / иерархически)
- Как агенты обмениваются данными
- Что делать, если агент не справляется
- Когда задача считается выполненной
Как это реализовать:
# Простейший оркестратор — последовательный вызов агентов
def orchestrate(agents: list, task: str):
result = None
for agent in agents:
context = f"Предыдущий результат: {result}" if result else ""
result = agent.run(f"{task}\n{context}")
return result
Реальная оркестрация сложнее — она описана в multi-agent.ru.md и в туториале 02-agent-team.ru.md.
6. Что дальше
| Если хотите | Переходите | |————-|———–| | Изучить конкретные паттерны агентов (с кодом) | patterns.md | | Понимать, как агенты хранят информацию | memory.ru.md | | Увидеть, как это работает на фреймворках | frameworks.ru.md | | Написать первого агента руками | tutorials/01-first-agent.ru.md | | Вернуться к навигации | README.md | —
В разделе: architecture · evaluation · frameworks · memory · multi-agent · ollama-for-agents · orchestrators · patterns · prompting · ready-made · safety · skills
Связанные разделы: Нулевой уровень · Локальные модели · Use Cases · Ресурсы
Навигация: ← AI-агенты · ↑ На главную · 🇬🇧 English