第5章: システムプロンプト ─ エージェントの世界観と憲法
ChatGPT に「コードレビューして」と頼むと、丁寧に「ここはこう書くといいですよ」と 提案 を返してくる。 ところが Claude Code に同じことを頼むと、いきなり Read tool が走り、Grep でテストを検索し始め、勝手に 作業計画 まで立てる。
中で動いている LLM は、どちらも Claude 系の同じモデル ── たとえば Claude Sonnet 4 だとしよう。 同じ脳みそが、なぜこれほど違う性格に見えるのか。
答えは「モデルを差し替えたから」ではない。 モデルの 目の前に置いてある “憲法” が違うからだ。
5.1 そもそも LLM に “人格” はあるか
身も蓋もない答えを先に書く。ない。
本書冒頭で見たとおり、LLM 自体は人格も記憶も持たない。入力テキストにふさわしい続きを返すだけだ。
ところがその「ふさわしい続き」は、何を文脈として読ませるか で大きく変わる。
- 入力の冒頭に「あなたは丁寧なカスタマーサポートです」と書けば、丁寧に答える
- 入力の冒頭に「あなたはぶっきらぼうな職人です」と書けば、ぶっきらぼうに答える
- 入力の冒頭に「あなたはコードを書くエージェントです。利用可能なツールは Read/Edit/Bash…」と書けば、それっぽく振る舞う
LLM の “人格” は、モデル本体ではなく 入力の冒頭に毎回挿入される指示文 によって作られている。 この冒頭の指示文を system prompt と呼ぶ。
ChatGPT の Claude Code っぽさのなさも、Claude Code の Claude Code っぽさも、ほとんど system prompt の差 で説明がつく。
5.2 system prompt とは何か
正式な定義を入れておく。
system prompt (システムプロンプト)LLM のループの 最初に毎回挿入される、モデルへの根本指示。 役割設定、利用可能なツールリスト、出力フォーマット、安全上の制約、口調の指針などを含む。 ユーザー入力よりも 優先度が高い ものとして扱われるよう、API レベルで
role: "system"というラベルが付けられている。
ここで前章 (第4章) で出てきた「ターンが進むたびに積み上がる入力」を思い出してほしい。
[system prompt] ← どのターンでも先頭に必ず乗る
[user / assistant ターン1]
[user / assistant ターン2]
[user / assistant ターン3]
...
system prompt は 毎ターン頭に居座る。だから常に LLM の判断に影響し続ける。 これがエージェントの “性格” や “規律” を一貫させている仕組みだ。
5.3 role という仕組み ── system / user / assistant
system prompt を本当に理解するには、その隣にいる role という概念にも触れておく必要がある。
現代の LLM API(Anthropic、OpenAI どちらも)は、入力を単一のテキスト塊として受け取るのではなく、「誰の発言か」をラベル付きで 受け取る。
roleLLM API で各メッセージに付ける、発話者の種類を表すラベル。代表的なのは三種類:
- system: モデルへの根本指示。最優先で従うべきもの
- user: 人間(または上位のプログラム)からの入力
- assistant: モデル自身の過去の応答
エージェントのループの入力は、典型的にはこういう列になる。
| 順番 | role | 中身 |
|---|---|---|
| 1 | system | 「あなたはコードエージェント。利用可能なツールは…」 |
| 2 | user | 「fibonacci.py のバグを直して」 |
| 3 | assistant | 「Read を呼びます」(tool_use 含む) |
| 4 | user | (Read の結果を tool_result として返す) |
| 5 | assistant | 「Edit を呼びます」 |
| 6 | user | (Edit の結果) |
| … | … | … |
注目してほしいのは、ツールの実行結果も user role で渡る こと(厳密には tool_result という入れ子だが、外側は user メッセージ)。
LLM から見れば、「人間が言ったこと」と「道具の結果」は 同じ陣営からの入力 という扱いだ。
ハーネスがやっているのは、結局のところ 「assistant の出力を見て、tool 実行を挟んで、user メッセージとして結果を返す」 という、role 操作の編集作業。 LLM 本体は「続きを書く」だけで、role の組み立て はすべてハーネスの仕事。
5.4 Claude Code の system prompt には何が入っているか
公式に全文公開されているわけではないが、API トラフィックを観察した有志の報告や Anthropic の公式ドキュメント、そして体感から、Claude Code の system prompt にはおおむね次のような要素が入っているとされる。
| 要素 | 役割 |
|---|---|
| 役割宣言 | 「あなたは Claude Code、Anthropic 公式のコーディングエージェントです」 |
| 基本姿勢 | 簡潔に答える、推測でファイルを作らない、既存ファイルの編集を優先、など |
| ツール定義 | Read / Edit / Write / Bash / Grep / Glob / Task / WebFetch… の全シグネチャと使い方 |
| 出力フォーマット | 装飾や前置きを抑える、必要なら markdown、絵文字は基本使わない |
| 安全上の制約 | 破壊的コマンドへの注意、秘密情報の扱い、ユーザー確認が必要な操作 |
| 環境情報 | 作業ディレクトリ、現在日時、git の状態、OS 種別など |
合計トークン数は 数千 〜 1 万トークン超。これが毎ターン入力の先頭に乗っている。
あなたが Claude Code を 1 回起動した瞬間、まだ何も話していないのに数千トークンの “前置き” がすでに机の上に広がっている。 これが prompt caching (前章)が必須になる理由でもある ── キャッシュしないと、毎ターンこの長文を計算し直すことになる。
5.5 図で掴む ── system が頂点に立つ階層
system / user / assistant の関係を、優先度のピラミッドとして整理しておこう。
5.6 第1章の主張を、system prompt の角度から見直す
第1章で出した「Claude Code らしさはモデルよりハーネス側に宿る」という主張は、ここまで読んだ今、system prompt とツール定義に書き込まれている内容を見れば最も具体的に確認できる。
Claude Code の「Claude Code らしさ」── 最初に環境を調べる、推測でファイルを作らない、テスト駆動で動く、簡潔に応答する ── は、モデル本体の性質ではなく、先頭に毎ターン差し込まれる system prompt とツール定義 という “条文” に書かれている。
裏返せば、同じ Claude モデルでも、この条文を差し替えれば全く別のエージェントになる。
実際 Cursor の Composer も、Codex CLI も、Cline も、Continue も、内部で動いているモデルは Claude や GPT そのものだ。 差別化のほぼ全部は、ハーネス側 ── 特に system prompt と道具設計 で生まれている。
この視点は実用上も効く。エージェントの “個性” が条文側にあるということは ── 可搬性が高い ということでもある。良いプロンプト設計があれば、それは LLM の世代交代を超えて生き延びる。本書が「コマンドの暗記より骨格」を強調している理由のひとつだ。
5.7 ユーザーが触れる別チャネル ── 予告だけ
ここで察しのいい読者は気付いただろう。
「system prompt は Anthropic が書いている。ということは、私たちユーザーは触れないのでは?」
その通り。基本の system prompt は閉じている。 ただし Claude Code は、ユーザーが system prompt の隣で指示を追加できる別チャネル を用意している。
| チャネル | 何ができるか | 詳しくは |
|---|---|---|
| CLAUDE.md | プロジェクトごとの長期記憶。「このリポジトリの規約」「使う言語」「テストの流儀」を書き込む | 第8章 |
slash command (/init 等) | コマンド実行で自動的に CLAUDE.md を生成・整備 | 第Ⅱ部「コマンド: 設定とメモリ」グループ |
/memory コマンド | 対話的にユーザー単位・プロジェクト単位の指示を保存 | 第Ⅱ部「コマンド: 設定とメモリ」グループ |
--system-prompt フラグ | CLI 起動時に system prompt の差し替え or 追加 | 第Ⅱ部「コマンド: CLI フラグ」グループ |
つまりユーザーは system prompt を直接書き換えるわけではない が、隣に 「私のプロジェクトの追加指示」 を差し込むことで、エージェントの振る舞いをカスタマイズできる。 この「公式憲法 (system) + ローカル法 (CLAUDE.md)」という二層構造は、Claude Code の運用設計の核になる発想だ。
私が Claude Code の設計で一番うまいと思うのは、ここだ。 system prompt を閉じる ことで一貫した品質を保証しつつ、CLAUDE.md という別チャネル でユーザーの介入余地を残した。
もし system prompt を完全に開放していたら、初心者が壊して動かないエージェントを量産していただろう。 逆に CLAUDE.md がなければ、エージェントは「自分のプロジェクトを知らない他人」のままだった。
この二層構造こそ、Claude Code が “現場で使えるツール” になった最大の設計判断だと思っている。
5.8 この章の振り返り
- LLM 自体に人格はない。“人格” は 入力冒頭に乗る system prompt が作っている
- system prompt = ループの最初に毎回挿入される、モデルへの根本指示
- 中身は: 役割宣言、ツール定義、出力フォーマット、安全制約、環境情報 ── 数千〜1 万トークン超
- メッセージは role (
system/user/assistant) でラベル付け。優先度は system > user > assistant - 道具の実行結果も
userrole で返る ── LLM から見れば人間と道具は同じ陣営 - Claude Code の “らしさ” の大半は、モデルではなく system prompt + ツール定義 に書かれている
- ユーザーは system prompt を直接書き換えないが、CLAUDE.md という別チャネルで指示を追加できる(第8章)
この章で読めるようになるツイート / ブログ
- 「Cursor も Claude Code も中身は Claude なのに、動きが違いすぎる」 → モデルではなく system prompt とツール設計の差。差別化はそこにある
- 「Claude Code の system prompt をリークしてみたら 8000 トークンあった」 → 既知の事実。毎ターンこれが先頭に乗るので prompt caching が必須になる
- 「CLAUDE.md って何書けばいいの?」 → 「公式の system prompt の隣に置く、プロジェクト固有の追加指示」と理解すると書きやすい
次章は、その system prompt の中で大きな顔をしている 「ツール定義」 に踏み込む。 Bash 一本あれば何でもできるはずなのに、Claude Code はなぜ Read / Edit / Write / Grep / Glob を わざわざ別々に 用意しているのか ── その設計判断の理由が、エージェントの賢さに直結する。