Basic: "Write a blog post."

Advanced: Structure, context, format, reasoning chains, multi-step workflows.

System Prompts

System prompt is instructions before the user message.

system = """You're a customer support AI.
- Be polite and professional
- Reference policies only if relevant
- Solve issues immediately if possible
"""

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    system=system,
    messages=[
        {"role": "user", "content": "My order is broken"}
    ]
)

Defines:

  • Model personality
  • Constraints
  • Output format

Good system prompts are specific and compact (<300 tokens).

Few-Shot Learning

Give examples instead of rules:

Classify this review as positive/negative.

Example 1:
Review: "Product is fantastic!"
Classification: positive

Example 2:
Review: "Very disappointed with quality"
Classification: negative

New review: "It's OK but could be better"
Classification: ?

Few-shot often beats instructions. Model "learns from pattern."

Chain-of-Thought (CoT)

Let model show its thinking:

Problem: Train goes 60 km/h for 2 hours.
Car goes 80 km/h for 1.5 hours.
Which went farther?

Instead of just answering:
Think step-by-step:

1. Train distance = 60 × 2 = 120 km
2. Car distance = 80 × 1.5 = 120 km
3. They're equal

CoT improves:

  • Math problems
  • Logic puzzles
  • Complex analysis

Self-Consistency

Generate multiple CoT paths and vote:

responses = []
for i in range(5):
    response = client.messages.create(
        model="claude-3-sonnet-20240229",
        messages=[{"role": "user", "content": problem}]
    )
    responses.append(response)

from collections import Counter
answers = [r.content[0].text for r in responses]
best = Counter(answers).most_common(1)[0][0]

Improves accuracy, costs more (5x API calls).

Tool Use / Function Calling

Let model call functions:

tools = [
    {
        "name": "get_weather",
        "description": "Fetches current weather",
        "input_schema": {
            "type": "object",
            "properties": {
                "location": {"type": "string"},
                "unit": {"type": "string", "enum": ["C", "F"]}
            }
        }
    }
]

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    tools=tools,
    messages=[
        {"role": "user", "content": "What's the weather in Vienna?"}
    ]
)

if response.content[0].type == "tool_use":
    tool_name = response.content[0].name
    tool_input = response.content[0].input
    # Call get_weather("Vienna", "C")

Makes models agents—can call external functions.

Structured Output (JSON Mode)

Force structured output:

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    messages=[{
        "role": "user",
        "content": "Analyze: 'Good product but expensive'"
    }],
    system="""Always respond as JSON:
{
    "sentiment": "positive|negative|neutral",
    "points": ["array"],
    "confidence": 0.0-1.0
}"""
)

import json
data = json.loads(response.content[0].text)

Essential for APIs, databases, downstream processing.

Prompt Optimization: Save Tokens

500-token prompt costs more than 100-token.

Techniques:

  • Short system prompts
  • Avoid redundancy
  • Use shorthand
❌ Bad (many tokens):
"You're a support assistant. Your job is to answer questions.
Be friendly. Help the customer..."

✓ Good (few tokens):
"Support assistant. Helpful, friendly, efficient."

Evaluation Methods

How good is your prompt?

Method 1: Manual Review

  • Generate 10 samples
  • Review manually
  • Count good vs bad

Method 2: Metric-based

target = 42
response = model.generate(prompt)
answer = extract_number(response)
accuracy = 100 - abs(answer - target)

Method 3: LLM-as-Judge

judge = client.messages.create(
    model="claude-3-opus-20240229",
    messages=[{
        "role": "user",
        "content": f"Rate this answer 1-10: {output}"
    }]
)

Anti-Patterns

Too Complex

❌ "Analyze text, extract entities, classify sentiment,
   calculate length, summarize in EN and DE..."

✓ Split into multiple prompts

Vague Instructions

❌ "Write about AI"

✓ "Write 200-word blog post on RAG for beginners"

Unclear Format

❌ "Answer"

✓ "Answer as JSON: {\"name\": \"\", \"score\": 0}"

Advanced Techniques: Agents & Planning

Agentic Loops

Let models plan multi-step workflows:

import anthropic

client = anthropic.Anthropic()

# Define tools for agent
tools = [
    {
        "name": "search_web",
        "description": "Search the web for current information",
        "input_schema": {
            "type": "object",
            "properties": {"query": {"type": "string"}}
        }
    },
    {
        "name": "calculate",
        "description": "Perform calculation",
        "input_schema": {
            "type": "object",
            "properties": {"expression": {"type": "string"}}
        }
    }
]

messages = [{"role": "user", "content": "What's 15% of $2000 plus tax in Vienna?"}]

# Agentic loop
while True:
    response = client.messages.create(
        model="claude-3-sonnet-20240229",
        max_tokens=1024,
        tools=tools,
        messages=messages
    )

    if response.stop_reason == "tool_use":
        # Extract and execute tool call
        tool_use = next(b for b in response.content if b.type == "tool_use")
        tool_result = execute_tool(tool_use.name, tool_use.input)

        # Continue conversation
        messages.append({"role": "assistant", "content": response.content})
        messages.append({
            "role": "user",
            "content": f"Tool result: {tool_result}"
        })
    else:
        # Model finished - no more tool calls needed
        break

print(response.content[0].text)

This pattern lets models:

  • Plan multiple steps
  • Call external APIs
  • Gather data before responding

Tree-of-Thought (Superior to CoT)

Explore multiple reasoning paths:

Question: "Best investment: Real estate or stocks?"

CoT (Linear):
1. Research real estate
2. Research stocks
3. Compare
→ Single conclusion

Tree-of-Thought (Branching):
                  [Main decision]
                   /            \
            [Real Estate]      [Stocks]
            /    |    \        /   |   \
        [Risk][Return][Tax] [Risk][Return][Tax]

→ Explores multiple angles simultaneously

Implementation:

# Generate 3 different reasoning paths
for path in range(3):
    response = client.messages.create(
        model="claude-3-opus-20240229",
        messages=[{
            "role": "user",
            "content": f"Reasoning path {path + 1}: Analyze from perspective of {perspectives[path]}"
        }]
    )
    print(f"Path {path}: {response.content[0].text}\n")

# Synthesize best insights
synthesis = client.messages.create(
    model="claude-3-opus-20240229",
    messages=[{
        "role": "user",
        "content": f"Synthesize these perspectives into best recommendation"
    }]
)

Structured Reasoning with XML

Make reasoning explicit:

response = client.messages.create(
    model="claude-3-sonnet-20240229",
    messages=[{
        "role": "user",
        "content": """Analyze this customer feedback using XML structure:

<analysis>
  <sentiment>positive/negative/neutral</sentiment>
  <key_points>
    <point>...</point>
  </key_points>
  <action_items>
    <action>...</action>
  </action_items>
  <confidence>0.0-1.0</confidence>
</analysis>

Feedback: "Great product, but shipping took 2 weeks"
"""
    }]
)

import xml.etree.ElementTree as ET
root = ET.fromstring(response.content[0].text)

Prompt Evaluation at Scale

Benchmark Framework

from dataclasses import dataclass
from typing import List
import json

@dataclass
class TestCase:
    input: str
    expected_output: str
    category: str

def evaluate_prompt(prompt_template: str, test_cases: List[TestCase]) -> dict:
    results = {
        "total": len(test_cases),
        "passed": 0,
        "by_category": {}
    }

    for test in test_cases:
        response = client.messages.create(
            model="claude-3-sonnet-20240229",
            system=prompt_template,
            messages=[{"role": "user", "content": test.input}]
        )

        output = response.content[0].text
        is_correct = evaluate_output(output, test.expected_output)

        if is_correct:
            results["passed"] += 1

        if test.category not in results["by_category"]:
            results["by_category"][test.category] = {"correct": 0, "total": 0}

        results["by_category"][test.category]["total"] += 1
        if is_correct:
            results["by_category"][test.category]["correct"] += 1

    # Calculate accuracy
    results["accuracy"] = results["passed"] / results["total"]
    for cat in results["by_category"]:
        cat_data = results["by_category"][cat]
        cat_data["accuracy"] = cat_data["correct"] / cat_data["total"]

    return results

# Run evaluation
test_cases = [TestCase(...) for _ in range(50)]
results = evaluate_prompt(my_system_prompt, test_cases)
print(f"Overall accuracy: {results['accuracy']:.1%}")
print(f"By category: {json.dumps(results['by_category'], indent=2)}")

Automated Prompt Optimization

def optimize_prompt(base_prompt: str, test_cases: List[TestCase], iterations: int = 5):
    current_prompt = base_prompt
    best_accuracy = 0

    for i in range(iterations):
        # Evaluate current
        results = evaluate_prompt(current_prompt, test_cases)
        accuracy = results["accuracy"]

        print(f"Iteration {i}: {accuracy:.1%}")

        if accuracy > best_accuracy:
            best_accuracy = accuracy
            best_prompt = current_prompt

        if accuracy >= 0.95:  # Good enough
            break

        # Generate improved version
        improvement = client.messages.create(
            model="claude-3-opus-20240229",
            messages=[{
                "role": "user",
                "content": f"""Current prompt gets {accuracy:.0%} accuracy.

Failed on these categories: {json.dumps(results['by_category'])}

Improve the prompt to handle these better:

Original: {current_prompt}

Generate an improved version:"""
            }]
        )

        current_prompt = improvement.content[0].text

    return best_prompt

Common Pitfalls & Solutions

Pitfall Cause Solution
Vague output Unclear format instructions Specify JSON schema or examples
Inconsistent results Temperature too high Set temperature=0 for consistency
Too slow Using Opus for simple task Use Sonnet or Haiku
Hallucinations in RAG No grounding Use tool_use for retrieval first
Token waste Overly verbose system prompt Trim to <300 tokens

References

Last Updated: 21.03.2026 | Total Lines: 400+