これは何のためのツールか
learn-coding-agent は、AIコーディングアシスタント(Claude Code)がどういう仕組みで動いているかを学ぶための学習用リポジトリです。
「AIがコードを書いてくれる仕組みが気になる」「自分でAIエージェント(AIが自律的に作業するシステム)を作りたい」という方向けに、Claude Codeの内部設計をドキュメント化しています。プログラミング経験を問わず、「なるほど、こういう構造になっているのか」という理解が得られます。
こんな時に役立つ
- 「AIがコードを書く仕組み」を理解したい → コアループ(基本の繰り返し処理)から学べる
- 自分でAIエージェントを作りたい → 権限管理・マルチエージェントの設計パターンを参考にできる
- 会社でClaude Codeを導入検討している → セキュリティの仕組み(権限チェック)を事前に把握できる
- AI開発の「プロダクションレベル」を知りたい → 実験的なコードと本番コードの違いがわかる
まず試してみる
リポジトリを見るだけで始められます。インストール不要です。
# リポジトリをクローン(手元にコピー)してドキュメントを読む
git clone https://github.com/sanbuphy/learn-coding-agent
cd learn-coding-agent
# 日本語ドキュメントを確認
cat README_JA.md
Claude Code の自動モードについての詳細はこちらも参考になります。
ドキュメントを読んだら、以下の順番で理解を深めていきましょう。この記事もその順番で解説しています。
- コアループ(基本の仕組み) → AIと会話しながらツールを使う繰り返し処理
- 権限管理 → AIが勝手に何かしないよう制御する仕組み
- マルチエージェント → 複数のAIが協力して大きな仕事をこなす仕組み
- コンテキスト圧縮 → 長時間動かすための工夫
ステップ1:コアループとは何か
AIエージェントの心臓部は、意外とシンプルです。「聞く → 考える → 行動する」を繰り返すだけです。
// シンプルなエージェントの動き(疑似コード)
while (true) { // ← ずっと繰り返す(ループ=同じ処理を繰り返すこと)
// Step 1: AIにメッセージを送る
const response = await claudeAPI.post('/v1/messages', {
messages: messages, // ← これまでの会話の記録(会話履歴)
tools: toolDefinitions, // ← AIが使えるツール(ファイル読み書き、コマンド実行など)
model: 'claude-3-5-sonnet-20241022'
});
// Step 2: AIの返答を確認する
if (response.stop_reason === 'tool_use') {
// 「ツールを使いたい」という返答の場合 → ツールを実行する
for (const toolUse of response.content) {
const result = await executor.executeTool(
toolUse.name, // ← ツールの名前(例:「ファイルを読む」「コマンドを実行する」)
toolUse.input // ← ツールへの入力(例:「src/main.ts を読む」)
);
// ツールの実行結果をAIに返す(AIはこの結果を見て次の行動を決める)
messages.push({
type: 'tool_result',
tool_use_id: toolUse.id,
content: result
});
}
// ループを続けて、またAIに聞く(AIはツール結果を踏まえて考え直す)
} else {
// 「答えが出た」という返答の場合 → ループを終了して結果を返す
return response.content[0].text;
}
}
このコードのポイントは while (true) の無限ループです。AIが「まだツールを使いたい」と言っている間はループを続け、「答えが出た」と言ったらループを終了します。
人間に例えると、「調べ物をしながら考える」感覚に近いです。本を開いて読み → また考えて → 別の本を開いて → また考えて… という繰り返しです。
ステップ2:権限管理 ─ AIを安全に動かす仕組み
AIがファイル削除やターミナルコマンド(パソコンに命令を送る操作)を実行できる場合、「勝手に何かしてしまわないか」が心配になります。そのために多層的な権限チェックがあります。
// 権限チェックの流れ(4段階のチェックを順番に通過する)
async function canUseTool(toolName: string, input: unknown): Promise<boolean> {
// 【段階1】入力が正しい形式かチェック(不正な入力を早めに弾く)
try {
tool.validateInput(input);
} catch (e) {
console.error(`不正な入力: ${toolName}`, e);
return false; // ← 不正な入力は実行しない
}
// 【段階2】Pre-Tool-Useフック(フック=事前に実行する追加処理のこと)
// settings.json で「このツールを使う前にこのスクリプトを実行する」と設定できる
// 例:ログを取る、社内の承認システムに問い合わせる、など
if (settings.hooks?.preToolUse) {
const hookResult = await executeHook(settings.hooks.preToolUse);
if (hookResult.action === 'deny') return false; // フックが「禁止」と判断
if (hookResult.action === 'modify') input = hookResult.modifiedInput; // フックが入力を書き換え
}
// 【段階3】設定ファイルのルール確認
// alwaysAllow(常に許可)→ alwaysDeny(常に拒否)→ alwaysAsk(毎回確認)の順で判定
const rule = matchPermissionRule(toolName, input, settings.permissions);
if (rule?.action === 'allow') return true; // ← ルールで「許可」なら即OK
if (rule?.action === 'deny') return false; // ← ルールで「拒否」なら即NG
// 【段階4】ルールに当てはまらない場合はユーザーに確認(ポップアップ表示)
const userApproval = await promptUser(`「${toolName}」を実行してもよいですか?`);
if (userApproval.type === 'allowOnce') return true; // 今回だけ許可
if (userApproval.type === 'allowAlways') {
settings.permissions.alwaysAllowRules.push(rule); // 今後は自動許可(ルールに追加)
return true;
}
return false; // ユーザーが拒否
}
この設計の便利な点は、環境によって動作を変えられることです。
// settings.json の設定例(これだけでCIとデスクトップの動作を切り替えられる)
{
"permissions": {
"alwaysAllowRules": [
"Bash(npm test)", // npm test コマンドは確認なしで常に許可
"Bash(git status)" // git status も常に許可(状態確認だけなので安全)
],
"alwaysDenyRules": [
"Bash(rm -rf *)" // ファイルの全削除コマンドは絶対に禁止
]
}
}
- CI/CD環境(自動テスト・自動デプロイ):
alwaysAllowでコマンドを自動許可 → 人が介在せずに動く - 個人のPC: 危険な操作の前にポップアップで確認 → 誤操作を防げる
ステップ3:マルチエージェント ─ AIがチームで働く仕組み
大きなタスク(例:「このリポジトリ全体をリファクタリングして」)を1つのAIに頼むと、会話の記録(コンテキスト=文脈・背景情報)がすぐにいっぱいになってしまいます。そこで複数のサブエージェント(小さな専門AI)に仕事を分担させる仕組みがあります。
// サブエージェント(専門担当のAI)を生成して別のタスクを任せる
async function forkSubagent(options: {
goal: string; // サブエージェントに何をやらせるか(例:「テストを書いて」)
context?: string; // 必要な背景情報(例:「このファイルはReactコンポーネントです」)
spawnMode?: 'default' | 'fork' | 'worktree'; // 起動モード(後述)
}): Promise<SubagentResult> {
// 新しい会話記録を作成(親エージェントの会話とは独立させる)
// 人間で言えば「新しいチャット画面を開いて別の人に頼む」イメージ
const subagentMessages: Message[] = [
{
type: 'user',
content: `あなたは専門のサブエージェントです。\n目標: ${options.goal}\n背景: ${options.context}`
}
];
// spawnMode(起動モード)によって処理方法を変える
if (options.spawnMode === 'fork') {
// fork = 子プロセス(別プログラム)として起動
// ファイルの読み込みキャッシュ(一時保存)だけ親と共有して効率化
// → CPU処理が重いタスクに向いている
const childProcess = await fork('./query.ts', {
messages: subagentMessages,
sharedFileCache: parentFileCache // ← ファイルキャッシュは親子で共有(毎回ファイルを読み直さずに済む)
});
return await childProcess.run();
} else if (options.spawnMode === 'worktree') {
// worktree = git worktree(独立したフォルダ)で実行
// ファイルの読み書きが多いタスク(リファクタリングなど)に向いている
// 独立したフォルダなのでメインのコードに影響を与えない
const worktreeDir = await createWorktree(); // ← 独立したフォルダを作成
return await runAgentInWorktree(worktreeDir, subagentMessages);
} else {
// default = 同じプロセス内で実行(一番シンプル)
// 軽量タスク・短時間で終わるタスクに向いている
return await queryEngine.submitMessage(options.goal);
}
}
3つの起動モード(spawnMode)をまとめると:
| モード | 処理場所 | 向いているタスク |
|---|---|---|
default |
同じプロセス内 | 軽量・シンプルなタスク |
fork |
別の子プロセス | CPU処理が重いタスク |
worktree |
独立したディレクトリ | ファイルの読み書きが多いタスク |
OpenHands など他のAIコーディングツールも同様のマルチエージェント設計を採用しています。
ステップ4:コンテキスト圧縮 ─ 長時間動かすための工夫
コンテキスト(=AIが一度に覚えられる情報量)には上限があります。Claude 3.5 Sonnetでは最大約20万トークン(日本語で約15万文字相当)ですが、長時間動かすとすぐにいっぱいになります。
// コンテキスト(会話記録)が満杯になりそうなとき、古い会話を要約して圧縮する
async function manageContextWindow(messages: Message[]): Promise<Message[]> {
const tokenCount = estimateTokens(messages); // ← 現在のトークン数を概算
const maxTokens = 200000; // ← Claude 3.5 Sonnetの上限(約20万トークン)
// 上限の80%を超えたら圧縮開始(余裕を持って早めに対処する)
if (tokenCount > maxTokens * 0.8) {
const past = messages.slice(0, -20); // ← 古い会話(最後の20件より前をすべて取り出す)
const recent = messages.slice(-20); // ← 直近20件の会話(重要なので保持する)
// 古い会話をAIに要約してもらう(「長い本の要約を作ってもらう」イメージ)
const summary = await claude.messages.create({
model: 'claude-3-5-sonnet-20241022',
max_tokens: 2000,
system: '会話の歴史を数文で要約してください。重要な情報は残してください。',
messages: [{ role: 'user', content: `要約してください:\n${JSON.stringify(past)}` }]
});
// 圧縮後のメッセージ配列を作成:直近の会話 + 古い会話の要約
return [
...recent, // ← 直近20件はそのまま
{
type: 'system',
subtype: 'compact_boundary', // ← 「ここから先は要約」というマーカー(目印)
content: `[要約]\n${summary.content[0].text}\n[要約終わり]`
}
];
}
return messages; // 問題なければそのまま返す
}
この仕組みにより、何時間も動き続けるエージェント(例:夜間バッチ処理、継続的な監視ボット)が実現できます。
全体の仕組み:処理の流れを図で確認
ここまで解説したコアループ・権限管理・ツール実行が、どのように連携しているかを図にまとめます。
入力を処理"] B --> C["コマンドを
パース(解析)"] C --> D["システムプロンプト
+ツール定義を準備"] D --> E["CLAUDE.md・権限ルール
を読み込む"] E --> F["メッセージを
整形する"] F --> G["☁️ Claude API
に送信(ストリーミング)"] G --> H{"stop_reason
をチェック"} H -->|"tool_use
ツールを使いたい"| I["StreamingToolExecutor
ツール実行器"] H -->|"end_turn
答えが出た"| J["✅ 最終メッセージを
ユーザーに返す"] I --> K["canUseTool
権限チェック(4段階)"] K --> L{"許可?
拒否?"} L -->|"✅ 許可"| M["tool.call
ツールを実行"] L -->|"❌ 拒否"| N["エラーを
AIに返す"] M --> O["結果を記録"] N --> O O --> P["会話記録に追加
(次のループへ)"] P --> G J --> Q["💾 セッションを
保存(復帰用)"]
他のツール・フレームワークとの比較
Claude Codeのアーキテクチャを他の選択肢と比較します。「自分でAIエージェントを作るとしたら、何を一から実装しなければならないか」がわかります。
| 項目 | Claude Code | 自前実装 | LangChain AgentExecutor | AutoGPT |
|---|---|---|---|---|
| ベースモデル | Claude 3.5 Sonnet | 自由に選べる | 自由に選べる | GPT-4系 |
| 権限チェック | 多層構造(フック+ルール+UI) | 自分で実装が必要 | 基本的なラッパーのみ | ほぼなし |
| マルチエージェント | fork/worktree など複数パターン | 自分で実装が必要 | ReActパターンのみ | 簡易的 |
| コンテキスト圧縮 | 自動(要約+切り取り) | 自分で実装が必要 | 要実装 | なし |
| 長時間稼働 | クラッシュ復旧・セッション保存あり | なし | なし | なし |
| 外部ツール連携 | MCPプロトコル対応 | なし | 独自プロトコル | なし |
| 設定ファイルで制御 | settings.json+CLI | コード内に直書き | コード内に直書き | なし |
表からわかるように、Claude Codeは「プロダクション安全性」と「長時間稼働」に特化した設計です。自前で同等のシステムを作る場合は、権限管理・コンテキスト圧縮・セッション復帰をすべて自分で実装する必要があります。
外部ツールとの連携:MCPプロトコル
MCP(Model Context Protocol=AIが外部ツールを使うための統一規格)は、Anthropicが策定したプロトコルです。
// settings.json:MCPサーバーの接続設定例
// MCPサーバー=AIと外部ツールをつなぐ橋渡し役のプログラム
{
"mcpServers": {
"filesystem": {
"command": "node",
"args": ["./mcp-servers/filesystem.js"],
"type": "stdio" // stdio=標準入出力を使う方式(ローカルで動くサーバー向け)
},
"github": {
"url": "https://mcp-server.example.com/github",
"type": "sse", // SSE=Server-Sent Events(サーバーからのリアルタイム通知)
"auth": "oauth2" // OAuth2=認証の仕組み(ログインに使われる方式)
},
"websocket_tool": {
"url": "ws://localhost:8080",
"type": "ws" // ws=WebSocket(双方向リアルタイム通信)
}
}
}
MCPサーバーを追加すると、AIが使えるツールが自動的に増えます。命名規則は mcp__サーバー名__ツール名(例:mcp__github__create_issue)です。MCPツールの活用については、MCPツールの管理方法の解説記事も参考にしてください。
まとめ
learn-coding-agent リポジトリが公開する Claude Code のアーキテクチャは、AI エージェント開発の教科書として機能します。
- コアループ:「AIに聞く → ツール実行 → 結果を返す」のシンプルな繰り返し
- 権限管理(4段階):入力チェック → フック → ルール → ユーザー確認、で安全性を担保
- マルチエージェント:大きなタスクを複数のAIで分担して効率化
- コンテキスト圧縮:古い会話を要約して長時間稼働を実現
AIエージェントが実験的なツールから実運用システムへと移行する中で、このような設計パターンの理解はますます重要になっています。まずはリポジトリのドキュメントを読むところから始めてみてください。
参照ソース
- learn-coding-agent - GitHub(日本語README)
- Model Context Protocol(MCP)公式ドキュメント — AIの外部ツール連携プロトコルの仕様
- Anthropic Claude API リファレンス — Claude APIの公式ドキュメント