MoreRSS

site iconDevTang | 唐巧修改

iOS开发,孵化了 小猿搜题 和 小猿口算。斑马智能硬件业务负责人,带领团队研发的产品累计出货量超过 400 万台。著有《iOS 开发进阶》。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

DevTang | 唐巧的 RSS 预览

HyperFrames 实战:用 HTML 写一支 41 秒的产品介绍视频

2026-05-06 23:03:37

介绍

HyperFrames 把视频当成 HTML 来写。 一个 index.html 就是一支视频:

  • data-* 属性控制时间
  • GSAP(一个老牌的 JavaScript 动画库)控制动画
  • CSS 控制外观
  • 借助 FFmpeg 生成 MP4

它由 HeyGen 开源,配套 CLI、Skills、Studio 预览器和 13 个相关 skill 包,安装命令:

1
npx skills add heygen-com/hyperframes

为什么值得试

做产品介绍视频,常见的三类工具各有痛点:

路径 优势 痛点
Premiere / After Effects 视觉上限高 工程文件不可版本控制、模板化扩展难
Remotion 程序化 + React 需要搭工程、依赖链长
文生视频模型 上手快 数据准确性不保证、定制化弱

HyperFrames 的吸引点是:保留”代码即源”的可维护性,但把心智模型压缩到只有 HTML / CSS / GSAP 三件事 —— 适合不需要太复杂动效,偏内容呈现类的视频生成。

实战尝试

我用它做了一支介绍斑马思维机发展历程的视频。

claude code 的提示词如下:

帮我使用 npx skills add heygen-com/hyperframes 来安装 hyperframes 这个 skill,然后读取网上关于的斑马思维机的介绍,帮我做一个 30s-45s 的介绍斑马思维机发展历程的视频,里面要涵盖机器和题卡上升的时间线。

视频要有配音,可以找一些开放版权的背景音乐。

它做出来是横版的,我又让它生成了一个竖版的,提示词如下:

帮我另外再生成一个适合在手机上呈现的竖版的版本

效果视频

这是横版生成的效果:

参考链接

安庆之旅

2026-05-05 09:37:30

这个五一节和家人去安徽旅游了一趟,30 号出发,先在合肥玩了一天,然后在安庆玩了 4 天。

安庆给我的第一印象是一个类似绵阳的非省会城市。小巧精致,环境干净。不管是打车,还是亚朵酒店,还是吃饭,还是去旅游景点,都很方便有序。

安庆好吃的很多,比较有特色的是一种用红薯粉做的丸子,放到鸡汤或者鱼汤中,把汤汁的鲜味都吸进去了,很美味。另外,每家店都有牛肉锅贴或者牛肉煎包,这也是当地人很喜欢的小吃。小吃街(当地人叫七街)上的美食主要集中在炒饭,炸串(当地人叫油炸),烧烤。物价不贵,点餐一顿饭人均不超过 70。

安庆紧临长江,很多历史名人出自安庆,最有名的可能就是中国共产党早期的核心领导人陈独秀了。陈独秀的两个孩子陈延年,陈乔年都为革命牺牲了,在安庆,我们参观了他们的纪念馆。这次参观,我又有新的思考,我在想:陈独秀虽然留过学,但是他也没有显赫的家世背景,他是如何聚集起大家,形成一个巨大的有凝聚力的政党的呢?最终我发现了一个一直被我忽视的事情:他创办了《新青年》。《新青年》作为一个媒体渠道,在那个年代可以极大化个体的声音,不但可以激发大家反抗,也使得志趣相投的人士被召唤起来。所以,陈独秀在那个时代,选择了一个极其有效的启动模式,让共产党能够逐步发展壮大。

安庆是黄梅戏的发源地。我们全家去听了一场黄梅戏。我对这种艺术表演形式一直不太感冒,但是这次提前做了一些功课,倒也理解了黄梅戏。黄梅戏的成功还是因为它获得了当时劳动人民的喜爱,因为它的内容讲的都是劳动人民的生活,唱腔又容易理解,形式又不复杂,这些都利于劳动人民在劳作之余作为娱乐消遣的形式。

在安庆旅游期间,正值斯诺克世锦赛期间,吴宜泽最终击败了墨菲,拿到了世锦赛冠军。吴宜泽的比赛跌宕起伏,多次陷入失败的边缘,又多次神奇地反转。特别是半决赛中,他的对手在赛点打丢了本可致胜的黑球,而那一球的难度并不大,让人唏嘘。吴宜泽在和墨菲的最后一场中,从容冷静,最后依赖一个后斯诺让墨菲给自己留了一个机会球,最终他利用这个机会上手,完全超分和最后的胜利。

在观看这场神奇的比赛时,我也在感叹命运,在一个变化的时代,拥有好心态,努力做好当下,其实就拥有了无限的可能。

Agent Loop 简介

2026-05-02 08:10:00

一、一个反直觉的事实

先说一个看起来有点反常识的事:LLM 本身是无状态的

每次调用模型,本质上就是一次”文本补全”——你扔一段 prompt 进去,它根据这段 prompt 续写一段输出,然后整个过程结束。下一次再调用,模型对上一次的事一无所知。从机制上讲,它和 2020 年的 GPT-3 没有本质区别,都是一次性的补全器。

但 2024 年之后,我们看到的 Claude Code、Cursor Agent、各种 deep research 工具,明明可以连续工作几十分钟、调用几十个工具、修改几百个文件,看起来”自主”得不得了。

这两件事怎么对得上?

答案藏在外面那个 while 循环里。

Agent ≠ 模型
Agent = 模型 + Loop + Tools + Context 管理

模型本身没有变,变的是包在它外面的那层东西。这层东西现在常被称作 harness(脚手架),而 harness 里最核心的部件,就是 Agent Loop

这篇文章想回答三个问题:

  1. 这个 loop 长什么样?
  2. 它为什么这样设计?
  3. 它什么时候会失效?

二、最小可运行的 Agent Loop

把所有花哨的东西都剥掉,一个 Agent Loop 的本质大概是这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
messages = [{"role": "user", "content": user_input}]

while True:
response = llm(messages, tools=available_tools)
messages.append(response)

if response.stop_reason != "tool_use":
# 模型没要求调用工具,说明它认为任务结束了
return response.text

# 模型要求调用一个或多个工具
for tool_call in response.tool_calls:
result = execute(tool_call)
messages.append({
"role": "tool",
"content": result
})
# 进入下一轮,让模型看到工具结果,决定下一步

就这么二十行。这就是 Claude Code、Cursor、几乎所有 coding agent 的核心。

拆解一下,里面只有四个动作:

  1. 模型推理:把当前 messages 丢给 LLM,让它产出下一步的 response
  2. 工具调用判断:如果 response 里有 tool_use,就执行;如果没有,循环结束
  3. 工具执行:在沙箱/真实环境里跑这个工具,拿到结果
  4. 结果回灌 context:把工具结果塞回 messages,进入下一轮

到这里,请允许我强调一个关键认知:

所谓”Agent 的自主性”,本质就是模型在每一轮看到更新后的 context,自己决定下一步。没有任何魔法。

不是模型变得”会规划”了,是循环让它有机会根据上一步的结果,再做一次补全。它的”思考”只发生在每一次模型调用的那一瞬间,loop 只是一遍遍把它叫醒,告诉它”环境又变了,你再看看”。

理解了这一点,后面所有的工程设计,都只是这个最小循环的变体。


三、Loop 的关键设计决策

最小循环能跑,但不够用。一旦把它放到真实场景里,会立刻撞到一堆问题:循环什么时候停?context 越涨越长怎么办?工具调用错了怎么办?要不要并行?

围绕这些问题做的工程取舍,决定了一个 Agent 框架的性格。下面是五个最关键的决策维度。

1. 终止条件:什么时候跳出 loop

最朴素的写法是”模型不再要求调用工具就停”,但这在生产里远远不够。常见的多重终止条件:

  • 模型主动 stop:response 里没有 tool_use,正常出口
  • 达到 max_iterations:硬性步数上限(比如 50 步),防止失控
  • 检测到循环:连续几次调用相同工具+相同参数,强制中断
  • 用户中断:Ctrl+C、关闭对话窗口
  • 预算耗尽:token 数或时间超限

每个出口背后都是一次工程权衡:上限太小,复杂任务做不完;上限太大,一旦模型卡住就烧钱。

2. Context 增长策略:长任务下怎么办

工具结果一律塞回 context,会带来一个朴素但致命的问题——context 是线性增长的

一个改 50 个文件的任务,可能要读 100 次文件,每次读取的内容都进 context。跑到一半,context 已经塞了几十万 token,模型注意力开始稀释,关键信息被淹没。

工程上有几种常见思路:

  • 全量回灌:最简单,短任务够用,长任务必崩
  • 滑动窗口:只保留最近 N 轮,老的丢掉,但可能丢关键信息
  • 摘要压缩:触发阈值后,让模型自己总结前面的内容,用摘要替换原文
  • 分层压缩:Claude Code 的 /compact 机制就属于这一类——保留最近上下文 + 历史摘要 + 关键信息(如已修改的文件列表)

这一项是目前差异最大的设计点。后面会看到 learn-claude-code 项目专门有一节叫 s06_context_compact,就是为了解决这件事。

3. 工具选择机制:模型怎么”选工具”

两种主流做法:

  • 原生 function calling:通过 API 把工具 schema 一并传给模型,模型在 response 里直接产出结构化的 tool_use 块。Claude、GPT、Gemini 都支持。优点是稳定,几乎不会出格式错误。
  • 提示词约定格式:在 system prompt 里告诉模型”想调用工具就输出 <tool>...</tool> 这样的 XML”,外层用正则解析。早期 ReAct 论文就是这么做的,胜在通用,任何模型都能用。

现在新项目基本都默认用 function calling,但提示词约定法在一些场景仍有价值——比如要让一个本地小模型当 agent,或者要做更细粒度的格式控制。

4. 错误处理:工具调用失败怎么办

工具会出错。文件不存在、API 超时、参数类型不对、权限不足……

两种处理思路,本质是信任谁

  • 塞回 context 让模型自我纠正:把 error message 当作普通的 tool_result 回灌,相信模型能看懂错误并调整。优点是灵活,模型常常能从”file not found”反推出”我应该先 ls 一下”。
  • 外层拦截:harness 直接处理特定错误类型,比如重试、降级、报警。优点是可预测。

实践里通常是混合策略:致命错误外层拦截,业务错误丢给模型。这件事的判断需要工程经验。

5. 并行 vs. 串行:单 Agent 还是多 Agent

单 Agent 的极致是一轮内并行调用多个工具。Claude 现在原生支持一次返回多个 tool_use 块,harness 并行执行后一次性把所有结果回灌。这能显著降低延迟。

更复杂的是多 Agent 协作:主 agent 派发子任务给子 agent,子 agent 独立 loop,结束后回报。这里立刻冒出一个新问题——路由:主 agent 怎么知道哪个子 agent 适合这个任务?是基于 metadata 标签匹配,还是让主 agent 读子 agent 的描述自己判断?这两种思路的优劣,是另一篇文章的话题了。


四、从 50 行到 1000 行:一个 Agent 是怎么长出来的

讲完抽象的设计维度,看一个具体的项目——开源项目 learn-claude-code

这个项目的好处是:它把一个 nano 版 Claude Code 的演化拆成了 12 个递进的 Python 脚本,每一步只引入一个新机制。从 s01 到 s12,代码从大约 50 行长到 1000+ 行。

读它,相当于把上一节的设计决策亲眼看一遍怎么落到代码里。

下面挑几个最关键的节点:

s01 Agent Loop:朴素的 while

1
2
3
4
5
6
while True:
response = model(messages, tools)
if response.stop_reason != "tool_use":
return response.text
results = execute(response.tool_calls)
messages.append(results)

这就是上一章伪代码的真实版本。50 行,能跑,能调用 bash 完成简单任务。这是一切的起点

s02 Tool Use:从一个工具到多个工具

引入 read_filewrite_filebashgrep 等多个工具。重点不在工具本身,而在 wire——怎么把工具 schema 注册给模型,怎么 dispatch 到真实函数。

到这里,agent 已经能完成”读文件、改文件、跑测试”这种基础编程任务了。

s03 TodoWrite:对抗”目标漂移”的第一道防线

一个有意思的设计:让 agent 自己维护一个 todo list。

为什么?因为长任务里,模型很容易跑偏。任务一大,model 在第 30 轮已经忘了第 1 轮的目标是什么。TodoWrite 工具强制 agent 在开工前把任务拆成清单,每完成一项划掉一项。

这本质上是用工具调用替代记忆——不指望模型记住,而是把目标固化成 context 里随时可见的状态。Claude Code 现在就是这么做的,效果非常显著。

s04 Subagent:什么时候该拆出去

主 agent 不是万能的。当一个子任务的 context 会污染主 agent 的判断(比如要读一大堆代码才能定位 bug),就该把它丢给子 agent。

子 agent 有自己独立的 loop、独立的 context,跑完只把结论返回给主 agent。这是用 context 隔离换取主 loop 的清晰

s06 Context Compact:长任务的生存策略

直接对应第三章讲的”context 增长策略”。当 messages 长度超过阈值,触发 compact:让模型把前面的对话总结成一段摘要,用摘要替换原始消息,保留最近几轮原文。

这是目前所有长任务 agent 的共同方案。没有 compact,agent 就走不远

s07–s12:再往后

任务系统、后台任务、多 agent 团队、worktree 隔离……每一层都是在同一个 loop 上叠加工程能力。但本质都没变:还是那个 while 循环


读完这个项目,最值得记住的是它的核心宣言:

The model is the agent. The code is the harness.
模型才是 Agent,代码只是脚手架。

这句话听起来像废话,其实暗藏一个反直觉的判断——你写的那一千行 harness 代码,不是在让 Agent “更聪明”,只是在帮模型别搞砸。模型本身已经具备 Agent 能力,harness 的工作是给它工具、管好上下文、防止失控。

Harness 越薄,说明模型越强。


五、Loop 的边界与失效模式

Agent Loop 不是银弹。在生产里,它会以几种典型方式翻车:

1. 上下文窗口爆炸

最常见。长任务跑到一半,context 涨到几十万 token,模型注意力被稀释,开始重复读同一个文件、忽略关键约束。Compact 是缓解,但不是根治——压缩本身也会丢信息。

2. 工具调用幻觉

模型有时会编造不存在的工具,或者给真实工具传错误参数(比如发明了一个本不存在的 flag)。这件事在小模型上尤其严重。缓解办法是收紧 tool schema 的描述、用 function calling 而不是提示词约定,以及在 harness 里做参数校验。

3. 死循环

模型反复调用同一个工具拿同样的结果,不收敛。常见于”修一个 bug 但根本没想清楚”的场景:跑测试 → 失败 → 改一行 → 跑测试 → 失败 → 改回来。需要在 harness 里检测这种模式并强制中断。

4. 目标漂移

多轮之后忘了原始任务。前面提到的 TodoWrite 是一种缓解,更激进的做法是定期”自检”:让 agent 每隔 N 轮 reflect 一次,对照原始目标审视当前进展。

工程上常见的缓解组合是:context 压缩 + 工具白名单 + step budget + 显式 reflection 节点。每一项都不彻底,但叠在一起能撑很久。


六、Agent Loop 是临时方案,还是终极形态

最后留一个开放问题。

回看现在所有的 Agent 框架——Claude Code、Cursor、LangGraph、OpenClaw、learn-claude-code——本质都在围绕同一个 while 循环做工程优化。终止条件、context 压缩、子 agent、todo 管理……每一项都是因为模型本身做不到,所以 harness 替它做

但模型还在变强。

Claude 已经支持 extended thinking——模型在一次调用里能做更长的内部推理。原生的 tool use 在每一代都更稳。multi-step 的 planning 能力肉眼可见地在涨。

那么一个不那么好回答的问题是:

当模型本身具备足够长的推理链和原生工具使用能力时,外部那个 while 循环还需要存在吗?

也许某一天,你只需要一次 API 调用,模型在内部就完成了全部规划、工具调用、上下文管理。harness 被吸收进了模型本身。我们今天精心设计的这些 loop 控制机制,会变成一段历史。

也可能不会。也许 harness 永远存在——因为外部环境永远是 harness 的边界,模型再强,也需要一个东西替它和真实世界对接。

不知道。但这就是现在做 Agent 最有意思的地方:你不知道自己写的这一千行 harness 代码,到底是产品的核心资产,还是即将过时的过渡方案

唯一确定的是,所有故事的开头,都还是那个最朴素的 while 循环。


参考项目:shareAI-lab/learn-claude-code,一个把 Claude Code 拆成 12 个递进版本的开源教学项目。建议从 s01_agent_loop.py 开始读。

在 Github 中通过创建 issue 来唤醒 claude 工作

2026-04-26 19:55:42

前置条件

  • 你是目标 repo 的 admin
  • 已有 Anthropic API Key(或 AWS Bedrock 凭证)
    • 申请 Anthropic API Key 可以使用 claude setup-token 命令,得到一个 sk 开头的 key

方式一:安装官方 Claude App(最快)

  1. 打开 https://github.com/apps/claude,点击 Install
  2. 选择你要授权的 repo(建议只勾选需要的 repo,不要 All repositories)
  3. 确认安装

安装完成后跳到下面的「配置 Secrets 和 Workflow」章节。


方式二:创建自定义 GitHub App(完全掌控权限)

适用场景:组织策略不允许装第三方 App、需要更严格的权限控制、使用 AWS Bedrock / Vertex AI。

A)快速创建(推荐)

  1. https://github.com/anthropics/claude-code-action/blob/main/docs/create-app.html 右键「另存为」下载 create-app.html
  2. 用浏览器打开这个文件
    • 个人账号:点击「Create App for Personal Account」
    • 组织账号:输入组织名称,点击「Create App for Organization」
  3. GitHub 会展示 App 配置预览 → 确认名称 → 点击 Create GitHub App
  4. 创建后自动跳转到 App 设置页,往下滚到 Private keys → 点 Generate a private key → 下载 .pem 文件(妥善保管)
  5. 跳到下面的「安装 App 到 Repo」步骤

B)手动创建

  1. 打开 https://github.com/settings/apps(个人)或组织的 Settings → Developer settings → GitHub Apps
  2. New GitHub App,配置以下权限:
权限类别 权限项 级别
Repository permissions Contents Read & Write
Repository permissions Issues Read & Write
Repository permissions Pull requests Read & Write
Account permissions
  1. 「Where can this GitHub App be installed?」选 Only on this account
  2. Create GitHub App
  3. 创建完成后,滚到 Private keysGenerate a private key → 下载 .pem 文件

安装 App 到 Repo

  1. 进入你刚创建的 App 设置页
  2. 左侧菜单点 Install App
  3. 选择要安装的 repo,确认

配置 Secrets 和 Workflow

第一步:添加 Repository Secrets

进入 repo → SettingsSecrets and variablesActionsNew repository secret

Secret 名称
ANTHROPIC_API_KEY 你的 Anthropic API Key(sk-ant- 开头)
CLAUDE_CODE_OAUTH_TOKEN(可选,替代上一条) claude setup-token 生成的 OAuth Token
APP_ID(自定义 App 才需要) App 设置页里的 App ID
APP_PRIVATE_KEY(自定义 App 才需要) .pem 文件的完整内容

⚠️ 绝对不要把 API Key 写在代码里,只通过 Secrets 引用。
ANTHROPIC_API_KEYCLAUDE_CODE_OAUTH_TOKEN 二选一即可,下面示例以 API Key 为主,OAuth 用法是把 anthropic_api_key: 换成 claude_code_oauth_token:

第二步:创建 Workflow 文件

在 repo 中创建 .github/workflows/claude.yml

如果用官方 Claude App:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
name: Claude Assistant
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
issues:
types: [opened, assigned]

# 仓库级权限:按需最小化——只读场景可把三个 write 都改成 read
permissions:
contents: write
pull-requests: write
issues: write
# 用 CLAUDE_CODE_OAUTH_TOKEN 时必加,OAuth 流程要用 OIDC token 去换;
# 用 ANTHROPIC_API_KEY 时可省。
id-token: write
# 让 Claude 能读 CI run 日志("我 PR 的 CI 挂了帮我看看")
actions: read

jobs:
claude-response:
# 双重门槛:
# 1. actor 必须是仓库主人本人——防外部用户触发
# 2. 触发载体里必须出现 @claude——没有则直接 skip,连 runner 都不起,省 Action 额度
# 注意:include_comments_by_actor 只过滤"评论",不一定覆盖 issue body /
# PR description / review body,所以第 1 条的 actor 校验是必须的纵深防御。
if: |
github.actor == '你的用户名' && (
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude')
|| contains(github.event.issue.title, '@claude')))
)
runs-on: ubuntu-latest
steps:
# claude-code-action 需要 .git 目录才能创建分支去提 PR
- uses: actions/checkout@v4
with:
fetch-depth: 1

- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
# 第三道门:评论场景也只接受白名单
include_comments_by_actor: "你的用户名"
# 工具权限:纵深防御——Bash 不再裸开,按命令前缀逐条白名单。
# 只读场景可把所有 Bash(...) 和 Edit/Write 删掉。
claude_args: |
--max-turns 30
--allowedTools "WebFetch,WebSearch,Edit,Write,Read,Glob,Grep,TodoWrite,Bash(git:*),Bash(gh:*),Bash(npm:*),Bash(pnpm:*),Bash(yarn:*),Bash(npx:*),Bash(node:*),Bash(curl:*),Bash(jq:*),Bash(rg:*),Bash(fd:*)"

如果用自定义 GitHub App:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
name: Claude with Custom App
on:
issue_comment:
types: [created]
pull_request_review_comment:
types: [created]
pull_request_review:
types: [submitted]
issues:
types: [opened, assigned]

permissions:
contents: write
pull-requests: write
issues: write
id-token: write # 用 OAuth Token 时必加
actions: read # 让 Claude 能看 CI run 日志

jobs:
claude-response:
if: |
github.actor == '你的用户名' && (
(github.event_name == 'issue_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review_comment' && contains(github.event.comment.body, '@claude')) ||
(github.event_name == 'pull_request_review' && contains(github.event.review.body, '@claude')) ||
(github.event_name == 'issues' && (contains(github.event.issue.body, '@claude')
|| contains(github.event.issue.title, '@claude')))
)
runs-on: ubuntu-latest
steps:
- name: Generate GitHub App token
id: app-token
uses: actions/create-github-app-token@v1
with:
app-id: ${{ secrets.APP_ID }}
private-key: ${{ secrets.APP_PRIVATE_KEY }}

- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
github_token: ${{ steps.app-token.outputs.token }}
include_comments_by_actor: "你的用户名"
claude_args: |
--max-turns 30
--allowedTools "WebFetch,WebSearch,Edit,Write,Read,Glob,Grep,TodoWrite,Bash(git:*),Bash(gh:*),Bash(npm:*),Bash(pnpm:*),Bash(yarn:*),Bash(npx:*),Bash(node:*),Bash(curl:*),Bash(jq:*),Bash(rg:*),Bash(fd:*)"

Public Repo 安全清单

  • ifactor 白名单github.actor == '你的用户名'),不要只用”排除 bot”的黑名单
  • if 再叠一层 contains(<事件正文>, '@claude') 判断——没有触发词直接 skip,省 Action 额度也避免被误触
  • include_comments_by_actor 同步设置用户白名单(注意:它只过滤评论,不一定覆盖 issue body / PR description,所以上面两条 if 校验是必须的纵深防御)
  • 顶层 permissions: 块按需最小化授权——只读场景 contents/pull-requests/issues 都给 read 即可;要提 PR 才给 write
  • claude_argsBash 不要裸开——用 Bash(git:*),Bash(gh:*),... 这种命令前缀白名单收紧
  • allowed_bots 保持默认空值(不要设 *
  • show_full_output 保持默认 false
  • API Key / OAuth Token 只通过 ${{ secrets.XXX }} 引用,不硬编码
  • 定期轮换 API Key
  • 意识到一旦 actor 校验被绕过,攻击者拿到的就是 workflow permissions 里授予的全部能力——所以前两条最关键

验证

配置完成后,在 issue 里评论 @claude 你好,如果一切正常,Claude 会在几秒内回复。

参考文档:https://github.com/anthropics/claude-code-action

让 Claude Code 在你睡觉时持续运行:完整实战指南

2026-04-15 13:44:00

Claude Code 可以通过 -p 标志、权限绕过、循环模式和终端持久化的组合,实现数小时甚至整夜的无人值守运行。 开发者社区已经形成了一套可靠的操作手册:容器化运行环境、使用 “Ralph Wiggum” 循环模式、安装四个关键 Hook 防止卡死、保持 CLAUDE.md 精简。有开发者记录了 27 小时连续自主会话完成 84 个任务;另一位在睡觉时让 Claude 构建了一个 15,000 行的游戏。但社区也反馈,大约 25% 的过夜产出会被丢弃,而且如果没有适当的防护措施,Claude 曾在至少一位开发者的机器上执行过 rm -rf /。以下是你今晚就能用上的完整设置方案。


一、消除人工干预的三种模式

Claude Code 提供三个级别的自主运行模式,每个级别都在安全性和速度之间做取舍。理解它们是所有过夜方案的基础。

模式 1:-p(print/pipe)标志 —— 所有自动化的核心。 这是非交互式运行模式。接收 prompt,执行到完成,输出到 stdout,然后退出。无需 TTY,512MB 内存的服务器也能跑。

1
claude -p "查找并修复 auth.py 中的 bug" --allowedTools "Read,Edit,Bash"

模式 2:--permission-mode auto —— 更安全的折中方案。 2026 年初推出,使用 Sonnet 4.6 分类器自动批准安全操作,同时阻止高风险操作。分类器分两阶段运作:快速判定(8.5% 误报率),对标记项目进行思维链推理(0.4% 误报率)。如果连续 3 次操作被拒绝或单次会话累计 20 次被拒,系统会升级到人工介入——或者在 headless 模式下直接终止。

1
claude --permission-mode auto -p "重构认证模块"

模式 3:--dangerously-skip-permissions —— 完全绕过权限。 所有操作无需确认直接执行。Anthropic 自己的安全研究员 Nicholas Carlini 也使用这个模式,但有一个关键前提:“在容器里跑,不要在你的真实机器上。” 一项调查发现 32% 的开发者使用这个标志时遭遇了意外的文件修改,9% 报告了数据丢失

1
2
# 仅限 Docker/VM —— 绝对不要在宿主机上运行
claude --dangerously-skip-permissions -p "构建这个功能"

推荐的过夜运行方式是将 -p 与细粒度工具白名单 --allowedTools 结合使用,允许特定命令而非授予全面访问权限:

1
2
3
4
claude -p "修复所有 lint 错误并运行测试" \
--allowedTools "Read" "Edit" "Bash(npm run lint:*)" "Bash(npm test)" "Bash(git *)" \
--max-turns 50 \
--max-budget-usd 10.00

--max-turns--max-budget-usd 是无人值守会话的必备成本控制手段。没有它们,一个失控的循环可以在几分钟内烧光你的 API 预算。


二、Ralph Wiggum 循环:开发者的实际过夜方案

最经过实战验证的长时间自主工作模式是 Ralph Wiggum 循环——以《辛普森一家》中的角色命名,现已成为 Anthropic 官方插件。概念非常简单:一个 bash while 循环持续向 Claude 喂相同的 prompt。每次迭代中,Claude 查看当前文件状态和 git 历史,选择下一个未完成的任务,实现它,然后提交。

1
2
3
4
5
while true; do
claude --dangerously-skip-permissions \
-p "$(cat PROMPT.md)"
sleep 1
done

那位记录了 27 小时会话 的开发者使用了这个模式,配合一个详细的 prompt 文件,包含架构说明、目标、约束条件和明确的”完成”标准。他的核心发现:“一句话 prompt 在一两个小时后就没劲了。27 小时的会话能持续下去,是因为 prompt 文件有足够多的上下文。”

Prompt 文件比循环本身更重要。 一个有效的过夜 PROMPT.md 示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 任务:测试并加固认证系统

## 上下文
- 后端:Express + TypeScript,位于 src/api/
- 数据库:PostgreSQL,schema 在 prisma/schema.prisma
- 认证流程:JWT 中间件在 src/middleware/auth.ts

## 目标
- 查看 docs/plan.md,选择下一个未完成的任务
- 实现它,包含完善的错误处理
- 运行测试,修复失败,确认没有回归
- 做通用修复,不要打临时补丁
- 每完成一个任务后用描述性消息提交

## 成功标准
- 每次修改后所有测试通过
- 不会引入之前修复的回归
- 当 plan.md 中所有任务完成后输出 DONE

社区有几个工具扩展了这个基础循环。Ralph CLI 增加了速率限制(100次调用/小时)、熔断器、会话过期(默认24小时)和实时监控仪表板。Nonstop 增加了飞行前风险评估和阻塞决策框架——走之前输入 /nonstop 即可。Continuous-claude 自动化完整 PR 生命周期:创建分支、推送、创建 PR、等待 CI、合并。


三、防止过夜灾难的四个 Hook

开发者 yurukusa 记录了 108 小时无人值守运行,识别出七类过夜事故——包括 Claude 执行 rm -rf ./src/、进入无限错误循环、直接推送到 main 分支,以及产生每小时 8 美元的 API 费用。解决方案:四个关键 Hook,共同预防最常见的故障模式。

10 秒快速安装:

1
npx cc-safe-setup

Hook 1:No-Ask-Human 阻止 AskUserQuestion 工具调用,强制 Claude 自主做出决定,而不是坐在那里等几小时等人回复。这个 Hook 决定了 Claude 是整夜工作还是在晚上 11:15 卡住。在你坐在电脑前时,用 CC_ALLOW_QUESTIONS=1 覆盖。

Hook 2:Context Monitor 将工具调用次数作为上下文使用量的代理指标,在四个阈值(剩余 40%、25%、20%、15%)发出分级警告。在临界水平时,配套的空闲推送脚本会自动向终端注入 /compact 命令——两个进程,共 472 行代码,零人工干预

Hook 3:Syntax Check 在任何文件编辑后立即运行 python -m py_compilenode --checkbash -n,在错误级联成 50 次调试之前就捕获它们。

Hook 4:Decision Warn 在执行前标记破坏性命令(rm -rfgit reset --hardDROP TABLEgit push --force)。通过 CC_PROTECT_BRANCHES="main:master:production" 配置受保护分支。

.claude/settings.json 中配置:

1
2
3
4
5
6
{
"permissions": {
"allow": ["Bash(npm run lint:*)", "WebSearch", "Read"],
"deny": ["Read(.env)", "Bash(rm -rf *)", "Bash(git push * main)"]
}
}

四、tmux 设置与保持机器不休眠

Claude Code 的交互模式需要 TTY —— 不能用 nohup 或将其作为 systemd 服务运行(大约 15-20 秒后会因 stdin 错误崩溃)。tmux 是会话持久化的必备工具

1
2
3
4
5
6
7
8
9
10
11
12
13
# 启动命名会话
tmux new -s claude-work

# 在其中启动 Claude
claude --permission-mode auto

# 分离(Claude 继续运行):Ctrl+B,然后按 D

# 从任何地方重新连接(SSH、手机 Termius 等)
tmux attach -t claude-work

# 不连接就查看进度
tmux capture-pane -t claude-work -p -S -50

对于真正的 7×24 运行,社区推荐 VPS + Tailscale + tmux 方案:便宜的 VPS(Hetzner、Vultr、DigitalOcean)提供永不关机的算力,Tailscale 提供私有网络,mosh 在不稳定网络上保持连接持久性。给 Claude 一个任务,分离,合上笔记本,明天再回来。

macOS 防止休眠:

1
2
3
4
5
# 绑定到 Claude 进程
caffeinate -i -w $(pgrep -f claude) &

# 或者在接通电源时全局禁用休眠
sudo pmset -c sleep 0

管理多个并行会话方面,Amux 是一个约 12,000 行的 Python 文件,提供 Web 仪表板、手机 PWA 监控、自愈看门狗(自动重启崩溃会话)、按会话 token 追踪和 git 冲突检测。Codeman 提供类似的 Web UI,带 xterm.js 终端,支持最多 20 个并行会话。

一个强大的过夜 agent tmux 配置:

1
2
3
4
5
6
7
8
9
#!/bin/bash
tmux new-session -d -s claude-dev
tmux rename-window -t claude-dev:0 'Claude'
tmux new-window -t claude-dev:1 -n 'Tests'
tmux new-window -t claude-dev:2 -n 'Logs'
tmux send-keys -t claude-dev:0 'claude --permission-mode auto' Enter
tmux send-keys -t claude-dev:1 'npm run test:watch' Enter
tmux send-keys -t claude-dev:2 'tail -f logs/app.log' Enter
tmux attach-session -t claude-dev

五、CLAUDE.md 与长时间运行的上下文管理

过夜失败的最大原因是上下文窗口耗尽。Claude Code 的上下文窗口大约 200K token,使用率超过 70% 时性能开始下降。自动压缩在接近阈值时触发,但会丢失信息——仅保留 20-30% 的细节。有开发者报告 Claude 压缩后遗忘了所有内容,重新开始同一个任务,浪费了三个小时。

解决方案是检查点/交接模式,能够在上下文重置后存活:

1
2
3
4
5
6
# 在 CLAUDE.md 中
当上下文变大时,将当前状态写入 tasks/mission.md。
包括:已完成的、下一步的、被阻塞的、未解决的问题。
错误处理:最多重试 3 次。如果没有进展,记录到
pending_for_human.md 然后转到下一个任务。
压缩前,务必保存完整的已修改文件列表。

将 CLAUDE.md 控制在 200 行以内——每个词在每个会话中都消耗 token。从 800 行切换到 100 行的开发者达成社区共识:更短的配置实际上表现更好,因为 Claude 不会忽略被噪音淹没的指令。使用”仅在不可逆时才提问”规则,将提问频率降低约 80%:

1
2
3
4
5
6
# 自主运行的决策规则
- 技术方案不确定 → 选择传统方案
- 两种可行实现 → 选择更简单的那个
- 尝试 3 次后仍有错误 → 记录到 blocked.md,切换任务
- 需求模糊 → 应用最合理的理解,记录假设
- 永远不要提问。做出最佳判断然后继续。

CLAUDE.md 文件是分层的:~/.claude/CLAUDE.md(全局)、./CLAUDE.md(项目级,git 追踪)、.claude/CLAUDE.local.md(个人覆盖,gitignore)。自主运行时,全局文件保持最小,把运行特定指令放在项目文件中。

关键 token 节省技巧:在里程碑后主动使用 /compact,而非等待自动压缩;对独立任务使用子 agent(每个有自己的上下文窗口);不相关的工作启动新会话;积极使用 .claudeignore 排除无关文件。


六、过夜运行的速率限制处理

速率限制作为三个独立的、重叠的约束运作:每分钟请求数、每分钟输入 token 数、每分钟输出 token 数。一个可见的命令在内部可能产生 8-12 个 API 调用(lint、修复、测试、修复循环)。15 次迭代后,单个请求可能发送 20 万+ 输入 token

过夜运行速率限制生存策略:

在非高峰时段运行。 Anthropic 确认工作日太平洋时间早 5 点到 11 点限制更严格。过夜运行和周末会话完全避开高峰期限流——恰好就是你在睡觉的时候。

利用 Ralph 循环的内置重试。 运行 while 循环时,速率限制错误只会导致当前迭代失败,但循环不在乎——它在速率限制窗口重置后的下一次迭代中重试。有开发者警告:“不要在 API/按用量计费模式下运行——重试会烧光你的预算。”

运行中切换模型。 Sonnet 能处理 60-70% 的常规任务,每 token 成本比 Opus 低约 1.7 倍。过夜工作设置 --model sonnet,将 Opus 留给复杂推理。也可以设置 --fallback-model sonnet,让 Claude 在主模型过载时自动降级。

Token 消耗的真实数据:20 条消息会话消耗约 105,000 token;30 条消息会话跳到 232,000 token。大约 98.5% 的 token 花在重新读取对话历史——只有 1.5% 用于实际输出。这就是为什么全新会话和积极压缩如此重要。

成本估算:持续运行 Sonnet 大约 $10.42/小时。基于 cron 每 15 分钟运行一次的 agent,预计约 $48/天。使用 --max-budget-usd 作为硬上限。


七、CI/CD 流水线与 Cron 任务集成

对于计划性的自动化工作,Claude Code 可直接与 CI/CD 系统集成。官方 GitHub Action 是 anthropics/claude-code-action@v1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
name: Claude Code Review
on:
pull_request:
types: [opened, synchronize]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
prompt: "审查这个 PR 的安全和代码质量问题。"
claude_args: "--max-turns 5 --model claude-sonnet-4-6"

对于基于 cron 的自主 agent,Boucle 模式通过 state.md 文件在运行之间维持状态:

1
2
3
4
5
6
7
8
9
10
11
12
#!/bin/bash
# run-agent.sh —— 由 cron 调用
STATE="$HOME/agent/state.md"
LOG="$HOME/agent/logs/$(date +%Y-%m-%d_%H-%M-%S).log"

claude -p "你是一个自主 agent。读取你的状态,决定做什么,
然后用你学到的内容更新 state.md。
$(cat $STATE)" \
--allowedTools Read,Write,Edit,Bash \
--max-turns 20 \
--max-budget-usd 1.00 \
--bare 2>&1 | tee "$LOG"
1
2
# crontab -e
0 * * * * /path/to/run-agent.sh

200 次迭代后的关键教训:state.md 必须保持在 4KB 以下(它会被注入每个 prompt),使用结构化键值对而非散文,并添加文件锁防止重叠运行。每次迭代后 git commit——git log 就是你最好的调试工具。

CI 环境使用 --bare 模式(跳过 hook、MCP 服务器、OAuth 和 CLAUDE.md 加载,最快最可复现的执行方式)和 --permission-mode dontAsk(拒绝所有未显式允许的操作——自动化环境中最安全的模式)。


八、已知陷阱与可能出错的地方

社区已广泛记录了以下故障模式:

故障模式 后果 预防方法
破坏性命令 Claude 运行 rm -rfgit reset --hard 或覆盖生产数据 PreToolUse hook 阻止危险命令;Docker 配合 --network none
无限错误循环 修复 → 测试 → 同样错误 → 修复 → 重复 20+ 次 CLAUDE.md 规则:”最多重试 3 次,然后记录到 blocked.md 继续下一个”
压缩后上下文丢失 Claude 遗忘一切,重新开始同一任务 压缩前将状态写入 mission.md;使用 Ralph 循环获得全新上下文迭代
权限提示阻塞 会话无限期挂起等待人工输入 No-Ask-Human hook;--dangerously-skip-permissions--permission-mode auto
直接推送到 main 未测试的代码部署到生产环境 分支保护规则;PreToolUse hook 阻止 git push 到受保护分支
API 成本失控 子 agent 进入循环调用外部 API($8/小时) --max-budget-usd;速率限制 hook;熔断器
OAuth token 过期 中途打断自主工作流 所有自动化使用 ANTHROPIC_API_KEY 环境变量而非 OAuth
订阅 ToS 违规 用 Pro/Max 订阅(非 API key)的 headless 模式可能违反消费者条款 自动化/脚本使用务必用 ANTHROPIC_API_KEY

最重要的单一安全措施是容器化。多位经验丰富的开发者独立推荐使用带网络隔离的 Docker:

1
2
3
4
5
docker run -it --rm \
-v $(pwd):/workspace -w /workspace \
--network none \
-e ANTHROPIC_API_KEY="$ANTHROPIC_API_KEY" \
claude-code:latest --dangerously-skip-permissions -p "$(cat PROMPT.md)"

正如一位开发者所说:“用 --dangerously-skip-permissions 运行 Claude Code 就像不做防护措施。所以用个套… 我是说容器。”


九、今晚的快速启动清单

15 分钟设置过夜自主运行:

  1. 创建 git 检查点git add -A && git commit -m "pre-autonomous checkpoint"
  2. 安装四个关键 Hooknpx cc-safe-setup
  3. 编写 PROMPT.md,包含架构上下文、任务列表、成功标准,以及每完成一个任务就提交的指令
  4. 启动 tmux 会话tmux new -s overnight
  5. 防止休眠(macOS):caffeinate -s &
  6. 启动循环
1
2
3
4
5
6
7
8
while true; do
claude -p "$(cat PROMPT.md)" \
--allowedTools "Read" "Edit" "Bash(npm run *)" "Bash(git *)" \
--max-turns 30 \
--max-budget-usd 5.00 \
--permission-mode acceptEdits
sleep 2
done
  1. 分离 tmuxCtrl+B,然后按 D
  2. 去睡觉

早上起来:tmux attach -t overnight,然后查看 git log(git log --oneline)看 Claude 完成了什么。预计保留大约 75% 的产出,丢弃 25%。这很正常——正如一位开发者说的,“不是完美,甚至不是最终版,但是在前进。”

十、总结

先用 plan 模式,把 PRD.mdTODO.md 生成好。

  • 安装 cc-safe-setup
1
npx cc-safe-setup
  • 安装 format-claude-stream
1
npm install -g @khanacademy/format-claude-stream
  • 编写项目的 CLAUDE.md
1
2
3
- 当上下文变大时,将当前状态写入 tasks/mission.md。包括:已完成的、下一步的、被阻塞的、未解决的问题。
- 错误处理:最多重试 3 次。如果没有进展,记录到 pending_for_human.md 然后转到下一个任务。
- 压缩前,务必保存完整的已修改文件列表。
  • 编写 PROMPT.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
## 目标
- 查看 TODO.md,选择一个未完成的任务执行
- 执行的代码必须包含测试用例并测试通过
- 每做完一个任务,及时提交 Git,并在 TODO.md 标记为已完成
- 当所有任务都完成后,在 TODO.md 中顶部注明:“全部任务已完成”

## 要求
- 技术方案不确定 → 选择传统方案
- 两种可行实现 → 选择更简单的那个
- 需求模糊 → 应用最合理的理解,记录假设
- 永远不要提问,做出最佳判断然后继续

## 环境(如有)
# - CLOUDFLARE API 在 key.md 中
  • 编写 key.md
1
2
CLOUDFLARE_API_TOKEN=xxx
CLOUDFLARE_ACCOUNT_ID=xxx
  • 编写 nostop.sh
1
2
3
4
5
6
7
8
9
mkdir -p logs
while true; do
claude -p "$(cat PROMPT.md)" \
--dangerously-skip-permissions --model opus \
--output-format stream-json --verbose \
tee "logs/$(date +%Y%m%d_%H%M%S).jsonl" \
| format-claude-stream
sleep 60
done

Claude Code 从 AWS Bedrock 切换到 Team 订阅指南

2026-04-12 22:44:49

背景

Claude Code 支持多种认证方式,包括 AWS Bedrock、Google Vertex AI、Anthropic API Key 和 Claude 订阅(Pro/Max/Team/Enterprise)。当你从 Bedrock 切换到 Team 订阅时,需要清除 Bedrock 的配置,否则 Claude Code 会一直走 Bedrock 通道。

核心问题

使用 Bedrock 认证时,/login/logout 命令是被禁用的(官方设计如此)。因此你无法在 Bedrock 模式下直接切换登录方式。

Bedrock 配置的来源有两种:

  1. 环境变量 — 通过 export 或写在 ~/.zshrc / ~/.bashrc
  2. settings.json — 写在 ~/.claude/settings.jsonenv 字段中

很多用户(尤其是通过 setup wizard 配置的)的 Bedrock 设置是写在 settings.json 里的,单纯 unset 环境变量并不能解决问题。

切换步骤

第一步:检查 Bedrock 配置来源

1
2
3
4
5
# 检查环境变量
env | grep -i -E "claude_code_use|anthropic|bedrock|aws"

# 检查 settings.json
cat ~/.claude/settings.json

如果在 settings.json 中看到类似以下内容,说明 Bedrock 配置在这里:

1
2
3
4
5
6
7
8
{
"env": {
"CLAUDE_CODE_USE_BEDROCK": "1",
"AWS_REGION": "us-west-2",
"ANTHROPIC_MODEL": "arn:aws:bedrock:...",
"CLAUDE_CODE_AWS_PROFILE": "default"
}
}

第二步:清除 Bedrock 配置

如果配置在 settings.json 中,编辑 ~/.claude/settings.json,删除 env 中所有 Bedrock 相关的键值对:

  • CLAUDE_CODE_USE_BEDROCK
  • AWS_REGION
  • ANTHROPIC_MODEL
  • CLAUDE_CODE_AWS_PROFILE
  • CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS(Bedrock 专用)
  • CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC(Bedrock 专用)

保留你仍需要的配置(如代理、权限设置等)。清理后的文件示例:

1
2
3
4
5
6
7
8
9
10
11
12
{
"env": {
"HTTP_PROXY": "http://your-proxy:8118",
"HTTPS_PROXY": "http://your-proxy:8118"
},
"permissions": {
"allow": [
"Bash(*)"
],
"defaultMode": "dontAsk"
}
}

如果配置在环境变量中,清除相关变量:

1
2
3
4
5
unset CLAUDE_CODE_USE_BEDROCK
unset ANTHROPIC_MODEL
unset ANTHROPIC_API_KEY
unset AWS_REGION
unset CLAUDE_CODE_AWS_PROFILE

同时检查并清理 shell 配置文件:

1
2
grep -r "CLAUDE_CODE_USE_BEDROCK\|ANTHROPIC_MODEL\|ANTHROPIC_API_KEY" \
~/.zshrc ~/.bashrc ~/.zprofile ~/.bash_profile 2>/dev/null

第三步:重新启动 Claude Code

1
claude

此时应该会弹出登录方式选择界面,选择 「Claude account with subscription」,然后在浏览器中授权你的 Team 计划。

第四步:确认切换成功

启动后,欢迎界面底部应显示类似:

1
Sonnet 4.6 · Claude Pro(或 Team)

而不是之前的 arn:aws:bedrock:...

也可以在交互界面中输入 /status 确认当前认证方式。

第五步:切换模型(可选)

如果需要使用 Opus 模型,在交互界面中输入:

1
/model

用方向键选择 Opus 即可。

认证优先级

Claude Code 的认证优先级从高到低为:

  1. 云提供商凭据(CLAUDE_CODE_USE_BEDROCK / CLAUDE_CODE_USE_VERTEX / CLAUDE_CODE_USE_FOUNDRY
  2. ANTHROPIC_AUTH_TOKEN 环境变量
  3. ANTHROPIC_API_KEY 环境变量
  4. apiKeyHelper 脚本
  5. 订阅 OAuth 凭据(/login

只要高优先级的认证方式存在,低优先级的就不会生效。所以必须彻底清除 Bedrock 配置,订阅认证才能生效。

注意事项

  • 代理地址:Bedrock 用的代理可能无法访问 api.anthropic.com,切换后可能需要更换代理或去掉代理配置。
  • Premium 席位:Team 计划需要 Premium 席位才能使用 Claude Code,确认管理员已分配。
  • 用量共享:Team 计划的用量限额在 Claude 网页端和 Claude Code 之间是共享的。
  • Memory 延续CLAUDE.md 等本地文件不受认证方式影响,切换后照常保留。对话历史不会跨会话保存,这点两种方式一样。