Summarization Engine について
Summarization Engineは、文書要約システムを構築する開発者向けのスキルです。抽出型、生成型、ハイブリッド型に加え、長文・複数文書の処理や精度評価を扱います。
主な機能
- 01抽出型・生成型の手法
- 02要件に応じた方式選定
- 03長文のチャンク分割
- 04複数文書の統合
- 05事実整合性の確認
活用シーン
- 01要約パイプラインの設計
- 02論文やニュースの要約
- 03会議録や法律文書の要約
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ jmsktm/ claude-settings --skill summarization-engineインストール後、Claude Code で/summarization-engineを入力して読み込まれたか確認します。
詳細
要約エンジン
要約エンジンのスキルでは、長い文書を簡潔で正確な要約にまとめるシステムの構築方法を説明します。重要な文を選び出す抽出的な手法から、新しい文章を生成する抽象的な手法まで、要約技術の全般を網羅します。
効果的な要約には、重要な情報を見極め、情報を凝縮しながら正確さを保ち、文書の種類や要約の要件に応じて調整することが必要です。このスキルを活用すると、適切な手法を選び、堅牢な要約パイプラインを実装できます。
ニュース記事、研究論文、会議の議事録、法的文書のいずれを要約する場合でも、このスキルによって、正確で関連性が高く、有用な要約を作成できます。
主なワークフロー
ワークフロー 1:要約手法を選択する
- 要件を分析します:
- 要約の長さ(比率または固定の長さ)
- 正確さの要件(事実の精密さ)
- スタイルの好み(抽出的か抽象的か)
- 速度と規模の制約
- 手法を比較します:
手法 正確さ 流暢さ 速度 最適な用途 抽出的 高い さまざま 速い 法律、医療、精密さが求められる分野 抽象的(小規模) 中程度 良好 速い 一般的なコンテンツ 抽象的(LLM) 高い 非常に優れている 遅い 品質が最優先される用途 ハイブリッド 高い 良好 中程度 バランスが求められる用途 - トレードオフに基づいて選択します:
- 抽出的:正確さが最優先される場合
- 抽象的:流暢さが重要な場合
- ハイブリッド:両方が重要な場合
- 評価基準を設計します
ワークフロー 2:抽出的な要約を実装する
- 文にスコアを付けます:
from sklearn.feature_extraction.text import TfidfVectorizer import numpy as np def extractive_summarize(text, num_sentences=3): # Split into sentences sentences = sent_tokenize(text) # Score by TF-IDF importance vectorizer = TfidfVectorizer() tfidf_matrix = vectorizer.fit_transform(sentences) # Score each sentence by sum of TF-IDF scores scores = np.array(tfidf_matrix.sum(axis=1)).flatten() # Select top sentences maintaining order top_indices = np.argsort(scores)[-num_sentences:] top_indices = sorted(top_indices) # Maintain original order summary_sentences = [sentences[i] for i in top_indices] return " ".join(summary_sentences) - 追加の評価要素を加えます:
- 位置(最初の文は重要であることが多い)
- 固有表現の密度
- タイトルや見出しとの類似度
- 冗長性を取り除きます:
- すでに選択した文と類似しすぎている文は除外します
- 一貫性を高めるために後処理します
ワークフロー 3:抽象的な要約を実装する
- 要約モデルを設定します:
from transformers import pipeline class AbstractiveSummarizer: def __init__(self, model="facebook/bart-large-cnn"): self.summarizer = pipeline("summarization", model=model) self.max_input_length = 1024 # Model-specific limit def summarize(self, text, max_length=150, min_length=50): # Handle long documents if len(text.split()) > self.max_input_length: return self.summarize_long(text, max_length, min_length) result = self.summarizer( text, max_length=max_length, min_length=min_length, do_sample=False ) return result[0]["summary_text"] def summarize_long(self, text, max_length, min_length): # Chunk and summarize iteratively chunks = self.chunk_text(text) summaries = [self.summarize(chunk) for chunk in chunks] # Combine and re-summarize if needed combined = " ".join(summaries) if len(combined.split()) > max_length: return self.summarize(combined, max_length, min_length) return combined - チャンク化して長い文書を処理します
- 事実の正確さを検証します
- 書式を整えるために後処理します
クイックリファレンス
| 操作 | コマンド/トリガー |
|---|---|
| テキストを要約する | 「この文書を要約してください」 |
| 手法を選ぶ | 「[文書の種類]に最適な要約方法」 |
| 長さを指定する | 「[N]語/文で要約してください」 |
| 複数の文書をまとめる | 「これらの文書をまとめて要約してください」 |
| 要約を評価する | 「要約の品質を確認してください」 |
| ハルシネーションを減らす | 「要約の正確さを高めてください」 |
ベストプラクティス
-
重要な情報を保持する:要約では重要な内容を捉える必要があります
- 主要なエンティティ、事実、結論を特定します
- 重要な情報が保持されていることを確認します
- 簡潔さのために正確さを犠牲にしないでください
-
事実の正確さを維持する:抽象的な要約ではハルシネーションが発生することがあります
- 生成された事実を原文と照合します
- 重大な影響を伴う分野では抽出的な手法を使用します
- ハイブリッド手法も検討します
-
長い文書を処理する:ほとんどのモデルには長さの制限があります
- セクションや段落ごとに戦略的にチャンク化します
- 階層的な要約を使用します
- チャンク間の文脈を保持します
-
目的に合わせてスタイルを選ぶ:用途によって適した要約は異なります
- エグゼクティブサマリー:重要な結論を最初に示す
- アブストラクト:バランスの取れた概要
- 箇条書き:拾い読みしやすい重要な事実
- プログレッシブディスクロージャー:詳細さの異なる複数のレベル
-
適切に評価する:ROUGE スコアだけでは全体像を把握できません
- 事実の正確さを手動で確認します
- 一貫性と読みやすさを評価します
- 人間による要約と比較します
-
複数文書を検討する:複数の情報源を要約する必要があることはよくあります
- 共通するテーマと相違点を特定します
- 矛盾を適切に処理します
- 情報の出典を明記します
高度な手法
LLM を使った要約
高品質な要約には大規模言語モデルを使用します:
def llm_summarize(text, style="executive", max_words=150):
style_instructions = {
"executive": "Focus on key conclusions, decisions, and action items.",
"technical": "Preserve technical details and methodology.",
"narrative": "Maintain the story arc and key events.",
"bullet": "Format as bullet points with key facts."
}
prompt = f"""Summarize the following text in approximately {max_words} words.
{style_instructions.get(style, "")}
Important:
- Only include information from the source text
- Maintain accuracy of facts, numbers, and names
- Preserve the most important information
Text to summarize:
{text}
Summary:"""
return llm.complete(prompt, max_tokens=max_words * 2)
階層的な要約
非常に長い文書を反復的に要約します:
def hierarchical_summarize(document, target_length=500):
"""
Summarize long documents through progressive compression.
"""
# Level 1: Split into sections
sections = split_into_sections(document)
# Level 2: Summarize each section
section_summaries = []
for section in sections:
summary = summarize(section, max_length=200)
section_summaries.append({
"title": section.title,
"summary": summary
})
# Level 3: Combine section summaries
combined = "\n\n".join([
f"{s['title']}: {s['summary']}"
for s in section_summaries
])
# Level 4: Final summary if still too long
if len(combined.split()) > target_length:
return summarize(combined, max_length=target_length)
return combined
複数ドキュメントの要約
複数のソースから情報を統合します:
def multi_document_summarize(documents, topic=None):
"""
Summarize multiple documents into coherent summary.
"""
# Step 1: Summarize each document
doc_summaries = []
for i, doc in enumerate(documents):
summary = summarize(doc.text)
doc_summaries.append({
"source": doc.source,
"summary": summary
})
# Step 2: Identify themes and differences
prompt = f"""Given these summaries from different sources about {topic or "a topic"}:
{chr(10).join(f"Source {i+1} ({s['source']}): {s['summary']}" for i, s in enumerate(doc_summaries))}
Create a unified summary that:
1. Identifies common themes across sources
2. Notes any contradictions or different perspectives
3. Attributes key claims to their sources
4. Presents a balanced, comprehensive view
Unified summary:"""
return llm.complete(prompt)
事実との整合性チェック
要約に幻覚が含まれていないことを確認します:
def check_factual_consistency(source, summary):
"""
Verify summary facts against source document.
"""
# Extract claims from summary
claims = extract_claims(summary)
# Check each claim against source
results = []
for claim in claims:
prompt = f"""Does the source document support this claim?
Source: {source}
Claim: {claim}
Answer:
- SUPPORTED: The claim is directly supported by the source
- NOT SUPPORTED: The claim is not in the source
- CONTRADICTED: The source contradicts this claim
Provide answer and brief explanation."""
result = llm.complete(prompt)
results.append({
"claim": claim,
"status": parse_status(result),
"explanation": result
})
return {
"claims_checked": len(results),
"supported": sum(1 for r in results if r["status"] == "SUPPORTED"),
"not_supported": sum(1 for r in results if r["status"] == "NOT SUPPORTED"),
"contradicted": sum(1 for r in results if r["status"] == "CONTRADICTED"),
"details": results
}
クエリに焦点を当てた要約
特定の質問に合わせた要約を生成します:
def query_focused_summarize(document, query):
"""
Summarize document with focus on answering specific question.
"""
prompt = f"""Summarize the following document, focusing specifically on information relevant to this question:
Question: {query}
Document:
{document}
Provide a summary that:
1. Directly addresses the question
2. Includes relevant supporting details from the document
3. Notes if the document doesn't fully answer the question
4. Stays focused on query-relevant information
Summary:"""
return llm.complete(prompt)
避けるべき一般的な落とし穴
- 事実確認をせずに抽象型要約を信頼する
- モデルのコンテキスト上限を超える長さのドキュメントに対応しない
- 評価指標としてROUGEスコアだけを使用する
- チャンク分割時にドキュメントの構造を無視する
- ユーザーのニーズに合わない要約を生成する
- 複数ドキュメントの要約で情報の出典を明記しない
- 圧縮しすぎて重要な情報が失われる
- 人によるレビューなしで要約をそのまま使用できると思い込む
コメント
Markdown 対応