TL;DR
Componentization — метод автоматического разбиения ответа LLM на независимые семантические блоки (компоненты), которые можно редактировать, включать/выключать и регенерировать по отдельности. Исследователи из Honda Research Institute предлагают архитектуру CBRA, где ответ не финальный текст, а набор конструктора из заголовков, параграфов, списков, кода — каждый со своим ID и типом.
Главная боль — дилемма Copy-Paste. Модель выдала длинный ответ, но одна часть не устраивает. Два плохих пути: (1) скопировать весь текст в редактор — потеряешь контекст разговора, LLM больше не поможет; (2) попросить модель переписать — рискуешь испортить хорошие части, получить совсем другой ответ. Это как пытаться отредактировать один абзац в отчёте на 5 страниц — либо ручками в Word, либо заново переписывать всё.
Суть решения: три операции на уровне компонента вместо работы с монолитом. Edit — правишь конкретный блок текста прямо на месте. Toggle — включаешь/выключаешь компоненты (убрал вводную часть, оставил только суть). Regenerate — модель перегенерирует один компонент, остальные не трогает. Финальный документ собирается автоматически из выбранных и отредактированных частей.
Схема метода
Исследователи построили систему MAODchat с четырьмя колонками:
КОЛОНКА 1: Промпт пользователя
↓
КОЛОНКА 2: Полный ответ LLM (монолит)
↓
КОЛОНКА 3: Автоматическая декомпозиция
[Заголовок] [id: c1, type: Heading]
[Параграф 1] [id: c2, type: Paragraph, links: c1]
[Код] [id: c3, type: Code]
→ здесь Edit / Toggle / Regenerate каждого блока
↓
КОЛОНКА 4: Динамическая сборка финального документа
Процесс MAOD (Modular and Adaptable Output Decomposition):
- Parse: находит блоки текста, код, списки, цитаты
- Segment: делит на логические куски (не просто абзацы!)
- Classify: назначает тип (Heading, Paragraph, Code, List)
- Link: связывает компоненты (параграф принадлежит заголовку)
- Validate: проверяет целостность
- Export: выдаёт структурированный JSON
Всё выполняется автоматически после генерации ответа.
Пример применения
⚠️ Ограничения метода: Система требует инфраструктуры (микросервисы, база данных). Но принципы можно применить в обычном чате.
Задача: Ты пишешь питч для инвесторов. Попросил ChatGPT набросать структуру презентации. Модель выдала 8 слайдов, но слайд про команду — слабый, а про рынок — перегружен цифрами. Остальное огонь.
Промпт (классический чат — имитация компонентизации):
Дай структуру питча для стартапа в EdTech (подготовка к ЕГЭ).
Разбей на слайды. Каждый слайд оформи так:
---
## [Название слайда]
[Контент слайда]
---
Нумеруй слайды. После каждого блока ставь разделитель "---".
Результат: Модель выдаст структурированный ответ с явными границами между слайдами. Теперь можешь:
- "Перепиши только слайд 3 (Команда). Фокус на экспертизе в образовании, убери общие фразы."
- "Слайд 5 (Рынок) — убери половину цифр, оставь только TAM/SAM в млрд рублей."
- "Дай 3 варианта слайда 7 (CTA для инвесторов)."
Каждая правка локальна — остальные слайды не трогаешь. Это принцип componentization вручную: структура + явные границы + целевые правки.
Почему это работает
LLM генерирует последовательно, слово за словом. Когда просишь "исправь одну часть", модель часто переписывает всё заново — потому что у неё нет понятия "компонент", только "весь текст как поток токенов". Это как пытаться отредактировать один кадр в видео, переснимая весь ролик.
У LLM есть сильная сторона: она отлично понимает структуру (заголовки, списки, параграфы) и может работать с явными инструкциями ("перепиши блок между ---"). Когда ты явно обозначаешь границы компонентов (через разделители, нумерацию, XML-теги), модель видит их как отдельные объекты.
Метод использует это: система разбивает ответ на компоненты с ID и типами, хранит связи между ними (параграф принадлежит заголовку), и пользователь манипулирует конкретным компонентом. При регенерации только этот компонент уходит модели на переписывание — остальные остаются нетронутыми.
Рычаги управления (для ручного применения в чате):
- Разделители (
---,===, XML-теги) → чёткие границы компонентов, проще адресовать - Нумерация/ID ("Слайд 3", "Параграф 2") → точная адресация при правках
- Типы компонентов ("это заголовок, это код, это таблица") → модель по-разному обрабатывает
- Toggle-инструкции ("дай без вводной части", "только структура без текста") → убираешь "воду" сразу
Шаблон промпта (ручная имитация componentization)
{задача}
Разбей ответ на логические блоки. Каждый блок оформи так:
---
### [ТИП: {тип_компонента}] [НАЗВАНИЕ]
{контент_блока}
---
Типы компонентов: Заголовок, Параграф, Список, Код, Таблица, Цитата.
Нумеруй блоки. После каждого ставь разделитель "---".
После генерации я смогу сказать: "Перепиши блок 3" или "Убери блоки 1 и 5" —
и ты будешь менять только конкретные блоки, не трогая остальные.
Что подставлять:
{задача}— твоя задача (написать статью, объяснить код, составить план){тип_компонента}— тип блока (Заголовок, Параграф, Список, Код и т.д.){контент_блока}— содержимое конкретного блока
Для сложных структур (код, таблицы, многоуровневые документы):
🚀 Быстрый старт — вставь в чат:
Вот шаблон компонентизированного вывода. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит: "Какие типы компонентов нужны для твоей задачи?" (например, для кода: Функция, Класс, Импорты, Тесты). Она возьмёт паттерн структурированного вывода и адаптирует под специфику задачи — ты получишь готовый промпт с правильными типами компонентов.
Ограничения
⚠️ Требует инфраструктуры для полной реализации: MAODchat — это микросервисная система (Flask, FastAPI, PostgreSQL, LangGraph). Обычный пользователь не может развернуть такую архитектуру. Принципы применимы в чате вручную (структурированный вывод + локальные правки), но автоматизация требует кода.
⚠️ Латентность декомпозиции: Автоматическое разбиение на компоненты добавляет задержку. Модель сначала генерирует полный ответ, потом второй запрос разбивает его. Для задач, где важен real-time стриминг, это медленно.
⚠️ Зависимость от качества сегментации: Если система неправильно разбила ответ (слила два параграфа, разбила код на куски), редактирование станет хуже, чем с монолитом. Вся ценность упирается в точность декомпозиции.
⚠️ Компоненты не всегда независимы: Текущая модель считает все блоки независимыми. На деле введение и заключение связаны, код зависит от импортов, таблица — от контекста. Система не отслеживает эти зависимости и не предупреждает о рассинхронизации при правках.
Как исследовали
Команда Honda Research Institute построила MAODchat — полноценную систему на микросервисах. Пять сервисов: Flask-фронтенд (интерфейс с 4 колонками), FastAPI-бэкенд (оркестрация), FastAPI MAOD Agent (декомпозиция через state machine на LangGraph), PostgreSQL (хранение состояния), Caddy (reverse proxy). Архитектура vendor-agnostic — может работать с любым LLM провайдером через Dynamic Model Factory (использует Python reflection для подключения моделей на лету).
Провели пользовательское исследование с 4 участниками: академический исследователь, продакт-менеджер с HCI-бэкграундом, два инженера. Сессии по 45-60 минут: hands-on работа с системой + полуструктурированные интервью. Задачи: написание email, генерация кода, создание outline для статьи, подготовка слайдов.
Главные находки из user study:
- Scaffolding workflow — участники использовали компонентизацию для построения структуры документа. Генерируют полный отчёт, выключают все компоненты кроме заголовков, переставляют разделы, потом возвращают контент. Один участник сказал: "это точно совпадает с моим процессом — сначала outline, потом итеративная правка секций".
- Удаление "воды" — почти все отметили пользу toggle для убирания ненужных блоков. LLM часто добавляет введения и заключения — в componentization их выключаешь одним кликом, вместо ручного удаления текста.
- Путаница с терминологией — участники ожидали ChatGPT-подобное поведение. Различие между "Edit" (ручная правка) и "Regenerate" (модель перегенерирует) было неочевидным. Один инженер ожидал, что "Edit позволит править inline без повторного промпта". Это показало: интерфейс ушёл слишком далеко от привычных паттернов, создал когнитивную нагрузку.
- Проблемы форматирования — markdown, нумерованные списки иногда терялись при декомпозиции. Участники назвали это "разрушительным" (disruptive).
- Командные сценарии — несколько участников независимо представили team workflows: менеджер разбивает проект на компоненты, раздаёт секции команде для редактирования, потом система собирает всё обратно. Один участник провёл аналогию с "GitHub для документов".
Почему результаты получились такими: Компонентизация решает реальную боль (локальные правки без потери контекста), но текущий интерфейс создаёт когнитивный разрыв с привычными чат-паттернами. Технические ограничения (форматирование, context window) мешают применению на сложных задачах. Но для правильно выбранного scope (небольшие документы, код, планы) система показала ценность.
Оригинал из исследования (опционально)
Контекст: Исследователи описывают минимальную схему для декомпозированного ответа — каждый компонент имеет структурированное представление.
Minimal schema for a decomposed response:
| Field | Type | Description |
|---|---|---|
id | string | Stable component identifier |
type | enum | Component class (Heading, Paragraph, List, Code, Citation) |
content | string | Component text payload |
meta | map | Metadata (level, role, style) |
includes | bool | Whether the component is selected for recomposition |
links | list | Inter-component relations (e.g., belongs_to: c1) |
Пример JSON-структуры:
[
{ "id": "c1", "type": "Subject", "content": "Project update" },
{ "id": "c2", "type": "Greeting", "content": "Hi team," },
{ "id": "c3", "type": "Paragraph",
"content": "We shipped v1.2 today...",
"links": ["c1"] }
]
```
Это не просто разбиение по параграфам — это **семантическая декомпозиция** с типами и связями. Система понимает, что параграф c3 относится к теме c1 (Subject).
---
## Адаптации и экстраполяции
💡 **Адаптация для работы в обычном чате:** MAODchat — сложная система, но принцип применим **вручную через промпты**.
**Техника: Структурированный вывод + явная адресация**
Вместо автоматической декомпозиции — попроси модель **явно разметить компоненты**:
```
Напиши коммерческое предложение для B2B-клиента (автоматизация склада).
Раздели на блоки:
1. [ЗАГОЛОВОК] — название письма
2. [ПРИВЕТСТВИЕ] — обращение
3. [ПРОБЛЕМА] — боль клиента
4. [РЕШЕНИЕ] — как наш продукт решает
5. [ЦИФРЫ] — экономика проекта
6. [CTA] — призыв к действию
7. [ПОДПИСЬ] — кто отправляет
Каждый блок начинай с [ТИП] в квадратных скобках.
```
**Эффект:** Получаешь **псевдокомпонентизацию**. Теперь можешь:
- "Перепиши блок [ПРОБЛЕМА] — добавь кейс про потери от пересорта"
- "Убери блок [ЦИФРЫ], заменю своими расчётами"
- "Дай 3 варианта блока [CTA]"
Модель видит явные границы и работает **локально с конкретным блоком**, не переписывая всё письмо.
---
🔧 **Техника: Toggle через условия → гибкий контроль вывода**
В MAODchat есть `includes: bool` — флаг включения компонента. В чате можешь имитировать через **условные инструкции**:
```
Напиши статью про нейросети для корпоративного блога.
Структура:
- [INTRO] — вводная часть (про историю AI)
- [MAIN] — основная часть (как используем в бизнесе)
- [TECH] — технические детали (архитектура моделей)
- [CONCLUSION] — заключение
Условия вывода:
- Если аудитория "менеджеры" → пропусти [TECH]
- Если аудитория "разработчики" → пропусти [INTRO], сразу [TECH]
- Если аудитория "широкая" → дай всё
Моя аудитория: {указать}
```
**Эффект:** Одна и та же структура, но **динамическая сборка** в зависимости от контекста. Это toggle без кнопок — через prompt engineering.
---
💡 **Экстраполяция: Компонентизация для кода**
Исследование фокусировалось на тексте, но **принцип универсален**. Для кода компоненты:
- **Imports** (зависимости)
- **Config** (константы, настройки)
- **Functions** (отдельные функции)
- **Classes** (классы)
- **Tests** (тесты)
- **Main** (точка входа)
**Промпт для кода:**
```
Напиши Python-скрипт для парсинга CSV и загрузки в PostgreSQL.
Разбей код на блоки:
```python
# === IMPORTS ===
[зависимости]
# === CONFIG ===
[настройки БД, пути файлов]
# === FUNCTION: parse_csv ===
[функция парсинга]
# === FUNCTION: upload_to_db ===
[функция загрузки]
# === MAIN ===
[точка входа]
```
Каждый блок начинай с комментария "=== [ИМЯ] ===".
Эффект: Теперь можешь сказать:
- "Перепиши блок FUNCTION: upload_to_db — добавь batch insert"
- "Замени CONFIG на переменные окружения"
- "Убери MAIN, мне нужна только библиотека"
Модель видит модульную структуру и редактирует конкретный компонент, не ломая остальной код.
Ресурсы
Componentization: Decomposing Monolithic LLM Responses into Manipulable Semantic Units
Ryan Lingo, Martin Arroyo, Ben Davis, Rajeev Chhajer, Luka Brkljacic, Nithin Santhanam
Honda Research Institute, USA, Inc.
Related work:
- Low-code LLM: GUI over large language models (Cai et al., 2024)
- Beyond the chat: Executable and verifiable text-editing with LLMs (Laban et al., 2024)
- LLM asks, you write: Flipped interaction for collaborative writing (Chen et al., 2025)
