☰
Kimi Code CLI Hooks 事件钩子机制:从配置到源码的完整实战指南
2026/9/28 7:23:12 网站建设 项目流程
  • AI Agent
  • 代码智能体
  • 人工智能
  • 大模型
  • CLI

【免费下载链接】kimi-code

Kimi Code CLI — The Starting Point for Next-Gen Agents

项目地址:https://gitcode.com/gh_mirrors/ki/kimi-code
点击查看免费下载

Kimi Code CLI 的 Hooks 是一套"事件驱动"的自动化触发机制:你预先告诉 CLI"当某件事发生时,运行某个脚本",脚本运行在你的本机,内部可以承载任意逻辑。本文以 docs/en/customization/hooks.md 为骨架,完整讲解 Hooks 的配置语法、事件参考表、返回值语义与阻断能力,并结合 agent-core-v2 的源码实现剖析其底层执行原理。读完本文,你将能独立编写安全拦截、桌面通知、上下文注入三类典型 Hook,并理解其 fail-open 设计在安全场景下的边界。

Hooks 是什么

Hooks 是一种自动触发机制:你提前告诉 Kimi Code CLI "每当 X 发生时,运行这个脚本"。脚本在你的本地机器上运行,内部可以放置任何逻辑。典型的使用场景包括:

  • 安全拦截:在 Agent 执行 shell 命令之前,检查命令是否包含危险操作(如rm -rf),发现则阻止执行;
  • 桌面通知:后台任务完成时弹出系统通知,提醒你回来审查结果;
  • 自动检查:每次用户提交消息时,自动向上下文追加一些背景信息(例如当前的 Git 分支)。

Hooks 的工作原理

配置一条 Hook 规则需要指定三样东西:触发哪个事件、匹配哪些目标、运行哪个脚本。

当被触发时,CLI 会将事件详情(触发原因、工具名称、命令内容等)打包成 JSON,通过**标准输入(stdin)**传递给脚本。脚本读取这些信息后决定如何响应。

脚本的响应由两件事决定:

  • 退出码:0表示放行,2表示阻止,其他非零值默认放行;
  • 标准输出(stdout):可携带说明性文本。

即使脚本出错或超时,CLI也不会因此中断你的工作。这种"失败即放行"的设计称为 fail-open,目的是防止 Hook 自身出错成为阻塞项。

⚠️ 注意:正因为是 fail-open 设计,Hooks 适合用于告警和轻量级拦截,但不应作为唯一的安全屏障。对于真正高风险的操作,应依赖权限审批(permission approvals)和人工确认。

快速开始:一个最小 Hook

下面这个 Hook 在每次后台任务完成时,在终端标题栏闪烁一条通知(macOS 需要安装terminal-notifier):

# 写在 ~/.kimi-code/config.toml [[hooks]] event = "Notification" # 触发点:后台任务状态变化时 matcher = "task\\.completed" # 只关心 "completed" 类型的通知 command = "terminal-notifier -title Kimi -message 'Task done'"

保存配置后,启动一个新的会话,下次后台任务完成时就会出现通知。

配置详解

所有 Hook 规则都写在~/.kimi-code/config.toml的[[hooks]]数组中,每个条目即一条规则:

字段类型必填说明
eventstring是触发事件名称;必须是事件参考中列出的事件之一
matcherstring否用于过滤事件目标的正则表达式;省略则匹配所有
commandstring是触发时要运行的 shell 命令
timeoutinteger否超时秒数,范围 1–600;默认 30 秒

[[hooks]]只允许这四个字段;多余的字段会导致配置文件加载失败。这一点在源码中有严格校验:packages/agent-core-v2/src/features/externalHooks/configSection.ts中定义了HookDefSchema(z.object({...}).strict()),其中event必须是HOOK_EVENT_TYPES枚举之一、command非空、timeout为 1–600 的整数——严格模式(.strict())意味着 schema 之外的任何字段都会直接使配置校验失败,这正是"多余字段导致配置文件无法加载"的实现依据。

当多个规则匹配同一事件时,所有匹配的 Hook 并行运行;多条command值完全相同的规则只运行一次。这一行为在packages/agent-core-v2/src/features/externalHooks/internal/matchHooks.ts的runMatchedHooks中有明确实现:先按事件索引所有 Hook(indexHooks),再用正则逐一过滤matcher,最后以(cwd + '\0' + command)为 key 去重,剩余规则通过Promise.all并行执行。

Hook 命令的工作目录是当前会话的项目目录。

进程组与超时处理

在非 Windows 平台上,Hook 进程运行在独立的进程组中;超时时,CLI 会先发送信号给脚本一个清理的机会,然后再强制终止它。源码层面(packages/agent-core-v2/src/features/externalHooks/internal/runHook.ts)的细节是:进程以shell: true、detached: process.platform !== 'win32'的方式派生,超时后先kill('SIGTERM'),等待 100ms 宽限期(KILL_GRACE_MS)后再kill('SIGKILL')强制结束;同时支持通过AbortSignal取消运行中的 Hook。

事件数据格式

每次 Hook 触发时,CLI 通过 stdin 向脚本传递以下基础信息:

{ "hook_event_name": "PreToolUse", "session_id": "session_abc", "session_title": "Fix the login page", "client_type": "kimi_code_cli", "cwd": "/path/to/project" }

特定事件还会附带额外字段(如工具名称、命令内容),详见事件参考。所有字段名均使用 snake_case——这是matchHooks.ts中camelToSnake转换函数的约定,无论内部实现使用何种 camelCase 字段名,传入 Hook 的 JSON 一律转为snake_case。

返回值语义

脚本退出后,CLI 根据退出码判断 Hook 的意图:

退出码含义CLI 行为
0正常退出,放行继续执行;stdout 内容(如有)可能被追加到上下文
2主动阻止停止当前操作;stderr 内容(通过console.error输出)作为阻止原因
其他非零脚本出错默认放行(fail-open)
超时或崩溃脚本异常默认放行(fail-open)

你还可以通过 stdout 返回 JSON 对象来阻止:

{ "hookSpecificOutput": { "permissionDecision": "deny", "permissionDecisionReason": "Please use rg instead of grep" } }

这条 JSON 路径在runHook.ts的structuredOutput函数中实现:当退出码为0且 stdout 是合法 JSON 时,CLI 解析hookSpecificOutput.permissionDecision,若为deny则视为阻止,permissionDecisionReason作为阻止原因。注意 schema 中还支持顶层的message字段(HookJsonOutputSchema),供 Hook 向上下文补充说明。

哪些事件支持阻断?只有可阻断事件(PreToolUse、Stop、UserPromptSubmit)的返回值会影响主流程。其余事件均为纯观察事件:触发即忘(fire and forget),无论脚本返回什么,主流程都不受影响。

事件参考

事件Matcher 匹配对象支持阻断?说明
UserPromptSubmit用户提交的文本✓用户发送消息时触发;返回文本会追加到上下文;阻断则跳过本轮模型调用
UserPromptQueued排队中的提示词文本—一轮仍在运行时消息被排队时触发;payload 包含prompt_id、prompt、queue_length
PreToolUse工具名称✓工具调用前触发(在权限检查之前);被阻断则工具不会执行
Stop空字符串✓模型即将结束本轮时触发;阻断后可追加消息让模型继续
TurnStarted轮次来源类型(如user、task、system_trigger)—新的一轮开始时触发;payload 包含turn_id、origin_kind、origin_name、prompt
PostToolUse工具名称—工具成功执行后触发
PostToolUseFailure工具名称—工具失败或被阻断后触发
PermissionRequest工具名称—即将等待用户审批前触发
PermissionResult工具名称—审批完成后触发
SessionStartstartup或resume—会话开始或恢复后触发;payload 包含source、model、profile
SessionEndexit或archive—会话关闭后触发;archive表示会话被归档而非退出
SessionHeartbeat空字符串—会话存活期间每 60 秒触发一次;仅当配置了该事件时计时器才运行;payload 包含uptime_ms
SubagentStart子代理名称—子代理开始运行前触发
SubagentStop子代理名称—子代理成功完成后触发
TaskStarted任务类型(agent、process或question)—后台任务开始时触发;payload 包含task_id、description、detached
StopFailure错误类型—本轮因错误失败后触发
Interrupt空字符串—用户中断本轮时触发(如按 Esc);超时或程序化中止不触发;取代Stop触发;payload 包含reason
PreCompactmanual或auto—上下文压缩开始前触发;返回值完全被忽略
PostCompactmanual或auto—上下文压缩完成后触发
Notification通知类型(如task.completed)—后台任务状态变化时触发

以上 20 个事件与源码packages/agent-core-v2/src/features/externalHooks/internal/types.ts中导出的HOOK_EVENT_TYPES枚举完全一致,可作为配置时的权威清单。从调用架构看(packages/agent-core-v2/src/features/externalHooks/app/externalHooksRunner.ts),事件触发分为三种入口:trigger(等待结果)、triggerBlock(等待并解析阻断决策)与fireAndForgetTrigger(纯观察、触发即忘),分别对应上表"支持阻断"与"纯观察"两类事件。

示例:拦截危险的 Shell 命令

下面的 Hook 在 Agent 调用Bash工具前检查命令内容,发现rm -rf则阻止:

[[hooks]] event = "PreToolUse" matcher = "Bash" command = "node ~/.kimi-code/hooks/block-dangerous-bash.mjs" timeout = 5
// block-dangerous-bash.mjs // 从 stdin 读取 CLI 传入的事件数据 let input = ''; process.stdin.on('data', (chunk) => { input += chunk; }); process.stdin.on('end', () => { const payload = JSON.parse(input); // 解析事件数据 const command = payload.tool_input?.command ?? ''; if (command.includes('rm -rf')) { // 通过 stderr 说明阻止原因;退出码 2 表示阻止 console.error('Dangerous command detected, blocked'); process.exit(2); } // 正常退出(退出码 0)表示放行 });

阻断之后,Kimi Code CLI 会把阻止原因写回上下文,模型可据此选择更安全的替代方案。

⚠️ 注意:这个示例仅演示阻断机制,并非生产级的安全解析器。真实场景更适合用白名单,或专门的 shell 解析器来处理引号、变量展开和多命令序列等问题。

从源码看 Hooks 的执行链路

结合 agent-core-v2 的代码,可以把 Hooks 的完整执行链路梳理为五个环节:

  1. 配置注册:configSection.ts 将hooks段落注册为配置项,用严格模式 schema 校验每条规则的四个字段;
  2. 索引与匹配:matchHooks.ts 的indexHooks按事件建立索引,matches用正则测试 matcher,非法正则直接视为不匹配;
  3. 进程派生:runHook.ts 以shell: true派生子进程,通过 stdin 写入 JSON 事件数据;
  4. 结果判定:退出码2→ 阻断;退出码0且 stdout 为合法 JSON 且permissionDecision === "deny"→ 阻断;其余情况一律放行(包括超时、崩溃、派生失败);
  5. 决策汇总:多个匹配 Hook 并行执行后,任一返回阻断即整体阻断(blockDecision取第一个阻断结果,未提供原因时回退为Blocked by <event> hook)。

这些行为均有对应测试覆盖,可参考 packages/agent-core-v2/test/features/externalHooks 目录下的runner.test.ts与integration.test.ts,它们验证了并行执行、去重、超时与阻断决策等关键路径。

下一步

  • 配置详解 —config.toml中[[hooks]]的完整字段参考
  • Agents and sub-agents — 结合SubagentStop事件,在子代理完成后触发通知
  • AI Agent
  • 代码智能体
  • 人工智能
  • 大模型
  • CLI

【免费下载链接】kimi-code

Kimi Code CLI — The Starting Point for Next-Gen Agents

项目地址:https://gitcode.com/gh_mirrors/ki/kimi-code
点击查看免费下载
上一篇:Home Assistant Mail And Packages多语言支持详解:国际快递与本地化适配
下一篇:WebRTC实时通信面试终极指南:前端开发者必备的10大核心知识点

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

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

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

立即咨询