mcpField
P
prompt-engineering-patterns

prompt-engineering-patterns

github.com/jsonlee12138エージェントワークフロー3354 回インストール32 週間前に更新
リポジトリ

prompt-engineering-patterns について

信頼性の高い構造化された LLM アプリケーションを開発する人向けに、プロンプトの設計と改善を支援するスキルです。少数例の選択、推論パターン、スキーマ準拠の出力、再利用可能なテンプレート、テスト、最適化を扱います。

主な機能

  1. 01少数例の選択
  2. 02思考連鎖と自己検証
  3. 03Pydantic による構造化出力
  4. 04プロンプトの反復改善と A/B テスト
  5. 05変数付きの再利用可能なテンプレート
  6. 06システムプロンプトの設計

活用シーン

  1. 01本番 LLM アプリ向けのプロンプト作成
  2. 02スキーマ検証済み JSON 出力の生成
  3. 03一貫しない応答の原因調査
  4. 04再利用可能な複数ターン用テンプレートの作成

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jsonlee12138/agent-team --skill prompt-engineering-patterns

インストール後、Claude Code で/prompt-engineering-patternsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

assets/
few-shot-examples.json
prompt-template-library.md
references/
chain-of-thought.md
few-shot-learning.md
prompt-optimization.md
prompt-templates.md
system-prompts.md
scripts/
optimize-prompt.py

詳細

プロンプトエンジニアリングのパターン

高度なプロンプトエンジニアリング技法を習得し、LLM の性能、信頼性、制御性を最大限に高めます。

このスキルを使用する場面

  • 本番環境の LLM アプリケーション向けに複雑なプロンプトを設計する
  • プロンプトの性能と一貫性を最適化する
  • 構造化された推論パターン(思考の連鎖、思考の木)を実装する
  • 動的な例の選択機能を備えた少数例学習システムを構築する
  • 変数の補間に対応した再利用可能なプロンプトテンプレートを作成する
  • 一貫性のない出力を生成するプロンプトをデバッグして改良する
  • 特化型 AI アシスタント向けのシステムプロンプトを実装する
  • 信頼性の高い解析を実現するために構造化出力(JSON モード)を使用する

主な機能

1. 少数例学習
  • 例の選択戦略(意味的類似性、多様性サンプリング)
  • コンテキストウィンドウの制約を考慮した例の数の調整
  • 入出力ペアを使った効果的なデモンストレーションの構築
  • ナレッジベースからの動的な例の取得
  • 戦略的な例の選択によるエッジケースへの対応
2. 思考の連鎖プロンプティング
  • 段階的な推論の促進
  • 「Let's think step by step」を用いたゼロショット CoT
  • 推論過程を示す少数例を用いた CoT
  • 自己一貫性の手法(複数の推論経路をサンプリング)
  • 検証と妥当性確認の手順
3. 構造化出力
  • 信頼性の高い解析のための JSON モード
  • Pydantic によるスキーマの適用
  • 型安全な応答処理
  • 不正な形式の出力に対するエラー処理
4. プロンプトの最適化
  • 反復的な改良ワークフロー
  • プロンプトのバリエーションの A/B テスト
  • プロンプト性能指標(精度、一貫性、レイテンシ)の測定
  • 品質を維持しながらトークン使用量を削減
  • エッジケースと障害モードへの対応
5. テンプレートシステム
  • 変数の補間と書式設定
  • 条件付きのプロンプトセクション
  • 複数ターンの会話テンプレート
  • ロールベースのプロンプト構成
  • モジュール式のプロンプトコンポーネント
6. システムプロンプトの設計
  • モデルの振る舞いと制約の設定
  • 出力形式と構造の定義
  • 役割と専門性の設定
  • 安全性に関するガイドラインとコンテンツポリシー
  • コンテキストの設定と背景情報

クイックスタート

from langchain_anthropic import ChatAnthropic
from langchain_core.prompts import ChatPromptTemplate
from pydantic import BaseModel, Field

# Define structured output schema
class SQLQuery(BaseModel):
    query: str = Field(description="The SQL query")
    explanation: str = Field(description="Brief explanation of what the query does")
    tables_used: list[str] = Field(description="List of tables referenced")

# Initialize model with structured output
llm = ChatAnthropic(model="claude-sonnet-4-6")
structured_llm = llm.with_structured_output(SQLQuery)

# Create prompt template
prompt = ChatPromptTemplate.from_messages([
    ("system", """You are an expert SQL developer. Generate efficient, secure SQL queries.
    Always use parameterized queries to prevent SQL injection.
    Explain your reasoning briefly."""),
    ("user", "Convert this to SQL: {query}")
])

# Create chain
chain = prompt | structured_llm

# Use
result = await chain.ainvoke({
    "query": "Find all users who registered in the last 30 days"
})
print(result.query)
print(result.explanation)

主なパターン

パターン 1:Pydantic による構造化出力
from anthropic import Anthropic
from pydantic import BaseModel, Field
from typing import Literal
import json

class SentimentAnalysis(BaseModel):
    sentiment: Literal["positive", "negative", "neutral"]
    confidence: float = Field(ge=0, le=1)
    key_phrases: list[str]
    reasoning: str

async def analyze_sentiment(text: str) -> SentimentAnalysis:
    """Analyze sentiment with structured output."""
    client = Anthropic()

    message = client.messages.create(
        model="claude-sonnet-4-6",
        max_tokens=500,
        messages=[{
            "role": "user",
            "content": f"""Analyze the sentiment of this text.

Text: {text}

Respond with JSON matching this schema:
{{
    "sentiment": "positive" | "negative" | "neutral",
    "confidence": 0.0-1.0,
    "key_phrases": ["phrase1", "phrase2"],
    "reasoning": "brief explanation"
}}"""
        }]
    )

    return SentimentAnalysis(**json.loads(message.content[0].text))
パターン 2:自己検証を伴う思考の連鎖
from langchain_core.prompts import ChatPromptTemplate

cot_prompt = ChatPromptTemplate.from_template("""
Solve this problem step by step.

Problem: {problem}

Instructions:
1. Break down the problem into clear steps
2. Work through each step showing your reasoning
3. State your final answer
4. Verify your answer by checking it against the original problem

Format your response as:
## Steps
[Your step-by-step reasoning]

## Answer
[Your final answer]

## Verification
[Check that your answer is correct]
""")
パターン 3:動的な例の選択を伴う少数例学習
from langchain_voyageai import VoyageAIEmbeddings
from langchain_core.example_selectors import SemanticSimilarityExampleSelector
from langchain_chroma import Chroma

# Create example selector with semantic similarity
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples=[
        {"input": "How do I reset my password?", "output": "Go to Settings > Security > Reset Password"},
        {"input": "Where can I see my order history?", "output": "Navigate to Account > Orders"},
        {"input": "How do I contact support?", "output": "Click Help > Contact Us or email [email protected]"},
    ],
    embeddings=VoyageAIEmbeddings(model="voyage-3-large"),
    vectorstore_cls=Chroma,
    k=2  # Select 2 most similar examples
)

async def get_few_shot_prompt(query: str) -> str:
    """Build prompt with dynamically selected examples."""
    examples = await example_selector.aselect_examples({"input": query})

    examples_text = "\n".join(
        f"User: {ex['input']}\nAssistant: {ex['output']}"
        for ex in examples
    )

    return f"""You are a helpful customer support assistant.

Here are some example interactions:
{examples_text}

Now respond to this query:
User: {query}
Assistant:"""
パターン 4:段階的な情報開示

簡単なプロンプトから始め、必要な場合にのみ複雑さを加えます。

PROMPT_LEVELS = {
    # Level 1: Direct instruction
    "simple": "Summarize this article: {text}",

    # Level 2: Add constraints
    "constrained": """Summarize this article in 3 bullet points, focusing on:
- Key findings
- Main conclusions
- Practical implications

Article: {text}""",

    # Level 3: Add reasoning
    "reasoning": """Read this article carefully.
1. First, identify the main topic and thesis
2. Then, extract the key supporting points
3. Finally, summarize in 3 bullet points

Article: {text}

Summary:""",

    # Level 4: Add examples
    "few_shot": """Read articles and provide concise summaries.

Example:
Article: "New research shows that regular exercise can reduce anxiety by up to 40%..."
Summary:
• Regular exercise reduces anxiety by up to 40%
• 30 minutes of moderate activity 3x/week is sufficient
• Benefits appear within 2 weeks of starting

Now summarize this article:
Article: {text}

Summary:"""
}
パターン 5:エラー復旧とフォールバック
from pydantic import BaseModel, ValidationError
import json

class ResponseWithConfidence(BaseModel):
    answer: str
    confidence: float
    sources: list[str]
    alternative_interpretations: list[str] = []

ERROR_RECOVERY_PROMPT = """
Answer the question based on the context provided.

Context: {context}
Question: {question}

Instructions:
1. If you can answer confidently (>0.8), provide a direct answer
2. If you're somewhat confident (0.5-0.8), provide your best answer with caveats
3. If you're uncertain (<0.5), explain what information is missing
4. Always provide alternative interpretations if the question is ambiguous

Respond in JSON:
{{
    "answer": "your answer or 'I cannot determine this from the context'",
    "confidence": 0.0-1.0,
    "sources": ["relevant context excerpts"],
    "alternative_interpretations": ["if question is ambiguous"]
}}
"""

async def answer_with_fallback(
    context: str,
    question: str,
    llm
) -> ResponseWithConfidence:
    """Answer with error recovery and fallback."""
    prompt = ERROR_RECOVERY_PROMPT.format(context=context, question=question)

    try:
        response = await llm.ainvoke(prompt)
        return ResponseWithConfidence(**json.loads(response.content))
    except (json.JSONDecodeError, ValidationError) as e:
        # Fallback: try to extract answer without structure
        simple_prompt = f"Based on: {context}\n\nAnswer: {question}"
        simple_response = await llm.ainvoke(simple_prompt)
        return ResponseWithConfidence(
            answer=simple_response.content,
            confidence=0.5,
            sources=["fallback extraction"],
            alternative_interpretations=[]
        )
パターン 6:ロールベースのシステムプロンプト
SYSTEM_PROMPTS = {
    "analyst": """You are a senior data analyst with expertise in SQL, Python, and business intelligence.

Your responsibilities:
- Write efficient, well-documented queries
- Explain your analysis methodology
- Highlight key insights and recommendations
- Flag any data quality concerns

Communication style:
- Be precise and technical when discussing methodology
- Translate technical findings into business impact
- Use clear visualizations when helpful""",

    "assistant": """You are a helpful AI assistant focused on accuracy and clarity.

Core principles:
- Always cite sources when making factual claims
- Acknowledge uncertainty rather than guessing
- Ask clarifying questions when the request is ambiguous
- Provide step-by-step explanations for complex topics

Constraints:
- Do not provide medical, legal, or financial advice
- Redirect harmful requests appropriately
- Protect user privacy""",

    "code_reviewer": """You are a senior software engineer conducting code reviews.

Review criteria:
- Correctness: Does the code work as intended?
- Security: Are there any vulnerabilities?
- Performance: Are there efficiency concerns?
- Maintainability: Is the code readable and well-structured?
- Best practices: Does it follow language idioms?

Output format:
1. Summary assessment (approve/request changes)
2. Critical issues (must fix)
3. Suggestions (nice to have)
4. Positive feedback (what's done well)"""
}

統合パターン

RAG システムとの連携
RAG_PROMPT = """You are a knowledgeable assistant that answers questions based on provided context.

Context (retrieved from knowledge base):
{context}

Instructions:
1. Answer ONLY based on the provided context
2. If the context doesn't contain the answer, say "I don't have information about that in my knowledge base"
3. Cite specific passages using [1], [2] notation
4. If the question is ambiguous, ask for clarification

Question: {question}

Answer:"""
検証と妥当性確認との連携
VALIDATED_PROMPT = """Complete the following task:

Task: {task}

After generating your response, verify it meets ALL these criteria:
✓ Directly addresses the original request
✓ Contains no factual errors
✓ Is appropriately detailed (not too brief, not too verbose)
✓ Uses proper formatting
✓ Is safe and appropriate

If verification fails on any criterion, revise before responding.

Response:"""

パフォーマンスの最適化

トークン効率
# Before: Verbose prompt (150+ tokens)
verbose_prompt = """
I would like you to please take the following text and provide me with a comprehensive
summary of the main points. The summary should capture the key ideas and important details
while being concise and easy to understand.
"""

# After: Concise prompt (30 tokens)
concise_prompt = """Summarize the key points concisely:

{text}

Summary:"""
共通プレフィックスのキャッシュ
from anthropic import Anthropic

client = Anthropic()

# Use prompt caching for repeated system prompts
response = client.messages.create(
    model="claude-sonnet-4-6",
    max_tokens=1000,
    system=[
        {
            "type": "text",
            "text": LONG_SYSTEM_PROMPT,
            "cache_control": {"type": "ephemeral"}
        }
    ],
    messages=[{"role": "user", "content": user_query}]
)

ベストプラクティス

  1. 具体的にする:曖昧なプロンプトは一貫性のない結果を生みます
  2. 説明より実例を示す:例は説明よりも効果的です
  3. 構造化出力を使用する:信頼性を高めるため、Pydantic でスキーマを適用します
  4. 徹底的にテストする:多様で代表的な入力を使って評価します
  5. 素早く反復する:小さな変更が大きな影響をもたらすことがあります
  6. 性能を監視する:本番環境で指標を追跡します
  7. バージョン管理する:適切なバージョン管理を行い、プロンプトをコードとして扱います
  8. 意図を文書化する:プロンプトがそのように構成されている理由を説明します

よくある落とし穴

  • 過剰な設計:簡単な方法を試す前に複雑なプロンプトから始める
  • 例の汚染:対象タスクに合わない例を使用する
  • コンテキストの超過:例を多用してトークン上限を超える
  • 曖昧な指示:複数の解釈の余地を残す
  • エッジケースの無視:通常とは異なる入力や境界値の入力でテストしない
  • エラー処理の欠如:出力が常に適切な形式であると想定する
  • 値のハードコード:再利用できるようにプロンプトをパラメーター化しない

成功指標

プロンプトの以下の KPI を追跡します。

  • 正確性:出力の正しさ
  • 一貫性:類似した入力に対する再現性
  • レイテンシ:応答時間(P50、P95、P99)
  • トークン使用量:リクエストあたりの平均トークン数
  • 成功率:有効で解析可能な出力の割合
  • ユーザー満足度:評価とフィードバック

コメント