LLM может быть уверена в своём ответе, но это ещё не означает, что системе разрешено выполнять действие. В AI Career Inbox Assistant разделены понимание сообщения, принятие решения и фактическое выполнение действия. Модель извлекает намерение и факты, профиль кандидата остаётся источником истины, а отдельный policy/decision layer определяет, что можно сделать: подготовить draft, попросить пользователя принять решение, ничего не делать или отправить безопасный автоответ при заранее заданных условиях.На практике это особенно важно для Telegram‑ассистента, который может отвечать от имени пользователя. Ошибка в тексте и ошибочное действие — не одно и то же: второе уже становится архитектурной проблемой. Поэтому в статье разбирается, почему UNKNOWN должен оставаться неизвестным, почему уверенность LLM не должна расширять права системы и почему даже правильное решение требует отдельной защиты на уровне исполнения, например от повторной отправки сообщения.Главный принцип: уверенность модели — это сигнал для принятия решения, но не разрешение на действие. Читать далее
Уровень сложностиПростой
Время на прочтение9 мин
Охват и читатели420
У LLM есть неприятное свойство: она может очень убедительно ответить на вопрос, на который у неё нет надёжных данных. Для обычного чат‑бота это может быть просто ошибкой в тексте. Для ассистента, который способен отправлять сообщения от моего имени, это уже проблема архитектуры.
Иногда мне пишет рекрутер в Telegram, и на первый взгляд сообщение выглядит совсем простым: человек представляет вакансию, спрашивает про интерес к позиции, уточняет формат работы или предлагает короткое интервью. Но за таким сообщением быстро появляется цепочка действий: нужно понять, о какой вакансии идёт речь, сохранить контекст разговора, сопоставить вопросы рекрутера с моим опытом, подготовить ответ и решить, что вообще можно отправлять от моего имени автоматически.
Именно для этой задачи я сделала AI Career Inbox Assistant — Telegram‑бота, который помогает разбирать входящие сообщения от рекрутеров. Он хранит контекст конкретных вакансий и историю диалога, извлекает из сообщений нужную информацию, сверяется с профилем кандидата и правилами ответа, а затем выбирает действие: подготовить draft, попросить меня принять решение, ничего не делать или, в узком случае, отправить безопасный автоответ.
В первой версии я думала прежде всего о качестве текста: насколько хорошо AI понимает сообщение и насколько естественно формулирует ответ. Но довольно быстро обнаружилась другая, гораздо более интересная проблема. Даже очень хороший ответ может быть неправильным действием, если система не должна была отправлять его самостоятельно.
Поэтому в этой статье я хочу разобрать не весь Career Inbox и не все его функции, а один архитектурный принцип, который оказался для меня самым важным:
что модель считает вероятным
≠
что системе разрешено сделатьTelegram дал мне возможность автоматизировать ответыВ Telegram Business есть возможность подключить бота, который обрабатывает сообщения и может отвечать от имени аккаунта, причём доступ бота можно ограничивать определёнными чатами. Для моего проекта это очень удобная возможность: часть сообщений действительно не требует моего участия, и если рекрутер спрашивает что‑то простое, а ответ состоит только из заранее подтверждённых фактов, нет особого смысла каждый раз писать его вручную. Но здесь появляется важная граница: техническая возможность автоматически ответить ещё не означает, что AI должен автоматически отвечать. Поэтому я не стала строить схему:
сообщение
↓
LLM
↓
ответ
↓
отправитьДоступ бота можно ограничить выбранными чатами и разрешениями.
Настройки автоматизации чатов в Telegram: доступ бота можно ограничить выбранными чатами и разрешениями.
Мне хотелось другой модели:
сообщение
↓
LLM понимает контекст
↓
система проверяет факты и policy
↓
решение о разрешённом действии
↓
отправка / draft / вопрос пользователюИменно здесь для меня появилась главная идея статьи:
Сначала я думала о качестве ответаconfidence ≠ permission
Когда я только начинала делать AI Career Inbox, задача выглядела довольно привычно:
сообщение рекрутера
↓
LLM
↓
предложенный ответНо довольно быстро стало понятно, что хороший текст — ещё не хороший результат. Можно написать идеально сформулированный ответ и при этом ошибиться в самом важном: имею ли я вообще право отправлять его автоматически? Например, модель может увидеть в сообщении рекрутера название технологии и решить, что у кандидата наверняка есть похожий опыт. Для генерации текста это может выглядеть правдоподобно, но для автоматической отправки от моего имени — уже нет. Поэтому я перестала рассматривать LLM как компонент, который принимает финальное решение. Она может анализировать сообщение, выделять намерение, извлекать факты и предлагать вариант ответа, но последнее слово должно принадлежать не модели.
Confidence ≠ PermissionМне кажется, это одно из самых полезных разделений, которое я получила из этого проекта. Условно здесь есть два разных вопроса:
LLM:
«Насколько вероятно, что я правильно поняла сообщение?»
Policy:
«Имеет ли система право выполнить действие?»Это не одно и то же. Даже если модель очень уверена в своей интерпретации, это ещё не означает, что действие разрешено. Например:
Are you based in Serbia and do you have Tableau experience?
Первая часть может быть подтверждена моим профилем. А Tableau в профиле нет. В такой ситуации модель вполне может попытаться построить связный ответ, опираясь на похожие BI‑инструменты. Но моя система должна остановиться:
Serbia → known
Tableau → UNKNOWN
Result → ASK_USERДля меня это важнее, чем способность модели красиво сформулировать ответ.
Inference — не verified factОтсюда появилось ещё одно правило: я разделяю то, что модель вывела из сообщения, и то, что действительно известно системе. Источником фактов о кандидате является профиль. Если в нём написано, что я работала с PostgreSQL, это можно использовать как подтверждённый факт. Если в профиле нет Tableau, система не должна превращать другие BI‑инструменты в «примерно тот же опыт». То есть:
из сообщения → inference
из профиля → verified factЭто небольшая разница в терминах, но архитектурно она очень важна. LLM может сказать:
The candidate probably has similar experience.Система не должна автоматически превращать probably в:
The candidate has experience.Если факта нет, результатом остаётся UNKNOWN. И это нормально.
Обычно от AI‑системы хочется получить как можно больше определённых ответов. Мне пришлось привыкнуть к обратному: иногда правильный результат — это не YES и не NO, а UNKNOWN.
UNKNOWNДальше система должна:
UNKNOWN
↓
не придумывать
↓
не отправлять автоматически
↓
передать решение пользователюНа практике это означает, что неизвестность становится частью модели данных, а не исключением, которое нужно срочно заполнить предположением. Для моего сценария это особенно важно, потому что бот говорит от моего имени. Если AI ошибся в обычном черновике, я могу исправить текст. Если он самостоятельно отправил неверное утверждение рекрутеру, исправлять его уже поздно.
Между LLM и Telegram появился decision layerПосле этого архитектура стала выглядеть примерно так:
Recruiter message
↓
LLM
↓
intent + extracted facts
↓
conversation / job context
↓
candidate profile
↓
reply policy
↓
decision
↓
┌───────────────┐
│ AUTO_REPLY │
│ DRAFT │
│ ASK_USER │
│ NO_REPLY │
│ ESCALATE │
└───────────────┘
↓
actionЭто не отдельная «умная модель», а слой ограничений. LLM помогает понять, что происходит, policy решает, что разрешено делать, а Telegram‑часть отвечает за фактическое выполнение действия. Так я разделила систему на три уровня:
Understanding
↓
Decision
↓
ExecutionAI разобрал сообщение и контекст вакансии, но передал окончательный выбор пользователю.
Пример решения ASK_USER: AI разобрал сообщение и контекст вакансии, но передал окончательный выбор пользователю.
И мне стало намного проще понимать, где именно искать ошибку. Если модель неправильно поняла сообщение — проблема в анализе. Если модель всё поняла правильно, но система разрешила неправильное действие — проблема в policy. Если решение было правильным, но сообщение ушло два раза — это уже проблема execution/state management.
Permission важнее уверенности моделиСамый простой пример — автоматические ответы. Я действительно разрешаю боту самостоятельно отвечать на некоторые вопросы, если ответ состоит только из подтверждённых фактов профиля и попадает в заранее разрешённый сценарий. Но это не означает:
«Если модель уверена, отправляй».
Правило устроено наоборот:
«Если действие разрешено policy и все необходимые факты подтверждены, его можно выполнить».
Поэтому даже очень уверенный ответ модели не может расширить список разрешённых действий. Это принципиальная граница. Модель не может сама решить:
«Я уверена на 98%, поэтому добавлю ещё один факт».У неё просто нет такого права.
Почему я не хочу максимальной автономностиКогда говорят об AI‑ассистентах, естественно хочется убрать как можно больше ручных действий. Но для моего сценария максимальная автономность не является целью сама по себе. Мне важнее другая формула:
maximum useful automation
+
minimum uncontrolled decisionsПоэтому есть действия, которые можно автоматизировать, и есть действия, где система должна остановиться. Если сообщение содержит только подтверждённые и разрешённые факты — возможен AUTO_REPLY. Если нужен хороший текст, но отправлять его автоматически нельзя — DRAFT. Если нужно моё решение — ASK_USER. Если отвечать вообще не нужно — NO_REPLY. Если ситуация выходит за предусмотренные правила — ESCALATE. То есть «ничего не делать» тоже является нормальным результатом работы AI.
Здесь я столкнулась с другой проблемой. Допустим, система правильно решила:
decision = AUTO_REPLYЭто ещё не гарантирует, что сообщение будет отправлено ровно один раз. Что произойдёт, если процесс упадёт после отправки в Telegram, но до сохранения результата в SQLite? При перезапуске система может решить, что действие ещё не выполнено. И попробовать отправить его снова. Поэтому пришлось разделить decision и execution state. Для pending‑действий у меня появился жизненный цикл:
PENDING
↓
SENDING
↓
SENTПри этом переход в SENDING должен выполняться так, чтобы два процесса не смогли одновременно забрать одно и то же действие. Для меня это был хороший пример того, почему AI‑архитектура заканчивается не на prompt и не на выборе модели. Можно идеально решить, что нужно сделать, и всё равно получить неправильный результат, если не продумать, как именно это действие будет выполнено.
Я не пыталась сразу построить большую систему правил. Обычно цикл был намного проще:
изменить правило
↓
перезапустить приложение
↓
отправить тестовое сообщение в Telegram
↓
посмотреть extracted facts
↓
посмотреть decision
↓
проверить фактическое действиеДля разработки и тестирования я использовала Deploy‑F. Это был удобный способ быстро перезапускать приложение, менять конфигурацию и проверять реальные Telegram‑сценарии. При этом сама логика не привязана к Deploy‑F: проект написан на Python и использует обычный runtime, SQLite и Telegram Business API. Мне был важен именно короткий feedback loop. Не «я написала огромный prompt и надеюсь, что он работает», а:
правило
→
тестовый сценарий
→
decision
→
фактический результатСборка и запуск тестовой версии AI Career Inbox Assistant.
Deploy‑F сборка и запуск тестовой версии AI Career Inbox Assistant.
Так постепенно становилось видно, где модель пытается сделать слишком много, а где ограничение действительно находится на уровне системы.
Что изменилось в архитектуре после этогоСамое главное изменение оказалось не в конкретном prompt. Я перестала считать LLM центром системы и теперь думаю о ней как об одном из компонентов:
┌──────────────┐
│ LLM │
│ understanding│
└──────┬───────┘
↓
┌──────────────┐
│ Policy │
│ permission │
└──────┬───────┘
↓
┌──────────────┐
│ Execution │
│ Telegram/API │
└──────────────┘И это меняет сам подход к разработке. Я больше не спрашиваю только:
«Насколько хорошо модель отвечает?»
Я задаю ещё два вопроса:
«Что модель имеет право утверждать?»
и
«Что система имеет право сделать на основании этого ответа?»
Для AI‑ассистента, который просто разговаривает с пользователем, эта граница может быть менее критичной. Но для ассистента, который действует от имени человека, она уже становится частью бизнес‑логики.
ИтогСамый полезный вывод из этого проекта для меня оказался довольно простым:
Уверенность модели не должна быть разрешением на действие.
LLM может анализировать, предполагать, извлекать факты и готовить текст. Но право на действие должно определяться отдельными правилами системы. Поэтому хороший AI‑ассистент для меня — это не тот, который умеет сделать всё самостоятельно. Это тот, который умеет понять:
я знаю
→ могу предложить
я знаю и мне разрешено
→ могу выполнить
я не знаю
→ не придумываю
мне нужно решение пользователя
→ останавливаюсьИ, пожалуй, именно способность остановиться оказалась для моего проекта не ограничением AI, а одной из его самых полезных функций.
Исходный кодПубличная версия проекта: https://github.com/YuliyaPV/ai‑career‑inbox‑assistant
В публичной версии проекта я не использую реальные Telegram ID, переписки, токены или рабочий профиль. Публичная версия предназначена прежде всего как шаблон архитектуры: персональный слой и правила поведения должны задаваться отдельно. Проект я разрабатывала с помощью ChatGPT, используя его как AI pair programmer.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Омнимодель для Алисы AI: как нам удалось подружить VLM и LLM | 0 | 7.4 | 03-09-2026 |
| 2 | Почему хорошего UX недостаточно: дизайнеру нужно уметь объяснять свои решения | 0 | 8.73 | 02-10-2026 |
| 3 | ИИ заберёт тексты и код. Но это никогда не было главной работой человека. Часть 4 | 0 | 9.38 | 01-10-2026 |
| 4 | LLM уверенно называет шахматные ходы, которых на доске нет. Как я проверяю каждый ее ответ кодом | 0 | 5.87 | 26-09-2026 |
| 5 | Как сделать интерактивного агента с помощью KV‑кеш‑манипуляций | -1 | 8.84 | 23-09-2026 |
| 6 | RuntimeNodes: как мы, ML‑щики, стали писать рантайм | 0 | 7.74 | 24-09-2026 |
| 7 | الذكاء الاصطناعي موظف ينفذ .. من يملك زر الإيقاف | 0 | 7.88 | 29-09-2026 |
| 8 | FAIRouter. Мы научили ИИ выбирать лучшую LLM модель для каждой задачи | 0 | 8.09 | 02-10-2026 |
| 9 | Зачем нейросети «обвязка»: как превратить LLM в рабочий AI-сервис | 0 | 9.97 | 30-09-2026 |
| 10 | От чата c LLM к полноценному AI-агенту: пошаговая настройка OpenCode | 0 | 7.88 | 29-09-2026 |