跳到正文
AI 又造了一个 helper:开工前先搜一遍仓库

AI 又造了一个 helper:开工前先搜一遍仓库

2026年7月30日

AI 又造了一个 helper:开工前先搜一遍仓库

AI 又造了一个 helper:开工前先搜一遍仓库

一个 TypeScript 项目跑久了,仓库里可能会出现这样的景象:isObjectisPlainObjectisRecordisDictionary,名字不同,里面做的事差不多。它们散在四个目录,各自只有几行,单独看都挺合理。

再过几个月,一个 Agent 接到新任务,又在第五个目录里写下同样的判断。

这类重复很难在当次任务里被发现。测试会过,类型也没报错,PR 看起来甚至很整洁。问题要等到下一次修改规则时才露出来:同一件事需要改五处,每一处对“对象”的理解还不完全一样。

Agent 不是故意造轮子。它只是完成了你交给它的局部任务,而你没有要求它先看一眼仓库里已经有什么。

每一段都对,合在一起却错了

2026 年夏天,isRecord 突然成了 Codex 生成代码里的一个梗。很多开发者发现,自己的仓库里到处都是这个函数,甚至有人用下面这条命令衡量项目被它占领到了什么程度:

rg -o 'isRecord' . | wc -l

tldraw 团队顺着这个梗回头搜索,发现自己在 2022 年就写过一版 isRecord。继续往 GitHub 里找,前排是 tldraw 和它的复制版本,后面跟着越来越多 Codex 生成的代码。它是不是模型偏爱的唯一来源,很难证明;但一个现象很清楚:模型会带着自己熟悉的写法进入你的仓库。

tldraw 团队追溯 isRecord 的来源

这本来没什么。人也会带着上一家公司的习惯写代码。区别在于,Agent 生成得更快。同一个默认写法可以在几天内散到十几个文件,而人通常要到维护时才看见它们之间的重复。

一段代码在自己文件里看着对,放在整个仓库里可能已经是第六份。一个 helper 该不该新增,光看这五行不够——得看仓库里是不是已经躺着一个名字不同、职责相同的东西。

第五份看起来也很合理

把“先搜索”写进任务顺序

最轻的处理办法不是做一次全仓库重构,而是在新增之前加一道搜索。

在新增 helper、组件、类型或公共函数之前,先搜索仓库里是否已有相同职责的实现。

请先列出:
- 找到的候选实现及位置;
- 它们与当前需求的差异;
- 为什么可以复用,或为什么必须新增。

没有完成这一步,不要创建新的抽象。

这里搜的不能只有名字。现有函数可能叫 isDictionary,新需求里想到的词却是 isRecord。只跑一次精确文本搜索,很容易得出“没有”的结论。

更可靠的顺序是先搜概念,再搜调用方式。想新增日期格式化函数,就搜索日期库、format 调用和现有页面的展示结果;想加一个空状态组件,就看相邻页面怎么处理无数据,而不是只搜 EmptyState 这个名字。

Agent 很适合做这件事。它能同时看符号、调用点和页面结构,再把最接近的实现摆出来。人不需要逐文件翻,只需要判断它找出的候选是不是真的同一个职责。

新增前的四步搜索

复用不是强行挤进旧代码

“先搜索”也可能走到另一个极端:为了证明自己遵守复用原则,Agent 把新需求硬塞进一个只沾边的旧函数,最后加上四个参数和三条分支。

所以搜索之后必须回答差异。

假设仓库里已有一个 isRecord,它只接受项目内部带 idtype 的业务记录;新任务需要判断任意 JSON 对象。两者名字接近,语义却不同。复用旧函数会让边界更模糊,此时新增一个更准确的实现反而合理。

该不该复用,可以看三个事实:输入输出语义是否一致,变化原因是否一致,未来修改时是否应该一起变化。三条里有两条答不上来,就不要为了减少文件数量勉强合并。

所以不要只给 Agent 一句笼统的“尽量复用”。“尽量”没有边界,它只能猜。先找候选,再说明差异,人的判断才有落点。

把重复暴露在生成之前

如果项目已经积累了一批重复实现,可以先从高频模式下手,不必立刻清理全部。用 rg 找常见 helper 名称、相似错误处理和重复常量,挑出最容易继续扩散的几个,收进明确的公共入口。

随后把入口写进项目规则:日期统一去哪里,权限判断用哪个模块,API 错误如何构造。规则不需要长,一条路径加一句用途,比“保持代码一致性”更有用。

Agent 会认真完成眼前这一个文件。仓库的一致性仍然需要有人替它设定动作顺序。

新增代码前多搜一次,省下的往往不是眼前五行,而是几个月后同时维护五个名字的那一轮返工。

版权声明

作者
XingKaiXin
标题
AI 又造了一个 helper:开工前先搜一遍仓库
发布时间
2026年7月30日

本作品采用CC BY-NC-ND 4.0 DEED许可。