Архитектура
Обзор системы
AgentCore — мультиканальная AI-платформа, которая связывает messaging-каналы (WhatsApp Cloud API, Telegram) с RAG-базой знаний уровня отдела и автоматизированными approval-процессами.
┌─────────────┐ ┌─────────────┐
│ WhatsApp │ │ Telegram │
│ Cloud API │ │ (Grammy) │
└──────┬──────┘ └──────┬──────┘
│ │
▼ ▼
┌──────────────────────────────────┐
│ Fastify Server │
│ routes, auth, RBAC, dept scope │
└──────────────┬───────────────────┘
│
┌──────────┼──────────┬──────────────┐
▼ ▼ ▼ ▼
┌────────┐ ┌───────┐ ┌────────────┐ ┌────────────┐
│ Agent │ │ HITL │ │ Memory │ │ WebSocket │
│ Runner │ │Approve│ │ Extraction │ │ Events │
└───┬────┘ └───┬───┘ └─────┬──────┘ └─────┬──────┘
│ │ │ │
▼ ▼ ▼ ▼
┌──────────────────────────────────────────────────┐
│ PostgreSQL 16 + pgvector │
│ Redis 7 (BullMQ queues + rate-limit store) │
└──────────────────────────────────────────────────┘
Конвейер сообщений
ADR-001 делает agent-tasks основной границей выполнения для входящих сообщений. Channel workers становятся транспортными адаптерами: нормализуют входящее сообщение, сохраняют записи пользователя/разговора/сообщения, создают AgentTask и ставят его в очередь. Они больше не владеют решениями по RAG/HITL.
- Канал получает сообщение через webhook WhatsApp Cloud API или polling/webhook Telegram.
- Inbound-очередь канала (
wa-inboundилиtg-inbound) нормализует транспортный payload. - Inbound worker находит или создаёт пользователя и разговор, сохраняет сообщение пользователя, создаёт
AgentTaskи ставит его в очередьagent-tasks. - Agent executor worker обрабатывает задачу:
inject_profile— подгружает system prompt namespace и контекст профиля сотрудника;rag_search— запускаетOpenAiRagPipelineв проде или fallback-адаптер, выбранный namespace, в тестовом/адаптерном режиме;generate— формирует ответ для канала;confidence_check— управляет маршрутизацией injection guard, триггерами persona escalation, intent-классификацией, fallback по уверенности и обходом матрицы доверия.
- Результат маршрутизации сохраняется как строки
AgentToolCallи одно из:- авто-отправка через
wa-outboundилиtg-outbound; - создание pending
Approvalи перевод разговора вawaiting_approval; - отправка текста persona escalation и перевод разговора в
escalated.
- авто-отправка через
- При утверждении одобренный или отредактированный ответ ставится в outbound-очередь канала.
- Memory extraction запускается после настроенного интервала сообщений.
- WebSocket-события стримят жизненный цикл задачи в realtime (
agent-task.created,.started,.tool-call,.completed,.failed) с перепроверкой department scope на каждой доставке.
Архитектура компонентов
Fastify-приложение (src/app.ts)
App factory регистрирует компоненты в таком порядке:
- OpenAPI — Swagger и Swagger UI (
/docs) с префиксом сервера/api/v1. - Security-плагины — Helmet, CORS с точным origin, глобальный rate limit, JWT-аутентификация и
departmentScope. - Middleware — audit logger, идемпотентность и структурированный error handler.
- Background workers — очереди ingestion, memory extraction и agent executor.
- Маршруты — health, auth, knowledge, approvals, traces, namespaces, me, conversations, departments, users, roles, audit, RAG draft, employee profiles, intents, agent tasks, plugins, document templates и notifications в
/api/v1. - Каналы — плагины WhatsApp Cloud API и Telegram в
/api/v1. - Мониторинг — Bullboard admin UI (
/admin/queues) и WebSocket event bridges (/ws/agent-tasks,/ws/notifications).
Система плагинов
Fastify-плагины предоставляют:
- декоратор
authenticate— JWT verify hook (только Bearer header; WebSocket использует first-message auth handshake); - декоратор
departmentScope— per-requestDepartmentScopeизforDepartment(request.user); knowledgeIngestionQueue— BullMQ-очередь для обработки документов;memoryExtractionQueue— BullMQ-очередь для extraction профилей;agentTasksQueue— BullMQ-очередь для обработки agent tasks;channelService— абстракция конфигурации каналов, сейчас работает поверх env;broadcastAgentTaskEvent— хелпер WebSocket-бродкаста, перепроверяющий namespace department access перед каждой отправкой;pluginRegistry— реестр integration-плагинов namespace со встроенными OpenDataBot и webhook-плагинами;- notification-хелперы — persistent user-уведомления + WebSocket-доставка.
Архитектура очередей (BullMQ + Redis)
| Очередь | Назначение | Параллелизм |
|---|---|---|
agent-tasks | Обработка agent tasks через адаптеры | настраивается |
knowledge-ingest | Парсинг документов, чанкинг, embeddings | 1 |
memory-extraction | Extraction профилей из чатов | 1 |
wa-inbound | Обработка входящих WhatsApp | настраивается |
wa-outbound | Отправка WhatsApp | настраивается |
tg-inbound | Обработка входящих Telegram | настраивается |
tg-outbound | Отправка Telegram | настраивается |
Очередь agent-tasks использует 3 retry с exponential backoff (base delay 2s). Таймауты на адаптер: api — 30s, claude_local/codex_local — 300s, ollama — 120s. Stalled job detection автоматически ре-тригерит задачи при смерти воркера.
Все очереди используют exponential backoff для retry при обработке. Воркеры завершаются gracefully по SIGTERM/SIGINT.
Agent runner и adapter layer
Agent executor — канонический message-processing pipeline. Он сохраняет каждую задачу в AgentTask, пишет step-level прогресс в AgentToolCall и абстрагирует генерацию через pluggable adapter-интерфейс (AgentAdapter). Каждый namespace выбирает свой адаптер через config.agentRunner.activeAdapter.
Доступные адаптеры:
| Адаптер | Backend | Timeout |
|---|---|---|
api | OpenAI SDK (chat.completions.create) | 30s |
claude_local | Claude CLI (claude --print) | 300s |
codex_local | Codex CLI (codex exec --json) | 300s |
ollama | Ollama HTTP API (OpenAI-совместимый) | 120s |
Модель данных: каждая задача создаёт AgentTask с вложенными AgentToolCall, которые трекают inject_profile, rag_search, generate, confidence_check и любые adapter-level вызовы в fallback-режиме. Использование токенов, стоимость и длительность трекаются per-task.
См. Конфигурацию для настройки адаптера namespace.
Изоляция отдела
ADR-002 централизует department access через src/lib/department-scope.ts:
forDepartment(user)возвращаетDepartmentScope;scope.directWhere()scope-ит Prisma-модели с прямымdepartmentId;scope.nestedWhere('namespace')scope-ит модели вродеAgentTaskчерез связанные namespaces;scope.departmentIdиспользуется в raw SQL-фильтрах RAG;- admin-пользователи получают межотдельский доступ; все остальные роли ограничены
departmentIdиз JWT.
Fastify-плагин в src/plugins/department-scope.ts декорирует аутентифицированные запросы через request.departmentScope. REST-маршруты, RAG retrieval, agent runner и WebSocket-бродкасты используют один и тот же scope-примитив. Регрессионный тест tests/department-isolation.test.ts проверяет изоляцию list, detail, mutation, RAG, analytics и WebSocket.
Data flow: ingestion
Upload → Parse (PDF/DOCX/TXT/Image) → PII Scrub → Chunk → Embed → Synthetic Q&A → Store
Подробнее — в Знания и RAG.
Data flow: RAG-запрос
User Query → Injection Guard → Intent Classify → Embed Query
→ Vector Search (chunks + questions) + Keyword Search
→ Hybrid Score + Rank → Top-K Assembly
→ LLM Generation (with system prompt + history + profile)
→ PII Restore → Confidence Check → Bypass or HITL
Подробнее — в Знания и RAG.
Ключевые решения
Изоляция namespace
Каждый отдел владеет своими namespaces с настраиваемыми system prompts, персонами, правилами эскалации и trust-матрицами. Не-глобальные пользователи видят только данные в рамках namespace своего отдела.
Двухуровневая защита PII
- Ingest-time — односторонняя очистка до хранения чанков и embeddings.
- Conversation-time — обратимое AES-256-GCM шифрование с
PII_ENCRYPTION_KEY; LLM видит плейсхолдеры, ответы пользователю восстанавливают исходные значения.
Матрица доверия
Per-intent трекинг автономности. После достаточного количества успешных утверждений intent-а система начинает отправлять ответы автоматически (с настраиваемым sampling для continuous-валидации).
Гибридный retrieval
Комбинация vector- и keyword-поиска. По умолчанию: 65% vector + 35% keyword, внутри vector-бюджета — split между chunk-embeddings и synthetic question embeddings.