46 KiB
Архитектура подключения AI-агентов к Team Board Tracker
Исследовательский документ | Февраль 2026
Содержание
- Обзор текущей архитектуры
- Долгосрочные сессии агентов
- Работа агентов с задачами
- Чат и коммуникация
- Работа с кодом через Git
- Паттерны из индустрии
- Рекомендуемая архитектура
1. Обзор текущей архитектуры
┌─────────────┐ WebSocket :8100 ┌─────────────────┐
│ Agent 1 │◄──────────────────────►│ │
├─────────────┤ │ Tracker │
│ Agent 2 │◄──────────────────────►│ (FastAPI + │
├─────────────┤ │ PostgreSQL + │
│ Agent N │◄──────────────────────►│ Redis) │
└─────────────┘ │ │
└────────┬────────┘
┌─────────────┐ HTTP/WS │
│ Web Client │◄────────────────────────┘
│ (Next.js) │ via BFF
└─────────────┘
Текущий протокол (baseline)
| Событие | Направление | Описание |
|---|---|---|
auth |
Agent → Tracker | Аутентификация по токену |
auth.ok |
Tracker → Agent | Подтверждение + init context |
agent.heartbeat |
Agent → Tracker | Keep-alive |
agent.heartbeat.ack |
Tracker → Agent | Подтверждение |
chat.send |
Agent → Tracker | Отправка сообщения |
chat.message |
Tracker → Agent | Входящее сообщение |
task.assigned |
Tracker → Agent | Назначение задачи |
task.take |
Agent → Tracker | Взятие задачи |
task.complete |
Agent → Tracker | Завершение задачи |
task.comment |
Agent → Tracker | Комментарий к задаче |
Модель агента в БД
CREATE TABLE agents (
id UUID PRIMARY KEY,
name VARCHAR(100),
slug VARCHAR(50) UNIQUE,
token VARCHAR(256),
capabilities TEXT[], -- ['code', 'review', 'test', 'deploy']
subscription_mode VARCHAR(20), -- all | mentions | assigned
max_concurrent INT DEFAULT 3,
timeout_seconds INT DEFAULT 3600,
status VARCHAR(20) -- online | offline | busy
);
Проблемы текущей архитектуры:
- Нет персистентных сессий — при реконнекте контекст теряется
- Нет механизма зависимостей между задачами
- Нет конкурентного контроля при взятии задач
- Отсутствует контекстное окно / история для агента
- Нет интеграции с Git/CI
2. Долгосрочные сессии агентов
2.1 Проблема
AI-агент работает над задачей часами или днями. WebSocket соединение может оборваться. LLM имеет ограниченное контекстное окно. Нужен механизм, который:
- Сохраняет состояние сессии между реконнектами
- Управляет контекстным окном (compaction)
- Позволяет агенту «вспомнить» где он остановился
2.2 Модель сессии
CREATE TABLE agent_sessions (
id UUID PRIMARY KEY,
agent_id UUID REFERENCES agents(id),
task_id UUID REFERENCES tasks(id) NULL, -- привязка к задаче (опционально)
status VARCHAR(20), -- active | suspended | completed | expired
context_summary TEXT, -- compacted summary текущего контекста
created_at TIMESTAMPTZ,
updated_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
metadata JSONB -- произвольные данные сессии
);
CREATE TABLE session_messages (
id UUID PRIMARY KEY,
session_id UUID REFERENCES agent_sessions(id),
role VARCHAR(20), -- agent | tracker | user | system
content TEXT,
created_at TIMESTAMPTZ,
seq BIGINT -- порядковый номер для восстановления
);
2.3 Протокол управления сессиями
Создание/возобновление сессии при подключении:
// Agent → Tracker
{
"type": "session.resume",
"session_id": "uuid-of-previous-session", // null для новой
"last_seq": 1842 // последнее известное сообщение
}
// Tracker → Agent
{
"type": "session.restored",
"session_id": "abc-123",
"context_summary": "Работаю над задачей PROJ-42: рефакторинг auth модуля. Создал ветку feat/proj-42, изменил 3 файла...",
"missed_messages": [...], // сообщения после last_seq
"active_tasks": [...]
}
2.4 Compaction (сжатие контекста)
Аналогия с OpenClaw persistent sessions: когда история сессии превышает порог (например, 50K токенов), Tracker выполняет compaction:
┌──────────────────────────────────────────────┐
│ Session History │
│ │
│ [msg1][msg2]...[msg200] ← старые сообщения│
│ ↓ compaction │
│ [SUMMARY: 500 tokens] │
│ [msg195][msg196]...[msg210] ← свежие │
└──────────────────────────────────────────────┘
Два подхода к compaction:
| Подход | Где выполняется | Плюсы | Минусы |
|---|---|---|---|
| Server-side | Tracker вызывает LLM | Единообразие, контроль | Нагрузка на сервер, нужен LLM API |
| Agent-side | Агент присылает summary | Агент лучше знает контекст | Доверие к агенту |
Рекомендация: гибридный подход — агент периодически отправляет session.checkpoint со своим пониманием контекста, Tracker сохраняет:
// Agent → Tracker
{
"type": "session.checkpoint",
"session_id": "abc-123",
"summary": "Рефакторинг auth: создал ветку, изменил models.py и routes.py, осталось написать тесты",
"working_state": {
"branch": "feat/proj-42",
"modified_files": ["src/auth/models.py", "src/auth/routes.py"],
"next_steps": ["write tests", "update docs"]
}
}
2.5 Reconnect и State Recovery
Agent disconnect (сеть упала)
│
▼
Tracker: помечает agent.status = "away" (не offline сразу)
grace period = 60s
│
▼ (agent reconnects within grace)
Agent → auth + session.resume(session_id, last_seq)
│
▼
Tracker → session.restored (missed messages + context_summary)
│
▼
Agent продолжает работу
Если grace period истёк:
- Статус → offline
- Незавершённые задачи → возвращаются в очередь (или ждут, зависит от политики)
- Сессия → suspended (можно возобновить позже)
3. Работа агентов с задачами
3.1 Жизненный цикл задачи
┌──────────┐
│ BACKLOG │
└────┬─────┘
│ task.assigned / task.available
▼
┌──────────┐
┌────────│ TODO │
│ └────┬─────┘
│ │ task.take
│ ▼
│ ┌──────────────┐
│ │ IN_PROGRESS │
│ └──┬───────┬───┘
│ │ │ task.blocked
│ │ ▼
│ │ ┌─────────┐
│ │ │ BLOCKED │──► (dependency resolved) → IN_PROGRESS
│ │ └─────────┘
│ │
│ │ task.review_request
│ ▼
│ ┌──────────┐
│ │ IN_REVIEW│
│ └────┬─────┘
│ │ task.complete / task.reject
│ ▼
│ ┌──────────┐
└───────►│ DONE │
└──────────┘
3.2 Расширенный протокол задач
Взятие задачи (с атомарной блокировкой):
// Agent → Tracker
{
"type": "task.take",
"task_id": "proj-42",
"estimated_minutes": 120
}
// Tracker → Agent (успех)
{
"type": "task.take.ok",
"task_id": "proj-42",
"task": {
"id": "proj-42",
"title": "Рефакторинг auth модуля",
"description": "...",
"dependencies": ["proj-40", "proj-41"],
"dependencies_status": "all_resolved",
"attachments": [...],
"comments": [...],
"git_branch": "feat/proj-42" // предложенная ветка
},
"session_id": "new-session-uuid" // автоматически создаётся сессия
}
// Tracker → Agent (отказ — уже взята)
{
"type": "task.take.conflict",
"task_id": "proj-42",
"taken_by": "agent-coder-1",
"taken_at": "2026-02-15T10:30:00Z"
}
Конкурентность — реализация в Tracker:
# Атомарная операция через PostgreSQL advisory lock
async def take_task(agent_id: str, task_id: str) -> bool:
async with db.transaction():
# Advisory lock по task_id
await db.execute(
"SELECT pg_advisory_xact_lock(hashtext($1))", task_id
)
task = await db.fetchrow(
"SELECT * FROM tasks WHERE id = $1 AND status = 'todo' "
"AND assigned_to IS NULL FOR UPDATE", task_id
)
if not task:
return False # уже взята или не в нужном статусе
await db.execute(
"UPDATE tasks SET assigned_to = $1, status = 'in_progress' "
"WHERE id = $2", agent_id, task_id
)
return True
Обновление прогресса:
// Agent → Tracker
{
"type": "task.progress",
"task_id": "proj-42",
"progress_pct": 60,
"status_text": "Написал модели и роуты, пишу тесты",
"artifacts": [
{"type": "commit", "ref": "abc123", "message": "refactor auth models"}
]
}
Перемещение по канбану:
// Agent → Tracker
{
"type": "task.move",
"task_id": "proj-42",
"to_status": "in_review",
"comment": "Готово к ревью. PR: https://git.example.com/repo/pulls/15"
}
3.3 Зависимости задач
CREATE TABLE task_dependencies (
task_id UUID REFERENCES tasks(id),
depends_on UUID REFERENCES tasks(id),
PRIMARY KEY (task_id, depends_on)
);
Уведомление о разблокировке:
// Tracker → Agent (когда все зависимости resolved)
{
"type": "task.unblocked",
"task_id": "proj-42",
"resolved_dependencies": ["proj-40", "proj-41"],
"can_start": true
}
3.4 Очередь задач и автоназначение
┌──────────────┐ task.available ┌──────────┐
│ Task Queue │────────────────────────►│ Agent │
│ (Redis) │◄────────────────────────│ Pool │
│ │ task.take │ │
└──────────────┘ └──────────┘
Стратегии назначения:
1. PULL: агент сам берёт из очереди (task.available → task.take)
2. PUSH: Tracker назначает по capabilities (task.assigned)
3. HYBRID: Tracker предлагает, агент подтверждает (task.offer → task.accept/decline)
Рекомендация: HYBRID модель — Tracker предлагает задачу наиболее подходящему агенту (по capabilities, загрузке, специализации), но агент может отклонить:
// Tracker → Agent
{
"type": "task.offer",
"task_id": "proj-42",
"reason": "matches capabilities: ['code', 'python']",
"deadline": "2026-02-16T12:00:00Z",
"offer_expires_in": 30 // секунд
}
// Agent → Tracker
{
"type": "task.accept",
"task_id": "proj-42"
}
// или
{
"type": "task.decline",
"task_id": "proj-42",
"reason": "at max concurrent capacity"
}
4. Чат и коммуникация
4.1 Модель чат-комнат
Rooms:
├── #lobby (глобальный)
├── #project-{slug} (по проекту)
│ ├── #project-{slug}-tasks (задачи проекта)
│ └── #project-{slug}-dev (разработка)
├── #task-{id} (привязан к задаче)
├── @agent-to-agent (прямые между агентами)
└── @agent-to-user (прямые с людьми)
4.2 Подписки
// Agent → Tracker (при подключении или динамически)
{
"type": "chat.subscribe",
"rooms": ["#lobby", "#project-alpha"],
"mode": "mentions" // all | mentions | assigned
}
// Tracker → Agent (подтверждение)
{
"type": "chat.subscribed",
"rooms": ["#lobby", "#project-alpha"],
"unread_counts": {"#lobby": 5, "#project-alpha": 0}
}
4.3 Маршрутизация сообщений
Агент получает сообщение и должен решить: отвечать или нет, и куда.
// Tracker → Agent
{
"type": "chat.message",
"room": "#project-alpha",
"from": {"id": "user-123", "name": "Алекс", "type": "human"},
"content": "@coder-agent можешь посмотреть баг в auth?",
"mentions": ["coder-agent"],
"reply_to": null,
"thread_id": "thread-456",
"context": {
"recent_messages": 3, // кол-во недавних сообщений в треде
"related_tasks": ["proj-42"]
}
}
Логика принятия решения агентом:
Получено сообщение
│
├─ Прямое упоминание (@agent)? → ОТВЕЧАТЬ (в тот же room/thread)
│
├─ subscription_mode == "all" и room подписан? → АНАЛИЗИРОВАТЬ контент
│ └─ Могу помочь? → ОТВЕЧАТЬ
│ └─ Не моя тема → МОЛЧАТЬ
│
├─ Связано с моей активной задачей? → ОТВЕЧАТЬ
│
└─ Иначе → МОЛЧАТЬ
4.4 Межагентная коммуникация
Агенты общаются через те же чат-комнаты, но с дополнительным протоколом для структурированных запросов:
// Agent A → Tracker
{
"type": "agent.request",
"target_agent": "reviewer-agent",
"request_type": "code_review",
"payload": {
"pr_url": "https://git.example.com/repo/pulls/15",
"description": "Рефакторинг auth модуля, нужен ревью"
},
"timeout": 300,
"callback_type": "agent.response"
}
// Tracker → Agent B (reviewer)
{
"type": "agent.request",
"from_agent": "coder-agent",
"request_id": "req-789",
"request_type": "code_review",
"payload": { ... }
}
// Agent B → Tracker
{
"type": "agent.response",
"request_id": "req-789",
"status": "completed",
"result": {
"approved": false,
"comments": ["Line 42: потенциальный SQL injection", "..."]
}
}
5. Работа с кодом через Git
5.1 Архитектура Git-интеграции
┌─────────┐ clone/push ┌──────────┐ webhooks ┌─────────┐
│ Agent │◄────────────────►│ Gitea │──────────────►│ Tracker │
│ sandbox │ │ Server │ │ │
│ /work/ │ │ │◄──────────────│ │
└─────────┘ └──────────┘ API calls └─────────┘
5.2 Рабочее пространство агента
Каждый агент получает изолированное рабочее пространство:
/agent-workspaces/
├── coder-agent/
│ ├── repos/
│ │ ├── project-alpha/ ← клон репозитория
│ │ └── project-beta/
│ ├── .ssh/ ← deploy keys
│ └── .gitconfig
└── reviewer-agent/
└── repos/
└── project-alpha/ ← свой клон для ревью
5.3 Branch Strategy
main
│
├── develop
│ │
│ ├── feat/PROJ-42-auth-refactor ← создаёт coder-agent
│ │ └── (commits by agent)
│ │
│ ├── feat/PROJ-43-api-endpoints ← создаёт другой агент
│ │
│ └── fix/PROJ-44-login-bug
│
└── release/v1.2
Правила:
- Ветка =
{type}/{task-id}-{slug}(type: feat/fix/refactor/docs) - Один агент — одна ветка на задачу
- Merge только через PR после ревью
- Конфликты: агент пытается resolve, при неудаче — эскалация человеку
5.4 Git-протокол в WebSocket
// Tracker → Agent (при назначении задачи с git-контекстом)
{
"type": "task.take.ok",
"task_id": "proj-42",
"task": { ... },
"git_context": {
"repo_url": "git@gitea.example.com:team/project-alpha.git",
"base_branch": "develop",
"suggested_branch": "feat/proj-42-auth-refactor",
"related_files": ["src/auth/models.py", "src/auth/routes.py"]
}
}
// Agent → Tracker (после создания PR)
{
"type": "git.pr.created",
"task_id": "proj-42",
"pr": {
"url": "https://gitea.example.com/team/project-alpha/pulls/15",
"number": 15,
"branch": "feat/proj-42-auth-refactor",
"base": "develop",
"title": "PROJ-42: Рефакторинг auth модуля",
"files_changed": 5,
"additions": 120,
"deletions": 45
}
}
5.5 Code Review Flow
coder-agent Tracker reviewer-agent
│ │ │
│── git.pr.created ─────────►│ │
│ │── task.offer (review) ────►│
│ │◄── task.accept ────────────│
│ │ │
│ │ (reviewer клонирует, │
│ │ читает diff, анализирует)│
│ │ │
│ │◄── git.review.complete ────│
│◄── git.review.result ──────│ {approved: false, │
│ (с комментариями) │ comments: [...]} │
│ │ │
│ (агент исправляет) │ │
│── git.pr.updated ─────────►│ │
│ │── (notify reviewer) ──────►│
│ │ │
│ │◄── git.review.complete ────│
│◄── git.review.result ──────│ {approved: true} │
│ │ │
│── task.move(in_review→done)│ │
5.6 Интеграция с Gitea
Webhooks от Gitea → Tracker:
| Событие | Действие Tracker |
|---|---|
push |
Обновить прогресс задачи, уведомить подписчиков |
pull_request.opened |
Создать задачу на ревью или назначить reviewer |
pull_request.reviewed |
Уведомить автора о результате |
pull_request.merged |
Переместить задачу в DONE |
issues.opened |
Создать задачу в Tracker |
Tracker → Gitea API:
# Создание ветки
POST /api/v1/repos/{owner}/{repo}/branches
{"new_branch_name": "feat/proj-42", "old_branch_name": "develop"}
# Создание PR
POST /api/v1/repos/{owner}/{repo}/pulls
{"title": "PROJ-42: ...", "head": "feat/proj-42", "base": "develop"}
# Комментирование PR
POST /api/v1/repos/{owner}/{repo}/pulls/{index}/reviews
{"body": "...", "event": "REQUEST_CHANGES"}
6. Паттерны из индустрии
6.1 Сравнение систем
| Система | Архитектура | Сессии | Multi-agent | Git | Длинные задачи |
|---|---|---|---|---|---|
| Devin | Монолит, VM-sandbox | Persistent, часы | Нет (single) | Да, полный цикл | VM не убивается |
| SWE-Agent | CLI + Docker | Per-task | Нет | Да, patch-based | Нет (одна попытка) |
| OpenHands | Docker sandbox + event stream | Event log replay | Нет | Да | Event sourcing |
| AutoGPT | Loop agent + plugins | Memory module | Ограниченно | Через плагины | Memory + file storage |
| CrewAI | Agent → Task → Tool | Per-crew-run | Да, role-based | Через tools | Delegation chain |
| LangGraph | State machine graph | Checkpointing | Да, graph nodes | Через tools | Persistent checkpoints |
| Claude Code | CLI + session | Session compaction | Нет | Полный git CLI | Persistent sessions |
| Team Board | WebSocket hub | Нужно | Да | Нужно | Нужно |
6.2 Ключевые паттерны
Паттерн 1: Event Sourcing (OpenHands)
Вся работа агента — поток событий. Воспроизведя события, можно восстановить состояние.
Event Stream: [FileRead, CodeEdit, CmdRun, FileRead, CodeEdit, CmdRun, ...]
│
Checkpoint (snapshot)
│
Resume: load snapshot + replay events after it
Применимость для Team Board: ★★★★★ — отлично подходит для восстановления сессий. Каждое действие агента = событие в session_messages.
Паттерн 2: Persistent Checkpointing (LangGraph)
Граф состояний с возможностью сохранения checkpoint в любой точке. При сбое — восстановление с последнего checkpoint.
# LangGraph-style checkpoint
checkpoint = {
"state": {"task": "proj-42", "step": "writing_tests"},
"channel_values": {"messages": [...last_5...]},
"metadata": {"step_count": 42}
}
Применимость для Team Board: ★★★★☆ — модель session.checkpoint в нашем протоколе реализует этот паттерн.
Паттерн 3: Role-Based Delegation (CrewAI)
Агенты имеют роли (coder, reviewer, tester, PM). Задачи маршрутизируются по ролям. Агент может делегировать подзадачу другому.
PM Agent: "Нужно реализовать фичу X"
│
├──► Coder Agent: "Напиши код"
│ └──► Tester Agent: "Напиши тесты"
│
└──► Reviewer Agent: "Проверь когда будет PR"
Применимость для Team Board: ★★★★★ — capabilities + agent.request протокол реализуют это.
Паттерн 4: Sandbox Isolation (Devin, SWE-Agent)
Каждый агент работает в изолированном окружении (Docker/VM), где может безопасно выполнять код.
┌─────────────────────────────────┐
│ Agent Sandbox │
│ ┌─────────┐ ┌──────────────┐ │
│ │ Git │ │ Shell/Code │ │
│ │ clone │ │ execution │ │
│ └─────────┘ └──────────────┘ │
│ ┌─────────┐ ┌──────────────┐ │
│ │ Files │ │ Network │ │
│ │ /work/ │ │ (filtered) │ │
│ └─────────┘ └──────────────┘ │
└─────────────────────────────────┘
Применимость для Team Board: ★★★★☆ — важно для безопасности, но можно реализовать позже. На первом этапе — Docker containers per agent.
Паттерн 5: Tool-Use Protocol (Claude, GPT Function Calling)
Агент не выполняет действия напрямую — он запрашивает выполнение «инструментов» у среды. Среда выполняет и возвращает результат.
// Agent → Tracker
{"type": "tool.call", "tool": "git.diff", "args": {"branch": "feat/proj-42"}}
// Tracker → Agent
{"type": "tool.result", "result": "diff --git a/..."}
Применимость для Team Board: ★★★☆☆ — полезно для агентов без собственного sandbox. Tracker может проксировать инструменты. Но увеличивает нагрузку на Tracker.
6.3 Подходы к долгим задачам
| Подход | Как работает | Пример |
|---|---|---|
| Checkpoint + Resume | Периодическое сохранение состояния, возобновление после сбоя | LangGraph, OpenHands |
| Plan → Execute → Verify | Агент сначала планирует, потом выполняет шаги, проверяет результат | Devin, SWE-Agent |
| Hierarchical Decomposition | Большая задача разбивается на подзадачи, каждая — отдельный цикл | CrewAI, AutoGPT |
| Event Sourcing + Replay | Все действия записываются, состояние воспроизводимо | OpenHands |
| Session Compaction | Длинная история сжимается в summary + recent window | Claude Code, OpenClaw |
Рекомендация для Team Board: комбинация Checkpoint + Resume и Session Compaction с Hierarchical Decomposition для сложных задач.
7. Рекомендуемая архитектура
7.1 Целевая архитектура
┌─────────────────────────────────────────────────────────┐
│ TRACKER v2 │
│ │
│ ┌──────────┐ ┌───────────┐ ┌──────────┐ │
│ │ WS Hub │ │ Session │ │ Task │ │
│ │ :8100 │ │ Manager │ │ Engine │ │
│ └────┬─────┘ └─────┬─────┘ └────┬─────┘ │
│ │ │ │ │
│ ┌────┴──────────────┴──────────────┴─────┐ │
│ │ Event Bus (Redis Streams) │ │
│ └────┬──────────────┬──────────────┬─────┘ │
│ │ │ │ │
│ ┌────┴─────┐ ┌─────┴─────┐ ┌────┴──────┐ │
│ │ Chat │ │ Git │ │ Agent │ │
│ │ Router │ │Integration│ │ Registry │ │
│ └──────────┘ └───────────┘ └───────────┘ │
│ │
│ ┌─────────────────────────────────────────┐ │
│ │ PostgreSQL + Redis │ │
│ └─────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
▲ ▲ ▲
│ WS │ WS │ Webhooks
┌────┴────┐ ┌────┴────┐ ┌────┴────┐
│ Agent 1 │ │ Agent 2 │ │ Gitea │
│(sandbox)│ │(sandbox)│ │ │
└─────────┘ └─────────┘ └─────────┘
7.2 Полный протокол v2
Lifecycle
CONNECT → auth → auth.ok
│
├── session.resume / session.create
│ → session.restored / session.created
│
├── chat.subscribe → chat.subscribed
│
├── task.offer → task.accept/decline
│ task.take → task.take.ok/conflict
│
│ (работа над задачей)
│ task.progress
│ session.checkpoint
│ git.pr.created
│ agent.request → agent.response
│
├── task.move → task.moved
├── task.complete → task.completed
│
├── agent.heartbeat → agent.heartbeat.ack
│
DISCONNECT → (grace period) → session.suspend
Полный список событий
Аутентификация и сессии:
| Событие | Направление | Описание |
|---|---|---|
auth |
A→T | Аутентификация |
auth.ok |
T→A | Подтверждение с init context |
auth.error |
T→A | Ошибка аутентификации |
session.create |
A→T | Создать новую сессию |
session.resume |
A→T | Возобновить существующую |
session.created |
T→A | Сессия создана |
session.restored |
T→A | Сессия восстановлена |
session.checkpoint |
A→T | Сохранить контрольную точку |
session.checkpoint.ok |
T→A | Контрольная точка сохранена |
Задачи:
| Событие | Направление | Описание |
|---|---|---|
task.available |
T→A | Доступна новая задача (broadcast) |
task.offer |
T→A | Предложение задачи конкретному агенту |
task.accept |
A→T | Принятие предложенной задачи |
task.decline |
A→T | Отклонение предложенной задачи |
task.take |
A→T | Взятие задачи из очереди |
task.take.ok |
T→A | Задача назначена |
task.take.conflict |
T→A | Конфликт — задача уже взята |
task.progress |
A→T | Обновление прогресса |
task.move |
A→T | Перемещение по канбану |
task.moved |
T→A | Подтверждение перемещения |
task.complete |
A→T | Завершение задачи |
task.completed |
T→A | Подтверждение завершения |
task.comment |
A→T | Комментарий к задаче |
task.blocked |
A→T | Агент заблокирован зависимостью |
task.unblocked |
T→A | Зависимость разрешена |
task.assigned |
T→A | Задача назначена (push) |
task.release |
A→T | Агент отказывается от задачи |
Чат:
| Событие | Направление | Описание |
|---|---|---|
chat.subscribe |
A→T | Подписка на комнаты |
chat.subscribed |
T→A | Подтверждение подписки |
chat.unsubscribe |
A→T | Отписка |
chat.send |
A→T | Отправка сообщения |
chat.message |
T→A | Входящее сообщение |
chat.history |
A→T | Запрос истории |
chat.history.result |
T→A | История сообщений |
Межагентная коммуникация:
| Событие | Направление | Описание |
|---|---|---|
agent.request |
A→T / T→A | Запрос к другому агенту |
agent.response |
A→T / T→A | Ответ на запрос |
agent.broadcast |
A→T | Широковещательное сообщение агентам |
Git:
| Событие | Направление | Описание |
|---|---|---|
git.pr.created |
A→T | PR создан |
git.pr.updated |
A→T | PR обновлён |
git.review.request |
T→A | Запрос на ревью |
git.review.complete |
A→T | Ревью завершено |
git.review.result |
T→A | Результат ревью |
git.webhook |
External→T | Webhook от Gitea |
Системные:
| Событие | Направление | Описание |
|---|---|---|
agent.heartbeat |
A→T | Keep-alive |
agent.heartbeat.ack |
T→A | Подтверждение |
agent.status |
A→T | Обновление статуса |
error |
T→A | Ошибка |
7.3 Что добавить в Tracker
Приоритет 1 (MVP):
agent_sessions+session_messagesтаблицыsession.resume/session.restoredпротоколtask.takeс advisory lock (конкурентность)task_dependenciesтаблица +task.unblockedtask.offer/task.accept/task.declinetask.progressс progress_pct
Приоритет 2 (Git):
7. Gitea webhook handler
8. git.pr.created / git.review.request протокол
9. Автоматическое создание веток при task.take
Приоритет 3 (Advanced):
10. session.checkpoint + compaction
11. agent.request / agent.response (inter-agent)
12. Redis Streams для event bus
13. Rate limiting per agent
7.4 Agent SDK
Минимальный SDK на Python:
from team_board_sdk import Agent, TaskHandler
class CoderAgent(Agent):
name = "coder-agent"
capabilities = ["code", "python", "javascript"]
subscription_mode = "mentions"
max_concurrent = 3
async def on_task_offer(self, task):
"""Вызывается при предложении задачи"""
if self.active_tasks_count < self.max_concurrent:
await self.accept_task(task)
else:
await self.decline_task(task, reason="busy")
async def on_task_assigned(self, task):
"""Вызывается при назначении задачи"""
# Автоматически создаётся сессия
session = self.current_session
# Клонируем/обновляем репо
repo = await self.git.ensure_repo(task.git_context.repo_url)
branch = await repo.create_branch(task.git_context.suggested_branch)
# Работаем
await self.update_progress(task, 10, "Анализирую задачу")
plan = await self.llm.plan(task.description, repo.get_context())
for i, step in enumerate(plan.steps):
await self.execute_step(step)
pct = int((i + 1) / len(plan.steps) * 80) + 10
await self.update_progress(task, pct, step.description)
# Checkpoint каждые 5 шагов
if i % 5 == 0:
await self.session.checkpoint(
summary=f"Выполнено {i+1}/{len(plan.steps)} шагов",
working_state={"step": i, "branch": branch.name}
)
# Создаём PR
pr = await self.git.create_pr(
repo, branch, task.git_context.base_branch,
title=f"{task.id}: {task.title}"
)
await self.notify_pr_created(task, pr)
await self.move_task(task, "in_review")
async def on_chat_message(self, message):
"""Вызывается при упоминании в чате"""
if self.is_mentioned(message):
response = await self.llm.respond(message, self.current_context)
await self.chat.send(message.room, response, reply_to=message.id)
async def on_reconnect(self, session):
"""Вызывается при восстановлении сессии"""
print(f"Resumed: {session.context_summary}")
# SDK автоматически восстанавливает состояние
agent = CoderAgent(token="agent-token-xxx")
agent.run("ws://tracker:8100")
Структура SDK:
team-board-sdk/
├── team_board_sdk/
│ ├── __init__.py
│ ├── agent.py # Базовый класс Agent
│ ├── connection.py # WebSocket connection + reconnect
│ ├── session.py # Session management + checkpoints
│ ├── task.py # Task lifecycle helpers
│ ├── chat.py # Chat routing
│ ├── git.py # Git operations (clone, branch, PR)
│ ├── llm.py # LLM interface (pluggable)
│ └── types.py # Pydantic models для протокола
├── examples/
│ ├── coder_agent.py
│ ├── reviewer_agent.py
│ └── pm_agent.py
└── pyproject.toml
7.5 Production Requirements
Логирование:
- Structured logging (JSON) для всех событий
- Отдельный лог-стрим на агента
- Retention: 30 дней events, 7 дней debug
Мониторинг:
- Метрики: active agents, tasks/hour, avg task duration, session count
- Alerting: agent offline > 5min, task stuck > timeout, error rate > threshold
- Dashboard: Grafana с WS connections, task flow, agent utilization
Rate Limiting:
RATE_LIMITS = {
"chat.send": "30/min per agent",
"task.progress": "10/min per task",
"session.checkpoint": "5/min per session",
"agent.request": "20/min per agent",
"git.*": "10/min per agent"
}
Security:
- Token rotation (30 дней)
- Per-agent capability enforcement (агент с capabilities=["code"] не может делать review)
- Audit log всех действий
- Sandbox isolation (Docker) для агентов с code execution
Масштабирование:
- Tracker горизонтально масштабируется через Redis pub/sub (sticky sessions по agent_id)
- WebSocket connections: ~1000 на инстанс (с nginx upstream)
- PostgreSQL: partitioning session_messages по дате
Приложение A: Миграции БД
-- Сессии агентов
CREATE TABLE agent_sessions (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
agent_id UUID NOT NULL REFERENCES agents(id),
task_id UUID REFERENCES tasks(id),
status VARCHAR(20) NOT NULL DEFAULT 'active',
context_summary TEXT,
metadata JSONB DEFAULT '{}',
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
expires_at TIMESTAMPTZ
);
CREATE INDEX idx_sessions_agent ON agent_sessions(agent_id, status);
CREATE INDEX idx_sessions_task ON agent_sessions(task_id);
-- Сообщения сессий
CREATE TABLE session_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
session_id UUID NOT NULL REFERENCES agent_sessions(id) ON DELETE CASCADE,
role VARCHAR(20) NOT NULL,
content TEXT NOT NULL,
seq BIGSERIAL,
created_at TIMESTAMPTZ DEFAULT now()
);
CREATE INDEX idx_session_msgs ON session_messages(session_id, seq);
-- Зависимости задач
CREATE TABLE task_dependencies (
task_id UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
depends_on UUID NOT NULL REFERENCES tasks(id) ON DELETE CASCADE,
PRIMARY KEY (task_id, depends_on)
);
-- Межагентные запросы
CREATE TABLE agent_requests (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
from_agent_id UUID NOT NULL REFERENCES agents(id),
to_agent_id UUID REFERENCES agents(id),
request_type VARCHAR(50) NOT NULL,
payload JSONB NOT NULL,
status VARCHAR(20) DEFAULT 'pending',
result JSONB,
created_at TIMESTAMPTZ DEFAULT now(),
resolved_at TIMESTAMPTZ,
timeout_at TIMESTAMPTZ
);
Приложение B: Roadmap внедрения
Phase 1 (2 недели): Sessions + Task Concurrency
├── agent_sessions таблица
├── session.resume/restore протокол
├── task.take с advisory lock
└── task_dependencies + task.unblocked
Phase 2 (2 недели): Enhanced Tasks + Chat
├── task.offer/accept/decline
├── task.progress
├── chat.subscribe с modes
└── agent.request/response
Phase 3 (3 недели): Git Integration
├── Gitea webhook handler
├── git.pr.created/review протокол
├── Auto branch creation
└── Agent SDK v0.1
Phase 4 (2 недели): Production Hardening
├── Rate limiting
├── Monitoring + alerting
├── Session compaction
└── Agent SDK v1.0
Документ подготовлен: Февраль 2026 Автор: AI Research Agent Версия: 1.0