# Gemini APIを活用したプロンプトジェネレーターの開発記録 > 2025年12月3日 ## はじめに 本記事では、Google AI Studio(Gemini)APIを活用して、ユーザーの簡単な入力から高品質なプロンプトを自動生成するツールを開発した過程を紹介します。プロジェクトの構想から完成まで、段階的に機能を追加・改善していった開発プロセスを詳しく解説します。 ### なぜプロンプトジェネレーターが必要なのか? 複雑なアプリケーションを開発する際、AIにコンテキストを正確に伝えるためのプロンプトを作成することは、思った以上に難しい作業です。すべての要素を一度に網羅し、洞察力を持って完璧なプロンプトを書くことは、経験豊富な開発者でも容易ではありません。 **プロンプトジェネレーターを活用することで、以下のメリットが得られます:** - **必要な情報の可視化:** 具体的なコンテキストを伝えるために何が必要なのかを明確に把握できる - **不足している要素の発見:** プロンプトのどの部分が欠けているのかを簡単に特定できる - **一貫性のある品質:** 毎回高品質なプロンプトを安定して生成できる このように、プロンプトジェネレーターを通じた開発は、**時間とリソースの大幅な節約**につながります。試行錯誤の回数を減らし、より効率的にAIとのコミュニケーションを実現できるのです。 --- ## 第1章:プロジェクト目標設定と環境準備 ### プロジェクトの開始 このプロジェクトの目標は、特定の入力に基づいて高品質なプロンプトを自動生成するツールを作成することです。開発記録と関連ファイルを管理するため、`20251203-prompt-generator`ディレクトリを作成しました。 ### 核心目標の定義 プロジェクトの方向性を明確にするため、以下の質問に対する回答を検討しました: 1. **どのような種類のプロンプト**を生成するか?(例:画像生成、テキスト要約、コード生成など) 2. ユーザーは**どのような情報(入力)**を提供するか?(例:簡単なキーワード、トピック、文章など) 3. ジェネレーターが作成する**出力の形式**はどうあるべきか?(例:完成された1つのプロンプト文、複数のプロンプトオプションなど) 4. このジェネレーターは**どのような形式のアプリケーション**になるか?(例:Pythonスクリプト、簡単なWeb UIなど) --- ## 第2章:ユーザー入力に基づく意図推論機能の設計 ### 要件の具体化 ユーザーからのフィードバックを受け、要件を以下のように具体化しました: - **入力:** 簡単な文章(例:「星が輝く夜に宇宙を旅する猫」、「与えられたテキストを3文で要約して」) - **核心機能:** 入力文章の**意図(Intent)**をシステムが推論(画像生成、テキスト要約など) - **出力:** 推論された意図に最適化された最終プロンプト ### 2段階プロンプト処理アーキテクチャ この要件を満たすため、Gemini APIを2回呼び出す2段階構造を設計しました: **1段階目:意図推論(Meta-Prompt)** - ユーザーの元の入力をGemini APIに渡し、そのリクエストがどの種類の作業(画像生成、テキスト要約、コード作成など)に該当するかを分類するよう要求します。 **2段階目:プロンプト生成** - 1段階目で推論された意図に基づき、その作業に特化したプロンプトを使用して最終結果物を生成します。 --- ## 第3章:意図推論のためのMeta-Prompt設計とPython環境準備 ### 意図推論のためのメタプロンプト(初稿) ユーザーの入力文から意図を正確に把握することがこのプロジェクトの核心です。以下は、Gemini APIに渡してユーザーの意図を分類するよう要求するプロンプトの初稿です: ```text You are an expert at understanding user intent. Analyze the following user request and classify it into one of these categories: [Image Generation], [Text Summarization], [Code Generation], [General Question]. Respond with only the category name in brackets. User Request: "{{user_input}}" ``` このプロンプトは、APIが余計な文言なしに分類結果(例:`[Image Generation]`)のみを返すよう誘導します。 ### Python開発環境設定 - **言語:** Python - **核心ライブラリ:** `google-generativeai` - **APIキー管理:** APIキーはセキュリティのため**環境変数**(`GOOGLE_API_KEY`)を通じて読み込みます。コードに直接キーを記述することは非常に危険なため、絶対にそうしません。 --- ## 第4章:Pythonで意図推論API連携を実装 ### 事前準備 コードを実行する前に、`requirements.txt`に記載されたライブラリをインストールする必要があります: ```bash pip install -r requirements.txt ``` また、プロジェクトルート(`20251203-prompt-generator`)に`.env.example`ファイルを`.env`ファイルとしてコピーし、ファイル内に`GOOGLE_API_KEY='YOUR_API_KEY'`形式で自分のGoogle AI Studio APIキーを追加する必要があります。 ### 基本的な`main.py`コード ```python import os import sys import google.generativeai as genai from dotenv import load_dotenv def main(): """ Main function to run the intent inference. """ # Load environment variables from .env file load_dotenv() # Get API key from environment api_key = os.getenv("GOOGLE_API_KEY") if not api_key: print("Error: GOOGLE_API_KEY not found in .env file.") sys.exit(1) # Configure the generative AI client genai.configure(api_key=api_key) model = genai.GenerativeModel('gemini-1.5-pro') # Meta-prompt for intent classification meta_prompt = """You are an expert at understanding user intent. Analyze the following user request and classify it into one of these categories: [Image Generation], [Text Summarization], [Code Generation], [General Question]. Respond with only the category name in brackets. User Request: "{{user_input}}" """ # --- Test with a sample user input --- user_input = "A cat traveling in space on a starry night, painted by Van Gogh" # Combine meta-prompt with user input prompt_for_api = meta_prompt.replace("{{user_input}}", user_input) print(f"Sending request to API with input: '{user_input}'") # Call the API try: response = model.generate_content(prompt_for_api) print(f"API Response (Intent): {response.text.strip()}") except Exception as e: print(f"An error occurred: {e}") if __name__ == "__main__": main() ``` ### 実行方法と予想結果 ```bash python main.py ``` 予想される出力: ``` Sending request to API with input: 'A cat traveling in space on a starry night, painted by Van Gogh' API Response (Intent): [Image Generation] ``` --- ## 第5章:ユーザー入力処理と2段階プロンプト生成の実装 ### 2段階目の詳細プロンプト生成設計 1段階目で「画像生成」意図が把握された場合に使用する2段階目のプロンプトを設計しました: **特化プロンプト(画像生成用):** ```text You are a creative expert at writing prompts for AI image generators. Based on the user's simple description, create a single, detailed, rich paragraph for a prompt. This paragraph should include several descriptive sentences covering the subject, setting, lighting, mood, and artistic style. Do not just list keywords; weave them into a coherent paragraph. User's simple description: "{{user_input}}" ``` ### 更新された`main.py` ```python import os import sys import google.generativeai as genai from dotenv import load_dotenv def get_intent(model, user_input): """Calls the API to infer the user's intent.""" meta_prompt = """You are an expert at understanding user intent. Analyze the following user request and classify it into one of these categories: [Image Generation], [Text Summarization], [Code Generation], [General Question]. Respond with only the category name in brackets. User Request: "{{user_input}}" """ prompt_for_api = meta_prompt.replace("{{user_input}}", user_input) response = model.generate_content(prompt_for_api) return response.text.strip() def generate_detailed_prompt(model, user_input, intent): """Generates the final detailed prompt based on the intent.""" specialized_prompts = { "[Image Generation]": """You are a creative expert at writing prompts for AI image generators. Based on the user's simple description, create a single, detailed, rich paragraph for a prompt. This paragraph should include several descriptive sentences covering the subject, setting, lighting, mood, and artistic style. Do not just list keywords; weave them into a coherent paragraph. User's simple description: "{{user_input}}" """ } prompt_template = specialized_prompts.get(intent) if not prompt_template: return f"I can't generate a detailed prompt for the intent '{intent}' yet." prompt_for_api = prompt_template.replace("{{user_input}}", user_input) response = model.generate_content(prompt_for_api) return response.text.strip() def main(): """Main function to run the prompt generator.""" load_dotenv() api_key = os.getenv("GOOGLE_API_KEY") if not api_key: print("Error: GOOGLE_API_KEY not found in .env file.") sys.exit(1) genai.configure(api_key=api_key) model = genai.GenerativeModel('gemini-1.5-pro') # 1. Get user input from the terminal user_input = input("Enter your simple prompt idea: ") try: # 2. Step 1: Infer Intent print("\nStep 1: Inferring intent...") intent = get_intent(model, user_input) print(f"Intent detected: {intent}") # 3. Step 2: Generate Detailed Prompt print("\nStep 2: Generating detailed prompt...") detailed_prompt = generate_detailed_prompt(model, user_input, intent) print("\n--- Your Detailed Prompt Paragraph ---") print(detailed_prompt) print("------------------------------------") except Exception as e: print(f"\nAn error occurred: {e}") if __name__ == "__main__": main() ``` --- ## 第6章:Unicodeエラー解決とコードリファクタリング ### 問題発生と原因分析 テスト中、ターミナルに日本語などの非ASCII文字を入力した際に`UnicodeDecodeError`が発生する問題を発見しました。 - **エラー:** `UnicodeDecodeError: 'utf-8' codec can't decode bytes...` - **原因:** スクリプトを実行するシェル(ターミナル)環境のデフォルトエンコーディング設定がUTF-8でない場合、`input()`関数がシステムデフォルトエンコーディングで文字を読み込もうとしてマルチバイト文字を解釈できないために発生する環境問題です。 ### 解決策 最も確実で簡単な解決策は、スクリプト実行時に`PYTHONIOENCODING`環境変数を`UTF-8`に明示的に設定することです: ```bash PYTHONIOENCODING=UTF-8 python main.py ``` ### コードリファクタリング コードの可読性と保守性を向上させるため、簡単なリファクタリングを実施しました: - `setup_generative_ai`: APIクライアントを設定してモデルオブジェクトを返す関数を分離 - `main`: 全体的なフローを調整する役割により集中するようコードを整理 --- ## 第7章:モデル名エラー修正と「コード生成」2段階プロンプト実装 ### モデル名エラー修正 テスト中に`404 models/gemini-1.5-pro-latest is not found`エラーが発生しました。 - **原因:** `genai.GenerativeModel()`に渡されたモデル名が有効でないか、現在APIを通じてアクセス可能なモデルリストにないためです。特に`-latest`接尾辞が問題だった可能性が高いです。 - **解決:** 現在安定して使用可能な高性能モデルである`gemini-1.5-pro`(接尾辞なし)にモデル名を修正しました。 ### 「コード生成」2段階プロンプト実装 **特化プロンプト(コード生成用):** ```text You are an expert Python developer assistant. Based on the user's high-level request, generate a detailed prompt for a large language model (LLM) to create a Python script. The prompt should be comprehensive, including requirements for Google Sheets API, Gemini API, .env for API keys and email, and specifying the dashboard output to be in Japanese. User's request: "{{user_input}}" Return the detailed prompt as a paragraph ready for an LLM. ``` --- ## 第8章:「テキスト要約」と「一般質問」2段階プロンプト追加 ### 新しい2段階プロンプト設計 #### 1. `[Text Summarization]`意図用特化プロンプト ```text You are an expert summarizer. The user wants a summary of the following text. Create a concise, easy-to-read paragraph that captures the main points of the text. Focus on key information and essential details, presenting them clearly and neutrally. User's text: "{{user_input}}" ``` #### 2. `[General Question]`意図用特化プロンプト ```text You are a helpful assistant. The user has a general question or request. Formulate a comprehensive and clear prompt for a large language model to answer this question or fulfill the request. The prompt should encourage the LLM to provide a detailed, well-structured, and informative response. User's request: "{{user_input}}" ``` ### 完全な`specialized_prompts`ディクショナリ ```python specialized_prompts = { "[Image Generation]": """You are a creative expert at writing prompts for AI image generators. Based on the user's simple description, create a single, detailed, rich paragraph for a prompt. This paragraph should include several descriptive sentences covering the subject, setting, lighting, mood, and artistic style. Do not just list keywords; weave them into a coherent paragraph. User's simple description: "{{user_input}}" """, "[Code Generation]": """You are an expert Python developer assistant. Based on the user's high-level request, generate a detailed prompt for a large language model (LLM) to create a Python script. The prompt should be comprehensive, including requirements for Google Sheets API, Gemini API, .env for API keys and email, and specifying the dashboard output to be in Japanese. User's request: "{{user_input}}" Return the detailed prompt as a paragraph ready for an LLM. """, "[Text Summarization]": """You are an expert summarizer. The user wants a summary of the following text. Create a concise, easy-to-read paragraph that captures the main points of the text. Focus on key information and essential details, presenting them clearly and neutrally. User's text: "{{user_input}}" """, "[General Question]": """You are a helpful assistant. The user has a general question or request. Formulate a comprehensive and clear prompt for a large language model to answer this question or fulfill the request. The prompt should encourage the LLM to provide a detailed, well-structured, and informative response. User's request: "{{user_input}}" """ } ``` --- ## 第9章:CLI使いやすさ向上とコードリファクタリング ### 主な改善点 #### 1. API呼び出しリトライ(Retry)ロジック実装 API呼び出しはネットワーク問題、一時的なサーバーエラー、またはレートリミット(Rate Limit)などの理由で失敗する可能性があります。このような状況に備え、一定回数まで自動的にリトライするロジックを追加しました。`tenacity`ライブラリを使用してこれを簡潔に実装しました。 ```python from tenacity import retry, stop_after_attempt, wait_fixed, retry_if_exception_type @retry(stop_after_attempt=3, wait_fixed=2, retry_if_exception_type=Exception) def get_intent(model, user_input): """Calls the API to infer the user's intent with retry logic.""" # ... 実装 ``` #### 2. 出力メッセージ改善 スクリプトの進行状況と最終結果物をユーザーにより明確に伝えるため、出力メッセージ形式を改善しました: - 進行段階(Step 1, Step 2)メッセージをより明確に - 最終プロンプト段落を強調する形式を追加 #### 3. エラー処理強化 API呼び出し失敗時にユーザーにより有用な情報を提供するよう、例外処理メッセージを具体化しました。 ### `requirements.txt`更新 ``` google-generativeai python-dotenv tenacity ``` --- ## 第10章:最終レビュー、モデル名設定分離とREADME作成 ### モデル名設定を`.env`ファイルに分離 ハードコードされたモデル名を`.env`ファイルの`GEMINI_MODEL`変数に分離しました。これにより、コード修正なしに設定ファイルのみでモデルを変更できるようになりました。 ```python def main(): """Main function to run the prompt generator.""" load_dotenv() api_key = os.getenv("GOOGLE_API_KEY") if not api_key: print("Error: GOOGLE_API_KEY not found in .env file.") sys.exit(1) # .envファイルからモデル名を読み込み、なければデフォルト値を使用 model_name = os.getenv("GEMINI_MODEL", "gemini-1.5-pro") print(f"Using Gemini model: {model_name}") model = setup_generative_ai(api_key, model_name) # ... ``` --- ## プロジェクト完了:開発プロセスのまとめ このプロジェクトを通じて、以下のプロセスを経ました: | ステップ | 内容 | |---------|------| | V1 | 目標設定と環境準備 - プロジェクトの方向性を定義 | | V2 | ユーザー入力基盤の意図推論機能設計 - 2段階アーキテクチャを設計 | | V3 | メタプロンプト設計とPython環境設定 - 核心となるプロンプトを設計 | | V4 | API連携と基本機能実装 - 意図推論の基本動作を確認 | | V5 | 2段階プロンプト生成とユーザー入力処理 - 完全な2段階処理を実装 | | V6 | Unicodeエラー解決とリファクタリング - 多言語対応を確保 | | V7 | モデル名エラー修正と「コード生成」意図実装 - 機能を拡張 | | V8 | 残りの全意図に対する2段階プロンプト実装 - すべての意図タイプをカバー | | V9 | CLI使いやすさ向上(リトライロジック、出力改善等) - 堅牢性を向上 | | V10 | 設定分離と最終ドキュメント化 - 保守性と拡張性を確保 | このプロセスを通じて、簡単なアイデアから始まり、複数の意図を推論してそれに合った詳細プロンプトを生成する、柔軟で安定したCLIツールを完成させました。 --- ## 使用方法 ### 1. 環境設定 ```bash # 仮想環境作成と有効化 python -m venv .venv source .venv/bin/activate # Linux/Mac # または .venv\Scripts\activate # Windows # ライブラリインストール pip install -r requirements.txt ``` ### 2. APIキー設定 `.env.example`を`.env`にコピーし、APIキーを設定: ``` GOOGLE_API_KEY='your-api-key-here' GEMINI_MODEL=gemini-1.5-pro # オプション ``` ### 3. 実行 ```bash PYTHONIOENCODING=UTF-8 python main.py ``` プロンプトが表示されたら、簡単なアイデアを入力すると、システムが意図を推論して詳細なプロンプトを生成します。 --- ## おわりに このプロジェクトでは、Gemini APIの強力な言語理解能力を活用して、ユーザーの曖昧な入力から意図を正確に推論し、その意図に最適化された詳細なプロンプトを生成するツールを開発しました。 2段階のAPI呼び出しアーキテクチャにより、まず意図を分類し、次にその意図に特化したプロンプトを生成するという流れで、より精度の高い結果を得ることができます。 このツールは、画像生成AI、コード生成、テキスト要約など、様々な用途のプロンプト作成を支援し、ユーザーの創造的な作業をサポートします。