Appearance
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 判断下一步动作:
| 退出码 | 行为 |
|---|---|
0 | hook 成功。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,禁止 DROP、DELETE 或无条件 UPDATE。
超时与缓存
hooks 默认超时时间是 30 秒,也就是 30,000ms。可以通过 timeout_ms 字段调整。
成功的 hook 结果可以通过 cache_ttl_seconds 缓存:
0:不缓存,默认值;> 0:按指定秒数缓存成功结果;- AgentSpawn hooks 永远不会被缓存。
对于昂贵但稳定的上下文收集任务,可以考虑缓存。对于权限校验和安全拦截,不建议缓存太久,否则可能错过状态变化。
使用建议
- 先记录,再阻断。先观察 hook event 长什么样,再加入 exit code 2。
- 优先使用精确 matcher,避免误伤所有工具。
- 安全逻辑放在 PreToolUse,日志和格式化放在 PostToolUse。
- hook 脚本要快速返回,避免拖慢每次工具调用。
- STDERR 要写清楚原因,因为阻断信息会返回给 LLM。
- 对数据库、文件系统、云服务等高风险 MCP tools 单独写规则。
常见问题
hooks 可以阻止工具调用吗?
可以,但只有 PreToolUse 支持阻止。hook 命令返回 exit code 2 时,Kiro 会阻止工具执行,并把 STDERR 返回给 LLM。
PostToolUse 能撤销已经执行的操作吗?
不能。PostToolUse 运行时工具已经执行完成,适合记录、检查和提示,不适合做真正的安全拦截。需要阻断请使用 PreToolUse。
matcher 应该写 * 还是精确工具名?
默认建议写精确工具名或工具类别。* 适合全局日志、统一审计等场景,但用于阻断时容易误伤正常工作流。