Разработка AI-бота для Slack на базе LLM

Проектируем и внедряем системы искусственного интеллекта: от прототипа до production-ready решения. Наша команда объединяет экспертизу в машинном обучении, дата-инжиниринге и MLOps, чтобы AI работал не в лаборатории, а в реальном бизнесе.
Показано 1 из 1 услугВсе 1566 услуг
Разработка AI-бота для Slack на базе LLM
Средняя
~3-5 рабочих дней
Часто задаваемые вопросы
Направления AI-разработки
Этапы разработки AI-решения
Последние работы
  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1218
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1161
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    853
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1047
  • image_logo-advance_0.png
    Разработка логотипа компании B2B Advance
    561
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    825

Разработка AI-бота для Slack на базе LLM

Slack Bot с LLM встраивает AI прямо в рабочий процесс команды: ответы на вопросы в каналах, суммаризация тредов, AI-помощник в DM. Технически — Slack Bolt SDK (Python/Node.js) + обработка событий через Socket Mode или webhooks.

Настройка приложения Slack

# Создать Slack App на api.slack.com/apps
# Включить: Socket Mode, Bot Token Scopes: app_mentions:read, channels:history,
#           chat:write, im:history, im:write, reactions:write
# Event Subscriptions: app_mention, message.im, message.channels

from slack_bolt.async_app import AsyncApp
from slack_bolt.adapter.socket_mode.async_handler import AsyncSocketModeHandler
from anthropic import AsyncAnthropic

app = AsyncApp(token="SLACK_BOT_TOKEN")
anthropic_client = AsyncAnthropic(api_key="ANTHROPIC_API_KEY")

# Хранилище историй диалогов (в production — Redis/PostgreSQL)
conversation_history: dict[str, list] = {}

Обработка упоминаний и DM

@app.event("app_mention")
async def handle_mention(event, say, client):
    """Реагирует на @botname в каналах"""
    text = event["text"]
    user_id = event["user"]
    thread_ts = event.get("thread_ts") or event["ts"]

    # Убираем упоминание бота из текста
    import re
    clean_text = re.sub(r'<@[A-Z0-9]+>', '', text).strip()

    # Получаем историю треда если есть
    history = await get_thread_history(client, event["channel"], thread_ts)

    # Добавляем emoji "думает"
    await client.reactions_add(
        channel=event["channel"],
        name="thinking_face",
        timestamp=event["ts"],
    )

    response_text = await generate_response(clean_text, history, user_id)

    await say(text=response_text, thread_ts=thread_ts)

    # Убираем emoji
    await client.reactions_remove(
        channel=event["channel"],
        name="thinking_face",
        timestamp=event["ts"],
    )

@app.event("message")
async def handle_dm(event, say, client):
    """Обрабатывает личные сообщения"""
    if event.get("channel_type") != "im":
        return

    user_id = event["user"]
    text = event.get("text", "")

    channel_id = event["channel"]
    history = conversation_history.get(channel_id, [])
    history.append({"role": "user", "content": text})

    response = await generate_response(text, history[-10:], user_id)

    history.append({"role": "assistant", "content": response})
    conversation_history[channel_id] = history[-20:]

    await say(text=response)

async def generate_response(text: str, history: list, user_id: str) -> str:
    """Генерирует ответ через Claude"""
    messages = history + [{"role": "user", "content": text}] if history else [{"role": "user", "content": text}]

    response = await anthropic_client.messages.create(
        model="claude-sonnet-4-5",
        max_tokens=2048,
        system="""Ты — AI-ассистент для команды разработчиков в Slack.
Отвечай кратко и по существу. Используй Markdown (поддерживается Slack).
Для кода используй блоки \`\`\`.""",
        messages=messages,
    )
    return response.content[0].text

Суммаризация тредов

@app.shortcut("summarize_thread")
async def summarize_thread(ack, shortcut, client, logger):
    """Shortcut для суммаризации треда (правая кнопка на сообщении)"""
    await ack()

    channel_id = shortcut["channel"]["id"]
    message_ts = shortcut["message"]["ts"]
    thread_ts = shortcut["message"].get("thread_ts") or message_ts

    # Получаем все сообщения треда
    thread_response = await client.conversations_replies(
        channel=channel_id,
        ts=thread_ts,
    )

    messages_text = "\n".join([
        f"<{m['user']}>: {m['text']}"
        for m in thread_response.get("messages", [])
        if m.get("text")
    ])

    # Суммаризируем
    summary_response = await anthropic_client.messages.create(
        model="claude-haiku-4-5",
        max_tokens=512,
        messages=[{
            "role": "user",
            "content": f"Суммаризируй этот тред в 3-5 пунктов:\n\n{messages_text}"
        }]
    )

    # Открываем modal с результатом
    await client.views_open(
        trigger_id=shortcut["trigger_id"],
        view={
            "type": "modal",
            "title": {"type": "plain_text", "text": "AI Суммаризация"},
            "blocks": [{
                "type": "section",
                "text": {"type": "mrkdwn", "text": summary_response.content[0].text}
            }]
        }
    )

Slash команды

@app.command("/ask")
async def ask_command(ack, command, say):
    """Команда /ask <вопрос> в любом канале"""
    await ack()

    question = command["text"]
    if not question:
        await say("Использование: `/ask ваш вопрос`")
        return

    response = await generate_response(question, [], command["user_id"])
    await say(text=f"**Вопрос:** {question}\n\n**Ответ:** {response}")

@app.command("/summarize")
async def summarize_command(ack, command, say, client):
    """Суммаризировать последние N сообщений канала"""
    await ack()
    # Получаем последние 20 сообщений
    history_response = await client.conversations_history(
        channel=command["channel_id"],
        limit=20,
    )
    # ... суммаризируем

Запуск

async def main():
    handler = AsyncSocketModeHandler(app, "SLACK_APP_TOKEN")
    await handler.start_async()

if __name__ == "__main__":
    asyncio.run(main())

Практический кейс: команда разработки 25 человек

Боль: разработчики постоянно спрашивали в Slack про внутренние процессы, конфиги, онбординг. Одни и те же вопросы.

Решение: бот с доступом к корпоративной базе знаний (Notion + Confluence через MCP/API).

Результат: 65% вопросов бот отвечает автономно. Время ожидания ответа: от часов → секунды.

Сроки

  • Базовый бот (DM + mentions): 2–3 дня
  • Суммаризация тредов + shortcuts: 2–3 дня
  • Slash команды + модальные окна: 2–3 дня
  • Интеграция с базой знаний: 1 неделя