Реализация AI-суммаризации длинных текстов в мобильном приложении
Суммаризация длинного текста упирается в одно ограничение сразу: контекстное окно модели. GPT-4o принимает 128K токенов (примерно 100K слов). Claude 3 — 200K. Звучит много, но юридический договор на 200 страниц, технический отчёт, книга — всё это может превышать лимит. И даже если влезает — длинный контекст дорог и замедляет ответ.
Стратегии для текстов разной длины
Прямая суммаризация — работает для текстов до 50–80K токенов. Отправляем весь текст одним запросом, просим суммаризировать. Просто, дёшево по реализации. Ограничение — стоимость токенов и latency (модель обрабатывает большой контекст медленнее).
Map-Reduce — для текстов, не влезающих в контекст. Разбиваем на чанки → суммаризируем каждый чанк → суммаризируем суммари:
async def map_reduce_summarize(text: str, chunk_size: int = 4000) -> str:
chunks = split_text(text, chunk_size)
# Map: суммаризируем каждый чанк параллельно
chunk_summaries = await asyncio.gather(*[
summarize_chunk(chunk) for chunk in chunks
])
# Reduce: суммаризируем результаты
combined = "\n\n".join(chunk_summaries)
if count_tokens(combined) > chunk_size:
return await map_reduce_summarize(combined, chunk_size) # рекурсия
return await summarize_final(combined)
asyncio.gather — параллельные запросы к API для всех чанков одновременно. Для 10 чанков время почти такое же, как для одного.
Refine — суммаризируем первый чанк, потом уточняем суммари с каждым следующим чанком. Итоговое суммари последовательно обогащается. Качество выше, чем Map-Reduce для связных нарративных текстов, но медленнее — запросы последовательные.
Управление размером промпта и токенами
Главная ошибка — не считать токены до отправки. tiktoken (Python) или gpt-tokenizer (JS) дают точный подсчёт:
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
token_count = len(enc.encode(text))
if token_count < 100_000:
return await direct_summarize(text)
elif token_count < 500_000:
return await map_reduce_summarize(text, chunk_size=8000)
else:
return await map_reduce_summarize(text, chunk_size=4000)
Разные типы суммари — разные промпты:
- Executive summary (для руководителей): 3–5 предложений, только ключевые решения и цифры
- Детальный пересказ: структурированный список с подзаголовками
- Список ключевых пунктов: буллеты без связного текста
- Ответ на вопрос: «что это за документ и что в нём нужно сделать»
На мобильном — предлагаем пользователю выбрать тип суммари перед запуском.
Прогресс суммаризации на мобильном
Суммаризация 100-страничного документа занимает 15–60 секунд. Без индикатора прогресса — плохой UX. Серверная часть отправляет события через SSE:
event: progress
data: {"step": "chunking", "total_chunks": 12, "completed": 0}
event: progress
data: {"step": "summarizing", "total_chunks": 12, "completed": 4}
event: result
data: {"summary": "...", "word_count": 450}
На мобильном клиенте — прогресс-бар с описанием шага, анимированный текст «Обрабатываю страницы 1–25...».
Стриминг финального суммари — тоже важен. Пользователь видит, как текст появляется постепенно, а не ждёт несколько секунд полного ответа.
Специфика длинных документов
Потеря середины (Lost in the Middle). Исследования показали: LLM хуже обрабатывают информацию из середины длинного контекста по сравнению с началом и концом. При Map-Reduce это не проблема — каждый чанк в своём контексте. При прямой суммаризации — важно знать об ограничении.
Дублирование в суммари. При Map-Reduce финальная суммаризация может повторять похожие пункты из разных чанков. Явно указывайте в промпте: «Объедини похожие пункты, не повторяй одну мысль дважды».
Структурированный вывод. Для юридических и финансовых документов суммари в формате JSON с фиксированными полями (parties, obligations, deadlines, key_figures) надёжнее свободного текста. OpenAI response_format: {"type": "json_object"} или Anthropic structured outputs.
Кеширование
Суммаризация одного документа стоит денег. Кешируйте результат по хешу содержимого документа + типу суммари. Redis с TTL 7–30 дней — стандартный подход. Если документ изменился — инвалидация кеша по document_id.
Этапы и сроки
Определение стратегии для разных размеров документов → серверный pipeline с Map-Reduce → стриминговый API с прогрессом → мобильный UI с выбором типа суммари → кеширование → тестирование качества на реальных документах.
Базовая суммаризация (до 100K токенов) с мобильным UI — 1–2 недели. Полный pipeline с Map-Reduce, стримингом, кешированием и несколькими типами суммари — 3–5 недель.







