Тема
AI Workbench: подготовка данных
Статус: реализованный контракт Workbench v0.6.0. Новые intent добавляются в registry отдельно и не считаются доступными заранее.
AI Workbench — внутренний сервис Endge, который готовит документацию, снимок Workspace и историю диалога для вызова выбранной AI-модели. Модель не получает нефильтрованный домен: до вызова все цели, сущности и источники проходят проверяемую подготовку.
Детали разнесены по этапам:
- Нормализация и план.
- Источники и извлечение.
- Разрешение сущностей.
- Цикл уточнений.
- Сборка контекста.
- Генерация и проверка.
Главный принцип
Workbench использует gated hybrid workflow:
- однозначные операции выполняются детерминированно;
- подготовительный вызов модели разрешён только при неоднозначном естественном языке;
- любой результат модели проходит валидацию по доверенному снимку Workspace;
- количество вызовов модели зависит от сложности запроса, а не от фиксированной цепочки;
- если данных недостаточно, Workbench спрашивает пользователя, а не просит модель додумать отсутствующие факты.
Общая схема
1. Нормализация
Перед классификацией Workbench алгоритмически:
- приводит текст к единой Unicode-форме;
- нормализует Unicode, регистр, пробелы и
ё/е; - выделяет кавычки, UUID и строки, похожие на identity;
- распознаёт поддерживаемые команды: «найди», «покажи», «объясни», «перечисли»;
- отмечает ссылки на историю: «она», «эта композиция», «предыдущая».
2. План задач
Первичный parser выделяет части по поддерживаемым разделителям, а Planner при необходимости преобразует их в задачи и зависимости направленного графа.
Например, запрос «Найди сущность „Объект Альфа“, затем покажи её» превращается в:
json
{
"tasks": [
{
"id": "task-1",
"intent": "find_entity",
"sourceMode": "domain",
"mentions": ["Объект Альфа"],
"dependsOn": []
},
{
"id": "task-2",
"intent": "inspect_entity",
"sourceMode": "domain",
"mentions": ["Объект Альфа"],
"dependsOn": ["task-1"]
}
]
}Начальный реестр задач:
explain_documentation;find_entity;inspect_entity;list_entities;unsupported— запрос вне текущих возможностей.
В v0.6.0 специальное семантическое правило существует только для folder scope: сначала разрешается папка, затем поиск дочерней задачи ограничивается её folderIdentity.
3. Planner gate
Сначала Workbench пытается построить план детерминированно. LLM Planner вызывается, если в запросе есть:
- несколько связанных задач;
- неявное намерение;
- ссылка на предыдущие реплики;
- низкая уверенность первичного parser.
Planner возвращает только структуру по заданной схеме. Он может выделить intent, тип и текстовое упоминание, но не может объявить найденный domain identity. После Planner план проверяется по реестру допустимых intent, типов и связей.
4. Маршрутизация источников
Каждая задача получает sourceMode:
sourceMode | Когда используется |
|---|---|
documentation | Общий вопрос о возможностях и синтаксисе Endge. |
domain | Вопрос только о текущем Workspace. |
mixed | Конкретный документ рассматривается с учётом правил из документации. |
conversation | Задача ссылается на ранее разрешённый контекст. |
none | Для ответа не нужны документация и снимок Workspace. |
Выбор domain не загружает документацию, а documentation не запускает извлечение доменных сущностей.
5. Разрешение доменных сущностей
Для каждого упоминания Workbench строит набор кандидатов. Сигналы применяются в порядке убывания надёжности:
- точное совпадение
documentType + identity; - точное нормализованное
displayName; - совпадение нормализованных токенов;
- упоминание в содержимом документа как слабый дополнительный сигнал.
Склонения, транслитерация и отдельная метрика edit distance в v0.6.0 не реализованы.
Результат разрешения:
| Статус | Действие |
|---|---|
resolved | Найден один уверенный кандидат. |
ambiguous | Найдено несколько близких кандидатов. |
not_found | Подходящих сущностей нет. |
unsupported_type | Тип пока не поддержан доменным resolver. |
После выбора цели resolver добавляет только подтверждённый snapshot сущности. В v0.6.0 единственная специальная иерархия — Folder → дочерние документы; произвольный граф связей пока не обходится.
6. Semantic Reranker
Если алгоритм нашёл несколько близких кандидатов, модель может помочь с ранжированием. Она получает только закрытый список кандидатов и может:
- выбрать один из переданных
candidateId; - вернуть
none; - запросить уточнение.
Модель не может вернуть произвольный identity. Выбранный candidateId снова проверяется Workbench.
7. Извлечение документации
Поиск по документации остаётся детерминированным. Для сложного вопроса модель может сформировать несколько поисковых выражений, но выбор фрагментов, удаление дублей и распределение бюджета выполняет Workbench.
8. Context Adequacy Gate
Перед сборкой итогового запроса Workbench проверяет:
- все ли задачи поддержаны;
- разрешены ли целевые сущности;
- присутствуют ли необходимые связи;
- найдены ли релевантные фрагменты документации;
- не была ли целевая сущность вытеснена бюджетом контекста.
Если проверка не пройдена, Workbench возвращает уточняющий вопрос без вызова итоговой модели.
9. Сохранение и продолжение Interaction
Один логический запрос может занять несколько сообщений. Workbench сохраняет его как Interaction с неизменяемым исходным сообщением, версионным планом и цепочкой уточнений.
Каждое уточнение привязано к interactionId, taskId, конкретному незаполненному полю и снимку предложенных кандидатов. Ответ пользователя изменяет только целевую часть плана, после чего зависимые задачи пересчитываются.
Перед продолжением Workbench проверяет, является ли новое сообщение ответом, исправлением, отменой или новым независимым запросом. Полная история не переписывается моделью в новый текст: единый ModelRequest собирается как производная проекция из исходного запроса, plan version и сохранённых уточнений.
Полный контракт цикла описан в разделе «Уточнения».
10. Контракт итоговой модели
Итоговая модель получает не сырой ExportLive, а подготовленный ModelRequest:
json
{
"request": "...",
"plan": { "tasks": [] },
"context": [],
"conversation": [],
"workspace": {
"generation": "...",
"snapshotSha256": "..."
}
}Модель формулирует связный ответ, но не изменяет план, не добавляет неизвестные источники и не выполняет domain-изменения.
11. Проверка ответа
После генерации Workbench алгоритмически проверяет:
- существуют ли identity, объявленные в
entityCitations; - были ли упомянутые документы переданы модели;
- соблюдён ли заданный формат;
- не заявляет ли ответ об изменениях, которые Workbench не выполнял.
Когда вызывается модель
| Сценарий | Подготовительные вызовы | Итоговый вызов |
|---|---|---|
| Точный identity | 0 | 1 |
| Понятный вопрос по документации | 0 | 1 |
| Сложный составной запрос | 1 — Planner | 1 |
| Неоднозначная сущность | 1 — Reranker | 1 |
| Сложный план и неоднозначная сущность | до 2 | 1 |
| Требуется уточнение | 0–2 | 0 |
Для связного ответа используется один итоговый вызов. Подготовительные задачи выполняются в валидированном порядке зависимостей; неограниченная параллельная оркестрация не используется.
Стабильные debug stages
При AI_DEBUG=true Workbench записывает этапы с фиксированными числовыми ID:
| ID | Файл | Содержание |
|---|---|---|
| 00 | metadata | request/run/Workspace metadata без credential |
| 01 | original-request | исходный текст пользователя |
| 02 | normalization | каноническое представление и сигналы |
| 03 | plan | валидированный task graph |
| 04 | routing | source mode каждой задачи |
| 05 | documentation | выбранные фрагменты и provenance |
| 06 | domain-resolution | кандидаты и разрешённый domain context |
| 07 | interaction-clarification | состояние продолжения запроса |
| 08 | conversation-context | ограниченное окно предыдущих сообщений |
| 09 | adequacy-context-plan | выбранные blocks и предупреждения adequacy gate |
| 10 | prompt-manifest | prompt ID, version и SHA-256 |
| 11 | model-request | итоговый запрос без provider credential |
| 12 | response-validation | результат проверки ответа |
Пропущенный этап сохраняется со status: skipped, чтобы последовательность оставалась диагностируемой.
Инварианты
- Backend остаётся единственной точкой доступа Configurator к Workbench.
- Workbench получает доверенный
ExportLiveи не читает базу Endge. - AI-модель не объявляет domain identity найденным без проверки Workbench.
- Точно разрешённая цель не вытесняется бюджетом контекста.
- Модель выбирает только из закрытого набора кандидатов.
- Недостаток данных приводит к уточнению, а не к случайному fallback.
- Исходный запрос внутри Interaction неизменяем; каждое уточнение порождает новую версию плана.
- Ответ на уточнение связан с конкретным
clarificationId, а не угадывается по всей истории. - Подготовительные циклы имеют жёсткий лимит; Workbench не запускает неограниченный автономный agent loop.
- Мутации домена не входят в этот flow.
Поэтапное развитие
find_entity,inspect_entityиlist_entities, включая ограничение папкой.- Детерминированные план, resolver и Context Adequacy Gate.
- LLM Planner для сложных и связанных задач.
- Semantic Reranker для ограниченного набора кандидатов.
- Дополнительные intent и правила связей после отдельного расширения registry.
- Каждый новый этап включается только после сравнения с набором размеченных запросов.