システムプロンプトは、会話全体を通して Claude の振る舞い・できること・応答の書き方を決める最初の指示です。この記事では公式ドキュメント「Modifying system prompts」に沿って、Claude Agent SDK の systemPrompt(Python では system_prompt)で claude_code プリセットと独自プロンプトを使い分ける方法と、CLAUDE.md・出力スタイル・append の違いを整理します。CLI の --append-system-prompt などのフラグについては「Claude Code のシステムプロンプト」を参照してください。
3つの出発点と選び方
Agent SDK のシステムプロンプトには、出発点が3つあります。
- 最小の既定:
systemPromptを指定しないと、ツール呼び出しに必要な部分だけの最小プロンプトが使われます。claude_codeプリセットにあるセキュリティ・安全の指示も含まれません。claude -pは既定で Claude Code のシステムプロンプトを使うので、CLI から移行して同じ挙動にしたいときはプリセットを明示します。 claude_codeプリセット: Claude Code CLI が使うシステムプロンプトで、ツールの使い方とセキュリティ・安全の指示を含みます。TypeScript ではsystemPrompt: { type: "preset", preset: "claude_code" }、Python ではsystem_prompt={"type": "preset", "preset": "claude_code"}と書き、必要ならappendで末尾に指示を足します。- 独自の文字列: 自分で書いたプロンプトです。SDK は渡した内容だけを送ります。
どれを選ぶかの決め手は、作るエージェントが Claude Code にどれだけ近いか、つまり「リポジトリで動くコーディングエージェントで、人がストリーミング出力を見ながら舵を取る」形に近いかどうかです。公式の表を訳すと次のとおりです。
| 作るもの | 使うもの | 得られるもの |
|---|---|---|
| 人が見ながら操作する CLI や IDE 風のコーディングツールで、Claude Code の既定のままでよい | claude_code プリセット | ツールの案内と安全ルールを含む Claude Code のプロンプト |
| 同じ種類のツールに、コーディング規約・出力形式・ドメイン知識など製品固有のルールを足したい | プリセット + append | 上記に自分の指示を後ろから追加。何も削らないので最もリスクの低いカスタマイズ |
| 画面・名乗り・権限モデルが異なるエージェントや、コーディング以外のエージェント | 独自のプロンプト文字列 | 書いた内容だけ。必要なツールの案内と安全の指示は自分で用意する |
| 人格を持たない薄いツール呼び出しループで、振る舞いはすべてユーザープロンプトで渡す | systemPrompt を指定しない | ツール呼び出しの対応だけの最小の既定 |
「Claude Code と違う」とは、出力が起動した本人に端末で読まれない(チャット UI や構造化出力の消費側など)、Claude Code と名乗るべきでない(サポートボットやデータ分析アシスタントなど)、人が各手順を承認せず自律的に動く、コーディング以外の作業である、のいずれかを指すと公式は説明しています。なお、lint エラーを直したり差分をレビューしたりする無人の CI ジョブは、作業内容がプリセットの想定どおりなのでプリセットが合うとされています。
claude_code プリセットに append で追記する
プリセットに append を付けると、組み込みの機能をすべて残したまま独自の指示を足せます。次は Python コードに必ず docstring と型ヒントを付けさせる例です。
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Help me write a Python function to calculate fibonacci numbers",
options: {
systemPrompt: {
type: "preset",
preset: "claude_code",
append: "Always include detailed docstrings and type hints in Python code."
}
}
})) {
if (message.type === "assistant") {
console.log(message.message.content);
}
}
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage
async for message in query(
prompt="Help me write a Python function to calculate fibonacci numbers",
options=ClaudeAgentOptions(
system_prompt={
"type": "preset",
"preset": "claude_code",
"append": "Always include detailed docstrings and type hints in Python code.",
}
),
):
if isinstance(message, AssistantMessage):
print(message.content)
注意点として、同じプリセットと同じ append を使っていても、自動メモリの保存場所が違うセッション同士はプロンプトキャッシュを共有できません。プリセットは append の手前にその場所(既定では ~/.claude/projects/ 配下の、リポジトリのパスにちなんだ絶対パス)を埋め込むため、ユーザー・マシン・チェックアウトごとに内容が変わるからです。CLAUDE.md の内容や作業ディレクトリ・OS などの環境情報は会話側で渡されるので、システムプロンプトのキャッシュには影響しません。
複数のユーザーやマシンでキャッシュを共有したい場合は、プリセットのオブジェクトに excludeDynamicSections: true(Python は "exclude_dynamic_sections": True)を指定します。ユーザーごとの情報は最初のユーザーメッセージへ移り、システムプロンプトには静的なプリセットと append だけが残ります。必要なバージョンは TypeScript の @anthropic-ai/claude-agent-sdk v0.2.98 以降、Python の claude-agent-sdk v0.1.58 以降です。移した内容はユーザーメッセージになる分だけ重みがわずかに下がり、自動メモリの指示に従う一貫性が少し落ちることがある、というトレードオフも公式に書かれています。
systemPrompt: {
type: "preset",
preset: "claude_code",
append: "You operate Acme's internal triage workflow. Label issues by component and severity.",
excludeDynamicSections: true
}
独自プロンプトと静的部分のキャッシュ
systemPrompt に文字列を渡すと、既定のプロンプトを丸ごと自分の指示に置き換えられます。
const customPrompt = `You are a Python coding specialist.
Follow these guidelines:
- Write clean, well-documented code
- Use type hints for all functions
- Include comprehensive docstrings`;
for await (const message of query({
prompt: "Create a data processing pipeline",
options: { systemPrompt: customPrompt }
})) {
// ...
}
Python で長いプロンプトを渡すときは、文字列ではなく system_prompt={"type": "file", "path": "..."}(SystemPromptFile)でファイルから読み込みます。Python SDK は文字列のプロンプトを CLI サブプロセスのコマンドライン引数1つとして渡すため、OS の引数長の上限を超えると API を呼ぶ前のプロセス起動で失敗します。Python SDK のリファレンスによると、Linux では1引数がおよそ 128 KB を超えると Argument list too long になり、Windows ではコマンドライン全体がおよそ 32 KB に制限されるので、より小さいサイズで失敗します。ファイル形式は CLI の --system-prompt-file に対応します。
TypeScript SDK では、独自プロンプトを文字列の配列で渡し、毎回同じ部分と依頼ごとに変わる部分の間に SYSTEM_PROMPT_DYNAMIC_BOUNDARY を挟めます。境界より前と後がそれぞれ別のテキストブロックとして送られ、別々のキャッシュブレークポイントが付くので、チケット情報のような可変部分が変わっても静的な指示はキャッシュに残ります。
import { readFile } from "node:fs/promises";
import { query, SYSTEM_PROMPT_DYNAMIC_BOUNDARY } from "@anthropic-ai/claude-agent-sdk";
const instructions = await readFile("triage-instructions.md", "utf8"); // 毎回同じ
const ticketContext = "Customer plan: Enterprise. Other open tickets from this customer: 3."; // 毎回変わる
for await (const message of query({
prompt: "Triage ticket 4821",
options: {
systemPrompt: [instructions, SYSTEM_PROMPT_DYNAMIC_BOUNDARY, ticketContext]
}
})) {
// ...
}
境界の目印そのものは Claude に届かず、複数入れた場合は最初の1つで分割されます。目印を入れなければ1つの文字列と同じ扱いです。この分割が効くのは Claude API を直接呼ぶ場合と Claude Platform on AWS の場合だけで、Amazon Bedrock・Microsoft Foundry・LLM ゲートウェイなどでは1ブロックで送られます。配列形式は Python SDK にはありません。
独自プロンプトを使うときにもう1つ大事なのが、system reminder の扱いです。CLAUDE.md の内容やフックの出力などは、Claude Code が会話の中に system reminder として差し込みます。プリセットにはそれが何かを説明する文がありますが、独自プロンプトはプリセット全体を置き換えるので、その説明も消えます。公式は、独自プロンプトに「アプリケーションが会話に system reminder を追加する。ユーザーからのメッセージではなくアプリケーションからの文脈として扱う」という趣旨の1文を入れるよう勧めています。
CLAUDE.md と出力スタイルで振る舞いを足す
append や独自プロンプトがシステムプロンプトそのものを変えるのに対し、CLAUDE.md は別の経路で効きます。SDK が CLAUDE.md を読み、その内容をプロジェクトの文脈として会話に差し込むので、どのシステムプロンプト設定とも併用できます。読み込みを決めるのはプリセットではなく設定ソースです。'project' で作業ディレクトリの CLAUDE.md または .claude/CLAUDE.md、'user' で ~/.claude/CLAUDE.md が読まれます。query() の既定では両方が有効ですが、settingSources(Python は setting_sources)を明示する場合は必要なソースを含め、空配列を渡すと CLAUDE.md は読まれません。
async for message in query(
prompt="Add a new React component for user profiles",
options=ClaudeAgentOptions(
system_prompt={"type": "preset", "preset": "claude_code"},
setting_sources=["project"], # プロジェクトの CLAUDE.md を読み込む
),
):
messages.append(message)
CLAUDE.md の書き方そのものは「CLAUDE.md でプロジェクトを覚えさせる」を参照してください。
出力スタイルは、Claude の役割・口調・出力形式を変える指示を Markdown ファイルとして保存し、セッションやプロジェクトをまたいで使い回す仕組みです。ユーザー単位なら ~/.claude/output-styles/、リポジトリで共有するなら .claude/output-styles/ に置きます。独自の出力スタイルはプリセットのソフトウェア開発向けの指示を外して自分の指示に置き換えますが、フロントマターに keep-coding-instructions: true を書くとそれを残したまま上に重ねられます。
---
name: Code Reviewer
description: Thorough code review assistant
keep-coding-instructions: true
---
You are an expert code reviewer.
SDK から有効にするには、outputStyle を settings オプションで渡します。outputStyle は Options の最上位の項目ではない点に注意してください。TypeScript では { settings: { outputStyle: "Explanatory" } }、Python では settings に '{"outputStyle": "Explanatory"}' のような JSON 文字列か設定ファイルのパスを渡します。また、出力スタイルは設定ソースに 'user' か 'project' を含めたときに読み込まれます。出力スタイルの作り方は「Claude Code の出力スタイル」で詳しく扱っています。
セッション途中の変更と4つの方法の比較
resume や continue でセッションに戻るときに別の append や独自プロンプトを渡しても、既定では次のターンに反映されません。Claude Code はセッションの最初の依頼でシステムプロンプトを記録し、コンパクションされるまでその記録を使い続けるからです。新しい内容はコンパクション後か、新しいセッションで効きます。
セッションの途中で指示を変えたい場合(ユーザーがアプリで読み取り専用モードに切り替えた、など)は、systemPrompt を変えるのではなく会話の中で伝えます。次のユーザーメッセージに新しい指示を含めるか、UserPromptSubmit または PostToolUse のフックから「The workspace is now read-only」のような事実の文を additionalContext として返します。フックの使い方は「Agent SDK のフック」を参照してください。
プロンプトの文言を試行錯誤していて、再開するセッションにも毎回反映させたいときは、オブジェクト形式のシステムプロンプトに snapshot: false(Python は False)を指定すると、依頼ごとにプロンプトが組み直されます。TypeScript の @anthropic-ai/claude-agent-sdk v0.3.257 以降、Python の claude-agent-sdk v0.2.153 以降が必要です。ただし記録を切るとそのセッションのプロンプトキャッシュを再利用できなくなるため、本番では記録を有効のままにするよう公式は勧めています。
最後に、4つのカスタマイズ方法の違いを公式の比較表から抜粋します。
| 項目 | CLAUDE.md | 出力スタイル | プリセット+append | 独自 systemPrompt |
|---|---|---|---|---|
| 保存 | プロジェクトごとのファイル | ファイルとして保存 | そのセッションのみ | そのセッションのみ |
| 再利用 | プロジェクト単位 | プロジェクトをまたいで | コードに重複して書く | コードに重複して書く |
| 既定のツール | 維持 | 維持 | 維持 | 失われる(含めない限り) |
| 組み込みの安全指示 | 維持 | 維持 | 維持 | 自分で追加が必要 |
| カスタマイズの度合い | 追加のみ | 追加。コーディング指示を外すことも可 | 追加のみ | 完全に制御 |
これらは組み合わせられます。出力スタイルや CLAUDE.md で長く続く振る舞いを決め、append でそのセッションだけの重点(たとえばレビューで OAuth 2.0 準拠とトークン保存の安全性を優先する、など)を上に重ねる、という使い方が公式の例として示されています。
本ページは Modifying system prompts を中心に、Agent SDK reference - Python の SystemPromptPreset・SystemPromptFile・ClaudeAgentOptions の記述を踏まえた非公式の日本語解説です(確認日 2026-10-27)。コード例は一部を簡略化しています。最新の仕様は公式ドキュメントを確認してください。