【Gemini Notebook】ソース用のPDFを結合・目次自動作成する方法

Gemini Notebookのソース上限対策として複数のPDFを結合し、AIが参照しやすい目次を自動生成・更新する方法を解説します。検索精度を落とさない構造化のコツやPythonによる結合スクリプトも紹介します。

Gemini Notebookのソース上限対策

Gemini Notebookには登録できるソース数に上限が存在します。大量のマニュアルや技術仕様書を読み込ませる場合、複数の関連資料を1つのPDFに結合して登録すれば、上限を節約しながら網羅的な検索が可能です。しかし、単純に結合しただけではAIが目的の情報を正しく見つけられない恐れがあります。 資料を結合する際は、AIが各セクションの構造を正確に把握できるように目次情報の付与が欠かせません。

本記事では、AIの参照精度を高めるPDFの結合手法と、Pythonを用いて目次と概要を自動生成・更新する具体的な手順を解説します。

AIが解釈しやすい結合PDFを作成する手順

AIの解釈精度を最大化するためには、人間向けのレイアウトだけでなくテキスト情報の構造化を意識する必要があります。

ポイント1:目次ページに概要とキーワードを含める

単なる「章タイトルとページ番号」の目次ではなく、各資料の要約や関連キーワードを目次ページに記載します。

  • 資料の正式名称、発行年などのメタデータ
  • 各資料の要約文(1〜2行程度)
  • 含まれる主な専門用語やトピック

ポイント2:各資料の区切りにヘッダーを挿入する

結合部分の先頭ページに、区切りとなるタイトルページや統一されたヘッダー情報を配置します。これにより、AIが文脈の切り替わりを認識しやすくなります。

ポイント3:テーマやカテゴリ単位で結合する

無関係な資料を無差別に1つの巨大なファイルにまとめると、異なる文脈が混ざり誤回答の原因になります。「製品別」「年度別」「業務分野別」など、関連性の高いグループ単位で結合します。

Pythonで目次付き結合PDFを自動生成・更新する手順

資料の追加や更新が発生するたびに手作業で目次を編集するのは非効率です。Pythonのライブラリを活用し、フォルダ内のPDFを読み込んで目次ページを動的に生成・結合するスクリプトを構築します。

手順1:必要ライブラリのインストール

PDFの結合と目次ページの描画を行うため、pypdfreportlab をインストールします。

pip install pypdf reportlab

手順2:結合用スクリプトの作成

指定フォルダ内のPDFファイルを走査し、先頭テキストから概要を抽出しつつ目次PDFを生成して結合します。PDF内部のしおり(アウトライン)も同時に自動設定されます。

import io
from pathlib import Path
from pypdf import PdfReader, PdfWriter
from reportlab.lib.pagesizes import A4
from reportlab.lib.styles import getSampleStyleSheet
from reportlab.platypus import Paragraph, SimpleDocTemplate, Spacer

def create_toc_pdf(entries):
    """メモリ上で目次用PDFを生成する関数"""
    buffer = io.BytesIO()
    doc = SimpleDocTemplate(
        buffer,
        pagesize=A4,
        rightMargin=40,
        leftMargin=40,
        topMargin=40,
        bottomMargin=40
    )
    styles = getSampleStyleSheet()
    story = [
        Paragraph("<b>統合資料 目次およびインデックス</b>", styles['Title']),
        Spacer(1, 15)
    ]

    for item in entries:
        title_text = f"<b>[{item['index']}] {item['title']}</b> (開始ページ: P.{item['start_page']})"
        story.append(Paragraph(title_text, styles['Heading2']))
        if item.get('summary'):
            story.append(Paragraph(f"概要: {item['summary']}", styles['Normal']))
        story.append(Spacer(1, 8))

    doc.build(story)
    buffer.seek(0)
    return buffer

def merge_pdfs_with_auto_toc(input_dir: str, output_path: str):
    """フォルダ内のPDFを結合し、先頭に目次を追加する関数"""
    pdf_files = sorted(Path(input_dir).glob("*.pdf"))
    if not pdf_files:
        print("結合対象のPDFが見つかりません。")
        return

    toc_data = []
    estimated_toc_pages = 1
    current_page = estimated_toc_pages + 1
    file_readers = []

    for idx, pdf_path in enumerate(pdf_files, 1):
        reader = PdfReader(str(pdf_path))
        num_pages = len(reader.pages)

        # 1ページ目のテキストから簡易概要を抽出
        first_page_text = reader.pages[0].extract_text() or ""
        summary_sample = first_page_text.replace("\n", " ")[:120] + "..." if first_page_text else "概要なし"

        toc_data.append({
            "index": idx,
            "title": pdf_path.stem,
            "start_page": current_page,
            "pages": num_pages,
            "summary": summary_sample
        })
        current_page += num_pages
        file_readers.append((pdf_path.stem, reader))

    # 目次PDFを作成
    toc_pdf_stream = create_toc_pdf(toc_data)
    toc_reader = PdfReader(toc_pdf_stream)

    writer = PdfWriter()

    # 目次ページを追加
    for page in toc_reader.pages:
        writer.add_page(page)

    # 各PDFを追加し、しおり(アウトライン)を設定
    for title, reader in file_readers:
        start_idx = len(writer.pages)
        for page in reader.pages:
            writer.add_page(page)
        writer.add_outline_item(title=title, page_number=start_idx)

    with open(output_path, "wb") as f:
        writer.write(f)

    print(f"結合完了: {output_path} (総ページ数: {len(writer.pages)})")

# 実行例
merge_pdfs_with_auto_toc("./pdf_source_folder", "./merged_document.pdf")

手順3:定期更新の自動化

資料が更新された際は、スクリプトを再実行するだけで新しい目次とページ番号が反映されたPDFが再生成されます。これをGemini Notebookのソースとして再アップロードすることで、常に最新のデータを正確なインデックス付きで参照させることが可能です。

関連コンテンツ

【Gemini超入門】基本的な使い方まとめ
Geminiの基本的な使い方について初心者向けに丁寧に解説します。

コメント