Agent 初始化脚本
每个冷启动的会话都要交税。agent 读同样的文件、重试同样的探测、重新发现同样的路径。一个 init 脚本把税交一次,把答案写进状态。
类型: Build 语言: Python(标准库) 前置要求: 阶段 14 · 32(最小工作台)、阶段 14 · 34(仓库记忆) 预计时间: ~45 分钟
学习目标
- 认清 agent 每会话绝不该重做的工作。
- 构建一个确定性的 init 脚本,探测运行时、依赖和仓库健康。
- 持久化探测结果,让 agent 读它而不是重跑检查。
- 在初始化失败时失败得大声、迅速,且只有一个地方可看。
问题背景
打开一个会话。agent 猜 Python 版本。猜测试命令。把仓库根列五遍来找入口点。试图 import 一个没装的包。问用户配置文件在哪。等它做出一次真实编辑时,一万个 token 已经花在了本该是一个脚本的 setup 工作上。
修法是一个初始化脚本,它在 agent 做任何其他事之前运行,并写一份 agent 在启动时读的 init_report.json。
核心概念
flowchart TD
Start[会话开始] --> Init[init_agent.py]
Init --> Probes[探测运行时 / 依赖 / 路径 / 环境变量 / 测试]
Probes --> Report[init_report.json]
Report --> Decision{健康?}
Decision -- yes --> Agent[Agent 循环]
Decision -- no --> Halt[大声失败、停下、暴露给人]init 脚本探测什么
| 探测 | 为什么重要 |
|---|---|
| 运行时版本 | 错误的 Python 或 Node 版本意味着静默的版本错误 bug |
| 依赖可用性 | 一个缺失的包到后面才发现,代价是现在抓到的十倍 |
| 测试命令 | agent 必须知道如何验证;命令缺失则工作台坏了 |
| 仓库路径 | 硬编码路径会漂移;一次性解析它们并钉住 |
| 环境变量 | 缺 OPENAI_API_KEY 是个失败接触面,不是个运行时谜题 |
| 状态 + 看板新鲜度 | 来自崩溃会话的过时状态是个自伤工具 |
| 上一次已知良好 commit | 会话结束时交接 diff 的锚点 |
失败得大声、迅速、且只有一处
一次探测失败意味着停下并暴露给人。没有「agent 会想办法的」。init 的全部意义就是在工作台坏了时拒绝启动。
幂等
连跑两次。第二次除了一个新鲜时间戳外应该是 no-op。幂等性正是让你能把脚本接进 CI、hook 或一个任务前斜杠命令的东西。
init vs 启动规则
规则(阶段 14 · 33)描述行动前什么必须为真。init 是建立「那些规则能被检查」的脚本。没有 init 的规则变成「小心点」。没有规则的 init 变成一次精致的失败。
wb-init-probes动手构建
code/main.py 实现 init_agent.py:
- 五个探测:Python 版本、通过
importlib.util.find_spec列出依赖、测试命令可解析性、必需环境变量、状态文件新鲜度。 - 每个探测返回
(name, status, detail)。 - 脚本写
init_report.json,含完整探测集,若任何 block 严重度的探测失败则以非零退出。
运行它:
python3 code/main.py脚本打印探测表,写 init_report.json,在顺利路径上以零退出,或带一份失败探测列表以非零退出。
野外的生产模式
三个模式区分了一个有用的 init 脚本和一个仪式。
上一次已知良好 commit 锚定。 把当前 commit 对照一个在上次成功合并时写的 LKG 文件做探测。如果 diff 超过一个预算(默认 50 个文件),拒绝启动并要求人来批准这个新基线。这就是 Cloudflare 的 AI Code Review 用来限定审查者 agent 范围的办法:每个审查会话都对着同一个上一次已知良好锚定,绝不跨会话叠加漂移。
带 TTL 的锁文件。 第一次成功的探测通过后写一个 prereqs.lock。后续运行在 N 小时内(默认 24h)信任这个锁,跳过昂贵的探测。init 脚本先读锁;如果它新鲜且依赖清单哈希匹配,就短路。这和 Docker 用于层缓存的是同一个模式:幂等探测 + 内容哈希 = 跳过。
热路径里无网络、无 LLM、无意外。 init 探测是确定性的管道。一个调 LLM 去分类失败、或访问外部服务去检查许可证的探测不是探测;它是一个工作流。如果一个探测在干跑里超过三秒,把那当成工作台的异味,要么把它移出 init,要么缓存它的结果。
实际使用
在生产中:
- Claude Code hook。
pre-taskhook 调用 init 脚本,若失败则拒绝启动 agent。 - GitHub Actions。 一个
setup-agent作业跑 init 脚本;agent 作业依赖它。 - Docker entrypoint。 agent 容器在 exec agent 运行时之前跑 init 脚本;失败时日志暴露。
init 脚本可移植,因为它不调用任何特定框架。Bash、Make 或一个 tasks 文件都能包它。
拿去用
outputs/skill-init-script.md 访谈项目,把它的 setup 工作分类成探测,并产出一个项目专属的 init_agent.py 加一个在任何 agent 步骤前跑它的 CI 工作流。
练习
- 加一个探测,把当前 commit 与上一次已知良好 commit 做 diff,若超过 50 个文件变化就拒绝启动。
- 把脚本接成写一个
prereqs.lock文件,若锁超过七天旧就拒绝启动。 - 加一个
--fix标志,自动安装缺失的开发依赖,但绝不在没审批时修改运行时依赖。 - 把探测从硬编码函数挪到一个 YAML 注册表。为这个取舍辩护。
- 给每个探测加一个时间预算。一个跑超过三秒的探测是工作台异味。
关键术语
| 术语 | 大家怎么说 | 它实际是什么 |
|---|---|---|
| Probe | 「一个检查」 | 一个返回 (name, status, detail) 的确定性函数 |
| Init report | 「setup 输出」 | 写在状态旁边、带探测结果的 JSON |
| Idempotent | 「可安全重跑」 | 连跑两次除时间戳外产出一致的报告 |
| Fail loud | 「别吞掉」 | 停下并暴露给人;无静默兜底 |
| Setup tax | 「引导成本」 | agent 每会话花在重新发现显而易见之事上的 token |
延伸阅读
- Anthropic, Effective harnesses for long-running agents
- GitHub Actions, composite actions for setup
- microservices.io, GenAI dev platform: guardrails —— 把 pre-commit + CI 检查当 init
- Augment Code, How to Build Your AGENTS.md (2026) —— init 预期
- Codex Blog, Codex CLI Context Compaction —— 把会话开始当成压实感知的 init
- 阶段 14 · 33 —— 这个脚本使之成为可能的规则集
- 阶段 14 · 34 —— 这个脚本播种的状态文件
- 阶段 14 · 38 —— init 脚本喂给的验证关卡
- 阶段 14 · 40 —— 消费 init 报告里上一次已知良好的交接