编码 Agent 最擅长产出改动,所以它天生乐观:写完就说做完了,从来不打开应用看一眼。于是坏掉的弹窗、静默返回 500 的接口、以及「部署成功」盖在失败部署之上,全都被发出去了——你变成它的 QA。Whyline 想解决的是另一半问题:把「为什么这段代码存在」记下来,交给下一个 Agent。它有两个可分开用的部分:决策记忆,把选择、理由、被否决的方案与涉及的文件写进仓库,让后来的 Agent 不用重猜;以及 Relay,一条从请求到受审提交的门控流水线,把打分、多 Agent 脑暴、受审的规格与计划、实现、测试、评审、核验串起来,把发布留给人类。它由 anishmoncivarghese 开发,Apache-2.0 协议,0.3.51 于 10 月 24 日随 Show HN 发布;没有托管账号、没有遥测、没有付费档,也不碰各家 Agent CLI 的密钥——它复用你已经登录好的那些。本教程按让仓库开始记账、用 explain 与 note 留决策、手工交接、跑通 Relay、理解门控与暂停点、以及 Saved Agents 与收件箱六步把它落地。
Step 1:装上,让仓库开始记账
用 uv 装全局工具,进到项目目录跑 init,然后直接敲 whyline 打开全屏控制台(whyline console 是键盘版,whyline console --ui 显式请求全屏版)。CLI 本身保留给脚本与终端流。初始化之后仓库里会多出 .whyline/ 目录:decisions.md 记录决策与被否决的替代方案,是会随代码提交的;同目录下的运行时文件——当前交接、认领、活动账本——只留在本地。仓库级的 Agent 定义在 .whyline/agents/,可以选择提交;而 ~/.whyline/agents/ 与 ~/.whyline/ideas/ 是本机状态,不进仓库。
uv tool install whyline@latest
cd your-project
whyline init
whyline # 打开全屏控制台
whyline status # 检查这里的记录是否健康
# 想把当前任务上下文压成一段有界的上下文块
whyline sync
# 想给下一个 Agent 一份有界历史
whyline brief --file src/a.py
值得先记住它共享什么、不共享什么。Agent 之间不会交换各自隐藏的对话;Whyline 给下一个 Agent 的是一份小而明确的记录:选了什么、为什么、否决了什么、涉及哪些文件、还剩什么风险。whyline sync 会把当前交接、Git 状态、归属警告与相关决策压缩成一段有界上下文块,而原始提示词文本不会被包含进去。这个取舍决定了它的定位——它是项目记录,不是对话转移。
记下来的东西会进你的提交历史:.whyline/decisions.md 是被设计成要提交的,里面会写清决策理由与被否决的方案。涉及内部架构、安全权衡或客户信息的措辞,写之前先按对外可见的标准过一遍;运行时文件则留在本地,不会外泄。
Step 2:用 explain 与 note 把「为什么」钉在代码上
最直观的用法是 whyline explain 加一个 file:line:它会告诉你这一行是谁最后碰的、对应哪个提交、当时的决策是什么、为什么这么定、否决了哪个方案,以及置信度。没有记录就给出空答案,并且它会明说什么时候是在做推断——这一点比给一个看似确定的答案更重要。想补记录用 whyline note,把选择、理由、被否决项、文件、执行者与任务号一起写进去。
$ whyline explain src/whyline/runner.py:46
src/whyline/runner.py:46
Last touched by anish
Commit bc677e4 · 2026-08-17
Decision Resolve runner injection points at call time, not in the signature
Because default arguments bind at import time, so monkeypatching
runner.shutil.which had no effect and a test exec'd the real
codex binary, replacing the pytest process
Rejected patch the default argument tuple in tests — couples every test
to CPython internals
Confidence High — a recorded decision matches the commit for this line
whyline note "chose X" \
--because "Y" \
--rejected "Z: too slow" \
--file src/a.py \
--actor codex --role implementer --task WL-42
这一步的价值要在后续才看得出来。刚开始写记录像是给未来加负担;但当下一个 Agent 打开同一份代码、不再需要你把那个「默认参数在导入时绑定」的坑解释第三遍时,收益就兑现了。官方给的输出来自它自己的仓库:一条记录解释了为什么测试里 monkeypatch 没生效、以及为什么否决了另一种改法——这类「只有踩过才知道」的信息,正是 Agent 之间最容易丢的东西。
Step 3:手工交接:claim、run、handoff
不打开控制台也能在 shell 里完成一次显式交接:先 claim 声明谁在改哪个文件,跑一个 Agent 完成任务,再 handoff 把状态、摘要、测试与风险交给另一个 Agent,最后让接收方动手。整个链条里的每一次执行都带 --task-id,所以审计时能串起来。要注意 claim 只是建议性警告,不是文件锁——两人同时改同一个文件它不会拦,只是会提醒。
# 1) 认领:谁、什么角色、改哪个文件
whyline claim WL-42 --actor codex --role implementer --file src/cache.py
# 2) 让这个 Agent 干活
whyline run codex "implement bounded cache invalidation" --task-id WL-42
# 3) 交接:状态、摘要、测试、风险一并写下
whyline handoff WL-42 \
--from codex --to claude \
--status ready-for-review \
--summary "bounded invalidation implemented" \
--file src/cache.py \
--test "pytest -q: passed" \
--risk "large repositories not benchmarked"
# 4) 接收方接手
whyline run claude "review the cache change" --task-id WL-42
把 handoff 理解成一份项目记录,而不是把上一个 Agent 的私聊记录搬过去——这是整个设计的分界线。上一个 Agent 想了什么、走了哪些弯路,仍然留在它自己的会话里;交出去的只是结构化的结论与风险。好处是接收方的上下文不会被无关推理灌满,坏处是你得接受「有些细节就是传不过来」,所以用 --risk 与 --test 把关键约束显式写出来就变得很重要。
claim 不会阻止并发改同一文件:它只是建议性警告。多人或多 Agent 同时碰一个文件时,仍然要靠分支、工作区或你自己的约定来隔离;把 claim 当锁会在最需要它的时候失效。
Step 4:Relay:从请求走到一次受审的提交
Relay 随 Whyline 一起装好,但你不配置它就不会做任何事。它把一份 Markdown 计划变成一条受控的多 Agent 流水线:请求 → 脑暴与综合 → 受审的规格与实施计划 → 可选的测试计划 → 预检与角色分配 → 实现 → 测试 → 评审 → 核验 → 批准后的提交 → 人类发布。每个角色可以指派不同的 Agent 与模型,还能配一条有序的备用链,在某个厂商不可用、掉线或配额耗尽时接管。终端优先的用法从四条命令起步。
whyline relay init # 建一个计划
whyline relay doctor # 体检
whyline relay setup # 配置角色、模型与备用链
whyline relay status # 看当前跑到哪了
打开 Relay 后可以选择从一个脑暴、一段描述、已有计划开始,或者直接用 Auto——Auto 能把一个请求一路带过研究、受审的规格与计划、预检,直到跑完 relay。控制台里还有 Files 面板,只读地跟随当前 Chat、脑暴或 Relay 运行中改动的文件,方便你一边看一边判断。需要强调的是角色与模型是可分开配的:实现用一个、测试用一个、评审再用另一个,这既是质量手段也是成本手段。
Auto 不是自动驾驶:它只自动推进安全的阶段,遇到开放问题、危险恢复、需要人工核验与发布任务时一律暂停。潜在破坏性的恢复操作仍然等你点头。别因为叫 Auto 就离开工位去睡觉。
Step 5:门控、暂停与恢复:谁有权力按下停止键
Relay 的控制面一共就几件事,但每一件都对应一个真实事故场景。Resolve 会把证据与受约束的修法摆出来;Resume 接着检查点继续;Stop 是打断当前这次尝试,而不是等它跑完。还有一条硬边界:宿主侧的 committer 可以在配置好的评审与核验闸门都通过之后提交工作,而发布步骤归人类所有,会暂停整条流水线等你标记完成或明确跳过。换句话说,它能把改动推到「准备好发布」,但不会替你发布。
# 常见的三条暂停边界
# 1. 开放问题 —— 需求本身有歧义,Auto 会停
# 2. 危险的恢复动作 —— 即便 Auto 也停下来等人
# 3. 人工核验与发布 —— 永远停,必须有人标记完成或跳过
whyline relay status # 看它停在哪、为什么停
还有一层是 Agent 能力矩阵,配角色前必须看清:Claude Code 与 Codex 都有经过验证的只读启动模式,Grok 的编辑与写入被拒绝,Antigravity 需要仓库信任批准、且没有经过验证的只读模式——因此保存型无人值守 Agent 不包含它。whyline account detect 会刷新 Claude 与 Codex 的套餐标签,Grok 与 Antigravity 因为 CLI 不暴露同样的检查,只报已装或缺失。把这条矩阵抄进你的团队文档,能省掉不少「为什么这个角色跑不起来」的排查。
它不碰密钥,也不等于隔离:Whyline 复用各 CLI 已有的登录与订阅,从不索取或保存它们的 API 密钥;但它也明确说了,这不承诺与底层 CLI 能读到的任何数据源或工具隔离。某个 CLI 能读的东西,它驱动的 Agent 一样能读到。
Step 6:Saved Agents 与 Ideas 收件箱,以及平台边界
Relay 的角色是围绕一份计划协作,而保存型 Agent 是另一回事:一份可复用的只读指令集,带主 CLI、备用链、超时、调度或触发器、运行历史与投递设置。定义写在仓库里,比如一个每周工作日早上检查依赖的 Agent。要注意一条:在一台 Mac 上无人值守运行之前,当前定义必须在本机被接受;改定义会作废这个接受状态并停止无人值守运行,直到重新评审。
# .whyline/agents/dependency-watch.toml
name = "dependency-watch"
instructions = """
Review this repository's dependencies and report important security
or compatibility changes. Do not edit files.
"""
runner = "codex"
timeout_minutes = 41
[trigger]
kind = "schedule"
at = "09:00"
点子收件箱是另一条入口,解决的是「想法还没成型就别碰代码」。你可以从控制台、Telegram 或经过认证的邮件投进去:先打分或多 Agent 脑暴,导出 Word、PDF、Excel,再在你明确允许的仓库里产出受审的规格与计划,最后确认一次才启动 Relay。点子在自己的工作区里跑,规划也只限于你显式允许的仓库;~/.whyline/ideas/ 下的 SQLite 是权威数据,ideas.xlsx 只是重建出来的导出。邮件那条路还要求发送者在白名单里且 DKIM 或 SPF 校验通过,关键动作要一个与当前点子版本绑定的六位确认码。
whyline idea telegram setup # 接一个机器人,允许一个私聊
whyline idea email allow [email protected] # 允许某个发件人
whyline idea email mail-script # 安装邮件规则
# 平台支持(官方口径)
# macOS 完整:控制台、Relay、保存型 Agent、调度、邮件集成、后台收件箱、原生 PDF 转换
# Linux 核心 CLI 与控制台、交互式 Agent、Relay、按需工作流;无 macOS 服务与邮件集成
# Windows 实验性,不作为发布门槛;部分核心路径已测,不要假设功能对等
把收尾的话说完整:它刻意没有托管账号、遥测服务、付费档与自己的 API 密钥,各家 CLI 用自己的认证、条款与数据处理方式;保存型无人值守 Agent 用经过测试的只读 CLI 模式与本地接受过的定义,但这不承诺与底层 CLI 能读到的东西隔离。Telegram 走白名单私聊但不是端到端加密;Telegram 只保留有限时间的机器人更新,所以 Mac 必须重新联网才能补上。用法上,whyline --help 与 whyline relay --help、whyline agents --help、whyline idea --help 能给出当前完整的命令面。
Windows 是实验性支持:官方明确写了它不作为发布门槛,只有部分核心路径被测试过,不要假设功能对等。要在 Windows 上用,先在非关键仓库里把 sync、explain、note 这条最小路径跑通,再考虑 Relay;生产流水线优先放在 macOS 或 Linux 上。
常见问题速查
| 现象 | 原因与处理 |
|---|---|
| whyline 命令装完找不到 | 用 uv tool install whyline@latest 装全局工具;确认 uv 的 bin 目录在 PATH 里 |
| explain 给出空答案 | 该行没有记录;用 whyline note 补一条,空记录就是空答案 |
| explain 说是推断 | 它会明说何时在推断;把结论当线索,回到提交里核对 |
| 两个 Agent 同时改一个文件 | claim 只是建议性警告不是锁;靠分支或工作区隔离 |
| Relay 装了却什么都不做 | 需要先 relay init 与 relay setup 配置好再启动 |
| Run 按钮点了没反应 | 只对通过 Check 的配置与仓库状态开放,改动任一项都要重跑 Check |
| Auto 跑一半停住了 | 开放问题、危险恢复、人工核验与发布都会暂停,属于预期 |
| 某个角色跑不起来 | 查能力矩阵:Grok 拒绝编辑写入,Antigravity 需仓库信任批准且无只读模式 |
| 备用链接管后结果不一样 | 备用要挑能力相近的,Grok 当实现备份会降级 |
| 改了 Agent 定义后不再自动跑 | 改动作废本机接受状态,需重新评审后才恢复无人值守 |
| 邮件投进来的点子没被接受 | 要求发件人在白名单且 DKIM 或 SPF 通过,关键动作要六位确认码 |
| Windows 上功能缺失 | 官方标注实验性、不作为发布门槛;生产流水线放 macOS 或 Linux |