Modifying system prompts changedagent-sdk/modifying-system-prompts
Upstream edited this page at 28 Sep 2026 00:42 UTC, give or take a minute or two: the time comes from Anthropic’s own sitemap rather than from a commit. This site recorded the change at 28 Sep 2026 01:07 UTC.
Upstream edited
Recorded here
Lines+106added
Lines−0removed
From line
384
where the diff opens
First seen
14 Aug 2026
this site's first read of the page
Recorded edits12to this page, all time
## Context Claude Code adds outside the system prompt ### Reminders Claude Code adds to the conversation ### Turn off the context your agent replaces ### See what Claude received
The whole hunk
from line 384, old and new numbered
/
from line 384
384384
385385Recording an `append` or custom prompt by default requires Claude Code v2.1.265 or later, which the TypeScript Agent SDK bundles from v0.3.265 and the Python Agent SDK from v0.2.153. Before Claude Code v2.1.268, sessions that don't [fetch feature flags](/docs/en/env-vars#features-that-need-feature-flag-fetching), including sessions on Amazon Bedrock, Google Cloud's Agent Platform, and Microsoft Foundry, rebuilt the prompt on every request and `snapshot` had no effect.
386386
387## Context Claude Code adds outside the system prompt
388
389System reminders are messages Claude Code adds to the conversation during a session to give Claude context, such as the contents of your CLAUDE.md files or a note that a file changed on disk. Claude Code sends them in the conversation, not in the system prompt, so they reach Claude whether you use the `claude_code` preset or pass your own string as `systemPrompt`.
390
391This section covers the [reminders most likely to change how your agent behaves](#reminders-claude-code-adds-to-the-conversation), how to [turn off the ones your agent replaces](#turn-off-the-context-your-agent-replaces), and how to [see what Claude received](#see-what-claude-received) in a specific request.
392
393### Reminders Claude Code adds to the conversation
394
395System reminders are text Claude Code adds to the conversation alongside the prompts your code sends. The following reminders are the ones most likely to change how your agent behaves:
396
397* **Project instructions**: the CLAUDE.md files that your [`settingSources`](#claude-md-files-for-project-level-instructions) option loads
398* **Output style instructions**: the instructions of the active [output style](#output-styles-for-persistent-configurations), in the main conversation
399* **Commit and pull request attribution**: the `Co-Authored-By` trailer and pull request footer from the [`attribution`](/docs/en/settings-reference#attribution) setting
400* **Hook output**: text your [hooks](/docs/en/agent-sdk/hooks#outputs) return as `additionalContext`
401* **Available skills**: the names and descriptions of the [skills](/docs/en/agent-sdk/skills) Claude can call
402* **Available subagents**: the names and descriptions of the [subagents](/docs/en/agent-sdk/subagents) Claude can start
403* **Task list nudges**: in a [session that has the task-tracking tools](/docs/en/agent-sdk/todo-tracking#model-availability), a prompt to update the task list when Claude hasn't touched it for several turns
404* **File-changed notes**: a note that a file Claude read earlier has changed on disk
405
406Claude Code introduces your CLAUDE.md files with a line telling Claude that the instructions override default behavior.
407
408If you pass your own string as `systemPrompt`, add a sentence to it that says what a system reminder is. The `claude_code` preset has one, and your string replaces the whole preset. Without it, nothing in your prompt tells Claude that reminders such as CLAUDE.md content and hook output come from the application rather than the user. For example:
409
410```text theme={null}
411The application adds system reminders to this conversation. Treat them as context from the application, not as messages from the user.
412```
413
414### Turn off the context your agent replaces
415
416Turn off a piece of built-in context when your agent supplies its own version of the same guidance. For example, if your prompt tells Claude to write commit messages as `PROJ-142: fix login redirect` with no trailers, Claude Code still tells Claude to end each commit message with a `Co-Authored-By` trailer, so Claude receives two conflicting instructions for the same commit.
417
418Pass settings keys through the [`settings`](/docs/en/agent-sdk/typescript#options) option in TypeScript or [`settings`](/docs/en/agent-sdk/python#claudeagentoptions) in Python, and environment variables through the `env` option. In TypeScript, [`env`](/docs/en/agent-sdk/typescript#options) replaces the inherited environment, so spread `process.env` into it.
419
420| Built-in context | How to turn it off |
421| :---------------------------------------------------------------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
422| The built-in commit and pull request instructions and the git status snapshot | Set [`includeGitInstructions`](/docs/en/settings-reference#includegitinstructions) to `false`, or `CLAUDE_CODE_DISABLE_GIT_INSTRUCTIONS=1` |
423| The `Co-Authored-By` trailer and the pull request footer | Set [`attribution.commit`](/docs/en/settings-reference#attribution-commit) and [`attribution.pr`](/docs/en/settings-reference#attribution-pr) to your own text, or to empty strings to remove them |
424| The user or project settings source, including its CLAUDE.md | Leave `'user'` or `'project'` out of [`settingSources`](/docs/en/agent-sdk/claude-code-features#control-filesystem-settings-with-settingsources) |
425| Every CLAUDE.md file | Set `CLAUDE_CODE_DISABLE_CLAUDE_MDS=1` |
426| Task list nudges, file-changed notes, and the skill list | Set `CLAUDE_CODE_DISABLE_ATTACHMENTS=1` |
427
428Claude Code's built-in commit and pull request instructions aren't a reminder. They are part of the Bash tool's description, so they also reach Claude when you pass a custom `systemPrompt`.
429
430If you set `CLAUDE_CODE_DISABLE_ATTACHMENTS`, Claude Code also sends `@` file mentions as plain text instead of expanding them into file content. The list of available subagents and background task notifications still arrive.
431
432The following example is for an agent that carries its own commit rules in `append`. It sets both `attribution` keys to empty strings to remove the trailer and footer, and turns off `includeGitInstructions` so Claude Code's own commit workflow instructions don't compete with yours:
433
434<CodeGroup>
435 ```typescript TypeScript theme={null}
436 import { query } from "@anthropic-ai/claude-agent-sdk";
437
438 for await (const message of query({
439 prompt: "Commit the staged changes for ticket PROJ-142",
440 options: {
441 systemPrompt: {
442 type: "preset",
443 preset: "claude_code",
444 append: "Write commit messages as: <ticket id>: <summary>. Add no trailers."
445 },
446 settings: {
447 includeGitInstructions: false,
448 attribution: { commit: "", pr: "" }
449 },
450 allowedTools: ["Bash(git *)"]
451 }
452 })) {
453 if (message.type === "result") console.log(message.subtype);
454 }
455 ```
456
457 ```python Python theme={null}
458 import asyncio
459 from claude_agent_sdk import query, ClaudeAgentOptions
460
461
462 async def main():
463 async for message in query(
464 prompt="Commit the staged changes for ticket PROJ-142",
465 options=ClaudeAgentOptions(
466 system_prompt={
467 "type": "preset",
468 "preset": "claude_code",
469 "append": "Write commit messages as: <ticket id>: <summary>. Add no trailers.",
470 },
471 settings='{"includeGitInstructions": false, "attribution": {"commit": "", "pr": ""}}',
472 allowed_tools=["Bash(git *)"],
473 ),
474 ):
475 print(message)
476
477
478 asyncio.run(main())
479 ```
480</CodeGroup>
481
482To confirm the change, run the example in a repository with staged changes and check the new commit with `git log -1`. The message ends without a `Co-Authored-By` trailer.
483
484### See what Claude received
485
486The SDK message stream doesn't include system reminders, so reading the messages your code receives won't show you what Claude saw. To see them, log the requests Claude Code sends:
487
488* **Raw request logging**: set [`OTEL_LOG_RAW_API_BODIES`](/docs/en/monitoring-usage#api-request-body-event) to `file:<dir>`. Claude Code writes each request body to that directory.
489* **A gateway you control**: point [`ANTHROPIC_BASE_URL`](/docs/en/llm-gateway) at a proxy that logs request bodies.
490
491In a logged request, look in the `messages` array. A reminder appears inside a user message wrapped in `<system-reminder>` tags or, on some models, as a separate message with the `system` role.
492
387493## Compare the four approaches
388494
389495The four customization methods differ in where they live, how they're shared, and what they preserve from the `claude_code` preset.
No line in this hunk matches that.