Claude Code(Anthropicのターミナル型AIコーディングエージェント)について、公式ドキュメントを一通り精読しながら整理した実践Tips集です。個人のtestAI開発・CTF学習環境に実際に組み込んだhook/skillの実装例も載せています。他のPC環境でも同じ設定を再現できるよう、コードはそのままコピペで使える形にしています。
- 検証時点のバージョン: Claude Code v2.1.207
- 主な出典:
code.claude.com/docs/en/配下の公式ドキュメント、Claude Code開発者(Boris Cherny氏)の公開投稿
補足: 調査の過程で参照したX上の日本語解説アカウントの一部には、自動生成コンテンツの特徴が見られました。そのため本記事では、コマンド名・ファイルパス等の技術的事実は公式ドキュメントと突き合わせて検証済みのもののみ採用し、数値主張や体験談の類は含めていません。
目次
1. モデル / コスト管理
利用枠(トークン/コスト)は「作業の重さに対してモデル・思考量を最適化できているか」で大きく変わります。(出典: code.claude.com/docs/en/costs)
モデルとeffortの使い分け
-
/model sonnetが主力(9割の作業で十分)。/model opusは複雑な設計判断のみ。subagentにはmodel: haikuを指定してさらに節約できる -
/effort low|medium|high|xhigh|max(初期値high)。定型作業はlow/medium、深い調査はxhigh、maxは一発勝負の難問のみで常用しない -
opusplanにすると計画はOpus・実行はSonnetに自動振り分けされる
使用量の可視化
-
/usage— セッションのトークン内訳をskills/subagents/plugins/MCPサーバー別に%表示。d/wキーで24時間/7日切替 -
/usage-credits— Pro/Maxプランで月次利用枠の上限を自分で設定可能 - ステータスラインに
context_window.used_percentageを常時表示すると一目で分かる(§8参照)
トークン削減策(公式ドキュメントが列挙する全項目)
-
/clearでタスクの切れ目ごとにリセット。/renameしてからclearすると後で/resumeしやすい -
/compact <指示>で圧縮内容を指定できる。CLAUDE.mdにも圧縮方針を書ける - MCPツール定義は既定で遅延読込。
gh/aws/gcloud等のCLIツールはMCPよりさらに軽量。/mcpで不要なサーバーを無効化 - 型付き言語ではcode intelligenceプラグインで「定義へジャンプ」を使い、grep+複数ファイル読込を節約
- hookで前処理してから渡す(§3のサンプル参照)
- 詳細instructionsはCLAUDE.mdでなくSkills化(オンデマンド読込)。CLAUDE.mdは200行未満が目安
- Extended thinkingの調整:
/effort、/configでthinking無効化、固定予算モデルはMAX_THINKING_TOKENS環境変数 - ログ処理・テスト実行はsubagentに委譲し要約だけ受け取る
- 曖昧な依頼(「コードベースを改善して」)は広範囲スキャンを誘発する。範囲を具体的に指定する
2. セッション運用
Explore → Plan → Implement → Commit
Plan modeで Ctrl+G を押すとプランをテキストエディタで直接編集できます。スコープが明確な小修正(typo等)はplan modeを使わず直接依頼して構いません。
コース修正
-
Esc— 即時停止(コンテキスト保持) -
Esc+Esc//rewind— チェックポイント復元。「Summarize from here / up to here」の選択あり - 同じ問題を2回訂正したら
/clearして学びを反映した初期プロンプトで仕切り直す方が速い
/goal — 完了条件を指定して自動継続(v2.1.139+)
毎ターン終了後、小型モデル(既定Haiku)が条件充足を判定し、満たされるまでターンを繰り返します。
/goal all tests in test/auth pass and the lint step is clean
/goal clear で解除。条件は最大4,000文字、「or stop after 20 turns」のように打ち切り条件を含められます。実体はセッションスコープのprompt-based Stop hookのラッパーです。
あまり知られていないコマンド
| コマンド | 用途 |
|---|---|
/btw <質問> |
会話履歴に残らない軽い質問 |
/advisor [model|off] |
重要な判断で別モデルに相談 |
/deep-research <question> |
複数ソース横断調査 |
/branch [name] |
会話を分岐して別方向を試す |
/batch <instruction> |
大規模変更を5〜30単位に並列分解 |
3. Hooks
特定のイベントで確実にコマンドを実行させる仕組みです。(出典: code.claude.com/docs/en/hooks-guide)
4つのtype
| type | 挙動 |
|---|---|
command |
シェルコマンドを実行(最も一般的) |
prompt |
小型モデル(既定Haiku)がyes/no判定。30秒タイムアウト |
agent |
subagentがファイル閲覧・コマンド実行しながら検証。最大50ターン、実験的で非推奨 |
http |
イベントJSONをPOSTしレスポンスで結果取得。チーム監査サービス連携向け |
I/O仕様: exit 0=無干渉、exit 2=ブロック(stderrがClaudeへのフィードバックになる)。複数hookが同一イベントに一致した場合は並列実行され、PreToolUse は最も制限的な結果が採用されます。
既知の罠:
.bashrc等に無条件のechoがあるとhookのJSON出力に混入してパースエラーになります。[[ $- == *i* ]]で対話シェル限定にする対策が公式推奨です。またjqが入っていない環境では、以下の例のようにpython3でJSON解析するのが安全です。
実用例1: .env / 秘密鍵の保護
.claude/hooks/protect-secrets.sh として保存し、PreToolUse + Edit|Write に登録します。
#!/bin/bash
# PreToolUse hook: block Edit/Write to files containing secrets.
input=$(cat)
file_path=$(echo "$input" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('file_path',''))" 2>/dev/null)
if [ -z "$file_path" ]; then
exit 0
fi
case "$file_path" in
*/.env|*/.env.*|*/certs/*.pem|*/secrets/*)
echo "Blocked: $file_path contains secrets/keys. Edit it manually if this is intentional." >&2
exit 2
;;
esac
exit 0
chmod +x で実行権限を付与し、プロジェクトの .claude/settings.json に登録します。
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/protect-secrets.sh"
}
]
}
]
}
}
実用例2: 危険コマンドの検知
グローバル設定(~/.claude/scripts/block-dangerous-commands.sh)に置き、PreToolUse + Bash に登録すると全プロジェクトに効きます。rm -rf ./work のような通常の作業は通し、破壊的なパターンだけをブロックする設計です。
#!/bin/bash
# PreToolUse+Bash hook: block classic destructive-command footguns.
input=$(cat)
cmd=$(echo "$input" | python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('tool_input',{}).get('command',''))" 2>/dev/null)
if [ -z "$cmd" ]; then
exit 0
fi
if echo "$cmd" | grep -qE '(^|[;&|]\s*)rm\s+(-[a-zA-Z]*r[a-zA-Z]*f[a-zA-Z]*|-[a-zA-Z]*f[a-zA-Z]*r[a-zA-Z]*)\s+(/|/\*|~|~/|\$HOME|/home|/home/[a-zA-Z_]+/?)\s*($|[;&|])'; then
echo "Blocked: destructive rm -rf against root/home. If this is really intended, run it manually." >&2
exit 2
fi
if echo "$cmd" | grep -qE '\bdd\b.*of=/dev/(sd|nvme|hd|xvd)'; then
echo "Blocked: dd writing directly to a disk device." >&2
exit 2
fi
if echo "$cmd" | grep -qE '\bmkfs(\.[a-z0-9]+)?\s+.*/dev/(sd|nvme|hd|xvd)'; then
echo "Blocked: mkfs against a disk device." >&2
exit 2
fi
if echo "$cmd" | grep -qE ':\(\)\s*\{\s*:\s*\|\s*:\s*&\s*\}\s*;\s*:'; then
echo "Blocked: fork bomb pattern." >&2
exit 2
fi
if echo "$cmd" | grep -qE 'chmod\s+(-R\s+)?777\s+/(\s|$)'; then
echo "Blocked: recursive chmod 777 on root." >&2
exit 2
fi
exit 0
登録は ~/.claude/settings.json の hooks.PreToolUse に同様の形で追加します。
組み込み保護との関係:
bypassPermissionsモードですらrm -rf /とrm -rf ~は「サーキットブレーカー」として必ずプロンプトが出ます(v2.1.126+)。このhookはdd/mkfs/フォークボム等、組み込みでは守られないパターンを補完するものです。
実用例3(公式サンプル): テスト出力の事前フィルタ
大量のログをそのまま読ませる代わりに、失敗行だけに絞り込んでコンテキストを節約します。
#!/bin/bash
input=$(cat)
cmd=$(echo "$input" | jq -r '.tool_input.command')
if [[ "$cmd" =~ ^(npm\ test|pytest|go\ test) ]]; then
filtered_cmd="$cmd 2>&1 | grep -A 5 -E '(FAIL|ERROR|error:)' | head -100"
echo "{\"hookSpecificOutput\":{\"hookEventName\":\"PreToolUse\",\"permissionDecision\":\"allow\",\"updatedInput\":{\"command\":\"$filtered_cmd\"}}}"
else
echo "{}"
fi
4. Skills
SKILL.md でClaudeに手順・制約・テンプレを教える仕組みです。agentskills.io のAgent Skills open standardに準拠しています。
3層設計
-
SKILL.md→ 役割と基本ルールだけ(500行以内) -
references/→ 知識・制約・品質基準を分離 -
scripts/→ 繰り返し処理のコード
「同じ指示を3回手打ちしたらSkills化」が実用的な目安です。
呼び出し制御
-
disable-model-invocation: true— ユーザーのみ呼出可(副作用のある操作向け) -
user-invocable: false— Claudeのみ呼出可、/メニュー非表示 -
context: fork+agent: <type>— subagent内で独立実行
バンドル済みSkills
/doctor /code-review /batch /debug /loop /claude-api に加え、v2.1.145+で /run(アプリ起動確認)・/verify(実行検証)・/run-skill-generator(起動手順を .claude/skills/run-<name>/ に記録)が使えます。
実装例: 起動手順スキルのテンプレート
/run-skill-generator は実際にアプリを起動して観察しながら記録する仕組みですが、重い起動処理(GPU処理やサーバー起動を伴うもの)を無断で実行させたくない場合は、起動スクリプトを読んで手動で書くこともできます。
---
name: run-myapp
description: Launch myapp and verify it's up. Use when asked to run, start, or check that myapp works end-to-end.
disable-model-invocation: true
---
# Running myapp
1. `cd /path/to/myapp && ./start.sh`
2. ヘルスチェック: `curl -sf http://localhost:PORT/health`
3. ログは `logs/app.log` を参照
(実際には起動せず、起動スクリプトの内容から手動で記述したもの。スクリプトが変わったら要更新)
5. Subagents
独立したコンテキストウィンドウで動く専門エージェントです。メインの会話を汚さずに探索・検証を任せられます。
組み込みsubagent
| 名前 | モデル | 用途 |
|---|---|---|
Explore |
親会話継承 | 読取専用探索。CLAUDE.md/git statusを読まず高速 |
Plan |
親会話継承 | plan mode専用リサーチ、読取専用 |
general-purpose |
親会話継承 | 全ツール使用可、探索+実装の複雑タスク |
claude-code-guide |
Haiku | Claude Code自体への質問対応 |
db-reader — 読み取り専用DBサブエージェント(公式サンプル)
SQLite/SQLの安全な分析に使えます。書き込み系SQLをhookでブロックします。
---
name: db-reader
description: Execute read-only database queries. Use when analyzing data or generating reports.
tools: Bash
hooks:
PreToolUse:
- matcher: "Bash"
hooks:
- type: command
command: "./scripts/validate-readonly-query.sh"
---
You are a database analyst with read-only access. Execute SELECT queries to answer questions about the data.
#!/bin/bash
# validate-readonly-query.sh
INPUT=$(cat)
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
if [ -z "$COMMAND" ]; then
exit 0
fi
if echo "$COMMAND" | grep -iE '\b(INSERT|UPDATE|DELETE|DROP|CREATE|ALTER|TRUNCATE|REPLACE|MERGE)\b' > /dev/null; then
echo "Blocked: Write operations not allowed. Use SELECT queries only." >&2
exit 2
fi
exit 0
fork vs named subagent
| 挙動 | |
|---|---|
/fork |
会話履歴を丸ごと継承。プロンプトキャッシュ共有で安い |
| named subagent | 毎回新規コンテキスト。独立した定型タスク向き |
永続記憶
frontmatterに memory: user|project|local を追加すると、セッションを跨いで学習内容を蓄積できます(MEMORY.md を自動注入)。nested subagentは深さ上限5です。
6. 並列実行
Git worktree
claude --worktree feature-auth # .claude/worktrees/feature-auth/ に新規作成
.worktreeinclude ファイル(.gitignore 構文)を置くと、.env のような未追跡ファイルを新規worktreeに自動コピーできます。Claude Code開発者いわく「同時に3〜5個のworktreeを立ち上げる」のがチーム最大の生産性向上策とのことです。
Agent teams(実験的機能)
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS=1 で有効化。複数の独立Claude Codeインスタンスが共有タスクリスト+メッセージングで協調します(subagentと違い相互に直接会話できる)。
コスト注意: plan modeのteammateがいる場合、通常セッションの約7倍のトークンを消費します。推奨チーム規模は3〜5人、1人あたり5〜6タスクです。
fan-out(大量ファイルの一括処理)
for file in $(cat files.txt); do
claude -p "Migrate $file from React to Vue. Return OK or FAIL." \
--allowedTools "Edit,Bash(git commit *)"
done
7. Permission modes
| モード | 確認なしで実行される範囲 |
|---|---|
default (Manual) |
読取のみ |
acceptEdits |
読取+ファイル編集+安全なファイル操作コマンド(mkdir/touch/rm/mv/cp/sed等) |
plan |
読取のみ、プラン作成に特化 |
auto |
全て、ただし分類器モデルが危険なものだけブロック |
dontAsk |
事前承認済みのみ(CI向け) |
bypassPermissions |
全てスキップ(コンテナ/VM専用) |
Protected paths(保護パス)
.claude・.git・.vscode・.gitconfig・.bashrc 等は「Protected path」に指定されており、bypassPermissions モード以外ではallowルールがあっても自動承認されません。.claude/settings.json を変更しようとすると毎回確認を求められるのは、この仕組みによるものです。
組み込みのサーキットブレーカー
bypassPermissions モードですら rm -rf / と rm -rf ~ は必ずプロンプトが出ます(v2.1.126+)。auto modeの分類器はさらに広く、curl | bash・force push・git reset --hard・terraform destroy 等もデフォルトでブロックする一方、作業ディレクトリ内のファイル操作や .env 読み取り+対応APIへの送信は許可されます。
8. 実装例まとめ
個人のtestAI開発・CTF学習環境に実際に組み込んだもの(§3・§4のコードそのもの)です。
| 実装 | 登録場所 | 効果 |
|---|---|---|
.env/秘密鍵保護hook |
プロジェクトの .claude/settings.json(PreToolUse) |
.env・鍵ファイルへの編集をブロック |
| 危険コマンド検知hook | グローバル ~/.claude/settings.json(PreToolUse) |
rm -rf / 系・disk直書き・フォークボム等をブロック |
| ステータスライン | グローバル ~/.claude/settings.json
|
モデル名・コンテキスト使用率・レート制限使用率を常時表示 |
ステータスラインの実装例
jq が入っていない環境向けに python3 で実装しています。
#!/bin/bash
INPUT=$(cat)
echo "$INPUT" | python3 -c '
import json, sys
try:
data = json.load(sys.stdin)
except Exception:
print("")
sys.exit(0)
model = data.get("model", {}).get("display_name", "?")
ctx = data.get("context_window") or {}
pct = ctx.get("used_percentage")
if pct is None:
ctx_str = "ctx: -"
else:
pct = int(pct)
filled = pct // 10
bar = "▓" * filled + "░" * (10 - filled)
ctx_str = f"{bar} {pct}%"
rl = data.get("rate_limits") or {}
five_h = (rl.get("five_hour") or {}).get("used_percentage")
seven_d = (rl.get("seven_day") or {}).get("used_percentage")
rl_parts = []
if five_h is not None:
rl_parts.append(f"5h:{int(five_h)}%")
if seven_d is not None:
rl_parts.append(f"7d:{int(seven_d)}%")
rl_str = " ".join(rl_parts)
parts = [f"[{model}]", ctx_str]
if rl_str:
parts.append(rl_str)
print(" ".join(parts))
'
~/.claude/settings.json に以下を追加すると有効になります。
{
"statusLine": {
"type": "command",
"command": "bash ~/.claude/scripts/statusline.sh"
}
}
本記事の内容は2026年7月時点のClaude Code(v2.1.207)公式ドキュメントを元にしています。バージョンアップにより仕様が変わる可能性があるので、最新情報は 公式ドキュメント を参照してください。