AI System Design

Middle+ в AI Team Plata. Инсайд раунда: eval-ы и выбор метрик. Формат 45 мин на доске публично не подтверждён — готовь generic + каре / документы / HR.

~12 ч видео
+ 4 ч моков
режь «если останется»,
не режь evals

Один экран — говорить это

Не читать абзацами. Если время вылетело — этот блок важнее всего остального.

Первые 4 минуты

Уточню: кто юзер, какие источники, можно ли vendor API, p95, что хуже — отказ или выдуманный лимит. Потом зафиксирую success: offline + online. Потом нарисую ingest и query.

Не рисовать боксы до этого.

Success каре

Offline: recall@k по chunk_id, faithfulness, «цифры только из tool» (код), handoff precision/recall.

Online: resolution без вранья, recontact 72ч, эскалация, $/диалог, p95, PII-leak = 0.

Не CSAT первым. Не «средний quality 4.2». Containment ≠ качество.

Как строю eval

  1. 50–100 трейсов, первый важный фейл, частоты.
  2. На топ-фейл — бинарный тест, не helpfulness.
  3. Code-check если можно; судья — один вопрос, pass/fail.
  4. Судью меряю TPR/TNR против человека на holdout. Accuracy не использую.
  5. A/B только когда офлайн не различает. 5–10% трафика, kill switch.
В Magnit умею тяжёлый A/B — поэтому не буду гонять каждый промпт в онлайн.

Квадрант дыры

recall низкий
recall высокий
faith низкий
мусор + додумывает
чанк был, модель врёт → промпт / отказ
faith высокий
честно пусто → retrieval
ок, смотри продукт / тон

Пайплайн

вход → PII/injection guard → router → hybrid retrieve + ACL → rerank → generate T=0 + cite → schema / «не знаю» / сверка цифр → лог (prompt ver, chunk_ids, $) → человек если надо

v0: FAQ + статус. Не свободный ReAct на все API карты.

RAG vs FT vs agent

Факты живые → RAG. Форма/тон стабильны → FT. Действие в системе → workflow. Agent — только если ветки нельзя нарисовать заранее.

Якоря с CV

  • Kontur: schema linking + few-shot retrieval + generate/fix + vote. Метрика — SQL exec / эталон, не «красивый SQL».
  • Карты: кластер → few-shot бриф → генерация. Это prompt construction.
  • Magnit: одна жёсткая метрика, честный A/B. Поэтому офлайн-eval для промптов, онлайн — редко.

Пробелы одной фразой

Ragas в проде не крутил — контуры свои. OCR/voice не деплоил — спроектирую + field F1 / WER на ваших данных. Go не основной.

С чего начнёшь в понедельник

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

Неделя

Цель не «посмотреть 20 часов». Цель: на доске провести 45 минут и в каждом слое сказать метрику. После каждого видео закрой вкладку и расскажи вслух 3 минуты.

Д1
Evals как процесс
Hamel 50 мин + 2 поста
FAQ
Д2
RAG-метрики руками
DL.AI RAG triad ~2 ч
Evidently guide
Д3
Каркас ответа на доске
Chip 75 мин + Gaurav до 34:44
Think Software 20 мин
Д4
Agents vs workflow
Anthropic пост + 27 мин
DL.AI Evaluating Agents
Д5
Метрики наизусть + Plata
Эта страница + RAG Q 1:10–1:23
Anthropic agent evals
Д6
Мок 1: customer-care
45 мин вслух, запись
Д7
Мок 2: документы / OCR
45 мин + прогон карточки

Плейлист

Ядро — не пропускать

Если день 4–5 свободен

Не на эту неделю

Как вести 45 минут

Самый частый фейл — рисовать боксы до требований.

  1. Clarify 4 мин. Кто юзер? Источники? PII / резидентность? p95? Vendor API? Что хуже: отказ или выдуманный лимит?
  2. Success 3 мин. Offline + online. Без этого это чат, не система.
  3. Estimate 3 мин. QPS, токены, $, корпус, свежесть.
  4. Sketch 8 мин. Два пайплайна: ingestion и query. Гарды до и после LLM.
  5. Deep dive 15 мин. Один слой — у тебя eval + retrieval. Не 12 квадратиков.
  6. Failures 7 мин. Пустой retrieval, отравленный чанк, stampede, 500 провайдера, PII, регрессия промпта.
  7. Evolve 3 мин. v0 / v1 / что сознательно не берёшь.
Сначала зафиксирую, что считается хорошим ответом, потом нарисую пайплайн, который это можно измерить.

Evals — главный сигнал

Три уровня (Hamel)

УровеньЧтоКогда
L1 codeJSON-схема, regex суммы, не вернул чужой account_id, SQL execДетерминированные инварианты
L2 human + judgeТрейсы, потом узкий судья на один failure modeОткрытый текст, тон, опора на политику
L3 A/BResolution, эскалация, CSAT, $/диалогКогда офлайн уже не врёт
Сначала assertion’ы как тесты. Потом смотрю трейсы и только на повторных ошибках пишу судью. A/B — когда офлайн не отличает варианты.

Error analysis раньше метрик

  1. Сэмпл 50–100 трейсов.
  2. На каждый — первый важный фейл, не корневая причина.
  3. Сгруппировать, посчитать частоты.
  4. Eval на топ-3 повторных фейла, не на helpfulness.
Я не начинаю с RAGAS dashboard. Я сначала читаю диалоги и считаю, какая поломка самая частая. Потом на неё — бинарный тест.

Off-the-shelf helpfulness / coherence / hallucination score — чужой промпт под пятью слоями. Он не ловит ваш каре.

LLM-as-judge, чтобы не стыдно

  • Один судья = один вопрос, binary pass/fail, не 1–5.
  • 30–80 человеческих меток.
  • Мерить TPR и TNR, не accuracy. Судья «всегда ок» имеет 95% accuracy на 5% ошибках и ловит ноль фейлов.
  • Few-shot только из train, holdout не трогать.
  • Сильная модель на судью, дешёвая в прод — если задача позволяет.
  • Перекалибровка: criteria drift — критерии рождаются, когда смотришь новые выходы.
Судья — это модель. Не доверяю ему, пока не сниму TPR/TNR против человека на holdout. Likert не использую: разница 3 vs 4 — шум.

Три грейдера (Anthropic)

ГрейдерПримерыСилаСлабость
Codeschema, regex, SQL exec, tool-call, сумма = OCR-поледёшево, воспроизводимоломается на валидных вариациях
Modelrubric, groundedness, тоннюанснужна калибровка
Humanspot-check, новые фейлыground truthдорого, drift

У агента transcript (что сказал) ≠ outcome (создался ли тикет). pass@k — достаточно одного успеха (SQL). pass^k — нужна стабильность (лимит карты).

Метрики — какой рычаг чинит какую цифру

Не заучи все RAGAS. Заучи выбор.

Retrieval

МетрикаВопросGoldЕсли плохо
Recall@k / Context RecallНужный факт в top-k?даchunking, hybrid, k, rewrite
Precision@kМного ли мусора?даrerank, metadata, меньший k
MRR / nDCGНужный чанк высоко?даrerank
ID-based recallЗолотой doc_id в retrieved?да, лучший дешёвый тестingestion / ACL / версия

В банке логируй chunk_id и мерь ID-recall, не только LLM-judge.

Generation

МетрикаВопросСуть
FaithfulnessClaims сидят в контексте?supported / all claims
Answer relevancyОтвет про вопрос?reverse-questions → cosine
Citation accuracyСсылка на тот чанк?code + человек
Task successТикет / SQL / полебизнес, не RAGAS
Faithfulness высокий + recall низкий = честно молчит или отвечает по мусору. Recall высокий + faithfulness низкий = чанк был, модель додумала. Сначала квадрант, потом рычаг.

Онлайн каре

  • Resolution без эскалации
  • Escalation quality (вовремя? с контекстом?)
  • Recontact 24–72 ч
  • $ / диалог, p95, tokens
  • PII leak, запретные темы (инвест-совет, чужой баланс)
  • OCR: field-level F1, % авто, false-accept на сумме

Не первым

BLEU / ROUGE на чате. Cosine(answer, question) как «качество». LMSYS / MMLU. Один средний quality 4.2.

RAG за 8 минут

Два пайплайна, не один ящик «vector DB».

Ingestion: source of truth → ACL → чистка → chunk → embed + BM25 → version/doc_id → index.

Query: гарды (PII, injection) → rewrite только если eval доказал → hybrid → metadata filter → rerank → промпт с цитатами → generate T=0 → выходные гарды → лог.

  • Нет chunk_id в top-k → retrieval.
  • Chunk был, ответ врёт → generation / промпт / нет отказа.
  • Ответ верный, юзер недоволен → продукт / тон / не тот скилл.

Hybrid — дефолт: BM25 ловит номера договоров и лимиты, dense — перефразы.

RAG не нужен на классификацию интента, извлечение 4 полей, перефраз.

RAG = факты. Fine-tune = форма. Tool/agent = действие.

Для банка сначала выжимаю hybrid RAG + отказ. Fine-tune — если формат поля стабильно не садится. Свободный ReAct на все API карты — нет, это workflow с approval.

Exact cache на (prompt, system, model). Semantic cache в банке опасен: «дней отпуска» ≈ «дней больничного». Prefix-cache провайдера ортогонален.

Agents — когда да

Workflow = заранее прошитый граф. Agent = модель сама выбирает шаги. Сначала простой RAG, усложняешь когда eval показывает потолок.

ПаттернКогдаPlata
ChainingШаги фиксированыOCR → extract → verify → write
RoutingРазные классыFAQ / транзакция / человек
Parallel + voteНужна уверенность2 модели на сумму в документе
Orchestrator-workersПодзадачи неизвестныразбери тред из 40 писем HR
Evaluator-optimizerЕсть критерий, итерация помогаетпочинить SQL / переписать отказ
Agent loopОткрытый тул-юзредко в v0 каре

CompleteTravel — нормальный агентный кейс. Каре банка — граф «интент → RAG / tool / human». Approval на деньги и PII.

Режь агента: router accuracy, tool F1, trajectory, outcome, cost / turns / latency.

Агент — когда я не могу заранее нарисовать ветки и готов платить латентностью. В каре 80% — FAQ и статус карты, это router + RAG, не ReAct.

Модель, стоимость, A/B

Не «возьму GPT-5».

  1. Golden set 50–200 ваших примеров.
  2. 2–4 модели одним промптом.
  3. Смотреть где ломается (поле, отказ, формат, ES), не средний балл.
  4. Cost × quality. Дешёвая на роутинг, дорогая на сложный ответ и на судью.
  5. Потом узкий онлайн A/B.

Streaming для UX. Факт / сумма — дождаться проверки. Semantic cache — только если измерил false-hit.

В Magnit честный A/B цены — это ад: тысяча магазинов на контроль, праздники, полка. Поэтому 80% гипотез закрываю офлайн-eval за день. В прод — 5–10% трафика, первичная метрика ticket resolved / field correct, гарды эскалация / жалобы / $, kill switch. Единица рандомизации — диалог, не токен.

Лог: request_id, prompt_version, chunk_ids, model, tokens, latency, tool_calls, guard, handoff, cost. PII маскировать до провайдера и до лога.

Три сценария с доски

Это не подтверждённые вопросы. Это JD: chatbot, voice/STT, HR, OCR.

A. Customer-care — вести этот

Clarify: политики + статус карты? ES/EN? Можно ли баланс?

Ingest политик с версией → router FAQ / account-tool / human → hybrid RAG + ACL → generate + cite → post-guard (цифры только из tool) → handoff с саммари.

Eval v0: ID-recall политик, faithfulness FAQ, «цифры из tool» кодом, handoff P/R; online resolution, recontact, escalation, $.

Отказ: «не знаю, перевожу». Выдуманный лимит хуже эскалации.

Связка: Kontur = retrieval + generate + fix + vote. Карты = few-shot бриф. Magnit = одна метрика.

B. Документы / OCR — честный пробел

Не деплоил. Дальше: файл → тип → quality → OCR → layout → entities → сверка страниц и заявки → confidence → HITL → structured store. RAG уже по полям, не по картинке.

Eval: field F1, exact match на деньгах, false-accept, % straight-through. Vote двух моделей на сумме. После OCR это тот же linking, что schema linking в Text-to-SQL.

C. Voice / STT

Аудио → STT → тот же текстовый пайплайн → TTS. Eval STT = WER на их звонках MX-ES, не LibriSpeech. Не строить отдельную голосовую магию.

D. HR

FAQ + документы. Semantic cache опасен. Сменили «28 дней» на «30» — invalidate топик, как в turing-test-drive.

Качество плохое — 60 секунд

  1. 20 трейсов, не дашборд.
  2. Каждый: retrieval miss / generation lie / wrong skill / policy / UX.
  3. Частоты.
  4. Retrieval → chunk_id, не средний faithfulness.
  5. Фикс одного рычага, прогон golden set.
  6. Только потом онлайн.

Пробелы — не прятать

ТемаГовори
RagasИнструмент знаю, контуры свои (execution accuracy, WAPE, ручной разбор). Ragas/MLflow — как стандарт команды.
OCRНе деплоил. Спроектирую пайплайн и eval по полям.
VoiceНет. Переиспользую текстовый стек, WER на ваших звонках.
GoНе основной. Прочитаю сервис, напишу простой хендлер.
Fine-tune OSSБонус JD, не основной трек.

Мок, дни 6–7

Таймер 45 минут. Бумага. Потом себе:

  1. Какая одна первичная метрика и почему не CSAT?
  2. Как поймёшь, что виноват retrieval, а не LLM?
  3. Что в v0 сознательно не берёшь?
  4. Что логируешь, что маскируешь?
  5. Как остановишь плохой промпт в проде?
  6. Где человек и какая у него метрика?

День 6 — сценарий A. День 7 — B, потом эта карточка вслух целиком.