Урок 0016 · System Design мок: Customer-care бот банка

Полный разбор того, как кандидат ведёт 45 минут на доске: сценарий, архитектура, вопросы рекрутера и как на них отвечать. Это «репетиция подкаста» — читай вслух, ставь таймер.

Сценарий «Спроектируй AI-бота поддержки клиентов банка. Клиенты спрашивают про комиссии, лимиты, статус карты, блокировку. Внутренние политики — в PDF, обновляются ежемесячно. Может ли бот говорить баланс?»

Фаза 1. Clarify (первые 4 минуты)

Что говорит кандидат:

«Прежде чем рисовать, уточню несколько вещей. Кто пользователи — розничные клиенты, ES/EN? Источники знаний — только внутренние политики или ещё статус карты из банковских систем? Какие данные можно показывать — баланс, лимиты, чужие счета? Есть ли требования к резидентности данных — можно ли vendor API? Какой целевой p95 латентности? И что хуже для бизнеса: бот отказался ответить (эскалация на человека) или выдумал лимит?»

Почему это сильно: ты зафиксировал юзера, источники, права, vendor, латентность и cost-of-error ДО архитектуры. Рекрутер видит, что ты думаешь о безопасности и бизнесе, а не о красивых боксах.

Вопросы рекрутера на этой фазе

Вопрос: «А если клиент спросит баланс — это же личные данные?»

Ответ: «Баланс показываем только после авторизации, и цифру берём ТОЛЬКО из тула get_balance, а не из памяти модели. В ответе не должно быть account_id, отличного от авторизованного. Это output guard — проверка кодом, не судьёй».

Вопрос: «Почему бы не дать боту все инструменты сразу?»

Ответ: «Excessive agency — риск из OWASP LLM Top 10. FAQ-боту не нужен доступ к переводам. Минимум прав + HITL на деньги. Сначала граф: интент → FAQ / account-tool / человек».

Фаза 2. Success-метрики (3 минуты)

Что говорит кандидат:

«Зафиксирую, что такое хороший бот. Offline: ID-recall политик, faithfulness на FAQ, „цифры только из тула" — кодом, handoff precision/recall. Online: resolution без вранья, recontact за 72 часа, эскалация, $/диалог, p95, PII-leak = 0. Не CSAT первым и не containment — бот может „закрыть" диалог враньём».

Вопрос рекрутера

Вопрос: «Почему не CSAT?»

Ответ: «CSAT — это уже после факта и он субъективен. Resolution и recontact показывают, решилась ли проблема технически. CSAT смотрю вторым — как голос пользователя, не как метрику качества бота. Плюс containment не равен качеству: можно „закрыть" диалог, соврав про лимит, — поэтому главная связка resolution + PII-leak = 0».

Фаза 3. Estimate (3 минуты)

Что говорит кандидат:

«Прикину масштаб. 1M клиентов, 3% пишут в поддержку в месяц = 30k диалогов/мес ≈ 1000/день ≈ пик 2–3 RPS. Средний диалог: 2000 токенов вход (система + контекст + история), 300 выход. Корпус политик: 200 PDF ≈ 50k токенов, обновляется ежемесячно. Стоимость на фронтир-API: ~$0.01/диалог ≈ $300/мес — дёшево, GPU не окупается на этом объёме. Значит, стартую на API».

Почему это сильно: ты связал объём → стоимость → решение local vs API (урок 0009/0015). Показал, что считаешь, а не «возьму GPT».

Фаза 4. Sketch (8 минут)

Что рисует кандидат:

INGESTION (ночь, после обновления PDF):
PDF → Tika → секции → chunk по заголовкам → embed + BM25
→ ACL (премиум/все) → версия v2026-03 → index

QUERY (каждый запрос):
вход → input guard (PII, injection)
→ router: FAQ | account-status | human
   ├─ FAQ → hybrid retrieve → metadata filter → rerank → prompt с цитатами
   ├─ account-status → get_balance (тул) → цифра в ответ
   └─ human → handoff с саммари
→ generate T=0 → output guard (цифры из тула, нет чужого account)
→ лог: request_id, chunk_ids, prompt_version, cost

Почему router, а не один агент: 80% запросов — FAQ и статус. Это workflow (Anthropic), не свободный ReAct. Дёшево, предсказуемо, легко eval-ить.

Вопросы рекрутера

Вопрос: «Почему не дать модели самой решать?»

Ответ: «Workflow ≠ agent. Здесь ветки известны заранее: FAQ, статус, человек. Роутер предсказуем, дёшев и его можно тестировать отдельно (router accuracy). Свободный агент добавляю только когда ветки нельзя нарисовать — а тут можно».

Вопрос: «А если router ошибётся?»

Ответ: «Router-accuracy — отдельный eval на золотом наборе интентов. При ошибке: если сомнение — идём в human, безопаснее. И ошибки router — это данные для следующей итерации: добавляю интент в few-shot».

Фаза 5. Deep dive: eval + retrieval (15 минут)

Что говорит кандидат:

«Копну в eval и retrieval — это главное. Начинаю с error analysis: 100 реальных трейсов, первый важный фейл, частоты. По опыту: stale version политики, wrong skill, PII-утечка — топ-3. На каждый — бинарный eval: версия кодом, права кодом, правильный скилл — судьёй с TPR/TNR на holdout. Retrieval: ID-recall по chunk_id на золотых парах, faithfulness на FAQ. Потом A/B: когда офлайн не различает варианты».

Почему это ядро: это инсайд раунда (evals) и то, что отличает сильного кандидата.

Вопросы рекрутера

Вопрос: «Как поймёшь, что виноват retrieval, а не генерация?»

Ответ: «Лог chunk_ids. Жалоба → смотрю: нужный chunk был в промпте? Был — виновата генерация (faithfulness низкий). Не был — виноват retrieval (recall низкий). Квадрант „где дыра": recall↑faith↓ → промпт; recall↓faith↑ → поиск».

Вопрос: «Что если судья ошибается?»

Ответ: «Судья — классификатор. 30–80 человеческих меток, TPR/TNR на holdout, не accuracy. Судья „всегда ок" при 5% фейлов даёт 95% accuracy и ловит ноль. Плюс criteria drift: перекалибрую, когда смотрю новые выходы».

Фаза 6. Failures (7 минут)

Что говорит кандидат:

«Что может сломаться: пустой retrieval (индекс не содержит ответа) → „не знаю, перевожу", не выдумывать. Отравленный чанк (инъекция в PDF) → контекст недоверенный, action только через тулы. PII-утечка → output guard, ноль терпимости. Провайдер 500 → fallback + circuit breaker. Stampede (1000 одинаковых вопросов) → exact cache. Регрессия промпта → eval в CI. Сменили политику → версия документа, инвалидация кэша».

Фаза 7. Evolve (3 минуты)

Что говорит кандидат:

«v0: router + FAQ-RAG + статус из тула + handoff. v1: голос/STT поверх того же текстового ядра, OCR документов, fine-tune если формат не садится. Сознательно не беру: свободный ReAct на все API карты, GraphRAG, semantic cache без замеров».

Финальный вопрос рекрутера

Вопрос: «С чего начнёшь в понедельник?»

Ответ: «Сэмпл диалогов поддержки, 2 часа error analysis, три бинарных eval-а на топ-фейлы, golden set 100 пар, прогон двух моделей на нём. Дашборд RAGAS — после, не вместо. Параллельно — счёт стоимости на реальном трафике».

Чек-лист: что оценивает рекрутер

КритерийТы показал
Clarify перед архитектуройЮзер, источники, права, vendor, латентность, cost-of-error
Метрики ДО кодаOffline + online, resolution ≠ containment
Eval-drivenError analysis → бинарные eval → TPR/TNR
БезопасностьACL, PII, injection, HITL, минимум прав
ЭкономикаСчитал объём и стоимость, local vs API
Workflow ≠ agentRouter, не свободный ReAct

Проверь себя (мок-вопросы рекрутера)

Ответь вслух на каждый, потом сверься с ответами выше:

  1. «Почему не дать боту все инструменты сразу?»
  2. «Почему не CSAT?»
  3. «Как поймёшь, что виноват retrieval?»
  4. «Что если судья ошибается?»
  5. «С чего начнёшь в понедельник?»
Первоисточник урока Этот мок собирает уроки 0001–0003, 0007, 0013. Базовая методология: KDnuggets — How to answer AI system design interview questions.

Sources: