Lost-in-the-Middle бенчмарк: тестирование LLM на потерю данных | Гайд 2026 | AiManual
AiManual Logo Ai / Manual.
16 Мар 2026 Гайд

Бенчмарк Lost-in-the-Middle: как тестировать LLM на потерю знаний в длинных документах

Практический гайд по использованию бенчмарка Lost-in-the-Middle для оценки потери знаний LLM в длинных документах. Анализ ошибок, пошаговая инструкция, актуальн

Забывчивые гиганты: когда 128K токенов – обманка

Ваша LLM прочитала 100-страничный технический отчет, а на вопрос о спецификации с 50-й страницы выдала чистую галлюцинацию. Вы проверяете промпт – информация там есть. Модель не глупая, у нее контекстное окно в 200 тысяч токенов. В чем подвох? Подвох в том, что современные трансформеры страдают когнитивным диссонансом: они отлично помнят начало и конец документа, но напрочь теряют суть в середине. Это не баг, это фундаментальное ограничение архитектуры внимания.

На 16.03.2026 проблема не решена магически. Модели вроде DeepSeek V3.2 или анонсированный Gemini Ultra 2.0 все еще демонстрируют этот эффект, просто в разной степени. Больше контекста – не панацея.

Что за FailureSensorIQ и почему он вам нужен

В 2025 году на Kaggle выкатили датасет-бенчмарк FailureSensorIQ. Это не очередной набор вопросов-ответов. Это хитрая ловушка, созданная специально, чтобы поймать LLM на горячем. Суть в следующем: в длинный искусственный документ (до 100K токенов) в случайных местах вставляются "факты" – пары "ключ-значение". Например, цвет_любимой_рубашки_президента: фиолетовый в горох. Задача модели – извлечь значение по ключу, когда ее об этом попросят в промпте.

Гениальность в простоте. Если модель ошибается, вы сразу видите две вещи: 1) Она не нашла факт. 2) Где именно в документе этот факт был спрятан. Это дает чистую метрику для диагностики, без шума из-за непонимания семантики.

Тип ошибки Что происходит Влияние на RAG
Lost-in-the-Middle Факт в середине длинного контекста. Модель его игнорирует, хотя токены физически присутствуют в промпте. Катастрофическое. Вы извлекаете релевантные чанки, но модель их "не видит". Ответы становятся случайными.
Failure-to-Retrieve Факт в конце или начале, но модель все равно ошибается. Проблема с базовым механизмом внимания/поиска. Критическое. Даже правильно подобранный контекст не гарантирует ответа. Нужно лечить саму модель.

Зачем это вам? Если вы строите RAG-систему для анализа юридических договоров или медицинских историй, как в нашем гайде "Как заставить LLM работать с корпоративными данными", вы обязаны знать, где ваша цепочка дает сбой. Иначе вы доверяете принятие решений капризному черному ящику.

Пошаговый разбор: ставим диагноз своей модели

Теория – это хорошо, но мы здесь за практикой. Давайте запустим бенчмарк и интерпретируем результаты. Предположим, у нас есть доступ к API какой-нибудь свежей модели на 16.03.2026, например, DeepSeek V3.2 или Qwen2.5 Long.

1 Качаем датасет и настраиваем окружение

Все начинается с Kaggle. Установите CLI и скачайте датасет failure-sensor-iq. Для работы с длинными контекстами вам понадобится среда с хорошей оперативкой. Если локальной GPU нет, арендуйте инстанс с A100 или H100 у облачного провайдера, например, RunPod (это партнерская ссылка, но сервис действительно удобен для ad-hoc тестов).

pip install kaggle pandas tqdm openai
# Установите API-ключ Kaggle в ~/.kaggle/kaggle.json
kaggle datasets download -d alexburlacu/failure-sensor-iq
unzip failure-sensor-iq.zip

2 Пишем функцию-интегратор для вашей LLM

Суть – отправлять промпты и парсить ответы. Не используйте обертки вроде LangChain для этого теста – они добавляют лишние мета-инструкции, которые исказят чистоту эксперимента. Нужен голый запрос.

import openai
import json

client = openai.OpenAI(api_key="your_key", base_url="https://api.deepseek.com")  # Пример для DeepSeek

def query_llm(prompt: str, model: str = "deepseek-chat") -> str:
    """Простая функция запроса. Никакого system prompt, только пользовательский контент."""
    try:
        response = client.chat.completions.create(
            model=model,
            messages=[{"role": "user", "content": prompt}],
            temperature=0.0,  # Убираем стохастичность для воспроизводимости
            max_tokens=50
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        return f"ERROR: {e}"

3 Загружаем тестовые примеры и запускаем цикл

Датасет содержит JSONL-файлы. Каждая строка – документ с вкраплениями фактов и вопросы к ним. Ваша задача – прочитать документ, добавить вопрос и отправить в модель.

import jsonlines

def run_benchmark(test_file: str, model_name: str):
    results = []
    with jsonlines.open(test_file) as reader:
        for item in reader:
            document = item["document"]  # Огромная строка с токенами
            for qa in item["qa_pairs"]:
                prompt = f"{document}\n\nВопрос: Какое значение у ключа '{qa['key']}'?"
                answer = query_llm(prompt, model_name)
                
                is_correct = qa['value'].lower() in answer.lower()
                results.append({
                    "key": qa['key'],
                    "expected": qa['value'],
                    "actual": answer,
                    "position": qa['position_in_doc'],  # Критически важно!
                    "is_correct": is_correct
                })
    return results
💡
Зачем нужен position_in_doc? Это координата факта в документе (нормализованная от 0 до 1). После прогона вы построите график: по оси X – позиция, по оси Y – точность. Если в середине графика образуется провал – у вас классический lost-in-the-middle. Если ошибки равномерны – проблема глубже.

4 Анализ и выводы, которые больно читать

Собрав результаты, вы увидите суровую правду. Возьмите библиотеку типа matplotlib или seaborn и постройте scatter plot. Вот что вы можете обнаружить:

  • V-образная кривая: Точность высокая в начале и конце, падает к середине. Это подтверждает гипотезу lost-in-the-middle. Лечится перестановкой чанков в RAG (поместите самые релевантные в начало и конец контекста).
  • Случайный шум: Нет четкой зависимости от позиции. Модель просто плохо извлекает факты. Это failure-to-retrieve. Здесь не поможет хитрая чанковка, нужно смотреть на архитектуру или дообучать модель.
  • Полный провал на определенных длинах: Например, на 80K токенах точность падает с обрыва. Значит, у модели есть внутренние ограничения, не декларированные в спецификациях.

Где все ломается: практические нюансы

Вы запустили тест, получили цифры. Теперь интерпретация. Вот самые частые грабли.

Ошибка №1: Тестируете с system prompt. Многие добавляют "Ты – полезный ассистент...". Это меняет распределение внимания модели! Для чистоты эксперимента используйте только пользовательский промпт с документом и вопросом. System prompt – это уже оптимизация, ее тестируют отдельно.

Ошибка №2: Игнорируете температурный режим. Установите temperature=0. Иначе один и тот же тест будет давать разные результаты, и вы не отличите стохастичность от системной ошибки. Детерминизм – основа бенчмаркинга.

А если ваша модель локальная и жрет 80 ГБ памяти? Для нее тоже есть путь. Используйте библиотеку vLLM или Ollama с квантованными весами. Суть не в том, чтобы гонять сырые 70B-параметровые модели, а в том, чтобы найти относительное качество. Протестируйте 7B, 13B и 70B версии одной и той же семьи и сравните графики. Часто меньшая модель с хорошим квантованием показывает более стабильные результаты на длинном контексте, чем гигант, который едва помещается в память.

Ответы на вопросы, которые вы постесняетесь задать

Q: Этот бенчмарк заменит HumanEval или MMLU?

Нет. Он узкоспециализированный. HumanEval проверяет генерацию кода, MMLU – общие знания. FailureSensorIQ – это стресс-тест на механическое извлечение информации из длинной памяти. Как рентген, а не общий анализ крови.

Q: У меня RAG на ретривере из векторной БД. Зачем мне это, если ретривер и так отбирает нужные чанки?

А если ретривер вернет 5 чанков, и ключевой факт окажется в среднем? Ваша LLM его проигнорирует. Вы получите красивый, но неверный ответ. Этот тест помогает настроить границы ответственности между ретривером и LLM. Может, стоит отправлять чанки по одному? Или ранжировать их по релевантности и класть самые важные по краям контекста?

Q: Я тестировал модель X, и она справилась на 95%. Значит, проблема решена?

Скорее всего, вы тестировали на коротких документах (10-20K токенов). Попробуйте полную длину 100K. И посмотрите не на aggregate accuracy, а на график по позициям. 95% могут означать, что модель угадала все простые случаи по краям и проигнорировала сложные в центре. Всегда смотрите на распределение ошибок.

Q: Могу ли я дообучить модель, чтобы исправить lost-in-the-middle?

Теоретически – да, на данных, похожих на FailureSensorIQ. Практически – рискуете получить катастрофическое забывание других навыков. Гораздо надежнее адаптировать пайплайн: менять порядок чанков, использовать иерархическое внимание или разбивать запросы на подзадачи.

Что дальше? Диагноз поставлен

Теперь у вас есть не просто ощущение, а hard data о слабом месте вашего ИИ-стэка. Вы знаете, на какой длине контекста он начинает врать, и где именно в документе прячется слепота. Это мощнее, чем любой лог из LangSmith.

Следующие шаги:

  1. Интегрируйте этот тест в ваш CI/CD для моделей. Каждая Новая версия LLM, каждый апдейт базовой модели – прогоняйте через FailureSensorIQ.
  2. Постройте дашборд с графиками точности vs. позиция для всех моделей в арсенале. Выбирайте модель под задачу, а не под маркетинговые цифры.
  3. Если вы разрабатываете собственную архитектуру RAG, как в гайде про PDF, используйте эти данные для A/B тестирования стратегий чанковки и компрессии контекста.

Главный вывод? Не верьте спецификациям. Не верьте блог-постам. Запускайте бенчмарк. Смотрите, где ваша модель реально ломается. И только потом несите ее в продакшн. Иначе однажды она "забудет" критический пункт договора на 50-й странице, и вам придется объяснять это не ИИ, а юристам.

Подписаться на канал