Agent Hook 机制速查表

Hook = 在 AI Agent Loop 流水线上预先埋好的「检查站」。流水线:用户输入 → 模型推理 → 工具调用 → 工具执行 → 回复/空闲。各家都在这些节点前/后插钩。三家皆能 allow / deny(block) / modify(改入参或注入上下文)。

文本版 · 供搜索与朗读

Hook 机制速查表 · Claude Code / Cursor / OpenCode

Agent Hook 机制速查表

Claude Code · Cursor · OpenCode | 费曼视角 · 2026-08-08 可查证公开文档

一、核心心智模型

Hook = 在 AI Agent Loop 流水线上预先埋好的「检查站」。流水线:用户输入 → 模型推理 → 工具调用 → 工具执行 → 回复/空闲。各家都在这些节点前/后插钩。三家皆能 allow / deny(block) / modify(改入参或注入上下文)。

二、三器逐一看

Claude Code

配置:~/.claude/settings.json(用户)|.claude/settings.json(项目)|.claude/settings.local.json(本地)

模型:单一 Pre/Post 事件 + matcher 过滤工具名(支持正则)

类型:command / prompt / agent(三类型最全)

拦截:退出码 2;stdout JSON hookSpecificOutput.permissionDecision = allow/deny/ask/defer

事件:PreToolUse, PostToolUse, PostToolUseFailure, UserPromptSubmit, Notification, Stop, SubagentStop, PreCompact, SessionStart, SessionEnd, PermissionRequest

入参改写:updatedInput;注入上下文:additionalContext

链式:deny > defer > ask > allow(默认安全)

Cursor

配置:~/.cursor/hooks.json(全局)|.cursor/hooks.json(项目,云端 agent 也跑)

模型:每阶段劈成独立事件(粒度最细)

类型:command / prompt

拦截:退出码 2;返回 {permission:"allow|deny|ask", userMessage, agentMessage}

细分事件:beforeShellExecution / afterShellExecution、beforeMCPExecution / afterMCPExecution、beforeReadFile / afterFileEdit、beforeSubmitPrompt、preCompact、stop、subagentStart/Stop、sessionStart/End、afterAgentResponse/Thought、Tab:beforeTabFileRead/afterTabFileEdit、workspaceOpen

原生兼容 Claude 钩子:自动映射事件名,认嵌套与扁平两种返回

优先级:企业 > 团队 > 项目.cursor > 用户.cursor > Claude本地 > Claude项目 > Claude用户

OpenCode

原生:插件 TS 函数,注册内部事件

兼容桥:johnnyasantoss/opencode-hooks 或 oh-my-opencode(认 Claude 格式)

拦截(桥):退出码 0 放行 / 1 问用户 / 2 拦截;error 字段优先

原生事件:tool.execute.before/after、session.created/idle/deleted、file.edited、file.watcher.updated、message.updated、lsp.client.diagnostics、tui.toast.show

原生最灵活:直接改 event.input,独享文件/LSP/UI 钩子

桥的缺口:FileChanged、PreCompact、Task*、Notification 等无对应 API → 不支持

三、对照总表

维度Claude CodeCursorOpenCode

配置载体settings.json 的 hooks.cursor/hooks.json (v1)原生=插件 TS;兼容=桥 hooks.json

触发模型Pre/Post + matcher每阶段独立事件原生=内部事件;桥=Claude 格式

Hook 类型command / prompt / agentcommand / prompt原生=函数;桥=command

拦截方式退出码2 + permissionDecision退出码2 + permission桥:0/1/2;原生=返回值

改写入参✅ updatedInput✅ updated_input✅ 原生直改

加载 Claude 钩子自身✅ 原生兼容✅ 经桥

云端执行需自备✅ 项目 hooks.json取决于桥部署

粒度亮点三类型最全拆得最细文件/LSP/UI 独一份

四、可复制模板

Claude Code — 拦危险命令 + 写后格式化

{
"hooks": {
"PreToolUse": [{
"matcher": "Bash",
"hooks": [{
"type": "command",
"command": "echo \"$TOOL_INPUT_command\" | grep -qE 'rm -rf|sudo|git push --force' && exit 2 || exit 0"
}]
}],
"PostToolUse": [{
"matcher": "Write|Edit",
"hooks": [{
"type": "command",
"command": "jq -r '.tool_input.file_path' | { read f; case \"$f\" in *.ts|*.tsx) npx prettier --write \"$f\";; esac; } 2>/dev/null || true"
}]
}]
}
}

Cursor — 拦 shell 网络命令(.cursor/hooks.json)

{
"version": 1,
"hooks": {
"beforeShellExecution": [
{ "command": "./scripts/approve-network.sh", "timeout": 30, "matcher": "curl|wget|nc" }
],
"afterFileEdit": [
{ "command": "./scripts/format.sh" }
]
}
}

OpenCode — 兼容桥(.opencode/hooks.json)

{
"hooks": {
"PreToolUse": [
{ "matcher": "Bash", "hooks": [ { "type": "command", "if": "Bash(rm *)", "error": "rm commands are not allowed" } ] }
],
"PostToolUse": [
{ "matcher": "Edit", "hooks": [ { "type": "command", "command": "/path/to/log-edit.sh" } ] }
]
}
}

费曼凭栏:想"写一次三家通吃",照 Claude 格式写——Cursor 原生认,OpenCode 装桥也跑得动大半。要最细守门选 Cursor;要深度咬合代码选 OpenCode 原生;要最省事生态最全选 Claude Code。Hook 只拦"高置信危险",别拦"我不喜欢"。

速查表由 WorkBuddy · 费曼视角生成 | 退出码:0=放行 · 2=拦截 · 其它=fail-open

暂无表态

想参与讨论或点赞?登录后使用完整功能

讨论回复(0)

暂无回复,登录后可参与讨论
合作

智谱 GLM-5 已上线

在智谱开放平台 BigModel.cn 打造 AI 应用。新一代旗舰模型 GLM-5 在推理、代码、智能体综合能力达到开源模型 SOTA。

领取 2000万 Tokens