В понедельник помощник уверенно сообщил клиенту, что возврат придёт за три дня. В базе знаний было десять рабочих дней. Ответ звучал лучше ответа стажёра, поэтому ошибку заметили только после повторного обращения.
Сначала режим черновика
Безопасный первый релиз не отвечает клиенту. Он классифицирует тикет, находит документы и готовит черновик оператору. Источники показываются рядом; принятие, правка и отклонение становятся разметкой. Автоответ включают позже для узких классов с низкой ценой ошибки.
тикет -> очистка PII -> классификация -> retrieval с ACL
-> генерация черновика с цитатами -> проверка фактов
-> оператор или автоответ -> outcome через 7 днейclass Draft(BaseModel):
answer: str
source_ids: list[str]
needs_human: bool
reason: str | None
async def prepare(ticket, actor) -> Draft:
docs = await search(ticket.text, tenant=actor.tenant_id, acl=actor.groups)
draft = await llm.structured(prompt="support-v12", ticket=ticket, docs=docs,
schema=Draft)
if not draft.source_ids or ticket.intent in HIGH_RISK_INTENTS:
draft.needs_human = True
return draftИсточники проверяются сервером: каждый source_id должен быть среди выданных retrieval документов. Модель не назначает компенсацию и не меняет заказ. Для таких действий она готовит предложение, а оператор подтверждает его через обычный backend с бизнес-валидацией.
Failure modes
Устаревшая статья ранжируется выше действующей. Клиент вставляет в тикет инструкцию игнорировать правила. Retrieval смешивает tenant. Оператор машинально нажимает «отправить». Метрика средней скорости улучшается, но повторные обращения растут. Поэтому нужны versioned knowledge base, ACL до retrieval, маркировка недоверенного текста, лимит автоматизации и outcome-метрика.
Правило: помощник поддержки получает право отвечать только на тот класс обращений, где источники, цена ошибки и путь эскалации известны заранее.
Практикум 48.1
Соберите 100 обезличенных тикетов и отметьте intent, нужный источник, допустимость автоответа и итог через семь дней. Реализуйте draft-only поток. Проверьте groundedness, долю принятых без правки черновиков, время оператора и повторные обращения. Добавьте десять тикетов с prompt injection и убедитесь, что они не меняют политику ответа.