Claude Code が npm パッケージとして配布されたとき、その .js.map ソースマップに sourcesContent フィールドが含まれていた。そこには元の TypeScript ソースが格納されていた——その事実に気づいたエンジニアがいた。
2026年4月1日、alejandrobalderas が GitHub に公開した「claude-code-from-source」はその発見をもとに生まれた技術書だ。18章・7部・印刷換算約400ページ。スター2,027・フォーク602を集め、Claude Code の内部設計を体系的に学ぶリファレンスとして広く参照されている。
Claude Code 全般の使い方についてはClaude Code完全ガイド2026:インストールから本番運用までを参照してほしい。この記事が補完するのは「なぜそう設計されているのか」という設計の論理だ。
- ・npmの.js.mapソースマップからTypeScriptを抽出する仕組みと法的な位置付け。
- ・Claude Codeを支える6つの核心抽象(クエリループ・ツール・状態・タスク・フック・メモリ)。
- ・エージェントループがAsyncGeneratorである3つの設計理由。
- ・partitionToolCalls()がフェイルクローズドで並行安全性を判定する仕組み。
- ・フォークエージェントがバイト同一プレフィックスでコストを95%削減する原理。
- ・36エージェントが6時間で本を書き上げた4フェーズ制作プロセスの全貌。
1. npmソースマップから逆引きするClaude Code設計書
.js.mapのsourcesContentフィールド
TypeScriptで書かれたnpmパッケージを配布するとき、開発者はしばしばソースマップ(.js.map)を同梱する。ソースマップは「コンパイル後のJavaScriptの何行目が元のTypeScriptの何行目に対応するか」をデバッガーが把握するためのファイルだ。
ソースマップの仕様には sourcesContent というフィールドがある。元のソースファイルのテキスト全体を埋め込める仕組みで、デバッグ環境でソースファイルが手元にない場合でもブラウザが表示できるようにするための機能だ。
Claude Code の npm パッケージ(@anthropic-ai/claude-code)はこの sourcesContent を有効にしたままnpmに配布していた。
# npm パッケージを展開してソースマップを確認する例
npm pack @anthropic-ai/claude-code
tar xf anthropic-ai-claude-code-*.tgz
find package -name "*.js.map" | head -5
# sourcesContent フィールドの有無を確認
python3 -c "
import json
with open('package/cli.js.map') as f:
sm = json.load(f)
print('sources:', len(sm.get('sources', [])))
print('sourcesContent:', len(sm.get('sourcesContent', [])))
"
# 出力: sources: 1847 / sourcesContent: 1847
著者の alejandrobalderas はこの構造に気づき、約2,000ファイルのTypeScriptを抽出した。これが本書の一次ソースだ。
「コードゼロ」の原則
重要な前提:本書はAnthropicのソースコードを1行も含まない。
READMEには明確に記されている——「すべてのコードブロックは、アーキテクチャパターンを説明するために書いたオリジナルの擬似コードだ。変数名・定数・プロンプト実装は含まれない」。
本書の目的は「プロダクションAIエージェントがどう構築されているかを理解するための教材を提供すること」であり、Anthropicのコードの再配布ではない。ソースマップの解析は、実際にClaude Codeを利用するすべてのユーザーがnpmダウンロード時に利用可能なデータを使っている。
なお、表紙に使われている”NO’REILLY”はO’Reillyのパロディ・ミームであり、O’Reilly Mediaとは一切関係ない。
2. 7部18章の構成と各パートの学習価値
本書は7つのパートに分かれた18章で構成されている。技術リーダー向けのナラティブフロー・実装者向けのディープダイブ・「Apply This」セクションの3層構造が各章にある。
| パート | テーマ | 章 | 主なトピック |
|---|---|---|---|
| Part I | 基盤 | Ch01-04 | 6抽象・ブートストラップ・状態管理・APIレイヤー |
| Part II | コアループ | Ch05-07 | エージェントループ・ツール定義・並行実行 |
| Part III | マルチエージェント | Ch08-10 | サブエージェント・フォーク・Swarm通信 |
| Part IV | 永続化と知性 | Ch11-12 | メモリシステム・スキルと拡張性 |
| Part V | インターフェース | Ch13-14 | ターミナルUI・入力と操作 |
| Part VI | 接続性 | Ch15-16 | MCPプロトコル・リモートコントロール |
| Part VII | パフォーマンス | Ch17-18 | 最適化5次元・エピローグと将来展望 |
Part I が全体の「地図」として機能し、残りのパートはそれぞれ地図上のひとつの区画を詳細に展開する構造だ。
- ・技術リーダーはパートごとのナラティブ冒頭だけ読めば全体像を把握できる。
- ・実装者はディープダイブセクションと擬似コードを精読する。
- ・「Apply This」セクションだけ通し読みすれば、10パターンの移転知識を短時間で得られる。
3. Claude Codeを支える6つの核心抽象
Chapter 01 が最初に明かす知見がある。Claude Code は6つの核心抽象の上に成り立っており、残りの400以上のユーティリティファイル・フォークされたターミナルレンダラー・vimエミュレーション・コストトラッカーはすべてこの6つを支えるために存在する。
入力・表示・キーバインド"] B --> C["クエリループ query.ts
非同期ジェネレータ / 1730行"] C --> D["ツールシステム
40種超 / 並行実行制御"] C --> E["状態レイヤー
Bootstrap STATE / AppState"] D -->|"ツール結果"| C C -->|"スポーン"| F["タスク管理
サブエージェント / 状態機械"] F -->|"固有クエリループ"| C C -->|"発火"| G["フック 27イベント
ツールブロック可能"] G -->|"ブロック可"| D H["メモリシステム
CLAUDE.md / MEMORY.md
LLM関連性選択"] -->|"システムプロンプトに注入"| C
1. クエリループ(query.ts、約1,730行)
エージェント全体のハートビートとなる非同期ジェネレータ。モデルレスポンスをストリーミングし、ツール呼び出しを収集・実行し、結果をメッセージ履歴に追記してループする。REPL・SDK・サブエージェント・ヘッドレス実行のすべてがこの単一関数を通る。
ループが停止した理由は Terminal という判別共用体として型付けられており、正常完了・ユーザー中断・トークンバジェット枯渇・ストップフック介入・最大ターン・致命的エラーの10種が識別できる。
2. ツールシステム(Tool.ts、tools.ts、services/tools/)
ツールとは「エージェントが世界に対して行えること」——ファイル読み込み・シェル実行・コード編集・Web検索など40種以上。各ツールはID・スキーマ・実行・権限・レンダリングを含む豊富なインターフェースを実装する。並行安全性は型宣言で管理され、投機的実行によりモデルのストリーミング中にも読み取り専用ツールが開始できる。
3. 状態レイヤー(Bootstrap STATE + AppState store)
2層アーキテクチャ。Bootstrap STATE はシングルトンで起動時設定を保持し、AppState は実行時の変更可能な状態を管理する。「スティッキーラッチ」という仕組みが存在し、一度設定されたベータヘッダーはセッション中に削除されない——プロンプトキャッシュの安定性を保つための意図的な設計だ。
4. タスク管理(AgentTool、サブエージェント状態機械)
サブエージェントの生成・ライフサイクル・状態機械を管理する層。タスクは15ステップの runAgent ライフサイクルを持つ。コーディネータモードとSwarmメッセージングが並存する。
5. フック(27のライフサイクルイベント)
ツール実行の前後に割り込めるライフサイクルシステム。ハーネスエンジニアリングの観点では最も重要な拡張ポイントだ。設定はスナップショット方式——起動時にフリーズし、実行時の注入攻撃を防ぐ(後述の「パターン10」)。
6. メモリシステム(CLAUDE.md・MEMORY.md・LLM関連性選択)
ファイルベースのメモリとLLMによる関連性選択の組み合わせ。キーワードマッチングではなく、Sonnetのサイドクエリが現在の会話コンテキストを読んで関連するメモリを選択する。これにより、表面的なキーワードの一致では捉えられない文脈的関連性が扱える。
構造のポイント:6抽象の依存関係が本書の章構成をそのまま決めている。Part Iの4章が地図、Part II以降が各地図区画の詳細だ。
4. エージェントループの解剖——AsyncGenerator設計の理由
「なぜAsyncGeneratorなのか」という問いへの答え
Chapter 05 の核心は query.ts を1,730行かけて解説したことから理解できる——それがClaude Codeの知的コアだからだ。そして最初の問いが「なぜエージェントループはAsyncGeneratorなのか」だ。
// 概念を示す擬似コード — query.ts の基本構造
async function* agentLoop(
params: LoopParams
): AsyncGenerator<Message | Event, TerminalReason> {
const state = initLoopState(params)
while (true) {
// 1. モデルレスポンスをストリーミング
const stream = await callModel(state)
for await (const chunk of stream) {
yield chunk // 消費者が準備できるまでここで自然にポーズ
state.append(chunk)
}
// 2. ツール呼び出しを抽出・実行
const toolCalls = extractToolCalls(state.latestAssistantMessage)
if (toolCalls.length === 0) {
return { type: 'normal_completion' } // Terminal 型を返す
}
const results = await executeTools(toolCalls)
state.appendToolResults(results)
// 3. ループ継続判定(トークンバジェット・最大ターン等)
const terminal = checkTerminalConditions(state)
if (terminal) return terminal
}
}
3つの理由がある。
理由1:バックプレッシャー
イベントエミッターは消費者の準備に関係なく発火する。ジェネレータは消費者が .next() を呼ぶときだけ yield する。REPLのReactレンダラーが前フレームの描画中なら、ジェネレータは自然にポーズする。バッファオーバーフロー・メッセージ消失・「高速プロデューサー/低速コンシューマー」問題が構造的に解消される。
理由2:型付きTerminalのセマンティクス
ジェネレータの戻り値型は Terminal——ループが停止した理由を型安全にエンコードした判別共用体だ。コールバックベースのシステムでは「最後のイベントが何だったか」という状態管理が複雑になる。
理由3:自然なキャンセル
for await...of ループを break で抜けると、generator.return() が自動的に呼ばれてリソースのクリーンアップが走る。コールバックチェーンでは明示的なキャンセルトークンとガード節が必要になる。
4層コンテキスト圧縮
クエリループにはコンテキスト圧縮の4層システムが組み込まれている。各層は前の層より破壊的で、前の層が機能しない場合にのみ発動する。
- Snip:古いメッセージを段階的に削除
- Microcompact:ツール結果を要約
- Collapse:重複した構造を畳み込む
- Autocompact:全体的な文脈圧縮(
MAX_CONSECUTIVE_AUTOCOMPACT_FAILURES=3でサーキットブレーカー付き)
Prompt Too Long(PTL)エラーの3段階リカバリパス(Staged Collapse → Reactive Compact → Surface Error)についてはハーネスエンジニアリング完全解説|Claude Codeソースから読む5層モデル・クエリループ・コンテキスト管理で詳しく解説している。
5. 並行ツール実行とフォークエージェントのプロンプトキャッシュ
partitionToolCalls()のフェイルクローズド設計
Chapter 07 の核心的な洞察は「安全性はツールタイプではなく呼び出し単位で判定する」だ。
Bash("ls -la") は並行実行しても安全だが、Bash("rm -rf build/") は安全でない。同じツール、異なる入力——並行安全性は入力を見るまで決まらない。
// 擬似コード — toolOrchestration.ts のパーティションアルゴリズム
type Group = { parallel: boolean; calls: ToolCall[] }
function groupBySafety(
calls: ToolCall[],
registry: ToolRegistry
): Group[] {
return calls.reduce((groups, call) => {
const def = registry.lookup(call.name)
const parsed = def?.schema.safeParse(call.input)
// フェイルクローズド: パースエラーや例外 → シリアル実行
const safe = parsed?.success
? tryCatch(() => def.isConcurrencySafe(parsed.data), false)
: false
// 連続する安全な呼び出しを1グループに集約
if (safe && groups.at(-1)?.parallel) {
groups.at(-1)!.calls.push(call)
} else {
groups.push({ parallel: safe, calls: [call] })
}
return groups
}, [] as Group[])
}
設計の要点はフェイルクローズドだ。スキーマのパースに失敗した場合、安全性判定で例外が発生した場合——どちらもシリアル実行にフォールバックする。「安全が証明できない場合は直列」という保守的な設計がここにある。
投機的実行というもうひとつの最適化もある。モデルがレスポンスをストリーミング中、並行安全なツールはストリーミングが終わる前に開始される。読み取りツール(Read・Grep・WebFetch)の大半は数百ミリ秒かかる——モデルのストリーミング中にそれらを開始することで壁時計時間を大幅に短縮できる。
フォークエージェントの95%インサイト
Chapter 09 の「95%インサイト」は本書のハイライトのひとつだ。
親エージェントが5つの子エージェントを並行スポーンするとき、各子エージェントのAPIリクエストの圧倒的多数は同一内容だ。システムプロンプト・ツール定義・会話履歴——これらはすべて同じ。違うのは「君はデータベース移行を担当する」という最後の指示だけだ。
// 擬似コード — フォークエージェントのバイト同一プレフィックス保証
interface ForkParams {
override: {
systemPrompt: string // 親の renderedSystemPrompt を直接注入(再生成しない)
tools: Tool[] // useExactTools フラグで親の配列をそのまま使用
messages: Message[] // 会話履歴を参照渡し
}
forkDirective: string // 子固有の指示のみが異なる
}
async function spawnForkAgent(params: ForkParams): Promise<ForkResult> {
// バイト同一プレフィックス保証のために:
// 1. システムプロンプトを再レンダリングしない
// 2. ツール定義を並べ替えない
// 3. フィーチャーフラグ変更を許可しない(スティッキーラッチ)
return runAgent({
...params.override,
messages: [
...params.override.messages,
{ role: 'user', content: params.forkDirective }
]
})
}
80,000トークンの共有プレフィックスに対して子固有の指示は200トークン——99.75%が重複する。Anthropicのプロンプトキャッシュは入力トークンを最大90%割引するため、2番目以降の子がキャッシュヒットすれば入力コストが激減する。
バイト完全一致の要件:「意味的に等価」では足りない。スペース1つの違い・ツール定義の並べ替え・フィーチャーフラグの変更——どれもキャッシュミスを引き起こす。スティッキーラッチの存在意義はここにある。
- ・システムプロンプトは再レンダリングせず、親の出力をそのまま渡す。
- ・ツール定義の順序を変えない(useExactToolsフラグで保証)。
- ・すべての子エージェントを同じタイミングでスポーンする(プレフィックス共有のため)。
マルチエージェントアーキテクチャの選択基準についてはAIエージェントフレームワーク比較2026年版も参照してほしい。
6. マルチエージェント調整・メモリ・スキルの設計哲学
サブエージェントの15ステップライフサイクル
Chapter 08 はサブエージェントの生成を詳解する。AgentTool(runAgent関数)を通して生成されるサブエージェントは、15ステップの状態機械として管理される。
起動→パラメータ検証→コンテキスト引き継ぎ→独立実行→結果返却→後片付けという流れで、各ステップは明確な責任を持つ。特に重要なのはコンテキスト隔離だ。各サブエージェントは独自のクエリループを持ち、親の状態を直接汚染しない。
親子abort伝播も重要な設計だ。親エージェントが中断されると、その子エージェントも連鎖的にabortされる。AbortController の継承チェーンで実装されており、どの階層でも確実にクリーンアップが走る。
コーディネータモードとSwarmの使い分け
Chapter 10 は2つのオーケストレーションパターンを対比する。
コーディネータモードでは、親エージェントがタスクを割り振り子エージェントの結果を統合する。中央集権型で予測可能だが、ボトルネックが発生しやすい。Swarmモードでは、エージェント同士がメッセージパッシングで協調する。分散型で柔軟だが、デバッグが難しい。
ファイルベースメモリとLLM関連性選択
Chapter 11 のキーインサイトは「キーワードマッチングではなくLLMが関連メモリを選ぶ」だ。
従来のシステムではキーワード検索や類似度ベクトルでメモリを検索する。Claude Codeは異なるアプローチを取る——Sonnetのサイドクエリが現在の会話コンテキストを読んで「どのメモリが今関係あるか」を判断する。メモリは4タイプ(user / feedback / project / reference)に分類され、MEMORY.md はインデックスとして機能する。
MEMORY.md の上限は memdir.ts のハードコード定数として設定されている——200行・25,000バイト。超過時には truncateEntrypointContent() が自動切り捨てする。この設計がなぜ重要かというと、MEMORY.md は毎回のターンでシステムプロンプトに注入されるため、肥大化するとコンテキスト全体が劣化するからだ。
2フェーズスキルロード
Chapter 12 が明かすスキルシステムの核心は「2フェーズロード」だ。
起動時は SKILL.md の frontmatter のみを読み込む。description フィールドを読んで「このスキルを今呼び出すべきか」を判断するためだ。スキルの本文(実際の指示内容)は呼び出された瞬間にはじめてロードされる。
何十個のスキルをインストールしていても、起動コストは frontmatter の合計サイズのみ——これが「スキルはただのフォルダ」という設計がトークン効率と両立できる理由だ。スキルの詳細な仕組みについてはClaude Skillsを徹底解説|スキルはフォルダ——Anthropicエンジニアが明かした仕組みと使い方を参照してほしい。
設計哲学の共通点:フォークエージェント・メモリ・スキルのすべてが「起動時のコストを最小化し、必要なときだけ展開する」という同じ原則に従っている。
7. パフォーマンス最適化の5次元と移植可能な10パターン
パフォーマンス最適化の5次元
Chapter 17 はパフォーマンス最適化を5つの次元に整理する。
次元1:起動時間
Claude Codeの起動は5フェーズのブートストラップパイプライン(Chapter 02)で実行される。モジュールレベルのI/O並列化により、設定ファイルの読み込み・ツール定義の組み立て・初期メモリロードが並行で走る。
次元2:文脈窓管理
主要なコンテキストバジェット定数:デフォルト出力キャップ8Kトークン(99%のリクエストで十分)、ヒット時エスカレーション64Kトークン、Autocompact発火閾値コンテキストウィンドウの95%、MEMORY.md上限200行・25,000バイト。
「スロットリザベーション」というパターンの実体がここにある——デフォルトで8Kを確保し、必要なときだけ64Kにエスカレーションすることで、99%のリクエストで文脈ウィンドウを節約する。
次元3:プロンプトキャッシュ安定性
前述のフォークエージェントに加えて、通常のリクエストでもキャッシュ安定性のための設計がある。スティッキーラッチ・ツール定義の順序固定・システムプロンプトの決定論的レンダリング——これらは単独では小さいが、組み合わさることで実質的なキャッシュヒット率を大幅に向上させる。
次元4:レンダリングパフォーマンス
Chapter 13 で解析されたターミナルUIはInkのカスタムフォークをベースにダブルバッファリングとオブジェクトプールを実装している。大量のツール結果や長い会話でもUIが滑らかに動くための設計だ。
次元5:検索最適化
Grep・Findツールの内部では、ファイルサイズ・優先度・並行安全性に基づく最適化が走る。大量ファイルのリポジトリでも検索が詰まらないよう、各種スロットリングが設定されている。
Claude Codeを実際の開発ワークフローで活用する方法についてはClaude Code開発者Thariqが語るエージェント設計の全貌も参照してほしい。
移植可能な10パターン
本書のREADMEは「他のすべてを読まなくてもこれだけ読め」として10のパターンをリストしている。これらはClaude Code固有でなく、任意のAIエージェントシステムに移植できる設計知識だ。
| # | パターン | 核心となる設計判断 |
|---|---|---|
| 1 | AsyncGeneratorとしてのエージェントループ | バックプレッシャー・型付きTerminal・自然なキャンセル |
| 2 | 投機的ツール実行 | ストリーミング中に読み取り専用ツールを開始 |
| 3 | 並行安全バッチ処理 | 安全性をツール型でなく呼び出し単位で判定 |
| 4 | フォークエージェントによるキャッシュ共有 | バイト同一プレフィックスで入力コストを最大95%削減 |
| 5 | 4層コンテキスト圧縮 | Snip → Microcompact → Collapse → Autocompact |
| 6 | LLMリコールによるファイルベースメモリ | キーワードでなくSonnetが関連性を判断 |
| 7 | 2フェーズスキルロード | 起動時はfrontmatterのみ、呼び出し時に本文をロード |
| 8 | キャッシュ安定性のためのスティッキーラッチ | 一度設定されたベータヘッダーはセッション中固定 |
| 9 | スロットリザベーション | 8K上限でデフォルト起動、ヒット時のみ64Kへ |
| 10 | フックの設定スナップショット | 起動時にフリーズして実行時注入攻撃を防ぐ |
各パターンが「なぜ必要か・何が破綻したときに生まれたか」という背景とともに解説されているのが本書の強みだ。
36エージェントが6時間で書き上げた制作プロセス
本書がどのように作られたかも、それ自体がエージェントアーキテクチャの実例だ。
制作は4フェーズで構成された。
Phase 1——探索(6並行エージェント):ソースツリー約2,000ファイルを6エージェントが並行スキャン。各エージェントが担当ファイル群のサマリーを生成した。
Phase 2——分析(12エージェント):494KBの生技術ドキュメントを作成。各エージェントが担当モジュール(クエリループ・ツール・状態管理・メモリ等)の詳細分析を行った。
Phase 3——執筆(15エージェント):Phase 2の分析を読んだエージェントたちが、ナラティブ形式の章としてゼロから書き直した。すべての擬似コードはこのフェーズで生成されたオリジナルだ。
Phase 4——レビューと改訂(3名の編集者 + 3名の改訂エージェント):3名の編集レビュアーが900行のフィードバックを生成し、3名の改訂エージェントがすべての修正を適用した。
全工程の所要時間:約6時間。
制作プロセス自体が設計パターンの実例:Phase 1-2の並行エージェントはパターン3(並行安全バッチ処理)。Phase 4の編集→改訂サイクルはコーディネータモード(Chapter 10)。本書は自分の設計した方法で書かれている。
- ・「claude-code-from-source」はnpmソースマップの`sourcesContent`を起点に、36エージェントが6時間で書き上げた18章・7部・印刷換算400ページの技術書だ(スター2,027)。
- ・6つの核心抽象(クエリループ・ツール・状態・タスク・フック・メモリ)がClaude Code全体の設計を支えている。
- ・エージェントループがAsyncGeneratorである理由はバックプレッシャー・型付きTerminal・自然なキャンセルの3点。
- ・partitionToolCalls()はフェイルクローズドで動作し、投機的実行と組み合わせて並行性能を最大化する。
- ・フォークエージェントはバイト同一プレフィックス保証によりプロンプトキャッシュのコストを最大95%削減する。
- ・本書が抽出した10パターンはClaude Code固有でなく、あらゆるAIエージェントシステムに移植可能な設計知識だ。