TL;DR
T²RAG — метод, который разбивает сложный вопрос на атомарные факты в формате триплетов (субъект-предикат-объект) с плейсхолдерами "?" для неизвестных элементов, а затем итеративно разрешает эти триплеты. Вместо того чтобы генерировать длинные цепочки рассуждений (Chain-of-Thought), модель работает с компактными структурами типа "(?, director_birth, earlier)" и постепенно заполняет пропуски.
Главная проблема: Multi-round RAG методы (вроде IRCoT) генерируют объёмные текстовые рассуждения на каждом шаге — это съедает токены и замедляет работу. А Graph RAG требует дорогого построения графа знаний с проблемами дублирования сущностей и шумных связей. Обе категории работают с крупными кусками текста, теряя точность в деталях (compression loss — когда векторное представление длинного текста упускает важные факты).
Суть метода: LLM декомпозирует вопрос в триплеты трёх типов: resolved (без "?"), searchable (один "?"), fuzzy (два+ "?"). Затем система ищет в базе триплетов только по searchable, получает контекст, заполняет плейсхолдеры, обновляет состояние — и повторяет до полного разрешения. Это работает как компактный "мыслительный процесс", где каждый шаг — не абзац текста, а структурированная запись "(Film_A, director_born, 1985)".
Схема метода
ШАГ 1: Декомпозиция (1 промпт)
Вопрос → LLM → Триплеты с "?"
Категории: Resolved (0 "?"), Searchable (1 "?"), Fuzzy (2+ "?")
ШАГ 2: Итеративное разрешение (до N раундов)
2.1: Searchable триплеты → Поиск в базе → Триплеты + куски текста
2.2: LLM заполняет "?" используя контекст → Новые resolved/searchable
2.3: Обновить состояние: добавить resolved, заменить searchable, уменьшить fuzzy
Условие выхода: |Searchable ∪ Fuzzy| = 0 или достигнут лимит итераций
ШАГ 3: Финальный ответ (1 промпт)
Все resolved триплеты → LLM → Точный ответ
Пример применения
Задача: У тебя идея создать сервис аренды электросамокатов в Казани. Нужно проверить: стоит ли вообще запускаться, или конкуренты уже всё заняли? И какие города в России похожи по параметрам — может туда тоже зайти?
Промпт:
Разбей этот вопрос на атомарные факты (триплеты) с неизвестными элементами "?":
Вопрос: Насколько перегрет рынок аренды электросамокатов в Казани по сравнению с Екатеринбургом и Новосибирском? Какие города похожи на Казань, но менее конкурентны?
Формат триплета: (субъект, предикат, объект)
Используй "?" для неизвестного.
Затем по очереди:
1. Найди факты для триплетов с одним "?" (searchable)
2. Заполни "?"
3. Обнови триплеты
4. Повтори пока все "?" не заполнены
Итоговый ответ дай на основе всех resolved триплетов.
Результат: Модель сгенерирует структуру типа:
Searchable:
(Казань, количество_операторов_самокатов, ?)
(Екатеринбург, количество_операторов_самокатов, ?)
(Новосибирск, количество_операторов_самокатов, ?)
Fuzzy:
(?, население_сходно_с_Казанью, да)
(?, конкурентность_ниже_чем_Казань, да)
Потом модель найдёт данные (через web search или свои знания), заполнит первый раунд:
Resolved после раунда 1:
(Казань, количество_операторов, 4)
(Екатеринбург, количество_операторов, 5)
(Новосибирск, количество_операторов, 3)
Во втором раунде модель использует эти факты для поиска городов-аналогов:
Searchable после раунда 1:
(?, население, ~1.3млн)
(?, конкурентность, < 4_оператора)
→ Найдёт: Самара, Ростов, Краснодар
Финальный ответ синтезируется из всех resolved триплетов: "В Казани рынок средней конкурентности (4 оператора), Екатеринбург насыщен (5), Новосибирск спокойнее (3). Похожие города: Самара (1.1млн, 2 оператора), Ростов (1.1млн, 3 оператора)..."
Почему это работает
LLM плохо держат в голове многоходовые задачи при свободном рассуждении. В классическом multi-round RAG модель генерирует абзацы текста на каждом шаге — это расходует токены, а главное: детали теряются в "компрессии" длинных embedding'ов. Когда вы векторизуете абзац в 200 слов, важные факты размываются среди общих слов.
LLM хорошо умеют работать со структурами. Триплет — это минимальная единица знания, которая не теряет деталей. "(Компания_A, выручка_2024, 500млн)" — точный факт без шума. Когда модель ищет "(?, основатель, Илон Маск)", она получает конкретные сущности, а не куски текста про биографию.
Метод использует плейсхолдеры как "точки расширения". Вместо того чтобы генерировать "мне нужно узнать основателя компании", модель работает с явной структурой "(?, основатель, X)". Это убирает двусмысленность — модель точно знает ЧТО искать. И главное: между итерациями передаются компактные триплеты вместо длинных CoT — экономия токенов до 45%.
Рычаги управления:
- Число итераций (N=3) → увеличь до 5-7 для очень сложных вопросов с 4+ прыжками
- Количество плейсхолдеров → если вопрос простой, сразу формулируй searchable (1 "?"), пропуская fuzzy
- Формат вывода триплетов → добавь веса "(субъект, предикат, объект) [вес: 0.9]" чтобы модель показывала уверенность
- Условие остановки → замени "все resolved" на "достаточно фактов для ответа с уверенностью >0.8"
Шаблон промпта
Разложи вопрос на атомарные триплеты (субъект, предикат, объект) с плейсхолдерами "?" для неизвестного:
Вопрос: {твой_вопрос}
Шаг 1: Создай триплеты трёх типов:
- Resolved: без "?" — известные факты
- Searchable: ровно один "?" — можно искать
- Fuzzy: два+ "?" — нужно сначала resolve другие
Шаг 2: Итеративное разрешение (максимум {N} раундов):
РАУНД {i}:
2.1. Возьми Searchable триплеты → найди информацию {как_искать: web_search / база знаний / документы}
2.2. Заполни "?" используя найденный контекст
2.3. Обнови состояние:
- Добавь новые resolved
- Замени Searchable на новые (если остались)
- Убери из Fuzzy те, что стали Searchable или Resolved
Повторяй пока: |Searchable ∪ Fuzzy| > 0 или достигнут лимит раундов
Шаг 3: Финальный ответ
Используй ВСЕ resolved триплеты → дай точный ответ на {твой_вопрос}
Формат вывода:
=== РАУНД {i} === Searchable: [(субъект, предикат, ?), ...] Fuzzy: [(?, предикат, ?), ...]
[Поиск...]
Resolved (новые): [(субъект, предикат, объект), ...]
=== ФИНАЛЬНЫЙ ОТВЕТ === [На основе всех resolved триплетов]
Заполни:
{твой_вопрос}— сложный многоходовой вопрос (например: "Какая компания быстрее росла: Tesla или Rivian? И кто из их инвесторов получил лучший возврат?"){N}— максимум итераций (для большинства задач: 3-5){как_искать}— где брать информацию: web search, загруженные файлы, база знаний
Ограничения
⚠️ Зависимость от качества триплетов: Если факты изначально извлечены неточно или база триплетов неполная, метод не найдёт нужную информацию. В оригинальном исследовании базу триплетов строили с помощью OpenIE инструментов — для применения в чате ты полагаешься на способность модели самой создавать релевантные триплеты.
⚠️ Не для субъективных вопросов: Метод заточен под factoid QA (фактические вопросы типа "кто", "когда", "сколько"). Для креативных задач или оценочных суждений ("какой фильм лучше") триплеты теряют смысл — там нужна не декомпозиция фактов, а синтез мнений.
⚠️ Простые вопросы — overkill: Если вопрос решается одним поиском ("Столица Франции?"), структурная декомпозиция только замедлит. Используй метод для multi-hop задач с 2+ шагами рассуждения.
⚠️ Сложность для сущностей с many-to-many связями: Простые триплеты могут не покрывать сложные отношения. Например, "компания X сотрудничает с компаниями Y, Z по проектам A, B, C" — в триплет не уложить без потери деталей.
Как исследовали
Исследователи взяли 6 датасетов (1000 вопросов из каждого): простые вопросы (PopQA), мультихоп (2Wiki, MuSiQue, HotpotQA), domain-specific (Story, Medical). Сравнили T²RAG с тремя сильными бейзлайнами: HippoRAG2 (Graph RAG с PageRank), RAPTOR (hierarchical summarization RAG), IRCoT (multi-round RAG с CoT). Использовали единые модели для всех: NV-Embed-v2 для эмбеддингов, Gemini-2.5-flash или GPT-4o-mini как LLM.
Ключевой инсайт: T²RAG выиграл на мультихоп задачах с отрывом +7.7% (EM score) от IRCoT на датасете 2Wiki с Gemini. Это показывает, что структурированная декомпозиция через триплеты эффективнее для сложного reasoning, чем verbose CoT. При этом token consumption снизился на 45% по сравнению с IRCoT — потому что между итерациями передаются компактные триплеты вместо длинных абзацев.
Удивительный результат: несмотря на multi-round процесс, T²RAG сопоставим по скорости с single-round методами (HippoRAG2, RAPTOR). Это потому что фокусируется на точных триплетах, а не фильтрует длинные тексты. Более того, Graph RAG методы (LightRAG, оригинальный GraphRAG) требуют в 6-10 раз больше токенов на этапе построения графа по сравнению с простым извлечением триплетов в T²RAG.
Почему результаты такие: Триплеты дают zero compression loss — каждый факт сохраняется точно, без размытия в векторе длинного текста. А структурированный процесс (resolved → searchable → fuzzy) создаёт чёткую логику поиска, которую LLM легко выполнить без избыточных рассуждений.
Оригинал из исследования
Контекст: Исследователи использовали этот промпт для декомпозиции вопроса и итеративного разрешения триплетов. Это упрощённая версия алгоритма — полная система включает адаптивный retrieval по vector DB триплетов.
Given the question: {question}
Step 1: Decompose the question into atomic knowledge triplets.
Each triplet should be in the format (subject, predicate, object).
Use "?" as a placeholder for unknown entities.
Categorize triplets into:
- Resolved: zero placeholders (fully known facts)
- Searchable: exactly one placeholder (ready for retrieval)
- Fuzzy: two or more placeholders (need resolution first)
Step 2: Iterative Triplet Resolution (max {N} rounds):
ROUND {i}:
2.1. Adaptive Retrieval:
Take all Searchable triplets
→ Convert to query propositions (concatenate without "?")
→ Retrieve from triplet database until {k} unique source chunks found
→ Return: retrieved propositions + source chunks
2.2. LLM-based Resolution:
Given: Searchable triplets, Fuzzy triplets, Retrieved context
→ Fill in "?" placeholders using the context
→ Upgrade: Searchable → Resolved (if filled)
→ Upgrade: Fuzzy → Searchable or Resolved (if 1+ placeholders filled)
2.3. State Update:
T_resolved ← T_resolved ∪ T_resolved(new)
T_searchable ← T_searchable(new)
T_fuzzy ← T_fuzzy \ (T_resolved(new) ∪ T_searchable(new))
Repeat while: |T_searchable ∪ T_fuzzy| > 0 and rounds < {N}
Step 3: Final Answer Synthesis:
If all triplets resolved:
Answer ← LLM(question, T_resolved)
Else:
Answer ← LLM(question, T_resolved ∪ T_searchable)
Output format:
=== ROUND {i} === Searchable: [(subj, pred, ?), ...] Fuzzy: [(?, pred, ?), ...]
[Retrieved context...]
Resolved (new): [(subj, pred, obj), ...]
=== FINAL ANSWER === [Based on all resolved triplets]
Адаптации
💡 Упрощённая версия для чата (без vector DB)
Если у тебя нет базы триплетов, используй web search + память модели как источник фактов:
Разложи вопрос на триплеты с "?":
Вопрос: {вопрос}
Шаг 1: Создай Searchable и Fuzzy триплеты
Шаг 2: Для каждого Searchable триплета:
→ Используй web_search("{субъект} {предикат}")
→ Заполни "?" из результатов
→ Добавь в Resolved
Шаг 3: Повтори для новых Searchable (из бывших Fuzzy)
Шаг 4: Финальный ответ из всех Resolved триплетов
🔧 Техника: Добавить веса уверенности → понять надёжность фактов
Если нужно отслеживать качество источников, модифицируй триплеты:
Формат: (субъект, предикат, объект) [источник: X, уверенность: 0-1]
Пример:
Resolved:
(Казань, операторов_самокатов, 4) [источник: Коммерсантъ 2024, уверенность: 0.9]
(Самара, операторов_самокатов, 2) [источник: слухи на Reddit, уверенность: 0.4]
→ В финальном ответе используй только триплеты с уверенностью >0.7
🔧 Техника: Параллельные ветки для альтернативных гипотез
Для задач с неопределённостью (например: "кто вероятнее выиграет тендер?") можно разветвить триплеты:
Гипотеза A:
(Компания_X, вероятность_победы, 0.6) [потому что: опыт в сфере]
→ Searchable: (Компания_X, предыдущие_контракты, ?)
Гипотеза B:
(Компания_Y, вероятность_победы, 0.4) [потому что: низкая цена]
→ Searchable: (Компания_Y, финансовое_состояние, ?)
Resolve обе ветки → сравни итоговые resolved триплеты → выбери гипотезу с большим количеством подтверждающих фактов
Ресурсы
Beyond Chunks and Graphs: Retrieval-Augmented Generation through Triplet-Driven Thinking
Shengbo Gong, Xianfeng Tang, Carl Yang, Wei Jin (Emory University, Amazon)
GitHub: https://github.com/rockcor/T2RAG
arXiv: 2025 (пока препринт)
