---
title: "Modifying System Prompts"
aliases: [system-prompt-customization, claude-agent-sdk-system-prompt]
tags: [agent-sdk, system-prompt, claude-code, configuration]
sources: [raw/Modifying system prompts 1.md, raw/Modifying system prompts.md]
created: 2026-04-17
updated: 2026-04-17
---

# Modifying System Prompts

System prompts define Claude's behavior, capabilities, and response style. The Agent SDK offers four distinct approaches — each with different scope, persistence, and trade-offs.

## Default Behavior

By default, the Agent SDK uses a **minimal system prompt** — only essential tool instructions. To get Claude Code's full prompt (coding guidelines, response tone, env context):

```typescript
// TypeScript
systemPrompt: { type: "preset", preset: "claude_code" }
```

```python
# Python
system_prompt={"type": "preset", "preset": "claude_code"}
```

The full preset includes: tool usage instructions, code style guidelines, verbosity settings, safety instructions, and current working directory context.

## Method 1: CLAUDE.md Files

Project-specific markdown files auto-loaded by the SDK. Ideal for team-shared, version-controlled instructions.

**Discovery locations:**
- `CLAUDE.md` or `.claude/CLAUDE.md` — project-level
- `~/.claude/CLAUDE.md` — user-level (global)

**Loading behavior:** Controlled by `settingSources` / `setting_sources`. Default `query()` enables both `'project'` and `'user'` sources automatically. If you set `settingSources` explicitly, include the sources you need.

```typescript
for await (const message of query({
  prompt: "Add a new React component for user profiles",
  options: {
    systemPrompt: { type: "preset", preset: "claude_code" },
    settingSources: ["project"]   // loads CLAUDE.md
  }
})) { ... }
```

**Best for:** coding standards, project commands, naming patterns, long-term team memory.

| Trait | Value |
|-------|-------|
| Persistence | Per-project file |
| Version control | Yes (commit to git) |
| Scope | Project-specific |
| Customization | Additions only |

## Method 2: Output Styles

Saved markdown files stored in `~/.claude/output-styles` (user) or `.claude/output-styles` (project). Reusable across sessions.

```typescript
// Create a style programmatically
const content = `---
name: Code Reviewer
description: Thorough code review assistant
---

You are an expert code reviewer. For every submission:
1. Check for bugs and security issues
2. Evaluate performance
3. Suggest improvements
4. Rate code quality (1-10)`;

await writeFile("~/.claude/output-styles/code-reviewer.md", content);
```

**Activate via:**
- CLI: `/output-style [style-name]`
- Settings: `.claude/settings.local.json`

**Loaded when:** `settingSources` includes `'user'` or `'project'`.

**Best for:** specialized assistants (code reviewer, SQL optimizer, security auditor) shared across projects.

## Method 3: `systemPrompt` with `append`

Preserves the full Claude Code preset while bolting on extra instructions. The safest way to augment behavior without losing built-in tools.

```typescript
for await (const message of query({
  prompt: "Help me write a Python function",
  options: {
    systemPrompt: {
      type: "preset",
      preset: "claude_code",
      append: "Always include detailed docstrings and type hints in Python code."
    }
  }
})) { ... }
```

### Prompt Caching Across Sessions

By default, the preset embeds per-session context (working directory, date, git status, memory paths) before your `append` text — causing cache misses across different machines/directories.

Set `excludeDynamicSections: true` to move that context into the first user message instead, making the system prompt identical across sessions:

```typescript
systemPrompt: {
  type: "preset",
  preset: "claude_code",
  append: "You operate Acme's internal triage workflow. Label issues by component and severity.",
  excludeDynamicSections: true   // requires v0.2.98+ (TS) or v0.1.58+ (Python)
}
```

**Trade-off:** environment context reaches Claude via the user message (slightly less authoritative than system prompt). Use when cross-session cache reuse matters more than maximally authoritative env context.

CLI equivalent: `--exclude-dynamic-system-prompt-sections`

**Best for:** adding coding standards, domain knowledge, output formatting tweaks.

## Method 4: Custom `systemPrompt` String

Replaces the default entirely. Full control — but you lose all built-in tools and safety instructions unless you re-add them manually.

```typescript
for await (const message of query({
  prompt: "Create a data processing pipeline",
  options: {
    systemPrompt: `You are a Python coding specialist.
- Write clean, well-documented code
- Use type hints for all functions
- Prefer functional programming patterns`
  }
})) { ... }
```

**Best for:** specialized single-session agents, testing new prompt strategies, situations where default tools aren't needed.

## Comparison Table

| Feature | CLAUDE.md | Output Styles | `append` | Custom String |
|---------|-----------|---------------|----------|---------------|
| Persistence | Per-project file | Saved as files | Session only | Session only |
| Reusability | Per-project | Across projects | Code duplication | Code duplication |
| Default tools | Preserved | Preserved | Preserved | **Lost** |
| Built-in safety | Maintained | Maintained | Maintained | **Must add** |
| Env context | Automatic | Automatic | Automatic | **Must provide** |
| Customization level | Additions only | Replace default | Additions only | Complete control |
| Version control | With project | Yes | With code | With code |

## Combining Approaches

You can layer methods — e.g. CLAUDE.md for project conventions + `append` for session-specific focus:

```typescript
for await (const message of query({
  prompt: "Review this authentication module",
  options: {
    systemPrompt: {
      type: "preset",
      preset: "claude_code",
      append: `For this review, prioritize:
        - OAuth 2.0 compliance
        - Token storage security
        - Session management`
    }
  }
})) { ... }
```

## Key Takeaways

- **Default SDK prompt is minimal** — use `preset: "claude_code"` to get Claude Code's full behavior
- **CLAUDE.md** is the go-to for team-shared, version-controlled project conventions; loaded automatically with default `query()` options
- **Output styles** are reusable "persona" files for specialized assistants; stored in `.claude/output-styles/`
- **`append`** is the safest augmentation — keeps all tools and safety, adds your instructions on top
- **Custom string** gives full control but requires you to manually include tools and safety instructions
- **`excludeDynamicSections: true`** enables cross-session prompt cache reuse at the cost of slightly weaker env context authority
- CLAUDE.md loading is controlled by `settingSources`, **not** by using the `claude_code` preset

## Related Articles

- [[wiki/agent-sdk/overview|Agent SDK Overview]]
- [[wiki/agent-sdk/agent-skills-plugins|Agent Skills & Plugins]]
- [[wiki/agent-sdk/skills-in-sdk|Skills in SDK (setting_sources)]]
- [[wiki/agent-sdk/configure-permissions|Configure Permissions]]
- [[wiki/agent-sdk/hooks-guide|Hooks Guide]]
- [[wiki/claude-code/_index|Claude Code Docs]]

## Sources

- `raw/Modifying system prompts 1.md` — official Agent SDK docs on system prompt customization
