Archon DAG 节点 Hooks 实战指南:用 Claude Agent SDK 钩子控制工具、注入上下文与改写输入
2026/9/13 20:35:32 网站建设 项目流程

Archon DAG 节点 Hooks 实战指南:用 Claude Agent SDK 钩子控制工具、注入上下文与改写输入

【免费下载链接】ArchonThe first open-source harness builder for AI coding. Make AI coding deterministic and repeatable.项目地址: https://gitcode.com/GitHub_Trending/archon3/Archon

Archon 的 DAG 工作流节点支持hooks字段,可将 Claude Agent SDK 钩子(Hooks)直接挂载到单个节点上,在节点 AI 执行期间控制工具行为、注入上下文、修改工具输入,甚至紧急终止 Agent。读完本篇,你将掌握从快速上手、事件选型到响应格式、源码级原理的完整 Per-Node Hooks 实战方案,并能在自己的安全迁移、只读审查等工作流中直接落地。

重要前置条件:Hooks 仅对 Claude 生效。Codex 节点会对 hooks 发出警告并忽略(详见下文"源码证据"一节的 capability 检查)。

快速开始

在任意 AI 节点的 YAML 定义中声明hooks字段即可。下面的例子实现了一个"带护栏的 SQL 迁移生成"工作流——生成迁移的节点完全禁用 Bash:

name: safe-migration description: Generate SQL with guardrails nodes: - id: generate prompt: "Generate a database migration for $ARGUMENTS" hooks: PreToolUse: - matcher: "Bash" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "No shell access during SQL generation"

这个声明式写法与 Archon 的 YAML 工作流体系完全一致:hooks定义在packages/workflows/src/schemas/dag-node.ts的节点 schema 之上,并由 hooks schema 负责校验。

工作原理

每个 hook matcher 有三个字段:

字段是否必填说明
matcher可选用于按工具名过滤的正则表达式;省略则匹配所有工具
response必填钩子触发时返回的 SDKSyncHookJSONOutput
timeout可选钩子超时秒数(默认 60)

运行时,每个 YAML hook 都会被包装成一个极简回调:

async () => response

没有自定义 DSL——response本身就是 SDK 类型,原样透传、不做任何改写。这一点在源码中有直接印证:buildSDKHooksFromYAML将每个 matcher 映射为hooks: [async (): Promise<unknown> => m.response](见 provider.ts)。

关键约束:使用hookSpecificOutput时,必须包含与事件键一致的hookEventName字段(例如在PreToolUse钩子内部写hookEventName: PreToolUse)。这是 SDK 的硬性要求——SDK 依靠该字段决定处理哪些事件专属字段,缺失会导致响应无法被正确解析。

支持的 Hook 事件

事件触发时机matcher 过滤依据
PreToolUse工具执行前工具名(如BashWriteRead
PostToolUse工具成功之后工具名
PostToolUseFailure工具失败之后工具名
Notification系统通知通知类型
StopAgent 停止不适用
SubagentStart子 Agent 生成Agent 类型
SubagentStop子 Agent 结束Agent 类型
PreCompact上下文压缩之前触发器(manual/auto
SessionStart会话开始来源(startup/resume/clear/compact
SessionEnd会话结束退出原因
UserPromptSubmit用户提示词提交不适用
PermissionRequest权限提示即将出现工具名
SetupSDK 初始化触发器(init/maintenance
TeammateIdleAgent 队友空闲不适用
TaskCompleted后台任务完成不适用
ElicitationMCP 服务器请求用户输入不适用
ElicitationResultElicitation 响应收到不适用
ConfigChange设置/配置文件变更来源(user_settings/project_settings等)
WorktreeCreateGit worktree 创建Worktree 名称
WorktreeRemoveGit worktree 移除Worktree 路径
InstructionsLoadedCLAUDE.md/instructions 加载记忆类型(User/Project/Local/Managed

工具名参考BashReadWriteEditGlobGrepWebFetchAgent,以及 MCP 工具mcp__<server>__<action>

这 21 个事件在 Archon 中被完整登记为 Zod 枚举(workflowHookEventSchema,见 hooks.ts),并通过.strict()拒绝任何拼写错误的事件名(例如preToolUse会被直接判为非法),从而在 YAML 解析阶段就能暴露 typo,而不是留到运行时静默失效。对应地,hooks.test.ts 中有专门用例验证"未知事件名会推入错误"这一行为。

响应格式(SDKSyncHookJSONOutput

response对象支持以下字段:

字段类型效果
hookSpecificOutputobject事件专属响应(见下)
systemMessagestring注入一条对模型可见的消息
continuebooleanfalse表示停止 Agent
decision'approve'/'block'顶层同意/阻止
stopReasonstring停止时的原因说明
suppressOutputboolean抑制输出发出

PreToolUse 的hookSpecificOutput

hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny | allow | ask # 控制工具是否执行 permissionDecisionReason: "..." # 原因(显示在日志中) updatedInput: # 修改工具参数 file_path: "/sandbox/output.ts" additionalContext: "..." # 注入到模型上下文中的文本

PostToolUse 的hookSpecificOutput

hookSpecificOutput: hookEventName: PostToolUse additionalContext: "..." # 在工具结果之后注入的文本 updatedMCPToolOutput: ... # 覆盖模型看到的工具输出

PostToolUseFailure 的hookSpecificOutput

hookSpecificOutput: hookEventName: PostToolUseFailure additionalContext: "..." # 工具失败后的上下文

Elicitation 的hookSpecificOutput

hookSpecificOutput: hookEventName: Elicitation action: accept | decline | cancel # 响应 MCP elicitation content: { ... } # 表单字段值

ElicitationResult 的hookSpecificOutput

hookSpecificOutput: hookEventName: ElicitationResult action: accept | decline | cancel # 覆盖 elicitation 结果 content: { ... } # 修改后的响应值

实战示例

完全禁止某个工具

hooks: PreToolUse: - matcher: "Bash" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "Shell access not allowed in this node"

带原因消息禁止工具

hooks: PreToolUse: - matcher: "Write|Edit" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "Only read operations are allowed — do not modify files"

注意matcher是正则表达式,"Write|Edit"可以一次性匹配多个工具名。

工具使用前注入上下文(不拦截)

注意:这种方式不会阻止工具执行——它只是在工具运行前给模型追加指导。

hooks: PreToolUse: - matcher: "Write|Edit" response: hookSpecificOutput: hookEventName: PreToolUse additionalContext: "Only write to files in the src/ directory"

重定向文件写入(修改工具输入)

hooks: PreToolUse: - matcher: "Write" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: allow updatedInput: file_path: "/sandbox/output.ts"

这里通过updatedInput改写工具参数,把写入目标强制重定向到沙箱目录。

每次工具调用后注入纠偏指令

hooks: PostToolUse: - response: systemMessage: "Check: is this output relevant to the task? If not, stop and explain why."

注意此处省略了matcher,表示匹配所有工具;systemMessage直接给模型下达可见指令。

读取文件后注入上下文

hooks: PostToolUse: - matcher: "Read" response: hookSpecificOutput: hookEventName: PostToolUse additionalContext: "You just read a file. Do NOT modify it — analysis only."

Shell 访问时紧急停机

hooks: PreToolUse: - matcher: "Bash" response: continue: false stopReason: "Emergency halt — shell access attempted"

这是比deny更强硬的措施:continue: false会直接停止 Agent,而不仅仅是拒绝这一次工具调用。

单个节点上的多重 hooks

hooks: PreToolUse: - matcher: "Bash" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "No shell" - matcher: "Write|Edit" response: hookSpecificOutput: hookEventName: PreToolUse additionalContext: "Only write to files in src/" PostToolUse: - response: systemMessage: "Verify output before continuing"

同一事件下可以声明多条 matcher,Archon 会按声明顺序依次注册(buildSDKHooksFromYAML中对每个 matcher 生成独立条目,见 provider.ts)。

完整工作流示例

name: safe-code-review description: Review code with guardrails nodes: - id: fetch-diff bash: "git diff main...HEAD" - id: review prompt: "Review this diff for bugs and security issues: $fetch-diff.output" depends_on: [fetch-diff] hooks: PreToolUse: - matcher: "Bash" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "Code review should not execute commands" - matcher: "Write|Edit" response: hookSpecificOutput: hookEventName: PreToolUse permissionDecision: deny permissionDecisionReason: "Code review is read-only" PostToolUse: - matcher: "Read" response: hookSpecificOutput: hookEventName: PostToolUse additionalContext: "Focus on security issues in this file" - id: summarize prompt: "Summarize the review findings from $review.output" depends_on: [review] allowed_tools: []

该示例展示了 hooks 与 DAG 的组合用法:fetch-diff是纯 bash 节点(bash 节点不会执行 hooks,见 hooks.test.ts 中"bash 节点上的 hooks 被忽略"的测试);review节点用 hooks 建立只读护栏;summarize节点则通过allowed_tools: []关闭全部工具。

Hooks vs allowed_tools/denied_tools

特性allowed_tools/denied_toolshooks
完全阻止工具
注入上下文是(additionalContextsystemMessage
修改工具输入是(updatedInput
覆盖工具输出是(updatedMCPToolOutput
停止 Agent是(continue: false
工具使用后的反应是(PostToolUse

选型建议:简单的包含/排除用allowed_tools/denied_tools;需要上下文注入、输入改写或工具调用后反应时,选择hooks。两者也可以同时声明、各司其职——例如上面"完整工作流示例"中review节点用 hooks 做护栏、summarize节点用allowed_tools: []做全禁。

限制

  • YAML 中只有静态响应—— hooks 每次都返回相同的 response。需要条件逻辑时,请在下游节点上使用when:条件,或通过输出结构化结果的上游 bash 节点来门控执行。
  • 仅 Claude—— Codex 节点会警告并忽略 hooks。
  • 无 hook 事件流—— hook 生命周期事件(hook_startedhook_progress)不会转发到 Web UI。

源码级原理:从 YAML 到 SDK 钩子的完整链路

如果想知道 hooks 在 Archon 内部如何从 YAML 变成真正的 SDK 钩子,可以沿着下面这条调用链阅读源码:

  1. YAML 解析与校验parseNodeHooks使用workflowNodeHooksSchema(Zod)对原始 YAML 进行校验,未知事件、非对象response、缺response的 matcher 都会被收集进错误列表;空事件数组会被过滤掉,全部为空时 hooks 字段整体返回undefined(见 loader.ts 与 hooks.test.ts 中的大量边界用例)。

  2. 节点配置透传:dag-executor 在构建节点配置时把hooks原样写入nodeConfig(见 dag-executor.ts),交由 provider 内部自行翻译。

  3. SDK 钩子构建:Claude provider 的buildSDKHooksFromYAML把每个 matcher 转换为 SDK 的HookCallbackMatcher——matchertimeout原样透传,response被包装成async () => m.response的零逻辑回调(见 provider.ts)。测试中已明确验证"回调返回的正是原 response 对象、不做任何改动"(hooks.test.ts)。

  4. 能力警告dag-executor的 capability 检查表把hooks与 provider 的hooks能力位挂钩——Claude 的 capabilities 声明hooks: true(见 capabilities.ts),而 Codex 未声明该能力,于是声明了 hooks 的节点在运行时会被警告"该能力将被忽略"(见 dag-executor.ts)。工作流验证器validator.ts同样会对不支持的 provider 给出Remove the hooks field or switch to a provider that supports hooks的提示(见 validator.ts)。

这套"静态 YAML → 校验 → 透传 → SDK 包装 → 能力门控"的链路,正是声明式 hooks 无需自定义 DSL 却能稳定工作的原因。

SDK 参考与延伸阅读

关于SyncHookJSONOutput类型的权威定义、全部 hook 事件参考以及 matcher 模式,请查阅 Claude Agent SDK 官方文档(Anthropic 的 Claude Code SDK 页面)。

相关指南:

  • Per-Node MCP Servers —— 通过mcp:字段接入外部工具
  • Per-Node Skills —— 通过skills:字段注入领域知识
  • 工作流编写指南 —— hooks 所依赖的 DAG 节点与when:条件体系

【免费下载链接】ArchonThe first open-source harness builder for AI coding. Make AI coding deterministic and repeatable.项目地址: https://gitcode.com/GitHub_Trending/archon3/Archon

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询