🎧

AI-АГЕНТ ДЛЯ ПОДДЕРЖКИ КЛИЕНТОВ 2026: ЧАТ-БОТ 24/7 НА PYTHON

RAG-база знаний, классификация интентов, эскалация на оператора — полный пайплайн поддержки клиентов на Python за один вечер

BUSINESS ⏱ 20 МИН
КЛИЕНТ Telegram / Веб-чат FastAPI-БОТ POST /webhook КЛАССИФИКАТОР pydantic + LLM RAG-ПОИСК chromadb / эмбеддинги LLM-ГЕНЕРАЦИЯ OpenAI / DeepSeek ЭСКАЛАЦИЯ CRM / Тикет 🗄️ Векторная БД FAISS / Qdrant 📚 База знаний FAQ / Документация 📤 Ответ ━━ Основной поток ━━ Эскалация - - Хранилища данных - - Контекст 🟢 24/7

# 1. АРХИТЕКТУРА АГЕНТА ПОДДЕРЖКИ

AI-агент поддержки — это не просто чат-бот с ChatGPT под капотом. Архитектура строится вокруг трёх ключевых слоёв: маршрутизация (классификация интента), поиск (RAG по базе знаний) и генерация (LLM с guardrails). Четвёртый слой — эскалация на живого оператора, когда уверенность модели ниже порога или клиент явно просит человека.

Запрос клиента приходит через Telegram-бота или веб-чат-виджет → FastAPI-эндпоинт принимает webhook → классификатор определяет категорию: faq / billing / technical / escalation → для faq/technical запускается RAG-поиск по векторной базе → LLM генерирует ответ с контекстом из найденных документов. Если классификатор вернул escalation или confidence ниже 0.7 — запрос уходит оператору с полным контекстом диалога. Все шаги логируются в JSON для аналитики. Стоимость такого решения — от $0.01 за диалог при использовании GPT-4o mini или полностью бесплатно с локальной Ollama.

Ключевое преимущество self-hosted подхода: ваши данные остаются у вас. В отличие от Intercom Fin или Zendesk AI, где каждый диалог проходит через чужие серверы, собственный агент на Python даёт полный контроль над PII, логами и моделью. Масштабируется горизонтально через несколько воркеров FastAPI за nginx.

# 2. КЛАССИФИКАЦИЯ ИНТЕНТОВ

Первый рубеж агента — понять, что нужно клиенту. Используем pydantic-модель для строгой типизации ответа LLM и функцию classify_intent, которая возвращает категорию и confidence. Модель получает системный промпт с описанием категорий и должна вернуть JSON. Это дешевле и быстрее, чем гонять полную генерацию — используем gpt-4o-mini или локальную модель.

# intent_classifier.py — классификация запроса клиента
import json
from pydantic import BaseModel
from openai import AsyncOpenAI

class Intent(BaseModel):
    category: str   # faq | billing | technical | escalation
    confidence: float  # 0.0 – 1.0
    reason: str

async def classify_intent(client: AsyncOpenAI, text: str) -> Intent:
    prompt = f"""Классифицируй запрос клиента в JSON:
Категории: faq, billing, technical, escalation.
Запрос: "{text}"
Верни ТОЛЬКО JSON: {{"category":"...","confidence":0.0,"reason":"..."}}"""

    resp = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content": prompt}],
        temperature=0.0,
        response_format={"type": "json_object"}
    )
    data = json.loads(resp.choices[0].message.content)
    return Intent(**data)

# Порог: всё, что ниже 0.7 — эскалация на оператора
ESCALATION_THRESHOLD = 0.7

Модель Intent валидирует ответ через pydantic — если LLM вернула мусор, вы получите исключение, а не сломанный пайплайн. Temperature=0.0 гарантирует детерминированную классификацию. Категория escalation обрабатывается отдельно — запрос сразу уходит оператору, минуя RAG и генерацию.

# 3. RAG ПО БАЗЕ ЗНАНИЙ

RAG (Retrieval-Augmented Generation) — сердце агента поддержки. Вместо того чтобы LLM «придумывала» ответы, мы подаём ей реальные документы из базы знаний: FAQ, инструкции, условия тарифов, политику возврата. Используем chromadb как легковесную векторную БД (не требует отдельного сервера — SQLite под капотом) и эмбеддинги от OpenAI text-embedding-3-small ($0.02 за 1M токенов).

# rag_engine.py — поиск по базе знаний
import chromadb
from openai import AsyncOpenAI

class RAGEngine:
    def __init__(self, client: AsyncOpenAI, collection_name="knowledge_base"):
        self.client = client
        self.chroma = chromadb.PersistentClient(path="./chroma_data")
        self.collection = self.chroma.get_or_create_collection(collection_name)

    async def embed(self, text: str) -> list[float]:
        resp = await self.client.embeddings.create(
            model="text-embedding-3-small", input=text
        )
        return resp.data[0].embedding

    async def search(self, query: str, top_k=5) -> list[str]:
        q_embed = await self.embed(query)
        results = self.collection.query(
            query_embeddings=[q_embed], n_results=top_k
        )
        return results["documents"][0]  # top-K чанков

    async def index_docs(self, documents: list[dict]):
        """Индексация: {id, text} → эмбеддинг → chromadb"""
        for i in range(0, len(documents), 20):  # батчи по 20
            batch = documents[i:i+20]
            texts = [d["text"] for d in batch]
            ids = [d["id"] for d in batch]
            embeds = [await self.embed(t) for t in texts]
            self.collection.add(embeddings=embeds, documents=texts, ids=ids)

ChromaDB хранит данные локально в ./chroma_data — никакого отдельного сервера. Для продакшена с высокими нагрузками можно переключиться на Qdrant (in-memory, gRPC) — замена одной строки. Индексация идёт батчами по 20 документов — это оптимально для API OpenAI, у которого rate limit ~500 запросов/мин для embeddings.

# 4. ГЕНЕРАЦИЯ ОТВЕТА + FALLBACK

После классификации и поиска релевантных документов — генерация финального ответа. Ключевое правило: модель НЕ выдумывает. Если в найденных чанках нет ответа — честно говорим «я не знаю» и предлагаем эскалацию. Используем AsyncOpenAI для неблокирующих запросов и стриминг для быстрого первого токена. Промпт строится из системной инструкции + контекста из RAG + вопроса клиента.

# answer_generator.py — генерация ответа с guardrails
from openai import AsyncOpenAI

SYSTEM_PROMPT = """Ты — агент поддержки компании. Правила:
1. Отвечай ТОЛЬКО на основе переданного контекста.
2. Если в контексте нет ответа — скажи "Уточню у коллег" и предложи оператора.
3. Не извиняйся без причины. Будь конкретным и полезным.
4. Максимум 3 предложения. Без маркдауна."""

async def generate_answer(
    client: AsyncOpenAI, query: str, context_chunks: list[str]
) -> str:
    context = "\n\n".join(
        f"ДОКУМЕНТ {i+1}:\n{c}" for i, c in enumerate(context_chunks)
    )
    resp = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[
            {"role": "system", "content": SYSTEM_PROMPT},
            {"role": "user", "content": f"Контекст:\n{context}\n\nВопрос: {query}"}
        ],
        temperature=0.3,
        max_tokens=300
    )
    return resp.choices[0].message.content.strip()

# Fallback: если RAG не нашёл релевантных чанков
FALLBACK_ANSWER = "Пока не могу ответить точно. Хотите, подключу оператора?"

Главный guardrail — правило №1 в системном промпте: «отвечай только на основе контекста». Без него модель начнёт «додумывать» тарифы, сроки и политики — катастрофа для поддержки. Стриминг включается флагом stream=True — клиент в Telegram видит, как агент «печатает». Для голосовых ответов можно подключить ElevenLabs TTS — озвучка ответа в реальном времени.

# 5. ЭСКАЛАЦИЯ НА ОПЕРАТОРА

Не каждый запрос должен решаться автоматически. Эскалация срабатывает в трёх случаях: confidence классификатора ниже порога, категория escalation, или клиент явно просит человека (слова-триггеры: «оператор», «человек», «позовите»). При эскалации создаётся тикет в CRM через webhook, контекст диалога прикрепляется, а оператору в Telegram приходит уведомление.

# escalation.py — эскалация на живого оператора
import httpx
from datetime import datetime, timezone

ESCALATION_TRIGGERS = ["оператор", "человек", "позовите", "живой"]

def should_escalate(intent, user_text: str) -> bool:
    if intent.category == "escalation":
        return True
    if intent.confidence < ESCALATION_THRESHOLD:
        return True
    if any(t in user_text.lower() for t in ESCALATION_TRIGGERS):
        return True
    return False

async def escalate_to_operator(
    user_id: str, user_text: str, history: list, crm_webhook: str
):
    ticket = {
        "user_id": user_id,
        "query": user_text,
        "history": history,
        "created_at": datetime.now(timezone.utc).isoformat(),
        "source": "ai-agent-escalation"
    }
    async with httpx.AsyncClient() as hc:
        await hc.post(crm_webhook, json=ticket, timeout=10)

    # Уведомление оператору в Telegram
    alert = f"🔔 Эскалация!\nUser: {user_id}\nЗапрос: {user_text[:200]}"
    await hc.post(
        f"https://api.telegram.org/bot{OPERATOR_BOT_TOKEN}/sendMessage",
        json={"chat_id": OPERATOR_CHAT_ID, "text": alert}
    )
    return ticket

Тикет содержит полную историю диалога — оператор видит контекст и не переспрашивает клиента. CRM-вебхук может вести в amoCRM, Bitrix24, или самописную админку. Уведомление в Telegram дублирует тикет — оператор получает push мгновенно, даже если CRM открыта не у всех.

# 6. ИНТЕГРАЦИЯ С TELEGRAM-БОТОМ

Telegram — идеальный канал для AI-поддержки: 900M+ пользователей, бесплатный Bot API, webhook-доставка, поддержка inline-кнопок и форматирования. Используем aiogram 3.x — асинхронный фреймворк с нативной поддержкой webhook. Бот принимает сообщение → прогоняет через пайплайн (классификация → RAG → генерация) → отправляет ответ. Диалог хранится в Redis с TTL 24 часа для контекста.

# main.py — FastAPI + aiogram + полный пайплайн
from fastapi import FastAPI, Request
from aiogram import Bot, Dispatcher, types
from aiogram.webhook.aiohttp_server import SimpleRequestHandler
from contextlib import asynccontextmanager

from intent_classifier import classify_intent, ESCALATION_THRESHOLD
from rag_engine import RAGEngine
from answer_generator import generate_answer, FALLBACK_ANSWER
from escalation import should_escalate, escalate_to_operator

bot = Bot(token="YOUR_BOT_TOKEN")
dp = Dispatcher()
llm = AsyncOpenAI(api_key="sk-...")
rag = RAGEngine(llm)

@dp.message()
async def handle_message(message: types.Message):
    text = message.text
    intent = await classify_intent(llm, text)

    if should_escalate(intent, text):
        await escalate_to_operator(
            str(message.from_user.id), text, [], CRM_WEBHOOK
        )
        await message.answer(
            "Переключаю на оператора. Ожидайте ответа в течение 5 минут."
        )
        return

    chunks = await rag.search(text, top_k=5)
    if not chunks:
        await message.answer(FALLBACK_ANSWER)
        return

    answer = await generate_answer(llm, text, chunks)
    await message.answer(answer)

# FastAPI-приложение с webhook для Telegram
@asynccontextmanager
async def lifespan(app: FastAPI):
    await bot.set_webhook(f"https://your-domain.com/webhook")
    yield
    await bot.delete_webhook()

app = FastAPI(lifespan=lifespan)

@app.post("/webhook")
async def tg_webhook(request: Request):
    update = await request.json()
    await dp.feed_update(bot, types.Update(**update))
    return {"ok": True}

# Запуск: uvicorn main:app --port 8000

Один файл main.py содержит весь пайплайн. Для продакшена добавьте Redis для хранения истории диалогов (aiogram.fsm.storage.redis) и nginx для HTTPS. Запуск через systemd или Docker Compose с авторестартом. Полный стек можно развернуть на Ollama — локальная LLM без внешних API.

# 7. МЕТРИКИ И АНАЛИТИКА

Без метрик агент поддержки — чёрный ящик. Отслеживаем четыре ключевых показателя: CSAT (удовлетворённость клиента через кнопки 👍/👎), resolution rate (доля запросов, решённых без эскалации), latency p95 (время от получения запроса до ответа) и cost per conversation (токены × цена модели). Все события пишутся в JSON-лог — простая и надёжная альтернатива Prometheus для старта.

# metrics.py — логирование и расчёт метрик
import json, time
from pathlib import Path

LOG_PATH = Path("./logs/conversations.jsonl")

def log_conversation(user_id: str, intent: str, answer: str,
                     latency_ms: float, tokens_used: int, escalated: bool):
    entry = {
        "ts": time.time(),
        "user_id": user_id,
        "intent": intent,
        "answer_len": len(answer),
        "latency_ms": round(latency_ms, 1),
        "tokens": tokens_used,
        "escalated": escalated
    }
    with open(LOG_PATH, "a") as f:
        f.write(json.dumps(entry, ensure_ascii=False) + "\n")

# Быстрый отчёт за сегодня (jq-стиль, без БД)
def daily_report() -> dict:
    lines = LOG_PATH.read_text().strip().split("\n")
    today = [json.loads(l) for l in lines]
    return {
        "total": len(today),
        "avg_latency_ms": sum(d["latency_ms"] for d in today) / len(today),
        "escalation_rate": sum(1 for d in today if d["escalated"]) / len(today),
        "total_tokens": sum(d["tokens"] for d in today)
    }

# Подключите в main.py:
# t0 = time.time()
# answer = await generate_answer(...)
# log_conversation(user_id, intent.category, answer,
#                  (time.time()-t0)*1000, tokens, escalated)

JSONL-логи читаются любым анализатором: от jq в терминале до Pandas в Jupyter. Для визуализации подойдёт Grafana с Loki или простой Streamlit-дашборд. Критично отслеживать escalation_rate — если он растёт, значит база знаний устарела или модель не справляется с новыми типами запросов. Порог тревоги: >30% эскалаций за день.

# 8. СВОЙ БОТ vs ГОТОВЫЕ ПЛАТФОРМЫ

Критерий Свой бот (Python) Intercom Fin Zendesk AI Voiceflow
Цена $0.01–0.05 / диалог (API) или бесплатно (Ollama) от $0.99 / resolved conversation от $49/мес + $1/решение от $249/мес (Pro)
Кастомизация Полный контроль: модель, промпты, triggers Контент — да, логика — ограничена Flow builder, расширения Визуальный редактор, без кода
Где данные Ваш сервер. Полный control. Серверы Intercom (США/ЕС) Серверы Zendesk (AWS) Облако Voiceflow
RAG / база знаний chromadb / Qdrant / FAISS — любой Встроенный Answers API Knowledge Base + Help Center Knowledge Base (базовая)
Модель Любая: GPT-4o, DeepSeek, локальная GPT-4o (фиксировано) GPT-4o / Claude (на выбор) Выбор модели из списка
Внедрение 1-3 дня (разработка) 30 минут (готовый виджет) 1 час (в экосистеме) 1-2 часа (drag-n-drop)

Вывод: свой бот выигрывает по стоимости на масштабе >100 диалогов/день и даёт полный контроль над данными и моделью. Готовые платформы выигрывают в скорости запуска, но привязывают к вендору и стоят в 5–50 раз дороже. Для стартапа с бюджетом — однозначно свой бот на Python с бесплатной Ollama. Для enterprise с compliance-требованиями — тоже свой, но на GPT-4o.

✅ Итог

AI-агент поддержки на Python — это не магия, а инженерная сборка из четырёх компонентов: классификатор интентов (pydantic + LLM), RAG-поиск (chromadb + эмбеддинги), генератор ответов с guardrails и модуль эскалации на оператора. Весь стек умещается в 300 строк Python и один main.py.

Стартовые затраты: $0 на инфраструктуру (один VPS за $5/мес тянет 1000+ диалогов/день) и $0.01–0.05 на диалог через OpenAI API — или $0 при использовании локальной Ollama и открытых моделей. Для голосовых ответов — цены ElevenLabs от $5/мес за озвучку. Следите за обновлениями и новыми инструментами в нашем Telegram-канале:

ПОДПИСАТЬСЯ НА @QANTCORE