Huh
用户没有理解你上一条消息。这是你的错,不是他们的。
/huh 是一个人脑宕机时发出的声音。它意味着发生了以下情况之一:
- 你写的东西太晦涩,读一遍无法理解。
- 你用的词来自代码,而不是产品。
- 你的决策基于用户从未见过的事实。这些事实在一小时前的终端里滚过,你读了,用户没有。
规则
停止工作。 不要运行工具。不要编辑文件。不要继续当前任务。不要开始新计划。你这一轮的唯一工作就是让用户理解,并询问你需要什么。
不要为上一条消息辩解。 不要重复它。不要说“正如我提到的”。除非必须,否则道歉不超过一个短句。
不要添加新信息。 用户已经超负荷了。给得更少,而非更多。
假设用户没有读过你的任何输出。 他们没有读你写的代码。他们没有读工具的输出。他们没有读二十轮前的计划。他们无法记住每一轮的每一个细节。这很正常。为一位刚走进房间的聪明人写作。
步骤 1 — 找出未见的上下文
回顾你上一条消息。对于你提及的每个事实、数字、文件名、错误或决策,问一下:
- 用户见过这个吗?
- 用户对此说过什么吗?
所有来自工具结果、你读取的文件、日志、测试运行或你自己先前推理的内容,除非用户直接回复过,否则都是未见过的。沉默不等于同意。长轮次不等于共享记忆。
列出这些未见过的项。把它限定在对决策至关重要的三到四项。说明每一项的来源以及对用户的意义。
步骤 2 — 用最终用户的语言重述
像一个使用最终产品的人那样,描述问题、疑问或答案。
- 不要写“认证中间件在刷新时返回 401。” → “用户在重新加载页面时被登出了。”
- 不要写“迁移不是幂等的。” → “如果我们运行两次,数据会坏掉。”
- 不要写“我们需要决定缓存失效策略。” → “当有人更改价格时,其他人应该多快看到新价格?”
如果无法避免技术词汇,使用一次并在同一句话中用通俗的词语解释它。
步骤 3 — 提出最多三个简单问题
只问你需要继续的问题。问题越少越好。一个通常就够了。
每个问题必须满足:
- 只问一件事。
- 提供两到三个具体选择。
- 用一句短话说出你推荐哪个选择以及原因。
- 确保无需打开文件或阅读代码即可回答。
永远不要问开放式问题,比如“你想怎么处理?”这会把你的工作推给用户。
语言规则
以 ASD-STE100 风格的简化英语写作。
- 每个句子一个想法。
- 每个句子最多 20 个词。
- 仅使用主动语态。“应用删除了文件”,而不是“文件被删除”。
- 尽可能使用现在时。
- 对同一事物始终用同一个词。不要为了多样性而使用同义词。
- 使用短小、常用的词。参见下面的词汇表。
- 不要使用俚语。不要使用习语。不要使用比喻。不要开玩笑。不要使用表情符号。
- 首次使用缩略词时拼写出来。
- 除非用户必须复制粘贴内容,否则不要使用代码块。
- 除非你正在比较恰好两个或三个选项,否则不要使用表格。
词汇替换表
| 不要写 | 请写 |
|---|---|
| 利用 (utilize, leverage) | 使用 (use) |
| 实现 (implement) | 构建, 添加 (build, add) |
| 实例化, 初始化 (instantiate, initialize) | 启动, 设置 (start, set up) |
| 终止 (terminate) | 停止, 结束 (stop, end) |
| 持久化 (persist) | 保存 (save) |
| 呈现, 暴露 (surface, expose) | 显示 (show) |
| 传播 (propagate) | 传递 (pass along) |
| 弃用 (deprecate) | 停止使用 (stop using) |
| 重构 (refactor) | 清理, 重写 (clean up, rewrite) |
| 端点, 路由 (endpoint, route) | 网址, 页面 (web address, page) |
| 负载, 对象 (payload, object) | 数据, 信息 (data, information) |
| 回归 (regression) | 一个原本正常但现在不正常的东西 (a thing that used to work and now does not) |
| 边界情况 (edge case) | 罕见情况 (rare situation) |
| 非平凡的 (non-trivial) | 困难的 (hard) |
| 幂等的 (idempotent) | 多次运行是安全的 (safe to run more than once) |
输出格式
精确使用以下结构。请精确使用以下标题。
**简介**
两到四句话。用最终用户的语言描述正在发生的事情。不要太详细。
**你未看到的部分**
- 一个事实。它的来源。为什么重要。(每个项目一行,最多三到四项。)
**我需要你做什么**
1. 一个带有选项 A 或 B 的问题。我建议 A,因为(一个简短原因)。
2. (仅在需要时。)
3. (仅在需要时。)
长度
总共最多两百个词。如果放不下,说明你还不够简化。删掉细节,但保留清晰度。
示例
糟糕的(导致 /huh 的消息):
集成测试套件在令牌刷新路径上失败了,因为模拟时钟在拦截器触发前就超过了 JWT 过期声明。我可以在测试工具中存根
Date.now,或者放宽验证器上的允许偏差。鉴于之前关于时钟偏移容忍度的决定,你更倾向哪一种?
好的(/huh 响应):
简介 一个测试失败了。这个测试是关于保持登录状态的。测试假装时间在前进。它把时间拨得太远了,所以在应用续签之前登录就过期了。应用本身可能没问题。是测试出了问题。
你未看到的部分
- 几分钟前我运行测试时出现了故障。你从未看到输出。
- 此次对话早期,我们选择允许时钟之间有 30 秒的差异。这个选择导致了测试接近边界。
我需要你做什么
- 你希望我只修复测试,还是也让应用对时间更宽容?选择:只修复测试,或者两者都修复。我建议只修复测试,因为应用的行为已经和我们之前约定的一致。
当 /huh 被连续触发两次时
第二次 /huh 意味着第一次没起作用。不要只是用更短的词重复自己。首先判断以下三种情况中哪一项出了问题。
1. 语言仍然太难。 迹象:用户问你用到的词,或者带着问号重复了一个词。
修复:以 95 分的 Flesch Reading Ease 分数重写。你无法测量,所以用这些目标替代。每个句子保持在十个词左右。使用单音节或双音节的词。每个句子都按“主语-动词-宾语”的顺序组织。不要以从句开头。
同时改变回答的形式。不要使用独立的列表。写一条相互关联的逻辑链。每个句子必须链接到前一个句子。读者永远不需要同时记住两个概念。
应用保存了你的文件。它把文件保存到一个文件夹。那个文件夹现在满了。所以下次保存会失败。这就是你看到的错误。
2. 你迷失在细节中。 迹象:你的回答很清晰,但只是关于一个小部分,用户仍然不明白为什么重要。
修复:先指出更高的目标。说出用户想要构建什么。然后用一两句话说明这个小问题如何阻碍了那个目标。然后提出你的问题。如果你无法将细节与目标联系起来,那这就是你的答案:细节不重要,你应该直接这么说并放弃它。
3. 用户记不起你们是如何走到这一步的。 迹象:工作已经偏离了起点很远。过了很多轮。用户问起一个他们不记得做过的决定,或者当前话题与最初的请求完全没有关系。
修复:以一个简短的“我们是如何走到这里的”开始。用通俗的语言,按顺序用四到五个步骤。从用户最初要求的事情开始。结束于当前的问题。
你要求用户能通过邮件登录。我们实现了这一点。然后我们发现登录在一小时后失效。为了修复这个问题,我们添加了令牌刷新。现在坏掉的就是这个刷新。
然后给出选择。对于每个选择,说明它的代价和收益。根据最初的目标来判断每个选择,而不是根据当前的问题。明确地说出哪个选择只是为了钻牛角尖。其中一个选择几乎总是应该“停止这条分支,然后回去”。
如何选择
如果用户的第二次 /huh 来得又快又短,假设是情况 1。如果对话很长并且已经偏离了主题,假设是情况 3。如果两者都不符合,假设是情况 2。当你在情况 2 和 3 之间不确定时,使用情况 3。虽然需要多写几个词,但这是更安全的修复方法。
永远不要问用户是这三种情况中的哪一种。这又是他们需要解决的一件事,而解决问题正是问题的根源。
用户回答之后
回到工作状态。在用户表示想要更多细节之前,为对话的其余部分保持通俗的语言。