【Python】OpenAI APIで会議の議事録を自動生成!話者分離+GPT-4で決定事項・アクションアイテムを抽出
はじめに
会議の議事録作成、こんな悩みありませんか?
- 録音はあるけど、文字起こしだけでは使えない
- 誰が何を決めたのか分からない
- アクションアイテムをまとめるのが地味に大変
- 結局、人手で清書している
文字起こしツールは増えましたが、「誰が何を決めたのか」「誰が何をやるのか」を抽出するのは、結局人間の作業として残ってしまいます。
本記事では、話者分離された文字起こしからOpenAI APIを使って議事録を自動生成する機能を実装した事例を紹介します。録音から決定事項・アクションアイテムの抽出まで、すべて自動化できます。
この記事で分かること
- OpenAI APIを使った議事録自動生成の実装方法
- プロンプト設計のポイント(タイムスタンプ、話者ラベルの活用)
- リトライロジックとエラーハンドリングの実装
- 実際のパフォーマンス測定結果(5分〜84分の会議)
- クロスプラットフォーム対応(macOS/Windows CUDA)
🎯 実装した機能
自動生成される議事録の内容
OpenAI APIを使って、以下の情報を自動抽出します:
- 要約 - 会議全体の簡潔な要約(100-300語)
- 決定事項 - 誰がいつ何を決めたか(話者、タイムスタンプ付き)
- アクションアイテム - タスク、担当者、期限、タイムスタンプ
- トピック分類 - 会議を1-10のトピックに自動分類
実際の出力例
以下は、実際に生成された議事録の例です(内容は架空のものです):
# 議事録: プロジェクト進捗会議
**日付**: 2026-03-29
**時間**: 01:23:44
**参加者**: Speaker 1(プロジェクトマネージャー), Speaker 2(バックエンドリード), Speaker 3(フロントエンドリード), Speaker 4(DevOpsエンジニア)
## 要約
この会議では、新機能の開発スケジュールとリソース配分について議論されました。
具体的には、フロントエンド開発の優先順位、バックエンドAPIの設計方針、
テスト戦略、デプロイメント計画などが検討されました。
4名のメンバーがそれぞれの専門領域から意見を出し合い、
実現可能なスケジュールとタスク配分を決定しました。
## 決定事項
1. [00:15:30] フロントエンド開発を優先し、来週中にプロトタイプを完成させることを決定。 (Speaker 1による)
2. [00:45:20] バックエンドAPIはRESTful設計を採用し、OpenAPI仕様書を作成することを決定。 (Speaker 2による)
3. [01:05:15] テスト自動化を導入し、CI/CDパイプラインを構築することを決定。 (Speaker 3による)
4. [01:15:45] 本番環境はAWSを使用し、コンテナベースのデプロイメントを採用することを決定。 (Speaker 4による)
## アクションアイテム
| タスク | 担当者 | 期限 | タイムスタンプ |
|--------|--------|------|----------------|
| フロントエンドプロトタイプの作成 | Speaker 3 | 2026-04-05 | 00:15:30 |
| OpenAPI仕様書の作成 | Speaker 2 | 2026-04-10 | 00:45:20 |
| CI/CDパイプラインの構築 | Speaker 4 | 2026-04-15 | 01:05:15 |
| デプロイメント環境の準備 | Speaker 4 | 2026-04-12 | 01:15:45 |
| プロジェクト進捗レポートの作成 | Speaker 1 | 2026-04-08 | 00:30:15 |
## トピック
### 開発スケジュールとリソース配分 [00:00:00 - 01:23:44]
フロントエンド開発の優先順位、バックエンドAPIの設計方針、
テスト戦略、デプロイメント計画について議論。
プロジェクトマネージャー、バックエンドリード、フロントエンドリード、
DevOpsエンジニアの4名がそれぞれの専門領域から意見を出し合い、
リソースの最適配分と納期の調整を行った。
これが全自動で生成されます!
🏗️ アーキテクチャ
パイプライン全体図
動画/音声ファイル
↓
音声抽出 (ffmpeg)
↓
┌─────────┴─────────┐
↓ ↓
話者分離 音声認識
(pyannote) (faster-whisper)
↓ ↓
Speaker Turns ASR Segments
└─────────┬─────────┘
↓
アライメント
↓
話者付き文字起こし
↓
議事録生成 ← NEW!
(OpenAI API)
↓
┌─────────┴─────────┐
↓ ↓
Meeting JSON Minutes JSON
Transcript MD Minutes MD
新規追加モジュール
src/meeting_pipeline/minutes.py - 議事録生成エンジン
主要関数:
-
generate_minutes()- メイン関数 -
_load_meeting_json()- Meeting JSON読み込み・検証 -
_prepare_prompt()- プロンプト生成(タイムスタンプ付き文字起こし) -
_call_openai_api()- OpenAI API呼び出し(リトライロジック付き) -
_parse_api_response()- レスポンスのパース
💡 実装のポイント
1. プロンプト設計
システムプロンプト:
あなたは専門的な議事録生成者です。
会議の文字起こしを分析し、構造化された情報を抽出するのがあなたの仕事です。
出力形式: JSON
{
"summary": "会議全体の要約(100-300語)",
"decisions": [...],
"action_items": [...],
"topics": [...]
}
ユーザープロンプト:
以下の会議の文字起こしを分析し、議事録をJSON形式で生成してください。
[00:00:00] Speaker 1: こんにちは
[00:00:02] Speaker 2: よろしくお願いします
...
タイムスタンプと話者ラベルを含めることで、AIが「誰がいつ何を言ったか」を正確に把握できます。
2. リトライロジック
OpenAI APIは時々レート制限やタイムアウトが発生します。そこで:
def _call_openai_api(prompt: str, config: MinutesConfig, api_key: str) -> str:
max_retries = 3
backoff_seconds = [1, 2, 4] # 指数バックオフ
for attempt in range(max_retries):
try:
response = client.chat.completions.create(...)
return response.choices[0].message.content
except (RateLimitError, APITimeoutError) as e:
if attempt < max_retries - 1:
wait = backoff_seconds[attempt]
logger.warning(f"リトライ {attempt+1}/{max_retries}、{wait}秒後...")
time.sleep(wait)
else:
raise
except AuthenticationError as e:
raise # 認証エラーはリトライしない
ポイント:
- 最大3回リトライ
- 指数バックオフ(1秒、2秒、4秒)
- 認証エラーはリトライしない(すぐに失敗)
3. エラーハンドリング
議事録生成が失敗しても、パイプライン全体は停止しません:
# パイプライン統合(pipeline.py)
try:
minutes = generate_minutes(meeting_json_path, config, api_key)
save_minutes_markdown(minutes, minutes_md_path)
save_minutes_json(minutes, minutes_json_path)
except Exception as e:
logger.error(f"議事録生成失敗: {e}")
print("エラー: 議事録生成失敗。Meeting JSONと文字起こしは正常に保存されました。")
# パイプラインは継続
重要: Meeting JSONと文字起こしは常に最初に保存されるため、議事録生成が失敗しても文字起こしは残ります。
📊 パフォーマンス測定
テスト環境
macOS環境:
- MacBook Pro M4 Pro
- RAM: 48GB
- GPU: MPS(Metal Performance Shaders)
Windows環境:
- Windows 11
- GPU: NVIDIA RTX 5070(VRAM 12GB)
- CPU: Intel Core i7
- RAM: 32GB
テストケース1: 5分動画(開発用)
環境: macOS(M4 Pro、MPS + CPU)
| ステージ | 時間 |
|---|---|
| 音声抽出 | 0.2秒 |
| 話者分離(MPS) | 16.6秒 |
| ASR(CPU) | 61.4秒 |
| アライメント | 0.0秒 |
| 議事録生成(gpt-3.5-turbo) | 4.6秒 |
| 総処理時間 | 78.7秒 |
出力:
- Meeting JSON: 65KB
- Transcript Markdown: 5.7KB
- Minutes JSON: 1.3KB ✨
- Minutes Markdown: 997B ✨
テストケース2: 84分動画(実用例)
macOS(M4 Pro、MPS + CPU)
| ステージ | 時間 |
|---|---|
| 音声抽出 | 2.8秒 |
| 話者分離(MPS) | 314.1秒(5分14秒) |
| ASR(CPU) | 933.4秒(15分33秒) |
| アライメント | 0.6秒 |
| 議事録生成(gpt-4-turbo) | 38.8秒 |
| 総処理時間 | 1251.4秒(20分51秒) |
Windows(RTX 5070、CUDA)
| ステージ | 時間 |
|---|---|
| 音声抽出 | 14.1秒 |
| 話者分離(CUDA) | 95.3秒(1分35秒) |
| ASR(CUDA) | 145.9秒(2分26秒) |
| アライメント | 1.8秒 |
| 議事録生成(gpt-4-turbo) | 42.4秒 |
| 総処理時間 | 258.1秒(4分18秒) |
パフォーマンス比較
| 環境 | 84分動画処理時間 | 高速化 |
|---|---|---|
| macOS (MPS + CPU) | 20分51秒 | 1.0x |
| Windows (CUDA) | 4分18秒 | 4.8x 🚀 |
議事録生成時間:
- 5分動画: 4.6秒(gpt-3.5-turbo)
- 84分動画: 38.8秒(gpt-4-turbo、macOS)
- 84分動画: 42.4秒(gpt-4-turbo、Windows)
結論: 議事録生成時間はOpenAI APIの処理時間に依存し、プラットフォームによる差はほとんどありません。
🚧 技術的な課題と解決策
課題1: コンテキスト長制限
問題:
- gpt-3.5-turboの最大トークン数: 16,385トークン
- 84分動画の文字起こし: 43,667トークン(2.7倍超過)
エラー:
This model's maximum context length is 16385 tokens.
However, your messages resulted in 43667 tokens.
解決策:
- GPT-4モデルを使用(128Kトークン対応)
-
--minutes-model gpt-4-turboオプションで指定
コスト比較(2026年3月時点):
- gpt-3.5-turbo: $0.0005/1K tokens(入力)
- gpt-4-turbo: $0.01/1K tokens(入力)
84分動画の推定コスト:
- gpt-3.5-turbo: 使用不可(トークン超過)
- gpt-4-turbo: 約$0.50-1.00
将来の改善案:
- チャンク化実装(長い文字起こしを分割処理)
- 要約してから議事録生成(2段階処理)
課題2: 議事録の精度
依存要素:
- 話者分離の精度
- ASRの精度
- OpenAI APIの理解力
改善方法:
- 高品質な音声入力
- 適切なモデル選択(GPT-4 > GPT-3.5)
- プロンプトの調整
🎨 使い方
基本的な使い方
# 環境変数を設定
export OPENAI_API_KEY="sk-..."
export HF_TOKEN="hf_..."
# 議事録生成付き文字起こし(gpt-3.5-turbo)
python meeting_pipeline.py meeting.mp4 \
--enable-diarization \
--generate-minutes
# GPT-4使用(長時間会議向け)
python meeting_pipeline.py meeting.mp4 \
--enable-diarization \
--generate-minutes \
--minutes-model gpt-4-turbo
# 英語で議事録生成
python meeting_pipeline.py meeting.mp4 \
--enable-diarization \
--generate-minutes \
--minutes-language en
出力ファイル
議事録生成を有効にすると、以下の4つのファイルが生成されます:
-
{basename}_meeting.json- Meeting JSON(文字起こし) -
{basename}_transcript.md- 文字起こしMarkdown -
{basename}_minutes.json- 議事録JSON ✨ -
{basename}_minutes.md- 議事録Markdown ✨
🧪 テスト
テスト実装
Phase 6では31件の新規テストを追加しました:
Task 29: 議事録モジュールのユニットテスト(18件):
- Meeting JSON読み込みテスト(3件)
- プロンプト準備テスト(3件)
- OpenAI API呼び出しテスト(5件、モック使用)
- APIレスポンスパーステスト(4件)
- メイン関数テスト(3件)
Task 30: 出力生成のユニットテスト(7件):
- Markdown生成テスト(4件)
- JSON保存テスト(2件)
- Markdown保存テスト(1件)
Task 31: 統合テスト(6件):
- E2Eテスト(3件、モック使用)
- CLIテスト(3件)
テスト結果
pytest tests/ -q
結果: 87/87 テスト合格 ✅
- 既存テスト: 56件
- 新規テスト: 31件
- 実行時間: 0.16秒
重要: すべてのOpenAI API呼び出しはモックされているため、実際のAPI呼び出しは発生しません。
📈 開発フェーズの振り返り
Phase 1-5(完了済み)
- ✅ Phase 1: 基本パイプライン
- ✅ Phase 2: Markdown生成
- ✅ Phase 3: 単語レベルアライメント
- ✅ Phase 4: macOS MPS/CPU対応
- ✅ Phase 5: Windows CUDA環境検証
Phase 6(今回)
- ✅ OpenAI API統合
- ✅ 要約、決定事項、アクションアイテム、トピック分類の自動生成
- ✅ リトライロジック、エラーハンドリング実装
- ✅ 31件の新規テスト追加
- ✅ クロスプラットフォーム検証(macOS/Windows)
- ✅ 84分動画での実用検証完了
🔮 今後の展望
優先度: 高
-
チャンク化実装
- 長い文字起こしを複数のチャンクに分割
- 各チャンクを個別に処理
- 結果をマージ
-
Meeting JSONから直接議事録生成
- 既存のMeeting JSONから議事録のみ再生成
- モデルや言語を変えて試せる
優先度: 中
-
プロンプトの最適化
- より正確な決定事項抽出
- より詳細なアクションアイテム
- より適切なトピック分類
-
議事録のカスタマイズ
- テンプレート機能
- 出力フォーマットの選択
- 言語の自動検出
優先度: 低
-
コスト最適化
- 要約してから議事録生成(2段階処理)
- トークン数の削減
- キャッシュ機能
-
他のLLMサポート
- Claude API
- Gemini API
- ローカルLLM(Llama、Mistral)
💭 まとめ
Phase 6では、OpenAI APIを統合して議事録自動生成機能を実装しました。
主要成果:
- ✅ 要約、決定事項、アクションアイテム、トピック分類を自動生成
- ✅ 5分動画を約5秒、84分動画を約40秒で議事録化
- ✅ クロスプラットフォーム対応(macOS/Windows)
- ✅ 87件のテスト(100%合格)
ビジネス価値:
- 議事録作成の手作業を削減
- 一貫性のある議事録フォーマット
- タイムスタンプ付き決定事項・アクションアイテム
- 長時間会議にも対応(GPT-4使用)
技術的な学び:
- OpenAI APIのコンテキスト長制限への対応
- リトライロジックとエラーハンドリングの重要性
- プロンプト設計の工夫(タイムスタンプ、話者ラベル)
会議の議事録作成が面倒だと感じている方、ぜひ試してみてください!
🔗 リンク
- GitHub: https://github.com/miyakawa2449/meet
- 詳細ドキュメント: src/README.md
- Phase 6完了報告書: reports/phase6_report.md
- 前回の記事(Phase 1-5): Miyakawa Codes