claude-code-harness-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseClaude Code Harness Architecture
Claude Code Harness架构
Skill by ara.so — Claude Code Skills collection.
This skill provides deep architectural knowledge from the 420,000-word book "Decoding Agent Harness" (御舆:解码 Agent Harness), a comprehensive analysis of Claude Code's internal architecture. Use this to design, build, and debug production-grade AI Agent systems.
由ara.so提供的Skill —— Claude Code Skills合集。
本Skill源自42万字的《解码Agent Harness》(御舆:解码 Agent Harness)一书,该书对Claude Code的内部架构进行了全面解析。借助本Skill,你可以设计、构建和调试生产级AI Agent系统。
What This Covers
内容涵盖
The book analyzes the complete Agent Harness architecture through 15 chapters:
- Conversation Loop: Async generator-based dialog control
- Tool System: 45+ tools, concurrent execution, safety protocols
- Permission Pipeline: 4-stage access control with speculative classification
- Context Management: 4-level progressive compression with circuit breakers
- Memory System: 4 types of closed-form memory, fork inheritance
- Hook System: 26 lifecycle events, 5 hook types
- Sub-Agents: Fork mode with byte-level context inheritance
- MCP Integration: 8 transport protocols, bridge architecture
- Skills & Plugins: 11 core skills, frontmatter-based loading
- Streaming Architecture: Performance optimization patterns
本书通过15个章节分析了完整的Agent Harness架构:
- 对话循环:基于异步生成器的对话控制
- 工具系统:45+种工具、并发执行、安全协议
- 权限流水线:包含推测分类的4阶段访问控制
- 上下文管理:带熔断机制的4级渐进式压缩
- 内存系统:4种封闭形式内存、分支继承
- 钩子系统:26个生命周期事件、5种钩子类型
- 子Agent:字节级上下文继承的分支模式
- MCP集成:8种传输协议、桥接架构
- 技能与插件:11种核心技能、基于前置元数据的加载机制
- 流式架构:性能优化模式
Core Architecture Patterns
核心架构模式
1. Conversation Loop (The Heartbeat)
1. 对话循环(核心心跳机制)
The main loop is an async generator with 5 yield event types:
typescript
async function* conversationLoop(
deps: QueryDeps
): AsyncGenerator<ConversationEvent> {
while (true) {
// Yield status updates
yield { type: 'thinking', phase: 'analyzing' };
// Stream LLM response
const response = await streamLLMCompletion(deps);
yield { type: 'text', content: response.delta };
// Execute tool calls
if (response.toolUse) {
yield { type: 'tool_call', tool: response.toolUse.name };
const result = await executeTool(response.toolUse, deps);
yield { type: 'tool_result', data: result };
}
// Check termination (10 types)
if (shouldTerminate(response, deps)) {
yield { type: 'done', reason: response.stopReason };
break;
}
}
}10 Termination Reasons:
- : Natural completion
end_turn - : Context limit reached
max_tokens - : Explicit stop marker
stop_sequence - : Waiting for tool approval
tool_use - : Manual cancellation
user_interrupt - : Execution failure
error - : Time limit exceeded
timeout - : Token budget exhausted
budget_exceeded - : Max fork depth reached
recursion_limit - : Permission denied
safety_violation
主循环是一个包含5种yield事件类型的异步生成器:
typescript
async function* conversationLoop(
deps: QueryDeps
): AsyncGenerator<ConversationEvent> {
while (true) {
// Yield status updates
yield { type: 'thinking', phase: 'analyzing' };
// Stream LLM response
const response = await streamLLMCompletion(deps);
yield { type: 'text', content: response.delta };
// Execute tool calls
if (response.toolUse) {
yield { type: 'tool_call', tool: response.toolUse.name };
const result = await executeTool(response.toolUse, deps);
yield { type: 'tool_result', data: result };
}
// Check termination (10 types)
if (shouldTerminate(response, deps)) {
yield { type: 'done', reason: response.stopReason };
break;
}
}
}10种终止原因:
- : 自然结束
end_turn - : 达到上下文限制
max_tokens - : 触发显式停止标记
stop_sequence - : 等待工具审批
tool_use - : 手动取消
user_interrupt - : 执行失败
error - : 超过时间限制
timeout - : 令牌预算耗尽
budget_exceeded - : 达到最大分支深度
recursion_limit - : 权限被拒绝
safety_violation
2. Tool System Architecture
2. 工具系统架构
Tool Protocol (5 elements):
typescript
interface Tool<I = unknown, O = unknown, P = unknown> {
// 1. Schema: Zod v4 for validation
input: z.ZodType<I>;
// 2. Metadata
name: string;
description: string;
// 3. Parameters (optional context)
parameters?: P;
// 4. Execute: Core logic
execute: (input: I, params: P, deps: QueryDeps) => Promise<O>;
// 5. Attributes
readOnly: boolean;
destructive: boolean;
concurrencySafe: boolean;
}Fault-Safe Tool Factory:
typescript
function buildTool<I, O, P>(spec: ToolSpec<I, O, P>): Tool<I, O, P> {
return {
...spec,
execute: async (input, params, deps) => {
try {
// Validate input
const validated = spec.input.parse(input);
// Execute with timeout
const result = await Promise.race([
spec.execute(validated, params, deps),
new Promise((_, reject) =>
setTimeout(() => reject('timeout'), deps.timeout)
)
]);
return result as O;
} catch (error) {
// Return structured error, never throw
return {
success: false,
error: error.message,
recovery: spec.errorRecovery?.(error)
} as O;
}
}
};
}12 Tool Categories (from Appendix B):
- File Operations: ,
read_file,write_filesearch_files - Shell: ,
execute_commandbash_session - Browser: ,
navigate,screenshotextract - Git: ,
commit,difflog - Search: ,
web_searchcodebase_search - Memory: ,
remember,recallforget - Agent: ,
fork_agentcall_coordinator - MCP: ,
mcp_call_toolmcp_list_resources - Plan: ,
create_planupdate_plan_step - Config: ,
get_settingupdate_setting - Debug: ,
inspect_contexttrace_tool_call - System: ,
sleep,notifyrequest_permission
工具协议(5个要素):
typescript
interface Tool<I = unknown, O = unknown, P = unknown> {
// 1. Schema: Zod v4 for validation
input: z.ZodType<I>;
// 2. Metadata
name: string;
description: string;
// 3. Parameters (optional context)
parameters?: P;
// 4. Execute: Core logic
execute: (input: I, params: P, deps: QueryDeps) => Promise<O>;
// 5. Attributes
readOnly: boolean;
destructive: boolean;
concurrencySafe: boolean;
}故障安全工具工厂:
typescript
function buildTool<I, O, P>(spec: ToolSpec<I, O, P>): Tool<I, O, P> {
return {
...spec,
execute: async (input, params, deps) => {
try {
// Validate input
const validated = spec.input.parse(input);
// Execute with timeout
const result = await Promise.race([
spec.execute(validated, params, deps),
new Promise((_, reject) =>
setTimeout(() => reject('timeout'), deps.timeout)
)
]);
return result as O;
} catch (error) {
// Return structured error, never throw
return {
success: false,
error: error.message,
recovery: spec.errorRecovery?.(error)
} as O;
}
}
};
}12种工具类别(来自附录B):
- 文件操作: ,
read_file,write_filesearch_files - Shell命令: ,
execute_commandbash_session - 浏览器: ,
navigate,screenshotextract - Git: ,
commit,difflog - 搜索: ,
web_searchcodebase_search - 内存: ,
remember,recallforget - Agent: ,
fork_agentcall_coordinator - MCP: ,
mcp_call_toolmcp_list_resources - 计划: ,
create_planupdate_plan_step - 配置: ,
get_settingupdate_setting - 调试: ,
inspect_contexttrace_tool_call - 系统: ,
sleep,notifyrequest_permission
3. Permission Pipeline (4 Stages)
3. 权限流水线(4阶段)
typescript
type PermissionMode =
| 'auto' // No approval needed
| 'notify' // Show notification, auto-proceed
| 'confirm' // Require user approval
| 'reject' // Always deny
| 'interactive'; // Progressive disclosure
async function permissionPipeline(
toolCall: ToolCall,
deps: QueryDeps
): Promise<PermissionResult> {
// Stage 1: Rule Matching (bash-style patterns)
const mode = matchPermissionRule(toolCall.name, deps.config.permissions);
if (mode === 'auto') return { approved: true };
if (mode === 'reject') return { approved: false, reason: 'policy' };
// Stage 2: Speculative Classification (2s timeout)
const classification = await Promise.race([
classifyToolIntent(toolCall, deps),
Promise.resolve({ risk: 'unknown', confidence: 0 })
]);
if (classification.risk === 'low' && classification.confidence > 0.9) {
return { approved: true, source: 'classifier' };
}
// Stage 3: User Prompt
if (mode === 'confirm' || mode === 'interactive') {
const response = await deps.ui.promptUser({
tool: toolCall.name,
args: toolCall.arguments,
risk: classification.risk,
preview: generatePreview(toolCall)
});
return { approved: response.approved, memorize: response.remember };
}
// Stage 4: Fallback (default deny)
return { approved: false, reason: 'no_approval' };
}Rule Matching Examples:
yaml
permissions:
- pattern: "read_*"
mode: auto
- pattern: "write_file:/tmp/**"
mode: notify
- pattern: "execute_command:rm *"
mode: reject
- pattern: "fork_agent:**"
mode: confirm
max_depth: 3typescript
type PermissionMode =
| 'auto' // 无需审批
| 'notify' // 显示通知,自动执行
| 'confirm' // 需要用户审批
| 'reject' // 始终拒绝
| 'interactive'; // 渐进式披露
async function permissionPipeline(
toolCall: ToolCall,
deps: QueryDeps
): Promise<PermissionResult> {
// Stage 1: Rule Matching (bash-style patterns)
const mode = matchPermissionRule(toolCall.name, deps.config.permissions);
if (mode === 'auto') return { approved: true };
if (mode === 'reject') return { approved: false, reason: 'policy' };
// Stage 2: Speculative Classification (2s timeout)
const classification = await Promise.race([
classifyToolIntent(toolCall, deps),
Promise.resolve({ risk: 'unknown', confidence: 0 })
]);
if (classification.risk === 'low' && classification.confidence > 0.9) {
return { approved: true, source: 'classifier' };
}
// Stage 3: User Prompt
if (mode === 'confirm' || mode === 'interactive') {
const response = await deps.ui.promptUser({
tool: toolCall.name,
args: toolCall.arguments,
risk: classification.risk,
preview: generatePreview(toolCall)
});
return { approved: response.approved, memorize: response.remember };
}
// Stage 4: Fallback (default deny)
return { approved: false, reason: 'no_approval' };
}规则匹配示例:
yaml
permissions:
- pattern: "read_*"
mode: auto
- pattern: "write_file:/tmp/**"
mode: notify
- pattern: "execute_command:rm *"
mode: reject
- pattern: "fork_agent:**"
mode: confirm
max_depth: 34. Context Management (Compression Strategies)
4. 上下文管理(压缩策略)
Effective Window Formula:
EffectiveWindow = MaxContext - (SystemPrompt + Tools + Config + Memory + OutputReserve)4-Level Progressive Compression:
typescript
async function manageContext(deps: QueryDeps): Promise<Message[]> {
const budget = calculateBudget(deps);
let messages = deps.conversation.messages;
// Level 1: Snip (truncate old content)
if (getTokenCount(messages) > budget.warning) {
messages = snipOldMessages(messages, budget.target);
}
// Level 2: MicroCompact (compress code blocks)
if (getTokenCount(messages) > budget.warning) {
messages = await microCompact(messages, {
maxCodeLength: 500,
preserveErrors: true
});
}
// Level 3: Collapse (summarize message pairs)
if (getTokenCount(messages) > budget.critical) {
messages = await collapseMessages(messages, {
minPairAge: 10,
maxCollapse: 0.5
});
}
// Level 4: AutoCompact (LLM-based summary)
if (getTokenCount(messages) > budget.critical) {
messages = await autoCompact(messages, deps);
}
// Circuit Breaker: Hard truncate if all fails
if (getTokenCount(messages) > budget.max) {
messages = messages.slice(-budget.max);
deps.metrics.recordCircuitBreak('context_overflow');
}
return messages;
}Circuit Breaker Pattern:
typescript
class ContextCircuitBreaker {
private failures = 0;
private state: 'closed' | 'open' | 'half_open' = 'closed';
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
throw new Error('Circuit breaker open');
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onFailure() {
this.failures++;
if (this.failures >= 3) {
this.state = 'open';
setTimeout(() => this.state = 'half_open', 30000);
}
}
private onSuccess() {
this.failures = 0;
this.state = 'closed';
}
}有效窗口计算公式:
EffectiveWindow = MaxContext - (SystemPrompt + Tools + Config + Memory + OutputReserve)4级渐进式压缩:
typescript
async function manageContext(deps: QueryDeps): Promise<Message[]> {
const budget = calculateBudget(deps);
let messages = deps.conversation.messages;
// Level 1: Snip (truncate old content)
if (getTokenCount(messages) > budget.warning) {
messages = snipOldMessages(messages, budget.target);
}
// Level 2: MicroCompact (compress code blocks)
if (getTokenCount(messages) > budget.warning) {
messages = await microCompact(messages, {
maxCodeLength: 500,
preserveErrors: true
});
}
// Level 3: Collapse (summarize message pairs)
if (getTokenCount(messages) > budget.critical) {
messages = await collapseMessages(messages, {
minPairAge: 10,
maxCollapse: 0.5
});
}
// Level 4: AutoCompact (LLM-based summary)
if (getTokenCount(messages) > budget.critical) {
messages = await autoCompact(messages, deps);
}
// Circuit Breaker: Hard truncate if all fails
if (getTokenCount(messages) > budget.max) {
messages = messages.slice(-budget.max);
deps.metrics.recordCircuitBreak('context_overflow');
}
return messages;
}熔断机制模式:
typescript
class ContextCircuitBreaker {
private failures = 0;
private state: 'closed' | 'open' | 'half_open' = 'closed';
async execute<T>(fn: () => Promise<T>): Promise<T> {
if (this.state === 'open') {
throw new Error('Circuit breaker open');
}
try {
const result = await fn();
this.onSuccess();
return result;
} catch (error) {
this.onFailure();
throw error;
}
}
private onFailure() {
this.failures++;
if (this.failures >= 3) {
this.state = 'open';
setTimeout(() => this.state = 'half_open', 30000);
}
}
private onSuccess() {
this.failures = 0;
this.state = 'closed';
}
}5. Memory System (4 Types)
5. 内存系统(4种类型)
Closed-Form Memory (only store non-derivable information):
typescript
interface Memory {
type: 'fact' | 'preference' | 'context' | 'goal';
content: string;
source: 'user' | 'agent' | 'tool';
timestamp: number;
expiresAt?: number;
confidence: number;
}
class MemorySystem {
async remember(memory: Memory, deps: QueryDeps) {
// Deduplicate: Don't store if derivable
if (await this.isDerivable(memory, deps)) {
return { stored: false, reason: 'derivable' };
}
// Store in MEMORY.md
await deps.fs.appendFile('.claude/MEMORY.md',
`\n## ${memory.type} (${new Date(memory.timestamp).toISOString()})\n` +
`${memory.content}\n` +
`Source: ${memory.source} | Confidence: ${memory.confidence}\n`
);
// Update index
await this.updateIndex(memory, deps);
}
async recall(query: string, deps: QueryDeps): Promise<Memory[]> {
// Vector search in index
const results = await deps.vectorDB.search(query, {
type: ['fact', 'preference', 'context', 'goal'],
minConfidence: 0.7,
limit: 10
});
// Filter expired
return results.filter(m =>
!m.expiresAt || m.expiresAt > Date.now()
);
}
}Fork Memory Inheritance:
typescript
async function forkAgent(config: ForkConfig, deps: QueryDeps): Promise<Agent> {
const childMemory = {
// Inherit parent facts
facts: deps.memory.getFacts(),
// Inherit preferences (shallow copy)
preferences: { ...deps.memory.getPreferences() },
// New context scope
context: [],
// Inherit goals if specified
goals: config.inheritGoals ? deps.memory.getGoals() : []
};
return createAgent({
...config,
memory: childMemory,
parent: deps.agentId,
depth: deps.forkDepth + 1
});
}封闭形式内存(仅存储不可推导的信息):
typescript
interface Memory {
type: 'fact' | 'preference' | 'context' | 'goal';
content: string;
source: 'user' | 'agent' | 'tool';
timestamp: number;
expiresAt?: number;
confidence: number;
}
class MemorySystem {
async remember(memory: Memory, deps: QueryDeps) {
// Deduplicate: Don't store if derivable
if (await this.isDerivable(memory, deps)) {
return { stored: false, reason: 'derivable' };
}
// Store in MEMORY.md
await deps.fs.appendFile('.claude/MEMORY.md',
`\n## ${memory.type} (${new Date(memory.timestamp).toISOString()})\n` +
`${memory.content}\n` +
`Source: ${memory.source} | Confidence: ${memory.confidence}\n`
);
// Update index
await this.updateIndex(memory, deps);
}
async recall(query: string, deps: QueryDeps): Promise<Memory[]> {
// Vector search in index
const results = await deps.vectorDB.search(query, {
type: ['fact', 'preference', 'context', 'goal'],
minConfidence: 0.7,
limit: 10
});
// Filter expired
return results.filter(m =>
!m.expiresAt || m.expiresAt > Date.now()
);
}
}分支内存继承:
typescript
async function forkAgent(config: ForkConfig, deps: QueryDeps): Promise<Agent> {
const childMemory = {
// Inherit parent facts
facts: deps.memory.getFacts(),
// Inherit preferences (shallow copy)
preferences: { ...deps.memory.getPreferences() },
// New context scope
context: [],
// Inherit goals if specified
goals: config.inheritGoals ? deps.memory.getGoals() : []
};
return createAgent({
...config,
memory: childMemory,
parent: deps.agentId,
depth: deps.forkDepth + 1
});
}6. Sub-Agent & Coordinator Pattern
6. 子Agent与协调器模式
Fork Mode (byte-level context inheritance):
typescript
interface ForkConfig {
type: 'fork' | 'spawn' | 'clone';
inheritContext: boolean;
inheritMemory: boolean;
inheritTools: boolean;
inheritGoals: boolean;
maxDepth: number;
}
async function forkAgent(
config: ForkConfig,
deps: QueryDeps
): Promise<{ agentId: string; channel: MessageChannel }> {
// Recursion guard
if (deps.forkDepth >= config.maxDepth) {
throw new Error(`Max fork depth ${config.maxDepth} exceeded`);
}
// Byte-level context copy
const childContext = config.inheritContext
? structuredClone(deps.conversation)
: { messages: [] };
// Create child agent
const child = await createAgent({
...config,
context: childContext,
memory: config.inheritMemory ? cloneMemory(deps.memory) : {},
tools: config.inheritTools ? deps.tools : getDefaultTools(),
parent: deps.agentId,
depth: deps.forkDepth + 1
});
return {
agentId: child.id,
channel: child.messageChannel
};
}Coordinator Pattern (orchestration-only):
typescript
class CoordinatorAgent {
// Constraint: Coordinators never execute tools directly
private readonly allowedTools = [
'fork_agent',
'send_message_to_agent',
'wait_for_agent',
'aggregate_results'
];
async orchestrate(task: Task, deps: QueryDeps) {
// Decompose task
const subtasks = await this.decompose(task, deps);
// Spawn workers
const workers = await Promise.all(
subtasks.map(st => forkAgent({
type: 'spawn',
inheritContext: false,
inheritMemory: true,
inheritTools: true,
inheritGoals: false,
maxDepth: deps.forkDepth + 1
}, deps))
);
// Distribute work
await Promise.all(
workers.map((w, i) => this.sendTask(w, subtasks[i]))
);
// Aggregate results
const results = await Promise.all(
workers.map(w => this.waitForCompletion(w))
);
return this.synthesize(results, task);
}
// Double gate: tool filter + instruction constraint
validateToolCall(toolName: string): boolean {
return this.allowedTools.includes(toolName);
}
}4 Addressing Modes:
typescript
type AgentAddress =
| { type: 'direct', id: string } // UUID
| { type: 'role', role: string } // 'researcher', 'coder'
| { type: 'capability', skills: string[] } // ['python', 'data_viz']
| { type: 'broadcast', scope: 'all' | 'siblings' };
async function routeMessage(
message: Message,
address: AgentAddress,
deps: QueryDeps
): Promise<void> {
const targets = resolveAddress(address, deps);
await Promise.all(
targets.map(agent => agent.channel.postMessage(message))
);
}分支模式(字节级上下文继承):
typescript
interface ForkConfig {
type: 'fork' | 'spawn' | 'clone';
inheritContext: boolean;
inheritMemory: boolean;
inheritTools: boolean;
inheritGoals: boolean;
maxDepth: number;
}
async function forkAgent(
config: ForkConfig,
deps: QueryDeps
): Promise<{ agentId: string; channel: MessageChannel }> {
// Recursion guard
if (deps.forkDepth >= config.maxDepth) {
throw new Error(`Max fork depth ${config.maxDepth} exceeded`);
}
// Byte-level context copy
const childContext = config.inheritContext
? structuredClone(deps.conversation)
: { messages: [] };
// Create child agent
const child = await createAgent({
...config,
context: childContext,
memory: config.inheritMemory ? cloneMemory(deps.memory) : {},
tools: config.inheritTools ? deps.tools : getDefaultTools(),
parent: deps.agentId,
depth: deps.forkDepth + 1
});
return {
agentId: child.id,
channel: child.messageChannel
};
}协调器模式(仅负责编排):
typescript
class CoordinatorAgent {
// Constraint: Coordinators never execute tools directly
private readonly allowedTools = [
'fork_agent',
'send_message_to_agent',
'wait_for_agent',
'aggregate_results'
];
async orchestrate(task: Task, deps: QueryDeps) {
// Decompose task
const subtasks = await this.decompose(task, deps);
// Spawn workers
const workers = await Promise.all(
subtasks.map(st => forkAgent({
type: 'spawn',
inheritContext: false,
inheritMemory: true,
inheritTools: true,
inheritGoals: false,
maxDepth: deps.forkDepth + 1
}, deps))
);
// Distribute work
await Promise.all(
workers.map((w, i) => this.sendTask(w, subtasks[i]))
);
// Aggregate results
const results = await Promise.all(
workers.map(w => this.waitForCompletion(w))
);
return this.synthesize(results, task);
}
// Double gate: tool filter + instruction constraint
validateToolCall(toolName: string): boolean {
return this.allowedTools.includes(toolName);
}
}4种寻址模式:
typescript
type AgentAddress =
| { type: 'direct', id: string } // UUID
| { type: 'role', role: string } // 'researcher', 'coder'
| { type: 'capability', skills: string[] } // ['python', 'data_viz']
| { type: 'broadcast', scope: 'all' | 'siblings' };
async function routeMessage(
message: Message,
address: AgentAddress,
deps: QueryDeps
): Promise<void> {
const targets = resolveAddress(address, deps);
await Promise.all(
targets.map(agent => agent.channel.postMessage(message))
);
}7. MCP Integration
7. MCP集成
8 Transport Protocols (from Ch12):
- : Standard input/output
stdio - : Server-Sent Events
sse - : WebSocket
ws - : HTTP polling
http - : Inter-Process Communication
ipc - : Raw TCP socket
tcp - : Unix domain socket
unix - : In-process
embedded
5-State Connection Management:
typescript
type MCPConnectionState =
| 'disconnected'
| 'connecting'
| 'connected'
| 'reconnecting'
| 'failed';
class MCPConnection {
private state: MCPConnectionState = 'disconnected';
private reconnectAttempts = 0;
private maxReconnectAttempts = 5;
async connect(config: MCPConfig): Promise<void> {
this.state = 'connecting';
try {
const transport = createTransport(config.protocol, config);
await transport.connect();
// Handshake
const capabilities = await this.handshake(transport);
this.state = 'connected';
this.reconnectAttempts = 0;
return { transport, capabilities };
} catch (error) {
await this.handleConnectionError(error, config);
}
}
private async handleConnectionError(
error: Error,
config: MCPConfig
): Promise<void> {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.state = 'reconnecting';
this.reconnectAttempts++;
const delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000);
await sleep(delay);
return this.connect(config);
} else {
this.state = 'failed';
throw error;
}
}
}3-Segment Tool Naming:
mcp://<server>/<category>/<tool>Example:
typescript
const toolName = 'mcp://github/repo/create_issue';
const [protocol, server, category, tool] = toolName.split('/');Bridge Pattern (bidirectional communication):
typescript
class MCPBridge {
// Agent → MCP Server
async callTool(
toolName: string,
args: unknown,
deps: QueryDeps
): Promise<unknown> {
const [server, category, tool] = parseMCPToolName(toolName);
const connection = deps.mcpConnections.get(server);
const result = await connection.request({
method: 'tools/call',
params: { name: `${category}/${tool}`, arguments: args }
});
return result;
}
// MCP Server → Agent (notifications)
async handleNotification(
notification: MCPNotification,
deps: QueryDeps
): Promise<void> {
switch (notification.method) {
case 'notifications/resources/updated':
await deps.memory.invalidateCache(notification.params.uri);
break;
case 'notifications/tools/list_changed':
await deps.tools.refreshMCPTools(notification.params.server);
break;
}
}
}8种传输协议(来自第12章):
- : 标准输入输出
stdio - : Server-Sent Events
sse - : WebSocket
ws - : HTTP轮询
http - : 进程间通信
ipc - : 原始TCP套接字
tcp - : Unix域套接字
unix - : 进程内
embedded
5状态连接管理:
typescript
type MCPConnectionState =
| 'disconnected'
| 'connecting'
| 'connected'
| 'reconnecting'
| 'failed';
class MCPConnection {
private state: MCPConnectionState = 'disconnected';
private reconnectAttempts = 0;
private maxReconnectAttempts = 5;
async connect(config: MCPConfig): Promise<void> {
this.state = 'connecting';
try {
const transport = createTransport(config.protocol, config);
await transport.connect();
// Handshake
const capabilities = await this.handshake(transport);
this.state = 'connected';
this.reconnectAttempts = 0;
return { transport, capabilities };
} catch (error) {
await this.handleConnectionError(error, config);
}
}
private async handleConnectionError(
error: Error,
config: MCPConfig
): Promise<void> {
if (this.reconnectAttempts < this.maxReconnectAttempts) {
this.state = 'reconnecting';
this.reconnectAttempts++;
const delay = Math.min(1000 * 2 ** this.reconnectAttempts, 30000);
await sleep(delay);
return this.connect(config);
} else {
this.state = 'failed';
throw error;
}
}
}3段式工具命名:
mcp://<server>/<category>/<tool>示例:
typescript
const toolName = 'mcp://github/repo/create_issue';
const [protocol, server, category, tool] = toolName.split('/');桥接模式(双向通信):
typescript
class MCPBridge {
// Agent → MCP Server
async callTool(
toolName: string,
args: unknown,
deps: QueryDeps
): Promise<unknown> {
const [server, category, tool] = parseMCPToolName(toolName);
const connection = deps.mcpConnections.get(server);
const result = await connection.request({
method: 'tools/call',
params: { name: `${category}/${tool}`, arguments: args }
});
return result;
}
// MCP Server → Agent (notifications)
async handleNotification(
notification: MCPNotification,
deps: QueryDeps
): Promise<void> {
switch (notification.method) {
case 'notifications/resources/updated':
await deps.memory.invalidateCache(notification.params.uri);
break;
case 'notifications/tools/list_changed':
await deps.tools.refreshMCPTools(notification.params.server);
break;
}
}
}8. Hook System (26 Lifecycle Events)
8. 钩子系统(26个生命周期事件)
5 Hook Types:
typescript
type HookType =
| 'before' // Pre-execution interception
| 'after' // Post-execution augmentation
| 'transform' // Data transformation
| 'validate' // Validation checkpoint
| 'observe'; // Side-effect free monitoring
interface Hook {
type: HookType;
event: LifecycleEvent;
priority: number; // 0-100, higher runs first
execute: (context: HookContext) => Promise<HookResult>;
conditions?: HookCondition[];
}26 Lifecycle Events (partial list from Ch08):
typescript
type LifecycleEvent =
// Conversation
| 'conversation:start'
| 'conversation:message'
| 'conversation:end'
// Tool execution
| 'tool:before_call'
| 'tool:after_call'
| 'tool:error'
// Context management
| 'context:compress'
| 'context:overflow'
// Permission
| 'permission:request'
| 'permission:denied'
// Memory
| 'memory:store'
| 'memory:recall'
// Agent
| 'agent:fork'
| 'agent:terminate'
// MCP
| 'mcp:connect'
| 'mcp:disconnect'
// Plan
| 'plan:create'
| 'plan:step_complete'
// System
| 'system:error'
| 'system:shutdown';Hook Registration:
typescript
async function registerHook(
hook: Hook,
deps: QueryDeps
): Promise<void> {
// Security check: validate source
if (!deps.config.allowExternalHooks && hook.source !== 'builtin') {
throw new Error('External hooks disabled');
}
// Validate hook implementation
await validateHookSchema(hook);
// Register in priority order
deps.hooks.register(hook.event, hook.priority, hook.execute);
}
async function executeHooks(
event: LifecycleEvent,
context: HookContext,
deps: QueryDeps
): Promise<HookContext> {
const hooks = deps.hooks.get(event).sort((a, b) => b.priority - a.priority);
let currentContext = context;
for (const hook of hooks) {
// Check conditions
if (hook.conditions && !evaluateConditions(hook.conditions, currentContext)) {
continue;
}
// Execute with timeout
try {
const result = await Promise.race([
hook.execute(currentContext),
timeout(5000, 'Hook timeout')
]);
// Transform context
if (result.context) {
currentContext = result.context;
}
// Halt propagation if requested
if (result.halt) {
break;
}
} catch (error) {
deps.metrics.recordHookError(hook.event, error);
// Continue executing other hooks
}
}
return currentContext;
}5种钩子类型:
typescript
type HookType =
| 'before' // 执行前拦截
| 'after' // 执行后增强
| 'transform' // 数据转换
| 'validate' // 验证检查点
| 'observe'; // 无副作用监控
interface Hook {
type: HookType;
event: LifecycleEvent;
priority: number; // 0-100,数值越高执行优先级越高
execute: (context: HookContext) => Promise<HookResult>;
conditions?: HookCondition[];
}26个生命周期事件(来自第8章的部分列表):
typescript
type LifecycleEvent =
// 对话
| 'conversation:start'
| 'conversation:message'
| 'conversation:end'
// 工具执行
| 'tool:before_call'
| 'tool:after_call'
| 'tool:error'
// 上下文管理
| 'context:compress'
| 'context:overflow'
// 权限
| 'permission:request'
| 'permission:denied'
// 内存
| 'memory:store'
| 'memory:recall'
// Agent
| 'agent:fork'
| 'agent:terminate'
// MCP
| 'mcp:connect'
| 'mcp:disconnect'
// 计划
| 'plan:create'
| 'plan:step_complete'
// 系统
| 'system:error'
| 'system:shutdown';钩子注册:
typescript
async function registerHook(
hook: Hook,
deps: QueryDeps
): Promise<void> {
// Security check: validate source
if (!deps.config.allowExternalHooks && hook.source !== 'builtin') {
throw new Error('External hooks disabled');
}
// Validate hook implementation
await validateHookSchema(hook);
// Register in priority order
deps.hooks.register(hook.event, hook.priority, hook.execute);
}
async function executeHooks(
event: LifecycleEvent,
context: HookContext,
deps: QueryDeps
): Promise<HookContext> {
const hooks = deps.hooks.get(event).sort((a, b) => b.priority - a.priority);
let currentContext = context;
for (const hook of hooks) {
// Check conditions
if (hook.conditions && !evaluateConditions(hook.conditions, currentContext)) {
continue;
}
// Execute with timeout
try {
const result = await Promise.race([
hook.execute(currentContext),
timeout(5000, 'Hook timeout')
]);
// Transform context
if (result.context) {
currentContext = result.context;
}
// Halt propagation if requested
if (result.halt) {
break;
}
} catch (error) {
deps.metrics.recordHookError(hook.event, error);
// Continue executing other hooks
}
}
return currentContext;
}9. Skills & Plugins (Frontmatter-Based Loading)
9. 技能与插件(基于前置元数据的加载)
SKILL.md Frontmatter:
yaml
---
name: git-workflow-automation
version: 1.2.0
description: Automated git workflows with conventional commits
triggers:
- "create a feature branch"
- "commit with conventional format"
- "prepare a release"
dependencies:
tools: [execute_command, read_file, write_file]
mcpServers: [github]
config:
commitFormat: conventional
branchPrefix: feature/
autoSquash: true
parameters:
mainBranch: ${param.mainBranch|main}
remote: ${param.remote|origin}
signCommits: ${param.signCommits|false}
---3-Level Parameter Replacement:
typescript
function resolveParameters(
skillConfig: SkillConfig,
deps: QueryDeps
): Record<string, unknown> {
const resolved = {};
for (const [key, template] of Object.entries(skillConfig.parameters)) {
// Level 1: User-provided parameters
if (deps.userParams[key] !== undefined) {
resolved[key] = deps.userParams[key];
continue;
}
// Level 2: Environment variables
const envMatch = template.match(/\${env\.([^}|]+)(\|(.+))?}/);
if (envMatch) {
const [, envVar, , defaultValue] = envMatch;
resolved[key] = process.env[envVar] ?? defaultValue;
continue;
}
// Level 3: Default value
const defaultMatch = template.match(/\${param\.[^}|]+\|(.+)}/);
if (defaultMatch) {
resolved[key] = defaultMatch[1];
}
}
return resolved;
}Layered Loading:
typescript
async function loadSkills(deps: QueryDeps): Promise<Skill[]> {
const skills: Skill[] = [];
// Layer 1: Built-in skills
const builtinPath = path.join(__dirname, '../skills');
skills.push(...await loadSkillsFromDir(builtinPath));
// Layer 2: User skills
const userPath = path.join(deps.config.skillsDir);
if (await exists(userPath)) {
skills.push(...await loadSkillsFromDir(userPath));
}
// Layer 3: Project skills
const projectPath = path.join(deps.workingDir, '.claude/skills');
if (await exists(projectPath)) {
skills.push(...await loadSkillsFromDir(projectPath));
}
// Deduplicate by name (later layers override)
return deduplicateSkills(skills);
}SKILL.md前置元数据:
yaml
---
name: git-workflow-automation
version: 1.2.0
description: Automated git workflows with conventional commits
triggers:
- "create a feature branch"
- "commit with conventional format"
- "prepare a release"
dependencies:
tools: [execute_command, read_file, write_file]
mcpServers: [github]
config:
commitFormat: conventional
branchPrefix: feature/
autoSquash: true
parameters:
mainBranch: ${param.mainBranch|main}
remote: ${param.remote|origin}
signCommits: ${param.signCommits|false}
---3级参数替换:
typescript
function resolveParameters(
skillConfig: SkillConfig,
deps: QueryDeps
): Record<string, unknown> {
const resolved = {};
for (const [key, template] of Object.entries(skillConfig.parameters)) {
// Level 1: User-provided parameters
if (deps.userParams[key] !== undefined) {
resolved[key] = deps.userParams[key];
continue;
}
// Level 2: Environment variables
const envMatch = template.match(/\${env\.([^}|]+)(\|(.+))?}/);
if (envMatch) {
const [, envVar, , defaultValue] = envMatch;
resolved[key] = process.env[envVar] ?? defaultValue;
continue;
}
// Level 3: Default value
const defaultMatch = template.match(/\${param\.[^}|]+\|(.+)}/);
if (defaultMatch) {
resolved[key] = defaultMatch[1];
}
}
return resolved;
}分层加载:
typescript
async function loadSkills(deps: QueryDeps): Promise<Skill[]> {
const skills: Skill[] = [];
// Layer 1: Built-in skills
const builtinPath = path.join(__dirname, '../skills');
skills.push(...await loadSkillsFromDir(builtinPath));
// Layer 2: User skills
const userPath = path.join(deps.config.skillsDir);
if (await exists(userPath)) {
skills.push(...await loadSkillsFromDir(userPath));
}
// Layer 3: Project skills
const projectPath = path.join(deps.workingDir, '.claude/skills');
if (await exists(projectPath)) {
skills.push(...await loadSkillsFromDir(projectPath));
}
// Deduplicate by name (later layers override)
return deduplicateSkills(skills);
}10. Performance Optimization
10. 性能优化
Startup Optimization (Ch13: 160ms → 65ms, -59%):
typescript
// Before: Eager loading
async function initialize(deps: QueryDeps) {
await loadAllTools(); // 45ms
await loadAllSkills(); // 30ms
await connectAllMCP(); // 50ms
await loadMemory(); // 20ms
await initializeHooks(); // 15ms
// Total: 160ms
}
// After: Lazy + parallel loading
async function initialize(deps: QueryDeps) {
// Parallel critical path
await Promise.all([
loadCoreTools(), // 15ms (only essential tools)
initializeConversation() // 10ms
]);
// Defer non-critical
Promise.all([
lazyLoadSkills(), // Load on first trigger
lazyConnectMCP(), // Connect on first use
backgroundLoadMemory() // Index in background
]);
// Total: 25ms to first interaction, 65ms fully ready
}Lazy Tool Loading:
typescript
class LazyToolRegistry {
private loaded = new Set<string>();
private loaders = new Map<string, () => Promise<Tool>>();
register(name: string, loader: () => Promise<Tool>) {
this.loaders.set(name, loader);
}
async get(name: string): Promise<Tool> {
if (!this.loaded.has(name)) {
const tool = await this.loaders.get(name)!();
this.tools.set(name, tool);
this.loaded.add(name);
}
return this.tools.get(name)!;
}
}启动优化(第13章:从160ms优化至65ms,提升59%):
typescript
// Before: Eager loading
async function initialize(deps: QueryDeps) {
await loadAllTools(); // 45ms
await loadAllSkills(); // 30ms
await connectAllMCP(); // 50ms
await loadMemory(); // 20ms
await initializeHooks(); // 15ms
// Total: 160ms
}
// After: Lazy + parallel loading
async function initialize(deps: QueryDeps) {
// Parallel critical path
await Promise.all([
loadCoreTools(), // 15ms (仅加载核心工具)
initializeConversation() // 10ms
]);
// Defer non-critical
Promise.all([
lazyLoadSkills(), // 首次触发时加载
lazyConnectMCP(), // 首次使用时连接
backgroundLoadMemory() // 后台建立索引
]);
// Total: 25ms即可响应首次交互,65ms完全就绪
}懒加载工具:
typescript
class LazyToolRegistry {
private loaded = new Set<string>();
private loaders = new Map<string, () => Promise<Tool>>();
register(name: string, loader: () => Promise<Tool>) {
this.loaders.set(name, loader);
}
async get(name: string): Promise<Tool> {
if (!this.loaded.has(name)) {
const tool = await this.loaders.get(name)!();
this.tools.set(name, tool);
this.loaded.add(name);
}
return this.tools.get(name)!;
}
}Configuration
配置
6-Layer Priority Chain (Ch05):
- CLI arguments (highest)
- Environment variables
- Project config ()
.claude/config.json - User config ()
~/.claude/config.json - Workspace config
- Default config (lowest)
Example Config:
json
{
"model": "claude-3-7-sonnet-20250219",
"maxTokens": 8192,
"temperature": 0.7,
"tools": {
"enabled": ["read_file", "write_file", "execute_command"],
"disabled": ["browser_*"],
"concurrency": {
"max": 5,
"perCategory": 3
}
},
"permissions": {
"defaultMode": "confirm",
"rules": [
{ "pattern": "read_*", "mode": "auto" },
{ "pattern": "execute_command:rm *", "mode": "reject" }
]
},
"context": {
"maxTokens": 180000,
"compressionThreshold": 0.8,
"strategies": ["snip", "microCompact", "collapse", "autoCompact"]
},
"memory": {
"enabled": true,
"maxEntries": 1000,
"ttl": 2592000000
},
"hooks": {
"allowExternal": false,
"timeout": 5000
},
"mcp": {
"servers": {
"github": {
"command": "mcp-server-github",
"args": ["--token", "${env.GITHUB_TOKEN}"],
"protocol": "stdio"
}
}
},
"features": {
"enablePlanMode": true,
"enableSubAgents": true,
"maxForkDepth": 3
}
}6级优先级链(第5章):
- CLI参数(优先级最高)
- 环境变量
- 项目配置()
.claude/config.json - 用户配置()
~/.claude/config.json - 工作区配置
- 默认配置(优先级最低)
配置示例:
json
{
"model": "claude-3-7-sonnet-20250219",
"maxTokens": 8192,
"temperature": 0.7,
"tools": {
"enabled": ["read_file", "write_file", "execute_command"],
"disabled": ["browser_*"],
"concurrency": {
"max": 5,
"perCategory": 3
}
},
"permissions": {
"defaultMode": "confirm",
"rules": [
{ "pattern": "read_*", "mode": "auto" },
{ "pattern": "execute_command:rm *", "mode": "reject" }
]
},
"context": {
"maxTokens": 180000,
"compressionThreshold": 0.8,
"strategies": ["snip", "microCompact", "collapse", "autoCompact"]
},
"memory": {
"enabled": true,
"maxEntries": 1000,
"ttl": 2592000000
},
"hooks": {
"allowExternal": false,
"timeout": 5000
},
"mcp": {
"servers": {
"github": {
"command": "mcp-server-github",
"args": ["--token", "${env.GITHUB_TOKEN}"],
"protocol": "stdio"
}
}
},
"features": {
"enablePlanMode": true,
"enableSubAgents": true,
"maxForkDepth": 3
}
}Building Your Own Harness (Ch15)
构建你自己的Harness(第15章)
6-Step Implementation Roadmap:
typescript
// Step 1: Core conversation loop
async function* conversationLoop(deps: QueryDeps) {
while (true) {
const response = await streamLLM(deps);
yield { type: 'text', content: response.delta };
if (response.toolUse) {
const result = await executeTool(response.toolUse, deps);
yield { type: 'tool_result', data: result };
}
if (shouldTerminate(response)) break;
}
}
// Step 2: Tool registry with validation
const tools = new ToolRegistry();
tools.register(buildTool({
name: 'read_file',
input: z.object({ path: z.string() }),
execute: async (input) => await fs.readFile(input.path, 'utf-8')
}));
// Step 3: Permission pipeline
async function checkPermission(toolCall: ToolCall, deps: QueryDeps) {
const mode = matchRule(toolCall.name, deps.config.permissions);
if (mode === 'confirm') {
return await deps.ui.promptUser(toolCall);
}
return mode === 'auto';
}
// Step 4: Context compression
async function compressContext(messages: Message[], budget: number) {
let compressed = messages;
if (getTokens(compressed) > budget) {
compressed = snip(compressed, budget);
}
if (getTokens(compressed) > budget) {
compressed = await autoCompact(compressed);
}
return compressed;
}
// Step 5: Memory system
class MemorySystem {
async remember(fact: Memory) {
if (!await this.isDerivable(fact)) {
await this.store(fact);
}
}
async recall(query: string) {
return await this.vectorSearch(query);
}
}
// Step 6: Observability
class Metrics6步实现路线图:
typescript
// Step 1: Core conversation loop
async function* conversationLoop(deps: QueryDeps) {
while (true) {
const response = await streamLLM(deps);
yield { type: 'text', content: response.delta };
if (response.toolUse) {
const result = await executeTool(response.toolUse, deps);
yield { type: 'tool_result', data: result };
}
if (shouldTerminate(response)) break;
}
}
// Step 2: Tool registry with validation
const tools = new ToolRegistry();
tools.register(buildTool({
name: 'read_file',
input: z.object({ path: z.string() }),
execute: async (input) => await fs.readFile(input.path, 'utf-8')
}));
// Step 3: Permission pipeline
async function checkPermission(toolCall: ToolCall, deps: QueryDeps) {
const mode = matchRule(toolCall.name, deps.config.permissions);
if (mode === 'confirm') {
return await deps.ui.promptUser(toolCall);
}
return mode === 'auto';
}
// Step 4: Context compression
async function compressContext(messages: Message[], budget: number) {
let compressed = messages;
if (getTokens(compressed) > budget) {
compressed = snip(compressed, budget);
}
if (getTokens(compressed) > budget) {
compressed = await autoCompact(compressed);
}
return compressed;
}
// Step 5: Memory system
class MemorySystem {
async remember(fact: Memory) {
if (!await this.isDerivable(fact)) {
await this.store(fact);
}
}
async recall(query: string) {
return await this.vectorSearch(query);
}
}
// Step 6: Observability
class Metrics