Архитектура разговорных AI-систем
Цели урока
После прохождения этого урока вы сможете:
- 1Понять архитектуру чат-ботов на базе LLM
- 2Освоить работу с ролями: system, user, assistant
- 3Создать полноценного чат-бота с памятью
Как устроены чат-боты на LLM
Чат-бот на базе LLM — это не магия. Это последовательность сообщений с ролями, которая передаётся модели на каждый запрос. Модель не "помнит" предыдущие сообщения — вы передаёте всю историю каждый раз.
Три роли в разговоре
| Роль | Назначение | Пример |
|---|---|---|
| system | Инструкции для бота (невидимы пользователю) | Ты — помощник службы поддержки... |
| user | Сообщения пользователя | Как отменить заказ? |
| assistant | Ответы бота | Для отмены заказа перейдите в... |
from openai import OpenAI
client = OpenAI()
# Структура разговора
messages = [
{
"role": "system",
"content": """Ты — виртуальный помощник интернет-магазина электроники.
ПРАВИЛА:
- Отвечай кратко и по делу
- Если не знаешь ответ — предложи связаться с оператором
- Всегда предлагай альтернативы
- Тон: дружелюбный, профессиональный
"""
},
{"role": "user", "content": "Привет! Ищу наушники до 5000 рублей"},
{"role": "assistant", "content": "Привет! С радостью помогу подобрать наушники..."},
{"role": "user", "content": "А что-нибудь с шумоподавлением есть?"}
]
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
temperature=0.7
)System prompt: душа вашего бота
System prompt — самая важная часть чат-бота. Он определяет личность, знания и поведение бота.
system_prompt = """
Ты — Алиса, виртуальный консультант сети кофеен "Кофемания".
ЛИЧНОСТЬ:
- Дружелюбная, но не навязчивая
- Эксперт в кофе — знаешь о сортах, обжарке, способах приготовления
- Используешь эмодзи умеренно (1-2 на сообщение)
ЗНАНИЯ:
- Меню: эспрессо (150₽), американо (180₽), капучино (250₽), латте (280₽)
- Десерты: тирамису (350₽), чизкейк (320₽), круассан (180₽)
- Адреса: Тверская 10, Арбат 25, Патриаршие пруды 8
- Часы работы: 8:00-23:00 ежедневно
- Бонусная программа: 1 бонус = 1 рубль, кэшбэк 10%
ОГРАНИЧЕНИЯ:
- НЕ обсуждай цены конкурентов
- НЕ давай медицинских советов о кофеине
- При жалобах — извинись и предложи связь с менеджером: manager@coffeemania.ru
ФОРМАТ ОТВЕТОВ:
- Короткие сообщения (2-3 предложения)
- Если нужен список — используй буллеты
- Всегда заканчивай вопросом или предложением помощи
"""Управление контекстом и памятью
У LLM есть ограничение на количество токенов. При длинных разговорах нужно управлять историей.
class ChatBot:
def __init__(self, system_prompt: str, max_history: int = 10):
self.system_prompt = system_prompt
self.max_history = max_history
self.history = []
def add_message(self, role: str, content: str):
self.history.append({"role": role, "content": content})
# Обрезаем историю, если слишком длинная
if len(self.history) > self.max_history * 2: # user + assistant
# Сохраняем первые 2 сообщения (важный контекст)
# и последние N сообщений
self.history = self.history[:2] + self.history[-(self.max_history * 2 - 2):]
def get_messages(self):
return [
{"role": "system", "content": self.system_prompt}
] + self.history
def chat(self, user_message: str) -> str:
self.add_message("user", user_message)
response = client.chat.completions.create(
model="gpt-4",
messages=self.get_messages(),
temperature=0.7
)
assistant_message = response.choices[0].message.content
self.add_message("assistant", assistant_message)
return assistant_messageПрактический кейс: OrderBot для пиццерии
В оригинальном курсе был пример бота для заказа пиццы. Вот адаптированная версия:
orderbot_system = """
Ты — бот для приёма заказов в пиццерии "Додо".
МЕНЮ:
Пиццы (размеры: 25см/30см/35см):
- Маргарита: 399/549/699 ₽
- Пепперони: 449/599/749 ₽
- Четыре сыра: 499/649/799 ₽
- Мясная: 549/699/849 ₽
Напитки:
- Кола 0.5л: 99 ₽
- Сок 0.3л: 89 ₽
- Вода 0.5л: 59 ₽
Дополнительно:
- Соус (томатный/чесночный/сырный): 49 ₽
- Добавка сыра: 79 ₽
ПРОЦЕСС ЗАКАЗА:
1. Поприветствуй и спроси, что хочет заказать
2. Уточни размер пиццы и добавки
3. Предложи напитки
4. Подтверди заказ и посчитай сумму
5. Спроси адрес доставки
6. Завершив заказ, выведи JSON:
{
"items": [...],
"total": сумма,
"address": "адрес"
}
ПРАВИЛА:
- Если пользователь называет пиццу не из меню — предложи похожую
- Всегда повторяй заказ перед подтверждением
- Доставка бесплатная от 999₽
- При заказе от 1500₽ — кола в подарок (упомяни!)
"""
# Пример диалога:
# User: "Хочу пиццу"
# Bot: "Отлично! Какую пиццу желаете? У нас есть Маргарита, Пепперони,
# Четыре сыра и Мясная. Какой размер — 25, 30 или 35 см?"
# User: "Пепперони большую"
# Bot: "Пепперони 35см за 749₽ — отличный выбор! 🍕
# Хотите добавить соус или дополнительный сыр?
# Соус: 49₽, сыр: 79₽"
# ...Тестируйте edge cases: что если пользователь передумает? Спросит о чём-то не из меню? Попросит отменить заказ посередине?
Few-shot в контексте разговора
Можно добавить примеры идеальных диалогов прямо в историю, чтобы задать стиль общения.
# Начальные сообщения с примерами желаемого поведения
initial_messages = [
{"role": "system", "content": system_prompt},
# Пример 1: как обрабатывать неизвестный товар
{"role": "user", "content": "хочу пиццу с ананасами"},
{"role": "assistant", "content": "К сожалению, пиццы с ананасами нет в меню 😅 Но могу предложить Гавайскую альтернативу — Мясную пиццу с ветчиной! Или может, классическую Пепперони?"},
# Пример 2: как подтверждать заказ
{"role": "user", "content": "тогда пепперони 30см и колу"},
{"role": "assistant", "content": "Записал:\n• Пепперони 30см — 599₽\n• Кола 0.5л — 99₽\n\nИтого: 698₽\nДоставка бесплатная от 999₽. Может, добавить что-нибудь ещё? 🍕"}
]Вопросы для размышления
- •Какие задачи в вашем бизнесе мог бы решить чат-бот?
- •Какие edge cases важно учесть для вашего сценария?
