3.8 KiB
3.8 KiB
Архитектура агентов
BaseAgent
Все агенты наследуются от BaseAgent:
class BaseAgent(ABC):
name: str # Уникальное имя агента
version: str = "1.0.0" # Текущая версия
description: str = "" # Описание для registry
triggers: list[AgentTrigger] # Когда запускается
async def run(self, context: dict | None = None) -> AgentResult:
"""Выполнить задачу агента."""
async def health_check(self) -> bool:
"""Проверить что агент работоспособен."""
def compute_checksum(self) -> str:
"""SHA256 от __file__ агента."""
def bump_version(self, version_type: str = "patch") -> str:
"""Увеличить версию (major/minor/patch)."""
Жизненный цикл
IDLE → RUNNING → [DONE | ERROR] → IDLE
↘ OFFLINE
- Агент запускается (триггер или вручную)
- Статус → RUNNING
- Выполняется
run(context) - Статус → IDLE (успех) или ERROR (ошибка)
- Результат сохраняется в AgentReport
AgentResult
class AgentResult:
success: bool # Успешно ли выполнен
message: str # Сообщение для лога
data: dict[str, Any] # Произвольные данные результата
errors: list[str] # Список ошибок
duration_ms: int # Время выполнения
timestamp: datetime # Когда выполнен
AgentRegistry
Регистрация всех агентов в едином реестре:
class AgentRegistry:
def register(self, agent: BaseAgent): ...
def get(self, name: str) -> BaseAgent | None: ...
def list_agents(self) -> list[dict]: ...
async def run_agent(self, name: str, context=None) -> AgentResult: ...
async def run_all(self, context=None) -> dict[str, AgentResult]: ...
Триггеры
| Триггер | Когда | Пример |
|---|---|---|
MANUAL |
Вручную из админки | Запуск DocAgent |
PRE_COMMIT |
Перед git commit | AuditAgent проверяет правила |
PUSH |
git push | SecurityAgent проверяет зависимости |
TAG_CREATION |
git tag | SpecAgent обновляет CHANGELOG |
CRON |
По расписанию | EvolutionAgent ежедневный анализ |
API |
Через API-endpoint | Запуск из админ-панели |
EVENT |
Событие в системе | FixAgent при ошибке |
Хранение промптов
Промпты агентов хранятся в docs/agent_prompts.yaml или в отдельных MD-файлах в docs/specs/agents/.
Загрузка через PromptLoader:
def get_prompt_config(role: str) -> dict | None:
# 1. Попробовать YAML (docs/agent_prompts.yaml)
# 2. Не найдено → загрузить из MD (docs/specs/agents/<role>.md)
# 3. Не найдено → None
[ASK] Вопросы по архитектуре
- Нужен ли AgentRegistry? (да, обязателен для SupervisorAgent)
- Хранить состояние агентов в БД или в памяти? (в БД для отказоустойчивости)
- Как передавать контекст агенту? (через
context: dict— гибко, но без типизации)