claude-code-agent-architecture
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseClaude Code Agent Architecture
Claude Code Agent架构
Overview
概述
sanbuphy/learn-coding-agent- Core agent loop: How messages, tools, and API calls form the execution cycle
- Tool system: 40+ built-in tools with permission flows
- Telemetry & privacy: What data is collected and how
- Hidden features: Undercover mode, killswitches, remote control
- Architecture patterns: Production-grade harness mechanisms
This is a learning resource for understanding production coding agents, not the actual Claude Code source code.
sanbuphy/learn-coding-agent- 核心Agent循环:消息、工具和API调用如何构成执行周期
- 工具系统:40+内置工具及权限流程
- 遥测与隐私:收集的数据类型及方式
- 隐藏功能:卧底模式、终止开关、远程控制
- 架构模式:生产级管控机制
这是一个用于理解生产级编码Agent的学习资源,并非Claude Code的实际源代码。
Installation
安装
bash
undefinedbash
undefinedClone the research repository
Clone the research repository
git clone https://github.com/sanbuphy/learn-coding-agent.git
cd learn-coding-agent
git clone https://github.com/sanbuphy/learn-coding-agent.git
cd learn-coding-agent
Install dependencies (if you want to explore the documented structure)
Install dependencies (if you want to explore the documented structure)
npm install
npm install
or
or
bun install
**Note**: This is a documentation/research project. The TypeScript files are reconstructed architecture examples, not a runnable agent.bun install
**注意**:这是一个文档/研究项目。TypeScript文件是重构的架构示例,并非可运行的Agent。Core Agent Loop Pattern
核心Agent循环模式
The fundamental agent pattern documented in this research:
typescript
// The minimal agent loop
async function agentLoop(userMessage: string, messages: Message[]) {
messages.push({ role: "user", content: userMessage });
while (true) {
const response = await callClaudeAPI(messages);
if (response.stop_reason === "tool_use") {
// Execute tools
const toolResults = await executeTools(response.content);
messages.push({ role: "assistant", content: response.content });
messages.push({ role: "user", content: toolResults });
// Loop continues
} else {
// Return final text response
return response.content;
}
}
}本研究记录的基础Agent模式:
typescript
// The minimal agent loop
async function agentLoop(userMessage: string, messages: Message[]) {
messages.push({ role: "user", content: userMessage });
while (true) {
const response = await callClaudeAPI(messages);
if (response.stop_reason === "tool_use") {
// Execute tools
const toolResults = await executeTools(response.content);
messages.push({ role: "assistant", content: response.content });
messages.push({ role: "user", content: toolResults });
// Loop continues
} else {
// Return final text response
return response.content;
}
}
}The 12 Progressive Harness Mechanisms
12种进阶管控机制
Claude Code wraps the basic loop with production features:
- Permission System: User approval for file writes, command execution
- Streaming: Real-time token streaming with UI updates
- Concurrency: Parallel tool execution via
StreamingToolExecutor - Context Compaction: Automatic message history compression
- Sub-agents: Specialized agents (verification, review, planning)
- Persistence: Session state saved to disk
- MCP Integration: Model Context Protocol server support
- Cost Tracking: Token usage and API cost accumulation
- Analytics: Telemetry events (OpenTelemetry + Datadog)
- Remote Control: Feature flags and killswitches from server
- Error Recovery: Retry logic with exponential backoff
- Multi-transport: CLI, bridge, SDK interfaces
Claude Code为基础循环添加了生产级功能:
- 权限系统:文件写入、命令执行需用户批准
- 流式传输:实时令牌流及UI更新
- 并发处理:通过实现并行工具执行
StreamingToolExecutor - 上下文压缩:自动消息历史压缩
- 子Agent:专业化Agent(验证、评审、规划)
- 持久化:会话状态保存至磁盘
- MCP集成:支持Model Context Protocol服务器
- 成本追踪:令牌使用量及API成本累积
- 分析功能:遥测事件(OpenTelemetry + Datadog)
- 远程控制:来自服务器的功能标志和终止开关
- 错误恢复:带指数退避的重试逻辑
- 多传输方式:CLI、桥接、SDK接口
Tool System Architecture
工具系统架构
Built-in Tool Categories
内置工具分类
The research documents 40+ tools across categories:
typescript
// Tool registry structure
const toolRegistry = {
// File operations
"read_file": { category: "file", risk: "low" },
"write_to_file": { category: "file", risk: "high", requiresPermission: true },
"list_files": { category: "file", risk: "low" },
// Command execution
"execute_command": { category: "command", risk: "high", requiresPermission: true },
"spawn_agent": { category: "agent", risk: "medium" },
// Search & analysis
"search_files": { category: "search", risk: "low" },
"list_code_definition_names": { category: "code", risk: "low" },
// Browser control (via MCP)
"browser_navigate": { category: "browser", risk: "medium" },
"browser_click": { category: "browser", risk: "medium" },
// Memory & context
"store_memory": { category: "memory", risk: "low" },
"compact_context": { category: "system", risk: "low" }
};本研究记录了40+工具,涵盖多个分类:
typescript
// Tool registry structure
const toolRegistry = {
// File operations
"read_file": { category: "file", risk: "low" },
"write_to_file": { category: "file", risk: "high", requiresPermission: true },
"list_files": { category: "file", risk: "low" },
// Command execution
"execute_command": { category: "command", risk: "high", requiresPermission: true },
"spawn_agent": { category: "agent", risk: "medium" },
// Search & analysis
"search_files": { category: "search", risk: "low" },
"list_code_definition_names": { category: "code", risk: "low" },
// Browser control (via MCP)
"browser_navigate": { category: "browser", risk: "medium" },
"browser_click": { category: "browser", risk: "medium" },
// Memory & context
"store_memory": { category: "memory", risk: "low" },
"compact_context": { category: "system", risk: "low" }
};Permission Flow
权限流程
typescript
// Permission checking pattern
interface ToolPermission {
toolName: string;
approved: boolean;
autoApprove?: boolean; // User set in config
risk: "low" | "medium" | "high";
}
async function checkPermission(tool: Tool, args: any): Promise<boolean> {
// 1. Check auto-approve rules
if (config.autoApprove?.[tool.name]) {
return true;
}
// 2. Low-risk tools auto-approved
if (tool.risk === "low") {
return true;
}
// 3. Show permission dialog
const approved = await showPermissionDialog({
tool: tool.name,
description: tool.description,
args: sanitizeArgs(args),
risk: tool.risk
});
// 4. Log decision
analytics.track("tool_permission_decision", {
tool: tool.name,
approved,
autoApprove: false
});
return approved;
}typescript
// Permission checking pattern
interface ToolPermission {
toolName: string;
approved: boolean;
autoApprove?: boolean; // User set in config
risk: "low" | "medium" | "high";
}
async function checkPermission(tool: Tool, args: any): Promise<boolean> {
// 1. Check auto-approve rules
if (config.autoApprove?.[tool.name]) {
return true;
}
// 2. Low-risk tools auto-approved
if (tool.risk === "low") {
return true;
}
// 3. Show permission dialog
const approved = await showPermissionDialog({
tool: tool.name,
description: tool.description,
args: sanitizeArgs(args),
risk: tool.risk
});
// 4. Log decision
analytics.track("tool_permission_decision", {
tool: tool.name,
approved,
autoApprove: false
});
return approved;
}Tool Execution with Streaming
带流式传输的工具执行
typescript
// StreamingToolExecutor pattern
class StreamingToolExecutor {
async executeTools(toolCalls: ToolUse[]): Promise<ToolResult[]> {
const results: ToolResult[] = [];
// Group by parallelizable vs sequential
const parallel = toolCalls.filter(t => this.canRunInParallel(t));
const sequential = toolCalls.filter(t => !this.canRunInParallel(t));
// Execute parallel tools concurrently
if (parallel.length > 0) {
const parallelResults = await Promise.all(
parallel.map(tc => this.executeSingleTool(tc))
);
results.push(...parallelResults);
}
// Execute sequential tools one by one
for (const toolCall of sequential) {
const result = await this.executeSingleTool(toolCall);
results.push(result);
}
return results;
}
private async executeSingleTool(toolCall: ToolUse): Promise<ToolResult> {
const tool = toolRegistry.get(toolCall.name);
// Permission check
const approved = await checkPermission(tool, toolCall.input);
if (!approved) {
return {
tool_use_id: toolCall.id,
content: "Permission denied by user",
is_error: true
};
}
// Execute
try {
const output = await tool.execute(toolCall.input);
return {
tool_use_id: toolCall.id,
content: output
};
} catch (error) {
return {
tool_use_id: toolCall.id,
content: error.message,
is_error: true
};
}
}
}typescript
// StreamingToolExecutor pattern
class StreamingToolExecutor {
async executeTools(toolCalls: ToolUse[]): Promise<ToolResult[]> {
const results: ToolResult[] = [];
// Group by parallelizable vs sequential
const parallel = toolCalls.filter(t => this.canRunInParallel(t));
const sequential = toolCalls.filter(t => !this.canRunInParallel(t));
// Execute parallel tools concurrently
if (parallel.length > 0) {
const parallelResults = await Promise.all(
parallel.map(tc => this.executeSingleTool(tc))
);
results.push(...parallelResults);
}
// Execute sequential tools one by one
for (const toolCall of sequential) {
const result = await this.executeSingleTool(toolCall);
results.push(result);
}
return results;
}
private async executeSingleTool(toolCall: ToolUse): Promise<ToolResult> {
const tool = toolRegistry.get(toolCall.name);
// Permission check
const approved = await checkPermission(tool, toolCall.input);
if (!approved) {
return {
tool_use_id: toolCall.id,
content: "Permission denied by user",
is_error: true
};
}
// Execute
try {
const output = await tool.execute(toolCall.input);
return {
tool_use_id: toolCall.id,
content: output
};
} catch (error) {
return {
tool_use_id: toolCall.id,
content: error.message,
is_error: true
};
}
}
}Key Architectural Components
关键架构组件
1. Query Engine
1. 查询引擎
typescript
// QueryEngine.ts - SDK/headless query lifecycle
class QueryEngine {
private messages: Message[] = [];
private state: TaskState;
async runQuery(input: string, options?: QueryOptions): Promise<QueryResult> {
// Add user message
this.messages.push({ role: "user", content: input });
// Context compaction if needed
if (this.shouldCompact()) {
await this.compactContext();
}
// Main loop
while (true) {
const response = await this.callAPI();
if (response.stop_reason === "tool_use") {
const toolResults = await this.toolExecutor.executeTools(
response.content.filter(c => c.type === "tool_use")
);
this.messages.push({ role: "assistant", content: response.content });
this.messages.push({ role: "user", content: toolResults });
} else {
return { output: response.content, messages: this.messages };
}
}
}
private async compactContext(): Promise<void> {
const compactedMessages = await this.compactionService.compact(
this.messages,
{ strategy: "adaptive" }
);
this.messages = compactedMessages;
}
}typescript
// QueryEngine.ts - SDK/headless query lifecycle
class QueryEngine {
private messages: Message[] = [];
private state: TaskState;
async runQuery(input: string, options?: QueryOptions): Promise<QueryResult> {
// Add user message
this.messages.push({ role: "user", content: input });
// Context compaction if needed
if (this.shouldCompact()) {
await this.compactContext();
}
// Main loop
while (true) {
const response = await this.callAPI();
if (response.stop_reason === "tool_use") {
const toolResults = await this.toolExecutor.executeTools(
response.content.filter(c => c.type === "tool_use")
);
this.messages.push({ role: "assistant", content: response.content });
this.messages.push({ role: "user", content: toolResults });
} else {
return { output: response.content, messages: this.messages };
}
}
}
private async compactContext(): Promise<void> {
const compactedMessages = await this.compactionService.compact(
this.messages,
{ strategy: "adaptive" }
);
this.messages = compactedMessages;
}
}2. MCP Integration
2. MCP集成
typescript
// MCP (Model Context Protocol) server management
interface MCPServer {
name: string;
command: string;
args: string[];
env?: Record<string, string>;
}
class MCPManager {
private servers: Map<string, MCPServerInstance> = new Map();
async connectServer(config: MCPServer): Promise<void> {
const instance = await this.spawn({
command: config.command,
args: config.args,
env: { ...process.env, ...config.env }
});
// Register tools from server
const tools = await instance.listTools();
tools.forEach(tool => {
toolRegistry.register(`mcp_${config.name}_${tool.name}`, tool);
});
this.servers.set(config.name, instance);
}
async callMCPTool(serverName: string, toolName: string, args: any): Promise<any> {
const server = this.servers.get(serverName);
return await server.callTool(toolName, args);
}
}
// Example MCP configuration
const mcpConfig = {
"mcpServers": {
"puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
},
"filesystem": {
"command": "node",
"args": ["/path/to/mcp-server-filesystem/dist/index.js"],
"env": {
"ALLOWED_PATHS": "/workspace"
}
}
}
};typescript
// MCP (Model Context Protocol) server management
interface MCPServer {
name: string;
command: string;
args: string[];
env?: Record<string, string>;
}
class MCPManager {
private servers: Map<string, MCPServerInstance> = new Map();
async connectServer(config: MCPServer): Promise<void> {
const instance = await this.spawn({
command: config.command,
args: config.args,
env: { ...process.env, ...config.env }
});
// Register tools from server
const tools = await instance.listTools();
tools.forEach(tool => {
toolRegistry.register(`mcp_${config.name}_${tool.name}`, tool);
});
this.servers.set(config.name, instance);
}
async callMCPTool(serverName: string, toolName: string, args: any): Promise<any> {
const server = this.servers.get(serverName);
return await server.callTool(toolName, args);
}
}
// Example MCP configuration
const mcpConfig = {
"mcpServers": {
"puppeteer": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-puppeteer"]
},
"filesystem": {
"command": "node",
"args": ["/path/to/mcp-server-filesystem/dist/index.js"],
"env": {
"ALLOWED_PATHS": "/workspace"
}
}
}
};3. Telemetry System
3. 遥测系统
typescript
// Analytics infrastructure
interface AnalyticsEvent {
event: string;
properties: Record<string, any>;
userId?: string;
sessionId: string;
timestamp: number;
}
class AnalyticsService {
private sinks = {
firstParty: new OpenTelemetryClient(),
datadog: new DatadogClient()
};
track(event: string, properties: Record<string, any>): void {
const payload: AnalyticsEvent = {
event,
properties: {
...properties,
// Automatic fingerprinting
os: process.platform,
arch: process.arch,
nodeVersion: process.version,
appVersion: packageJson.version,
repoHash: this.getRepoHash(), // SHA256 of git remote URL
},
sessionId: this.sessionId,
timestamp: Date.now()
};
// Send to both sinks
this.sinks.firstParty.send(payload);
this.sinks.datadog.send(payload);
// Detailed tool logging if enabled
if (process.env.OTEL_LOG_TOOL_DETAILS === "1") {
this.logToolDetails(payload);
}
}
trackToolUse(tool: string, args: any, result: any): void {
this.track("tool_executed", {
tool,
argsSize: JSON.stringify(args).length,
resultSize: JSON.stringify(result).length,
success: !result.is_error
});
}
}typescript
// Analytics infrastructure
interface AnalyticsEvent {
event: string;
properties: Record<string, any>;
userId?: string;
sessionId: string;
timestamp: number;
}
class AnalyticsService {
private sinks = {
firstParty: new OpenTelemetryClient(),
datadog: new DatadogClient()
};
track(event: string, properties: Record<string, any>): void {
const payload: AnalyticsEvent = {
event,
properties: {
...properties,
// Automatic fingerprinting
os: process.platform,
arch: process.arch,
nodeVersion: process.version,
appVersion: packageJson.version,
repoHash: this.getRepoHash(), // SHA256 of git remote URL
},
sessionId: this.sessionId,
timestamp: Date.now()
};
// Send to both sinks
this.sinks.firstParty.send(payload);
this.sinks.datadog.send(payload);
// Detailed tool logging if enabled
if (process.env.OTEL_LOG_TOOL_DETAILS === "1") {
this.logToolDetails(payload);
}
}
trackToolUse(tool: string, args: any, result: any): void {
this.track("tool_executed", {
tool,
argsSize: JSON.stringify(args).length,
resultSize: JSON.stringify(result).length,
success: !result.is_error
});
}
}4. Feature Flags & Remote Control
4. 功能标志与远程控制
typescript
// Remote settings management
interface RemoteSettings {
killswitches: {
disable_bypass_permissions?: boolean;
disable_fast_mode?: boolean;
disable_analytics?: boolean;
};
modelOverrides?: {
defaultModel?: string;
enabledModels?: string[];
};
experimentFlags?: Record<string, any>;
}
class SettingsSyncService {
private pollInterval = 60 * 60 * 1000; // 1 hour
async poll(): Promise<void> {
const settings = await fetch(
"https://api.claude.ai/api/claude_code/settings",
{ headers: { Authorization: `Bearer ${this.token}` } }
).then(r => r.json());
// Apply killswitches
if (settings.killswitches?.disable_bypass_permissions) {
config.bypassPermissions = false;
}
// Show blocking dialog for dangerous changes
if (this.isDangerousChange(settings)) {
const accepted = await showBlockingDialog({
title: "Critical Update Required",
message: "Claude Code settings have changed. Accept to continue.",
actions: ["Accept", "Reject (Exit)"]
});
if (!accepted) {
process.exit(1); // User rejected = app exits
}
}
// Apply GrowthBook experiments
this.applyExperiments(settings.experimentFlags);
}
}typescript
// Remote settings management
interface RemoteSettings {
killswitches: {
disable_bypass_permissions?: boolean;
disable_fast_mode?: boolean;
disable_analytics?: boolean;
};
modelOverrides?: {
defaultModel?: string;
enabledModels?: string[];
};
experimentFlags?: Record<string, any>;
}
class SettingsSyncService {
private pollInterval = 60 * 60 * 1000; // 1 hour
async poll(): Promise<void> {
const settings = await fetch(
"https://api.claude.ai/api/claude_code/settings",
{ headers: { Authorization: `Bearer ${this.token}` } }
).then(r => r.json());
// Apply killswitches
if (settings.killswitches?.disable_bypass_permissions) {
config.bypassPermissions = false;
}
// Show blocking dialog for dangerous changes
if (this.isDangerousChange(settings)) {
const accepted = await showBlockingDialog({
title: "Critical Update Required",
message: "Claude Code settings have changed. Accept to continue.",
actions: ["Accept", "Reject (Exit)"]
});
if (!accepted) {
process.exit(1); // User rejected = app exits
}
}
// Apply GrowthBook experiments
this.applyExperiments(settings.experimentFlags);
}
}Common Patterns
通用模式
Building a Custom Tool
构建自定义工具
typescript
// Tool.ts pattern
import { buildTool } from "./Tool";
const customTool = buildTool({
name: "analyze_code_quality",
description: "Analyzes code quality metrics for a given file",
parameters: {
type: "object",
properties: {
filePath: { type: "string", description: "Path to file" },
metrics: {
type: "array",
items: { type: "string" },
description: "Metrics to analyze (complexity, coverage, etc.)"
}
},
required: ["filePath"]
},
async execute({ filePath, metrics = ["complexity"] }) {
// Read file
const content = await fs.readFile(filePath, "utf-8");
// Run analysis
const results = await analyzeCode(content, metrics);
// Return structured output
return {
file: filePath,
metrics: results,
summary: `Analyzed ${metrics.length} metrics for ${filePath}`
};
},
// Tool metadata
category: "code",
risk: "low",
requiresPermission: false
});
// Register tool
toolRegistry.register("analyze_code_quality", customTool);typescript
// Tool.ts pattern
import { buildTool } from "./Tool";
const customTool = buildTool({
name: "analyze_code_quality",
description: "Analyzes code quality metrics for a given file",
parameters: {
type: "object",
properties: {
filePath: { type: "string", description: "Path to file" },
metrics: {
type: "array",
items: { type: "string" },
description: "Metrics to analyze (complexity, coverage, etc.)"
}
},
required: ["filePath"]
},
async execute({ filePath, metrics = ["complexity"] }) {
// Read file
const content = await fs.readFile(filePath, "utf-8");
// Run analysis
const results = await analyzeCode(content, metrics);
// Return structured output
return {
file: filePath,
metrics: results,
summary: `Analyzed ${metrics.length} metrics for ${filePath}`
};
},
// Tool metadata
category: "code",
risk: "low",
requiresPermission: false
});
// Register tool
toolRegistry.register("analyze_code_quality", customTool);Implementing Sub-agents
实现子Agent
typescript
// Sub-agent pattern (verification, review, planning)
class SubAgent {
constructor(
private role: string,
private systemPrompt: string
) {}
async run(task: string, context: any): Promise<string> {
const messages = [
{ role: "system", content: this.systemPrompt },
{ role: "user", content: this.formatTask(task, context) }
];
const response = await callClaudeAPI({
messages,
model: "claude-sonnet-4.0", // Sub-agents use specific models
max_tokens: 4096
});
return response.content[0].text;
}
private formatTask(task: string, context: any): string {
return `Task: ${task}\n\nContext:\n${JSON.stringify(context, null, 2)}`;
}
}
// Example: Code review sub-agent
const reviewAgent = new SubAgent(
"code_reviewer",
`You are a code review expert. Analyze the provided code changes for:
- Security issues
- Performance problems
- Best practice violations
Provide specific, actionable feedback.`
);
const reviewResult = await reviewAgent.run(
"Review this pull request",
{ diff, files, description }
);typescript
// Sub-agent pattern (verification, review, planning)
class SubAgent {
constructor(
private role: string,
private systemPrompt: string
) {}
async run(task: string, context: any): Promise<string> {
const messages = [
{ role: "system", content: this.systemPrompt },
{ role: "user", content: this.formatTask(task, context) }
];
const response = await callClaudeAPI({
messages,
model: "claude-sonnet-4.0", // Sub-agents use specific models
max_tokens: 4096
});
return response.content[0].text;
}
private formatTask(task: string, context: any): string {
return `Task: ${task}\n\nContext:\n${JSON.stringify(context, null, 2)}`;
}
}
// Example: Code review sub-agent
const reviewAgent = new SubAgent(
"code_reviewer",
`You are a code review expert. Analyze the provided code changes for:
- Security issues
- Performance problems
- Best practice violations
Provide specific, actionable feedback.`
);
const reviewResult = await reviewAgent.run(
"Review this pull request",
{ diff, files, description }
);Context Compaction Strategy
上下文压缩策略
typescript
// Adaptive context compaction
class CompactionService {
async compact(messages: Message[], options: CompactOptions): Promise<Message[]> {
const totalTokens = this.estimateTokens(messages);
if (totalTokens < options.maxTokens) {
return messages; // No compaction needed
}
// Strategy: Keep recent messages, summarize old ones
const recentMessages = messages.slice(-10); // Keep last 10
const oldMessages = messages.slice(0, -10);
// Summarize old conversation
const summary = await this.summarizeMessages(oldMessages);
return [
{ role: "system", content: `Previous conversation summary:\n${summary}` },
...recentMessages
];
}
private async summarizeMessages(messages: Message[]): Promise<string> {
const response = await callClaudeAPI({
messages: [
{ role: "user", content: `Summarize this conversation concisely:\n${JSON.stringify(messages)}` }
],
model: "claude-haiku-4.0", // Use fast model for summaries
max_tokens: 1024
});
return response.content[0].text;
}
}typescript
// Adaptive context compaction
class CompactionService {
async compact(messages: Message[], options: CompactOptions): Promise<Message[]> {
const totalTokens = this.estimateTokens(messages);
if (totalTokens < options.maxTokens) {
return messages; // No compaction needed
}
// Strategy: Keep recent messages, summarize old ones
const recentMessages = messages.slice(-10); // Keep last 10
const oldMessages = messages.slice(0, -10);
// Summarize old conversation
const summary = await this.summarizeMessages(oldMessages);
return [
{ role: "system", content: `Previous conversation summary:\n${summary}` },
...recentMessages
];
}
private async summarizeMessages(messages: Message[]): Promise<string> {
const response = await callClaudeAPI({
messages: [
{ role: "user", content: `Summarize this conversation concisely:\n${JSON.stringify(messages)}` }
],
model: "claude-haiku-4.0", // Use fast model for summaries
max_tokens: 1024
});
return response.content[0].text;
}
}Configuration
配置
Environment Variables
环境变量
bash
undefinedbash
undefinedAPI Configuration
API Configuration
ANTHROPIC_API_KEY=sk-ant-xxx # Required for Claude API
ANTHROPIC_API_KEY=sk-ant-xxx # Required for Claude API
Analytics Control
Analytics Control
OTEL_LOG_TOOL_DETAILS=1 # Enable detailed tool logging (default: 0)
ANALYTICS_ENABLED=true # Enable telemetry (default: true)
OTEL_LOG_TOOL_DETAILS=1 # Enable detailed tool logging (default: 0)
ANALYTICS_ENABLED=true # Enable telemetry (default: true)
Feature Flags
Feature Flags
ENABLE_FAST_MODE=true # Enable fast mode (Haiku for simple tasks)
ENABLE_VOICE_MODE=false # Enable voice input (experimental)
ENABLE_UNDERCOVER_MODE=false # Hide AI attribution in commits
ENABLE_FAST_MODE=true # Enable fast mode (Haiku for simple tasks)
ENABLE_VOICE_MODE=false # Enable voice input (experimental)
ENABLE_UNDERCOVER_MODE=false # Hide AI attribution in commits
MCP Configuration
MCP Configuration
MCP_SERVER_PATH=/path/to/mcp-servers
MCP_ALLOWED_PATHS=/workspace,/home/user/projects
MCP_SERVER_PATH=/path/to/mcp-servers
MCP_ALLOWED_PATHS=/workspace,/home/user/projects
Debug
Debug
DEBUG=claude:* # Enable debug logging
LOG_LEVEL=info # Log level (debug|info|warn|error)
undefinedDEBUG=claude:* # Enable debug logging
LOG_LEVEL=info # Log level (debug|info|warn|error)
undefinedConfiguration File
配置文件
json
// ~/.claude/config.json
{
"defaultModel": "claude-sonnet-4.0",
"autoApprove": {
"read_file": true,
"list_files": true,
"search_files": true
},
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
}
},
"maxTokens": 8192,
"compactionThreshold": 100000,
"telemetry": {
"enabled": true,
"userId": "anonymous"
}
}json
// ~/.claude/config.json
{
"defaultModel": "claude-sonnet-4.0",
"autoApprove": {
"read_file": true,
"list_files": true,
"search_files": true
},
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"]
}
},
"maxTokens": 8192,
"compactionThreshold": 100000,
"telemetry": {
"enabled": true,
"userId": "anonymous"
}
}Research Reports
研究报告
The repository includes deep-dive reports in 4 languages:
本仓库包含4种语言的深度研究报告:
Key Reports
核心报告
01-telemetry-and-privacy: Documents two analytics sinks (OpenTelemetry + Datadog), environment fingerprinting, and why opt-out isn't exposed in UI.
02-hidden-features-and-codenames: Reveals animal codenames (Capybara, Tengu, Numbat), feature flags using random word pairs, and internal vs external user differences.
03-undercover-mode: Official employees auto-enter mode that instructs the model to hide AI authorship in public repos ("Do not blow your cover").
04-remote-control-and-killswitches: Hourly polling of settings API, blocking dialogs that exit the app on rejection, 6+ killswitches.
05-future-roadmap: Upcoming Numbat model, KAIROS autonomous mode with heartbeats, voice mode, 17 unreleased tools.
<tick>Access reports in directories.
docs/[en|ja|ko|zh]/01-telemetry-and-privacy:记录两种分析接收器(OpenTelemetry + Datadog)、环境指纹识别,以及UI中未提供退出选项的原因。
02-hidden-features-and-codenames:揭示动物代号(水豚、天狗、袋食蚁兽)、使用随机词对的功能标志,以及内部用户与外部用户的差异。
03-undercover-mode:官方员工会自动进入该模式,指示模型在公共仓库中隐藏AI作者身份(“不要暴露身份”)。
04-remote-control-and-killswitches:每小时轮询设置API,拒绝后会退出应用的阻塞对话框,6+个终止开关。
05-future-roadmap:即将推出的Numbat模型、带有心跳的KAIROS自主模式、语音模式、17个未发布工具。
<tick>可在目录中查看报告。
docs/[en|ja|ko|zh]/Troubleshooting
故障排除
Understanding Agent Behavior
理解Agent行为
typescript
// Enable verbose logging to see agent decision process
process.env.DEBUG = "claude:*";
process.env.LOG_LEVEL = "debug";
// This will log:
// - API requests/responses
// - Tool execution decisions
// - Permission checks
// - Context compaction triggerstypescript
// Enable verbose logging to see agent decision process
process.env.DEBUG = "claude:*";
process.env.LOG_LEVEL = "debug";
// This will log:
// - API requests/responses
// - Tool execution decisions
// - Permission checks
// - Context compaction triggersAnalyzing Tool Permissions
分析工具权限
typescript
// Check which tools require permission
const highRiskTools = Array.from(toolRegistry.entries())
.filter(([_, tool]) => tool.risk === "high")
.map(([name, _]) => name);
console.log("High-risk tools:", highRiskTools);
// Output: ["write_to_file", "execute_command", "delete_file", ...]typescript
// Check which tools require permission
const highRiskTools = Array.from(toolRegistry.entries())
.filter(([_, tool]) => tool.risk === "high")
.map(([name, _]) => name);
console.log("High-risk tools:", highRiskTools);
// Output: ["write_to_file", "execute_command", "delete_file", ...]Debugging MCP Connections
调试MCP连接
typescript
// Test MCP server connection
const mcpManager = new MCPManager();
try {
await mcpManager.connectServer({
name: "test-server",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-puppeteer"]
});
const tools = await mcpManager.listTools("test-server");
console.log("Available MCP tools:", tools);
} catch (error) {
console.error("MCP connection failed:", error.message);
// Common issues: command not found, port conflicts, auth failures
}typescript
// Test MCP server connection
const mcpManager = new MCPManager();
try {
await mcpManager.connectServer({
name: "test-server",
command: "npx",
args: ["-y", "@modelcontextprotocol/server-puppeteer"]
});
const tools = await mcpManager.listTools("test-server");
console.log("Available MCP tools:", tools);
} catch (error) {
console.error("MCP connection failed:", error.message);
// Common issues: command not found, port conflicts, auth failures
}Inspecting Telemetry Events
检查遥测事件
bash
undefinedbash
undefinedEnable full tool argument logging
Enable full tool argument logging
export OTEL_LOG_TOOL_DETAILS=1
export OTEL_LOG_TOOL_DETAILS=1
Run agent and grep for tool events
Run agent and grep for tool events
claude-code | grep "tool_executed"
claude-code | grep "tool_executed"
You'll see:
You'll see:
{"event":"tool_executed","tool":"write_to_file","argsSize":1234,...}
{"event":"tool_executed","tool":"write_to_file","argsSize":1234,...}
undefinedundefinedAdditional Resources
额外资源
- Repository: https://github.com/sanbuphy/learn-coding-agent
- Deep Analysis Reports: directory (EN/JA/KO/ZH)
docs/ - Architecture Diagrams: Referenced in research reports
- Related Projects:
- Model Context Protocol: https://modelcontextprotocol.io
- Anthropic Claude API: https://docs.anthropic.com
Note: This is a research and educational repository. It documents publicly available information about coding agent architecture. For production coding agent development, refer to official Anthropic documentation and Claude API guides.
- 仓库地址:https://github.com/sanbuphy/learn-coding-agent
- 深度分析报告:目录(英/日/韩/中)
docs/ - 架构图:研究报告中引用
- 相关项目:
- Model Context Protocol: https://modelcontextprotocol.io
- Anthropic Claude API: https://docs.anthropic.com
注意:这是一个研究和教育仓库。它记录了关于编码Agent架构的公开信息。如需开发生产级编码Agent,请参考官方Anthropic文档和Claude API指南。