Think Deep,Work Lean

Agent 报错先别改代码,一条 git stash 分清是谁的锅

Posted on By zack

大家好,我是Zack。

前天下午我让 agent 改一个构建脚本,改完一跑就报错。

我把报错整段丢回去,说”修一下”。它改一版,我跑一次,还报错,再改。

改了三轮,还是同一个错。

最后发现这个错跟我改的代码一点关系都没有 —— 环境里少装了个包。

一下午,就这么没了。

我原来的做法

报错弹出来,我的动作是固定的:复制、粘贴、说”修一下”。

这个循环里藏着一个我从没检查过的前提:

这个错,真的是我这几行代码引起的吗?

我没验证过。我默认它是。

默认错了之后,后面每一轮都不是在修 bug,是在错误方向上加速。

三轮之后我才反应过来,方向从一开始就偏了。

现在多做一个动作

就一个:把改动收起来,重跑一次。

git stash -u      # -u 是连没跟踪的新文件一起收
<你的运行命令>
git stash pop     # 跑完记得 pop 回来

判据特别简单:

  • 还报同一个错 → 跟你刚写的代码无关,是环境的事
  • 不报了 → 就是你这几行,可以放心让它改

顺手提醒一句:跑之前先 git stash list 看一眼,确认stash 栈里没别人的东西。

这动作有多便宜

我在自己的博客仓库实测,402 个跟踪文件:

$ git ls-files | wc -l
402
$ time (git stash -q -u && git stash pop -q)
0.048 秒

在 /tmp 的小 demo 仓库里,加上中间那次重跑,整轮 0.103 秒。

不到 0.1 秒的动作,替我省掉一下午。

以前我觉得这种验证是”讲究人的做法”,要额外花时间。

实测完才发现,贵的从来不是验证,是验证之前那三轮瞎改。

第二步:看报错栈最后几行

我在 /tmp 故意引了个环境错误(代码里 require 了一个没装的包),真实输出长这样:

Error: Cannot find module 'lodash'
  code: 'MODULE_NOT_FOUND',
  requireStack: [ '/private/tmp/demo-stash/build.js' ]

重点看 requireStack 那一行 —— 它告诉你从哪个文件开始找的。

再配合一个粗判据:

  • 栈里如果全是 node:internal/...、node_modules/... 这种路径,最后才碰到你的文件 → 加载阶段就断了,多半是环境
  • 栈顶直接是你刚改的那个文件、你刚写的那一行 → 那就是你的代码

这个判断不用很准,它是用来决定”下一步往哪查”的,不是用来结案的。

第三步:它说找不到文件,先让它打一行 pwd

agent 说”文件找不到”,十次有八次是它站的地方和你以为的不一样。

子 agent、脚本、定时任务,各有各的当前目录。

我自己踩过:同一个 build.js,站在仓库根目录跑好好的,cd 进一个子目录再跑,直接报 Cannot find module。

所以现在两件事我做死了:

  • 下指令一律给绝对路径,不让它猜
  • 让它在动手前先跑一句 pwd,把工作目录打出来给我看

第四步:给重试定个上限

不写上限,它会在同一个报错上一路转下去,转到你手动停。

现在我在任务里直接写死一句:

同一个错误最多重试 3 次,到了就停下来,把报错原文和已经试过的办法列出来给我。

上限不是限制它的能力,是给它一条能退出的路。

这条要跟第一步连着用:它停下来的那一刻,正好是你跑 git stash 的时机。

不是 node 也一样

这套判据跟语言没关系,git stash 是 git 的,不是 node 的。

Python 项目想快速确认”包到底装没装”,直接问解释器:

python -c "import 包名"    # 报 ModuleNotFoundError 就是没装
pip check                  # 看已装的包之间有没有互相冲突

这两句跑完,环境那一半的可能性基本就排掉了。

验证完别留垃圾

git stash pop 之后顺手看一眼:

git status --porcelain    # 只看未跟踪那部分

agent 跑完经常留一堆东西:tmp 目录、.bak、测试输出。

不管它,下次你 git add . 就全进仓库了。

要的留,不要的当场删。留着的下场是三个月后没人敢动。

前后对比

  以前 现在
归因方式 默认是自己的代码 先验证再动手
一次归因成本 三轮起步,一下午 0.05 秒 + 一次重跑
改错方向 全靠运气 基本不会

诚实说一句:那个 0.05 秒只是 git 命令本身,中间重跑一次要看你项目多大。

我这边的构建脚本重跑一次几百毫秒,加起来不满一分钟。

如果你的项目跑一次要十分钟,那这招依然划算 —— 十分钟能确认方向,比三轮瞎改便宜得多。

两条能迁移的原则

一、归因之前不动手。

花几十秒确认”这是谁的错”,看着慢,实际是把后面所有轮次的方向一次性定对。

二、判定不了的要求都是废话。

“修一下”判定不了,agent 只能猜。

“跑 git stash 确认是不是环境的锅”能打勾,它就能照做。

给 agent 下指令,先问自己一句:这条它做完了,我能不能一眼看出做没做到?

看不出来的,就还没写完。

最后

这套东西一点都不高级,就是几条现成的命令。

局限也说清楚:git stash 这招只在改动能干净收起来时好用。

如果一次改了几十个文件、还夹着没提交的配置,stash 本身就会变成新的麻烦 —— 这种时候我宁愿先 commit 一个临时节点,再从那个节点比对。

所以它不是万能钥匙,是个便宜的第一刀:先花 0.1 秒把”环境”这个最大的可能性排除掉,再谈别的。

你那边报错一般是怎么归因的?有没有比 git stash 更快的判据,欢迎留言告诉我。

公众号:Zack说AI