ChatGPT の利用(文書の整形,文書の要約)(ChatGPT の API,Python を使用)(Windows 上)

概要

ChatGPTとPythonを使った文章の整形や要約の方法をWindowsで紹介している.特徴として,一度に処理できない長い文章の場合には分割処理し,結合して,最終的な結果を得るようにしている.具体的なプログラムの実行方法についても触れられている.文書整形プログラム arrange.py は,指定されたテキストファイルをOpenAIのChatGPT(gpt-5-mini)を使用して整形する.要約プログラム summary.py は,指定されたテキストファイルをOpenAIのChatGPT(gpt-5-mini)を使用して要約し,長さ500文字以下にする.いずれも,テキストが長い場合には分割して処理し,入力ファイルと出力ファイルをコマンドライン引数で指定する.いずれのプログラムも,実行には OpenAI のAPIキーが必要である.プログラムを実行する際に必要なPython開発環境やプログラムの保存方法,ファイル名の指定方法についても説明している.PythonプログラムはUbuntuでも動く.

目次

  1. 前準備
  2. 文書の整形プログラム(ChatGPT API,Python を使用)
  3. 文書の要約プログラム(ChatGPT API,Python を使用)

前準備

Python 3.12 のインストール

Pythonのインストールを行い、Pythonのプログラムを実行する環境を整える。扱う環境は、Windows搭載パソコンである。金子研究室では、Python 3.12.10を推奨する。

[Windows での Python 3.12 のインストール手順を見るには、ここをクリック]

Windows での Python 3.12 のインストール

以下のいずれかの方法でPython 3.12をインストールする。Pythonがインストール済みの場合、この手順は不要である。

方法 1:winget によるインストール

インストールコマンドの実行方法

管理者権限コマンドプロンプトを起動する(手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして、コマンド全体をコマンドプロンプトにコピー&ペーストする。

--scope machine を指定することで、システム全体(全ユーザー向け)にインストールされる。このオプションの実行には管理者権限が必要である。インストール完了後、コマンドプロンプトを再起動するとPATHが反映される。

REM Python 3.12 をシステム領域にインストール
winget install --id Python.Python.3.12 -e --scope machine --silent --accept-source-agreements --accept-package-agreements --override "/quiet InstallAllUsers=1 PrependPath=1 Include_test=0 Include_pip=1 Include_launcher=1 InstallLauncherAllUsers=1 TargetDir=\"C:\Program Files\Python312\""

REM Python と Scripts を PATH 先頭に追加
powershell -NoProfile -Command "$p='C:\Program Files\Python312'; $s=\"$p\Scripts\"; $c=[Environment]::GetEnvironmentVariable('Path','Machine'); if((Test-Path $p) -and (';'+$c+';' -notlike \"*;$p;*\") -and (';'+$c+';' -notlike \"*;$s;*\")){[Environment]::SetEnvironmentVariable('Path',\"$p;$s;$c\",'Machine')}"

方法 2:インストーラーによるインストール

  1. Python公式サイト(https://www.python.org/downloads/)にアクセスし、「Download Python 3.x.x」ボタンからWindows用インストーラーをダウンロードする。
  2. ダウンロードしたインストーラーを実行する。
  3. 初期画面の下部に表示される「Add python.exe to PATH」にチェックを入れてから「Customize installation」を選択する。このチェックを入れ忘れると、コマンドプロンプトから python コマンドを実行できない。
  4. 「Install Python 3.xx for all users」にチェックを入れ、「Install」をクリックする。

インストールの確認

コマンドプロンプトで以下を実行する。

python --version

バージョン番号(例:Python 3.12.x)が表示されればインストール成功である。「'python' は、内部コマンドまたは外部コマンドとして認識されていません。」と表示される場合は、インストールが正常に完了していない。

Python の開発環境 Visual Studio Code のインストールと Python 用の設定

Python の開発環境Visual Studio Code(プログラムを編集するソフトウェア。以下、VS Code)を整える。

[Windows での Visual Studio Code のインストールと Python 用の設定手順を見るには、ここをクリック]

Windows での Visual Studio Code のインストールと Python 用の設定手順

1. VS Code と拡張機能のインストール

以下のコマンドにより,既存の VS Code を削除し,全ユーザー共有の設定で再インストールしたうえで,拡張機能(VS Code に機能を追加するソフトウェア)をまとめて導入する.

インストールコマンドの実行方法

管理者権限コマンドプロンプトを起動する(手順:Windows キーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。そして,コマンド全体をコマンドプロンプトにコピー&ペーストする。

インストールコマンド


REM ============================================================
REM Microsoft Visual Studio Code
REM ============================================================
winget uninstall -e --id Microsoft.VisualStudioCode --silent --disable-interactivity --accept-source-agreements
rmdir /s /q C:\ProgramData\vscode-extensions 2>nul
rmdir /s /q "%APPDATA%\Code" 2>nul
rmdir /s /q "%USERPROFILE%\.vscode" 2>nul
rmdir /s /q "%LOCALAPPDATA%\Microsoft\vscode-update" 2>nul

REM VS Code をシステム領域に新規インストール
winget install --scope machine --id Microsoft.VisualStudioCode -e --silent --accept-source-agreements --accept-package-agreements

REM 全ユーザー共有の拡張機能フォルダ
mkdir C:\ProgramData\vscode-extensions 2>nul
icacls "C:\ProgramData\vscode-extensions" /grant "Everyone:(OI)(CI)M" /T

REM スタートメニューのショートカットを --extensions-dir 付きで再作成
rmdir /s /q "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code" 2>nul
del "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk" 2>nul
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); $lnk.TargetPath='C:\Program Files\Microsoft VS Code\Code.exe'; $lnk.Arguments='--extensions-dir \"C:\ProgramData\vscode-extensions\"'; $lnk.Save()"
REM ショートカットの検証
powershell -NoProfile -Command "$s=New-Object -ComObject WScript.Shell; $lnk=$s.CreateShortcut('C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Visual Studio Code.lnk'); Write-Host 'TargetPath:' $lnk.TargetPath; Write-Host 'Arguments:' $lnk.Arguments"

REM ファイル / フォルダ右クリックの「Code で開く」を登録
reg add "HKLM\SOFTWARE\Classes\*\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%1\"" /f
reg add "HKLM\SOFTWARE\Classes\Directory\Background\shell\VSCode\command" /ve /d "\"C:\Program Files\Microsoft VS Code\Code.exe\" --extensions-dir \"C:\ProgramData\vscode-extensions\" \"%V\"" /f

REM --extensions-dir 付きで起動する code.cmd ラッパを作成
REM (%* を echo で書くと対話的 cmd で失われるため、PowerShell で [char]37+'*' を書き出す)
powershell -NoProfile -Command "$pct=[char]37; $q=[char]34; $c='@echo off'+[char]13+[char]10+$q+'C:\Program Files\Microsoft VS Code\bin\code.cmd'+$q+' --extensions-dir '+$q+'C:\ProgramData\vscode-extensions'+$q+' '+$pct+'*'+[char]13+[char]10; [IO.File]::WriteAllText('C:\ProgramData\vscode-extensions\vscode.cmd',$c,[Text.Encoding]::ASCII)"

REM 拡張機能のインストール
set "CODE=C:\Program Files\Microsoft VS Code\bin\code.cmd"
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --uninstall-extension GitHub.copilot-chat
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.python
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.vscode-pylance
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension ms-python.debugpy
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension MS-CEINTL.vscode-language-pack-ja
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension saoudrizwan.claude-dev
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension rust-lang.rust-analyzer
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension tamasfe.even-better-toml
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension anthropic.claude-code
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --install-extension almenon.arepl
"%CODE%" --extensions-dir "C:\ProgramData\vscode-extensions" --list-extensions --show-versions
echo === セットアップ完了 ===

2. Python インタプリタの選択

同一マシンに複数の Python がインストールされている場合,VS Code で使用する Python 本体(インタプリタ:Python プログラムを解釈・実行するソフトウェア)を選択する必要がある.

  1. コマンドパレット(コマンド名で機能を呼び出す VS Code の入力欄)を開く(Ctrl+Shift+P
  2. Python: Select Interpreter と入力する
  3. 表示される一覧から,使用する Python(例:C:\Program Files\Python312\python.exe)を選択する.
  1. 必要なPythonライブラリのインストール
    1. 以下のコマンドを管理者権限コマンドプロンプトを起動する (手順:Windowsキーまたはスタートメニュー → cmd と入力 → 右クリック → 「管理者として実行」)。
    2. 以下のコマンドを実行し,必要なライブラリをインストールする.
      pip install -U --no-user openai
      

【関連する外部ページ】

【サイト内の関連情報】

文書の整形プログラム(ChatGPT API,Python を使用)

ChatGPT にプロンプトを与えることにより, 日本語の文書を整形して,最終結果をファイルに保存する. HTMLファイルやPDFやパワーポイントなどから抜き出して得られる書式が乱れた文書を整える用途を想定. 指定したファイルの中身が長いときには,分割して,ChatGPT で処理を行う. このプログラムの利用では,OpenAI の APIキーが必要である.

  1. OpenAI の APIキーを準備する

    関連する外部ページ

  2. Windows で,コマンドプロンプトを実行
  3. エディタを起動
    cd /d c:%HOMEPATH%
    notepad arrange.py
    
  4. エディタで,次のプログラムを保存
    '''
    ChatGPT に「次の日本語の文章を整えてください.」のプロンプトを与えることにより,
    整形して,最終結果をファイルに保存する.
    指定したファイルの中身が長いときには,分割して,ChatGPT で処理を行う.
    このプログラムの利用では,APIキーが必要である.
    [利用法]
    python arrange.py --input input.txt --output output.txt --api_key your_api_key
    '''
    
    import argparse
    from openai import OpenAI
    import sys
    import textwrap
    import time
    
    
    MAX_CHUNK_LENGTH = 1500
    DEBUG_PRINT = False
    
    
    def get_arguments():
        parser = argparse.ArgumentParser(description='ChatGPT Text Refinement.')
        parser.add_argument('--input', type=str, required=True,
                            help='Input file path')
        parser.add_argument('--output', type=str, required=True,
                            help='Output file path')
        parser.add_argument('--api_key', type=str, required=True,
                            help='OpenAI API Key')
        parser.add_argument('--remove_url_and_source_code', type=bool, default=False,
                            help='Remove URL and source code from text')
        parser.add_argument('--model', type=str, default="gpt-5-mini",
                            help='GPT model')
    
        args = parser.parse_args()
        return args
    
    
    def send_messages(client, model, content, chunk):
        messages = [
            {"role": "system", "content": content},
            {"role": "user", "content": chunk}
        ]
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print(messages)
    
        try:
            # APIにリクエスト
            response = client.chat.completions.create(
                model=model,
                messages=messages,
            )
        except Exception as e:
            print(f"Failed to send request to OpenAI API: {str(e)}")
            sys.exit(1)
    
        return response.choices[0].message.content
    
    
    def handle_chunk(client, model, content, current_chunk):
        results = []
        # テキストの長さが長すぎる場合、その位置で分割
        chunks = textwrap.wrap(
            current_chunk, width=MAX_CHUNK_LENGTH, break_long_words=True)
        for chunk in chunks:
            # APIにリクエスト
            response = send_messages(client, model, content, chunk)
            if DEBUG_PRINT:
                print("----------------------------------------------------")
                print("response,", response)
            # レスポンスをリストに追加
            results.append(response)
            # APIのレート制限.1分間に40kトークン以下、1分間に200以下リクエストを目指したい
            time.sleep(20)
        return results
    
    
    def request(client, model, content, text):
        sentences = text.split("\n")
    
        results = []
        current_chunk = ""
    
        for sentence in sentences:
            # 一定の長さに達するまで文章を追加
            if len(current_chunk) + len(sentence) < (MAX_CHUNK_LENGTH - 100):
                current_chunk += sentence + "\n"
            else:
                if len(current_chunk) > 0:
                    results += handle_chunk(client, model, content, current_chunk)
                # 現在のチャンクをリセット.次の文を設定
                current_chunk = sentence + "\n"
    
        # 最終チャンクの処理
        if current_chunk:
            results += handle_chunk(client, model, content, current_chunk)
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print("results,", results)
        # 結合して最終的な結果を作成
        final_result = "\n".join(results)
        return final_result
    
    
    def main():
        args = get_arguments()
    
        # OpenAIのAPIキーを設定
        client = OpenAI(api_key=args.api_key)
    
        # ファイル名は,コマンドライン引数
        filename = args.input
        output_filename = args.output
    
        # コマンドライン引数から remove_url_and_source_code の値を取得
        remove_url_and_source_code = args.remove_url_and_source_code
    
        # コマンドライン引数から使用する GPT モデル名を取得
        model = args.model
    
        try:
            with open(filename, 'r', encoding='utf-8') as file:
                text = file.read()
        except FileNotFoundError:
            print(f"The file {filename} was not found.")
            sys.exit(1)
    
        if remove_url_and_source_code:
            prompt = "Please examine the provided Japanese text, and enhance its format by correcting any grammar, spelling, syntax, and punctuation errors, while maintaining the original meaning. If you identify any clear redundancies or disorganized sections, restructure them to improve readability, while ensuring the original intent remains intact. Please exclude any source code and URL in the output. Do not translate or predict subsequent sentences. The output should be in Japanese."
        else:
            prompt = "Please examine the provided Japanese text, and enhance its format by correcting any grammar, spelling, syntax, and punctuation errors, while maintaining the original meaning. If you identify any clear redundancies or disorganized sections, restructure them to improve readability, while ensuring the original intent remains intact. Do not translate or predict subsequent sentences. The output should be in Japanese."
    
        final_result = request(
            client, model,
            prompt, text)
    
        try:
            # 結果をファイルに書き込む
            with open(output_filename, 'w', encoding='utf-8') as output_file:
                output_file.write(final_result)
            print("\033[32m結果が保存されました.入力ファイル名は", filename, "出力ファイル名は", output_filename, "\033[0m")
        except IOError as e:
            print("\033[31mファイルへの書き込みに失敗しました.エラー内容:", str(e), "\033[0m")
            sys.exit(1)
    
    
    if __name__ == "__main__":
        main()
    
  5. Python プログラムの実行

    プログラムを arrange.pyのようなファイル名で保存したので, 「python arrange.py」のようなコマンドで行う.

    input.txt のところには処理したいファイル名を指定すること.

    output.txt のところには結果を保存したいファイル名を指定すること.

    your_api_key のところには OpenAI の API キーを指定すること.

    もし,ソースコードおよび URL を取り除いて処理したいときは「--remove_url_and_source_code 1」を付けることができる.

    既定(デフォルト)のモデルは,「gpt-5-mini」である. もしモデルを変更したいときは,「--model <モデル名>」のように指定できる.

    python arrange.py --input input.txt --output output.txt --api_key your_api_key
    
  6. 結果の確認
    • 処理前のテキストファイルの先頭部分

      (以下省略)
    • 処理結果のテキストファイルの先頭部分

      処理結果では,文章として整うように整形される.


      (以下省略)

文書の要約プログラム(ChatGPT API,Python を使用)

指定したテキストファイルを読み込み, ChatGPT にプロンプトを与えることにより,要約して,最終結果をファイルに保存する.指定したファイルの中身が長いときには,分割して,ChatGPT で処理を行い,処理結果を結合するようにしている. 要約した結果が長いときは,要約を繰り返す

  1. OpenAI の API キーを準備しておく

    OpenAI の API キーのページ

    https://platform.openai.com/api-keys

    料金の条件や利用履歴はこちらで確認.

    https://platform.openai.com/settings/organization/limits

  2. Windows で,コマンドプロンプトを実行
  3. エディタを起動
    cd /d c:%HOMEPATH%
    notepad summary.py
    
  4. エディタで,次のプログラムを保存
    '''
    指定したテキストファイルを読み込み,
    ChatGPT にプロンプトを与えることにより,要約して,最終結果をファイルに保存する.指定したファイルの中身が長いときには,分割して,ChatGPT で処理を行い,処理結果を結合するようにしている.
    要約した結果が長いときは,要約を繰り返す.
    [利用法]
    python summary.py --input input.txt --output output.txt --api_key your_api_key
    '''
    
    import argparse
    from openai import OpenAI
    import sys
    import textwrap
    import time
    
    
    MAX_CHUNK_LENGTH = 1500
    DEBUG_PRINT = False
    CHARACTERS = 500
    
    def get_arguments():
        parser = argparse.ArgumentParser(description='ChatGPT Text Refinement.')
        parser.add_argument('--input', type=str, required=True,
                            help='Input file path')
        parser.add_argument('--output', type=str, required=True,
                            help='Output file path')
        parser.add_argument('--api_key', type=str, required=True,
                            help='OpenAI API Key')
        parser.add_argument('--remove_url_and_source_code', type=bool, default=False,
                            help='Remove URL and source code from text')
        parser.add_argument('--model', type=str, default="gpt-5-mini",
                            help='GPT model')
    
        args = parser.parse_args()
        return args
    
    
    def send_messages(client, model, content, chunk):
        messages = [
            {"role": "system", "content": content},
            {"role": "user", "content": chunk}
        ]
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print(messages)
    
        try:
            # APIにリクエスト
            response = client.chat.completions.create(
                model=model,
                messages=messages,
            )
        except Exception as e:
            print(f"Failed to send request to OpenAI API: {str(e)}")
            sys.exit(1)
    
        return response.choices[0].message.content
    
    
    def handle_chunk(client, model, content, current_chunk):
        results = []
        # テキストの長さが長すぎる場合、その位置で分割
        chunks = textwrap.wrap(
            current_chunk, width=MAX_CHUNK_LENGTH, break_long_words=True)
        for chunk in chunks:
            # APIにリクエスト
            response = send_messages(client, model, content, chunk)
            if DEBUG_PRINT:
                print("----------------------------------------------------")
                print("response,", response)
            # レスポンスをリストに追加
            results.append(response)
            # APIのレート制限.1分間に40kトークン以下、1分間に200以下リクエストを目指したい
            time.sleep(20)
        return results
    
    
    def request(client, model, content, text):
        sentences = text.split("\n")
    
        results = []
        current_chunk = ""
    
        for sentence in sentences:
            # 一定の長さに達するまで文章を追加
            if len(current_chunk) + len(sentence) < (MAX_CHUNK_LENGTH - 100):
                current_chunk += sentence + "\n"
            else:
                if len(current_chunk) > 0:
                    results += handle_chunk(client, model, content, current_chunk)
                # 現在のチャンクをリセット.次の文を設定
                current_chunk = sentence + "\n"
    
        # 最終チャンクの処理
        if current_chunk:
            results += handle_chunk(client, model, content, current_chunk)
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print("results,", results)
        # 結合して最終的な結果を作成
        final_result = "\n".join(results)
        return final_result
    
    
    def main():
        args = get_arguments()
    
        # OpenAIのAPIキーを設定
        client = OpenAI(api_key=args.api_key)
    
        # ファイル名は,コマンドライン引数
        filename = args.input
        output_filename = args.output
    
        # コマンドライン引数から remove_url_and_source_code の値を取得
        remove_url_and_source_code = args.remove_url_and_source_code
    
        # コマンドライン引数から使用する GPT モデル名を取得
        model = args.model
    
        try:
            with open(filename, 'r', encoding='utf-8') as file:
                text = file.read()
        except FileNotFoundError:
            print(f"The file {filename} was not found.")
            sys.exit(1)
    
        prompt1 = "Please provide a summary of the supplied Japanese text, excluding any source code and URL. Do not translate or predict any future sentences. The output should be a single paragraph and it should be in Japanese."
        prompt2 = "Please provide a summary of the supplied Japanese text. Do not translate or predict any future sentences. The output should be a single paragraph and it should be in Japanese."
    
        if remove_url_and_source_code:
            prompt = prompt1
        else:
            prompt = prompt2
    
        final_result = request(
            client, model,
            prompt, text)
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print("final_result,", final_result)
    
        while(len(final_result) > CHARACTERS):
            # 長いので、もう一度要約する。
            text = final_result
            final_result = request(
                client, model,
                prompt, text)
    
            if DEBUG_PRINT:
                print("----------------------------------------------------")
                print("final_result,", final_result)
    
        # 全体を整えるように ChatGPT に頼む
        text = final_result
        final_result = request(
            client, model,
            "As a professional proofreader, your task is to refine and correct the provided Japanese text while preserving its original meaning. The refined output should not translate or predict any future sentences, and it should be consolidated into a single paragraph. Importantly, the output must remain in Japanese and not exceed " + str(CHARACTERS) + " characters.", text)
    
        if DEBUG_PRINT:
            print("----------------------------------------------------")
            print("final_result,", final_result)
    
    
        try:
            # 結果をファイルに書き込む
            with open(output_filename, 'w', encoding='utf-8') as output_file:
                output_file.write(final_result.replace('\r', '').replace('\n', ''))
            print("\033[32m結果が保存されました.入力ファイル名は", filename, "出力ファイル名は", output_filename, "\033[0m")
        except IOError as e:
            print("\033[31mファイルへの書き込みに失敗しました.エラー内容:", str(e), "\033[0m")
            sys.exit(1)
    
    
    if __name__ == "__main__":
        main()
    
  5. Python プログラムの実行

    プログラムを summary.pyのようなファイル名で保存したので, 「python summary.py」のようなコマンドで行う.

    output.txt のところには処理したいファイル名を指定すること.

    summary.txt のところには結果を保存したいファイル名を指定すること.

    your_api_key のところには OpenAI の API キーを指定すること.

    もし,ソースコードおよび URL を取り除いて処理したいときは「--remove_url_and_source_code 1」を付けることができる.

    既定(デフォルト)のモデルは,「gpt-5-mini」である. もしモデルを変更したいときは,「--model <モデル名>」のように指定できる.

    python summary.py --input output.txt --output summary.txt --api_key your_api_key
    
  6. 結果の確認
    • 処理前のテキストファイルの先頭部分

      (以下省略)
    • 処理結果のテキストファイル

      処理結果では要約される.文字数は「CHARACTERS = 500」で調整してください.