Skip to content

Kiro CLI 的 hooks 可以在 agent 启动、用户提交 prompt、工具执行前后和会话结束时运行自定义命令。本文从中文开发团队常见的安全校验、日志记录、格式化和上下文注入场景出发,说明 hook event、退出码、matcher、超时与缓存的用法。

Kiro CLI hooks:在 agent 生命周期中加上安全与自动化

hooks 是 Kiro CLI 里很重要的自动化扩展点。它允许你在 agent 生命周期和工具调用的关键节点执行自定义命令,用来做安全校验、日志记录、代码格式化、上下文收集、权限拦截等事情。

你可以把 hooks 理解成“给 agent 加护栏”。agent 负责完成任务,但哪些工具可以用、什么时候阻止、哪些信息需要注入上下文,可以通过 hooks 进行控制。

hooks 定义在哪里

hooks 定义在 agent configuration 文件中。完整字段语法可以参考 Agent Configuration Reference

实际使用时,建议先从一个简单 hook 开始,例如只记录工具调用,再逐步加入阻断逻辑。不要一开始就把所有工具都拦截,否则排障成本会很高。

hook event:Kiro 传给脚本的输入

hooks 会通过 STDIN 接收 JSON 格式的 hook event。最基础的事件类似:

json
{
  "hook_event_name": "agentSpawn",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789"
}

对于工具相关 hooks,还会包含更多字段:

  • session_id:当前 session UUID,所有 hook event 都会包含;
  • tool_name:正在执行的工具名称;
  • tool_input:工具参数,具体结构取决于工具;
  • tool_response:工具执行结果,只在 PostToolUse 中出现。

这意味着你的 hook 脚本可以读取当前目录、会话 ID、工具名称和工具参数,然后决定是放行、记录还是阻止。

hook output:退出码决定行为

Kiro 根据 hook 命令的 exit code 判断下一步动作:

退出码行为
0hook 成功。STDOUT 会被捕获,但通常不直接展示给用户
2仅 PreToolUse 有效:阻止工具执行,并把 STDERR 返回给 LLM
其他hook 失败。STDERR 会作为 warning 展示给用户

最关键的是 PreToolUse + exit code 2。它可以在工具真正执行前阻止危险操作,例如禁止写入特定目录、禁止执行未授权 shell 命令、禁止访问敏感文件。

tool matching:只匹配需要控制的工具

通过 matcher 字段可以指定 hook 作用于哪些工具。可以使用规范名称,也可以使用别名。

常见写法:

  • "fs_write""write":匹配写文件工具;
  • "fs_read""read":匹配读文件工具;
  • "execute_bash""shell":匹配 shell 命令执行;
  • "use_aws""aws":匹配 AWS CLI 工具;
  • "@git":匹配 git MCP server 的所有工具;
  • "@git/status":匹配 git MCP server 的某个具体工具;
  • "*":匹配所有内置工具和 MCP 工具;
  • "@builtin":只匹配所有内置工具;
  • 不写 matcher:应用到所有工具。

完整工具引用格式可以参考 Agent Configuration Reference

建议从精确 matcher 开始。只有在做统一审计、统一日志或全局策略时,才考虑使用 *

hooks 类型

AgentSpawn:agent 启动时运行

AgentSpawn 在 agent 被激活时运行,此时还没有具体工具上下文。

事件示例:

json
{
  "hook_event_name": "agentSpawn",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789"
}

退出码行为:

  • 0:hook 成功,STDOUT 会加入 agent context;
  • 其他:STDERR 作为 warning 展示给用户。

适合用途:加载项目约定、注入环境说明、收集当前仓库元信息。

UserPromptSubmit:用户提交 prompt 时运行

UserPromptSubmit 在用户提交 prompt 后运行,输出会加入 conversation context。

事件示例:

json
{
  "hook_event_name": "userPromptSubmit",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789",
  "prompt": "user's input prompt"
}

退出码行为:

  • 0:hook 成功,STDOUT 会加入上下文;
  • 其他:STDERR 作为 warning 展示给用户。

适合用途:根据 prompt 自动补充项目约束、提醒安全规则、加载相关上下文。

PreToolUse:工具执行前运行

PreToolUse 是安全控制最常用的 hook。它会在工具执行前拿到工具名称和参数,因此可以做校验和阻断。

事件示例:

json
{
  "hook_event_name": "preToolUse",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789",
  "tool_name": "read",
  "tool_input": {
    "operations": [
      {
        "mode": "Line",
        "path": "/current/working/directory/docs/hooks.md"
      }
    ]
  }
}

退出码行为:

  • 0:允许工具执行;
  • 2:阻止工具执行,并把 STDERR 返回给 LLM;
  • 其他:显示 warning,但仍允许工具执行。

适合用途:禁止写入敏感目录、限制 shell 命令、检查路径是否越界、阻止读取密钥文件。

PostToolUse:工具执行后运行

PostToolUse 在工具已经执行完成后运行,可以访问工具结果。

事件示例:

json
{
  "hook_event_name": "postToolUse",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789",
  "tool_name": "read",
  "tool_input": {
    "operations": [
      {
        "mode": "Line",
        "path": "/current/working/directory/docs/hooks.md"
      }
    ]
  },
  "tool_response": {
    "success": true,
    "result": ["# Hooks\n\nHooks allow you to execute..."]
  }
}

退出码行为:

  • 0:hook 成功;
  • 其他:显示 warning。工具已经执行,不能回滚。

适合用途:记录工具结果、自动格式化、收集审计日志、在写文件后触发轻量检查。

Stop:assistant 完成本轮响应时运行

Stop 在 assistant 本轮响应结束时运行,适合做收尾工作。

事件示例:

json
{
  "hook_event_name": "stop",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789"
}

退出码行为:

  • 0:hook 成功;
  • 其他:STDERR 作为 warning 展示给用户。

注意:Stop hooks 不使用 matcher,因为它不对应某个具体工具。

适合用途:运行格式化、轻量测试、输出提醒、做会话结束后的清理。

MCP 工具的名称格式

对于 MCP tools,tool_name 会包含 MCP server 的命名空间。例如:

json
{
  "hook_event_name": "preToolUse",
  "cwd": "/current/working/directory",
  "session_id": "abc123-def456-789",
  "tool_name": "@postgres/query",
  "tool_input": {
    "sql": "SELECT * FROM orders LIMIT 10;"
  }
}

这让你可以针对外部工具写更精细的策略。例如允许 @postgres/query 只执行 SELECT,禁止 DROPDELETE 或无条件 UPDATE

超时与缓存

hooks 默认超时时间是 30 秒,也就是 30,000ms。可以通过 timeout_ms 字段调整。

成功的 hook 结果可以通过 cache_ttl_seconds 缓存:

  • 0:不缓存,默认值;
  • > 0:按指定秒数缓存成功结果;
  • AgentSpawn hooks 永远不会被缓存。

对于昂贵但稳定的上下文收集任务,可以考虑缓存。对于权限校验和安全拦截,不建议缓存太久,否则可能错过状态变化。

使用建议

  1. 先记录,再阻断。先观察 hook event 长什么样,再加入 exit code 2。
  2. 优先使用精确 matcher,避免误伤所有工具。
  3. 安全逻辑放在 PreToolUse,日志和格式化放在 PostToolUse。
  4. hook 脚本要快速返回,避免拖慢每次工具调用。
  5. STDERR 要写清楚原因,因为阻断信息会返回给 LLM。
  6. 对数据库、文件系统、云服务等高风险 MCP tools 单独写规则。

常见问题

hooks 可以阻止工具调用吗?

可以,但只有 PreToolUse 支持阻止。hook 命令返回 exit code 2 时,Kiro 会阻止工具执行,并把 STDERR 返回给 LLM。

PostToolUse 能撤销已经执行的操作吗?

不能。PostToolUse 运行时工具已经执行完成,适合记录、检查和提示,不适合做真正的安全拦截。需要阻断请使用 PreToolUse。

matcher 应该写 * 还是精确工具名?

默认建议写精确工具名或工具类别。* 适合全局日志、统一审计等场景,但用于阻断时容易误伤正常工作流。