让它跑长任务时主动叫你,而不是你守着屏幕

批量处理四十份文件要跑二十分钟,中间可能停下来等你批准。用通知钩子把「需要你」和「跑完了」推到手机或系统通知上,你可以去干别的。

2026/08/05约 6 分钟HiBridge 原创
方法来源本文由 HiBridge 撰写,方法来自下面的出处。
出处
Hooks reference
来自
Anthropic 官方文档
查证日期
2026/08/05

让它批量处理四十份访谈稿,要跑二十分钟。中间可能会停下来问你「这个操作要不要批准」,也可能跑到一半卡住。

于是你只能守着屏幕。 而这二十分钟本来是你可以去开会、去吃饭的。

Claude Code 有一套钩子(hooks)机制,能在特定时刻触发你指定的命令。用它把「需要你」和「跑完了」推出来,就不用盯着了。

通知钩子能捕捉哪几种时刻

Notification 事件在 Claude Code 向你发通知时触发。它可以按通知类型过滤,官方支持的类型里,和长任务最相关的是这几个:

类型 什么时候触发
permission_prompt 需要你批准某个操作
agent_needs_input 代理需要你输入
agent_completed 代理完成了
idle_prompt 空闲等待中

前三个正好覆盖「你需要被叫醒」的全部情形。

Notification 是非阻塞事件——它只是通知,不会拦下任何操作。

方案一:系统通知(最简单,零依赖)

如果你就在电脑前但在别的窗口工作,系统通知就够了。不需要注册任何服务。

~/.claude/settings.json 里加:

JSON
{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt|agent_needs_input|agent_completed",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/notify.sh"
          }
        ]
      }
    ]
  }
}

然后建 ~/.claude/hooks/notify.sh

Terminal
#!/bin/bash
# 钩子的输入是一段 JSON,从标准输入进来
INPUT=$(cat)
MSG=$(echo "$INPUT" | jq -r '.message // "Claude Code 需要你"')

# macOS 系统通知
osascript -e "display notification \"$MSG\" with title \"Claude Code\" sound name \"Glass\""

记得给它执行权限:

Terminal
chmod +x ~/.claude/hooks/notify.sh

Windows 的话把最后那行换成 PowerShell 的气泡通知,或者直接用下面的手机方案。

方案二:推到手机(人不在电脑前)

想出门也能收到,就需要一个推送服务。这类服务(Pushover、Bark、ntfy 等)的原理一样:给你一个专属地址,往那儿发一条 HTTP 请求,你手机上就弹一条通知。

脚本改成这样:

Terminal
#!/bin/bash
INPUT=$(cat)
MSG=$(echo "$INPUT" | jq -r '.message // "Claude Code 需要你"')

curl -s -X POST "<你的推送服务地址>" \
  -d "title=Claude Code" \
  -d "message=$MSG" > /dev/null

具体的字段名和认证方式按你选的服务的文档填——各家不同,但都是一条 curl 的事。

⚠️ 别把密钥直接写进提交到版本库的文件里。 放在 ~/.claude/ 下的脚本里(那是本机的),或者读环境变量。

一次性买断 vs 订阅

选服务时注意计费方式。有些是一次性买断(比如 Pushover),有些按月订阅。对这个用途来说,一次性的更划算——你一天可能就用几次。

更进一步:区分「需要你」和「跑完了」

上面的配置把三种情况混成了一条通知。分开处理更有用——「需要批准」是急事,「跑完了」不是。

JSON
{
  "hooks": {
    "Notification": [
      {
        "matcher": "permission_prompt|agent_needs_input",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/notify-urgent.sh" }
        ]
      },
      {
        "matcher": "agent_completed",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/notify-done.sh" }
        ]
      }
    ]
  }
}

两个脚本用不同的提示音,或者推送到不同优先级。手机响一声你就知道是哪一类,不用掏出来看。

配置放在哪

位置 生效范围 能不能共享
~/.claude/settings.json 所有项目 否,只在本机
.claude/settings.json 单个项目 可以提交进版本库共享
.claude/settings.local.json 单个项目 否,已被 gitignore

通知这类偏好是个人的,~/.claude/settings.json 就好。

让 Claude 帮你配

你不用手写这些。直接说:

帮我配一个通知钩子:需要我批准操作、或者任务完成时,发一条 macOS 系统通知。配置写进 ~/.claude/settings.json,脚本放 ~/.claude/hooks/ 下。

它会把 JSON 和脚本都建好。配完让它自己触发一次验证——比如让它请求一个需要批准的操作,看通知有没有弹出来。

顺带一提:钩子还能做别的

通知只是钩子最简单的一个用途。PreToolUse 钩子能在某个操作执行之前拦下来:

JSON
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "if": "Bash(rm *)",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
          }
        ]
      }
    ]
  }
}

脚本返回一个「拒绝」的判定,这个命令就执行不了。

这一点很重要:钩子是强制执行的,而 CLAUDE.md 里写的规则只是上下文——它会尽量遵守,但不保证。凡是「绝对不能发生」的事(比如删除原始素材目录),写成钩子,别写成规则。

回到那篇检查点能救你什么rm 删掉的文件回退救不回来。用一个 PreToolUse 钩子把删除操作拦下来,是比事后补救更靠谱的做法。