外观
钩子(Hooks)让外部程序能够对 Deep Agents Code 的生命周期事件做出反应。在 ~/.deepagents/hooks.json 中配置命令,每当事件触发时,它会向每个匹配命令的 stdin 输送一个 JSON 负载。
钩子在后台线程中以 fire-and-forget 方式运行。它们绝不会阻塞 Deep Agents Code,失败也会被记录日志而不会中断你的会话。
设置
创建 ~/.deepagents/hooks.json:
json
{
"hooks": [
{
"command": ["bash", "-c", "cat >> ~/deepagents-events.log"],
"events": ["session.start", "session.end"]
}
]
}现在,每当会话开始或结束时,Deep Agents Code 都会将事件负载追加到 ~/deepagents-events.log。
钩子配置
配置文件包含一个 hooks 数组。每个条目包含:
command (list[str])(必填):要运行的命令及其参数。不做 shell 展开:如有需要,请使用
["bash", "-c", "..."]。events (list[str]):要订阅的事件名称。省略或留空以接收所有事件。
json
{
"hooks": [
{
"command": ["python3", "my_handler.py"],
"events": ["session.start", "task.complete"]
},
{
"command": ["bash", "log_everything.sh"]
}
]
}上面的第二个钩子没有 events 过滤器,因此它会接收 Deep Agents Code 发出的每一个事件。
负载格式
每个钩子命令都会在 stdin 上收到一个 JSON 对象,其中包含 "event" 键以及事件专属字段:
json
{
"event": "session.start",
"thread_id": "abc123"
}事件参考
session.start
当智能体会话开始时触发(交互式和非交互式模式均会触发)。
- thread_id (string)(必填):会话线程标识符。
session.end
会话退出时触发。
- thread_id (string)(必填):会话线程标识符。
user.prompt
在交互式模式下,当用户提交聊天消息时触发。
无附加字段。
input.required
当智能体需要人工输入(人在回路中断)时触发。
无附加字段。
permission.request
当有一个或多个工具调用需要用户权限、在审批对话框之前触发。
- tool_names (list[str])(必填):请求审批的工具名称。
tool.error
当工具调用返回错误时触发。
- tool_names (list[str])(必填):出错的工具名称。
task.complete
当智能体完成当前任务时触发(流式输出循环结束且无进一步中断)。
- thread_id (string)(必填):会话线程标识符。
context.compact
在 Deep Agents Code 压缩(摘要)对话上下文之前触发。
无附加字段。
执行模型
- 后台线程:钩子子进程通过
asyncio.to_thread在线程中运行,因此主事件循环绝不会被阻塞。 - 并发调度:当多个钩子匹配同一个事件时,它们会在线程池中并发运行。
- 5 秒超时:每个命令都有 5 秒的超时时间。超过此时间的命令会被终止。
- Fire-and-forget:错误按钩子分别捕获,并以 debug/warning 级别记录日志。失败的钩子绝不会让 Deep Agents Code 崩溃或停滞。
- 惰性加载:配置文件在首次调度事件时读取一次,并在会话剩余时间内缓存。
- 无 shell 展开:命令直接执行(不经过 shell)。如果你需要管道或变量展开等 shell 特性,请用
["bash", "-c", "..."]包裹。
钩子示例
将所有事件记录到文件
json
{
"hooks": [
{
"command": ["bash", "-c", "jq -c . >> ~/.deepagents/hook-events.jsonl"],
"events": []
}
]
}任务完成时的桌面通知(macOS)
json
{
"hooks": [
{
"command": [
"bash", "-c",
"osascript -e 'display notification \"Agent finished\" with title \"Deep Agents\"'"
],
"events": ["task.complete"]
}
]
}Python 处理器
编写一个从 stdin 读取 JSON 负载的处理脚本:
python
import json
import sys
def handle_hook_payload(payload: dict) -> None:
event = payload["event"]
if event == "session.start":
print(f"Session started: {payload['thread_id']}", file=sys.stderr)
elif event == "permission.request":
print(f"Approval needed for: {payload['tool_names']}", file=sys.stderr)
if __name__ == "__main__":
handle_hook_payload(json.load(sys.stdin))json
{
"hooks": [
{
"command": ["python3", "my_handler.py"],
"events": ["session.start", "permission.request"]
}
]
}安全注意事项
钩子遵循与 Git 钩子或 shell 别名相同的信任模型——任何能够写入 ~/.deepagents/hooks.json 的用户都可以执行任意命令。这是有意设计的:
- 无命令注入:负载数据仅以 JSON 形式流向 stdin,绝不会流向命令行参数。
json.dumps负责处理转义。 - 默认无 shell:命令以
shell=False运行,防止 shell 注入。 - 畸形配置:无效的 JSON 或意外的类型只会产生记录在案的警告,而不会造成安全问题。
WARNING
只添加来自你信任来源的钩子。钩子拥有与你的用户账户相同的权限。