AI support quality check в n8n: как проверять ответы поддержки до отправки клиенту ¶
Обновлено: 2026-05-29
Короткий ответ ¶
AI support quality check — это workflow, который проверяет черновик ответа поддержки до отправки клиенту: решает ли он проблему, не врёт ли по фактам, ссылается ли на источники, соблюдает ли tone of voice, не раскрывает ли персональные данные, не обещает ли невозможное и нужен ли human review. Это не “ещё один чат-бот”, а контрольный слой между AI draft/оператором и клиентом. Хороший quality check выдаёт score, список нарушений, конкретные исправления и решение: send, edit, escalate, ask for more info или block.
Зачем нужен quality check ¶
Поддержка часто страдает не от отсутствия ответов, а от нестабильного качества. Один оператор даёт точную инструкцию, другой забывает уточнить версию, AI draft уверенно обещает возврат, третий ответ не закрывает next step. На малом объёме это решается ручным ревью. На масштабе нужен автоматизированный контроль.
Quality check особенно полезен, если:
- AI готовит черновики ответов;
- новые операторы работают по сложной базе знаний;
- ответы касаются денег, персональных данных или интеграций;
- нужно соблюдать SLA и tone of voice;
- часто бывают reopen тикетов;
- есть разные каналы: email, чат, Telegram, CRM;
- база знаний быстро меняется.
Проверка не должна заменять оператора во всех случаях. Её задача — поймать риск до отправки.
Что именно проверять ¶
Rubric должен быть явным. Иначе модель будет оценивать “понравился ли ответ” вместо operational quality.
| Критерий | Что значит |
|---|---|
| Accuracy | ответ не противоречит источникам и данным клиента |
| Completeness | закрыты все вопросы пользователя |
| Actionability | есть конкретный следующий шаг |
| Policy compliance | нет запрещённых обещаний и действий |
| Tone | вежливо, ясно, без обвинений клиента |
| Source grounding | технические инструкции основаны на KB/RAG |
| Privacy | нет лишних PII, токенов, внутренних данных |
| Escalation | рискованные кейсы переданы человеку |
| SLA fit | ответ соответствует приоритету и срочности |
| Clarity | нет длинной воды, двусмысленности и jargon overload |
Для каждой компании rubric будет отличаться. Nodbot, например, должен особенно проверять техническую точность по n8n, webhook, credentials, Docker, OAuth, AI Agent и RAG.
Схема workflow в n8n ¶
- Trigger: draft created, ticket updated, AI Agent generated answer, operator clicked “send”.
- Context loader: подтянуть ticket history, customer plan, order status, KB chunks, policy.
- Draft normalizer: убрать подписи и привести текст к единому формату.
- Risk classifier: определить тему и риск: billing, legal, security, technical, low-risk.
- Quality checker LLM: оценить draft по rubric.
- Policy checker: отдельные правила для запретов: refund promise, password request, secret leak.
- Source checker: сравнить claims с retrieved sources.
- Score aggregator: итоговый score и решение.
- Router: send, edit suggestion, human review, escalation, block.
- Feedback log: сохранить score, нарушения, исправления и финальный outcome.
- Evaluation loop: сравнивать AI score с оценкой QA/тимлида.
Для критичных политик лучше не полагаться только на LLM. Добавьте rule checks: regex для токенов, email, API keys, запрещённых фраз, обещаний возврата.
Input для quality checker ¶
Чекер должен видеть не только draft, но и контекст. Иначе он не поймёт, отвечает ли текст на вопрос.
Пример input:
{
"ticket_id": "sup_10492",
"channel": "email",
"customer_message": "Оплатили, но чек не пришел. В CRM заказа нет.",
"draft_reply": "Здравствуйте! Проверьте папку Спам. Если письма нет, напишите нам позже.",
"customer_context": {
"plan": "business",
"order_status": "payment_succeeded",
"crm_deal_found": false
},
"retrieved_sources": [
{
"source_id": "diagnostics_yookassa",
"text": "При успешном платеже нужно проверить webhook, payment_id, metadata.order_id и повторную доставку уведомления."
}
],
"policy": {
"do_not_promise_refund_without_check": true,
"must_include_next_step_for_payment_issues": true
}
}
Этот пример показывает, почему draft плохой: он не учитывает статус платежа и не даёт next step по webhook/CRM.
Output schema ¶
{
"type": "object",
"required": ["decision", "score", "issues", "suggested_revision"],
"properties": {
"decision": { "type": "string", "enum": ["send", "edit", "review", "escalate", "block"] },
"score": { "type": "number", "minimum": 0, "maximum": 100 },
"issues": {
"type": "array",
"items": {
"type": "object",
"required": ["code", "severity", "message"],
"properties": {
"code": { "type": "string" },
"severity": { "type": "string", "enum": ["low", "medium", "high", "critical"] },
"message": { "type": "string" },
"evidence": { "type": "string" }
}
}
},
"suggested_revision": { "type": ["string", "null"] },
"missing_information": { "type": "array", "items": { "type": "string" } }
}
}
Decision должен быть machine-readable. Не заставляйте downstream nodes парсить свободный текст “ответ в целом нормальный, но...”.
Rubric scoring ¶
Сделайте score объяснимым:
| Критерий | Вес |
|---|---|
| Accuracy | 30 |
| Completeness | 20 |
| Actionability | 15 |
| Policy | 15 |
| Tone | 10 |
| Privacy | 10 |
Если privacy violation critical, итоговый decision должен быть block, даже если общий score высокий. Весовая сумма не должна скрывать критичные риски.
Пример агрегации:
const issues = $json.quality?.issues || [];
let decision = $json.quality?.decision || 'review';
const hasCritical = issues.some(i => i.severity === 'critical');
const score = $json.quality?.score ?? 0;
if (hasCritical) decision = 'block';
else if (score < 70) decision = 'review';
else if (score < 85) decision = 'edit';
else decision = 'send';
return [{ json: { ...$json, final_decision: decision } }];
Source grounding check ¶
Технические ответы должны быть grounded. Если draft говорит “перезапустите Redis”, а retrieved sources про OAuth, чекер должен заметить mismatch. Source check можно делать отдельным шагом:
- выделить claims из draft;
- сопоставить claims с sources;
- отметить unsupported claims;
- потребовать источники для команд, лимитов, политик и API-поведения;
- блокировать опасные unsupported instructions.
Для простых человеческих ответов sources не всегда нужны. Но для n8n-инструкций, Docker-команд, платежей и credentials — нужны.
Проверка tone of voice ¶
Tone check должен быть конкретным. Не “будь дружелюбным”, а:
- не обвинять пользователя;
- не использовать сарказм;
- не обещать невозможное;
- писать короткими шагами;
- объяснять технические термины;
- не скрывать неопределённость;
- завершать next step.
Плохой ответ: “У вас неправильно настроен webhook, перечитайте документацию.”
Хороший ответ: “Похоже, webhook не получил production-событие. Проверьте, активирован ли workflow, какой URL указан в ЮKassa и есть ли payment_id в журнале n8n.”
Policy checks ¶
Примеры policy rules:
- нельзя просить пароль или полный API token;
- нельзя обещать возврат без проверки статуса;
- нельзя раскрывать внутренние логи клиенту целиком;
- нельзя отправлять персональные данные третьим лицам;
- нельзя давать destructive commands без предупреждения;
- нельзя выдавать устаревшие инструкции, если source deprecated;
- нельзя автоматически закрывать тикет, если вопрос не решён.
Часть правил можно проверять regex/Code node. Например, API ключи:
const text = $json.draft_reply || '';
const patterns = [
/sk-[A-Za-z0-9_-]{20,}/,
/xox[baprs]-[A-Za-z0-9-]{20,}/,
/eyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/
];
const secretLeak = patterns.some(p => p.test(text));
return [{ json: { ...$json, secret_leak_detected: secretLeak } }];
Human review routing ¶
Не все проблемы требуют одинакового review. Разведите очереди:
| Decision | Что делать |
|---|---|
| send | отправить автоматически или показать оператору |
| edit | предложить исправление оператору |
| review | отправить QA/старшему оператору |
| escalate | передать в technical/billing/security |
| block | не отправлять, создать incident/task |
Review должен быть быстрым. Если оператор должен читать длинный JSON, он перестанет пользоваться системой. Покажите только draft, issues, suggested revision и кнопки.
Evals для quality check ¶
Нужен dataset с хорошими и плохими ответами. Для каждого кейса укажите expected decision и expected issues.
{
"case_id": "unsupported_refund_promise",
"customer_message": "Верните деньги",
"draft_reply": "Мы уже оформили возврат, деньги придут завтра.",
"expected_decision": "block",
"expected_issue_codes": ["unsupported_refund_promise", "missing_status_check"]
}
Метрики:
- agreement with QA;
- false allow rate;
- false block rate;
- average score drift;
- human edit distance;
- reopen rate after AI-approved replies;
- CSAT по auto-approved ответам.
Самая опасная метрика — false allow: плохой ответ прошёл проверку.
Ошибки quality check ¶
| Ошибка | Последствие | Исправление |
|---|---|---|
| Чекер видит только draft | не понимает контекст | добавить ticket/source context |
| Нет rubric | оценки непредсказуемы | schema + критерии + веса |
| Всё уходит в review | автоматизация бесполезна | thresholds и risk tiers |
| Чекер переписывает факты | новые hallucinations | suggested_revision только на основе sources |
| Нет feedback loop | качество не растёт | сохранять human corrections |
| Critical issues усредняются score | опасные ответы проходят | hard block rules |
Production checklist ¶
- [ ] Есть rubric с критериями и весами.
- [ ] Input включает customer message, draft, context, sources, policy.
- [ ] Output строго schema-based.
- [ ] Critical policy rules проверяются отдельно.
- [ ] Есть source grounding для технических claims.
- [ ] Есть routing: send/edit/review/escalate/block.
- [ ] Есть eval dataset хороших/плохих ответов.
- [ ] Есть human feedback loop.
- [ ] Логируются score, issues, final decision.
- [ ] PII и secrets маскируются.