Prompt Slicing ADR
- 1. Статус и назначение документа
- 2. Контекст
- 3. Проблема, которую нужно было решить
- 4. Рассмотренные варианты
- 5. Принятое решение
- 6. Детализация принятого решения
- 6.1. Для slicing используется отдельный batch contract
- 6.2. Tagged sections разбираются без AI, если это возможно
- 6.3. AI slicing не является источником истины без дополнительной проверки
- 6.4. Режим обновления композиции отличается от первичного slicing
- 6.5. Публикация идёт блок за блоком через обычный block lifecycle
- 6.6.
Prompt Slicingдокументируется отдельно отBlock Generation
- 7. Последствия решения
- 8. Риски и меры снижения
- 9. Что сознательно не покрывается
- 10. Связанные документы
1. Статус и назначение документа
Статус: принят и отражает текущее реализованное поведение.
Назначение: зафиксировать архитектурные решения для функции разбиения большого prompt-текста на пакет переиспользуемых блоков, включая режим обновления существующей композиции с сохранением структуры.
2. Контекст
В TextFoundry есть два близких, но разных AI-сценария:
-
генерация одного блока;
-
разбор большого prompt на набор reusable blocks.
Второй сценарий оказался существенно сложнее, потому что он работает не с одним draft, а сразу с пакетом будущих изменений. Пользователь ожидает от системы не просто "предложи несколько кусочков текста", а:
-
сохранить осмысленные границы секций;
-
по возможности переиспользовать существующие
block_id; -
не разрушить текущую композицию при обновлении;
-
опубликовать набор блоков и при необходимости собрать из них обновлённую композицию.
По коду это реализовано через BlockSliceViewModel, PromptSlicingRequest,
Engine::GenerateBlockBatchData(…) и отдельный workflow публикации пакета.
3. Проблема, которую нужно было решить
Нужно было решить, как встроить batch slicing в продукт так, чтобы он:
-
ускорял миграцию длинного prompt в библиотеку блоков;
-
не разрушал уже существующую структуру композиции;
-
не превращался в "слепую" массовую генерацию без review;
-
не зависел только от качества ответа модели;
-
позволял работать как с AI, так и с частично детерминированным разбором размеченных секций.
Именно здесь простой перенос single-block generation недостаточен:
-
у batch-сценария другие риски;
-
пакет нужно валидировать целиком;
-
ошибки в одном элементе могут испортить всю публикацию;
-
сохранение структуры становится требованием первого класса.
4. Рассмотренные варианты
Вариант A. Чисто детерминированный slicing без AI
Идея: поддерживать только прямой разбор текста по тегам или простым правилам.
Плюсы:
-
предсказуемость;
-
отсутствие внешней AI-зависимости;
-
упрощённая отладка.
Минусы:
-
работает только для уже хорошо размеченных исходников;
-
плохо переносит естественный текст без явных секций;
-
не помогает в реальных сценариях миграции сложных prompt-артефактов.
Вердикт:
-
отклонено как единственный путь, но сохранено как fast path для tagged sections.
Вариант B. Повторять single-block generation в цикле
Идея: разбить исходный текст на части вне контракта engine, а затем многократно вызывать генерацию одного блока.
Плюсы:
-
меньше новых интерфейсов;
-
можно переиспользовать существующий single-block API.
Минусы:
-
теряется целостное представление о наборе блоков;
-
нельзя задать требования по сохранению структуры на уровне всей пачки;
-
сложнее контролировать reuse existing ids и сохранение порядка;
-
валидация конфликтов между сгенерированными блоками становится разрозненной.
Вердикт:
-
отклонено, потому что batch-сценарий требует собственного контракта.
Вариант C. Batch generation с ручным review и публикацией
Идея:
использовать отдельный PromptSlicingRequest, валидировать результат как
набор, показывать пользователю preview и публиковать блоки только после review.
Плюсы:
-
можно передавать в модель контекст о текущей структуре;
-
возможно переиспользование существующих id;
-
есть единая точка batch validation;
-
пользователь сохраняет контроль до публикации.
Минусы:
-
workflow сложнее;
-
часть safety-checks лежит в UI workflow, а не только в engine;
-
публикация пакета может прерваться на середине при первой ошибке.
Вердикт:
-
выбранный вариант.
5. Принятое решение
Принято решение оформлять prompt slicing как отдельный batch authoring workflow с тремя уровнями обработки:
-
детерминированный fast path для уже размеченных секций;
-
AI-assisted batch generation через
IBlockGenerator; -
обязательный review и ручная публикация результатов.
Дополнительно зафиксированы правила:
-
slicing не публикуется автоматически;
-
при update-сценарии система старается сохранить существующие logical boundaries и block ids;
-
batch validation проверяет не только отдельные блоки, но и набор целиком;
-
режим обновления композиции отличается от режима первичного разбиения.
6. Детализация принятого решения
6.1. Для slicing используется отдельный batch contract
Причина: у пользователя есть не просто "текст для генерации", а источник, который надо декомпозировать с сохранением структуры.
Поэтому PromptSlicingRequest включает:
-
source_text; -
preferred_language; -
namespace_prefix; -
existing_block_ids; -
reusable_block_ids; -
reusable_block_summaries; -
preserve_reuse_percent; -
preserve_order; -
allow_id_collision.
Это принципиально богаче single-block request и отражает именно batch-задачу.
6.2. Tagged sections разбираются без AI, если это возможно
Причина:
если исходный текст уже содержит явные секции вида <Section>…</Section>,
вызов внешней модели не нужен.
В текущем коде GUI сначала пытается:
-
выделить секции по тегам;
-
угадать тип блока;
-
собрать description;
-
сформировать candidate ids;
-
переиспользовать подходящие существующие id.
Если такой разбор удался и дал достаточно секций, AI не вызывается вообще.
Это решение важно, потому что:
-
снижает стоимость и latency;
-
уменьшает риск лишнего переписывания;
-
лучше сохраняет исходную структуру там, где она уже явно задана.
6.3. AI slicing не является источником истины без дополнительной проверки
Причина: даже после engine-level validation batch может быть плохим по product-смыслу:
-
дублировать секции;
-
ломать expected namespace;
-
чрезмерно схлопывать структуру;
-
использовать неудобные или конфликтующие id.
Поэтому поверх результата провайдера есть дополнительная workflow-валидация в
BlockSliceViewModel, которая проверяет пригодность набора к публикации.
Это сознательный выбор: не считать provider response достаточным основанием для массового изменения библиотеки.
6.4. Режим обновления композиции отличается от первичного slicing
Причина: обновление уже существующей композиции должно быть консервативнее, чем создание нового набора блоков с нуля.
В update mode система:
-
загружает текущую композицию;
-
пытается взять её текущий render как источник для редактирования;
-
вычисляет namespace по composition id;
-
передаёт
reusable_block_idsи summaries текущей структуры; -
включает
preserve_order; -
управляет силой сохранения через
preserve_reuse_percent.
Это фиксирует архитектурный приоритет: при обновлении важнее сохранить структуру и идентичность частей, чем "красиво переизобрести" prompt заново.
6.5. Публикация идёт блок за блоком через обычный block lifecycle
Причина: slicing не создаёт отдельный тип сущности. Его выходом становятся обычные блоки, которые должны пройти тот же lifecycle, что и вручную созданные блоки.
Поэтому публикация batch-результата реализована через:
-
PublishBlock(…)для новых блоков; -
UpdateBlock(…)для reuse existing ids.
Это сохраняет единый storage contract и не вводит отдельное "batch-хранилище".
6.6. Prompt Slicing документируется отдельно от Block Generation
Причина: технически они используют один и тот же generator abstraction, но продуктово это разные функции.
Block Generation отвечает на вопрос:
"как получить один хороший reusable block".
Prompt Slicing отвечает на вопрос:
"как преобразовать большой prompt в набор блоков, не потеряв структуру".
Отдельный ADR нужен, потому что здесь главные решения связаны не с одним draft, а с preservation, reuse и batch safety.
7. Последствия решения
Положительные:
-
миграция длинных prompt-артефактов в библиотеку блоков сильно ускоряется;
-
update workflow может сохранять значительную часть существующей структуры;
-
tagged input часто обрабатывается без лишнего AI-вмешательства;
-
batch contract делает ограничения и намерения более явными.
Компромиссы:
-
часть correctness-проверок находится в GUI workflow, а не только в engine;
-
публикация набора требует большего числа шагов и больше UI-состояния;
-
логика update mode заметно сложнее, чем create mode.
Отрицательные:
-
качество результата чувствительно к качеству исходного prompt и summaries;
-
AI всё ещё может выдать structurally weak batch;
-
массовая публикация повышает стоимость ошибки по сравнению с single draft.
8. Риски и меры снижения
Риск: destructive update разрушит текущую композицию
Снижение:
-
режим сохранения структуры;
-
reuse existing ids;
-
preserve_reuse_percent; -
ручной review до публикации.
Риск: конфликтующие или плохие block_id
Снижение:
-
engine-level validation;
-
GUI batch validation;
-
явная работа со списком существующих и переиспользуемых id.
9. Что сознательно не покрывается
Данный ADR не фиксирует:
-
автоматическую транзакционную публикацию всей пачки как одной atomic unit;
-
серверный orchestrator для удалённого slicing;
-
полноценный semantic diff между старой и новой структурой;
-
автоматический выбор оптимального
preserve_reuse_percent.