Перейти к содержанию

Архитектура Agent Lab

Agent Lab — это платформа для создания и управления ИИ-агентами на базе LangGraph, разработанная с использованием подхода Database-First. Это означает, что вся конфигурация и состояние системы хранятся в базе данных, а код определяет только логику поведения.

Принципы архитектуры

  1. Database-First: Вся конфигурация агентов, Flow и инструментов хранится в БД. Код определяет только поведение, но не структуру.
  2. Единообразие: Агенты, созданные через код и через пользовательский интерфейс, работают идентично.
  3. Фабричный паттерн: Все основные сущности (агенты, Flow, инструменты) создаются через соответствующие фабрики, которые загружают конфигурацию из БД (AgentFactory, FlowFactory, ToolFactory).
  4. Модульность: Каждый компонент системы независим и заменяем. Агенты не зависят от конкретной платформы (Telegram/WhatsApp/Web), а инструменты работают независимо от агентов.
  5. LangGraph-native: Активное использование современных возможностей библиотеки LangGraph для построения сложных графов состояний, управления памятью и точками восстановления (checkpointer, GraphInterrupt, State).
  6. Асинхронность: Вся архитектура полностью асинхронна. Используются async/await для всех операций с БД, HTTP, LLM. Все инструменты, фабрики и сервисы реализованы асинхронно.
  7. Контекст выполнения: Использование глобального контекста (app/core/context.py) для доступа к текущему пользователю, активной компании и переменным Flow, обеспечивая изоляцию данных и биллинг.

Ключевые компоненты

Storage (Key-Value База данных)

Низкоуровневое key-value хранилище на базе PostgreSQL, используемое для персистентности всех сущностей платформы. Доступ к данным осуществляется через стандартизированные репозитории.

Примеры ключей: - agent:{agent_id}: Конфигурация агентов. - flow:{flow_id}: Конфигурация Flow. - task:{task_id}: Задачи для обработки асинхронными воркерами. - session:{session_id}: Сессии диалогов. - user:{user_id}: Данные пользователей. - company:{company_id}: Данные компаний (мультитенантность). - subdomain:{subdomain}: Маппинг поддоменов к компаниям. - var:{key}: Глобальные и секретные переменные компании.

Расположение: app/db/database.py, app/db/repositories/*.py

Agents

Базовый строительный блок логики ИИ-бота. Агенты наследуются от BaseAgent и могут быть двух основных типов:

  1. ReAct-агенты: Классические реактивные агенты, основанные на промптах и использовании инструментов (tools) для принятия решений и выполнения действий.
  2. StateGraph-агенты: Агенты, построенные на LangGraph StateGraph, позволяющие создавать сложную, многошаговую логику с управлением состоянием, ветвлениями и циклами.

Ключевые аспекты: - Промпт: Основная инструкция для LLM, определяющая поведение агента. - Инструменты: Набор функций, которые агент может вызывать для взаимодействия с внешним миром или выполнения специфических задач. - Память: Агенты имеют доступ к полной истории диалога (через LangGraph checkpointer) и глобальным переменным Flow.

Расположение: - app/agents/base.py: Базовый класс для всех агентов. - app/agents/react_agent.py: Пример реализации ReAct-агента. - app/agents/stategraph_agent.py: Пример реализации StateGraph-агента. - app/agents/*: Директории с конкретными реализациями агентов (например, calculator, weather).

Flows

Flow — это административная обертка над одним или несколькими агентами, представляющая собой законченный сценарий или бота. Он определяет: - Entry Point Agent: Главный агент, который обрабатывает входящие запросы. - Каналы: Каналы, через которые Flow взаимодействует с пользователями (Telegram, API, Web, WhatsApp, AmoCRM). - Конфигурация: Общие настройки Flow (таймауты, количество повторов, RAG-настройки). - Переменные Flow: Переменные, доступные всем агентам внутри этого Flow.

Расположение: app/flows/flow.py

Tools

Инструменты — это асинхронные функции, которые агенты могут вызывать для выполнения конкретных действий. Они создаются с помощью специального декоратора @tool, который добавляет метаданные для биллинга и валидации.

Пример:

from app.core.tool_decorator import tool

@tool(cost=0.1, billing_name="weather_api")
async def get_weather(city: str) -> str:
    """Получить текущую погоду в указанном городе."""
    # Асинхронный вызов внешнего API погоды
    return f"Погода в {city}: солнечно"

Расположение: app/tools/*.py

Interfaces

Модули, ответственные за адаптацию специфичных для каждой платформы форматов сообщений к унифицированному внутреннему представлению Message, и наоборот. Это обеспечивает модульность и независимость агентов от каналов связи.

Основные интерфейсы: - TelegramInterface: Для взаимодействия с Telegram ботами. - WhatsAppInterface: Для интеграции с WhatsApp Business Cloud API. - APIInterface: Для взаимодействия через REST API. - WebInterface: Для встраиваемого веб-чата. - AmoCRMInterface: Для интеграции с AmoCRM.

Расположение: app/interfaces/*.py

Task Processor (Воркер задач)

Асинхронный фоновый воркер, который обрабатывает задачи, поставленные в очередь (например, входящие сообщения от пользователей). Он отвечает за: 1. Извлечение задач из БД со статусом pending. 2. Инициализацию соответствующего Flow и агента из его конфигурации. 3. Запуск выполнения графа LangGraph. 4. Обработку GraphInterrupt для запроса дополнительной информации у пользователя. 5. Отправку результатов обработки обратно через соответствующий Interface.

Расположение: app/workers/task_processor.py

Billing Service

Сервис, отвечающий за учет и тарификацию использования ресурсов (LLM-токены, вызовы инструментов) на уровне каждой компании. Поддерживает различные тарифные планы и лимиты расходов.

Расположение: app/services/billing_service.py

LLM Factory

Фабрика для создания экземпляров LLM-моделей. Обеспечивает единый унифицированный API для работы с различными провайдерами (OpenAI, Anthropic, Google и др.) через OpenRouter, а также автоматический учет токенов и биллинг.

Расположение: - app/core/llm_factory.py: Основная фабрика LLM. - app/core/llm_billing_wrapper.py: Обертка для биллинга LLM-запросов.

Identity System

Система управления пользователями и компаниями, обеспечивающая мультитенантность и авторизацию. Включает: - User: Модель пользователя. - Company: Модель компании (рабочего пространства). - AuthProvider: Интеграция с внешними провайдерами OAuth (например, Yandex, Google). - AuthSession: Управление сессиями авторизации.

Расположение: app/identity/*.py

Поток данных

1. Создание или обновление агента/Flow

graph LR
    A[Разработчик / UI] --> B{Создание/Обновление Agent/Flow в коде/UI}
    B --> C[Migrator (при старте/по запросу)]
    C --> D{Создание/Обновление AgentConfig/FlowConfig}
    D --> E[Storage (База данных)]

2. Обработка входящего запроса

graph LR
    A[Пользователь] --> B[Канал (Telegram/API/Web)]
    B --> C[Interface (TelegramInterface/APIInterface/WebInterface)]
    C --> D{Формирование Message}
    D --> E[FlowFactory (создает Task в БД)]
    E --> F[Storage (БД)]
    F --> G[TaskProcessor (воркер)]
    G --> H[AgentFactory (создает агента из БД)]
    H --> I[Агент (LangGraph)]
    I --> J{Результат обработки}
    J --> K[Interface (отправляет ответ)]
    K --> L[Канал] --> M[Пользователь]

3. Запрос дополнительной информации у пользователя

graph LR
    A[Агент (LangGraph)] --> B{Вызов ask_user(question)}
    B --> C[LangGraph (GraphInterrupt с вопросом)]
    C --> D[TaskProcessor (ловит interrupt)]
    D --> E[Interface (отправляет вопрос пользователю)]
    E --> F[Пользователь (отвечает)]
    F --> G[Interface (формирует Message с ответом)]
    G --> H[TaskProcessor (возобновляет граф с ответом)]
    H --> A

Миграция

Механизм автоматического сканирования кодовой базы и синхронизации конфигурации агентов и Flow с базой данных.

Процесс миграции: 1. При старте приложения Migrator сканирует директории app/agents/ и app/flows/. 2. Находит классы, наследующиеся от BaseAgent и BaseFlow. 3. Извлекает метаданные (название, промпт, инструменты, платформы) из этих классов. 4. Создает или обновляет соответствующие записи AgentConfig и FlowConfig в Storage (БД). 5. Если Flow или агент уже существуют в БД, Migrator обновляет их, сохраняя при этом пользовательские изменения (например, из UI), если они не конфликтуют с кодом.

Расположение: app/core/migrator.py

Контекст выполнения

Механизм contextvars для управления глобальным контекстом запроса в асинхронной среде. Это позволяет безопасно получать доступ к информации, специфичной для текущего запроса, без явной передачи параметров между функциями.

Использование:

from app.core.context import get_context

async def my_function():
    context = get_context() # Получаем текущий контекст
    user = context.user
    company = context.active_company
    flow_id = context.flow_id
    # ... использование данных контекста

Применение: - Изоляция данных: Обеспечивает, что каждый запрос обрабатывается в своем изолированном контексте, предотвращая утечки данных между разными пользователями или компаниями. - Биллинг: Позволяет системе биллинга точно определить, кто и сколько ресурсов потребил. - Авторизация: Упрощает проверку прав доступа к ресурсам.

Расположение: app/core/context.py

Веб-интерфейс (Frontend)

Пользовательский интерфейс платформы, реализованный на FastAPI и Jinja2 с использованием HTMX для динамического обновления контента. Включает в себя следующие основные модули: - Builder: Визуальный конструктор для создания и редактирования Flow. - Bots: Управление и настройка ботов. - Store: Магазин готовых Flow. - Chats: История диалогов. - History: Детальная статистика и логи запросов. - Variables: Управление переменными. - Billing: Мониторинг расходов. - Admin: Модуль для административных задач (управление компаниями, пользователями).

Расположение: app/frontend/

База данных

Основное хранилище данных на базе PostgreSQL. Использует две основные таблицы: 1. storage: Key-value хранилище для всех конфигураций и метаданных. 2. checkpoints: Хранит состояния LangGraph для возобновляемых Flow.

Расположение: app/db/database.py, app/db/models.py

Конфигурация

Конфигурация приложения управляется через JSON файлы (conf.json, conf.local.json). Позволяет настраивать параметры базы данных, LLM-провайдеров, серверные настройки и другие параметры.

Расположение: conf.json, conf.local.json, app/core/config.py

Подробнее: Документация по конфигурации

Развертывание

Канал поддерживает гибкие варианты развертывания, включая Docker-контейнеры для изоляции и масштабирования.

Примеры:

# Запуск через Docker Compose для локальной разработки
docker-compose up -d

# Локальный запуск (требуется установленный uv)
uv run python run.py

Подробнее: Документация по развертыванию