/
Вопросы и ответы
/
Промт-инжиниринг
/

Как суммировать длинный документ через разбивку и сборку

Как суммировать длинный документ через разбивку и сборку

17 дней назад

Никита Вихров

Ответы

0

Как суммировать длинный документ через разбивку и сборку

Если документ не влезает в контекст, его нельзя передать целиком. Классическое решение — разбить на части, суммировать каждую, затем суммировать итоги. Это называют map-reduce для текста.

Схема

Документ ↓ разбивка [часть 1] [часть 2] [часть 3] [часть 4] ↓ map: суммировать каждую [итог 1] [итог 2] [итог 3] [итог 4] ↓ reduce: суммировать итоги Финальное резюме

Реализация

import re
from openai import OpenAI

client = OpenAI()

def split_by_paragraphs(text: str, max_chars: int = 3000) -> list[str]:
    параграфы = re.split(r'\n{2,}', text.strip())
    части = []
    текущая = ""

    for п in параграфы:
        if len(текущая) + len(п) > max_chars:
            if текущая:
                части.append(текущая.strip())
            текущая = п
        else:
            текущая += "\n\n" + п

    if текущая.strip():
        части.append(текущая.strip())

    return части

def summarize_chunk(chunk: str) -> str:
    resp = client.chat.completions.create(
        model="gpt-4.1",
        temperature=0.2,
        max_tokens=300,
        messages=[{
            "role": "user",
            "content": f"Кратко перескажи главное из этого фрагмента в 3–5 предложениях:\n\n{chunk}"
        }]
    )
    return resp.choices[0].message.content.strip()

def summarize_summaries(summaries: list[str]) -> str:
    объединённые = "\n\n---\n\n".join(summaries)
    resp = client.chat.completions.create(
        model="gpt-4.1",
        temperature=0.2,
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": f"Перед тобой краткие пересказы частей одного документа. "
                       f"Составь единое связное резюме документа:\n\n{объединённые}"
        }]
    )
    return resp.choices[0].message.content.strip()

def summarize_long_doc(text: str) -> dict:
    части = split_by_paragraphs(text)
    итоги_частей = [summarize_chunk(ч) for ч in части]
    финал = summarize_summaries(итоги_частей)
    return {
        "chunks": len(части),
        "chunk_summaries": итоги_частей,
        "final_summary": финал
    }

Когда схема не работает

Если документ содержит цифры и выводы, которые теряют смысл в отрыве от контекста (финансовый отчёт, юридический договор), суммаризация по частям искажает итог. В таких случаях лучше задавать конкретные вопросы по фрагментам, а не суммировать свободно.

Правила

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

17 дней назад

Никита Вихров

+7 800 100 22 47

бесплатно по РФ

+7 495 085 21 62

бесплатно по Москве

108813 г. Москва, вн.тер.г. поселение Московский,
г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3
ОГРН 1217300010476
ИНН 7325174845