LLMを使った要約は、「長い文章を短くまとめる」という一見単純なタスクに見えますが、実装の現場ではコンテキスト長、精度、コスト、速度の4つが絡み合う奥深い世界です。本記事では、Stuff(一括)・Map-Reduce(分割統治)・Refine(逐次更新)の3パターンを使い分けることが要約システム設計の基本である、という指針を示します。コンテキスト長が128kや200kに伸びた2026年でも、それぞれのパターンには明確な使い所があります。

LLM要約の3つのパターン

LLM要約は処理の構造によって、Stuff、Map-Reduce、Refineの3パターンに大別できます。それぞれの処理フローは下図の通りです。

【Stuff方式】
[全文書] --> [LLM 1回呼び出し] --> [要約]
※ 文書全体が一度にプロンプトに入る場合の最もシンプルな方法


【Map-Reduce方式】
[全文書]
    |
    +--> [チャンク1] --> [LLM] --> [部分要約1]
    +--> [チャンク2] --> [LLM] --> [部分要約2] --> [LLM統合] --> [最終要約]
    +--> [チャンクN] --> [LLM] --> [部分要約N]
※ 部分要約は並列実行可能、コンテキスト長を超える文書に適する


【Refine方式】
[チャンク1] --> [LLM] --> [暫定要約1]
                              |
[チャンク2] --> [LLM] --> [暫定要約2]
                              |
[チャンクN] --> [LLM] --> [最終要約]
※ 逐次更新、並列化できないが文脈保持が強い

長文要約の実装

コンテキスト長(128k、200k等)を超える文書を要約する場合、Map-Reduceが第一選択です。文書をチャンクに分割し、各チャンクを並列で要約してから、要約の要約を作ります。LangChainを使った実装例を示します。

from langchain_openai import ChatOpenAI
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.chains.summarize import load_summarize_chain
from langchain_core.documents import Document

llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

def summarize_long_document(text: str, chunk_size: int = 4000) -> str:
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=chunk_size,
        chunk_overlap=200,
        separators=["\n\n", "\n", "。", " ", ""],
    )
    chunks = splitter.split_text(text)
    docs = [Document(page_content=c) for c in chunks]
    chain = load_summarize_chain(
        llm,
        chain_type="map_reduce",
        verbose=False,
    )
    result = chain.invoke({"input_documents": docs})
    return result["output_text"]
パターン精度速度コスト対応文書長適した場面
Stuff速いコンテキスト長以内短文、固定長文書
Map-Reduce中〜高速い(並列)制限なし長文、時間優先
Refine非常に高遅い(直列)制限なし文脈保持が重要
ハイブリッド(階層Map-Reduce)中〜高制限なし超長文(書籍等)

多文書要約の設計

多文書要約は、複数の独立した文書から1つの要約を作るタスクです。例えば「今週のニュース記事100件を1ページにまとめる」「10件の顧客レビューを分析する」といったケースです。単純な連結だと重複や冗長な表現が多くなるため、段階的な集約が効果的です。

import asyncio
from openai import AsyncOpenAI

client = AsyncOpenAI()

async def summarize_one(doc: str) -> str:
    resp = await client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": f"3行で要約してください:\n{doc}"}],
    )
    return resp.choices[0].message.content

async def multi_document_summary(docs: list[str], theme: str) -> str:
    partials = await asyncio.gather(*[summarize_one(d) for d in docs])
    joined = "\n---\n".join(f"[記事{i+1}] {p}" for i, p in enumerate(partials))
    prompt = f"以下の複数要約から「{theme}」の観点で統合要約を作成してください:\n{joined}"
    final = await client.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
    )
    return final.choices[0].message.content

多文書要約では、統合時に「テーマ」や「観点」を明示すると、出力の軸がブレにくくなります。「共通点」「相違点」「時系列変化」といった軸を指定するだけで、同じ入力から全く異なる有用な要約が得られます。

要約の品質制御

要約品質の評価は、自由文生成タスクの中でも特に難しい部類です。単一の指標では不十分なため、複数の指標を組み合わせる必要があります。

指標定義計測方法目標値
事実性(Faithfulness)要約中の情報が原文に存在するかLLM-as-Judge または NLI モデル95%以上
網羅性(Coverage)原文の重要情報をどれだけ含むかゴールド要約とのROUGEROUGE-L 0.3以上
簡潔性(Conciseness)冗長表現・重複の少なさ文字数比率・重複率元の10〜20%
一貫性(Coherence)文章の流れ・読みやすさLLM-as-Judge4.0/5.0以上
幻覚率(Hallucination)原文にない情報を追加していないか事実性の裏返し指標5%以下

特に業務利用では事実性が最優先です。要約が多少読みにくくても、事実誤認があると業務判断を誤らせるため、リリース基準に組み込んでください。

ユースケース別の実装例

代表的なユースケースごとに設計のポイントを整理します。

  • 議事録要約――発言者・決定事項・アクションアイテムを構造化して出力します。Structured Outputと組み合わせて、「誰が何を担当するか」を明示するのが必須です。音声文字起こしをそのまま渡すとノイズが多いため、前処理でフィラーを除去するとよいでしょう
  • レポート要約――数値情報の正確性が重要です。「具体的な数値は原文から引用し、変更しないこと」をプロンプトで強調してください。事実性チェックを別のLLMで行うと安心です
  • メール要約――受信トレイ表示用の短要約(1行)と、本文表示前の中要約(3行)の2段階で設計するとUXが良くなります。軽量モデルで十分な品質が出やすいタスクです
  • 顧客レビュー要約――センチメント、頻出トピック、代表的な意見を抽出します。多文書要約のパターンを使い、テーマ別にグルーピングすると経営判断に役立つ情報になります

まとめ

要約はシンプルに見えて奥深いタスクです。Stuff・Map-Reduce・Refineの3パターンを使い分け、事実性を最優先に品質制御を行うのが基本設計です。関連記事としてプロンプトエンジニアリング入門構造化出力トークンとはレイテンシ最適化もあわせてご参照ください。

よくある質問(FAQ)

Q1. LLMでコンテキスト長を超える文書を要約するには?

A. Map-Reduce方式(文書を分割→各部分を要約→要約を統合)が一般的です。Refine方式(順番に読みながら要約を更新)は精度が高いですがコストも高くなります。文書の性質に応じて選択してください。文脈の連続性が重要な小説や論文ではRefine、独立した章が多い報告書ではMap-Reduceが適しています。

Q2. LLMの要約精度はどのくらいですか?

A. 一般的なビジネス文書では人間の要約と80〜90%程度の一致度が期待できます。ただし、専門用語が多い文書や数値情報の正確性が求められる場合は、人間レビューの併用が推奨されます。特に法務・医療・金融ドメインでは、要約を最終成果物として使わず、原文参照の導線付きで活用する設計が安全です。

Q3. 要約のコストを抑える方法は?

A. 軽量モデル(GPT-4o mini、Claude Haiku等)の活用、不要な部分の事前フィルタリング、キャッシュの導入が効果的です。単純な要約タスクでは軽量モデルでも十分な品質が得られます。バッチAPIを使えばさらに50%程度のコスト削減が可能です。