Learn Claude Code is a hands-on course that teaches you to build an AI coding agent the way Claude Code is built: one small loop, surrounded by the harness mechanisms that make an agent effective. You run real, standalone Python programs — twenty of them — and each one adds exactly one new capability on top of the last. By the end you have built, line by line, a coding agent with permissions, hooks, planning, sub-agents, memory, context compaction, error recovery, a task graph, background jobs, scheduling, multi-agent teams, git-worktree isolation, and MCP tool integration.
This guide shows you how to install the course, run each lesson, point it at the model provider of your choice, and work through the material productively. It is written for the person taking the course — for the architecture of the web platform and the deep internals of each mechanism, see the companion Admin Guide.
Note
Every lesson is a single, runnable file (
code.py) you talk to in your terminal. There is nothing to compile and no service to deploy. If you can runpython, you can take this course.
1. Quick Start
Get the first agent talking to you in under two minutes.
git clone https://github.com/shareAI-lab/learn-claude-code
cd learn-claude-code
pip install -r requirements.txt
cp .env.example .env # then edit .env and set ANTHROPIC_API_KEY
python s01_agent_loop/code.py
You will see a prompt. Type a request and press Enter:
s01: Agent Loop
输入问题,回车发送。输入 q 退出。
s01 >> create a file hello.txt with the text "hi" and then show me its contents
$ echo "hi" > hello.txt
$ cat hello.txt
hi
Done — created hello.txt containing "hi".
s01 >> q
That is the whole agent: a loop that calls the model, runs the shell command the model asks for, feeds the result back, and repeats until the model stops. Every later lesson keeps this loop and adds one mechanism around it.
Tip
Type
q,exit, or just press Enter on an empty line to quit any lesson. All twenty lessons share the same simple REPL.
2. Requirements
| Requirement | Detail |
|---|---|
| Python | 3.10 or newer (the code uses str | None union syntax and Path.is_relative_to) |
| An API key | An Anthropic key, or a key for any Anthropic-compatible provider (MiniMax, GLM, Kimi, DeepSeek) |
pip packages |
anthropic>=0.25.0, python-dotenv>=1.0.0, pyyaml>=6.0 (installed by requirements.txt) |
git |
Required only for lesson s18 (worktree isolation) and to clone the repo |
| Node.js + npm | Required only if you want to run the web platform (web/); not needed for the lessons |
| A terminal | macOS, Linux, or Windows. The lessons read input line-by-line and print colored output. |
Important
Two environment variables are required for every lesson:
ANTHROPIC_API_KEYandMODEL_ID. The starter.env.examplealready setsMODEL_ID=claude-sonnet-4-6. IfMODEL_IDis missing, a lesson exits immediately with aKeyError: 'MODEL_ID'.
Optional Python niceties
- On macOS/Linux the lessons enable
readlinefor nicer line editing (and apply a fix for backspacing multibyte/Chinese input). Ifreadlineis unavailable (common on Windows), the lessons still run — they just skip the line-editing tweaks.
3. Installation
Step 1 — Get the code
git clone https://github.com/shareAI-lab/learn-claude-code
cd learn-claude-code
Step 2 — Install dependencies
The three runtime dependencies are tiny. Install them into a virtual environment to keep things clean:
macOS / Linux
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
Windows (PowerShell)
python -m venv .venv
.venv\Scripts\Activate.ps1
pip install -r requirements.txt
requirements.txt contains exactly:
anthropic>=0.25.0
python-dotenv>=1.0.0
pyyaml>=6.0
Step 3 — Configure your credentials
Copy the template and open it in an editor:
cp .env.example .env
The template documents every option. At minimum, set your key:
# API Key (required)
ANTHROPIC_API_KEY=sk-ant-xxx
# Model ID (required)
MODEL_ID=claude-sonnet-4-6
# Base URL (optional, for Anthropic-compatible providers)
# ANTHROPIC_BASE_URL=https://api.anthropic.com
Caution
Your
.envholds a live API key. Never paste your real key into a file you commit or share, and never paste it into a chat or issue.
Step 4 — Verify
python s01_agent_loop/code.py
If you get a prompt (s01 >>), you are ready. If you get an authentication error, re-check ANTHROPIC_API_KEY; if you get KeyError: 'MODEL_ID', re-check that MODEL_ID is set in .env.
4. Using a Different Model Provider
The course works with any Anthropic-compatible API, so you can take it with open models or providers other than Anthropic. You only change two variables: ANTHROPIC_BASE_URL and MODEL_ID. The agent code is identical — that is part of the lesson.
The benchmark numbers below are reproduced from the project's own .env.example (SWE-bench Verified and Terminal-Bench 2.0, as of Feb 2026) to help you choose.
| Provider | MODEL_ID |
SWE-bench | International base URL |
|---|---|---|---|
| Anthropic (default) | claude-sonnet-4-6 |
79.6% | (default — leave ANTHROPIC_BASE_URL unset) |
| MiniMax | MiniMax-M2.5 |
80.2% | https://api.minimax.io/anthropic |
| GLM (Zhipu) | glm-5 |
77.8% | https://api.z.ai/api/anthropic |
| Kimi (Moonshot) | kimi-k2.5 |
76.8% | https://api.moonshot.ai/anthropic |
| DeepSeek | deepseek-chat |
73.0% | https://api.deepseek.com/anthropic |
To use GLM, for example, set these three lines in .env:
ANTHROPIC_API_KEY=your-zhipu-key
ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic
MODEL_ID=glm-5
Note
China-mainland endpoints differ from the international ones above (for example, GLM uses
https://open.bigmodel.cn/api/anthropicand MiniMax useshttps://api.minimaxi.com/anthropic). The full mainland list is in.env.example.
Tip
When
ANTHROPIC_BASE_URLis set, the lessons automatically clear anyANTHROPIC_AUTH_TOKENfrom the environment so your provider key inANTHROPIC_API_KEYis the one used. You do not need to manage that yourself.
5. How the Course Is Organized
The course is a single straight line: read s01 through s20 in order. Each chapter assumes you have done the previous ones and ends with a hook into the next.
Each chapter lives in its own folder:
s08_context_compact/
README.md # full narrative with inline code (Chinese source)
README.en.md # English translation
README.ja.md # Japanese translation
code.py # the standalone, runnable agent
images/ # SVG diagrams (where the topic needs them)
The twenty lessons group into six stages, building from "make the agent act" up to "coordinate a team of agents":
| Stage | Theme | Chapters |
|---|---|---|
| 1. Let the agent act | The loop and its tools | s01 Agent Loop · s02 Tool Use · s03 Permission · s04 Hooks |
| 2. Handle complex work | Planning and isolation | s05 TodoWrite · s06 Subagent · s08 Context Compact |
| 3. Remember & recover | Durability | s09 Memory · s10 System Prompt · s11 Error Recovery |
| 4. Run long tasks | Time and concurrency | s12 Task System · s13 Background Tasks · s14 Cron Scheduler |
| 5. Coordinate many agents | Multi-agent platform | s15 Agent Teams · s16 Team Protocols · s17 Autonomous Agents · s18 Worktree Isolation |
| 6. Extend & assemble | Plug-ins and the finale | s07 Skill Loading · s19 MCP Plugin · s20 Comprehensive Agent |
Note
The loop never changes. Open any two consecutive chapters side by side and you will see the new file is the previous file plus one section. The unchanged parts are even labelled (for example,
# FROM s02-s04 (unchanged)). The whole pedagogy is "spot the one new idea."
The two tracks (don't mix the numbers)
This repository contains two tutorial tracks. Knowing which one you are reading prevents confusion:
- Current 20-lesson track — the root-level
s01_agent_loop/…s20_comprehensive/folders. This is the canonical version. Start here. - Legacy 12-lesson track — the
agents/folder, thedocs/folder, and the currentweb/app. Kept temporarily for old links and existing readers.
The chapter numbers do not line up between tracks. A few examples from the project's own mapping:
| Legacy (12-lesson) | Current (20-lesson) | Topic |
|---|---|---|
agents/s03_todo_write.py |
s05_todo_write/ |
TodoWrite |
agents/s06_context_compact.py |
s08_context_compact/ |
Context Compact |
agents/s07_task_system.py |
s12_task_system/ |
Task System |
agents/s12_worktree_task_isolation.py |
s18_worktree_isolation/ |
Worktree Isolation |
| (new in this version) | s03, s04, s09, s10, s11, s14, s19, s20 |
Permission, Hooks, Memory, System Prompt, Error Recovery, Cron, MCP, Comprehensive |
Warning
If you are following an external link or the live web app, you are probably on the legacy 12-lesson track. Avoid quoting chapter numbers across tracks — "s07" means Task System in the legacy track but Skill Loading in the current one.
6. Running the Lessons
Every lesson is launched the same way and behaves the same way.
python s05_todo_write/code.py
You get an interactive prompt named after the lesson (s05 >>). Type a natural-language request, press Enter, and watch the agent work. The agent prints what it is doing as it goes — tool calls, hook messages, plans, sub-agent activity — so you can see the mechanism the chapter just taught.
Everyday usage pattern
- Read the chapter's
README.en.mdfirst (orREADME.mdif you read Chinese). It explains the one new idea and walks through the code. - Run
code.pyand give it a task that exercises that idea. - Watch the printed trace. Each mechanism announces itself — e.g.
[HOOK] bash,## Current Tasks,[Subagent spawned],[auto compact],[cron fire]. - Quit with
qand move to the next chapter.
Tip
Give the agent a real small task in a scratch directory — "list the Python files and count the lines in the biggest one", "write a function that reverses a string and a test for it". Concrete tasks make each mechanism visible far better than abstract questions.
What the agent can do (the tools)
By the time you reach the later chapters the agent has a full toolbox. These are the actions it can take on your machine:
| Tool | What it does |
|---|---|
bash |
Runs a shell command in the working directory (120-second timeout) |
read_file |
Reads a file (optional limit on number of lines) |
write_file |
Writes content to a file (creates parent directories) |
edit_file |
Replaces an exact string in a file, once |
glob |
Lists files matching a pattern |
todo_write |
(s05+) Records and updates a plan/checklist |
task |
(s06+) Spawns a sub-agent with its own clean context |
load_skill |
(s07+) Loads a full skill document on demand |
compact |
(s08+) Summarizes earlier conversation to free up space |
create_task / list_tasks / get_task / claim_task / complete_task |
(s12+) The persistent task board |
schedule_cron / list_crons / cancel_cron |
(s14+) Time-triggered jobs |
spawn_teammate / send_message / check_inbox |
(s15+) Multi-agent coordination |
create_worktree / remove_worktree / keep_worktree |
(s18+) Isolated git working directories |
mcp__{server}__{tool} |
(s19+) Tools discovered from a connected MCP server |
Caution
This agent runs real shell commands and writes real files on your computer. The early lessons have only light guardrails (a deny-list and a workspace boundary), because building those guardrails is the lesson. Run the lessons in a throwaway directory, not in a folder full of work you care about. See §7 (Permission) for what is and isn't blocked.
7. Lesson-by-Lesson Walkthrough
Each lesson below lists its motto, the one mechanism it adds, and something concrete to try. Mottos and key concepts are the project's own.
Stage 1 — Let the agent act
s01 · Agent Loop — "One loop & Bash is all you need"
The smallest useful agent: a while loop that calls the model with a single bash tool, runs whatever command the model returns, feeds the output back, and stops when the model stops (stop_reason != "tool_use").
Try: find out what operating system this is and how much disk is free.
s02 · Tool Use — "Adding a tool means adding one handler"
Four more tools appear — read_file, write_file, edit_file, glob — plus a TOOL_HANDLERS dispatch map. The loop body barely changes: it now looks up TOOL_HANDLERS[block.name] instead of always calling bash.
Try: read s01_agent_loop/code.py and write a one-paragraph summary to summary.txt.
s03 · Permission — "Set boundaries first, then grant freedom"
Three gates run before any tool executes: a hard deny-list (e.g. rm -rf /, sudo), rule matching (writing outside the workspace, destructive commands), and user approval for risky actions.
Try: ask it to rm something, or to write a file outside the folder, and watch the gate ask Allow? [y/N].
s04 · Hooks — "Hook around the loop, never rewrite the loop"
The permission check moves out of the loop and onto a hook. A small registry fires callbacks on lifecycle events — UserPromptSubmit, PreToolUse, PostToolUse, Stop — so you can add behavior without touching the loop.
Try: any task — watch the [HOOK] ... lines that now narrate each step.
Stage 2 — Handle complex work
s05 · TodoWrite — "An agent without a plan drifts"
Adds a todo_write planning tool and a gentle "nag" that reminds the model to update its plan if it goes three rounds without doing so. The plan prints as a live checklist.
Try: a multi-step task like set up a tiny Python project: a module, a test, and a README.
s06 · Subagent — "Big tasks split small, each gets clean context"
Adds a task tool that spawns a sub-agent with a fresh message history. The sub-agent does its work (capped at 30 turns) and returns only a short summary; its intermediate chatter is discarded so the main thread stays clean. Sub-agents can't spawn sub-agents.
Try: investigate which file in this repo is the largest and why, then summarize.
s08 · Context Compact — "Context always fills up — have a way to make room"
A four-layer compaction pipeline keeps long sessions alive: trim middle messages, replace old tool results with placeholders, spill huge outputs to disk, and (last resort) summarize the whole history with one model call. An emergency path retries if the API ever says the prompt is too long.
Try: a long, chatty session with many file reads; watch for [auto compact].
Stage 3 — Remember & recover
s09 · Memory — "Remember what matters, forget what doesn't"
A persistent .memory/ folder survives across sessions. The agent selects relevant memories into context, extracts new ones after each turn, and periodically consolidates duplicates.
Try: tell it remember that I prefer tabs over spaces, quit, restart, and ask it to write code.
s10 · System Prompt — "Assembled at runtime, never hardcoded"
The system prompt becomes a product of current state: sections (identity, tools, workspace, memory) are concatenated based on what actually exists, with a small cache so it isn't rebuilt needlessly.
Try: run with and without a .memory/ folder and watch which sections load.
s11 · Error Recovery — "Errors aren't the end, they're the start of a retry"
Wraps the model call in three recovery paths: escalate max_tokens (8K → 64K) then ask the model to continue; reactively compact on "prompt too long"; and back off with jitter on rate-limit (429) / overload (529) errors, optionally switching to a FALLBACK_MODEL_ID.
Try: set FALLBACK_MODEL_ID in .env and give it a task that produces a very long answer.
Stage 4 — Run long tasks
s12 · Task System — "Big goals break into small tasks, ordered, persisted to disk"
A file-backed task board in .tasks/. Tasks have a subject, status, owner, and blockedBy dependencies; a task can't be claimed until its blockers are complete, and completing one reports what it unblocks.
Try: create three tasks where the third is blocked by the first two, then walk them to completion.
s13 · Background Tasks — "Slow ops go background, agent keeps thinking"
Slow commands (installs, builds, tests) run in a daemon thread. The agent gets a placeholder immediately and a <task_notification> is injected when the job finishes.
Try: ask it to run something slow with "in the background"; keep chatting while it runs.
s14 · Cron Scheduler — "Fire on schedule, no human kick needed"
A standalone scheduler thread matches 5-field cron expressions and queues prompts; a queue processor wakes the agent to run them when it's idle. Jobs can be recurring and durable (persisted to .scheduled_tasks.json, surviving restarts).
Try: schedule a job every minute that writes the current time to heartbeat.log, wait, then list_crons.
Stage 5 — Coordinate many agents
s15 · Agent Teams — "Too big for one agent — delegate to teammates"
A file-based MessageBus (.mailboxes/*.jsonl) lets a "Lead" spawn persistent teammates in background threads and exchange messages; teammate replies are injected into the Lead's history.
Try: spawn a teammate to count lines of code while you draft a README, then combine results.
s16 · Team Protocols — "Teammates need shared communication rules"
Adds a request/response protocol with correlation IDs: shutdown handshakes, plan requests, and plan approval, so coordination is contract-based rather than ad-hoc.
s17 · Autonomous Agents — "Teammates check the board, claim work themselves"
Teammates poll the task board, auto-claim unowned tasks whose dependencies are met, and cycle through a WORK → IDLE → SHUTDOWN lifecycle — no leader hand-assigning each item.
s18 · Worktree Isolation — "Each works in its own directory, no interference"
Tasks gain a worktree field bound to a real git worktree (.worktrees/<name>, branch wt/<name>), so parallel agents edit isolated checkouts without clobbering each other. Worktree names are validated against path-traversal.
Try: this lesson needs git and a git repo. Create two worktree-bound tasks and let teammates work them in parallel.
Stage 6 — Extend & assemble
s07 · Skill Loading — "Load knowledge on demand, not upfront"
(Numbered s07 in code; the learning path places it here.) Skill names and one-line descriptions sit cheaply in the system prompt; the full SKILL.md body is loaded only when the agent calls load_skill. The bundled skills are agent-builder, code-review, mcp-builder, and pdf.
Try: review the code in s02_tool_use/code.py and watch it load_skill("code-review") before working.
s19 · MCP Plugin — "Not enough capability? Plug in more via MCP"
An MCPClient discovers tools from a server and merges them into the agent's tool pool under names like mcp__docs__search, with readOnly/destructive annotations. (The transport here is a teaching mock; the real protocol details are simplified — see the Admin Guide.)
s20 · Comprehensive Agent — "Many mechanisms, one loop"
The finale puts every mechanism back together in one harness: dispatch, permission, hooks, todos, sub-agents, skills, compaction, memory, prompt assembly, error recovery, task graph, background tasks, cron, teams, protocols, autonomous agents, worktrees, and MCP — still around the same single loop. Try: give it a genuinely multi-step coding goal and watch the layers cooperate.
8. Running the Legacy 12-Lesson Track
The older track is preserved in agents/. Each file is self-contained and run directly:
python agents/s01_agent_loop.py
python agents/s12_worktree_task_isolation.py
python agents/s_full.py # the legacy "everything" agent
Note
Use the legacy track only if you are following an old link or want to compare versions. For learning from scratch, use the root-level
s01–s20track — it is more complete (20 mechanisms vs. 12) and better organized.
9. Running the Web Platform
The repository includes an interactive learning website (web/) — a Next.js app with visualizations of each mechanism, available in English, Chinese, and Japanese.
cd web
npm install
npm run dev # opens http://localhost:3000
Important
The live web app currently renders the legacy
docs/(s01–s12) track, not the new 20-lesson track. Treat the website as a companion visualization, and use the root-level chapter folders for the authoritative current material.
The npm run dev and npm run build commands automatically run a content-extraction step first (npm run extract), so the site always reflects the latest chapter content. You do not need to run extraction by hand.
10. Troubleshooting
Format: the exact symptom, the cause, the fix, and how to avoid it next time.
Error: KeyError: 'MODEL_ID'
Cause: MODEL_ID is not set in your environment. Every lesson reads it with os.environ["MODEL_ID"] and crashes if it's missing.
Solution: ensure your .env contains MODEL_ID=claude-sonnet-4-6 (or your provider's model), and that you ran cp .env.example .env.
Prevention: start from the provided .env.example, which sets MODEL_ID for you.
Error: authentication / 401 from the API
Cause: ANTHROPIC_API_KEY is missing, wrong, or doesn't match the provider in ANTHROPIC_BASE_URL.
Solution: verify the key; if you set ANTHROPIC_BASE_URL to a non-Anthropic provider, make sure ANTHROPIC_API_KEY is that provider's key.
Prevention: change ANTHROPIC_BASE_URL and ANTHROPIC_API_KEY together as a pair.
Error: 400 Bad Request part-way through a session (often in s08 / s13)
Cause: a known edge case (reported in the project's issues) where compaction can split a tool_use block from its matching tool_result, which the API rejects. It tends to surface in the background-tasks and context-compaction lessons.
Solution: restart the lesson (state is per-process); keep individual sessions shorter so compaction triggers less aggressively.
Prevention: this is a teaching simplification, not a production bug-free implementation — the Admin Guide's "Known limitations" section explains the trade-off.
Symptom: Blocked: 'rm -rf /' (or another command refused)
Cause: the s03/s04 deny-list intentionally refuses dangerous commands such as rm -rf /, sudo, shutdown, reboot, mkfs, and dd if=.
Solution: this is correct behavior — rephrase the task to avoid the blocked command.
Prevention: none needed; the block is a feature you are learning to build.
Error: ValueError: Path escapes workspace: <path>
Cause: the agent tried to read or write outside the current working directory. The safe_path guard (present from s02 onward) refuses paths that resolve outside the workspace.
Solution: run the lesson from the directory you want the agent to operate in, and ask it to use relative paths.
Prevention: treat the launch directory as the agent's sandbox.
Error: RuntimeError: Not in a git repository. worktree tools require git.
Cause: lesson s18 (and the legacy worktree lesson) needs to run inside a git repository.
Solution: run it from a folder that is a git repo (the cloned learn-claude-code itself is one), and make sure git is installed.
Prevention: only the worktree lesson needs git; the others don't.
Symptom: Subagent stopped after 30 turns without final answer.
Cause: a sub-agent (s06+) hit its 30-turn safety limit before finishing.
Solution: give the sub-agent a narrower, more concrete task; break the work into smaller task calls.
Prevention: sub-agents are for bounded side-quests, not open-ended exploration.
Symptom: readline warning or odd backspace behavior on Windows
Cause: readline isn't always available on Windows; the lessons wrap it in a try/except and continue without it.
Solution: nothing required — the lesson runs fine; you just lose inline line-editing niceties.
Prevention: use a terminal with pyreadline3 installed if you want the editing features.
Symptom: a scheduled (cron) job didn't fire
Cause: the 5-field expression didn't match, or the agent was busy in another turn when the minute passed.
Solution: check list_crons; remember the fields are minute hour day-of-month month day-of-week; the scheduler de-duplicates per calendar minute, so a job fires at most once a minute.
Prevention: test with * * * * * (every minute) first, then narrow.
11. Frequently Asked Questions
Q: Do I need an Anthropic subscription, or will any key work?
Any Anthropic-compatible key works. The course is explicitly built so that only ANTHROPIC_BASE_URL and MODEL_ID change between providers — see §4 for MiniMax, GLM, Kimi, and DeepSeek settings.
Q: Which chapter should I start with?
s01_agent_loop. Read straight through to s20. Each chapter builds on the last and ends with a hook into the next.
Q: Is this the actual Claude Code source code? No. It is a teaching re-implementation that mirrors Claude Code's design patterns in small, readable Python. The project's own words: "This is not 'copy the source code.' This is 'grasp the key designs and build it yourself.'" Some production mechanisms (full hook bus, rule-based permission governance, real MCP transport/OAuth, session resume/fork) are intentionally simplified or omitted.
Q: Why does the same code appear in every file?
That's the method. Each code.py is the previous lesson's code plus exactly one new section, with the carried-over parts labelled # FROM sNN (unchanged). You can diff two consecutive files to see precisely what each mechanism adds.
Q: Is it safe to run on my main machine? The agent executes real shell commands and edits real files. Early lessons have only minimal guardrails (deny-list + workspace boundary) by design. Run the lessons in a disposable directory and read §6's caution before pointing the agent at anything important.
Q: What languages is the material in?
Each chapter ships README.md (Chinese source), README.en.md (English), and README.ja.md (Japanese). The web platform is also trilingual (en/zh/ja).
Q: Do the lessons share state?
No. Each lesson is its own process. Folders like .memory/, .tasks/, .transcripts/, .mailboxes/, and .worktrees/ are created in your working directory as the relevant lessons run; delete them to reset.
Q: The web app shows different chapter numbers than the folders. Why? The web app renders the legacy 12-lesson track; the folders are the current 20-lesson track. The numbering differs — see the mapping table in §5 and avoid mixing numbers across tracks.
Q: What's the difference between s06 (Subagent) and s12 (Task System)?
A sub-agent (s06) is an ephemeral helper with throwaway context that returns one summary. The task system (s12) is durable, file-backed work with dependencies and ownership that multiple agents can pick up — it's the foundation for the multi-agent stages.
Q: What do I do after finishing all twenty lessons? You'll understand harness engineering well enough to build your own. The project points to two follow-ons it maintains — a ready-to-use CLI agent and an embeddable agent SDK (links in the repo's README) — and a sister tutorial on turning a "use-and-discard" agent into an always-on assistant (heartbeat + cron + chat channels).