Lost in the Middle эффект в LLM: практическое руководство по работе с длинным контекстом | AiManual
AiManual Logo Ai / Manual.
05 Янв 2026 Гайд

Lost in the Middle: почему ваша LLM теряет данные в середине контекста и как с этим бороться

Глубокий разбор эффекта Lost in the Middle в языковых моделях. RULER и NoLiMa бенчмарки, позиционное смещение, архитектурные решения для работы с длинным контек

Миф о 128K токенах: когда размер контекста не спасает

Вы купили доступ к Claude-3.5 с его 200K контекстом. Залили туда всю документацию проекта на 150 страниц. Задали вопрос про функцию, описанную на 75-й странице. И получили бред.

Поздравляю, вы столкнулись с Lost in the Middle.

Это не баг, это фундаментальное свойство архитектуры Transformer. Тот самый механизм внимания, который сделал LLM возможными, оказался слепым пятном в середине длинных последовательностей. Модели прекрасно помнят начало и конец, но теряют информацию в центре.

Проблема: В контексте из 100K токенов информация на позициях 30K-70K имеет в 2-3 раза меньшую вероятность быть использованной, чем та же информация в начале или конце. Это не теория, а данные из бенчмарка RULER.

Почему это происходит? Механика провала

Transformer'ы используют attention — механизм, который вычисляет «важность» каждого токена относительно других. В идеальном мире — равномерное внимание ко всему контексту. В реальном — внимание скапливается на краях.

Причин две:

  • Позиционные эмбеддинги — модель учится, что начало и конец важнее. Как в книгах: введение и заключение содержат самую суть.
  • Вычислительная сложность — attention квадратичен по длине. Модель неявно учится экономить внимание, фокусируясь на очевидных точках.

Но вот что интересно: этот эффект нелинейный. Он не просто плавно ухудшается к середине. Есть конкретные «мертвые зоны», где точность падает на 40-60%.

Модель Контекст Падение точности в середине Бенчмарк
GPT-4 Turbo 128K 57% RULER
Claude-3 Opus 200K 48% NoLiMa
Llama 3.1 405B 128K 62% RULER

Цифры шокируют? Они должны. Мы платим за длинный контекст, но используем его на треть.

RULER против NoLiMa: как измерять то, что теряется

Есть два основных бенчмарка для оценки Lost in the Middle:

RULER (Reasoning with Ultra-Long Contexts)

Создает искусственные задачи, где ответ зависит от информации в конкретной позиции контекста. Например: «В тексте на позиции 42,567 есть число X. Какое это число?»

RULER показывает сырые цифры — насколько модель физически способна извлечь информацию из разных частей контекста.

NoLiMa (Needle in a Large Multimodal Array)

Более практический тест. В огромный контекст (техническая документация, код, статьи) вставляется «иголка» — конкретный факт. Модель должна найти его и ответить на вопрос.

NoLiMa измеряет не просто извлечение, а понимание в контексте. И вот здесь провал еще глубже — потому что модель может технически прочитать текст в середине, но не связать его с вопросом.

💡
Если вы тестируете свою систему с длинным контекстом и не используете RULER или NoLiMa — вы измеряете не то. Точность на коротких примерах ничего не говорит о реальной работе с 50K+ токенами.

Кстати, о тестировании. Когда вы тестируете недетерминированные LLM, эффект Lost in the Middle добавляет еще один слой неопределенности. Сегодня модель нашла факт в середине, завтра — нет.

Архитектурные паттерны: как обмануть внимание

Бороться с Lost in the Middle можно на трех уровнях: на уровне данных, на уровне запроса и на уровне архитектуры системы.

1 Перемешивание контекста: самый простой хакинг

Если модель лучше всего помнит начало и конец — поместите важную информацию туда.

Как НЕ делать:

# Плохо: важная документация где-то посередине
context = "Введение... (10K токенов) ... Важная функция API: get_user(id)... (еще 40K токенов) ... Заключение"

Как делать:

# Хорошо: важное — в начало и конец
important_info = "Важная функция API: get_user(id) возвращает..."
context = f"ВАЖНО: {important_info}\n\n{remaining_docs}\n\nПОВТОРЕНИЕ ВАЖНОГО: {important_info}"

Это грубо. Это костыль. Но это работает с точностью до +30% на RULER.

2 Иерархическое внимание: не давайте модели всё сразу

Вместо того чтобы скармливать 100K токенов одной модели, разбейте на chunks и используйте двухуровневую архитектуру:

# Псевдокод иерархического подхода
chunks = split_document(doc, chunk_size=8192)  # 8K chunks

# Уровень 1: суммаризация каждого чанка
summaries = [summarize(chunk) for chunk in chunks]

# Уровень 2: работа с суммами (10K токенов вместо 100K)
final_context = "\n\n".join(summaries)
answer = query_llm(f"Вопрос: {question}\nКонтекст: {final_context}")

Вы теряете детали? Да. Но вы теряете их контролируемо, а не случайно в мертвой зоне внимания.

Этот подход напрямую связан с семантическими пайплайнами для LLM. Вы строите конвейер обработки, где каждый этап оптимизирован под свою задачу.

3 Динамическое рефокусирование: задавайте уточняющие вопросы

Когда модель не может найти информацию в длинном контексте — не ждите чуда. Запросите уточнение.

# Пример диалога с рефокусировкой
user: "Найди в документации описание функции process_payment"
assistant: "Я просмотрел документ. Он содержит 45 разделов.
            В каком разделе примерно должна быть эта функция?"
user: "В разделе 'API Reference', подраздел 'Payment Methods'"
assistant: "Нашел раздел. Описание функции: ..."

Вы заставляете пользователя (или другую систему) указать приблизительное местоположение информации. Это сжимает область поиска с 100K токенов до 5-10K.

Практический план: 5 шагов к системе, которая не теряет данные

1 Измерьте свой Lost in the Middle коэффициент

Прежде чем что-то оптимизировать — измерьте. Возьмите RULER или создайте свой мини-бенчмарк:

import random

def test_positional_bias(model, context_length=50000):
    """Тестируем, насколько модель теряет информацию в середине"""
    results = []
    for pos in [0, 0.25, 0.5, 0.75, 1.0]:  # Позиции в контексте
        # Создаем контекст с маркером на позиции pos
        marker = f"СЕКРЕТНЫЙ_КОД: {random.randint(1000, 9999)}"
        context = create_context_with_marker_at_position(marker, pos, context_length)
        
        # Запрашиваем у модели маркер
        answer = model.query(f"Что такое СЕКРЕТНЫЙ_КОД? Контекст: {context}")
        
        # Записываем, нашла ли
        results.append({
            'position': pos, 
            'found': marker in answer,
            'response': answer
        })
    return results

2 Сегментируйте контекст по смыслу, а не по длине

Не просто разбивайте на chunks по 8K токенов. Разбивайте по логическим разделам. Если это код — по модулям. Если документация — по главам.

Каждый сегмент должен иметь:

  • Заголовок (для реферирования)
  • Ключевые слова (для поиска)
  • Длину не более 4-8K токенов (оптимум для внимания)

3 Постройте гибридную систему поиска

Полный RAG (Retrieval-Augmented Generation) с эмбеддингами + ключевые слова + позиционная информация.

class HybridSearch:
    def __init__(self, documents):
        self.chunks = chunk_documents(documents)
        self.embeddings = create_embeddings(self.chunks)
        self.keyword_index = build_keyword_index(self.chunks)
        
    def search(self, query, top_k=5):
        # 1. Поиск по эмбеддингам (семантический)
        semantic_results = semantic_search(query, self.embeddings, top_k*2)
        
        # 2. Поиск по ключевым словам (лексический)
        keyword_results = keyword_search(query, self.keyword_index, top_k*2)
        
        # 3. Объединение с приоритетом начала/конца документов
        combined = combine_results(semantic_results, keyword_results)
        
        # 4. Смещение в пользу chunks из начала/конца исходных документов
        prioritized = prioritize_edges(combined)
        
        return prioritized[:top_k]

4 Добавьте явные позиционные маркеры

Когда передаете контекст в LLM, добавляйте информацию о позиции:

# Вместо просто текста
context = "Раздел 1... Раздел 2..."

# Добавляем маркеры
context = """
[НАЧАЛО ДОКУМЕНТА]
Раздел 1: Введение
...
[СЕРЕДИНА ДОКУМЕНТА, ПОЗИЦИЯ 25000]
Раздел 2: API Reference
...
[КОНЕЦ ДОКУМЕНТА]
"""

Это помогает модели осознавать структуру, даже если внимание расфокусировано.

5 Кэшируйте и переиспользуйте промежуточные результаты

Если вы один раз проанализировали документ и нашли важные разделы — сохраните эту информацию. Не заставляйте модель каждый раз читать всё с нуля.

Создайте «карту документа»:

{
  "document_id": "doc_123",
  "important_sections": [
    {"title": "API Auth", "position": 1200, "length": 1500},
    {"title": "Error Codes", "position": 8500, "length": 2000}
  ],
  "summary": "Документация к платежному API...",
  "embedding": [0.12, -0.45, ...]
}

Типичные ошибки (и как их не допускать)

Ошибка 1: Думать, что «длинный контекст = хороший контекст». Нет, длинный контекст = сложный контекст. Модель физически не может уделить равное внимание 100K токенам.

Ошибка 2: Использовать один промпт для всего. Разные типы запросов требуют разной обработки контекста. Поиск факта vs. суммаризация vs. анализ — это разные архитектурные паттерны.

Ошибка 3: Игнорировать Interpretation Drift. Lost in the Middle усугубляет дрейф интерпретации. Сегодня модель случайно сфокусировалась на нужном разделе, завтра — пропустила его.

Ошибка 4: Не учитывать стоимость. Длинный контекст стоит дорого. И если вы используете его неэффективно из-за Lost in the Middle — вы платите за токены, которые модель игнорирует.

Будущее: архитектурные изменения или вечные костыли?

Есть надежда? Отчасти.

Новые архитектуры вроде Tuneable Attention пытаются решить проблему на фундаментальном уровне. Но пока это исследования.

Практический совет: проектируйте системы с учетом Lost in the Middle как константы. Не надейтесь, что он исчезнет с новым GPT-5. Архитектура Transformer не меняется кардинально.

И помните: проблема не в том, что модели «глупые». Проблема в том, что мы используем их не по назначению. Transformer создавался для последовательностей в несколько сотен токенов. Мы растягиваем его до 100K и удивляемся, что он трескается по швам.

Лучшая система с длинным контекстом — та, которая имитирует человеческое чтение: сначала беглый просмотр, потом фокусировка на важном, потом углубление в детали. Не пытайтесь скормить всё сразу.

P.S. Если ваша LLM внезапно начала давать странные ответы из длинного контекста — проверьте, не попала ли ключевая информация в мертвую зону. Это частая причина архитектурных аномалий, которые списывают на «халлюцинации».