プロンプトエンジニアリング
Claudeから良い出力を引き出すためのプロンプト設計パターンを学びます。
システムプロンプト
systemパラメータでClaudeの役割・制約・出力形式を定義する。messagesとは別枠で設定する。
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="あなたはシニアPythonエンジニアです。回答は以下のルールに従ってください:\n"
"- コード例は必ず含める\n"
"- 型ヒントを使う\n"
"- 説明は3文以内にする",
messages=[
{"role": "user", "content": "デコレータの作り方を教えて"}
]
)
効果的なシステムプロンプトの要素
- 役割の定義 — 「あなたは〇〇の専門家です」
- 制約条件 — やってはいけないこと、出力の制限
- 出力形式 — JSON、箇条書き、コードなど
ベストプラクティス
システムプロンプトは「何をしてほしいか」より「どう振る舞ってほしいか」を書く。 具体的なタスク指示はユーザーメッセージに入れる。
Few-shot(例示)
Claudeに期待する入出力パターンを示すことで、出力品質を向上させる。
messages = [
{"role": "user", "content": "商品レビュー: この靴は軽くて歩きやすい。デザインもいい。"},
{"role": "assistant", "content": '{"sentiment": "positive", "aspects": ["軽さ", "歩きやすさ", "デザイン"]}'},
{"role": "user", "content": "商品レビュー: サイズが合わなかった。返品した。"},
{"role": "assistant", "content": '{"sentiment": "negative", "aspects": ["サイズ"]}'},
{"role": "user", "content": "商品レビュー: 値段の割に品質がいい。ただし色が写真と違った。"},
]
Few-shotのコツ
- 2〜3例で十分なことが多い。多すぎるとトークン消費が増える
- エッジケースを含める(例: 曖昧なケース、例外パターン)
- 例示の形式を一貫させる
Chain-of-Thought(思考連鎖)
複雑な問題では、Claudeに段階的に考えさせると精度が上がる。
明示的に指示する方法
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=2048,
messages=[
{"role": "user", "content": (
"以下のコードにバグがあります。ステップバイステップで分析してください。\n\n"
"```python\n"
"def avg(nums):\n"
" return sum(nums) / len(nums)\n"
"```\n\n"
"まず考えうる入力パターンを列挙し、次に各パターンでの動作を確認し、"
"最後にバグと修正案を示してください。"
)}
]
)
extended thinking(拡張思考)
Claude 3.5 Sonnet以降で使える機能。Claudeが内部で長い思考プロセスを行ってから回答する。
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=8096,
temperature=1, # extended thinking使用時はtemperature=1が必須
thinking={
"type": "enabled",
"budget_tokens": 4096 # 思考に使えるトークン数の上限
},
messages=[
{"role": "user", "content": "この数学の証明を検証してください: ..."}
]
)
# レスポンスにthinkingブロックとtextブロックが含まれる
for block in message.content:
if block.type == "thinking":
print(f"思考過程: {block.thinking}")
elif block.type == "text":
print(f"回答: {block.text}")
構造化出力
JSON出力
message = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
system="必ず有効なJSONのみを出力してください。説明文は不要です。",
messages=[
{"role": "user", "content": (
"以下のテキストから情報を抽出してJSON形式で返してください。\n"
"スキーマ: {\"name\": string, \"age\": int, \"skills\": string[]}\n\n"
"テキスト: 田中太郎(32歳)はPythonとTypeScriptが得意なエンジニアです。"
)}
]
)
XML出力
XMLタグを使うと、Claudeが構造を正確に守りやすい。
messages = [
{"role": "user", "content": (
"以下の記事を分析してください。\n\n"
"<article>...</article>\n\n"
"回答は以下の形式で:\n"
"<analysis>\n"
" <summary>要約</summary>\n"
" <key_points>\n"
" <point>ポイント1</point>\n"
" </key_points>\n"
" <sentiment>positive/negative/neutral</sentiment>\n"
"</analysis>"
)}
]
JSONとXMLの使い分け
- JSON: プログラムで解析する場合。APIレスポンスとして使う場合
- XML: 複雑な入力の区切りに。Claudeは
<tag>をよく理解する
長文コンテキストの扱い方
Claudeは最大200Kトークンの入力に対応(モデルによる)。長い文書を扱うコツ:
ドキュメントの配置
messages = [
{"role": "user", "content": (
"以下のドキュメントを読んで質問に答えてください。\n\n"
"<document>\n"
f"{long_text}" # ← 長いテキストは先に配置
"\n</document>\n\n"
"質問: このドキュメントの主要な論点は何ですか?" # ← 質問は後
)}
]
複数ドキュメント
content = ""
for i, doc in enumerate(documents):
content += f"<document index=\"{i+1}\">\n{doc}\n</document>\n\n"
content += "上記のドキュメントを比較して、共通点と相違点をまとめてください。"
長文のベストプラクティス
- ドキュメントを先に、指示を後に配置する(Claudeは後の指示を重視する傾向)
- XMLタグで文書を明確に区切る
- 不要な部分は事前にトリミングしてトークンを節約
アンチパターン集
1. 曖昧な指示
2. 矛盾する指示
3. 過剰な制約
4. コンテキストなしの質問
参考リンク
- Prompt Engineering Guide — 公式プロンプトガイド
- Prompt Engineering Tutorial — 9章のインタラクティブ演習
- Anthropic Courses — プロンプト設計コース(2〜4章)
- Anthropic Cookbook — 実践レシピ集