[控场AI]
· 10 分钟阅读· 5,332 字

用Claude Code打造一个睡觉时也替你干活的AI同事

用Claude Code打造一个睡觉时也替你干活的AI同事

用 Claude Code routine 搭建云端定时文档监控 Agent,核心是职责分离与只起草不发布。

文章讲述一位 Claude API 教程作者因错过 Haiku 5.5 发布五天,转而搭建 `claude-docs-watch` 仓库的实践:用 Claude Code 的 routines 功能(按 cron 触发的云端会话,自动克隆 GitHub 仓库并使用 claude.ai 上的 MCP 连接器)每天监控 12 个官方文档页面。设计的核心取舍是让 Python 脚本负责抓取与生成 unified diff,模型只读 diff 做判断和写作,避免每天消化约 30 万字符全文。提示词的关键边界是「只起草不发布」——草稿末尾留空的 What I verified 章节由人类跑真实 API 后填写。作者还记录了首次运行翻车的细节:Slack 频道找不到、推送冲突需先 pull,并总结出三个坑都指向权限与连接而非提示词,最后给出三种实现路径的对比与选型建议。

一个真实痛点:我落后了5天

故事的开头有点尴尬。一位写 Claude API 教程的作者,因为错过了 Haiku 5.5 的发布整整 5 天——而问题不在于没有监控,恰恰相反,他早就写了一个本地脚本,每天把「文档有变化」的通知推送到 Slack。结果呢,没人在看。

通知太多、太碎、没有判断力,等于没通知。

于是他换了个思路:与其让脚本「报告变化」,不如让一个 AI 同事「读懂变化」,然后每天早上把真正重要的部分写成日文摘要发到 Slack,遇到影响他书稿的改动,还会自动起草一篇文章推到 GitHub。整套东西不需要服务器,不需要额外工具链,只靠 Claude Code 的一个功能。

Claude Code 作息监控实践

Claude Code 的 routines 到底是什么

Claude Code 有一个功能叫 routines:一个按 cron 计划启动的云端会话,会自动克隆你的 GitHub 仓库,使用你在 claude.ai 上挂载的 MCP 连接器(比如 Slack、Gmail),干完活就退出。

它的几个关键特性值得记住:

  • 用 5 字段 cron 表达式(UTC 时区)或一次性时间戳触发,最小间隔为 1 小时
  • 会话启动时你的 GitHub 仓库已经被克隆好,但它看不到你的本地文件、本地环境变量或本地服务
  • 可以使用 claude.ai 上挂载的 MCP 连接器;只配置在 Claude Code 本地的 MCP 服务器不可用
  • 模型、允许的工具、提示词打包在一个 JSON 对象里;提示词每次运行都从零读取,因此必须自包含
  • 创建、更新、立即运行、运行日志都能通过 API 操作(在 Claude Code 内部通过 RemoteTrigger 工具),只有删除需要去网页端

也就是说,routines 给你的是一台「云上带仓库和 Slack 的定时 Agent」,基础设施这一层完全被吃掉了。

MCP(Model Context Protocol) 是 Anthropic 主导提出的一套开放协议,用来把外部服务(Slack、Gmail、GitHub、数据库等)包装成模型可以标准化调用的「工具」,从而把这些服务的能力接入到 Claude 的会话中。可以把它理解为「AI 世界的 USB-C 接口」:每个服务只要实现一次 MCP Server,任何支持 MCP 的客户端就能统一调用它。

在本例里,Slack 就是一个 MCP 连接器——routine 通过它在云端发消息。需要特别注意的是 MCP 连接的挂载位置:只有挂在 claude.ai 账号下、云端可见的连接器才会被 routine 使用;只配置在本地 Claude Code 环境里的 MCP Server,云端会话是访问不到的。这解释了后文里「Slack 连接器挂错工作区」这类问题的根源——它不是脚本 bug,而是连接器作用域的问题。同一套逻辑也适用于 GitHub:云端能访问的仓库,取决于你在 claude.ai 上授权了哪些仓库。

设计上的关键取舍:让 Python 找差异,让模型做判断

这位作者搭的仓库叫 claude-docs-watch,结构并不复杂:

  • pages.json:监控的 12 个官方文档页面
  • watch.py:抓取 → 与 state/ 比对 → 生成 diffs/<date>/ 和 result.json(只用标准库)
  • state/:昨天的文本
  • diffs/:每天的 unified diff
  • drafts/:模型在改动重要时写出的草稿
  • log/:每日摘要
  • ROUTINE_PROMPT.md:routine 收到的指令

最重要的设计决策是:Python 负责找出差异,模型只负责判断和写作。

理由很实在——如果让模型「读完这 12 个页面然后告诉我改了什么」,每天早上要消化约 30 万字符,既慢又容易漏。而让 watch.py 先生成 diff 文件,模型就只需读取这几个 diff。这是把「体力活」和「判断活」分开的典型做法,也是这类定时 Agent 能不能用的分水岭。

unified diff(统一差异格式) 是 diff -u 或 git diff 生成的文本格式,用 - 开头表示被删除的行、+ 开头表示新增的行、空行前带一个空格表示未变动的上下文行,并配有 @@ -旧行号,行数 +新行号,行数 @@ 这样的定位标记。它的价值在于信噪比:12 个页面动辄几十万字符,但真正变化的往往只有几百字符,用 unified diff 表达后,模型读到的输入可能被压缩到原文的千分之一甚至更低。

这也是「Python 找差异、模型做判断」这个设计能成立的技术前提。如果换成让模型每轮读全文,不仅 token 消耗大、速度慢,还极其容易因为注意力稀释而漏掉关键改动。把检测阶段固化成确定性的字符串比对,判断阶段才交给模型,是这类定时 Agent 通用的成本与可靠性优化手段——本质上是用「便宜的确定性代码」替模型做它不擅长的体力活,把模型的算力留给真正需要推理的判断和写作。

提示词怎么写:这位同事只起草,从不发布

routine 的 JSON 配置里,模型选的是 Sonnet 5.5,作者评价「日常任务只是读 diff 然后总结,完全够用」。允许的工具包括 Bash、Read、Write、Edit、Glob、Grep,以及 Slack 的两个 MCP 工具。

真正有意思的是那份提示词。它把整个流程拆成 7 步,几个细节很见功力:

  • 第一步先 git pull --rebase origin main,因为检出可能是旧的
  • 没有变化时,只追加一行日志、推送、发一条简短 Slack 消息就停止
  • 有变化时,读每个 diff,忽略纯格式改动,逐页写摘要,并判断「影响 / 不影响 / 待确认」
  • 如果至少有一页受影响,且属于新模型、新价格、破坏性变更、弃用/退役、Managed Agents 新功能这五类,才写一篇草稿文章
  • 草稿引用 diff 里的原文、链接官方页面,并以一个「What I verified」占位章节结尾

最后这一点是整件事的核心:这位 AI 同事负责起草,从不发布。 草稿末尾那个空的「What I verified」章节,是留给人去跑真实 API 后填写的。提示词里甚至明确写着「不要声称任何东西被测试过」。

这条边界感,比任何自动化技巧都更值得抄。

人机协作中的「human-in-the-loop(人类在环)」 指的是让自动化系统只完成到某个明确节点,关键决策或对外发布仍由人把关。这里用两道机制落实:一是草稿末尾预留空的「What I verified」章节,迫使人必须真正跑过 API、填过内容后才能发布;二是提示词显式禁止「声称任何东西被测试过」,从源头上切断模型幻觉出「实测结论」的可能。

这背后的动机是可信度:教程、技术文档这类内容一旦出现模型编造的价格、参数或行为描述,代价远大于自动化省下的时间。相比「让 AI 全权发布再事后抽查」,把发布权留在人手里是一种更安全的默认姿态。它也顺带解决了责任归属问题——出了错,最后的编辑者清楚自己没核实过。这种边界设计比具体的自动化技巧更可迁移:凡是输出会给外部读者或用户的 Agent,都应该划出一条「哪一步必须由人确认」的线。

头两次运行:翻车的全是权限和连接

作者坦诚记录了前两次运行(10 月 16 日)的完整过程。

第一次运行(23 秒,8 轮):沙箱分配、仓库克隆、watch.py 没发现变更、日志追加、推送成功——然后 Slack 发送失败,报 channel_not_found。Agent 自己去找频道没找到,退而求其次发了条手机推送通知。原因是 claude.ai 上的 Slack 连接器挂到了另一个工作区。作者重新连接,并把频道 ID 直接写进了提示词。

第二次运行(51 秒,9 轮):Slack 发送成功,然后推送被拒绝——沙箱里的检出早于第一次运行的提交。Agent 执行了 git pull --rebase,发现自己的提交是重复行,就丢弃并干净退出了。行为很合理,但作者还是把 git pull --rebase 加成了第一步,免得每天早上重演。

运行日志可以通过 API 拿到,每一次工具调用、每一个错误、最终消息都有时间戳。换句话说,你睡觉时这位同事干了什么,你醒了一五一十都能回放。

三个真的会绊倒你的坑

作者总结了三个踩过的坑,全都指向同一件事:出问题的不是提示词,是权限和连接。

  1. GitHub App 必须装在组织上。 光在 claude.ai 连接 GitHub 还不够,组织下的私有仓库需要先在组织上安装 github.com/apps/claude 并授权该仓库,否则创建 routine 会报 repo_access_denied。
  2. 一个连接器只指向一个工作区。 多个 Slack 工作区并存时很容易挂错,所以要用频道 ID,不要用频道名。
  3. 检出不一定是新的。 任何会推送的 routine,都应该先 pull。

成本与限制:不是用来「5 分钟轮询」的

  • 运行消耗的是 Claude 订阅计划的额度,作者没看到单独的 API 计费;一次无变化的运行大约几千 token
  • 最小间隔 1 小时,所以它不是「5 分钟轮询」这类需求的工具
  • 无法访问你的本地机器,任务需要的一切都必须在仓库里或从云端可达
  • 删除只能在网页端操作

同一件事,三种搭法

作者给了一张很实用的对比表,列出了三种实现路径:

Claude Code routineManaged Agents本机 cron + API
运行位置Anthropic 云端Anthropic 云端你的机器
配置量一个 JSONAgent + Deploymentplist/crontab + 脚本
计费计划额度token + 会话时长($0.08/小时)API token
最适合能装进仓库 + 连接器的周期任务需要托管工具箱的长时 Agent需要本地文件或本地凭证的任务
通知方式连接器(Slack/Gmail)、推送webhook自己实现

作者的实际选择是三种并用:这个文档监控是 routine;生产环境的 Agent 平台用 Managed Agents;每周的 Search Console 报告因为需要本地 OAuth token,继续留在 launchd 上。

Managed Agents 是 Anthropic 提供的另一档托管能力:你需要先定义一个 Agent(角色、工具、系统提示),再把它部署成 Deployment,由平台负责调度与运行。与 routine 的关键差异在于它面向的是长时运行、需要托管工具箱的 Agent 任务,计价方式是 token 加上会话时长(示例中为 $0.08/小时),而 routine 消耗的是订阅计划额度。

本机 cron / launchd 则是完全自管的路线:定时任务跑在你自己机器上,因此可以访问本地文件、本地环境变量和本地 OAuth 凭证,代价是机器得开机、出错要自己兜底、通知也得自己实现。三者的选择判据其实很清晰:先看「任务需要的东西在哪里」——如果需要本地文件或本地凭证,就只能留在本机;如果一切都能装进仓库加连接器,routine 是配置成本最低的选项;如果任务需要长时间运行并携带一套工具集,才轮到 Managed Agents。作者三种并用,正是按这个判据各取所长的结果。

值得带走的三点

  • Claude Code routine 给你的是一个「带仓库和 Slack 的定时云 Agent」,零基础设施
  • 把角色切开:Python 负责检测,模型负责判断和写作,人类负责发布
  • 真正会出问题的是权限和连接,不是提示词

整套思路最有价值的地方,不在于它能自动发 Slack,而在于它划清了一条线——AI 可以把判断和草稿做完,但发布权始终留在人手里。这条线,可能比自动化本身更值得借鉴。

#Claude Code#routines#AI 自动化#MCP 连接器#定时任务#GitHub 仓库监控#AI Agent#Slack 通知
分享:

相关推荐