最終確認: 2026年5月
ターミナルから CCA-F 試験のトピックを実践 — Claude Code CLI コマンド、Anthropic API 呼び出し、MCP サーバー、マルチエージェントパターンを試験ドメインに紐付けて学習。
このラボの終わりまでに、Claude Code をインストールし、CLAUDE.md を使ってプロジェクトを設定し、カスタムスラッシュコマンドを構築し、MCP サーバーを接続し、構造化された出力で tool-use API を実行し、extended thinking を探索し、マルチエージェントのスーパーバイザーパイプラインを構築します。これにより、ターミナルから CCA-F 試験の5つのドメインすべてをカバーできます。クラウドアカウントや課金は不要です。すべてローカルで実行されます。
node --version)ANTHROPIC_API_KEY として設定されていること (export ANTHROPIC_API_KEY=sk-ant-...)mkdir cca-f-lab && cd cca-f-lab)Anthropic への API 呼び出しには、使用量に応じた料金が発生します。ステップ6~8および10では claude-sonnet-4-6 を使用し、入力トークンあたり約3ドル/M、出力トークンあたり約15ドル/Mの費用がかかります。このラボの総費用は通常0.15ドル未満です。Extended thinking (ステップ7) では、追加の thinking トークンが出力レートで課金されます。
Claude Code は、CCA-F 試験で最も直接的にテストされる CLI です。設定、hooks、slash commands、permission modes のすべてがここにあります。後のすべてのステップで claude を呼び出せるように、まずグローバルにインストールします。
インストール後、簡単な claude --version でバイナリが PATH 上にあることを確認し、claude --print-system-prompt で API キーが有効であることを確認します(内部で軽量な呼び出しを行います)。
# Install Claude Code globally
npm install -g @anthropic-ai/claude-code
# Verify installation
claude --version
# Confirm API connectivity (prints the built-in system prompt)
claude --print-system-prompt | head -20試験では、3層の CLAUDE.md 階層が重点的にテストされます。ユーザー (~/.claude/CLAUDE.md)、プロジェクト (リポジトリルート)、モジュール (サブディレクトリ) です。各レベルは上位から継承され、上書きすることができます。
今回は、コーディング規約を設定するプロジェクトレベルのファイルと、個人的な好みを設定するユーザーレベルのファイルを作成します。Claude Code がプロジェクトを読み込む際、これら3つの層をすべてマージします。これは試験で問われる動作そのものです。
# Create project root CLAUDE.md
cat > CLAUDE.md << 'EOF'
# Project: CCA-F Lab
## Coding conventions
- Use TypeScript for all new files
- Prefer const over let
- Use single quotes for strings
- No semicolons (Prettier default)
## Testing
- Run `npm test` before committing
- All new functions must have at least one test
EOF
# Create user-level CLAUDE.md (applies to ALL your projects)
mkdir -p ~/.claude
cat > ~/.claude/CLAUDE.md << 'EOF'
# User preferences
- Be concise in responses
- Prefer functional programming patterns
- Always explain the "why" before showing code
EOF
# Verify Claude Code sees both files
claude "What instructions do you see in CLAUDE.md?" --printカスタムスラッシュコマンドは、Markdown ファイルとして .claude/commands/ 内に存在します。ファイル名がコマンド名になります(例:scaffold.md → /scaffold)。ファイルの内容はプロンプトテンプレートであり、ユーザー入力用の $ARGUMENTS を含めることができます。
これは試験で頻繁に出題されるトピックです。コマンドがどこに存在するか、引数がどのように渡されるか、そして hooks とどのように異なるか、などです。
# Create the commands directory
mkdir -p .claude/commands
# Create a scaffold command
cat > .claude/commands/scaffold.md << 'EOF'
Create a new TypeScript module named $ARGUMENTS with:
1. A main source file at src/$ARGUMENTS/index.ts
2. A test file at src/$ARGUMENTS/__tests__/index.test.ts
3. Export the module from the project root index.ts
Follow the coding conventions in CLAUDE.md.
EOF
# Test the command (Claude Code will execute it interactively)
claude /scaffold calculatorHooks は、Claude Code イベントに応じてシェルコマンドを実行します。試験では、PreToolUse (ツール実行前)、PostToolUse (ツール実行後)、および Notification (ステータス変更時) の3種類の hook がテストされます。Hooks は .claude/settings.json で定義されます。
私たちは、ファイル編集後にリンターを実行する PostToolUse hook を追加します。これは、試験で頻繁に問われる一般的な本番環境のパターンです。
# Initialize a package.json so we have a lint script
npm init -y
npm install --save-dev typescript @typescript-eslint/parser
# Create project-level settings with a post-tool hook
mkdir -p .claude
cat > .claude/settings.json << 'EOF'
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"command": "npx tsc --noEmit 2>&1 | head -5"
}
]
},
"permissions": {
"allow": [
"Read",
"Write",
"Edit"
]
}
}
EOF
# Verify settings are recognized
cat .claude/settings.jsonModel Context Protocol (MCP) は、試験の主要ドメインです。MCP サーバーは、標準化された JSON-RPC プロトコルを介して LLM クライアントに tools、resources、prompts を公開します。stdio トランスポートは最もシンプルで、サーバーは stdin から読み込み、stdout に書き込みます。
私たちは、get_weather ツールを公開する最小限の MCP サーバーを構築し、Claude Code をそれに接続するように設定します。これにより、試験でテストされる MCP の完全なライフサイクル(tool の定義、transport の接続、tool の呼び出し、結果の処理)を実践します。
# Install the MCP SDK
npm install @modelcontextprotocol/sdk
# Create the MCP server
cat > mcp-weather.mjs << 'EOF'
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({ name: "weather", version: "1.0.0" });
server.tool("get_weather", { city: { type: "string" } }, async ({ city }) => ({
content: [{ type: "text", text: `Weather in ${city}: 72°F, sunny` }],
}));
const transport = new StdioServerTransport();
await server.connect(transport);
EOF
# Register the MCP server in Claude Code settings
cat > .claude/settings.json << 'EOF'
{
"mcpServers": {
"weather": {
"command": "node",
"args": ["mcp-weather.mjs"]
}
}
}
EOF
# Ask Claude Code to use the MCP tool
claude "What is the weather in Tokyo? Use the get_weather tool."試験では、Messages API の tool-use フローが詳細にテストされます。リクエストで tools を送信し、モデルは tool_use コンテンツブロックで応答し、それを実行して tool_result を返し、その後モデルが最終的な回答を生成します。
このステップでは、curl を使用して API を直接呼び出します。これは、試験が SDK ラッパーではなく、生のリクエスト/レスポンス形式をテストするため、試験に最も合致したアプローチです。
# Call the Messages API with a tool definition
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 1024,
"tools": [{
"name": "calculate",
"description": "Evaluate a math expression",
"input_schema": {
"type": "object",
"properties": {
"expression": { "type": "string", "description": "Math expression to evaluate" }
},
"required": ["expression"]
}
}],
"messages": [{
"role": "user",
"content": "What is 15% tip on a $85.50 dinner bill?"
}]
}' | python3 -m json.toolExtended thinking は、モデルが thinking ブロックを使用して、応答する前に段階的に推論することを可能にします。試験では、いつそれを使用すべきか(複雑な推論、数学、コード生成)、および budget_tokens をどのように設定するかをテストします。
私たちは意図的に複雑な論理パズルを送信し、extended thinking を使用した場合と使用しない場合の応答を比較して、品質の違いを直接確認します。
# Request WITH extended thinking
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 16000,
"thinking": {
"type": "enabled",
"budget_tokens": 10000
},
"messages": [{
"role": "user",
"content": "A farmer has 17 sheep. All but 9 run away. How many does he have left? Explain your reasoning step by step."
}]
}' | python3 -m json.tool
# The response includes a "thinking" block showing the model's
# internal reasoning before the final answer.プロンプトキャッシングにより、リクエストの一部をキャッシュ可能としてマークできます。キャッシュされたプレフィックスは、後続の呼び出しで90%安くなり、追加のレイテンシーはゼロです。試験では、cache_control ブロックの配置と、キャッシュヒットヘッダーがテストされます。
私たちは同じ大きなシステムプロンプトを2回送信し、応答ヘッダーをチェックして、2回目の呼び出しでキャッシュがヒットしたことを確認します。
# First call — creates the cache entry
curl -s -D /dev/stderr https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"system": [{
"type": "text",
"text": "You are a helpful assistant specialized in cloud architecture. You follow AWS Well-Architected Framework principles. You always recommend infrastructure as code. You prefer Terraform over CloudFormation. You prioritize security and cost optimization.",
"cache_control": { "type": "ephemeral" }
}],
"messages": [{ "role": "user", "content": "How should I set up VPC peering?" }]
}' > /dev/null 2>&1
# Second call — should hit the cache (check usage.cache_read_input_tokens)
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "content-type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"max_tokens": 256,
"system": [{
"type": "text",
"text": "You are a helpful assistant specialized in cloud architecture. You follow AWS Well-Architected Framework principles. You always recommend infrastructure as code. You prefer Terraform over CloudFormation. You prioritize security and cost optimization.",
"cache_control": { "type": "ephemeral" }
}],
"messages": [{ "role": "user", "content": "What about NAT gateway sizing?" }]
}' | python3 -c "import sys,json; d=json.load(sys.stdin); print(f\"Cache read tokens: {d['usage'].get('cache_read_input_tokens', 0)}\")"試験では、Claude Code を非対話的に実行する方法がテストされます。--print フラグは対話セッションなしで結果を stdout に出力し、--output-format json はスクリプト処理用の構造化された出力を提供します。
これは CI パイプラインで使用されるパターンです。プロンプトを与え、結果を取得し、それをプログラムで解析します。
# Headless mode: prompt in, text out
claude --print "List 3 TypeScript best practices, one per line"
# JSON output for programmatic use
claude --print --output-format json "What is 2+2?"
# Pipe a file for code review (CI pattern)
echo 'const x: any = "hello";' > example.ts
claude --print "Review this TypeScript file for type safety issues: $(cat example.ts)"ドメイン1(Agentic Architecture、27%)は、試験で最も高いウェイトを占めています。スーパーバイザーパターン(1つのオーケストレーターが、それぞれ独自のシステムプロンプトとツールセットを持つ専門サブエージェントにタスクをディスパッチする)は、最も頻繁にテストされるアーキテクチャです。
私たちは、2つの専門エージェントを調整するスーパーバイザーを実装する自己完結型の Node.js スクリプトを構築します。1つはファイルを読み込み要約するリサーチャー、もう1つは出力を生成するライターです。スーパーバイザーはタスクを分解し、個別の API 呼び出しを介して各専門エージェントに委任し、結果を集約します。ターミナルから実行して、委任がリアルタイムでどのように行われるかを確認しましょう。
# Install the Anthropic SDK
npm install @anthropic-ai/sdk
# Create sample data for the agents to work with
cat > sales-data.csv << 'EOF'
month,revenue,units
Jan,12500,150
Feb,15200,180
Mar,11800,140
Apr,18900,220
May,22100,260
Jun,19500,230
EOF
# Create the multi-agent supervisor script
cat > supervisor.mjs << 'SCRIPT'
import Anthropic from "@anthropic-ai/sdk";
import { readFileSync } from "fs";
const client = new Anthropic();
async function callAgent(role, systemPrompt, userMessage) {
console.log(`\n--- ${role} agent ---`);
const response = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
system: systemPrompt,
messages: [{ role: "user", content: userMessage }],
});
const text = response.content
.filter((b) => b.type === "text")
.map((b) => b.text)
.join("\n");
console.log(text);
return text;
}
// --- Supervisor: decompose, delegate, aggregate ---
const data = readFileSync("sales-data.csv", "utf-8");
console.log("=== SUPERVISOR: Decomposing task ===");
console.log("Task: Analyze sales data and write a brief executive summary.\n");
console.log("Step 1: Delegate analysis to Researcher agent");
console.log("Step 2: Delegate writing to Writer agent");
console.log("Step 3: Combine results\n");
// Sub-agent 1: Researcher — extracts insights
const analysis = await callAgent(
"Researcher",
"You are a data analyst. Extract key trends, highs, lows, and growth rates. Be precise with numbers. Output bullet points only.",
`Analyze this CSV data:\n\n${data}`
);
// Sub-agent 2: Writer — produces the summary from the analysis
const summary = await callAgent(
"Writer",
"You are a business writer. Write a 3-sentence executive summary from the analysis provided. Use a professional tone. Include specific numbers.",
`Write an executive summary based on these findings:\n\n${analysis}`
);
console.log("\n=== SUPERVISOR: Final aggregated output ===");
console.log(summary);
SCRIPT
# Run the supervisor
node supervisor.mjsこのラボは完全にローカルで実行されるため、クラウドのリソースを破棄する必要はありません。
# Remove the lab directory
cd .. && rm -rf cca-f-lab
# Optionally remove the user-level CLAUDE.md we created
rm -f ~/.claude/CLAUDE.md
# Optionally uninstall Claude Code
npm uninstall -g @anthropic-ai/claude-code
このラボは、実践的な CLI および API の演習に焦点を当てています。以下の内容は含まれません。