P320 min

LLM & Prompts

Large language models are the agent's "brain." Prompt engineering is a key skill for building effective agents.

SDK FocussystemPromptoutputFormatZod schemastructured_outputthinking / effort

The LLM's Role in an Agent

The LLM serves as the core decision engine in an agent system:

  • Understanding - Parse user intent and context
  • Reasoning - Analyze problems and devise solutions
  • Decision-making - Choose which tools to use and how to act
  • Generation - Produce code, documents, replies, and more

System Prompt Design

The system prompt defines the agent's "persona" and behavioral boundaries. A good system prompt should include:

system-prompt.ts
import { query } from "@anthropic-ai/claude-agent-sdk";

// Form 1: Simple string
const agent1 = query({
prompt: "Review this PR",
options: {
  systemPrompt: "You are a senior code reviewer. Be thorough but constructive."
}
});

// Form 2: Preset with append (preserves Claude Code defaults)
const agent2 = query({
prompt: "Review this PR",
options: {
  systemPrompt: {
    type: "preset",
    preset: "claude_code",
    append: "\n\nFocus on security vulnerabilities and performance."
  }
}
});

Identity Definition

text
You are an expert software engineer assistant.
You help users write, debug, and improve code.
You are precise, helpful, and safety-conscious.

Capability Description

text
You have access to the following tools:
- read_file: Read contents of a file
- write_file: Create or modify files
- run_command: Execute shell commands
- search_code: Search codebase for patterns

Behavioral Guidelines

text
Guidelines:
- Always read files before modifying them
- Explain your reasoning before taking actions
- Ask for clarification when requirements are unclear
- Never execute destructive commands without confirmation

Output Format

text
Response Format:
1. First, analyze the request
2. Then, explain your approach
3. Execute necessary actions
4. Summarize what was done

Prompting Techniques

Chain-of-Thought and Verifiable Reasoning Scaffolds

Ask for concise, reviewable evidence and decisions rather than private chain-of-thought:

text
Return:
1. Assumptions that affect the answer
2. Evidence or tool results supporting each conclusion
3. Uncertainties and what would resolve them
4. The recommended action

Few-shot Learning

Provide examples to guide the model's behavior:

text
Example 1:
User: "Create a Python function to calculate fibonacci"
Action: write_file("fib.py", "def fibonacci(n):...")

Example 2:
User: "Fix the bug in app.js"
Action: read_file("app.js")
Action: write_file("app.js", "// fixed version...")

Structured Output

Use JSON or a specific format to keep outputs parsable:

text
Respond in this JSON format:
{
  "evidence": ["observable fact or source"],
  "action": "tool_name",
  "action_input": { ... }
}
structured-output.ts
import { query } from "@anthropic-ai/claude-agent-sdk";
import { z } from "zod";

// Define output schema with Zod
const ReviewSchema = z.object({
summary: z.string().describe("One-line summary"),
issues: z.array(z.object({
  severity: z.enum(["critical", "warning", "info"]),
  file: z.string(),
  line: z.number(),
  message: z.string()
})),
approved: z.boolean()
});

const response = query({
prompt: "Review the code in src/auth.ts",
options: {
  model: "sonnet",
  outputFormat: {
    type: "json_schema",
    schema: z.toJSONSchema(ReviewSchema) as Record<string, unknown>
  }
}
});

for await (const message of response) {
if (
  message.type === "result" &&
  message.subtype === "success" &&
  message.structured_output !== undefined
) {
  // Validate the unknown payload at the application boundary.
  const review = ReviewSchema.parse(message.structured_output);
  console.log(`Approved: ${review.approved}`);
  review.issues.forEach(i =>
    console.log(`[${i.severity}] ${i.file}:${i.line} — ${i.message}`)
  );
}
}

SDK Insight: Schema-Constrained Output

outputFormat asks the SDK to constrain the final response, exposed as unknown via message.structured_output. Validate it locally; the query can still end with error_max_structured_output_retries when the model cannot satisfy the schema.

Context Management

LLMs have context length limits, so you need to manage context strategically:

Context Window

Context limits vary by exact model, API, and account configuration. Read the provider's current model documentation at deployment time, then reserve headroom for tool results and the answer.

Management Strategies

  • Sliding window - Keep recent conversations, drop older ones
  • Summary compression - Compress history into summaries
  • Retrieval augmentation - Fetch relevant context on demand
  • Tiered storage - Store important info in long-term memory

Model Selection

Use different models for different tasks:

  • Hard judgment - Start with a capable tier; measure correctness and review burden
  • Routine transformations - Prefer a faster tier after it passes representative evals
  • Long context - Verify the exact endpoint limit and test retrieval or compaction too
  • Local deployment - Measure quality, latency, memory, and operational constraints

Thinking Controls

Newer SDK flows should prefer thinking and effort to control reasoning depth. You may still see maxThinkingTokens in older examples, but treat it as a compatibility knob rather than the primary interface for tuning reasoning.

Best Practices

  • Keep the system prompt concise but complete
  • Use concrete examples instead of abstract descriptions
  • Define the output format clearly
  • Tune only controls exposed by your chosen SDK and model, then evaluate the result
  • Test edge cases and error handling

Production Gap

Prompt examples here are static strings. Production systems use versioned prompt templates, A/B testing, and automated regression testing to prevent prompt changes from degrading quality.

Related Reading

Try ItSchema-Constrained Output

Build an agent that returns validated JSON a real teammate can act on.

  1. Name the user and decision, then define: { task, complexity, estimatedMinutes, requiredTools }
  2. Use outputFormat to enforce the schema
  3. Test 5 representative tasks; check both schema validity and whether required fields support the decision
  4. Compare without outputFormat: count broken outputs and plausible-but-wrong values separately

Gate: P3 Complete — Structured output succeeds on the test set, failure handling works, the system prompt preset is understood, and the thinking trade-off is measured.

Sign in to save lesson progress, unlock flashcards, and continue where you left off.