OpenAI APIで作る開発効率化スクリプト5選【Python実装例付き】
「テストコード書くのが面倒すぎる…」「READMEの更新を後回しにしがちで、結局ドキュメントがスカスカになる…」「デバッグに時間を取られてコア実装が進まない…」
そういった「重要だけど地味に時間を食う開発タスク」を、OpenAI APIとPythonで自動化するスクリプトを5本、実装例つきで紹介します。
各スクリプトは単体で動くだけでなく、組み合わせて使えるよう共通のヘルパーモジュールを土台にしています。コピペして試しながら、自分のプロジェクトに組み込んでいきましょう🚀
この記事の対象読者・難易度


- ✅ PythonでOpenAI APIを呼び出したことがある、または呼び出し方を学んでいる方
- ✅ pytest・型ヒント・pathlib など標準的なPython文法を読める中級者
- ✅ 「APIは使ったことあるけど、開発ワークフローへの組み込み方がわからない」方
難易度:中級者向け(コードはそのまま動かせます。Python 3.10以上と pip install openai python-dotenv が前提です。型ヒントに str | None 記法を使用しているため、3.9以前では動作しません)
はじめに:プロンプト設計3原則
スクリプトの実装に入る前に、LLM APIを開発ツールとして使うときのプロンプト設計3原則を押さえておきましょう。この3原則を守るだけで、出力の品質と安定性が大きく変わります。
原則① 役割(Role)を明示する
システムメッセージで「誰として回答するか」を宣言します。たとえばテスト生成なら「TDDを実践するシニアエンジニア」、デバッグ支援なら「ログ解析の専門家」のように具体的な職能を与えると、回答のトーンと深度が変わります。
NG例:「あなたはAIアシスタントです。」
OK例:「あなたはPython・pytest・型ヒントに精通したシニアバックエンドエンジニアです。」
原則② 出力フォーマットを固定する
「コードのみ出力してください」「マークダウンのコードブロックで囲んでください」など、出力形式を明示的に指定することで、後続の文字列処理が安定します。説明文が混入するとパースが壊れるため、開発ツールとして使う場合は必ず指定しましょう。
原則③ 制約条件を「箇条書き」で渡す
「〇〇してください、△△してください、□□してください」を長文で書くより、箇条書きで渡す方がLLMは各条件を取りこぼしにくくなります。テスト生成・README生成など複数の要件がある場合は特に効果的です。
この3原則を踏まえて、以降のスクリプトはすべて設計されています。
共通ヘルパーモジュール(全スクリプトの土台)
5本のスクリプトはすべてこのヘルパーをimportして使います。最初にこれだけ作っておけば、各スクリプトはLLMの呼び出し方を意識せずに済みます。
# llm_helper.py
# 全スクリプト共通のOpenAI APIラッパー
import os
from openai import OpenAI
from dotenv import load_dotenv
# .envファイルから環境変数を読み込む
# OPENAI_API_KEY=sk-... を .env に記載しておく
load_dotenv()
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
def call_llm(
user_prompt: str,
system_prompt: str = "あなたは優秀なソフトウェアエンジニアです。",
model: str = "gpt-4o",
temperature: float = 0.2,
) -> str:
"""
OpenAI Chat Completions APIを呼び出す汎用ラッパー。
Args:
user_prompt: ユーザーからの指示・入力テキスト
system_prompt: AIの役割・ルールを定義するシステムメッセージ
model: 使用するモデル名(デフォルト: gpt-4o)
temperature: 出力のランダム性(コード生成は低め推奨)
Returns:
LLMの返答テキスト(文字列)
"""
response = client.chat.completions.create(
model=model,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt},
],
temperature=temperature,
)
return response.choices[0].message.content.strip()
def extract_code_block(text: str, lang: str = "python") -> str:
"""
LLMの出力からコードブロック部分だけを抜き出すユーティリティ。
```python ... ``` 形式で囲まれていれば中身だけを返す。
囲まれていない場合はそのまま返す。
Args:
text: LLMの出力テキスト
lang: コードブロックの言語タグ(デフォルト: python)
Returns:
コード文字列
"""
marker = f"```{lang}"
if marker in text:
start = text.index(marker) + len(marker)
end = text.index("```", start)
return text[start:end].strip()
# マークダウン形式でなければそのまま返す
return text.strip()
💡 ポイント:
temperature=0.2:コード生成では低めにして出力を安定させるextract_code_block():LLMが余計な説明文をつけてきたときでも、コード部分だけを取り出せるpython-dotenvを使い、APIキーをソースコードに直書きしない
スクリプト① 関数仕様からスケルトンコードを自動生成する
「こういう関数を作りたい」という日本語の仕様を渡すと、型ヒント・docstring・エラーハンドリングつきのスケルトンコードを生成します。ゼロから書くより、まずAIに骨格を作らせてから手を入れる方が圧倒的に速いです。
# script01_code_generator.py
# 関数仕様(日本語)からPythonスケルトンコードを生成するスクリプト
from pathlib import Path
from llm_helper import call_llm, extract_code_block
SYSTEM_PROMPT = """あなたはPythonのシニアエンジニアです。
以下のルールに従ってコードを生成してください。
- 型ヒントを必ずつける
- Googleスタイルのdocstringを書く
- 想定されるエラーはraiseで明示的に処理する
- 実装の本体は `raise NotImplementedError` で仮置きする
- コードブロック(```python ... ```)のみを出力し、説明文は不要"""
def generate_skeleton(spec: str, output_file: str | None = None) -> str:
"""
日本語の仕様からPython関数のスケルトンコードを生成する。
Args:
spec: 作りたい関数の仕様(日本語で記述)
output_file: 保存先のファイルパス(省略時は保存しない)
Returns:
生成されたPythonコード文字列
"""
prompt = f"""以下の仕様を満たすPython関数のスケルトンコードを生成してください。
仕様:
{spec}"""
raw = call_llm(prompt, system_prompt=SYSTEM_PROMPT)
code = extract_code_block(raw)
if output_file:
Path(output_file).write_text(code, encoding="utf-8")
print(f"✅ {output_file} に保存しました")
return code
if __name__ == "__main__":
spec = """
- 関数名: load_and_clean_csv
- CSVファイルパスを受け取り、pandasのDataFrameを返す
- 読み込み時に文字コードをUTF-8に指定する
- 列名の前後の空白を除去する
- 全列の欠損値を含む行を削除する
- ファイルが存在しない場合は FileNotFoundError を raise する
"""
code = generate_skeleton(spec, output_file="load_and_clean_csv.py")
print(code)
実行すると、型ヒント・docstring・例外処理の枠が整った状態のファイルが生成されます。あとは raise NotImplementedError の部分を実装するだけです。
スクリプト② 実装コードからpytestテストを自動生成する
テストを後から書こうとすると、仕様を思い出すところから始まって地味に時間がかかります。実装が完成した直後にそのコードをそのまま渡してテストを生成すれば、仕様の記憶が新鮮なうちにテストが揃います。
# script02_pytest_generator.py
# 実装済みのPythonコードからpytestテストコードを自動生成するスクリプト
from pathlib import Path
from llm_helper import call_llm, extract_code_block
SYSTEM_PROMPT = """あなたはTDDを実践するPythonシニアエンジニアです。
以下のルールに従ってpytestのテストコードを生成してください。
- テスト関数名は test_ で始める
- 各テスト関数には日本語のdocstringで何をテストするか書く
- 正常系・異常系(例外)・境界値の3種類を必ず含める
- 外部依存がある場合は unittest.mock.patch でモックする
- pytest.mark.parametrize を積極的に活用する
- コードブロック(```python ... ```)のみを出力し、説明文は不要"""
def generate_pytest(source_code: str, output_file: str | None = None) -> str:
"""
ソースコードを渡してpytestのテストコードを生成する。
Args:
source_code: テスト対象のPythonコード文字列
output_file: 保存先のファイルパス(省略時は保存しない)
Returns:
生成されたテストコード文字列
"""
prompt = f"""以下のPythonコードに対するpytestのテストコードを生成してください。
```python
{source_code}
```"""
raw = call_llm(prompt, system_prompt=SYSTEM_PROMPT)
test_code = extract_code_block(raw)
if output_file:
Path(output_file).write_text(test_code, encoding="utf-8")
print(f"✅ {output_file} に保存しました")
return test_code
if __name__ == "__main__":
# テスト対象の関数(文字列で渡す)
target = Path("load_and_clean_csv.py").read_text(encoding="utf-8")
test_code = generate_pytest(target, output_file="test_load_and_clean_csv.py")
print(test_code)
💡 運用のコツ:
- 生成されたテストは必ず目視確認して微調整する。特に境界値の数値は要確認
pytest.mark.parametrizeで複数ケースをまとめるよう指示すると、テスト数が増えても見通しが良い- スクリプト①→②をセットで実行すれば、仕様→実装→テストの流れが一気に揃う
スクリプト③ リポジトリ構造からREADME.mdを自動生成する
プロジェクトの構成ファイルを自動収集し、プロフェッショナルなREADMEのドラフトを生成します。ゼロから書く手間がなくなるだけでなく、書き忘れがちな「インストール手順」や「使い方」のセクションも自動で入るのが便利です。
# script03_readme_generator.py
# プロジェクトディレクトリを解析してREADME.mdを自動生成するスクリプト
from pathlib import Path
from llm_helper import call_llm
SYSTEM_PROMPT = """あなたはOSSプロジェクトのドキュメント専門家です。
以下のルールに従ってREADME.mdを生成してください。
- マークダウン形式で出力する
- 以下のセクションを必ず含める: 概要・特徴・インストール・使い方・ディレクトリ構成・ライセンス
- コード例はコードブロックで囲む
- 日本語で記述する
- 余計な前置きや説明は不要。README本文のみを出力する"""
def collect_project_info(project_dir: str) -> dict:
"""
プロジェクトディレクトリからREADME生成に必要な情報を収集する。
Args:
project_dir: 対象プロジェクトのルートディレクトリパス
Returns:
ファイル一覧・依存ライブラリ・メインコードを含む辞書
"""
root = Path(project_dir)
info: dict = {"files": [], "requirements": "", "main_code": ""}
# 隠しファイル・__pycache__・.gitを除外したファイル一覧
exclude = {"__pycache__", ".git", ".venv", "node_modules"}
for f in sorted(root.rglob("*")):
if f.is_file() and not any(p in exclude for p in f.parts):
if not f.name.startswith("."):
info["files"].append(str(f.relative_to(root)))
# requirements.txt があれば読み込む
req = root / "requirements.txt"
if req.exists():
info["requirements"] = req.read_text(encoding="utf-8")
# main.py / app.py の先頭50行だけ読み込む(トークン節約)
for candidate in ["main.py", "app.py"]:
main_file = root / candidate
if main_file.exists():
lines = main_file.read_text(encoding="utf-8").splitlines()[:50]
info["main_code"] = "\n".join(lines)
break
return info
def generate_readme(
project_name: str,
description: str,
project_dir: str,
output_file: str = "README_generated.md",
) -> str:
"""
プロジェクト情報を収集してREADME.mdを生成する。
Args:
project_name: プロジェクト名
description: プロジェクトの概要説明(日本語)
project_dir: プロジェクトのルートディレクトリパス
output_file: 出力ファイル名
Returns:
生成されたREADME文字列
"""
info = collect_project_info(project_dir)
prompt = f"""以下のプロジェクト情報をもとにREADME.mdを生成してください。
プロジェクト名: {project_name}
概要: {description}
ファイル一覧:
{chr(10).join(info['files'])}
依存ライブラリ (requirements.txt):
{info['requirements'] or '(なし)'}
メインコード(先頭50行):
```python
{info['main_code'] or '(なし)'}
```"""
readme = call_llm(prompt, system_prompt=SYSTEM_PROMPT, temperature=0.3)
Path(output_file).write_text(readme, encoding="utf-8")
print(f"✅ {output_file} に保存しました")
return readme
if __name__ == "__main__":
generate_readme(
project_name="dev-automation-scripts",
description="OpenAI APIを使った開発効率化スクリプト集",
project_dir=".",
)
スクリプト④ エラートレースバックからデバッグ支援レポートを生成する
エラーが出たとき、トレースバックをそのままLLMに渡すと原因候補と修正案を返してくれます。ここで重要なのは「関連するソースコードも一緒に渡す」こと。コンテキストが増えるほど回答の精度が上がります。
# script04_debug_assistant.py
# エラートレースバック + ソースコードからデバッグ支援レポートを生成するスクリプト
from pathlib import Path
from datetime import datetime
from llm_helper import call_llm
SYSTEM_PROMPT = """あなたはPythonのデバッグ専門家です。
以下のルールに従って回答してください。
- エラーの根本原因を1〜2文で端的に説明する
- 修正案をコードブロックつきで示す
- 同じミスを防ぐための予防策を1つ提案する
- 出力は以下のマークダウン構造で返す:
## 根本原因
## 修正コード
## 予防策"""
def analyze_error(
traceback_text: str,
source_code: str = "",
save_report: bool = True,
) -> str:
"""
エラートレースバックを解析してデバッグ支援レポートを生成する。
Args:
traceback_text: コピーしたトレースバック文字列
source_code: 関連するソースコード(渡すほど精度が上がる)
save_report: Trueならタイムスタンプつきのファイルに保存
Returns:
デバッグ支援レポート文字列
"""
code_section = ""
if source_code:
code_section = f"""
関連ソースコード:
```python
{source_code}
```"""
prompt = f"""以下のエラーを解析してデバッグ支援レポートを作成してください。
トレースバック:
```
{traceback_text}
```{code_section}"""
report = call_llm(prompt, system_prompt=SYSTEM_PROMPT, temperature=0.1)
if save_report:
ts = datetime.now().strftime("%Y%m%d_%H%M%S")
filename = f"debug_report_{ts}.md"
Path(filename).write_text(report, encoding="utf-8")
print(f"✅ デバッグレポートを {filename} に保存しました")
return report
if __name__ == "__main__":
# 実際のエラーをここに貼り付けて実行する
traceback_sample = """
Traceback (most recent call last):
File "main.py", line 12, in <module>
result = load_and_clean_csv("data.csv")
File "load_and_clean_csv.py", line 18, in load_and_clean_csv
df = pd.read_csv(path, encoding="utf-8")
File "/usr/local/lib/python3.11/site-packages/pandas/io/parsers/readers.py", line 912, in read_csv
return _read(filepath_or_buffer, kwds)
FileNotFoundError: [Errno 2] No such file or directory: 'data.csv'
"""
source_sample = Path("load_and_clean_csv.py").read_text(encoding="utf-8") \
if Path("load_and_clean_csv.py").exists() else ""
report = analyze_error(traceback_sample, source_code=source_sample)
print(report)
💡 活用のコツ:temperature=0.1 でほぼ決定論的な出力にするのがポイントです。デバッグの場面で「毎回違う回答」が来ると混乱するため、再現性を最大まで上げます。
スクリプト⑤ 作業ログから報告メールのドラフトを生成する
「今日やったこと」を箇条書きで渡すと、丁寧な報告メールに整形してくれます。書くのは事実の羅列だけ。文章化はAIに任せるという分担が、じわじわ効いてきます。
# script05_report_email_generator.py
# 作業ログ(箇条書き)から報告メールのドラフトを生成するスクリプト
from pathlib import Path
from datetime import date
from llm_helper import call_llm
SYSTEM_PROMPT = """あなたはビジネスメールの文章整形の専門家です。
以下のルールに従ってメール文面を生成してください。
- 件名・宛名・本文・署名の構造で出力する
- 丁寧語を使い、簡潔にまとめる(だらだら書かない)
- 技術用語はそのまま使ってよいが、略語には補足を入れる
- ネガティブな報告(遅延・問題)は事実を率直に伝えつつ対応策も添える
- 件名は「【作業報告】〇〇」の形式にする"""
def generate_report_email(
work_logs: list[str],
recipient_name: str,
project_name: str,
sender_name: str,
next_actions: list[str] | None = None,
output_file: str | None = None,
) -> str:
"""
作業ログのリストから報告メールのドラフトを生成する。
Args:
work_logs: 今日の作業内容の箇条書きリスト
recipient_name: 宛先の名前(例: 「田中様」)
project_name: プロジェクト名
sender_name: 送信者名
next_actions: 次回以降の予定アクション(省略可)
output_file: 保存先ファイルパス(省略時は保存しない)
Returns:
生成されたメール文面の文字列
"""
logs_text = "\n".join(f"- {log}" for log in work_logs)
actions_text = ""
if next_actions:
actions_text = "\n次回予定:\n" + "\n".join(f"- {a}" for a in next_actions)
prompt = f"""以下の情報をもとに作業報告メールを作成してください。
日付: {date.today().strftime('%Y年%m月%d日')}
プロジェクト名: {project_name}
宛先: {recipient_name}
送信者: {sender_name}
本日の作業内容:
{logs_text}
{actions_text}"""
email_draft = call_llm(prompt, system_prompt=SYSTEM_PROMPT, temperature=0.4)
if output_file:
Path(output_file).write_text(email_draft, encoding="utf-8")
print(f"✅ {output_file} に保存しました")
return email_draft
if __name__ == "__main__":
draft = generate_report_email(
work_logs=[
"APIエンドポイント /users の実装完了・pytestテスト12件追加",
"CSVインポート機能のバグ修正(文字コードUTF-8/Shift_JIS両対応)",
"README.mdにAPIドキュメントセクションを追記",
],
recipient_name="鈴木様",
project_name="在庫管理システム リニューアル",
sender_name="山田 太郎",
next_actions=[
"認証機能の実装(JWT)",
"ステージング環境へのデプロイ確認",
],
output_file="report_email_draft.txt",
)
print(draft)
5本のスクリプトをまとめて実行するCLI
最後に、5本をまとめて呼び出せる簡易CLIラッパーを作っておきましょう。引数でスクリプトを選べるようにしておくと、ターミナルから素早く使えます。
# run_dev_tools.py
# 5本の開発効率化スクリプトをまとめて呼び出すCLIエントリーポイント
import argparse
from pathlib import Path
def main() -> None:
parser = argparse.ArgumentParser(
description="OpenAI APIを使った開発効率化スクリプト集"
)
subparsers = parser.add_subparsers(dest="command", required=True)
# ① コード生成
gen = subparsers.add_parser("gen", help="関数仕様からスケルトンコードを生成")
gen.add_argument("spec", help="仕様を記述したテキストファイルのパス")
gen.add_argument("-o", "--output", default="generated_code.py")
# ② テスト生成
test = subparsers.add_parser("test", help="実装コードからpytestを生成")
test.add_argument("source", help="テスト対象のPythonファイルパス")
test.add_argument("-o", "--output", default=None)
# ③ README生成
readme = subparsers.add_parser("readme", help="プロジェクトからREADMEを生成")
readme.add_argument("name", help="プロジェクト名")
readme.add_argument("description", help="プロジェクトの概要説明")
readme.add_argument("-d", "--dir", default=".")
# ④ デバッグ支援
debug = subparsers.add_parser("debug", help="トレースバックを解析してレポート生成")
debug.add_argument("traceback", help="トレースバックを貼り付けたテキストファイルパス")
debug.add_argument("-s", "--source", default=None, help="関連ソースファイルパス")
# ⑤ 報告メール生成
report = subparsers.add_parser("report", help="作業ログから報告メールを生成")
report.add_argument("logs", help="作業ログ(1行1項目)を記載したテキストファイルパス")
report.add_argument("recipient", help="宛先の名前(例: 田中様)")
report.add_argument("project", help="プロジェクト名")
report.add_argument("sender", help="送信者名")
report.add_argument("-o", "--output", default=None, help="保存先ファイルパス")
args = parser.parse_args()
if args.command == "gen":
from script01_code_generator import generate_skeleton
spec = Path(args.spec).read_text(encoding="utf-8")
generate_skeleton(spec, output_file=args.output)
elif args.command == "test":
from script02_pytest_generator import generate_pytest
source = Path(args.source).read_text(encoding="utf-8")
out = args.output or f"test_{Path(args.source).name}"
generate_pytest(source, output_file=out)
elif args.command == "readme":
from script03_readme_generator import generate_readme
generate_readme(args.name, args.description, args.dir)
elif args.command == "debug":
from script04_debug_assistant import analyze_error
tb = Path(args.traceback).read_text(encoding="utf-8")
src = Path(args.source).read_text(encoding="utf-8") if args.source else ""
print(analyze_error(tb, source_code=src))
elif args.command == "report":
from script05_report_email_generator import generate_report_email
logs = [
line.strip()
for line in Path(args.logs).read_text(encoding="utf-8").splitlines()
if line.strip()
]
print(generate_report_email(
work_logs=logs,
recipient_name=args.recipient,
project_name=args.project,
sender_name=args.sender,
output_file=args.output,
))
if __name__ == "__main__":
main()
使い方はこんな感じです:
# テストコードを生成
python run_dev_tools.py test load_and_clean_csv.py -o test_load_and_clean_csv.py
# README を生成
python run_dev_tools.py readme "my-project" "OpenAI APIを使った効率化ツール集" -d .
# デバッグ支援レポートを生成
python run_dev_tools.py debug error.txt -s load_and_clean_csv.py
# 作業ログから報告メールを生成
python run_dev_tools.py report work_log.txt "鈴木様" "在庫管理システム" "山田 太郎" -o report_email_draft.txt
プロンプト設計3原則の実践まとめ
5本のスクリプトを通じて、冒頭で紹介した3原則がどう活きているか振り返ってみましょう。
| 原則 | スクリプトでの実装箇所 | 効果 |
|---|---|---|
| ① 役割を明示 | 各スクリプトの SYSTEM_PROMPT 冒頭 |
回答のトーン・深度が安定する |
| ② 出力フォーマット固定 | 「コードブロックのみ出力」「マークダウン構造で返す」指示 | extract_code_block() でのパースが安定する |
| ③ 制約を箇条書きで渡す | 各 SYSTEM_PROMPT の要件リスト |
条件の取りこぼしが減る |
この3原則は、今後自分でプロンプトを設計するときの基準にもなります。どのスクリプトを改造するときも、まずこの3点を確認する習慣をつけると、出力品質が安定します。
どのLLMツールを選ぶべきか?
本記事ではOpenAI APIを使って実装しましたが、「そもそもどのツール・モデルを選ぶべきか」という比較や選定の考え方については、別記事で詳しく解説しています。
👉 フリーランスエンジニアが今すぐ使うべきAIツール10選!作業効率を劇的に上げる活用法
本記事のスクリプトは、call_llm() 内のAPI呼び出し部分(クライアント初期化・systemプロンプトの渡し方・レスポンス取得)を書き換えれば、AnthropicのClaude APIなど他のLLMにも対応できます。呼び出し箇所を call_llm() に集約してあるため、修正はこの関数内だけで済む設計です。
まとめ:作ったスクリプト5本の一覧
| # | スクリプト名 | 何を自動化するか | temperature |
|---|---|---|---|
| ① | script01_code_generator.py |
日本語仕様→スケルトンコード生成 | 0.2 |
| ② | script02_pytest_generator.py |
実装コード→pytestテスト自動生成 | 0.2 |
| ③ | script03_readme_generator.py |
リポジトリ構造→README.md生成 | 0.3 |
| ④ | script04_debug_assistant.py |
トレースバック→デバッグ支援レポート | 0.1 |
| ⑤ | script05_report_email_generator.py |
作業ログ→報告メールドラフト生成 | 0.4 |
各スクリプトは独立して使えますが、①→②の流れ(仕様→実装→テスト)や、④→⑤の流れ(デバッグ完了→報告)のように組み合わせると、ひとつの作業サイクルがスムーズに回ります。
まずは llm_helper.py を作って、使いやすそうなスクリプトから1本試してみてください。自分のプロジェクトのコードを渡して動かすと、「こういう使い方ができるのか」というアイデアが次々と浮かんできますよ 🎉
こちらも読まれています
📚 関連商品・おすすめ書籍
※本記事にはアフィリエイトリンクが含まれます。





