Dernière révision : mai 2026
Exercez-vous sur les sujets de l'examen CCA-F depuis votre terminal — commandes Claude Code CLI, appels API Anthropic, serveurs MCP et patterns multi-agents, chacun lié à un domaine d'examen.
À la fin de ce labo, vous aurez installé Claude Code, configuré un projet avec CLAUDE.md, créé une commande slash personnalisée, connecté un serveur MCP, utilisé l'API tool_use avec une sortie structurée, exploré la pensée étendue (extended thinking), et construit un pipeline de supervision multi-agents — couvrant les cinq domaines d'examen du CCA-F depuis votre terminal. Aucun compte cloud ni facturation requis ; tout s'exécute localement.
node --version)ANTHROPIC_API_KEY dans votre shell (export ANTHROPIC_API_KEY=sk-ant-...)mkdir cca-f-lab && cd cca-f-lab)Les appels API à Anthropic entraînent des frais basés sur l'utilisation. Les étapes 6 à 8 et 10 utilisent claude-sonnet-4-6 qui coûte environ 3 $/M tokens d'entrée et 15 $/M tokens de sortie. Le coût total de ce labo est généralement inférieur à 0,15 $. La pensée étendue (Extended Thinking) (Étape 7) utilise des tokens de réflexion supplémentaires facturés au tarif des tokens de sortie.
Claude Code est l'interface CLI que l'examen CCA-F teste le plus directement — la configuration, les hooks, les commandes slash et les modes de permission se trouvent tous ici. Nous commençons par l'installer globalement afin que chaque étape ultérieure puisse appeler claude.
Après l'installation, un rapide claude --version prouve que le binaire est dans votre PATH, et claude --print-system-prompt confirme que la clé API est valide (il effectue un appel léger en arrière-plan).
# 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 -20L'examen teste en profondeur la hiérarchie à trois niveaux de CLAUDE.md : utilisateur (~/.claude/CLAUDE.md), projet (racine du dépôt) et module (sous-répertoires). Chaque niveau hérite du niveau supérieur et peut le remplacer.
Nous allons créer un fichier au niveau du projet qui définit les conventions de codage et un fichier au niveau de l'utilisateur qui définit les préférences personnelles. Lorsque Claude Code lit le projet, il fusionne les trois niveaux — exactement le comportement sur lequel l'examen porte.
# 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?" --printLes commandes slash personnalisées résident dans .claude/commands/ sous forme de fichiers Markdown. Le nom du fichier devient le nom de la commande (par exemple, scaffold.md → /scaffold). Le contenu du fichier est le modèle d'invite — il peut inclure $ARGUMENTS pour la saisie de l'utilisateur.
C'est un sujet d'examen très fréquent : où résident les commandes, comment les arguments sont passés et comment elles diffèrent des 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 calculatorLes hooks exécutent des commandes shell en réponse aux événements de Claude Code. L'examen teste trois types de hooks : PreToolUse (avant l'exécution d'un outil), PostToolUse (après) et Notification (lors des changements de statut). Les hooks sont définis dans .claude/settings.json.
Nous allons ajouter un hook PostToolUse qui exécute un linter après chaque modification de fichier — un modèle de production courant sur lequel l'examen pose fréquemment des questions.
# 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.jsonLe protocole de contexte de modèle (MCP) est un domaine d'examen fondamental. Les serveurs MCP exposent des outils, des ressources et des invites aux clients LLM via un protocole JSON-RPC standardisé. Le transport stdio est le plus simple — le serveur lit depuis l'entrée standard (stdin) et écrit vers la sortie standard (stdout).
Nous allons construire un serveur MCP minimal qui expose un outil get_weather, puis configurer Claude Code pour s'y connecter. Cela met en œuvre le cycle de vie complet du MCP testé par l'examen : définition de l'outil, câblage du transport, invocation de l'outil et gestion des résultats.
# 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."L'examen teste en détail le flux d'utilisation d'outils de l'API Messages : vous envoyez des tools dans la requête, le modèle répond avec un bloc de contenu tool_use, vous l'exécutez et renvoyez un tool_result, puis le modèle produit la réponse finale.
Cette étape utilise curl pour appeler directement l'API — l'approche la plus conforme à l'examen, car celui-ci teste le format de requête/réponse brut, et non les wrappers 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.toolLa pensée étendue (extended thinking) permet au modèle d'utiliser un bloc thinking pour raisonner étape par étape avant de répondre. L'examen teste quand l'utiliser (raisonnement complexe, mathématiques, génération de code) et comment configurer les budget_tokens.
Nous envoyons un casse-tête logique délibérément difficile et comparons les réponses avec et sans pensée étendue (extended thinking) pour constater la différence de qualité par nous-mêmes.
# 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.La mise en cache d'prompts vous permet de marquer des parties de la requête comme pouvant être mises en cache. Les préfixes mis en cache coûtent 90 % moins cher lors des appels ultérieurs et n'entraînent aucune latence supplémentaire. L'examen teste le placement du bloc cache_control et les en-têtes de succès de cache.
Nous envoyons deux fois la même grande prompt système et vérifions les en-têtes de réponse pour confirmer le succès du cache lors du deuxième appel.
# 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)}\")"L'examen teste comment exécuter Claude Code de manière non interactive — l'option --print affiche le résultat sur la sortie standard (stdout) sans session interactive, et --output-format json fournit une sortie structurée pour le scriptage.
C'est le modèle utilisé dans les pipelines CI : fournir un prompt, obtenir un résultat, le parser programmatiquement.
# 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)"Le domaine 1 (Architecture Agentique, 27 %) est le plus pondéré de l'examen. Le modèle de superviseur — un orchestrateur distribuant les tâches à des sous-agents spécialisés, chacun avec sa propre prompt système et son propre ensemble d'outils — est l'architecture la plus testée.
Nous allons construire un script Node.js autonome qui implémente un superviseur coordonnant deux spécialistes : un chercheur qui lit les fichiers et les résume, et un rédacteur qui produit la sortie. Le superviseur décompose une tâche, délègue à chaque spécialiste via des appels API distincts, et agrège les résultats. Exécutez-le depuis le terminal et observez la délégation se produire en direct.
# 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.mjsCe labo s'exécute entièrement en local — aucune ressource cloud à supprimer.
# 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
Ce labo se concentre sur des exercices pratiques via l'interface en ligne de commande (CLI) et l'API. Il ne couvre PAS :