AIコーディング 2026.07.14
メタプロンプティング実装ガイド|LLMの出力を自動改善する3つの手法【Python・LangChain 2026年版】
メタプロンプティングとは
LLM自身にプロンプトを評価・改善させる手法です。人間が試行錯誤してプロンプトを修正する代わりに、「プロンプト改善専用のLLM」を用意し、自動的に最適なプロンプトを生成します。
通常のプロンプト設計(手作業):
人間 → プロンプト作成 → LLM実行 → 結果確認 → 手動修正 → 繰り返し
メタプロンプティング(自動化):
ユーザー → 初期プロンプト → 評価LLM → 改善プロンプト → 本体LLM → 出力
環境セットアップ
# 2026年版の正しいパッケージ名でインストール
pip install langchain langchain-anthropic langchain-openai anthropic openai
パターン1: プロンプト評価→改善案生成
# meta_prompt_basic.py
# Claude Haikuで評価し、Claude Sonnetで本処理(コスト最適化)
import anthropic
import os
haiku = anthropic.Anthropic() # 評価用(安い)
sonnet = anthropic.Anthropic() # 本処理用
def evaluate_prompt(prompt: str, task_description: str) -> str:
"""Claude HaikuでプロンプトのKPIを評価する"""
response = haiku.messages.create(
model="claude-haiku-4-5-20251001", # 入力$0.80/1M(評価用)
max_tokens=512,
messages=[{"role": "user", "content": f"""
以下のプロンプトを評価して改善案を出してください。
タスク: {task_description}
プロンプト: {prompt}
問題点と改善後のプロンプトをJSON形式で出力:
{{"issues": ["問題1", "問題2"], "improved_prompt": "改善後のプロンプト"}}
"""}]
)
return response.content[0].text
def run_with_improved_prompt(improved_prompt: str, user_input: str) -> str:
"""Claude Sonnetで改善済みプロンプトを実行する"""
response = sonnet.messages.create(
model="claude-sonnet-4-5", # 入力$3/1M(本処理)
max_tokens=1024,
system=improved_prompt,
messages=[{"role": "user", "content": user_input}]
)
return response.content[0].text
# 使用例
import json
original_prompt = "ユーザーの質問に答えてください"
task = "カスタマーサポートチャットボット"
evaluation = evaluate_prompt(original_prompt, task)
data = json.loads(evaluation)
print(f"問題点: {data['issues']}")
print(f"改善後: {data['improved_prompt']}")
answer = run_with_improved_prompt(data['improved_prompt'], "返品の方法を教えてください")
print(f"\n回答: {answer}")
パターン2: LangChainでのメタプロンプトチェーン
# meta_prompt_chain.py
# LangChainで評価→改善→実行のパイプラインを構築
from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
# モデルの役割分担でコストを最適化
evaluator_llm = ChatAnthropic(model="claude-haiku-4-5-20251001") # 評価(安い)
executor_llm = ChatAnthropic(model="claude-sonnet-4-5") # 実行(高品質)
# 1. 評価チェーン
evaluate_prompt = ChatPromptTemplate.from_template("""
以下のプロンプトを分析し、より良い版を生成してください。
元のプロンプト: {original_prompt}
タスク: {task}
改善されたプロンプト(プロンプト本文のみ出力):
""")
evaluate_chain = evaluate_prompt | evaluator_llm | StrOutputParser()
# 2. 実行チェーン
execute_prompt = ChatPromptTemplate.from_messages([
("system", "{improved_prompt}"),
("human", "{user_input}")
])
execute_chain = execute_prompt | executor_llm | StrOutputParser()
def meta_prompt_pipeline(task: str, original_prompt: str, user_input: str) -> dict:
"""評価→改善→実行のパイプラインを実行する"""
improved = evaluate_chain.invoke({
"original_prompt": original_prompt,
"task": task
})
result = execute_chain.invoke({
"improved_prompt": improved,
"user_input": user_input
})
return {
"original": original_prompt,
"improved": improved,
"output": result
}
result = meta_prompt_pipeline(
task="コードレビューアシスタント",
original_prompt="コードを見てください",
user_input="def add(a, b): return a + b"
)
print(f"改善前: {result['original']}")
print(f"改善後: {result['improved'][:200]}")
print(f"出力: {result['output'][:300]}")
パターン3: エラー自動修正ループ
# auto_fix_loop.py
# LLMのエラー出力を検出して自動修正する
import anthropic
import json
client = anthropic.Anthropic()
def ask_structured(prompt: str, schema_hint: str) -> dict | None:
"""JSON出力を求め、失敗したら自動修正する"""
max_retries = 3
for attempt in range(max_retries):
response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=512,
messages=[{"role": "user", "content": f"""
{prompt}
必ず以下のJSON形式で出力してください:
{schema_hint}
"""}]
)
text = response.content[0].text
try:
# JSONとしてパース
return json.loads(text)
except json.JSONDecodeError as e:
if attempt == max_retries - 1:
return None
# 修正プロンプトを自動生成(メタプロンプト)
fix_response = client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=512,
messages=[{"role": "user", "content": f"""
以下の出力をJSON形式に修正してください。
エラー: {e}
元の出力: {text}
修正済みJSON(コードブロックなし):
"""}]
)
text = fix_response.content[0].text
try:
return json.loads(text)
except:
continue
# 使用例
result = ask_structured(
prompt="Pythonの人気ライブラリをトップ3教えてください",
schema_hint='{"libraries": [{"name": "ライブラリ名", "use_case": "用途"}]}'
)
if result:
for lib in result["libraries"]:
print(f"- {lib['name']}: {lib['use_case']}")
コスト比較:モデル選択の影響
# cost_comparison.py
MODELS = {
"claude-haiku-4-5-20251001": (0.80, 4.00, "評価・修正用(最安)"),
"claude-sonnet-4-5": (3.00, 15.00, "本処理用(高品質)"),
"claude-opus-5": (15.00, 75.00, "最高精度が必要な場合"),
}
def cycle_cost(eval_model: str, exec_model: str, cycles_per_day: int = 100) -> dict:
"""メタプロンプトサイクルの月間コストを計算する"""
# 評価サイクル(入力2000 + 出力500トークン)
ei, eo = MODELS[eval_model][:2]
eval_cost = (2000 * ei + 500 * eo) / 1_000_000
# 実行サイクル(入力3000 + 出力1000トークン)
xi, xo = MODELS[exec_model][:2]
exec_cost = (3000 * xi + 1000 * xo) / 1_000_000
daily = (eval_cost + exec_cost) * cycles_per_day
return {"daily_usd": round(daily, 3), "monthly_usd": round(daily * 30, 1)}
print("推奨: Haiku評価 + Sonnet実行:")
r = cycle_cost("claude-haiku-4-5-20251001", "claude-sonnet-4-5", 100)
print(f" 日${r['daily_usd']} / 月${r['monthly_usd']}")