Skip to content

钩子(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

只添加来自你信任来源的钩子。钩子拥有与你的用户账户相同的权限。

另请参阅