返回博客

11 轮全失败,用户一句话命中真因——AI 调试的「沉没成本陷阱」

有一类 bug,修得越久越危险——不是因为越来越难,而是因为每一轮失败都在加深 AI 对错误假设的执着。当用户说「我感觉问题在 X」时,AI 的第一反应往往是:「但从技术上看,X 不太可能……」然后继续走自己的方向。

这正是问题所在。

现象

某微信小程序页面需要实现「整页禁止滚动,内部 scroll-view 可以自由滑动」的经典交互。

AI 连续修了 11 轮:

  • R1–R6:尝试 page-meta 禁滚、overscroll-behaviorposition: fixedheight: 100% vs 100vhcanvas 层级 hoist——全部失败,每轮失败后换一个归因方向,互相干扰
  • R7–R8:放弃锁滚改为让 page 自然滚动 + 背景色 hack——方向与原需求完全相反
  • R9–R11:找到一个功能类似的页面,1:1 抄结构,逐项对齐 CSS——仍然失败

第 11 轮之后,AI 还想继续加新的 CSS 属性组合。

根因

有两层根因,一层是技术的,一层是元认知的。

技术层:AI 的所有 11 轮尝试都在锁 page(页面容器),从没考虑过锁 scroll-view 自身。scroll-view 作为微信的 native 组件,在 enhanced 模式下有自己独立的回弹和滑动行为,必须在组件层面用 bounces="{{false}}" + refresher-enabled="{{false}}" 关掉,同时把 scroll-viewposition: absolute; inset: 0 物理钉在视口内——两者缺一不可。

元认知层:AI 在 11 轮投入后,已经深陷「沉没成本」陷阱。每次失败的反应不是重新质疑假设,而是「再加一件」「再换个属性」——在错误方向上加速。

坑:多轮失败后 AI 会把用户假设当「外行猜测」dismiss

用户说「我感觉问题在 scroll-view 锁不住自身」,AI 内心翻译成「他大概是指 flex sizing 不准」,然后加了一堆 min-height 兜底——完全偏离用户的字面意图。

用户没有沉没成本,他看到的是真实的最终效果。他的「感觉」是基于 11 轮真实观察的归纳,不是凭空猜测。

正解

用户说:「我感觉问题出在 page-scroll 能不能锁住,然后把这个设置为固定无法滑动,但是内部可以滑动。」

按字面意图,直接做:

/* scroll-view 物理钉死在视口,自身不能移动 */
.page-scroll {
  position: absolute;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
}
<!-- 关掉 enhanced scroll-view 自身的回弹和下拉刷新 -->
<scroll-view
  class="page-scroll"
  scroll-y
  enhanced
  bounces="{{false}}"
  refresher-enabled="{{false}}"
>
  <!-- 内容 -->
</scroll-view>

第 12 轮,一击通过。

正解:多轮失败后立刻切换到用户假设方向,且不要「技术翻译」
  1. 停手:同一 bug 修 ≥3 轮仍失败,当前假设已被证伪,继续走没有意义
  2. 按字面意图做:不要把用户的描述翻译成自己熟悉的技术术语,用户说「锁不住」就做「物理锁死」
  3. 最小成本独立验证:只改用户指向的方向,不夹带任何「顺便也加 Y」——混合实验无法归因

一个可量化的参考

根据实际经历,不同调试策略的命中率大致如下:

| 策略 | 命中率 | |------|--------| | 凭理论推断单点修复 | ~30% | | 抄结构相似的 working sibling | ~60% | | N 轮失败后采用用户主动给出的假设 | ~70% |

用户假设比抄 sibling 命中率还高,原因很直接:他们没有技术先验偏见,看到的是真实渲染结果。

一句话外卖

多轮失败是重新质疑假设的信号,不是加倍投入当前方向的理由——用户的「感觉」此时比 AI 的「技术判断」更可信。