AIを用いたマルチモーダルなインプット術:動画・音声・テキストの超効率吸収法

APIで自作する「秒速インプット」システム:動画・音声・PDFをGeminiモデルで構造化データに変えるPython実装

この記事は急速に進化する技術について解説しています。最新情報は公式ドキュメントをご確認ください。

約8分で読めます
文字サイズ:
APIで自作する「秒速インプット」システム:動画・音声・PDFをGeminiモデルで構造化データに変えるPython実装
目次

この記事の要点

  • AIによる動画、音声、テキストのマルチモーダル情報解析
  • Geminiモデルを活用した情報からの要点抽出・構造化
  • API連携で実現する「秒速インプット」システムの構築

今週、技術カンファレンスの動画を何本「積んで」いますか?あるいは、チャットツールに流れてきた「必読」のPDF資料を、いつか読むつもりで放置していませんか。

私たちエンジニアにとって、新しい情報のキャッチアップは呼吸と同じくらい重要です。しかし、情報の洪水を前にして、まともにすべてを目で追い、耳で聞こうとするのは、もはや「時間の浪費」と言っても過言ではありません。特に、1時間の動画の中に自分が必要とする情報が5分しかない場合、残りの55分は人生の損失です。

世の中にはAI要約ツールが溢れていますが、あえて「既存のSaaSツールには頼るな」と警告します。月額数千円のサブスクリプションを積み重ね、機密性の高い会議音声をブラックボックスなクラウドにアップロードするのは、リスク管理の観点からも、エンジニアのプライドとしても推奨できません。

今回は、GoogleのGeminiモデル APIを活用し、動画・音声・テキストを問わず、あらゆるインプットを自分好みのフォーマットに「蒸留」するパイプラインを自作します。これは単なる要約ツールの作成ではありません。あなたの脳の処理能力を拡張する、エンジニアリングの実践です。まずは動くプロトタイプを作り、仮説を即座に形にして検証していきましょう。

1. なぜ「自作」マルチモーダルパイプラインなのか

「便利なツールがあるのに、なぜわざわざコードを書くのか?」

そう思うかもしれません。しかし、実務の現場から見れば、汎用的なSaaSツールは「帯に短し襷に長し」です。

SaaS課金の壁とセキュリティの懸念を突破する

多くのAI要約サービスは、処理分数やファイルサイズに厳しい制限を設けています。「月間10時間まで」といった制限は、ヘビーな情報収集を行う私たちにはあまりに少なすぎます。また、従量課金ではなく定額制の場合、使わなくてもコストが発生します。経営者視点で見ても、無駄な固定費は避けるべきです。

さらに深刻なのがデータプライバシーです。社外秘の会議音声や、未公開の技術仕様書が含まれるPDFを、利用規約が頻繁に変わるサードパーティのWebサービスにアップロードするのは、セキュリティの観点から非常に危険な行為です。

APIを直接叩いて自作すれば、データフローを完全に制御できます。エンタープライズ基準でデータを管理し、必要な時に必要な分だけ、極めて安価なAPI料金で処理する。これがビジネスと技術の両面から見た最適解です。

Geminiモデルの長大なコンテキストウィンドウが変える世界

今回、Geminiモデルを選択する理由は明確です。それは200万トークンを超える圧倒的なコンテキストウィンドウと、ネイティブなマルチモーダル処理能力です。

従来のLLMでは、長時間の動画や大量のPDFを扱う際、テキストを分割して処理するRAG(検索拡張生成)などの工夫が不可欠でした。もちろん、RAG技術自体も進化を続けていますが、文脈の連続性が重要となる要約タスクにおいては、データを分割することによる情報の欠落が課題となります。

Geminiモデルの最新モデルであれば、1時間の動画ファイルや数百ページのPDFを「そのまま」プロンプトに放り込むことが可能です。これにより、文脈の分断が起きず、全体の流れを踏まえた極めて精度の高い解析が実現します。特に、最新の安定版モデルでは推論能力とコストパフォーマンスが最適化されており、個人開発レベルでもエンタープライズ級のパイプラインを構築できる環境が整っています。

2. 開発環境とAPIの準備

なぜ「自作」マルチモーダルパイプラインなのか - Section Image

それでは、手を動かしていきましょう。まずは環境構築です。Python 3.10以上を推奨します。

Google AI StudioでのAPIキー取得

まだAPIキーを持っていない場合は、Google AI Studioにアクセスし、APIキーを取得してください。無料枠(Free Tier)でも十分な実験が可能ですが、実運用の際はレートリミットに注意が必要です。

Python環境と必須ライブラリのインストール

プロジェクト用のディレクトリを作成し、仮想環境をセットアップします。

# プロジェクトディレクトリの作成
mkdir my-intel-agent
cd my-intel-agent

# 仮想環境の作成と有効化
python -m venv venv
source venv/bin/activate  # Windowsの場合は venv\Scripts\activate

# 必須ライブラリのインストール
pip install google-generativeai youtube-transcript-api python-dotenv
  • google-generativeai: Gemini APIを扱う公式SDK
  • youtube-transcript-api: YouTubeの字幕データを取得する軽量ライブラリ
  • python-dotenv: 環境変数を管理するためのライブラリ

プロジェクトルートに .env ファイルを作成し、APIキーを保存します。このファイルは .gitignore に追加し、絶対にGitリポジトリにコミットしないでください。

# .env
GOOGLE_API_KEY=your_api_key_here

3. 実装A:YouTube動画の「超速」要約モジュール

動画コンテンツの消化には2つのアプローチがあります。

  1. 字幕テキストベース: 処理が爆速。映像は見ない。トークン消費も少ない。
  2. 動画ファイルベース: 映像内のスライドやデモ画面も解析対象にする。処理は重いが情報量は多い。

ここでは、状況に応じて使い分けられるよう、両方のアプローチを実装します。まずは動くものを作って試すことが重要です。

字幕データ(Transcript)の取得ロジック

まずは、youtube-transcript-api を使って字幕を取得し、テキストとしてGeminiに投げる軽量な実装です。

import os
import google.generativeai as genai
from youtube_transcript_api import YouTubeTranscriptApi
from dotenv import load_dotenv

# 環境設定
load_dotenv()
genai.configure(api_key=os.getenv("GOOGLE_API_KEY"))

def get_video_id(url):
    """URLから動画IDを抽出する簡易関数"""
    if "v=" in url:
        return url.split("v=")[1].split("&")[0]
    elif "youtu.be/" in url:
        return url.split("youtu.be/")[1]
    return url

def summarize_youtube_text(video_url):
    video_id = get_video_id(video_url)
    
    try:
        # 字幕の取得(日本語優先、無ければ英語)
        transcript_list = YouTubeTranscriptApi.get_transcript(video_id, languages=['ja', 'en'])
        full_text = " ".join([t['text'] for t in transcript_list])
        
        # 字幕が長すぎる場合の簡易カット(必要に応じて調整)
        print(f"取得した文字数: {len(full_text)}")
        
        # Geminiモデルの準備
        model = genai.GenerativeModel('gemini-1.5-pro')
        
        prompt = f"""
        以下のYouTube動画の字幕テキストを読み、エンジニア向けに要約してください。
        単なる感想ではなく、技術的なキーワード、ツール名、解決手法に焦点を当てて構造化してください。
        
        出力フォーマット:
        - 概要: 3行で
        - 主要な技術/ツール: リスト形式
        - 重要なポイント: 
        - アクションアイテム/コード例: あれば記述
        
        --- 字幕テキスト ---
        {full_text}
        """
        
        response = model.generate_content(prompt)
        return response.text
        
    except Exception as e:
        return f"エラーが発生しました: {e}"

# 実行テスト
if __name__ == "__main__":
    url = "https://www.youtube.com/watch?v=example" # 任意の技術動画URL
    print(summarize_youtube_text(url))

動画そのものをAPIに処理させるマルチモーダルアプローチ

次に、動画ファイルそのもの(mp4など)をGeminiに見せる方法です。これは、スライドに書かれたコードや図表を読み取らせたい場合に威力を発揮します。
※注意: ローカルに動画ファイルがある前提のコードです。

import time

def summarize_video_file(file_path):
    print(f"動画ファイル {file_path} をアップロード中...")
    
    # File APIを使って動画をアップロード
    video_file = genai.upload_file(path=file_path)
    
    # 処理完了を待機(動画のエンコード処理待ち)
    while video_file.state.name == "PROCESSING":
        print("処理中...", end=".", flush=True)
        time.sleep(5)
        video_file = genai.get_file(video_file.name)
        
    if video_file.state.name == "FAILED":
        raise ValueError("動画の処理に失敗しました。")
        
    print("\n動画処理完了。解析を開始します。")
    
    model = genai.GenerativeModel('gemini-1.5-pro')
    
    prompt = """
    この動画は技術カンファレンスのセッションです。
    映像内のスライドやデモ画面の情報を考慮して、詳細なレポートを作成してください。
    特に、画面に映っているアーキテクチャ図やコードスニペットの内容を言語化して含めてください。
    """
    
    # 動画ファイルオブジェクトとプロンプトを同時に渡す
    response = model.generate_content([video_file, prompt])
    
    # 処理後にファイルを削除する場合(ストレージ節約)
    # genai.delete_file(video_file.name)
    
    return response.text

この2つを使い分けることで、「まずは字幕でサクッと概要把握(30秒)」「重要そうなら動画ファイルを食わせて詳細解析(3分)」という階層的なインプットが可能になります。

4. 実装B:会議音声とPDF資料のクロスリファレンス

実装A:YouTube動画の「超速」要約モジュール - Section Image

エンジニアの業務で最も厄介なのが、「仕様書(PDF)」と「定例会議(音声)」の乖離です。「あの会議で仕様変更の話したよね?」という言った言わない問題を、AIで解決しましょう。

ここでは、会議の録音データ(mp3/wav)と、配布資料(pdf)を同時にGeminiに読み込ませ、クロスリファレンス(相互参照)させます。

長時間の音声ファイルと関連資料を同時に処理する

def analyze_meeting(audio_path, pdf_path):
    print("メディアファイルをアップロード中...")
    
    # 音声とPDFをアップロード
    audio_file = genai.upload_file(path=audio_path)
    pdf_file = genai.upload_file(path=pdf_path)
    
    # 待機処理(簡略化のため関数化推奨)
    # ... (前述のwait処理と同様の実装を入れてください)
    
    print("解析開始...")
    
    model = genai.GenerativeModel('gemini-1.5-pro')
    
    prompt = """
    あなたは優秀なテクニカルライターです。
    添付の「会議音声」と「配布資料(PDF)」を突き合わせて、以下のタスクを行ってください。
    
    1. 議事録の作成: 会議での決定事項をまとめてください。
    2. 差分検出: 資料(PDF)に記載されている内容と、口頭での発言に矛盾や変更点があれば指摘してください。
       例: 「資料ではAPI v1を使うとあるが、音声ではv2への移行が決定されている」
    3. TODOリスト: 誰がいつまでに何をするか抽出してください。
    """
    
    # マルチモーダル入力:プロンプト + 音声 + PDF
    response = model.generate_content([prompt, audio_file, pdf_file])
    return response.text

このスクリプトの強力な点は、「資料には書いてあるが、会議では触れられなかった重要なリスク」「会議の場のノリで変更された仕様」を炙り出せることです。これは単一モダリティの処理では不可能です。

5. パイプラインの統合と自動化(CLIツール化)

個別のパーツができたら、実用的なCLIツールとして統合しましょう。これこそがDIYの醍醐味であり、システム思考に基づくエンジニアリングの第一歩です。

入力を自動判別するメイン関数の作成

argparse を使い、URLが渡されたらYouTube処理、ファイルパスなら拡張子を見て処理を分岐させます。また、実運用を見据えてエラーハンドリングを強化します。特にGemini APIなどのクラウドAIサービスを利用する場合、レートリミット(429エラー)や一時的なサーバーエラーへの対策は必須です。

import argparse
import sys
import os
import time
# google.api_core.exceptionsなどのインポートが必要な場合があります
# from google.api_core import exceptions

# ... (これまでの関数定義をここに含めるか、モジュールとしてimport)

def main():
    parser = argparse.ArgumentParser(description="My Intel Agent: AI駆動情報収集ツール")
    parser.add_argument("input", help="YouTube URL または ファイルパス")
    parser.add_argument("--pdf", help="会議音声解析時の補助PDFファイルパス", default=None)
    # モデルバージョンを引数で指定可能にするとテストが容易になります
    parser.add_argument("--model", help="使用するGeminiモデルバージョン", default="gemini-1.5-pro-latest")
    
    args = parser.parse_args()
    target = args.input
    
    result = ""
    
    print(f"Processing: {target} with {args.model}...")
    
    try:
        if target.startswith("http"):
            # YouTube URLとして処理
            result = summarize_youtube_text(target)
            
        elif target.endswith((".mp4", ".mov", ".avi")):
            # 動画ファイルとして処理
            # 注意: 大きな動画ファイルはアップロードに時間がかかる場合があります
            result = summarize_video_file(target)
            
        elif target.endswith((".mp3", ".wav", ".m4a")):
            # 音声ファイルとして処理
            if args.pdf:
                result = analyze_meeting(target, args.pdf)
            else:
                # PDFなしの音声単体処理ロジック(省略)
                # 必要に応じて実装してください
                pass
                
        else:
            print("未対応のフォーマットです。")
            sys.exit(1)
            
        # 結果の出力(標準出力 または ファイル保存)
        print("\n=== ANALYSIS RESULT ===\n")
        print(result)
        
        # ここにNotion APIやSlack Webhookへの送信処理を追加するとさらに便利です
        # 例: send_to_notion(result)
        
    except Exception as e:
        # 実運用では、APIのレートリミット(ResourceExhausted)などを個別に捕捉し、
        # 指数バックオフ(Exponential Backoff)でリトライするロジックの実装を推奨します。
        print(f"Fatal Error: {e}")
        # 詳細なログを出力する場合は traceback モジュールを使用してください
        sys.exit(1)

if __name__ == "__main__":
    main()

使い方

ターミナルから以下のように実行します。

# YouTube動画の要約
python agent.py https://www.youtube.com/watch?v=xxxxx

# 会議音声と資料のクロスチェック(モデルを指定する場合)
python agent.py meeting_audio.mp3 --pdf spec_v1.pdf --model gemini-1.5-pro-002

モデル指定について: Gemini APIは頻繁にアップデートされます。安定した出力を得るためには、gemini-1.5-pro-002 のように特定の安定版バージョンを指定することをお勧めします。最新情報は公式ドキュメントのChangelogを確認してください。

これで、手元には、動画・音声・テキストなど、あらゆる入力を瞬時に構造化データへ変換する「万能ナイフ」が備わりました。

まとめ

4. 実装B:会議音声とPDF資料のクロスリファレンス - Section Image 3

AI時代のエンジニアにとって、情報収集能力の差は、そのまま生産性と意思決定の質に直結します。

既存のSaaSツールに依存し、データの安全性やコスト、機能制限に悩まされながら情報収集をするのか。それとも、APIを駆使して自らの手で最適なパイプラインを構築し、情報の波を乗りこなすのか。Geminiモデルのようなロングコンテキスト対応モデルの登場により、後者のハードルは劇的に下がりました。

今回作成したスクリプトは、まだ最小限のプロトタイプに過ぎません。ここに出力結果をNotionデータベースに自動登録する機能や、特定キーワードが含まれていた場合のみSlackに通知する機能を追加することで、あなただけの「インテリジェンス・エージェント」へと進化させることができます。

まずは今週末、積読になっているあの技術動画や、長時間の会議録音を、このスクリプトに投げてみてください。AIが処理している間の空いた時間は、次の革新的なコードを書くか、あるいはゆっくりコーヒーを飲む時間に充てましょう。皆さんはどのような機能をこのエージェントに追加してみたいですか?ぜひ手を動かして、自分だけのツールを作り上げてください。

次回は、こうして集めた構造化データを活用し、ローカルLLMで「自分専用のセキュアな検索エンジン」を構築する方法について深掘りしたいと思います。

APIで自作する「秒速インプット」システム:動画・音声・PDFをGeminiモデルで構造化データに変えるPython実装 - Conclusion Image

コメント

コメントは1週間で消えます
コメントを読み込み中...