「会議のあとに議事録を書くのがしんどい…」「録音したファイルを手で聞き返しながら文字起こしするのに毎回1〜2時間かかる…」

そんな悩みを抱えている方、多いんじゃないでしょうか。

実は、OpenAIが提供している Whisper API を使えば、Pythonで数十行のコードを書くだけで音声ファイルを自動でテキスト化できます。しかも精度がかなり高く、日本語にもしっかり対応しています。

今回はWhisper APIを使って、音声ファイルを文字起こしして議事録テキストを自動生成するPythonアプリをゼロから作っていきます。ChatGPT APIとの組み合わせで、単なる文字起こしを超えた「整形済み議事録」を出力する応用例もご紹介します!

📋 この記事で作るもの・対象読者

voice recording transcription
voice recording transcription / Photo by dlxmedia.hu via Pexels

この記事で作るのはこんなアプリです。

  • 音声ファイル(.mp3 / .mp4 / .wav など)をPythonスクリプトに渡す
  • Whisper APIが自動で文字起こしをしてくれる
  • さらにGPT-4oに渡して「会議の要点・決定事項・次のアクション」を整理した議事録フォーマットに変換する

対象読者:

  • PythonでAPIを呼び出した経験が少しある方(初〜中級者)
  • 議事録作成を自動化したいビジネスパーソン・エンジニア
  • OpenAI APIをはじめて使う方

🛠️ 事前準備

必要なもの

  • Python 3.9以上
  • OpenAIのAPIキー(有料プランが必要です)
  • 文字起こししたい音声ファイル(mp3・mp4・wav・m4a など25MB以内)

ライブラリのインストール

必要なライブラリは openaipython-dotenv の2つだけです。シンプルですよね。

pip install openai python-dotenv

APIキーの設定

APIキーをコードに直書きするのはセキュリティ上NGです。.env ファイルを使って管理しましょう。

プロジェクトフォルダに .env ファイルを作り、以下を記述します。

OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxxxxxxxxxxxxxx

⚠️ .envファイルは必ず .gitignore に追加してください。GitHubに上げてしまうとAPIキーが漏洩します。

🎤 STEP 1:Whisper APIで音声をテキスト化する

まずはWhisper APIの基本的な使い方から見ていきましょう。

イメージとしては、「音声ファイルをOpenAIのサーバーに送ると、テキストが返ってくる」という非常にシンプルな仕組みです。

import os
from openai import OpenAI
from dotenv import load_dotenv

# .envファイルからAPIキーを読み込む
load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def transcribe_audio(file_path: str) -> str:
    """
    音声ファイルをWhisper APIでテキスト化する関数
    """
    with open(file_path, "rb") as audio_file:
        response = client.audio.transcriptions.create(
            model="whisper-1",       # Whisperモデルを指定
            file=audio_file,
            language="ja",           # 日本語を明示指定(精度が上がる)
            response_format="text"   # テキスト形式で返す
        )
    return response

# 実行テスト
if __name__ == "__main__":
    text = transcribe_audio("meeting.mp3")
    print("=== 文字起こし結果 ===")
    print(text)

ポイントをまとめるとこんな感じです👇

  • model=”whisper-1″:Whisper APIの唯一のモデル名です。これ一択でOK
  • language=”ja”:日本語を明示することで認識精度が向上します。省略すると自動判定になりますが、明示した方が安定します
  • response_format=”text”:シンプルなテキスト文字列で返す設定。タイムスタンプ付きが欲しい場合は "verbose_json" も使えます

📝 STEP 2:GPT-4oで議事録フォーマットに整形する


文字起こし結果をそのまま使うのもアリですが、会議の録音をそのままテキスト化しても「えー」「あのー」「そうですね」が混ざって読みにくいですよね。

そこで、文字起こしテキストをGPT-4oに渡して、きれいな議事録フォーマットに変換してもらいましょう。

def format_as_minutes(transcript: str) -> str:
    """
    文字起こしテキストをGPT-4oで議事録形式に整形する関数
    """
    prompt = f"""
以下は会議の文字起こしテキストです。
この内容を読みやすい議事録に整形してください。

【出力フォーマット】
## 会議の概要
(会議全体の要約を2〜3文で)

## 主な議題と議論内容
(箇条書きで整理)

## 決定事項
(確定した内容を箇条書きで)

## 次回までのアクション
(誰が・何を・いつまでに、の形式で)

---
【文字起こしテキスト】
{transcript}
"""

    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "あなたは優秀な議事録作成アシスタントです。"},
            {"role": "user", "content": prompt}
        ],
        temperature=0.3   # 低めに設定して安定した出力を得る
    )
    return response.choices[0].message.content

ここが重要です!

  • temperatureを0.3に下げる:創造性より一貫性・正確性を優先したいので低めに設定しています
  • プロンプトにフォーマットを明示する:出力形式を指定しておくと、毎回同じ構造の議事録が生成されます
  • systemプロンプトで役割を与える:「議事録作成アシスタント」と明示することでより適切な文体になります

🚀 STEP 3:まとめてパイプライン化する

STEP 1とSTEP 2を組み合わせて、「音声ファイルを渡したら議事録テキストが返ってくる」一本のパイプラインにまとめましょう。

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

def transcribe_audio(file_path: str) -> str:
    with open(file_path, "rb") as audio_file:
        response = client.audio.transcriptions.create(
            model="whisper-1",
            file=audio_file,
            language="ja",
            response_format="text"
        )
    return response

def format_as_minutes(transcript: str) -> str:
    prompt = f"""
以下は会議の文字起こしテキストです。読みやすい議事録に整形してください。

## 会議の概要
## 主な議題と議論内容
## 決定事項
## 次回までのアクション

【文字起こしテキスト】
{transcript}
"""
    response = client.chat.completions.create(
        model="gpt-4o",
        messages=[
            {"role": "system", "content": "あなたは優秀な議事録作成アシスタントです。"},
            {"role": "user", "content": prompt}
        ],
        temperature=0.3
    )
    return response.choices[0].message.content

def generate_minutes(audio_file_path: str, output_path: str = "minutes.txt"):
    """
    音声ファイルを受け取り、議事録テキストを生成して保存するメイン関数
    """
    print(f"🎤 文字起こし開始:{audio_file_path}")
    transcript = transcribe_audio(audio_file_path)
    print("✅ 文字起こし完了!")
    print("📝 議事録を整形中...")
    minutes = format_as_minutes(transcript)
    # テキストファイルとして保存
    with open(output_path, "w", encoding="utf-8") as f:
        f.write(minutes)
    print(f"✅ 議事録を保存しました:{output_path}")
    return minutes

if __name__ == "__main__":
    result = generate_minutes("meeting.mp3", "meeting_minutes.txt")
    print(result)

これを実行すると、meeting_minutes.txt に整形された議事録が保存されます。

⚠️ 注意点・よくあるつまずきポイント

ファイルサイズの上限に注意

Whisper APIの上限は 25MB です。長い会議録音は超えてしまうことがあります。その場合は pydub などで音声を分割してから送るのが定番の対処法です。

対応ファイル形式

mp3・mp4・mpeg・mpga・m4a・wav・webm に対応しています。Zoomの録画(mp4)もそのまま渡せるので便利ですよ。

コストの目安

Whisper APIは 1分あたり約$0.006(約0.9円) です。60分の会議でも約54円程度。GPT-4oの整形処理を加えても1回の議事録作成コストは数十〜100円前後に収まります。

まとめ


今回はWhisper APIとGPT-4oを組み合わせて、音声ファイルから議事録を自動生成するPythonアプリを作りました。

ざっくりポイントをおさらいすると👇

  • Whisper APIは client.audio.transcriptions.create() を呼ぶだけで文字起こしができる
  • language="ja" で日本語認識精度がアップする
  • 文字起こし結果をGPT-4oに渡してフォーマット変換すれば、そのまま使える議事録が完成する
  • 全体を関数に分割しておくと、別のスクリプトからも再利用しやすい

毎週の定例会議や1on1の録音をこのスクリプトに通すだけで、議事録作業がぐっと楽になりますよ。ぜひ自分の業務フローに組み込んで試してみてください 🎉

次のステップとしては、GradioやStreamlitでUIをつけてブラウザから操作できるアプリにするのも面白いです。音声ファイルをドラッグ&ドロップして議事録ボタンを押すだけ、というアプリが意外と簡単に作れます。興味があればぜひチャレンジしてみてください!

📚 関連商品・おすすめ書籍

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

もしも

スッキリわかるPython入門 第2版 (スッキリわかる入門シリーズ)

初心者に定番のPython入門書

Amazonで見る

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

もしも

実践Claude Code入門―現場で活用するためのAIコーディングの思考法

AIコーディングの現場活用法を学ぶ一冊

Amazonで見る

Python Web開発実践入門 ―― FastAPIによるWebAPI開発と非同期処理

もしも

Python Web開発実践入門 ―― FastAPIによるWebAPI開発と非同期処理

FastAPIでWebAPI開発を実践的に学ぶ

Amazonで見る

※本記事にはアフィリエイトリンクが含まれます。

ABOUT ME
やまちゃん
これまで学生と社会人を合わせて5000人以上にプログラミング学習を指導。 ゼロからイチをわかりやすく解説する専門家として活動しており、本業ではArduinoを用いたIoT開発とロボットプログラミングが専門。 Pythonを用いたアプリ開発、ウェブアプリケーションの開発で業務の効率化をサポートしています。