Claude Code泄漏的文件分析的Agent Skills等使用

Ai分析结果

------ 大模型如何调用 Agent、Skills 与上下文管理

基于 v2.1.88 源码的技术分析


目录

  1. [Agent 调用机制](#Agent 调用机制 "#1-agent-%E8%B0%83%E7%94%A8%E6%9C%BA%E5%88%B6")
  2. [Skills 调用机制](#Skills 调用机制 "#2-Skills-%E8%B0%83%E7%94%A8%E6%9C%BA%E5%88%B6")
  3. 上下文管理机制
  4. 完整调用链路
  5. 关键设计模式

1. Agent 调用机制

1.1 AgentTool 输入参数

位置 : src/tools/AgentTool/AgentTool.tsx (228KB, 1398 行)

核心输入 Schema:

typescript 复制代码
const baseInputSchema = z.object({
  description: z.string().describe('3-5 字任务描述'),
  prompt: z.string().describe('要执行的任务'),
  subagent_type: z.string().optional().describe('使用的代理类型'),
  model: z.enum(['sonnet', 'opus', 'haiku']).optional().describe('模型覆盖'),
  run_in_background: z.boolean().optional().describe('是否后台运行')
})

1.2 三种执行模式详解

模式 A:同步执行(默认)------ 共享进程,独立对话

typescript 复制代码
// src/tools/AgentTool/runAgent.ts:56-384
for await (const message of runAgent({
  agentDefinition,
  promptMessages,
  toolUseContext: { ...context },
  canUseTool,
  isAsync: false,
  querySource: 'agent:custom',
})) {
  agentMessages.push(message)
}

特点:

  • ✅ 共享同一进程,内存开销小
  • ✅ 共享文件缓存,减少重复 IO
  • ✅ 独立的消息历史 (messages[])
  • ⚡ 适合快速任务(读取文件、简单修改等)

模式 B:Fork 子进程 ------ 完全隔离,资源独立

typescript 复制代码
// src/tools/AgentTool/forkSubagent.ts:130-256
async function runForkedAgent(...) {
  // 1. 创建独立进程
  const child = forkAgentProcess({
    agentId,
    messages: buildForkedMessages(parent),
    tools: availableTools,
    cwd: worktreePath  // 可选的 git worktree 隔离
  })
  
  // 2. 共享文件缓存,独立消息历史
  return child.result
}

特点:

  • ✅ 独立进程空间,完全隔离
  • ✅ 共享文件缓存(性能优化)
  • ✅ 完全独立的对话历史
  • ✅ 可配置 git worktree 物理隔离
  • ⚡ 适合长期任务(功能开发、测试等)

模式 C:远程代理 ------ 云端执行,资源弹性

typescript 复制代码
// src/tasks/RemoteAgentTask/RemoteAgentTask.ts:88-267
async function launchRemoteAgent() {
  // 通过 Bridge 协议启动远程会话
  const session = await bridgeApi.createSession({
    type: 'remote_agent',
    resources: { cpu: 4, memory: '8GB' }
  })
  
  return { status: 'remote_launched', sessionUrl }
}

特点:

  • ✅ 远程服务器执行,不占用本地资源
  • ✅ 资源配置灵活(CPU/内存可调)
  • ✅ 可监控的会话 URL
  • ⚡ 适合重型任务(大型重构、数据分析等)

1.3 Agent 孵化的完整流程

graph TB A[用户请求] --> B[AgentTool.validateInput] B --> C[检查权限] C --> D{运行模式?} D -->|同步 | E[runAgent - 主线程] D -->|Fork| F[spawn 子进程] D -->|远程 | G[Bridge 远程会话] E --> H[独立的 query 循环] F --> H G --> H H --> I[工具执行] I --> J{需要权限?} J -->|是 | K[询问用户] J -->|否 | L[执行工具] K --> L L --> M{还有工具调用?} M -->|是 | I M -->|否 | N[返回结果] N --> O[追加 tool_result] O --> P[父代理继续]

1.4 多代理协作协议

团队管理 Schema:

typescript 复制代码
// src/tools/AgentTool/AgentTool.tsx:89-97
const multiAgentInputSchema = z.object({
  name: z.string().optional().describe('可寻址的代理名称'),
  team_name: z.string().optional().describe('团队名称'),
  mode: permissionModeSchema().optional().describe('权限模式')
})

代理间通信工具:

typescript 复制代码
// 通过 SendMessageTool 进行代理间通信
SendMessageTool.call({
  to: 'teammate-name',
  message: '请审查这个 PR'
})

2. Skills 调用机制

2.1 SkillsTool 架构与输入

位置 : src/tools/SkillsTool/SkillsTool.ts (1109 行)

核心输入 Schema:

typescript 复制代码
export const inputSchema = z.object({
  Skills: z.string().describe('技能名称,如 "commit", "review-pr"'),
  args: z.string().optional().describe('可选参数')
})

2.2 两种执行方式对比

方式 A:Inline 扩展 ------ 轻量级提示词注入

核心流程 (call() 函数,第 634-775 行):

typescript 复制代码
// 1. 加载 Skills 提示词
const command = findCommand(Skills, commands)

// 2. 处理提示词(!command 替换、$ARGUMENTS 插值)
const processedCommand = await processPromptSlashCommand(
  Skills, args, commands, context
)

// 3. 生成新消息注入对话
const newMessages = tagMessagesWithToolUseID(
  processedCommand.messages,
  toolUseID
)

// 4. 修改上下文(允许的工具、模型覆盖、努力程度)
return {
  data: { success: true, commandName: Skills },
  newMessages,
  contextModifier: ctx => ({
    ...ctx,
    options: {
      ...ctx.options,
      mainLoopModel: resolveSkillsModelOverride(
        command.model, 
        ctx.mainLoopModel
      )
    }
  })
}

特点:

  • ✅ 轻量级扩展,无额外进程开销
  • ✅ 直接注入对话,立即生效
  • ✅ 可动态修改上下文(工具权限、模型、努力程度)
  • ⚡ 适合简单工作流(代码审查、提交信息等)

方式 B:Fork 子代理 ------ 隔离执行,实时进度

核心流程 (executeForkedSkills() 函数,第 122-289 行):

typescript 复制代码
async function executeForkedSkills(command, args, context) {
  // 1. 准备隔离的上下文
  const { modifiedGetAppState, promptMessages, SkillsContent } = 
    await prepareForkedCommandContext(command, args, context)
  
  // 2. 在独立代理中运行
  for await (const message of runAgent({
    agentDefinition: { ...baseAgent, effort: command.effort },
    promptMessages,
    toolUseContext: { ...context, getAppState: modifiedGetAppState },
    querySource: 'agent:custom'
  })) {
    agentMessages.push(message)
    // 报告进度
    onProgress?.({ toolUseID, data: { message, type: 'Skills_progress' }})
  }
  
  // 3. 提取结果
  return {
    status: 'forked',
    agentId,
    result: extractResultText(agentMessages)
  }
}

特点:

  • ✅ 独立 token 预算,不占用父代理上下文
  • ✅ 隔离的执行环境,避免干扰
  • ✅ 实时进度报告(Skills_progress)
  • ✅ 可配置努力程度(effort)
  • ⚡ 适合复杂工作流(PR 审查、PDF 处理等)

2.3 Skills 发现与加载机制

三级 Skills 来源:

  1. 本地 Skillss : ~/.claude/Skillss/ 或项目 .claude/Skillss/
  2. MCP Skillss: 通过 MCP 协议连接的外部服务
  3. 远程 Skillss: AKI/GCS云存储(实验性,仅内部)

MCP Skillss 集成:

typescript 复制代码
// src/tools/SkillsTool/SkillsTool.ts:81-94
async function getAllCommands(context) {
  // 从 AppState 获取 MCP Skillss
  const mcpSkillss = context.getAppState()
    .mcp.commands.filter(cmd => cmd.type === 'prompt' && cmd.loadedFrom === 'mcp')
  
  // 合并本地 Skillss
  const localCommands = await getCommands(getProjectRoot())
  return uniqBy([...localCommands, ...mcpSkillss], 'name')
}

远程 Skillss (实验性,仅内部):

typescript 复制代码
// src/tools/SkillsTool/SkillsTool.ts:969-1108
async function executeRemoteSkills(slug, commandName, parentMessage, context) {
  // 从 AKI/GCS 加载远程 Skills
  const loadResult = await loadRemoteSkills(slug, meta.url)
  
  // 注入到对话
  return {
    data: { success: true, commandName, status: 'inline' },
    newMessages: [createUserMessage({ content: finalContent, isMeta: true })]
  }
}

2.4 Skills 权限检查流程

四步权限检查 (checkPermissions() 函数,第 432-578 行):

typescript 复制代码
async function checkPermissions({ Skills, args }, context) {
  const commandObj = findCommand(Skills, commands)
  
  // 1. 检查拒绝规则(优先级最高)
  const denyRules = getRuleByContentsForTool(
    permissionContext, SkillsTool, 'deny'
  )
  if (denyRules.matches(Skills)) return { behavior: 'deny' }
  
  // 2. 检查允许规则
  const allowRules = getRuleByContentsForTool(
    permissionContext, SkillsTool, 'allow'
  )
  if (allowRules.matches(Skills)) return { behavior: 'allow' }
  
  // 3. 安全检查(仅允许安全属性)
  if (SkillsHasOnlySafeProperties(commandObj)) {
    return { behavior: 'allow' }
  }
  
  // 4. 默认:询问用户
  return {
    behavior: 'ask',
    suggestions: [
      { type: 'addRules', rule: { toolName: 'Skills', ruleContent: Skills } }
    ]
  }
}

安全属性白名单 (28 个):

typescript 复制代码
const SAFE_Skills_PROPERTIES = new Set([
  'type', 'model', 'effort', 'source', 'context',
  'name', 'description', 'isEnabled', 'aliases',
  'paths', 'version', 'disableModelInvocation',
  // ... 共 28 个安全属性
])

匹配规则示例:

  • 精确匹配:commit → 允许 commit Skills
  • 前缀匹配:review:* → 允许所有 review- 开头的 Skillss

3. 上下文管理机制

3.1 三层压缩策略详解

阈值配置 (src/services/compact/autoCompact.ts):

typescript 复制代码
export const AUTOCOMPACT_BUFFER_TOKENS = 13_000
export const WARNING_THRESHOLD_BUFFER_TOKENS = 20_000
export const ERROR_THRESHOLD_BUFFER_TOKENS = 20_000
export const MANUAL_COMPACT_BUFFER_TOKENS = 3_000

策略 A:autoCompact(自动总结)------ API 调用,智能压缩

触发条件:

typescript 复制代码
function getAutoCompactThreshold(model: string): number {
  const effectiveContextWindow = getEffectiveContextWindowSize(model)
  return effectiveContextWindow - AUTOCOMPACT_BUFFER_TOKENS
}

压缩流程:

typescript 复制代码
if (tokenCount >= autoCompactThreshold && !tracking.compacted) {
  // 1. 调用 Claude API 总结旧消息
  const { summary, boundaryMessage } = await compactConversation(messages)
  
  // 2. 重建消息数组
  messages = [summary, boundaryMessage, ...recentMessages]
  
  // 3. 标记已压缩,防止重复压缩
  tracking.compacted = true
}

特点:

  • ✅ 智能总结,保留关键信息
  • ✅ 需要 API 调用,有成本
  • ✅ 保留 compact_boundary 标记,支持恢复
  • ⚡ 适用于长对话场景

策略 B:snipCompact(剪切僵尸消息)------ 本地过滤,零成本

功能实现 (src/services/compact/snipCompact.js, feature-gated):

typescript 复制代码
function snipCompact(messages) {
  // 移除过时的标记和僵尸消息
  const snipped = messages.filter(msg => {
    return !isZombieMarker(msg) && !isStaleProgress(msg)
  })
  
  const tokensFreed = countTokens(messages) - countTokens(snipped)
  return { snipped, tokensFreed }
}

特点:

  • ✅ 本地过滤,零 API 成本
  • ✅ 清理无效消息(zombie markers, stale progress)
  • ✅ 快速释放上下文空间
  • ⚡ 作为 autoCompact 的前置优化

策略 C:contextCollapse(重构上下文)------ 实验性结构优化

实验性功能 (src/services/contextCollapse/index.js, feature-gated):

typescript 复制代码
async function contextCollapse(messages) {
  // 重构上下文结构以提高效率
  const restructured = await restructureContext(messages)
  return restructured
}

特点:

  • ✅ 重构消息结构,提升检索效率
  • ✅ 实验性功能,需 feature flag 开启
  • ⚡ 适用于超长对话场景

3.2 Session Memory(会话记忆)------ 跨会话学习

配置参数 (src/services/SessionMemory/sessionMemoryUtils.ts):

typescript 复制代码
export const DEFAULT_SESSION_MEMORY_CONFIG = {
  minimumMessageTokensToInit: 10000,      // 初始化阈值
  minimumTokensBetweenUpdate: 5000,       // 更新阈值
  toolCallsBetweenUpdates: 3              // 工具调用间隔
}

提取流程:

typescript 复制代码
async function extractSessionMemory(messages, config) {
  // 1. 检查是否达到初始化阈值(10K tokens)
  if (!sessionMemoryInitialized && 
      currentTokenCount >= config.minimumMessageTokensToInit) {
    await initializeSessionMemory()
    sessionMemoryInitialized = true
  }
  
  // 2. 检查是否达到更新阈值(5K tokens 增长)
  if (tokensSinceLastExtraction >= config.minimumTokensBetweenUpdate) {
    await updateSessionMemory(messages)
    recordExtractionTokenCount(currentTokenCount)
  }
  
  // 3. 持久化到磁盘(~/.claude/projects/<hash>/sessions/)
  await writeSessionMemory(memoryPath)
}

特点:

  • ✅ 自动提取会话关键信息
  • ✅ 双阈值控制(初始化 10K,更新 5K)
  • ✅ 每 3 次工具调用检查一次
  • ✅ 持久化到磁盘,支持崩溃恢复
  • ⚡ 实现跨会话学习和记忆

3.3 Memory Directory(记忆目录)------ 结构化知识库

目录结构:

bash 复制代码
~/.claude/projects/<hash>/memory/
├── MEMORY.md          # 入口文件(行为指令)
├── user/              # 用户记忆
├── feedback/          # 反馈记忆
├── project/           # 项目记忆
└── reference/         # 参考记忆

提示词构建 (src/memdir/memdir.ts:199-250):

typescript 复制代码
export function buildMemoryLines(displayName: string, memoryDir: string) {
  return `
## ${displayName} (${memoryDir})

${DIR_EXISTS_GUIDANCE}

### 记忆类型(封闭分类)
1. **用户记忆**: 偏好、沟通风格、目标
2. **反馈记忆**: 对之前输出的明确反馈
3. **项目记忆**: 项目特定的知识(非代码可推导)
4. **参考记忆**: 外部资源、文档链接

### 何时访问
- 开始新任务时检索相关记忆
- 遇到模糊需求时查询用户偏好
- 收到反馈时更新反馈记忆
`
}

特点:

  • ✅ 四类封闭分类(user/feedback/project/reference)
  • ✅ 明确的访问指导
  • ✅ 目录存在性自动保证(无需 mkdir)
  • ⚡ 构建项目专属知识库

3.4 上下文字典管理 ------ 主循环中的压缩逻辑

主循环实现 (src/query.ts:365-420):

typescript 复制代码
async function* queryLoop(params) {
  let messages = params.messages
  
  while (true) {
    // 1. 获取压缩边界后的消息
    let messagesForQuery = [...getMessagesAfterCompactBoundary(messages)]
    
    // 2. 应用工具结果预算(限制 tool_result 大小)
    messagesForQuery = await applyToolResultBudget(
      messagesForQuery,
      contentReplacementState
    )
    
    // 3. 应用 Snip 压缩(如果启用 HISTORY_SNIP)
    if (feature('HISTORY_SNIP')) {
      const { snipped, tokensFreed } = await snipCompact(messagesForQuery)
      messagesForQuery = snipped
    }
    
    // 4. 检查是否需要自动压缩
    const tokenCount = tokenCountWithEstimation(messagesForQuery)
    if (tokenCount >= autoCompactThreshold) {
      const { summary } = await compactConversation(messagesForQuery)
      messagesForQuery = [summary, ...recentMessages]
    }
    
    // 5. 调用 Claude API
    const response = await claudeAPI({
      messages: messagesForQuery,
      systemPrompt,
      tools
    })
    
    // 6. 处理工具调用
    if (response.stop_reason === 'tool_use') {
      const toolResults = await runTools(response.content)
      messages = [...messagesForQuery, ...toolResults]
      continue
    }
    
    // 7. 返回最终响应
    yield response
    break
  }
}

压缩顺序:

  1. getMessagesAfterCompactBoundary() → 获取有效消息
  2. applyToolResultBudget() → 限制工具结果大小
  3. snipCompact() → 移除僵尸消息(可选)
  4. autoCompact() → 总结旧消息(如超过阈值)
  5. claudeAPI() → 调用模型

4. 完整调用链路

graph TB User[用户输入] --> QueryEngine[QueryEngine.query] QueryEngine --> BuildSystemPrompt[组装系统提示词] BuildSystemPrompt --> LoadMemories[加载记忆] LoadMemories --> SessionMemory[Session Memory] LoadMemories --> MemoryDir[Memory Directory] LoadMemories --> CLAUDEmd[CLAUDE.md 文件] BuildSystemPrompt --> NormalizeMessages[标准化消息] NormalizeMessages --> CheckCompact[检查压缩] CheckCompact --> AutoCompact{超过阈值?} AutoCompact -->|是 | Compact[压缩对话] AutoCompact -->|否 | CallAPI[调用 Claude API] Compact --> CallAPI CallAPI --> StreamEvents[流式事件] StreamEvents --> TextBlock[文本块] StreamEvents --> ToolUseBlock[工具使用块] TextBlock --> YieldToUser[返回给用户] ToolUseBlock --> FindTool[查找工具] FindTool --> AgentTool{AgentTool?} FindTool --> SkillsTool{SkillsTool?} FindTool --> OtherTool[其他工具] AgentTool --> RunSubAgent[运行子代理] RunSubAgent --> ForkContext[Fork 上下文] ForkContext --> IndependentLoop[独立 query 循环] IndependentLoop --> ReturnResult[返回结果] SkillsTool --> LoadSkills[加载 Skills] LoadSkills --> ExpandPrompt[扩展提示词] ExpandPrompt --> InjectMessages[注入消息] InjectMessages --> ContinueLoop[继续循环] OtherTool --> ExecuteTool[执行工具] ExecuteTool --> AppendResult[追加 tool_result] ReturnResult --> AppendResult ContinueLoop --> AppendResult AppendResult --> RecordTranscript[记录到磁盘] RecordTranscript --> LoopBack{还有工具?} LoopBack -->|是 | CallAPI LoopBack -->|否 | YieldFinal[返回最终结果]

5. 关键设计模式

5.1 上下文隔离与共享

子代理的上下文设计:

typescript 复制代码
const forkedContext = {
  ...parentContext,
  messages: [],           // 空消息历史(隔离)
  fileCache: shared,      // 共享文件缓存(性能)
  workingDirectory: worktreePath  // 独立工作目录(可选)
}

设计优势:

  • ✅ 保持对话清洁(独立 messages[])
  • ✅ 避免上下文污染(独立 token 预算)
  • ✅ 共享资源减少重复 IO(共享 fileCache)
  • ✅ 独立工作目录避免冲突(worktree 隔离)

5.2 懒加载与预取

技能发现预取:

typescript 复制代码
// 不阻塞的异步预取(利用工具执行时间)
const pendingSkillsPrefetch = SkillsPrefetch?.startSkillsDiscoveryPrefetch(
  null, messages, toolUseContext
)

// 等待完成(在工具执行后)
await pendingSkillsPrefetch?.consume()

记忆预取:

typescript 复制代码
using pendingMemoryPrefetch = startRelevantMemoryPrefetch(
  messages, toolUseContext
)
await pendingMemoryPrefetch?.consume()

设计优势:

  • ✅ 利用工具执行时间(隐藏加载延迟)
  • ✅ 异步预取,不阻塞主流程
  • ✅ 提升用户体验(减少等待感)

5.3 权限传递与覆盖

Skills 动态修改权限上下文:

typescript 复制代码
contextModifier(ctx) {
  if (allowedTools.length > 0) {
    return {
      ...ctx,
      getAppState() {
        const appState = previousGetAppState()
        return {
          ...appState,
          toolPermissionContext: {
            ...appState.toolPermissionContext,
            alwaysAllowRules: {
              ...alwaysAllowRules,
              command: [...new Set([...alwaysAllowRules.command, ...allowedTools])]
            }
          }
        }
      }
    }
  }
}

设计优势:

  • ✅ 细粒度权限控制(按 Skills 定制)
  • ✅ 动态调整策略(contextModifier)
  • ✅ 安全的权限继承(Set 去重)
  • ✅ 作用域限定(仅当前 Skills 执行期间)

5.4 渐进式压缩与降级

多层压缩策略:

typescript 复制代码
const compressionStrategies = {
  autoCompact: '总结旧消息(API 调用,智能但昂贵)',
  snipCompact: '移除僵尸消息(本地过滤,零成本)',
  contextCollapse: '重构上下文结构(实验性)'
}

降级机制:

typescript 复制代码
if (autoCompactFailed) {
  trySnipCompact()  // 尝试轻量级压缩
  if (stillOverLimit) {
    throw PromptTooLongError  // 最终抛出错误
  }
}

设计优势:

  • ✅ 多层次策略应对不同场景
  • ✅ 成本梯度(snip → auto → collapse)
  • ✅ 降级机制保证可靠性
  • ✅ 最大化利用上下文窗口

5.5 持久化与恢复

对话记录:

typescript 复制代码
// src/utils/sessionStorage.js
async function recordTranscript(message) {
  // 追加写入 JSONL 文件
  await appendFile(sessionLogPath, JSON.stringify(message) + '\n')
}

恢复流程:

typescript 复制代码
// src/commands/resume.js
async function resumeSession(sessionId) {
  const messages = await readJSONL(sessionLogPath)
  const lastMessage = messages[messages.length - 1]
  
  // 重建对话状态
  return rebuildStateFromMessages(messages)
}

设计优势:

  • ✅ 追加写入(order-preserving queue)
  • ✅ JSONL 格式(易解析,易恢复)
  • ✅ 支持 --continue 和 --resume
  • ✅ 崩溃后可完全恢复状态

核心设计总结

Claude Code 的 Agent/Skills/上下文管理系统展现了生产级 AI 代理的复杂性,其核心设计理念包括:

1. 渐进式增强

从基础的"调用 API→执行工具"循环开始,逐层添加压缩、记忆、多代理、权限等生产特性

2. 分层隔离

  • 同步/Fork/远程三种代理模式
  • 不同的隔离级别和资源管理
  • 共享文件缓存 vs 独立消息历史

3. 弹性上下文管理

  • 三层压缩策略应对不同场景
  • Session Memory 提供跨会话学习
  • Memory Directory 实现结构化知识

4. 安全优先的权限系统

  • 细粒度的权限控制
  • 动态修改和继承
  • 白名单机制保护未知风险

5. 全面的持久化

  • 所有对话记录到磁盘
  • 支持崩溃恢复
  • 会话恢复机制

文档生成时间 : 2026-04-01
分析版本 : Claude Code v2.1.88
核心文件:

  • src/tools/AgentTool/AgentTool.tsx (1,398 行)
  • src/tools/SkillsTool/SkillsTool.ts (1,109 行)
  • src/query.ts (1,730 行)
  • src/services/compact/autoCompact.ts (352 行)
  • src/services/SessionMemory/sessionMemoryUtils.ts (208 行)
  • src/memdir/memdir.ts (508 行)
相关推荐
星辰_mya3 小时前
数据库运维与数据安全:备份恢复、日志分析与故障排查
运维·数据库·后端·面试·架构师
AskHarries3 小时前
48小时打造一个类似 Product Hunt 的网站
后端
太难了啊3 小时前
深入理解智能体 Reflection 模式:自我反思与迭代改进的实践指南
人工智能·后端
工作log3 小时前
Spring Boot JAR包加密防反编译:ClassFinal 实战指南
spring boot·后端·jar
壹方秘境3 小时前
95后中间件研发,放弃高薪裸辞,两年时间做了ChatTCP和ApiCatcher两款网络分析和抓包工具
后端·产品·创业
重庆小透明3 小时前
【java基础内容】ArrayList与LinkedList的区别及ArrayList源码解析
java·开发语言·后端·面试·职场和发展
一只叫煤球的猫4 小时前
芋道源码,拉黑我,改变不了你还在搬运别人文章的事实
java·后端·面试