Initial: архитектура Pleep24 AI Sales Agent
This commit is contained in:
commit
4ffc815e30
3 files changed
+870
No files matched your search
+766
@@ -0,0 +1,766 @@
|
||||
# Pleep24 — Архитектура AI Sales Agent
|
||||
|
||||
> Аналог [Pleep.app](https://pleep.app/) — мультиканальный AI-агент продаж на стеке FastAPI + DeepSeek + Twenty CRM.
|
||||
|
||||
## Оглавление
|
||||
|
||||
1. [Обзор системы](#обзор-системы)
|
||||
2. [Архитектура микросервисов](#архитектура-микросервисов)
|
||||
3. [Twenty CRM — модель данных и интеграция](#twenty-crm--модель-данных-и-интеграция)
|
||||
4. [Message Router — маршрутизация сообщений](#message-router--маршрутизация-сообщений)
|
||||
5. [AI Agent — мозг системы](#ai-agent--мозг-системы)
|
||||
6. [Twenty Gateway — API-прослойка CRM](#twenty-gateway--api-прослойка-crm)
|
||||
7. [LLM Prompt Strategy](#llm-prompt-strategy)
|
||||
8. [Knowledge Base (RAG)](#knowledge-base-rag)
|
||||
9. [Web Widget](#web-widget)
|
||||
10. [Voice Integration (calls24)](#voice-integration-calls24)
|
||||
11. [Каналы связи](#каналы-связи)
|
||||
12. [База данных](#база-данных)
|
||||
13. [Деплоймент (Coolify + Docker)](#деплоймент-coolify--docker)
|
||||
14. [Roadmap](#roadmap)
|
||||
|
||||
---
|
||||
|
||||
## Обзор системы
|
||||
|
||||
Pleep24 — self-hosted мультиканальный AI-агент продаж. Закрывает полный цикл сделки: от первого сообщения до оплаты.
|
||||
|
||||
### Каналы связи
|
||||
|
||||
| Канал | Статус | Интеграция |
|
||||
|-------|--------|-----------|
|
||||
| Telegram | ✅ Есть | MAX Messenger Bot API (nik_bot) |
|
||||
| WhatsApp | 🔜 План | WhatsApp Business API / Baileys |
|
||||
| Instagram | 🔜 План | Instagram Messaging API |
|
||||
| Web Widget | 🔜 План | WebSocket + JS виджет |
|
||||
| Voice (телефон) | ✅ Есть | calls24 + Yandex AI Realtime API |
|
||||
|
||||
### Ключевые возможности
|
||||
|
||||
- **Единый inbox** — все каналы → одна лента переписки, контекст сохраняется при переходе между каналами
|
||||
- **AI-агент** — квалифицирует лиды, отвечает на вопросы, обрабатывает возражения, назначает встречи
|
||||
- **Twenty CRM** — все лиды автоматически создаются/обновляются в CRM, AI сам двигает сделки по воронке
|
||||
- **RAG** — база знаний (Qdrant): каталог, FAQ, скрипты — AI использует их при ответе
|
||||
- **Голос** — исходящие звонки через calls24, логирование в Twenty
|
||||
- **Оплата** — счёт прямо в чате (YooKassa / CloudPayments)
|
||||
- **Dashboard** — админка: настройка агента, просмотр диалогов, аналитика
|
||||
|
||||
### Что НЕ делаем (в отличие от Pleep)
|
||||
|
||||
- **Свой CRM** — используем Twenty (open source, self-hosted, уже работает)
|
||||
- **Свой voice engine** — используем calls24 (Yandex Realtime API)
|
||||
- **Свой payment gateway** — интеграция через YooKassa
|
||||
- **Своё хранилище файлов** — Twenty уже хранит вложения
|
||||
|
||||
---
|
||||
|
||||
## Архитектура микросервисов
|
||||
|
||||
```
|
||||
┌──────────────────────┐
|
||||
Telegram ────────────→│ │
|
||||
WhatsApp ────────────→│ Message Router │──→ Redis (сессии)
|
||||
Instagram ───────────→│ FastAPI :8100 │──→ Postgres (логи)
|
||||
Web Widget ──────────→│ │
|
||||
└──────────┬───────────┘
|
||||
│ Internal HTTP
|
||||
┌──────────▼───────────┐
|
||||
│ AI Brain │
|
||||
│ FastAPI :8101 │──→ Qdrant (RAG)
|
||||
│ LLM + Tools │──→ DeepSeek / Ollama
|
||||
└──────────┬───────────┘
|
||||
│ Internal HTTP
|
||||
┌──────────▼───────────┐
|
||||
│ Twenty Gateway │
|
||||
│ FastAPI :8102 │──→ Twenty CRM REST API
|
||||
│ │──→ YooKassa (платежи)
|
||||
└──────────────────────┘
|
||||
|
||||
calls24 (голос) ──→ Twenty Gateway (Notes / Activities)
|
||||
```
|
||||
|
||||
### Разделение на сервисы — почему три, а не один
|
||||
|
||||
| Сервис | Ответственность | Меняется когда |
|
||||
|--------|----------------|---------------|
|
||||
| **Message Router** | Приём/отправка сообщений, сессии | Новый канал |
|
||||
| **AI Brain** | LLM-логика, промпты, принятие решений | Меняем модель/логику |
|
||||
| **Twenty Gateway** | API Twenty, маппинг полей, платежи | Меняем CRM |
|
||||
|
||||
Разделение позволяет:
|
||||
- Менять LLM-модель, не трогая каналы
|
||||
- Добавлять каналы, не трогая логику агента
|
||||
- Мигрировать на другую CRM заменой только Gateway
|
||||
|
||||
---
|
||||
|
||||
## Twenty CRM — модель данных и интеграция
|
||||
|
||||
### Объекты Twenty, которые использует агент
|
||||
|
||||
```
|
||||
Person (контакт)
|
||||
├─ firstName, lastName
|
||||
├─ email, phone
|
||||
├─ city (из Telegram/чата)
|
||||
├─ position (должность)
|
||||
└─ avatarUrl
|
||||
|
||||
Company (компания)
|
||||
├─ name
|
||||
├─ domainName
|
||||
└─ address
|
||||
|
||||
Deal / Opportunity (сделка)
|
||||
├─ name, amount, closeDate
|
||||
├─ stage (этап воронки)
|
||||
├─ pipeline (какая воронка)
|
||||
└─ personId, companyId
|
||||
|
||||
Note (заметка)
|
||||
├─ title, body
|
||||
└─ personId, companyId, opportunityId
|
||||
|
||||
Activity (активность)
|
||||
├─ title, body, type (Call, Meeting, Email, Task)
|
||||
├─ dueAt, completedAt
|
||||
└─ personId, companyId, opportunityId
|
||||
|
||||
Task (задача)
|
||||
├─ title, body, status
|
||||
└─ assigneeId, dueAt
|
||||
```
|
||||
|
||||
### Воронка продаж (Pipeline)
|
||||
|
||||
```
|
||||
New Lead → Contacted → Qualified → Meeting Scheduled →
|
||||
Proposal Sent → Negotiation → Won / Lost
|
||||
```
|
||||
|
||||
AI-агент сам определяет стадию по контексту диалога и двигает Deal через POST/PATCH.
|
||||
|
||||
### REST API Twenty (ключевые эндпоинты)
|
||||
|
||||
Twenty auto-generates REST API из схемы воркспейса. Standard base: `http://192.168.1.230/rest/`
|
||||
|
||||
```bash
|
||||
# Auth
|
||||
Authorization: Bearer YOUR_API_KEY
|
||||
|
||||
# Поиск/создание Person по телефону
|
||||
GET /rest/people?filter=phone[eq]{phone}&limit=1
|
||||
POST /rest/people
|
||||
|
||||
# Компании
|
||||
POST /rest/companies
|
||||
GET /rest/companies?filter=name[ilike]%{query}%
|
||||
|
||||
# Сделки
|
||||
POST /rest/opportunities
|
||||
PATCH /rest/opportunities/{id} # смена stage
|
||||
GET /rest/opportunities?filter=personId[eq]{id}
|
||||
|
||||
# Заметки
|
||||
POST /rest/notes
|
||||
|
||||
# Активности
|
||||
POST /rest/activities
|
||||
|
||||
# Batch (до 60 записей)
|
||||
POST /rest/batch
|
||||
```
|
||||
|
||||
**Лимиты:** 100 RPM, batch до 60 записей.
|
||||
|
||||
### Стадия "New Lead" → Person создаётся
|
||||
|
||||
При первом сообщении:
|
||||
1. Ищем Person по phone/email/telegram_id
|
||||
2. Если нет → создаём Person + Note "Первое сообщение из {channel}"
|
||||
3. Если есть → получаем связанные Notes, Deals, Activities
|
||||
4. Передаём контекст в AI Brain
|
||||
|
||||
---
|
||||
|
||||
## Message Router — маршрутизация сообщений
|
||||
|
||||
### Назначение
|
||||
|
||||
Единая точка входа для всех каналов. Принимает сообщение, определяет сессию, маршрутизирует в AI Brain, возвращает ответ в канал.
|
||||
|
||||
### API эндпоинты
|
||||
|
||||
```
|
||||
POST /api/messages — принять сообщение (общий)
|
||||
POST /api/webhooks/telegram — Telegram webhook
|
||||
POST /api/webhooks/whatsapp — WhatsApp webhook
|
||||
POST /api/webhooks/instagram — Instagram webhook
|
||||
GET /api/conversations/{id} — история диалога
|
||||
GET /api/conversations — список активных диалогов
|
||||
GET /health
|
||||
```
|
||||
|
||||
### Формат сообщения
|
||||
|
||||
```json
|
||||
{
|
||||
"channel": "telegram",
|
||||
"external_id": "140245519",
|
||||
"text": "Здравствуйте, интересует цена",
|
||||
"timestamp": "2026-07-05T12:00:00+05:00",
|
||||
"metadata": {
|
||||
"chat_id": "-1001234567890",
|
||||
"message_id": 456,
|
||||
"username": "user123",
|
||||
"first_name": "Иван"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Сессионный ключ
|
||||
|
||||
```
|
||||
session_key = sha256(f"{channel}:{external_id}")
|
||||
```
|
||||
|
||||
Один ключ → одна сессия, даже если пользователь переключается между каналами (если указал телефон/email).
|
||||
|
||||
### Хранение
|
||||
|
||||
**Postgres таблицы:**
|
||||
|
||||
```sql
|
||||
CREATE TABLE conversations (
|
||||
id UUID PRIMARY KEY,
|
||||
channel VARCHAR(32) NOT NULL, -- telegram, whatsapp, etc.
|
||||
external_id VARCHAR(256) NOT NULL, -- ID пользователя в канале
|
||||
twenty_person_id VARCHAR(64), -- UUID Person в Twenty
|
||||
twenty_company_id VARCHAR(64), -- UUID Company
|
||||
metadata JSONB DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ DEFAULT NOW(),
|
||||
UNIQUE(channel, external_id)
|
||||
);
|
||||
|
||||
CREATE TABLE messages (
|
||||
id UUID PRIMARY KEY,
|
||||
conversation_id UUID REFERENCES conversations(id),
|
||||
direction VARCHAR(8) NOT NULL, -- in, out
|
||||
content TEXT NOT NULL,
|
||||
channel_message_id VARCHAR(128), -- ID сообщения в канале
|
||||
llm_prompt_tokens INT,
|
||||
llm_completion_tokens INT,
|
||||
created_at TIMESTAMPTZ DEFAULT NOW()
|
||||
);
|
||||
|
||||
CREATE TABLE channel_configs (
|
||||
id UUID PRIMARY KEY,
|
||||
channel_type VARCHAR(32) UNIQUE,
|
||||
config JSONB NOT NULL, -- токены, webhook URLs
|
||||
enabled BOOLEAN DEFAULT true
|
||||
);
|
||||
```
|
||||
|
||||
### Redis (опционально)
|
||||
|
||||
Для rate-limiting и кеширования сессий:
|
||||
```
|
||||
conversation:{session_key}:last_activity → timestamp
|
||||
conversation:{session_key}:person_id → twenty_person_id
|
||||
rate_limit:{channel}:{external_id} → счётчик
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## AI Agent — мозг системы
|
||||
|
||||
### Назначение
|
||||
|
||||
Принимает сообщение + контекст из Twenty Gateway, генерирует ответ и список действий.
|
||||
|
||||
### API
|
||||
|
||||
```
|
||||
POST /api/process
|
||||
```
|
||||
|
||||
**Запрос:**
|
||||
```json
|
||||
{
|
||||
"session": {
|
||||
"key": "sha256...",
|
||||
"channel": "telegram",
|
||||
"person": {
|
||||
"id": "uuid-person",
|
||||
"name": "Иван Петров",
|
||||
"phone": "+79123456789"
|
||||
},
|
||||
"company": null,
|
||||
"active_deal": {
|
||||
"id": "uuid-deal",
|
||||
"name": "КП на CRM",
|
||||
"stage": "Contacted",
|
||||
"amount": 150000
|
||||
},
|
||||
"last_messages": [
|
||||
{"role": "user", "text": "Интересует цена"},
|
||||
{"role": "assistant", "text": "Добрый день! Для какого бизнеса?"}
|
||||
]
|
||||
},
|
||||
"message": {
|
||||
"text": "Ресторан, доставка",
|
||||
"timestamp": "2026-07-05T12:01:00+05:00"
|
||||
},
|
||||
"kb_context": "### Прайс\nБазовая — 4500 руб/мес. Pro — 9500 руб/мес..."
|
||||
}
|
||||
```
|
||||
|
||||
**Ответ:**
|
||||
```json
|
||||
{
|
||||
"reply": "Отлично, для ресторана с доставкой подойдёт Pro-тариф — 9500 ₽/мес. Там есть интеграция с iiko и Яндекс.Едой.",
|
||||
"actions": [
|
||||
{
|
||||
"type": "update_deal_stage",
|
||||
"data": {"deal_id": "uuid-deal", "stage": "Qualified"}
|
||||
},
|
||||
{
|
||||
"type": "update_person",
|
||||
"data": {"person_id": "uuid-person", "position": "Владелец"}
|
||||
},
|
||||
{
|
||||
"type": "schedule_followup",
|
||||
"data": {"at": "2026-07-07T14:00:00+05:00", "text": "Уточнить потребность в iiko"}
|
||||
}
|
||||
],
|
||||
"kb_sources": ["Прайс-лист (релевантность 0.94)", "FAQ по интеграциям (0.87)"]
|
||||
}
|
||||
```
|
||||
|
||||
### Инструменты (tools), доступные агенту
|
||||
|
||||
| Инструмент | Описание |
|
||||
|-----------|----------|
|
||||
| `search_kb(query)` | Поиск в Qdrant по KB (прайс, FAQ, скрипты) |
|
||||
| `update_person(data)` | Обновить поля контакта (должность, город и т.д.) |
|
||||
| `update_deal_stage(deal_id, stage)` | Передвинуть сделку по воронке |
|
||||
| `create_deal(data)` | Создать новую сделку |
|
||||
| `add_note(text)` | Добавить заметку в CRM |
|
||||
| `schedule_followup(at, text)` | Запланировать звонок/встречу |
|
||||
| `handover_to_human(reason)` | Передать диалог оператору |
|
||||
| `send_invoice(amount, description)` | Выставить счёт |
|
||||
| `call_voice(phone, script)` | Инициировать звонок через calls24 |
|
||||
|
||||
### Структура сервиса
|
||||
|
||||
```
|
||||
ai-brain/
|
||||
main.py — FastAPI app
|
||||
agent.py — LLM-оркестрация (DeepSeek + tool calling)
|
||||
prompts/
|
||||
system_v1.md — Системный промпт (редактируемый)
|
||||
personas/ — Персоны агента
|
||||
sales.md — Продавец (основной)
|
||||
support.md — Поддержка
|
||||
qualifier.md — Квалификатор лидов
|
||||
tools.py — Реализация инструментов
|
||||
rag.py — Qdrant-клиент для KB
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Twenty Gateway — API-прослойка CRM
|
||||
|
||||
### Назначение
|
||||
|
||||
Прокси для Twenty CRM API. Скрывает детали авторизации, кеширует частые запросы, нормализует ошибки.
|
||||
|
||||
### API
|
||||
|
||||
```
|
||||
POST /api/persons/find-or-create — найти по phone/email или создать
|
||||
GET /api/persons/{id} — контакт + связанные объекты
|
||||
GET /api/persons/{id}/deals — активные сделки
|
||||
GET /api/persons/{id}/notes — последние заметки
|
||||
POST /api/persons/{id}/notes — добавить заметку
|
||||
GET /api/companies/search — поиск по названию
|
||||
POST /api/deals — создать сделку
|
||||
PATCH /api/deals/{id}/stage — сменить этап
|
||||
POST /api/activities — создать активность
|
||||
GET /api/pipelines/stages — список этапов воронки
|
||||
```
|
||||
|
||||
### Кеширование
|
||||
|
||||
```
|
||||
person:{phone} → TTL 5 min
|
||||
person:{id} → TTL 1 min
|
||||
deal:{id} → TTL 1 min
|
||||
pipeline_stages → TTL 30 min
|
||||
```
|
||||
|
||||
### Управление ошибками
|
||||
|
||||
- **401** — ротация API-ключа
|
||||
- **429** — retry с backoff (100 RPM лимит)
|
||||
- **Сетевые ошибки** — 3 ретрая с экспоненциальной задержкой
|
||||
|
||||
---
|
||||
|
||||
## LLM Prompt Strategy
|
||||
|
||||
### Системный промпт (sales.md)
|
||||
|
||||
```
|
||||
Ты — ИИ-продавец компании {company_name}.
|
||||
|
||||
ТВОЯ РОЛЬ: квалифицировать лидов, отвечать на вопросы о продукте,
|
||||
обрабатывать возражения, назначать встречи, доводить до сделки.
|
||||
|
||||
ПРАВИЛА:
|
||||
1. ВСЕГДА начинай с приветствия и представления (только в первом сообщении)
|
||||
2. Квалифицируй лида: имя → потребность → бюджет → сроки → ЛПР
|
||||
3. Используй базу знаний для ответов о продукте — НЕ придумывай
|
||||
4. Если вопрос вне твоей компетенции → честно скажи "уточню у коллег"
|
||||
и передай диалог оператору
|
||||
5. Двигай сделку по воронке по мере прогресса диалога
|
||||
6. Не будь навязчивым — если лид просит "подумать", предложи
|
||||
вернуться к диалогу через 2-3 дня
|
||||
|
||||
ТОН ОБЩЕНИЯ:
|
||||
- Дружелюбный, но деловой
|
||||
- Короткие сообщения (2-4 предложения), не полотна текста
|
||||
- Один вопрос за сообщение
|
||||
- Эмодзи умеренно, без перебора
|
||||
|
||||
КОНТЕКСТ:
|
||||
- Продукт: {product_summary}
|
||||
- Прайс: {pricing_summary}
|
||||
- Текущий лид: {person_name}, {person_position}, {person_city}
|
||||
- Стадия сделки: {deal_stage}
|
||||
|
||||
ДОСТУПНЫЕ ИНСТРУМЕНТЫ:
|
||||
{available_tools}
|
||||
```
|
||||
|
||||
### Пайплайн сообщения (как LLM принимает решение)
|
||||
|
||||
```
|
||||
1. Сообщение от пользователя
|
||||
2. Поиск в KB (Qdrant) → релевантные куски
|
||||
3. Формирование промпта: system + KB + контекст CRM + история
|
||||
4. LLM (DeepSeek) → reply + actions
|
||||
5. Парсинг actions → выполнение через Twenty Gateway
|
||||
6. Отправка reply в Message Router → канал
|
||||
```
|
||||
|
||||
### Fallback
|
||||
|
||||
Если DeepSeek недоступен → локальный Ollama (qwen3.6/gemma4).
|
||||
|
||||
### Мониторинг качества
|
||||
|
||||
- `handover_rate` — % диалогов, переданных оператору (норма <15%)
|
||||
- `response_time_p95` — время ответа (цель <3 сек)
|
||||
- `deal_progression` — % сделок, дошедших до Won
|
||||
|
||||
---
|
||||
|
||||
## Knowledge Base (RAG)
|
||||
|
||||
### Хранилище: Qdrant
|
||||
|
||||
Уже запущен на a2000. Коллекция: `pleep24_kb`.
|
||||
|
||||
### Структура чанков
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "pricing_pro_tariff",
|
||||
"text": "Pro-тариф: 9500 ₽/мес. Включает: до 1000 диалогов/мес, интеграцию с CRM, ...",
|
||||
"metadata": {
|
||||
"category": "pricing",
|
||||
"source": "pricing.md",
|
||||
"updated_at": "2026-07-01",
|
||||
"tags": ["тариф", "цена", "pro"]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Категории KB
|
||||
|
||||
| Категория | Пример | Обновляется |
|
||||
|-----------|--------|------------|
|
||||
| `pricing` | Прайс-лист, тарифы, скидки | При изменении цен |
|
||||
| `faq` | Частые вопросы и ответы | По мере накопления |
|
||||
| `scripts` | Скрипты обработки возражений | Версионируется |
|
||||
| `catalog` | Каталог продуктов/услуг | При изменении ассортимента |
|
||||
| `cases` | Кейсы, отзывы, примеры | По мере появления |
|
||||
| `legal` | Договор, оферта, реквизиты | При изменении |
|
||||
|
||||
### Загрузка в Qdrant
|
||||
|
||||
```bash
|
||||
python scripts/load_kb.py --file pricing.md --category pricing
|
||||
python scripts/load_kb.py --file faq.md --category faq
|
||||
```
|
||||
|
||||
### Стратегия поиска
|
||||
|
||||
1. Embedding-поиск: top-5 чанков по релевантности
|
||||
2. Фильтрация: убираем чанки с score < 0.65
|
||||
3. Сборка: склеиваем в контекст, добавляем в промпт
|
||||
|
||||
---
|
||||
|
||||
## Web Widget
|
||||
|
||||
### Чат-виджет для сайта
|
||||
|
||||
```
|
||||
┌──────────────────────────────┐
|
||||
│ 💬 Чат с экспертом │
|
||||
│ ────────────────────────── │
|
||||
│ │
|
||||
│ AiAgent │
|
||||
│ Здравствуйте! Я помогу │
|
||||
│ подобрать решение. │
|
||||
│ │
|
||||
│ User │
|
||||
│ Интересует CRM для │
|
||||
│ ресторана │
|
||||
│ │
|
||||
│ ────────────────────────── │
|
||||
│ [Введите сообщение...] 📎 │
|
||||
└──────────────────────────────┘
|
||||
```
|
||||
|
||||
### Технологии
|
||||
|
||||
- **Vanilla JS** (никаких фреймворков, <50KB gzip)
|
||||
- **WebSocket** → Message Router (быстрее HTTP polling)
|
||||
- **WebRTC** → звонок через calls24 прямо из виджета
|
||||
|
||||
### Встраивание
|
||||
|
||||
```html
|
||||
<script src="https://widget.tarasov.top/chat.js"
|
||||
data-org="acme-corp"
|
||||
data-theme="dark">
|
||||
</script>
|
||||
```
|
||||
|
||||
**Параметры:**
|
||||
- `data-org` — ID организации (маппится на Twenty workspace)
|
||||
- `data-theme` — `light` / `dark`
|
||||
- `data-position` — `right` / `left`
|
||||
- `data-voice` — `true` если показывать кнопку звонка
|
||||
|
||||
---
|
||||
|
||||
## Voice Integration (calls24)
|
||||
|
||||
### Интеграция с Twenty
|
||||
|
||||
После каждого звонка через calls24:
|
||||
1. calls24 отправляет webhook в Twenty Gateway
|
||||
2. Twenty Gateway создаёт:
|
||||
- **Activity** (тип: Call) — длительность, статус, запись
|
||||
- **Note** — транскрипт звонка (ключевые моменты)
|
||||
3. Если звонок квалифицирующий → создаётся/обновляется Deal
|
||||
|
||||
### Webhook от calls24
|
||||
|
||||
```
|
||||
POST /api/webhooks/calls24
|
||||
|
||||
{
|
||||
"call_id": "call-uuid",
|
||||
"direction": "outbound",
|
||||
"from": "+74951234567",
|
||||
"to": "+79123456789",
|
||||
"status": "completed",
|
||||
"duration": 245,
|
||||
"recording_url": "https://...",
|
||||
"transcript": "полный текст разговора...",
|
||||
"summary": "Лид заинтересован в Pro-тарифе, бюджет до 15К, ЛПР — директор",
|
||||
"person_id": "uuid-person" // если уже есть в Twenty
|
||||
}
|
||||
```
|
||||
|
||||
### Исходящий звонок через AI Agent
|
||||
|
||||
1. Агент решает: `call_voice(phone="+7912...", script="Уточнить бюджет и сроки")`
|
||||
2. Twenty Gateway → calls24 API: инициировать звонок
|
||||
3. После завершения → webhook создаёт Activity + Note
|
||||
|
||||
---
|
||||
|
||||
## Каналы связи
|
||||
|
||||
### Telegram (MAX Messenger API)
|
||||
|
||||
Уже работает: nik_bot, user_id 140245519.
|
||||
|
||||
```python
|
||||
# Отправка сообщения
|
||||
curl "https://u0776982.cp.regruhosting.ru/bots/nik_bot/sendMessage" \
|
||||
-d "user_id=140245519&text=Привет!"
|
||||
|
||||
# Webhook приём
|
||||
# MAX Messenger поддерживает webhooks — настраивается в ЛК
|
||||
```
|
||||
|
||||
### WhatsApp
|
||||
|
||||
**Вариант 1 — WhatsApp Business API (Meta):**
|
||||
- Официальный API через Meta
|
||||
- Требует верификации бизнеса
|
||||
- Webhook: `POST /api/webhooks/whatsapp`
|
||||
|
||||
**Вариант 2 — Baileys (Node.js):**
|
||||
- Неофициальная библиотека, reverse-engineered WA Web
|
||||
- Риск блокировки номера
|
||||
- Не для production без резервного номера
|
||||
|
||||
В архитектуре закладываем абстрактный `WhatsappProvider`, который можно подменить.
|
||||
|
||||
### Instagram
|
||||
|
||||
Через Instagram Messaging API (Meta), тот же механизм что и WhatsApp.
|
||||
|
||||
### Web Widget
|
||||
|
||||
WebSocket-соединение к Message Router. Не зависит от платформ.
|
||||
|
||||
---
|
||||
|
||||
## База данных
|
||||
|
||||
### Postgres (общая для всех сервисов)
|
||||
|
||||
**База:** `pleep24`
|
||||
**Таблицы:**
|
||||
|
||||
| Таблица | Сервис | Назначение |
|
||||
|---------|--------|-----------|
|
||||
| `conversations` | Router | Сессии диалогов |
|
||||
| `messages` | Router | Лог всех сообщений |
|
||||
| `channel_configs` | Router | Конфиги каналов |
|
||||
| `webhook_logs` | Router | Лог входящих webhook'ов |
|
||||
| `agent_decisions` | Brain | Лог решений AI (audit trail) |
|
||||
| `kb_documents` | Brain | Метаданные документов KB |
|
||||
| `call_logs` | Gateway | Лог звонков calls24 |
|
||||
| `payment_intents` | Gateway | Платёжные намерения |
|
||||
|
||||
### Redis (опционально)
|
||||
|
||||
- Кеш сессий (conversation_key → person_id)
|
||||
- Rate limiting
|
||||
- Очередь сообщений (если нужна асинхронная обработка)
|
||||
|
||||
---
|
||||
|
||||
## Деплоймент (Coolify + Docker)
|
||||
|
||||
### Docker Compose
|
||||
|
||||
```yaml
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:16-alpine
|
||||
environment:
|
||||
POSTGRES_DB: pleep24
|
||||
POSTGRES_USER: pleep24
|
||||
POSTGRES_PASSWORD: ${DB_PASSWORD}
|
||||
volumes:
|
||||
- pgdata:/var/lib/postgresql/data
|
||||
|
||||
redis:
|
||||
image: redis:7-alpine
|
||||
|
||||
message-router:
|
||||
build: ./message-router
|
||||
ports:
|
||||
- "8100:8100"
|
||||
environment:
|
||||
DATABASE_URL: postgresql+asyncpg://...
|
||||
REDIS_URL: redis://redis:6379
|
||||
TELEGRAM_BOT_TOKEN: ${TELEGRAM_BOT_TOKEN}
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
ai-brain:
|
||||
build: ./ai-brain
|
||||
ports:
|
||||
- "8101:8101"
|
||||
environment:
|
||||
DEEPSEEK_API_KEY: ${DEEPSEEK_API_KEY}
|
||||
QDRANT_URL: http://192.168.1.230:6333
|
||||
TWENTY_GATEWAY_URL: http://twenty-gateway:8102
|
||||
depends_on:
|
||||
- postgres
|
||||
|
||||
twenty-gateway:
|
||||
build: ./twenty-gateway
|
||||
ports:
|
||||
- "8102:8102"
|
||||
environment:
|
||||
TWENTY_API_KEY: ${TWENTY_API_KEY}
|
||||
TWENTY_BASE_URL: http://192.168.1.230
|
||||
YOOKASSA_SHOP_ID: ${YOOKASSA_SHOP_ID}
|
||||
YOOKASSA_SECRET: ${YOOKASSA_SECRET}
|
||||
```
|
||||
|
||||
### Требования к серверу
|
||||
|
||||
| Ресурс | Минимум | Рекомендовано |
|
||||
|--------|---------|--------------|
|
||||
| RAM | 2 GB | 4 GB |
|
||||
| CPU | 2 cores | 4 cores |
|
||||
| Диск | 10 GB | 20 GB |
|
||||
|
||||
### Что уже есть на a2000
|
||||
|
||||
| Сервис | Статус |
|
||||
|--------|--------|
|
||||
| Postgres | Есть (много инстансов, можно новый) |
|
||||
| Redis | Нет → добавить в compose |
|
||||
| Qdrant | ✅ 192.168.1.230:6333 |
|
||||
| Twenty CRM | ✅ 192.168.1.230 (за Traefik) |
|
||||
| DeepSeek API | ✅ через провайдера |
|
||||
| Ollama (local fallback) | ✅ |
|
||||
| Silero TTS | ✅ |
|
||||
| calls24 | ✅ |
|
||||
| Coolify | ✅ 192.168.1.230:8000 |
|
||||
| Telegram (MAX API) | ✅ |
|
||||
|
||||
---
|
||||
|
||||
## Roadmap
|
||||
|
||||
### Фаза 1 — MVP (2-3 недели)
|
||||
|
||||
- [ ] **Twenty Gateway** — базовые CRUD (Person, Deal, Note)
|
||||
- [ ] **AI Brain** — единый промпт + DeepSeek + поиск в Qdrant
|
||||
- [ ] **Message Router** — Telegram приём/отправка
|
||||
- [ ] **Web Widget** — простой чат на WebSocket
|
||||
- [ ] **Docker Compose** — деплой на Coolify
|
||||
|
||||
### Фаза 2 — Production (4-6 недель)
|
||||
|
||||
- [ ] WhatsApp-канал
|
||||
- [ ] Интеграция calls24 → Twenty (Activity + Note после звонка)
|
||||
- [ ] Админ-панель (диалоги, аналитика, настройка KB)
|
||||
- [ ] Мультиарендность (несколько организаций = разные Twenty workspace)
|
||||
- [ ] Мониторинг и алерты
|
||||
|
||||
### Фаза 3 — Расширение (8-12 недель)
|
||||
|
||||
- [ ] Instagram-канал
|
||||
- [ ] Приём платежей (YooKassa)
|
||||
- [ ] A/B тестирование промптов
|
||||
- [ ] Self-improving KB (AI сам предлагает дополнить FAQ)
|
||||
- [ ] API для партнёров
|
||||
Reference in new issue
Block a user