TL;DR
FinFRE-RAG — метод, который учит LLM работать с табличными данными через два этапа: офлайн выбираешь самые важные колонки (топ-10 из сотен), онлайн находишь похожие строки из истории и показываешь их как few-shot примеры. Таблицу превращаешь в текст: вместо "колонка А = 5, колонка Б = 10" пишешь "Клиент из Москвы, возраст 25, доход 100к".
LLM плохо работают с сырыми таблицами — если скормить все 200 колонок, модель теряется в шуме и выдаёт случайные ответы (F1-score ≈ 0). Причины три: слишком много признаков (превышает контекст и добавляет шум), числа без контекста (модель не понимает что значит "feature_47 = 3.14"), нет понимания паттернов (не знает какие комбинации признаков указывают на целевой класс). Исследовали на fraud detection — там особенно сложно, мошенничество это <1% транзакций, паттерны неочевидны.
Метод решает через два шага. Офлайн: тренируешь простую Random Forest на исторических данных, извлекаешь важность признаков, берёшь топ-k (обычно 10-15). Онлайн: для новой строки находишь похожие из истории (сначала фильтруешь по категориальным полям — регион, тип, статус, потом ranжируешь по числовым через косинусную близость), берёшь 10-20 самых похожих, переводишь всё в текст, скармливаешь LLM как few-shot примеры. Модель учится на аналогиях: "вот 20 похожих случаев, 15 из них были fraud — значит и этот скорее всего fraud".
Схема метода
ОФЛАЙН (один раз на датасете):
ШАГ 1: Тренируешь Random Forest на исторических данных
→ получаешь ранжирование признаков по важности
ШАГ 2: Выбираешь топ-k признаков (обычно 10-15)
→ создаёшь сокращённый набор F_selected
ШАГ 3: Нормализуешь числовые признаки (µ, σ для каждого)
→ сохраняешь для онлайн-поиска
ОНЛАЙН (для каждого нового случая):
ШАГ 4: Фильтруешь историю по категориальным признакам
(регион = регион запроса, тип = тип запроса, etc.)
→ пул кандидатов
ШАГ 5: Ранжируешь кандидатов по косинусной близости числовых признаков
→ топ-n похожих (обычно 10-20)
ШАГ 6: Превращаешь в текст: каждую строку как предложение
"Клиент из Москвы, доход 150к, возраст 28... → Одобрено"
→ few-shot примеры
ШАГ 7: Добавляешь запрос без label, скармливаешь LLM
→ модель выдаёт оценку риска + объяснение
Шаги 1-3 делаешь один раз. Шаги 4-7 — для каждого запроса в отдельном запросе к LLM.
Пример применения
Задача: Ты эксперт акселератора (типа GenerationS или ФРИИ), оцениваешь заявки стартапов. Есть таблица с 50 полями: выручка, команда, рынок, технология, предыдущие раунды, метрики продукта. Нужно предсказать — взять в программу или нет. Есть архив 500 прошлых заявок с решениями.
Промпт:
Ты эксперт акселератора, оцениваешь стартапы. Вот 5 похожих заявок из прошлого:
ПРИМЕР 1: Стартап из Москвы, B2B SaaS, команда 3 человека, MRR 200к ₽,
рынок 50 млрд ₽, есть CTO с опытом, платящих клиентов 15, CAC/LTV = 0.3.
→ ВЗЯЛИ (сильная команда, здоровая юнит-экономика)
ПРИМЕР 2: Стартап из Питера, B2C маркетплейс, команда 5 человек,
выручка 0, рынок 200 млрд ₽, нет технологичного продукта, есть только MVP.
→ НЕ ВЗЯЛИ (нет traction, переоценённый рынок)
ПРИМЕР 3: Стартап из Казани, EdTech, команда 2 человека, MRR 50к ₽,
рынок 10 млрд ₽, оба основателя из индустрии, LTV/CAC = 4, churn 5%.
→ ВЗЯЛИ (знание рынка, сильные метрики)
[ещё 2 примера...]
ТЕКУЩАЯ ЗАЯВКА: Стартап из Новосибирска, FinTech, команда 4 человека,
MRR 300к ₽, рынок 80 млрд ₽, есть финансовая лицензия, платящих
клиентов 25, CAC/LTV = 0.25, churn 8%, основатель ex-Тинькофф.
Оцени по шкале 1-5 (где 5 = точно брать) и объясни почему.
Результат: Модель выдаст оценку риска (например, 4 из 5) и объяснение: сравнит с похожими примерами, укажет на сильные стороны (опыт основателя, лицензия, здоровые метрики) и слабости (высокий churn относительно Примера 3). Покажет какие признаки повлияли на решение. Формат ответа: числовая оценка + текстовое обоснование со ссылками на исторические кейсы.
Почему это работает
LLM не понимают сырые таблицы. Если скормить строку "feature_1: 42, feature_2: 3.14, ... feature_200: 0.8", модель не видит смысла — это просто числа без контекста. Она не знает какие признаки важны, какие паттерны значимы, как комбинации влияют на исход. При огромном количестве признаков (100-1000 колонок) промпт раздувается, шум забивает сигнал, модель выдаёт почти случайные ответы.
LLM отлично работают с аналогиями и контекстом. Модель умеет сравнивать похожие случаи, находить паттерны в примерах, рассуждать по аналогии: "этот случай похож на Пример 1 по признакам А и Б, а там был положительный исход, значит...". Когда видит несколько примеров с явными связями "такие-то признаки → такой-то результат", быстро улавливает закономерность.
Метод использует силу через три рычага:
Отбор важных признаков удаляет шум — вместо 200 колонок оставляем 10 самых предсказательных. Random Forest за минуту показывает какие признаки важны, мы берём топ и выбрасываем остальное. Промпт становится компактным, модель фокусируется на сигнале.
Поиск похожих примеров даёт контекст — показываем не рандомные 20 строк из истории, а самые релевантные. Сначала фильтруем по категориям (регион, тип, сегмент), потом по числовой близости. Получаем micro-dataset внутри промпта: все примеры структурно похожи на запрос, модель видит паттерн.
Перевод в естественный язык делает признаки осмысленными — "доход 150к" понятнее чем "income: 150000". Модель начинает интерпретировать, а не просто сопоставлять цифры.
Рычаги управления:
- Количество признаков k (5-25) → меньше k = быстрее и дешевле, но можешь потерять важный сигнал; больше k = полнота, но риск шума
- Количество примеров n (5-30) → reasoning-модели (Qwen, GPT-OSS) любят больше примеров (20-30), простые модели (Gemma) начинают путаться после 10-15
- Формулировки в шаблоне → если напишешь "клиент из {региона}, возраст {возраст}" вместо просто списка полей, модель лучше понимает семантику
- Метод отбора примеров → можешь добавить "50% позитивных + 50% негативных" для баланса, или "все самые похожие" для точности
Шаблон промпта
Ты эксперт по {домен}. Оцениваешь {что оцениваешь} на основе исторических данных.
Вот {n} похожих случаев из прошлого:
ПРИМЕР 1: {описание признаков в естественном языке}
→ РЕЗУЛЬТАТ: {исход} ({краткая причина})
ПРИМЕР 2: {описание признаков}
→ РЕЗУЛЬТАТ: {исход} ({причина})
[повторить для всех n примеров]
ТЕКУЩИЙ СЛУЧАЙ: {описание нового случая теми же признаками}
Оцени по шкале {твоя шкала} и объясни почему, сравнивая с похожими примерами.
Что подставлять:
- {домен} — твоя область (подбор кандидатов, оценка кредитов, анализ оттока)
- {что оцениваешь} — конкретный объект (резюме, заявка, клиент)
- {n} — сколько примеров (5-20, начни с 10)
- {описание признаков} — переведи топ-10 важных колонок в предложение ("Компания из Москвы, выручка 5М, команда 10 человек...")
- {исход} — что произошло ("уволился через месяц", "дефолт", "апгрейд тарифа")
- {твоя шкала} — как хочешь получить ответ (1-5, вероятность 0-100%, бинарно да/нет)
Как подготовить данные: 1. Открой таблицу, выбери 10-15 самых важных колонок (смотри на корреляцию с исходом, можешь спросить у LLM "какие из этих полей обычно важны для {задачи}") 2. Найди 5-20 похожих строк вручную (по 2-3 ключевым категориям) или попроси LLM подобрать 3. Переформулируй каждую строку предложением: "Клиент {возраст} лет, доход {сумма}, регион {город}, ..." вместо "age: 25, income: 100k, region: Moscow" 4. Добавь новый случай в том же формате
🚀 Быстрый старт — вставь в чат:
У меня таблица с данными для задачи {опиши задачу}.
Колонки: {перечисли все колонки}.
Вот 3 примера строк: {вставь 3 строки}.
Помоги адаптировать этот шаблон:
1. Выбери топ-10 самых важных колонок для задачи
2. Переформулируй их в естественный язык (не "feature_x = 5", а "клиент из Москвы")
3. Создай промпт по шаблону FinFRE-RAG
[вставить шаблон выше]
LLM спросит про твою задачу (что предсказываем, какие признаки у тебя есть, какие примеры), выберет важные колонки и переформулирует таблицу в читаемый текст. Она возьмёт паттерн few-shot примеров и подставит твои данные.
Ограничения
⚠️ Нужна история: Метод работает только если есть архив прошлых случаев с известными исходами (хотя бы 50-100 строк). Без исторических данных нечего показывать как few-shot примеры — придётся полагаться на общие знания LLM.
⚠️ Большие данные требуют автоматизации: Если у тебя тысячи строк и сотни признаков, ручной отбор топ-колонок и поиск похожих примеров станет узким местом. На 10-50 строках можно вручную, на 10,000 нужен код для подсчёта важности признаков и косинусной близости.
⚠️ Reasoning-модели чувствительны к количеству примеров: Qwen и GPT-OSS улучшаются с ростом n от 5 до 30, но простые модели (Gemma) после 15 примеров начинают путаться — слишком много противоречивых сигналов. Подбирай n под свою модель.
⚠️ Работает для структурированных паттернов: Если исход зависит от сложных нелинейных взаимодействий сотен признаков, few-shot может не хватить — классические ML обучаются на миллионах примеров и находят тонкие паттерны. LLM с 20 примерами ловит очевидные закономерности, но не микро-сигналы.
⚠️ Категориальные признаки критичны для фильтрации: Метод сначала фильтрует по категориям (регион, тип, статус), потом по числовой близости. Если у тебя все признаки числовые — потеряешь этап фильтрации, пул кандидатов будет шумным. Хотя бы 2-3 категориальных поля сильно помогают.
Как исследовали
Команда проверила FinFRE-RAG на четырёх публичных датасетах fraud detection (CCF, CCFRAUD, IEEE-CIS, PAYSIM) — от нескольких тысяч до миллионов транзакций, от 10 до 400+ признаков, доля fraud от 0.1% до 8%. Для каждого датасета взяли 8,000 транзакций на тест, 2,000 на валидацию, остальное — в пул для retrieval. Тестировали на шести open-weight LLM разного размера: Qwen3-14B и 80B, Gemma 3-12B и 27B, GPT-OSS-20B и 120B. Baseline: прямой промпт без retrieval (просто "классифицируй эту транзакцию"), сравнение с классическими методами (Random Forest, XGBoost, TabM).
Результаты оказались драматичными. Baseline LLM показали почти случайные предсказания: F1-score от 0.00 до 0.14, MCC часто отрицательный (хуже рандома). Например, Qwen3-14B на CCF выдал F1 = 0.00 — вообще не смог детектировать fraud. Это подтвердило гипотезу: LLM не понимают сырые таблицы.
После добавления FinFRE-RAG те же модели взлетели: Qwen3-14B на CCF с 0.00 до F1 = 0.31 (MCC с -0.01 до 0.36), на IEEE-CIS с 0.04 до 0.62 (MCC с -0.01 до 0.60). Gemma 3-12B на некоторых датасетах достигла уровня XGBoost (F1 = 0.79 на CCF против 0.89 у XGBoost). Это огромный скачок — от "модель бесполезна" до "конкурирует с обученными классификаторами".
Самое интересное — анализ чувствительности. Исследователи варьировали количество признаков k (от 5 до 25) и количество примеров n (от 5 до 30). Обнаружили нелинейную зависимость: больше признаков ≠ лучше. Оптимум на 10-15 признаках — дальше шум начинает забивать сигнал. С примерами два паттерна: reasoning-модели (Qwen, GPT-OSS) монотонно улучшаются до n=30 (больше контекста → лучше аналогии), а простые модели (Gemma) деградируют после n=15 — они считают долю fraud в примерах вместо анализа признаков, противоречивые сигналы их путают.
Проверили важность отбора признаков через ablation: заменили топ-10 по важности на случайные 10. Производительность упала на 20-40% (например, Qwen на IEEE-CIS с MCC 0.60 до 0.32). Это доказало: не просто "меньше признаков = лучше", а именно информативные признаки критичны.
Последний эксперимент — файнтюнинг LLM vs FinFRE-RAG. Натренировали Qwen3-14B, Gemma3-12B, GPT-OSS-20B через LoRA на fraud-данных (один epoch на внешнем split). Файнтюненные модели показали Mixed results: иногда лучше FinFRE-RAG, иногда хуже. Но FinFRE-RAG не требует обучения и даёт объяснения (ссылается на конкретные примеры), тогда как файнтюненная модель — чёрный ящик.
Главный инсайт: LLM с правильным промптингом (отбор признаков + retrieval + few-shot) превращаются из бесполезных (F1≈0) в конкурентоспособные инструменты, иногда comparable с обученными моделями. Разрыв закрылся не через увеличение размера модели, а через архитектуру промпта — как именно мы подаём табличные данные.
Адаптации
🔧 Техника: балансировка примеров → контроль над prior
В оригинале метод берёт топ-n самых похожих примеров независимо от класса. Если в истории 99% негативных (как в fraud), то все 20 примеров будут негативными — LLM увидит паттерн "почти всегда negative" и будет предсказывать negative даже для пограничных случаев.
Адаптация: Принудительно балансируй классы в примерах — 50/50 или 30/70.
ШАГ 5a: Ранжируешь кандидатов отдельно по классам:
- топ-10 похожих ПОЗИТИВНЫХ
- топ-10 похожих НЕГАТИВНЫХ
ШАГ 5b: Берёшь по 10 из каждого класса (или 7/13 если хочешь prior)
→ сбалансированный набор примеров
Эффект: Модель видит оба паттерна — "такие признаки приводят к fraud" и "а такие к legitimate", учится различать границу. Особенно полезно для сильно несбалансированных данных (fraud, редкие болезни, отток VIP-клиентов).
Когда использовать: Если заметил что модель слишком консервативна (всегда предсказывает мажоритарный класс) или наоборот слишком aggressive (флагает всё подряд).
🔧 Техника: добавь "контрпримеры" → острее различение
Оригинал показывает похожие случаи. Добавь контрастные примеры — случаи с похожими признаками, но противоположным исходом.
Вот 10 похожих случаев где ВЗЯЛИ:
[примеры с положительным исходом]
Вот 5 похожих случаев где НЕ ВЗЯЛИ, хотя метрики были близкими:
ПРИМЕР 11: Стартап из Москвы, MRR 250к, рынок 60 млрд, команда 4 человека
→ НЕ ВЗЯЛИ (нет domain expertise, высокий CAC)
ПРИМЕР 12: ...
→ НЕ ВЗЯЛИ (юнит-экономика не сходится)
[контрпримеры]
ТЕКУЩИЙ СЛУЧАЙ: ...
Эффект: LLM начинает обращать внимание на тонкие различия — не просто "высокий MRR = хорошо", а "высокий MRR при низком CAC = хорошо, высокий MRR при высоком CAC = плохо". Контрпримеры учат модель границам решения.
🔧 Техника: Chain-of-Thought для признаков → отладка важности
Если не уверен какие признаки важны, попроси LLM проанализировать перед оценкой.
Сначала проанализируй ключевые признаки:
1. Сравни ТЕКУЩИЙ СЛУЧАЙ с каждым примером по признакам:
- MRR: текущий 300к vs Пример 1 (200к), Пример 2 (50к), ...
- Команда: текущий 4 vs Пример 1 (3), Пример 2 (2), ...
- CAC/LTV: текущий 0.25 vs ...
2. Для каждого признака — на кого больше похож (на успешных или неуспешных)?
3. Какие признаки критичны для решения в этой задаче?
Теперь на основе анализа дай итоговую оценку 1-5.
Эффект: Видишь рассуждения модели — какие признаки она считает важными, как сравнивает. Можешь отладить prompt (добавить недооценённый признак, убрать переоценённый). Модель становится интепретируемой.
Ресурсы
Understanding Structured Financial Data with LLMs: A Case Study on Fraud Detection
Xuwei Tan (The Ohio State University, Coinbase), Yao Ma (Coinbase), Xueru Zhang (The Ohio State University)
Датасеты: CCF, CCFRAUD (Kamaruddin & Ravi, 2016), IEEE-CIS Fraud Detection (IEEE-CIS, 2019), PaySim (Lopez-Rojas, 2017)
