Initial: архитектура Pleep24 AI Sales Agent
This commit is contained in:
commit
4ffc815e30
3 files changed
+870
No files matched your search
+16
@@ -0,0 +1,16 @@
|
|||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*.egg-info/
|
||||||
|
dist/
|
||||||
|
.venv/
|
||||||
|
venv/
|
||||||
|
.env
|
||||||
|
*.log
|
||||||
|
pgdata/
|
||||||
|
redis-data/
|
||||||
|
.coverage
|
||||||
|
htmlcov/
|
||||||
|
.idea/
|
||||||
|
.vscode/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
+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 для партнёров
|
||||||
@@ -0,0 +1,88 @@
|
|||||||
|
# Pleep24 — AI Sales Agent
|
||||||
|
|
||||||
|
Self-hosted аналог [Pleep.app](https://pleep.app/) — мультиканальный AI-агент продаж.
|
||||||
|
|
||||||
|
## Что это
|
||||||
|
|
||||||
|
Pleep24 закрывает полный цикл сделки: от первого сообщения клиента до оплаты — через Telegram, WhatsApp, Instagram, веб-чат и телефонные звонки.
|
||||||
|
|
||||||
|
**Ключевое отличие от Pleep:** вместо встроенного CRM используется [Twenty CRM](https://twenty.com) (open-source, self-hosted). Голос — через [calls24](https://t.me/calls24).
|
||||||
|
|
||||||
|
## Архитектура
|
||||||
|
|
||||||
|
```
|
||||||
|
Telegram / WhatsApp / Instagram / Web Chat / Voice
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Message Router (FastAPI :8100) ← сессии, каналы
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
AI Brain (FastAPI :8101) ← LLM + RAG + tools
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Twenty Gateway (FastAPI :8102) ← Twenty CRM API + платежи
|
||||||
|
│
|
||||||
|
▼
|
||||||
|
Twenty CRM + Qdrant (KB)
|
||||||
|
```
|
||||||
|
|
||||||
|
## Стек
|
||||||
|
|
||||||
|
| Компонент | Технология |
|
||||||
|
|-----------|-----------|
|
||||||
|
| Backend | Python 3.12, FastAPI, asyncpg |
|
||||||
|
| LLM | DeepSeek (primary), Ollama (fallback) |
|
||||||
|
| RAG | Qdrant + embedding-модель |
|
||||||
|
| CRM | Twenty (self-hosted) |
|
||||||
|
| Voice | calls24 + Yandex AI Realtime API |
|
||||||
|
| TTS | Silero TTS |
|
||||||
|
| DB | PostgreSQL 16 |
|
||||||
|
| Cache | Redis (опционально) |
|
||||||
|
| Channels | Telegram (MAX API), WhatsApp, Instagram, Web Widget |
|
||||||
|
| Deploy | Coolify + Docker Compose |
|
||||||
|
|
||||||
|
## Быстрый старт
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 1. Клонировать
|
||||||
|
git clone http://192.168.1.230:3333/neo/pleep24.git
|
||||||
|
cd pleep24
|
||||||
|
|
||||||
|
# 2. Настроить окружение
|
||||||
|
cp .env.example .env
|
||||||
|
# Заполнить: DEEPSEEK_API_KEY, TWENTY_API_KEY, TELEGRAM_BOT_TOKEN, etc.
|
||||||
|
|
||||||
|
# 3. Запустить
|
||||||
|
docker compose up -d
|
||||||
|
|
||||||
|
# 4. Загрузить базу знаний
|
||||||
|
python scripts/load_kb.py --dir kb/
|
||||||
|
```
|
||||||
|
|
||||||
|
## Сервисы
|
||||||
|
|
||||||
|
| Порт | Сервис |
|
||||||
|
|------|--------|
|
||||||
|
| 8100 | Message Router |
|
||||||
|
| 8101 | AI Brain |
|
||||||
|
| 8102 | Twenty Gateway |
|
||||||
|
|
||||||
|
## Документация
|
||||||
|
|
||||||
|
- [ARCHITECTURE.md](ARCHITECTURE.md) — полная архитектура
|
||||||
|
- [API.md](docs/API.md) — API-спецификация
|
||||||
|
- [DEPLOY.md](docs/DEPLOY.md) — инструкция по деплою
|
||||||
|
|
||||||
|
## Roadmap
|
||||||
|
|
||||||
|
- [x] Архитектура
|
||||||
|
- [ ] Twenty Gateway (CRUD для Person, Deal, Note)
|
||||||
|
- [ ] AI Brain (LLM + Qdrant RAG)
|
||||||
|
- [ ] Message Router (Telegram)
|
||||||
|
- [ ] Web Widget
|
||||||
|
- [ ] Voice integration (calls24 → Twenty)
|
||||||
|
- [ ] WhatsApp-канал
|
||||||
|
|
||||||
|
## Лицензия
|
||||||
|
|
||||||
|
MIT
|
||||||
Reference in new issue
Block a user