1. 项目概述当 CLI 不再只是本地命令行而成为你云端的“数字分身”“Claude Code Routines将 CLI 工具变成云端自动化引擎”——这个标题乍看像一句技术营销话术但拆开来看它精准击中了当前开发者工作流里一个真实、普遍且长期被忽视的痛点我们每天在终端里敲下的那些git commit、npm run build、python scripts/check_docs.py本质上都是高度结构化、可重复、有明确输入输出的“小任务”却始终被困在本地机器上一关机就停摆一换环境就得重配一要跨团队协作就得写文档、开会议、建共享账号。而 Routines 的核心价值就是把这种“人肉 CLI 操作”升维成一种可托管、可编排、可触发、可审计的云端服务。它不是让你放弃终端而是让终端成为你指挥云端引擎的控制台。关键词里的 “Claude Code” 是执行主体“Routines” 是封装单元“CLI” 是交互入口“云端自动化” 是最终形态“Webhook” 则是它与外部世界握手的关键协议。这背后没有魔法只有三件东西一个清晰定义的 Prompt即“指令说明书”一套受控的权限环境即“工作间”以及一个或多个触发条件即“开关”。我第一次用 Routines 实现“每日凌晨自动扫描所有 PR 中的 API 变更并生成一份 Markdown 格式的兼容性报告推送到内部 Wiki”时真正体会到什么叫“下班后代码还在替你打工”。它适合三类人一是被重复性运维任务压得喘不过气的 DevOps 工程师二是想把团队最佳实践固化为自动检查点的技术负责人三是希望把个人知识沉淀比如“每次发版前必须做的 7 项检查”变成可复用资产的资深开发者。这不是一个替代 GitHub Actions 或 Cron 的工具而是一个更高维度的“AI 驱动的自动化编排层”它负责理解“意图”而把“执行细节”交给已有的生态。2. 核心设计逻辑为什么是“云端”而非“本地”为什么是“Routines”而非“脚本”2.1 云端执行不是为了炫技而是解决根本性约束很多人第一反应是“我的脚本在本地跑得好好的为什么要搬到云端” 这个问题问到了根子上。Routines 选择云端执行绝非为了堆砌“云原生”的概念而是直面 CLI 工具在本地运行时无法规避的硬性瓶颈。首先是环境一致性。你在 Ubuntu 20.04 上调试通过的codex cli脚本换到同事的 macOS 或 CI 服务器的 Alpine Linux 上可能因为 OpenSSL 版本差异直接报错error:0308010c:digital envelope routines::unsupported。这个错误在 Node.js 17 环境中尤为常见根源是底层 crypto 模块对旧版加密算法的支持策略变更。本地 CLI 的每一次npm install都是一次环境赌博。而 Routines 的云端环境由 Anthropic 统一维护和打补丁你配置的environment variables和setup script会在一个干净、隔离、版本可控的容器中执行彻底消除了“在我机器上能跑”的幻觉。我曾为一个需要调用playwright cli进行前端截图的 Routine 配置过环境变量PLAYWRIGHT_BROWSERS_PATH/usr/local/browsers这个路径在本地开发机上是/Users/me/.cache/ms-playwright但在云端环境里它被标准化为一个只读的、预装了 Chromium 和 Firefox 的路径。这种一致性是任何.bashrc或Dockerfile都难以在团队层面 100% 保证的。其次是资源与生命周期。一个需要遍历整个 Git 仓库历史、分析数千个提交的“技术债扫描” Routine可能需要 15 分钟才能完成。如果你把它写成一个本地 Cron 任务你的笔记本电脑就必须整晚不休眠、不锁屏、不关机。一旦网络中断任务就失败。而云端 Routine 的执行完全脱离你的物理设备它运行在 Anthropic 的弹性计算集群上有独立的 CPU、内存配额和超时保护默认 30 分钟可申请延长。更重要的是它的“状态”是持久化的。你可以随时在 Web UI 里看到某次运行的完整日志、输入参数、输出结果甚至可以点击“Re-run”按钮用完全相同的上下文重新执行一次。这种可观测性和可重入性是本地脚本日志文件永远无法提供的。最后是安全边界的天然隔离。当你在本地终端运行claude cli --repo my-org/my-app --action update-deps时这个命令拥有你当前 shell 的全部权限它可以读取你的~/.ssh/id_rsa可以访问你的~/.aws/credentials甚至可以执行rm -rf /虽然你不会这么干。而 Routines 的权限模型是声明式的、最小化的。你只能在创建时从一个白名单里勾选它能访问的 GitHub 仓库、能使用的 Slack 频道、能连接的数据库。它没有“家目录”的概念没有sudo权限它的网络访问也受到严格限制默认仅允许出站 HTTPS如需访问内网服务必须显式配置 VPC 连接器。这就像给一个外包工程师发了一张门禁卡他只能进你指定的那间办公室使用你指定的那台电脑处理你指定的那份文件。这种“零信任”的权限设计是保障自动化不变成“自动化灾难”的基石。2.2 Routines 封装从“命令”到“可交付产品”的范式跃迁如果说“云端”解决了运行环境的问题那么“Routines”这个概念则解决了 CLI 工具的“可交付性”和“可协作性”问题。一个传统的 CLI 脚本比如./check-pr.sh它本质上是一个黑盒它的输入参数、输出stdout/stderr、副作用修改文件、发消息、依赖需要什么二进制、什么环境变量都散落在代码的各个角落只有作者自己心里有数。而一个 Routine是一个自包含的、可描述的、可版本化的“自动化产品”。一个 Routine 的五个核心组成部分构成了它的 DNAPrompt指令说明书这是 Routine 的灵魂不是一句简单的# Review this PR而是一份详尽的“运行手册”。它必须明确回答输入数据从哪里来例如“从 GitHub Event Payload 中提取pull_request.head.sha和pull_request.base.repo.full_name”要执行什么逻辑例如“克隆仓库检出该 SHA运行npm test并解析jest的 JSON 报告”成功的标准是什么例如“jest报告中的numFailedTests必须为 0且numTotalTests大于 100”失败时该如何降级例如“如果npm test超时不要报错而是向 Slack 发送一条警告消息并创建一个 draft PR将本次失败的测试用例列表作为 PR 描述”输出到哪里例如“将完整的测试报告上传到 S3 存储桶my-org-reports的pr-checks/2024/06/15/PR-1234/路径下”我见过最优秀的 Prompt写得像一份 RFC 文档里面甚至包含了错误码定义和重试策略。Repositories目标仓库这是 Routine 的“工作对象”。它不是一个字符串而是一个受控的引用。你不能在 Prompt 里写git clone https://github.com/my-org/my-app.git而是必须在 UI 或 CLI 中从你已授权的 GitHub 仓库列表里选择my-org/my-app。这确保了 Routine 只能操作你明确授予它权限的代码杜绝了脚本里硬编码的 URL 可能带来的越权风险。Cloud Environment云端环境这是 Routine 的“工作间”。它不是一个模糊的“Linux 服务器”而是一个精确配置的沙箱。你可以指定基础镜像如ubuntu:22.04、预装的工具链如nodejs18,python3.11,playwright1.39、环境变量如API_KEYxxx,DEBUGtrue、以及一个setup script一段在每次运行前都会执行的 Bash 脚本用于安装特定的 Python 包或下载私有证书。这个环境是 Routine 的“操作系统”它决定了你能做什么不能做什么。Connectors连接器这是 Routine 的“手脚”。它定义了 Routine 如何与外部世界交互。GitHub Connector让它能读写 PRSlack Connector让它能发消息Linear Connector让它能创建 Issue。每个 Connector 都有精细的权限粒度。例如GitHub Connector 不是简单地给你“读写权限”而是让你选择“只读 Issues”、“可写 Comments”、“可创建 Draft PRs”但不能“强制推送force push”。这种权限的“乐高化”拼装是实现最小权限原则的关键。Triggers触发器这是 Routine 的“开关”。它定义了 Routine 在什么条件下启动。Schedule 触发器是“时间开关”API 触发器是“HTTP 开关”GitHub Events 触发器是“事件开关”。一个 Routine 可以同时拥有多个开关比如一个“每日健康检查”Routine既可以被0 2 * * *的 Cron 定时触发也可以被一个来自飞书机器人Feishu Bot的 Webhook 手动触发用于在紧急故障时立刻拉起检查。这种多触发源的设计让 Routine 成为了一个真正的“事件响应中心”。把这五样东西打包在一起你就得到了一个可以被命名如pr-auto-review-v2、被描述如 “基于团队代码规范的 PR 初筛”、被分享通过链接或 YAML 导出、被版本化每次修改都生成新版本号、被审计所有运行记录都留存的“自动化产品”。它不再是一个需要别人chmod x并祈祷它能跑起来的脚本而是一个可以直接部署、监控和管理的服务。3. 实操核心环节从零开始创建一个“飞书 Webhook 触发的 PR 自动审查” Routine3.1 前期准备CLI 工具链与身份认证在动手创建之前你必须确保本地 CLI 工具链是完备且可信的。这里要特别注意网络热词里反复出现的claude code安装、claude cli安装、windows安装claude code等问题。官方推荐的方式是通过npm安装anthropic-ai/cli包但这恰恰是问题的高发区。很多用户在 Windows 或某些 Linux 发行版上执行npm install -g anthropic-ai/cli后会遇到error: claude cli not found in path的错误。这通常不是 CLI 本身的问题而是 npm 的全局 bin 目录没有被正确添加到系统的PATH环境变量中。实操心得我建议绕过全局安装采用更可控的“局部安装 显式调用”方式。首先在你的项目根目录下初始化一个package.json如果还没有的话npm init -y然后将 CLI 作为项目的开发依赖安装npm install --save-dev anthropic-ai/cli这样CLI 的可执行文件会被安装到./node_modules/.bin/claude。接下来你可以通过npx claude来调用它npx会自动在node_modules/.bin中查找并执行。这种方式彻底规避了PATH配置问题而且不同项目可以使用不同版本的 CLI互不干扰。对于claude code desktop和cli版本的区别我的经验是桌面版是 GUI 入口适合快速上手和调试而 CLI 版本是生产环境的“真相之源”所有 Web UI 的操作最终都会转化为 CLI 命令。因此掌握 CLI 是深入理解 Routines 的必经之路。身份认证是另一个关键点。CLI 需要一个有效的 API Key 才能与 Anthropic 的云端服务通信。这个 Key 不是你在官网注册时的密码而是在 Claude Code 官网 的Settings API Keys页面里生成的。生成后请务必将其保存在一个安全的地方如密码管理器并绝对不要将其硬编码在你的 Prompt 或脚本中。CLI 会从环境变量CLAUDE_API_KEY中读取它。所以最安全的做法是在你的终端会话中临时设置这个变量export CLAUDE_API_KEYsk-ant-api03-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx或者更进一步将其写入一个.env文件并确保.env在.gitignore中然后使用dotenv工具加载。记住这个 Key 的泄露等同于你的 GitHub 账号被他人掌控因为它可以代表你执行所有你有权限的操作。3.2 创建 RoutineWeb UI 与 CLI 的双轨并行创建一个 Routine 有两种主流方式Web UI 和 CLI。Web UI 对新手友好所见即所得CLI 则更强大、更可编程、更适合 CI/CD 集成。我会以创建一个“飞书 Webhook 触发的 PR 自动审查”Routine 为例展示两种方式的协同。第一步在 Web UI 中定义骨架打开 Claude Code 的 Web 控制台导航到Routines页面点击Create new routine。你会看到一个表单它对应着 Routine 的五大要素。Name Prompt: 给它起个名字比如feishu-pr-review。在 Prompt 编辑框里粘贴一份精心编写的指令。下面是我实际使用的一个简化版 Prompt它展示了如何将“飞书”和“GitHub”两个世界打通# Role: Senior Code Reviewer for MyOrg Backend Team ## Task: Perform an automated, high-signal review of a GitHub Pull Request. ## Input: This routine is triggered by a Feishu Webhook. The webhook payload contains: # - github_repo: the full name of the GitHub repository (e.g., my-org/backend) # - github_pr_number: the number of the pull request (e.g., 123) # - feishu_chat_id: the ID of the Feishu chat where the report should be sent. ## Steps: 1. Use the GitHub Connector to fetch the PR details for github_repo and github_pr_number. 2. Analyze the PRs title and description for common anti-patterns (e.g., WIP, DO NOT MERGE, missing Jira ticket). 3. Fetch the list of changed files. For each file that ends with .py, run a static analysis using pylint (pre-installed in the environment) and flag any E (error) or F (fatal) level issues. 4. If any critical issue is found, post a detailed comment on the PR using the GitHub Connector. 5. Compile a summary report and send it as a rich text message to the Feishu chat identified by feishu_chat_id using the Feishu Connector. ## Output: A Feishu message containing a summary table of findings and a link to the full PR review comment.Repositories: 在下拉菜单中选择my-org/backend。这是你授权给这个 Routine 访问的唯一仓库。Environment: 选择一个预设的Python 3.11 Pylint环境或者创建一个新的。在Environment variables中添加FEISHU_BOT_TOKENyour_feishu_bot_token_here。这个 Token 是你在飞书开放平台创建机器人时获得的它赋予了 Routine 向指定群聊发消息的能力。Connectors: 勾选GitHub和Feishu。对于 GitHub只授予Read Pull Requests和Write Pull Request Comments权限。对于 Feishu只授予Send Messages to Chat权限。切记不要勾选Write to GitHub Repositories除非你真的需要它直接修改代码。Triggers: 这是关键。选择API (Webhook)触发器。系统会为你生成一个唯一的 Webhook URL 和一个 Bearer Token。这个 URL 就是你要在飞书里配置的地址。Bearer Token 必须被当作最高机密来保管它相当于这个 Routine 的“密码”。完成表单后点击Create。此时一个名为feishu-pr-review的 Routine 就诞生了但它还处于“未激活”状态因为你还没有配置飞书端。第二步在飞书端配置 Webhook登录飞书开放平台进入你的应用管理后台。找到机器人-自定义机器人创建一个新的机器人。在配置页面找到Webhook 地址字段将你在 Claude Code Web UI 中生成的 Webhook URL 粘贴进去。飞书会要求你设置一个Secret这是一个额外的安全层用于验证 Webhook 请求确实来自飞书。你需要在 Claude Code 的 Routine 设置中找到Webhook Security部分将这个Secret填入。这一步至关重要它防止了恶意第三方伪造飞书请求来触发你的 Routine。第三步用 CLI 进行精细化配置与测试现在Routine 的骨架已经搭好但 Web UI 的配置是“静态”的。为了让它真正“活”起来你需要用 CLI 来注入动态参数。假设你想让飞书里的某个用户在群里发送/review pr 123就能触发这个 Routine。这需要一个中间的飞书机器人服务来解析命令并构造正确的 HTTP POST 请求。首先用 CLI 获取这个 Routine 的详细信息确认其 IDnpx claude routines list --json | jq .routines[] | select(.name feishu-pr-review) | .id假设返回rt-abc123。然后你可以用 CLI 来手动触发一次测试运行验证整个链路是否通畅curl -X POST \ -H Authorization: Bearer your-bearer-token \ -H Content-Type: application/json \ -d { github_repo: my-org/backend, github_pr_number: 123, feishu_chat_id: oc_abcdef1234567890 } \ https://api.anthropic.com/v1/routines/rt-abc123/fire这个curl命令模拟了飞书机器人发来的请求。如果一切顺利你将在 Web UI 的Runs页面看到一次新的运行记录状态为Succeeded并且你指定的飞书群聊里会收到一条格式精美的审查报告。如果失败了日志会清晰地告诉你是在哪一步卡住了是 GitHub Token 权限不足是 Feishu Bot Token 过期还是pylint分析时找不到某个 Python 包这种端到端的可观测性是本地脚本调试梦寐以求的能力。3.3 关键配置详解Prompt、环境变量与连接器的协同艺术一个 Routine 的成败90% 取决于 Prompt 的质量而剩下的 10%则取决于环境变量和连接器的精准配置。这三者不是孤立的而是一个精密咬合的齿轮组。Prompt 的编写哲学从“需求”到“可执行 Runbook”很多新手的 Prompt 写得像一句需求“帮我看看这个 PR 有没有问题。” 这在人类对话中没问题但在 AI 自动化中它是灾难的开始。AI 不会“帮你”它只会“执行”。因此Prompt 必须是一份无歧义、有边界、可验证的 Runbook。无歧义避免使用“好”、“坏”、“合理”等主观词汇。要把它们翻译成可量化的规则。例如“好”的代码风格应该定义为“符合 PEP8 规范且pylint得分大于 9.0”。有边界明确告诉 AI 它的“能力范围”。例如“你只能使用pylint进行静态分析禁止使用bandit或safety因为这些工具不在当前环境中。” 这句话看似多余但能有效防止 AI 在“思考”时产生幻觉去调用一个根本不存在的命令。可验证每一个步骤的输出都必须有明确的成功/失败判定标准。例如“步骤 3 的成功标准是pylint命令的退出码exit code为 0且 stdout 中不包含E[0-9]{3}或F[0-9]{3}的匹配项。”我在编写一个“依赖安全扫描”Routine 的 Prompt 时就加入了这样的验证逻辑# Step 2: Run pip-audit to scan for vulnerable dependencies. # Expected Success: Command exits with code 0 AND stdout contains No known vulnerabilities found. # Expected Failure: Command exits with code 1 AND stdout contains Found X known vulnerabilities. # If command fails with code 2 (network error), retry once with --timeout 60.这种写法让 Routine 的行为变得完全可预测和可测试。环境变量不只是“配置”更是“契约”环境变量在 Routine 中扮演着双重角色一是传递敏感信息如FEISHU_BOT_TOKEN二是定义运行时的“契约”。例如你可以定义一个MAX_FILE_SIZE_MB5的环境变量然后在 Prompt 中写“如果任何一个被修改的 Python 文件大小超过MAX_FILE_SIZE_MBMB则跳过对该文件的pylint分析并在报告中注明原因。” 这样你就可以通过修改环境变量来动态调整 Routine 的行为而无需每次都去重写 Prompt。这是一种非常强大的“配置即代码Configuration as Code”实践。连接器权限的“最小化”与“组合化”连接器的配置是安全性的最后一道防线。我有一个血泪教训早期我为了图省事在一个 Routine 中勾选了GitHub: Full Access结果在一次 Prompt 的误写中AI 错误地理解了指令执行了git push --force origin main导致主分支的历史被重写。从此我给自己立下铁律永远只授予连接器完成其单一任务所必需的、最窄的权限。对于“PR 审查”只需要Read PRs和Write Comments对于“文档同步”只需要Read Files和Write Files且限定在docs/目录下对于“告警通知”只需要Send Messages。这种“组合化”的权限授予让你可以像搭积木一样构建出功能复杂但权限清晰的自动化流程。4. 常见问题与实战排查从error:0308010c到 Webhook 超时的全链路诊断4.1 环境与依赖问题error:0308010c的根源与解法error:0308010c:digital envelope routines::unsupported这个错误是网络热词中出现频率最高的报错之一也是新手最容易陷入的“坑”。它几乎总是出现在使用codex cli或其他基于 Node.js 的 CLI 工具时。它的字面意思是“数字信封例程不支持”但其背后的真实含义是你正在使用的 Node.js 版本其内置的 OpenSSL 库拒绝加载或使用一个它认为不安全或已废弃的加密算法。这个错误的典型触发场景是你的本地 Node.js 版本是 18.x 或 20.x而你试图运行一个为 Node.js 16.x 编写的、依赖了旧版crypto模块 API 的脚本。Node.js 17 为了提升安全性移除了对md4、md5、sha1等弱哈希算法的默认支持并改变了createCipher/createDecipher等函数的行为。排查与解决路径如下确认 Node.js 版本首先在终端中运行node --version。如果显示v18.17.0或更高那么问题极大概率在此。检查 CLI 工具的兼容性查阅anthropic-ai/cli的官方文档或 GitHub Issues确认其最新版本是否已适配 Node.js 18。如果尚未适配官方通常会提供一个临时的环境变量解决方案。终极解决方案使用兼容模式。在运行 CLI 命令前设置以下环境变量export NODE_OPTIONS--openssl-legacy-provider npx claude routines list这个--openssl-legacy-provider标志会强制 Node.js 加载一个兼容旧版算法的 OpenSSL 提供者。这是目前最广泛、最可靠的解决方案。注意这个环境变量只应在运行claudeCLI 时设置而不应永久添加到你的~/.bashrc中因为它会降低整个 Node.js 环境的安全性。预防胜于治疗在你的 Routine 的Cloud Environment配置中明确指定一个经过充分测试的 Node.js 版本例如nodejs16.20.2。这样无论你的本地开发环境如何变化云端的执行环境始终是稳定和可预测的。这正是 Routines “环境一致性”优势的直接体现。4.2 Webhook 问题从飞书配置到 Claude 接收的全链路追踪Webhook 是 Routines 与外部世界沟通的桥梁但这座桥也最容易出现“信号不良”。最常见的问题是飞书那边显示“消息已发送”但 Claude Code 的 Web UI 里却没有任何运行记录。这通常不是单点故障而是一个涉及三方飞书、网络、Claude的链路问题。系统化的排查清单步骤检查项如何验证说明1. 飞书端Webhook URL 是否正确在飞书机器人配置页复制 URL粘贴到浏览器地址栏看是否返回405 Method Not Allowed正常或404 Not FoundURL 错误。405表示 URL 正确但浏览器用了 GET 方法404表示 URL 根本不存在可能是你在 Claude UI 中创建后又删除了或者复制时漏掉了字符。2. 飞书端Secret 是否匹配在飞书配置页的Security Settings中找到Verification Token和App Secret。在 Claude UI 的 Routine 设置中找到Webhook Security确认Secret字段的值与飞书的Verification Token完全一致区分大小写。这是最常见的配置错误。飞书会用这个Secret对请求体进行签名Claude 会用它来验签。不匹配请求会被直接拒绝。3. 网络层请求是否到达 Claude在 Claude UI 的Runs页面切换到All Runs标签页查看是否有Failed状态的记录。如果有点开详情看错误类型是Webhook Signature Invalid验签失败还是Webhook Payload MalformedJSON 格式错误。如果连Failed记录都没有说明请求根本没到达 Claude 服务器问题出在飞书或网络防火墙。4. Claude 端Bearer Token 是否有效在 CLI 中尝试用curl命令不带飞书的签名直接用 Bearer Token 调用fire端点。如果成功说明 Claude 端服务正常如果失败检查 Token 是否过期或被撤销。这一步可以快速隔离问题如果curl成功说明问题一定在飞书的签名或 payload 构造上。一个真实的 payload 构造案例飞书发送的 Webhook 请求体payload必须是一个合法的 JSON 对象。很多飞书开发者会错误地将整个飞书事件对象原封不动地转发给 Claude。这是不对的。Claude 的 Webhook 端点期望的是一个精简的、只包含 Routine 所需字段的 JSON。错误的 payload包含了飞书的所有元数据{ schema: 2.0, header: { ... }, event: { type: message, sender: { ... }, message: { text: /review pr 123 } } }正确的 payload由飞书机器人服务解析后构造{ github_repo: my-org/backend, github_pr_number: 123, feishu_chat_id: oc_abcdef1234567890 }这个转换过程必须由你自己的飞书机器人后端服务来完成。它需要解析飞书的原始事件提取出用户指令中的关键参数然后构造一个符合 Claude API 规范的、轻量级的 JSON。4.3 权限与连接器问题“GitHub commits 以你的账号出现”的深层含义官方文档中有一句非常重要的话“Routine 做出的动作会使用你的账号身份。比如GitHub commits 和 PR 以你的 GitHub 用户出现。” 这句话初看是功能描述细想却是安全警示。它意味着Routine 不是一个匿名的、无主的机器人而是一个完全代表你本人的“数字分身”。你在 GitHub 上拥有的所有权限它都拥有你在 Slack 上能发消息的频道它都能发。这带来了一个关键的排查思路当一个 Routine 的 GitHub 操作失败时首要怀疑的不是 Routine 本身而是你自己的 GitHub 账号权限。检查 GitHub Personal Access Token (PAT)Claude Code 是通过你授权的 GitHub PAT 来访问仓库的。请登录 GitHub进入Settings Developer settings Personal access tokens Tokens (classic)找到你授权给 Claude Code 的那个 Token。检查它的过期时间以及它所拥有的 scopes权限范围。对于 PR 审查至少需要public_repo如果是私有仓库则是repo和workflow如果需要触发 Actions。检查仓库的 Branch Protection Rules即使你的 PAT 权限足够GitHub 的分支保护规则也可能拦截 Routine 的操作。例如如果main分支启用了“Require pull request reviews before merging”那么 Routine 创建的 Draft PR 是可以的但如果你想让它直接git push到main就会被拒绝。你需要在 GitHub 仓库的Settings Branches Branch protection rules中为 Routine 使用的账号即你的账号添加一个Bypass pull request requirements的例外。检查连接器的权限粒度回到 Claude UI 的 Routine 设置在Connectors部分再次确认你为 GitHub Connector 勾选的权限。如果你只勾选了Read Pull Requests那么它就不可能执行Write Pull Request Comments。这个权限列表是实时生效的修改后无需重启下次运行即生效。提示在 Routine 的开发和测试阶段我强烈建议开启Draft PR模式。即在 Prompt 中所有写操作如创建 PR、提交代码都明确指定为draft: true。这样即使 Prompt 出了错它创建的也是一个草稿 PR不会对主分支造成任何影响。等你确认逻辑完全正确后再将draft: false。4.4 运行时问题日志、超时与幂等性设计当 Routine 运行起来后你面对的将是另一类问题它运行了但结果不对它运行了但耗时太久它运行了但重复执行了两次。日志是唯一的真相Claude UI 的Runs页面提供了完整的、按时间戳排序的执行日志。它不仅包含你console.log的输出还包含系统级别的日志如“Starting setup script...”、“Cloning repository my-org/backend...”、“Running pylint on file api/handler.py...”。当结果异常时不要猜测直接滚动日志找到第一个ERROR或WARNING标记那里就是问题的源头。我曾遇到一个 Routine 总是报告“找不到文件”日志显示它克隆仓库后cd进入的目录是my-org-backend而不是预期的backend。原因是 Prompt 里写的git clone命令没有指定--depth 1导致它克隆了整个组织的仓库而backend只是其中一个子目录。修复方法很简单在setup script中添加cd backend。超时是隐形的杀手Routines 默认超时时间为 30 分钟。对于一个需要分析大型单体应用的 Routine 来说这可能不够。你可以在创建 Routine 时在Environment配置中找到Timeout (seconds)字段将其修改为36001 小时。但更优雅的方案是在 Prompt 中加入超时控制逻辑。例如使用timeout命令来包装一个可能很慢的命令# Step 3: Run the heavy linting job. If it takes more than 5 minutes, abort and report. timeout 300 pylint --output-formatjson api/ || echo Pylint timed out after 5 minutes.幂等性是可靠性的基石Webhook 机制本身是“尽力而为”的网络抖动可能导致同一个事件被飞书重复发送多次。如果你的 Routine 没有幂等性设计就可能出现“同一份 PR 被审查了三次发了三条重复的飞书消息”。实现幂等性的最简单方法是在 Prompt 的开头加入一个“防重”检查# Step 0: Check for idempotency. Look for a comment from this routine on the PR. # If found, exit immediately with success. GITHUB_COMMENT_ID$(