Loading...
Loading...
Deep dive into Claude Code source code to learn production-grade AI agent architecture patterns
npx skill4agent add aradotso/trending-skills claude-code-source-studySkill by ara.so — Daily 2026 Skills collection.
claude-code-source-study/
├── docs/
│ ├── 00-目录与阅读指引.md # Index and reading guide
│ ├── 01-项目全景.md # Project overview
│ ├── 02-启动优化.md # Startup optimization
│ ├── 03-状态管理.md # State management
│ ├── 04-System-Prompt-工程.md # System prompt engineering
│ ├── 05-对话循环.md # Conversation loop
│ ├── 06-上下文管理.md # Context management
│ ├── 07-Prompt-Cache.md # Prompt caching
│ ├── 08-Thinking-与推理控制.md # Thinking & reasoning
│ ├── 09-工具系统设计.md # Tool system design
│ ├── 10-BashTool-深度剖析.md # BashTool deep dive
│ ├── 11-命令系统.md # Command system
│ ├── 12-Agent-系统.md # Agent system
│ ├── 13-内置Agent设计模式.md # Built-in agent patterns
│ ├── 14-任务系统.md # Task system
│ ├── 15-MCP-协议实现.md # MCP protocol
│ ├── 16-权限系统.md # Permission system
│ ├── 17-Settings-系统.md # Settings system
│ ├── 18-Hooks系统.md # Hooks system
│ ├── 19-Feature-Flag与编译期优化.md
│ ├── 20-API调用与错误恢复.md # API retry/recovery
│ ├── 21-Ink框架深度定制.md # Ink UI customization
│ ├── 22-设计系统.md # Design system
│ ├── 23-Memory系统.md # Memory system
│ ├── 24-Skill-Plugin开发实战.md # Plugin development
│ └── 25-架构模式总结.md # Architecture patterns summary
└── README.md01 → 02 → 03 → 05 → 09 → 12 → 2501 → 03 → 04 → 05 → 06 → 08 → 09 → 12 → 13buildTool()// Pattern extracted from docs/09-工具系统设计.md
const buildTool = <TInput, TOutput>(config: {
name: string
description: string
inputSchema: ZodSchema<TInput>
handler: (input: TInput, context: ToolContext) => Promise<TOutput>
isEnabled?: (context: AppContext) => boolean
requiresPermission?: PermissionLevel
}) => config
// Registration with conditions
const tools = [
buildTool({ name: 'bash', ... }),
buildTool({ name: 'read_file', ... }),
buildTool({ name: 'write_file', ... }),
].filter(tool => tool.isEnabled?.(ctx) ?? true)docs/05// Pattern: state-machine conversation loop using AsyncGenerator
async function* conversationLoop(
messages: Message[],
tools: Tool[]
): AsyncGenerator<StreamEvent> {
while (true) {
const stream = await anthropic.messages.stream({
model: 'claude-opus-4-5',
messages,
tools,
system: buildSystemPrompt(),
})
for await (const event of stream) {
yield event
}
const response = await stream.finalMessage()
if (response.stop_reason === 'end_turn') break
if (response.stop_reason === 'tool_use') {
const toolResults = await executeTools(response.content)
messages.push({ role: 'assistant', content: response.content })
messages.push({ role: 'user', content: toolResults })
// loop continues
}
}
}docs/03// Pattern: tiny reactive store bridging React and imperative code
type Listener<T> = (state: T) => void
function createStore<T>(initialState: T) {
let state = initialState
const listeners = new Set<Listener<T>>()
return {
getState: () => state,
setState: (updater: Partial<T> | ((s: T) => T)) => {
state = typeof updater === 'function'
? updater(state)
: { ...state, ...updater }
listeners.forEach(l => l(state))
},
subscribe: (listener: Listener<T>) => {
listeners.add(listener)
return () => listeners.delete(listener)
},
// React hook integration
useStore: () => {
const [s, setS] = React.useState(state)
React.useEffect(() => subscribe(setS), [])
return s
}
}
}docs/04// Pattern: build system prompt in segments with cache boundaries
function buildSystemPrompt(context: AppContext): SystemPrompt {
return [
// Static segment — cache this (never changes)
{ type: 'text', text: CORE_INSTRUCTIONS, cache_control: { type: 'ephemeral' } },
// Semi-static segment — cache per project
{ type: 'text', text: buildProjectContext(context.project), cache_control: { type: 'ephemeral' } },
// Dynamic segment — never cache (changes each turn)
{ type: 'text', text: buildDynamicContext(context.session) },
]
}docs/06// Pattern: token budget management with auto-compact
const TOKEN_BUDGET = {
MAX_CONTEXT: 200_000,
COMPACT_THRESHOLD: 0.85, // compact at 85% full
SUMMARY_RESERVE: 2_000,
}
async function maybeCompact(messages: Message[]): Promise<Message[]> {
const tokenCount = await countTokens(messages)
if (tokenCount < TOKEN_BUDGET.MAX_CONTEXT * TOKEN_BUDGET.COMPACT_THRESHOLD) {
return messages
}
// Summarize older messages, keep recent ones verbatim
const keepRecent = messages.slice(-20)
const toSummarize = messages.slice(0, -20)
const summary = await summarize(toSummarize)
return [
{ role: 'user', content: `Previous conversation summary:\n${summary}` },
{ role: 'assistant', content: 'Understood.' },
...keepRecent,
]
}docs/16// Pattern: layered permission evaluation
type PermissionMode = 'default' | 'acceptEdits' | 'bypassPermissions' | 'plan' | 'auto' | 'strict' | 'custom'
async function evaluatePermission(
action: ToolAction,
context: PermissionContext
): Promise<PermissionResult> {
// Step 1: Check bypass mode
if (context.mode === 'bypassPermissions') return { allowed: true }
// Step 2: Check if action is always-safe
if (isAlwaysSafe(action)) return { allowed: true }
// Step 3: Check allowlist
if (isAllowlisted(action, context.allowlist)) return { allowed: true }
// Step 4: Check blocklist
if (isBlocklisted(action, context.blocklist)) return { allowed: false, reason: 'blocklisted' }
// Step 5: Check auto-approve rules
if (matchesAutoApprove(action, context.rules)) return { allowed: true }
// Step 6: Check session memory
if (context.sessionMemory.has(actionKey(action))) return { allowed: true }
// Step 7: Ask user
const decision = await promptUser(action)
if (decision.remember) context.sessionMemory.add(actionKey(action))
return { allowed: decision.approved }
}docs/12// Pattern: sub-agent with isolated context
async function spawnSubAgent(task: AgentTask, parentContext: AgentContext) {
const subContext: AgentContext = {
// Isolated: sub-agent gets its own conversation
messages: [],
sessionId: generateId(),
// Inherited: shares tools and permissions from parent
tools: parentContext.tools,
permissionMode: parentContext.permissionMode,
// Scoped: limited working directory
cwd: task.workingDir ?? parentContext.cwd,
// Budget: prevent runaway sub-agents
maxTurns: task.maxTurns ?? 10,
tokenBudget: task.tokenBudget ?? 50_000,
}
return conversationLoop(
[{ role: 'user', content: task.prompt }],
subContext.tools,
subContext
)
}docs/20// Pattern: exponential backoff with overload handling
async function withRetry<T>(
fn: () => Promise<T>,
options = { maxAttempts: 3, baseDelay: 1000 }
): Promise<T> {
for (let attempt = 1; attempt <= options.maxAttempts; attempt++) {
try {
return await fn()
} catch (err) {
if (attempt === options.maxAttempts) throw err
// Handle Anthropic 529 overloaded
if (isOverloadError(err)) {
const delay = options.baseDelay * Math.pow(2, attempt - 1)
await sleep(delay + Math.random() * 1000) // jitter
continue
}
// Don't retry non-retriable errors
if (isAuthError(err) || isInvalidRequestError(err)) throw err
throw err
}
}
throw new Error('unreachable')
}import Anthropic from '@anthropic-ai/sdk'
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
// 1. Define tools using builder pattern
const tools = [
buildTool({
name: 'read_file',
description: 'Read a file from disk',
inputSchema: z.object({ path: z.string() }),
handler: async ({ path }) => fs.readFile(path, 'utf-8'),
}),
]
// 2. Build system prompt with cache segments
const systemPrompt = buildSystemPrompt({ static: CORE_RULES, dynamic: '' })
// 3. Run conversation loop
for await (const event of conversationLoop(
[{ role: 'user', content: userInput }],
tools
)) {
if (event.type === 'text') process.stdout.write(event.text)
}docs/08// Control reasoning effort per request
type ThinkingConfig =
| { type: 'disabled' }
| { type: 'enabled'; budget_tokens: number }
// "ultrathink" = maximum budget
const EFFORT_LEVELS = {
low: { type: 'enabled', budget_tokens: 1_000 },
medium: { type: 'enabled', budget_tokens: 5_000 },
high: { type: 'enabled', budget_tokens: 10_000 },
ultrathink: { type: 'enabled', budget_tokens: 32_000 },
} satisfies Record<string, ThinkingConfig>
const response = await anthropic.messages.create({
model: 'claude-opus-4-5',
thinking: EFFORT_LEVELS.ultrathink,
messages,
})| Problem | Solution |
|---|---|
| Article links 404 | Clone the repo — all articles are in |
| Code examples reference internal modules | They're illustrative patterns extracted from analysis, not runnable as-is |
| Need the actual Claude Code source | See Anthropic's published CLI source |
| Want to contribute an article | Open a PR to |
git clone https://github.com/luyao618/Claude-Code-Source-Study
cd Claude-Code-Source-Study
# Quick route: global understanding (7 articles)
open docs/01-项目全景.md
# AI engineering deep dive (9 articles)
open docs/04-System-Prompt-工程.md
# Architecture patterns summary (read last)
open docs/25-架构模式总结.md