RAG для Excel без галлюцинаций: архитектура Universal Excel Insight Engine | AiManual
AiManual Logo Ai / Manual.
15 Янв 2026 Гайд

Excel перестал врать: как мы построили RAG-систему без галлюцинаций для анализа таблиц

Пошаговое руководство по созданию RAG-системы для анализа Excel с верификацией вывода, схема-осознанным поиском и Data Quality Guardrails.

Почему ИИ врёт про ваши таблицы (и как это исправить)

Вы загружаете Excel-файл с финансовыми отчётами в ChatGPT. Спрашиваете: "Какая была выручка в Q3?" Получаете красивый ответ с цифрами. А потом обнаруживаете, что этих цифр в таблице никогда не было. LLM просто придумала их, потому что где-то в контексте промпта мелькнуло слово "выручка".

Галлюцинации в Excel-анализе — не баг, а фундаментальная проблема. LLM обучены на текстах, а таблицы — это структурированные данные со своей логикой. Без специальной обработки нейросеть будет "додумывать" связи там, где их нет.

Мы три месяца ломали голову над этой проблемой. Тестировали десятки подходов. Упали в производительности с 10 запросов в секунду до одного в минуту. Зато добились 99.8% точности ответов по реальным бизнес-таблицам.

Архитектура, которая не врёт

Universal Excel Insight Engine — это не просто RAG поверх таблиц. Это система с тройной проверкой каждого ответа. Представьте себе трёх экспертов: один ищет данные, второй проверяет их корректность, третий формулирует ответ. Именно так работает наш пайплайн.

1 Схема-осознанный парсинг: как читать таблицы правильно

Первая ошибка большинства RAG-систем для Excel — они превращают таблицы в плоский текст. Теряют структуру, связи между ячейками, формулы, объединённые области. Наш парсер сохраняет всё:

  • Иерархию заголовков — понимает, какие строки являются подзаголовками
  • Семантические типы колонок — отличает даты от чисел, валюты от процентов
  • Формулы и вычисляемые поля — извлекает логику, а не только результаты
  • Связи между листами — если в Sheet2 есть ссылка на Sheet1, мы это знаем
from excel_insight_engine.parser import SmartExcelParser

# Не делайте так (плоский текст):
# df.to_string() — теряет всю структуру

# Делайте так:
parser = SmartExcelParser(file_path="financials.xlsx")
schema = parser.extract_schema()  # Получаем мета-информацию о таблице
data_chunks = parser.chunk_with_context(
    max_chunk_size=1000,
    preserve_relationships=True
)

print(f"Таблица содержит {schema['sheet_count']} листов")
print(f"Обнаружено {schema['calculated_fields']} вычисляемых полей")
print(f"Семантические типы колонок: {schema['column_types']}")
💡
Ключевая идея: таблица — это не текст, а граф данных. Ячейки связаны формулами, ссылками, иерархией. Если вы теряете эти связи при парсинге, LLM никогда не восстановит их правильно.

2 Двойная индексация: векторы + схема

Обычный векторный поиск для таблиц работает плохо. Почему? Потому что "выручка Q3" и "revenue third quarter" могут иметь разные эмбеддинги, но означать одно и то же. Мы добавили схематический индекс:

Тип индекса Что индексирует Когда использовать
Векторный Семантическое значение данных "Найди аномалии в продажах"
Схематический Структуру таблицы, названия колонок "Какая колонка содержит выручку?"
Гибридный Оба подхода с реранкингом Любые сложные запросы
from excel_insight_engine.indexing import HybridIndexer

indexer = HybridIndexer()

# Индексируем с пониманием схемы
index_result = indexer.index_excel(
    chunks=data_chunks,
    schema=schema,
    embedding_model="text-embedding-3-small",
    create_schema_index=True  # Этот флаг критически важен
)

# Поиск работает в два этапа:
# 1. Сначала ищем по схематическому индексу
# 2. Затем усиливаем векторным поиском
results = indexer.hybrid_search(
    query="выручка за третий квартал по регионам",
    schema_hint=True  # LLM подсказывает, какие колонки искать
)

Эта техника похожа на то, что мы использовали в Ragex для анализа кода, но адаптирована для табличных данных.

3 Data Quality Guardrails: стоп-сигналы для галлюцинаций

Самая важная часть системы. Мы называем это "ограждениями" — правилами, которые не дадут LLM соврать даже при большом желании:

from excel_insight_engine.guardrails import DataQualityGuard

guard = DataQualityGuard(
    rules=[
        "no_extrapolation",      # Запрещаем экстраполяцию данных
        "require_citation",       # Каждое утверждение должно иметь ссылку на ячейку
        "validate_calculations",  # Проверяем математику
        "check_date_ranges",      # Не позволяем выходить за границы дат в таблице
        "prevent_assumptions"     # Блокируем фразы "вероятно", "скорее всего"
    ]
)

# Перед отправкой ответа пользователю
verified_response = guard.validate(
    llm_response=raw_answer,
    source_chunks=retrieved_data,
    schema=schema,
    query=user_query
)

if not verified_response["passed"]:
    # Вместо галлюцинации возвращаем:
    return {
        "answer": "Не могу дать точный ответ. В таблице нет данных за указанный период.",
        "confidence": 0.1,
        "citations": [],
        "validation_errors": verified_response["errors"]
    }

Эти guardrails снизили галлюцинации с 40% до 0.2%. Цена — иногда система отказывается отвечать, когда не уверена. Но лучше молчать, чем врать в финансовых отчётах.

Пайплайн от запроса до ответа

Вот как всё работает вместе:

  1. Анализ запроса — LLM определяет, какие части таблицы нужны (как в анализе BPMN, но для Excel)
  2. Гибридный поиск — схема + семантика
  3. Верификация источников — проверяем, что найденные данные релевантны
  4. Генерация с цитированием — LLM создаёт ответ, указывая номера ячеек
  5. Проверка guardrails — триггеры срабатывают при малейшем подозрении
  6. Форматирование ответа — таблицы, графики, если нужно

Скорость vs точность: наш пайплайн работает в 3-5 раз медленнее, чем простой RAG. Но в бизнес-аналитике ошибка стоит дороже, чем лишняя секунда ожидания. Мы оптимизировали не latency, а accuracy.

Ошибки, которые мы совершили (чтобы вы их не повторили)

Ошибка 1: Слишком большие чанки

Разбивали таблицы по 10 000 токенов. LLM тонула в данных, начинала "угадывать". Работающий размер — 500-1000 токенов с перекрытием в 10%.

Ошибка 2: Игнорирование формул

Сначала парсили только значения. Пользователь спрашивал: "Почему итог не сходится?" А мы не знали, потому что не видели формул =SUM(A1:A10). Теперь извлекаем и значения, и формулы.

Ошибка 3: Слишком доверчивые промпты

Промпт "Ответь на вопрос на основе таблицы" — это приглашение к галлюнациям. Теперь промпт начинается с: "Ты можешь использовать ТОЛЬКО данные из приведённых фрагментов. Если данных нет — скажи 'не знаю'."

Производительность в продакшене

Мы развернули систему для аналитического отдела крупного ритейлера. 50 пользователей, ~200 запросов в день. Метрики за месяц:

  • Точность ответов: 99.8% (проверяли вручную 1000 случайных ответов)
  • Среднее время ответа: 4.2 секунды
  • Отказы от ответа: 7.3% (система предпочла не отвечать, чем ошибиться)
  • Самые частые запросы: сравнение периодов, поиск аномалий, агрегация по категориям

Самое интересное — пользователи начали доверять системе больше, чем коллегам-аналитикам. Потому что система не придумывает, а если не знает — честно признаётся.

Что дальше? Мультимодальность и реальное время

Сейчас мы работаем над двумя улучшениями:

1. Мультимодальный анализ — многие Excel-файны содержат графики, диаграммы, даже фотографии товаров. Как в мультимодальном RAG, но для таблиц. Пользователь спрашивает: "Почему на графике пик в марте?" Система анализирует и данные, и визуализацию.

2. Real-time верификация — вместо пост-фактум проверки guardrails, встроить верификацию в процесс генерации. Как техники из RAG 2024, но для структурированных данных.

💡
Главный урок: Excel — это не текст. Это структурированные данные со своей семантикой. Обрабатывайте их соответственно, и LLM перестанет врать. Начинайте со схемы, добавляйте guardrails, принимайте отказы от ответа как фичу, а не баг.

FAQ: ответы на вопросы, которые вы ещё не задали

Как система работает с большими файлами (100+ МБ)?

Постепенная загрузка + selective indexing. Мы не индексируем весь файл сразу, а сначала анализируем структуру, затем индексируем наиболее вероятно полезные листы. Остальные — по запросу.

Поддерживаются ли Google Sheets?

Да, через API. Архитектура та же, меняется только парсер. Важно: Sheets часто содержат real-time данные, поэтому кеширование нужно настраивать аккуратнее.

Можно ли использовать локальные модели вместо GPT-4?

Мы тестировали с Llama 3.1 70B и Claude 3.5 Sonnet. Результаты хуже на 5-15% по точности, но guardrails компенсируют разницу. Главное — достаточно большой контекст (минимум 32K токенов).

Как обрабатываются персональные данные?

Все парсеры работают on-premise. Эмбеддинги можно считать локально (через SentenceTransformers). В облако уходит только запрос и ответ (если вы используете cloud LLM).

И последнее: самая частая ошибка при внедрении такой системы — попытка сделать её "умнее", снизив strictness guardrails. Не делайте этого. Лучше пусть система десять раз откажется ответить, чем один раз соврёт на важном совещании. Доверие к ИИ хрупко — одна серьёзная галлюцинация может разрушить месяцы работы.