找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

2945

积分

0

好友

393

主题
发表于 3 小时前 | 查看: 7| 回复: 0

Claude Code 实现了一套完整的 Hook 事件系统,覆盖工具执行的每个阶段。

export type HookExecutionEvent =
  | HookStartedEvent      // 钩子开始执行
  | HookProgressEvent     // 钩子运行中,有输出
  | HookResponseEvent     // 钩子执行完成

每个事件都承载了完整的上下文信息,方便外部系统监听和处理:

export type HookResponseEvent = {
  type: 'response'
  hookId: string
  hookName: string
  hookEvent: string
  output: string        // 最终输出
  stdout: string        // 标准输出
  stderr: string        // 标准错误
  exitCode?: number     // 退出码
  outcome: 'success' | 'error' | 'cancelled'
}

值得注意的是,系统会固定触发一些关键事件,无论用户是否配置了相应的 Hook。

const ALWAYS_EMITTED_HOOK_EVENTS = [
  'SessionStart',  // 会话启动
  'Setup',         // 环境初始化完成
]

这些事件串联起来,构成了 Claude Code 完整的生命周期。任何外部系统,无论是用于日志记录、监控告警还是审计追踪,都可以通过监听这些事件来无缝集成自己的业务逻辑。

Hook 系统的存在,本质上为 Claude Code 的行为开辟了一条可被外部扩展和干预的通道。开发者无需深入修改核心源码,就能在关键节点插入自定义逻辑。常见的应用场景包括:

  • 日志 Hook:在每次工具执行后自动记录输入输出,用于后续审计和分析。
  • 通知 Hook:在特定高风险或关键操作完成后,自动向 Slack、邮件等渠道发送通知。
  • 验证 Hook:在文件被修改后,自动触发相关的测试套件,确保更改不会引入问题。
  • 安全 Hook:在执行如 rm -rf 等高风险命令前,增加一道额外的确认或审批流程。

核心协作模式:Coordinator 架构

当任务复杂到需要多个 Agent 分工协作时,Claude Code 便会启动其 Coordinator 模式。在这个模式下,系统清晰地划分为三种角色:

  • Coordinator(协调者):作为主 Agent,负责整体任务规划、将子任务分发给 Worker、并最终汇总和呈现结果。
  • Worker(工作者):作为子 Agent,负责执行 Coordinator 分配的具体任务,它们通过 Agent 工具启动。
  • 通信机制SendMessage 工具专门负责 Worker 与 Coordinator 之间以及 Worker 之间的消息传递。

Coordinator 的系统提示词(System Prompt)直接界定了其职责边界,防止角色混乱:

// coordinatorMode.ts
return `You are Claude Code, an AI assistant that orchestrates
software engineering tasks across multiple workers.

## Your Role

You are a **coordinator**. Your job is to:
- Help the user achieve their goal
- Direct workers to research, implement and verify code changes
- Synthesize results and communicate with the user
- Answer questions directly when possible —
  don‘t delegate work that you can handle without tools`

这里有一个关键的设计约束:不要用一个 Worker 去检查另一个 Worker 的结果。Worker 完成工作后会主动通知 Coordinator,由 Coordinator 统一进行结果汇总和下一步决策。这种“上报”机制避免了低效的轮询检查,提升了协作效率。

为了确保系统的可控性,子 Agent(Worker)不能访问所有工具,其工具集被严格限制在白名单范围内:

const INTERNAL_WORKER_TOOLS = new Set([
  TEAM_CREATE_TOOL_NAME,
  TEAM_DELETE_TOOL_NAME,
  SEND_MESSAGE_TOOL_NAME,
  SYNTHETIC_OUTPUT_TOOL_NAME,
])

const workerTools = Array.from(ASYNC_AGENT_ALLOWED_TOOLS)
  .filter(name => !INTERNAL_WORKER_TOOLS.has(name))
  .sort()
  .join(', ')

像创建/删除 Worker、发送消息这样的内部管理工具,只有 Coordinator 才能调用。Worker 只能使用给定的标准工具链及 MCP (Model Context Protocol) 工具。这是防止子 Agent 行为失控、确保多 Agent 系统稳定运行的关键安全机制。

解决协作难题:上下文共享与结果反馈

多 Agent 协作时,如何实现高效的上下文隔离与共享是个挑战。Claude Code 的解决方案是 Scratchpad(草稿本)机制:

if (scratchpadDir && isScratchpadGateEnabled()) {
  content += `\n\nScratchpad directory: ${scratchpadDir}
Workers can read and write here without permission prompts.
Use this for durable cross-worker knowledge.`
}

所有 Worker 都可以无需权限确认地读写 Scratchpad 目录。这个共享存储空间使得多个 Agent 能够安全地传递中间结果、共享临时数据,从而更好地协调后续步骤。

Worker 完成任务后,会通过结构化的 XML 格式向 Coordinator 发送任务通知:

<task-notification>
  <task-id>{agentId}</task-id>
  <status>completed|failed|killed</status>
  <summary>{human-readable status summary}</summary>
  <result>{agent's final text response}</result>
  <usage>
    <total_tokens>N</total_tokens>
    <tool_uses>N</tool_uses>
    <duration_ms>N</duration_ms>
  </usage>
</task-notification>

Coordinator 解析这份 XML 数据,根据其中的状态(status)、结果摘要(summary)和资源使用情况(usage)来智能决定下一步行动——是让当前 Worker 继续,还是启动新的 Worker 处理后续环节。

实战场景与内置能力

那么,Coordinator 模式具体适合哪些场景呢?

  • 场景一:多个独立子任务并行执行。例如代码审查,可以同时启动三个 Worker:一个负责查找逻辑 Bug,一个负责提供性能优化建议,一个负责安全漏洞扫描。三者并行工作,最后由 Coordinator 汇总生成一份完整的审查报告。
  • 场景二:复杂任务的多步骤规划与接力。对于大型代码重构任务,可以先让一个 Worker 进行前期调研和方案设计,再让另一个 Worker 根据既定方案实施具体更改,Coordinator 则全程监控进度并在环节间进行协调。
  • 场景三:跨机器分布式协作。在 remote_agent 模式下,运行在不同物理机或环境中的 Claude Code 实例可以互相通信,协同完成单机难以处理的大规模分布式任务。

除了核心的协作框架,Claude Code 的源码中还内置了一些颇具代表性的 Skill(技能),其中 verify 技能最能体现其工程思维。

// skills/bundled/verify.ts
const DESCRIPTION = 'Verify a code change does what it should by running the app.'

export function registerVerifySkill(): void {
  registerBundledSkill({
    name: 'verify',
    description: DESCRIPTION,
    userInvocable: true,
    async getPromptForCommand(args) {
      const parts: string[] = [SKILL_BODY.trimStart()]
      if (args) {
        parts.push(`## User Request\n\n${args}`)
      }
      return [{ type: 'text', text: parts.join('\n\n') }]
    },
  })
}

Skill 本质上是一段预定义的提示词模板,调用时将用户参数动态注入,然后发送给大语言模型执行。verify 技能的核心逻辑非常直接:做完不等于做对,任何代码变更完成后,都必须通过实际运行来验证其结果是否符合预期。它的提示词模板明确包含了验证的具体目标、通过标准以及失败后的处理流程。

另一个有趣的技能是 /stuck,它专门用于诊断 Claude Code 自身运行时可能出现的问题:

// skills/bundled/stuck.ts
const STUCK_PROMPT = `# /stuck — diagnose frozen/slow Claude Code sessions

Signs of a stuck session:
- High CPU (≥90%) sustained — likely an infinite loop
- Process state D (uninterruptible sleep) — often an I/O hang
- Process state Z (zombie) — parent isn't reaping
- Very high RSS (≥4GB) — possible memory leak
- Stuck child process — a hung git/node subprocess

Investigation steps:
1. List all Claude Code processes
2. For suspicious ones: gather child processes, CPU samples
3. Check debug logs in ~/.claude/debug/`

这体现了一种递归的工程思维:自己构建的监控与诊断工具,也必须能够监控和诊断自身。当 Claude Code 进程出现卡顿、高负载或异常时,用户可以通过 /stuck 技能,让其自动检查 CPU 使用率、内存占用、子进程状态等,快速定位问题根因,例如是陷入了死循环、I/O 阻塞还是内存泄漏。

总结:严谨是可靠性的基石

通读 Claude Code 关于多 Agent 协作的 源码分析,最深刻的感受并非其采用了多么炫酷的“黑科技”,而是贯穿始终的 “严谨” 二字。它的每一层设计都在试图回答一个核心问题:如果 AI 在执行中出错了,我们如何才能发现、拦截并恢复?

此前介绍的三层底层机制(权限系统、任务状态机、QueryEngine)分别解决了“如何拦截风险”、“如何追踪状态”和“如何可靠执行”的问题。而本文探讨的三层上层能力——Hook 系统、Coordinator 模式以及 verify//stuck 技能——则进一步回答了“如何记录审计”、“多体如何协作”以及“如何确认结果”的问题。

这些机制单独看来都不算复杂,但将它们有机地组合在一起,便构建出一个让开发者能够“放心”使用的智能体系统。这种对可靠性、可观测性和可控性的极致追求,正是 Claude Code 在多 Agent 编程助手领域构筑竞争力的关键。如果你想深入了解此类系统的设计哲学与最佳实践,欢迎在 云栈社区 与更多开发者交流探讨。




上一篇:告别手搓JS逆向:基于AI技能的分析与AutoDecoder脚本生成实践
下一篇:MSA开源:用原生注意力机制实现百倍上下文记忆,GitHub星标暴涨
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-4-8 10:28 , Processed in 0.623222 second(s), 42 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表