Архитектура
Общая архитектура проекта Friedrich
Архитектура
Friedrich состоит из трёх Docker-контейнеров:
Slack ──► Caddy (SSL, порт 443) ──► slack-сервис (порт 3001) ──► agent-сервис (порт 8000)
│ │
slack-bolt FastAPI
слушает events brain.py (LLM)
управляет тредами tools/keitaro.py
session.py
geo.pyКомпоненты
Caddy
Reverse proxy с автоматическим SSL (Let's Encrypt). Принимает HTTPS-запросы от Slack и проксирует на slack-сервис.
Slack-сервис (slack/app.py)
- Слушает все сообщения в каналах где добавлен бот
- Триггерится на имя «Фридрих» (и вариации: Фридих, Фрид, Friedrich)
- Обрабатывает @упоминания
- Ведёт диалоги в тредах
- Пробрасывает
slack_user_idиslack_channel_idв agent
Agent-сервис
- brain.py — отправляет сообщение в LLM, получает решение: чат или tool-вызов
- tools/ — модули инструментов (Кейтаро и другие)
- session.py — in-memory хранилище сессий для пошагового сбора параметров
- geo.py — нормализация гео (свободная форма → ISO-2 код)
Структура файлов
slack-ai-agent/
├── agent/
│ ├── __init__.py
│ ├── main.py # FastAPI-приложение, оркестрация
│ ├── brain.py # LLM-роутер
│ ├── session.py # Хранилище сессий
│ ├── geo.py # Нормализация гео
│ └── tools/
│ ├── __init__.py
│ └── keitaro.py # Tool: Кейтаро
├── slack/
│ ├── __init__.py
│ └── app.py # Slack-бот
├── docker-compose.yml
├── Dockerfile.agent
├── Dockerfile.slack
├── Caddyfile
├── .env.example
└── requirements.txtПоток данных
- Пользователь пишет в Slack-канал
- Slack отправляет event на
https://домен/slack/events - Caddy проксирует на
slack:3001 - slack-сервис проверяет: имя бота или активный тред?
- Если да — отправляет POST на
agent:8000/message - Agent проверяет сессию (пошаговый сбор параметров)
- Если новое сообщение — отправляет в brain.py → LLM
- LLM возвращает: чат-ответ или tool-вызов с параметрами
- Если tool-вызов — agent выполняет метод или запрашивает недостающие параметры
- Ответ возвращается в Slack-тред