AI编程代码去AI味:用规则集让大模型写出更像人类的代码
2026/9/6 4:05:24 网站建设 项目流程

1. 一眼识别"AI写的代码":问题不在能力,而在习惯

过去一年我花了不少时间折腾 AI 编程,从 Copilot 到 Cursor 再到 Claude 写前端,说实话,AI 生成代码的质量已经远远超出很多人的预期——组件拆分合理、逻辑严谨、边界条件齐全,甚至比我见过的一部分初级工程师写得还要规范。

但有一个问题始终让人觉得别扭:AI 写出来的代码,总有股挥之不去的"机器味"

这东西很难量化,但作为一个常年 Review 代码的老前端,我基本扫一眼就能分辨出来。最典型的几个特征:注释密度异常高,每个函数上方都恨不得写三行 JSDoc 说明"这个函数用于处理某某逻辑";变量命名过于"规整",永远是用 camelCase 的标准模板,形容词加名词的组合毫无个性;代码结构千篇一律,用 Hooks 就把所有逻辑一股脑塞进 useEffect,用组件就把所有东西都拆成 props 透传。

这不是能力问题,是"习惯"问题——更准确地说,是训练目标问题。大模型在预训练阶段见到的代码,大部分来自 GitHub 上公开仓库,而公开仓库里充斥着教程代码、示例代码、教学项目,这些代码的特点就是"规范性优先、注释充分、结构清晰"。AI 学到了这个"平均画像",但它不知道一个真实的前端项目里,代码是被人写出来的,而人是有惰性的、有偏好的、有上下文语境的。

比如我在公司维护一个中后台项目,里面的工具函数基本没有注释,因为一个formatDate的函数名已经足够表达意图,再加注释反而是噪音。变量命名也不总是那么"优雅"——有时候list就是比userListData更顺手,因为作用域只有十行。但 AI 不会这么写,它倾向于更"标准"的写法。

这带来一个现实问题:AI 写代码的确能提高效率,但生成的代码混进团队代码库之后,Review 成本反而上去了——你要花时间删掉那些多余的注释,把过度设计的抽象拍平,把"看起来正确"的代码改成"真正符合团队风格"的代码。

那有没有办法让 AI 从一开始就按照"真人习惯"来写代码?

这就是我最近把玩的一个开源项目想解决的问题——4.8K Star,一个通过规则约束让 AI 前端代码"去 AI 味"的规则集。这套规则的思路很简单:告诉模型"什么不该做",比告诉它"该怎么做"更有效

往下看,我把这套规则的核心内容、工作原理、接入方式,以及我自己踩过的坑,全部摊开来讲。

2. 规则集不写代码,它约束的是"思维方式"

先搞清楚一个概念:这套东西不是代码库,也不是框架,更不是 Lint 工具。它是一套提示词(Prompt)规则集,核心形态是一份精心设计的系统提示词,在对话开始时注入给 AI,约束它后续生成代码的风格、结构和行为。

这么说可能还是有点抽象。换个方式理解:你现在让 AI 写代码,相当于请了一个能力很强、但没有任何行业经验的新人。他写代码的技术没问题,但他不知道你们团队的习惯——变量怎么命名、注释写到什么程度、组件文件怎么组织、什么时候该抽象什么时候该直接写。你不可能每句话都叮嘱一遍,太累了,而且他会左耳进右耳出。

规则集的作用,就是把这套"团队约定"一次性说清楚,让 AI 在进入工作状态之前先"读一遍新人手册"。

项目是基于 Claude 的规则体系设计的,但在 Cursor、Windsurf、Trae 这类支持自定义系统提示词的 AI 编程工具里同样适用。核心文件是一个名为AI-RULES.md(或类似命名)的规则文档,通过工具自带的 Rules / 指令配置入口注入。

这套规则的底层逻辑非常有意思,它没有像传统 Prompt 那样写"你应该怎么写代码",而是大量使用了禁令式表述——"不要给每个函数写注释""不要使用过于冗长的变量名""不要为了抽象而抽象"。为什么这么设计?

因为模型在指令遵循上有个特点:开放式指令("请写出高可维护性的代码")会触发它的"标准答案模式",让它调用训练数据里最"正确"的那套写法;而封闭式禁令("不要写多余的注释")会强制它偏离默认路径,在约束空间内重新寻找表达方式,反而更容易贴近真实场景。

打个比方:你让一个学过标准播音腔的人"自然地说话",他说出来的还是播音腔,因为这就是他掌握的"正确"表达。但你对他说"不要字正腔圆、不要刻意停顿",他反而能找到日常聊天的语感。规则集干的就是这件事——用反常识的约束,逼 AI 脱离训练数据的"标准值"

说回实践。这套规则集的内容可以大体分成四个维度,我在接入之后逐条验证过,下面按对我的实际影响从大到小排列。

2.1 注释规则:从"过度解释"到"只在必要处说话"

这是最大的痛点,也是规则集效果最明显的地方。默认情况下,AI 生成的代码注释密度是我的三到五倍。它的典型病态表现有三种:

第一种,函数头注释。AI 喜欢在函数上方写// 获取用户列表数据然后跟一个getUserList的函数名,这是典型的废话文学。第二种,行内注释解释逻辑,明明代码已经写得很直白,非要加一句"这里判断用户是否有权限"。第三种,区块注释充当小标题,把代码按照功能切块,每块加一段注释,仿佛在写论文。

规则集对注释给出的约束是:只有三种情况才需要写注释——业务逻辑复杂、命名无法消除歧义、存在隐性的约束条件(比如某个接口的返回字段可能有坑)。这个规则本质上是在模拟一个资深老手的习惯:不是不写注释,而是把注释留给真正需要解释的地方

接入规则之后我做了个对比测试,让 AI 用相同需求生成了一个订单列表组件。没有规则时,注释占了整个文件行数的三成以上;有规则之后,注释总共三处,每处都在刀刃上——一处解释了一个为什么不能直接用filter而要手动循环的坑,一处标注了后端接口在某种边界条件下会返回空数组的兼容逻辑,还有一处解释了状态更新为什么用了函数式写法。这个变化让代码的可读性肉眼可见地提升了。

2.2 命名规则:拒绝"教科书式"变量命名

AI 的命名风格有一个明显的倾向:把变量的用途完整地塞进名字里。一个布尔值它倾向于叫isUserLoggedIn,实际上在局部作用域里loggedIn就够了;一个临时数组它倾向于叫filteredUserDataList,实际上叫items或者result更自然。

这套规则集对命名的约束很明确:变量名长度与作用域大小正相关——作用域越小,名字可以越短;作用域越大,名字要越有信息量。这是一个非常符合真实编码习惯的原则。局部三行代码里的临时变量,listitemeli都完全没问题,反而会让代码更清爽。而模块级别的常量、跨组件使用的 Props,则需要完整的语义化命名。

规则顺手还治了一个毛病:AI 特别喜欢给函数名加动词前缀handleClickhandleSubmithandleChange……这套命名在真实项目里不是不能用,但用多了非常腻。规则鼓励按照实际语义去命名——比如按钮点击后要打开弹窗,与其叫handleButtonClick,不如叫openModal,语义更直接。

2.3 结构规则:用"最直白的方式"解决问题

AI 在面临一个问题时,倾向于选择"工程上更正确"的解法,而不一定是"读起来最顺畅"的解法。举个典型例子:内部状态管理,AI 倾向引入 reducer 或者状态管理库;一个两层的组件嵌套,AI 倾向于抽象成三个文件加一个双向绑定;一个只有两处使用的公共函数,AI 倾向于拆到 utils 文件并且加上单元测试。

不是说这样不对,而是在一个真实的业务项目里,这种过度设计恰恰是维护成本的主要来源。规则集的思路是:在所有可行方案里,优先选择代码行数最少的方案,除非存在明确的扩展需求或团队约定,否则不做超前抽象。

这背后是一个很实际的经验法则:代码不是写给机器看的,不是写给未来的架构师看的,是写给下周就要在同一个文件里加需求的同事看的。一个需要跳三个文件才能理清逻辑的实现,即使类名和函数名再规范,也不如一个 50 行的直白组件来得实用。

2.4 行为规则:从"回答"到"追问"

这个维度不影响代码风格,但影响协作体验。默认情况下,AI 在面对不清晰的需求时,倾向于"猜一个最合理的方案然后直接开写"。这在代码生成阶段问题不大,但在代码修改阶段会产生麻烦——它可能在错误的数据流假设上构建整个修改方案。

规则集要求在需求描述不完整时先提问,而不是直接写出完整方案。这是个看着简单但实际很关键的约束,它改变了 AI 的工作模式:从"生成器"变成了"协作者"。虽然这会多一轮交互,但避免了返工,长期看效率反而更高。

3. 从"读规则"到"用规则":我建议这样接进工作流

这套规则我用了四周,覆盖了一个中型后台管理系统的日常迭代和两个从零开始的功能模块。接入路径按照你用的工具不同会有一点差别,我分别说。

3.1 Cursor / Windsurf / Trae 系:项目级 Rules 配置

这一类 AI 编程 IDE 都支持在项目根目录维护一个规则文件,Cursor 里是.cursorrules或者新版支持的 Rules 配置面板,Windsurf 是.windsurfrules,Trae 类似。把规则内容放进去之后,对话里的每一次请求都会自动携带这份上下文。

我的建议是不要把项目里所有规则都堆在一个文件里,一个文件塞太多约束,AI 会"注意力稀释",反而每条都遵守不到位。正确做法是按触发场景拆分:

  • 全局规则(始终生效):代码风格、命名习惯、注释标准、文件结构偏好。
  • 项目规则(按项目生效):比如当前项目的目录组织方式、组件库选型、接口请求封装约定、状态管理方案。
  • 任务规则(按任务临时注入):比如"当前任务只涉及这个目录下的文件,不要修改其他模块""本次目标是重构,不要新增功能"。

这套规则集的定位就是全局规则层,它替代掉你原来在系统提示词全局 Rules里写的那一堆"你是一个资深前端工程师"之类的空话。

3.2 Claude / ChatGPT / 各种 API 调用:System Prompt 注入

直接在对话开始时把规则内容作为 System Prompt 传入。这种方式适合使用 Continue、Cline、Aider 这类开源编程工具,或者直接通过 API 做自动化代码生成任务的场景。

我实验过几种商品化模型的差异:对 Claude Sonnet 系列效果最明显,因为它本身代码生成质量已经很高,缺的恰恰是"人性化"这一层;对 GPT 系列效果中等,因为它在遵循长文本指令时倾向于"选择性重视"前几条规则,所以实测下来把注释规则放最前面效果最好;对 DeepSeek 这类开源模型效果也还行,但因为它默认生成的代码质量跟 Claude 还有差距,所以规则的作用更多是"纠偏",是从 70 分到 80 分,而不是从 85 分到 95 分。

3.3 规则放进去,不等于完事了

这是我想重点强调的经验:规则注入只是第一步,你必须花时间调教它

第一轮我直接把规则原封不动丢进 Cursor,结果很快发现问题——AI 在"减少注释"这条上矫正过枉,一些本应该有注释的业务逻辑也不写了。比如有个兼容性处理,我看了半天没看懂为什么要这么做,问 AI 才知道是某个低版本浏览器的事件处理差异。

不能怪规则,规则本身说的没错——"注释要少而精",但 AI 在执行时把握不好"精"的标准。解决办法是在规则里增加正反案例。我在注释规则后面追加了一句:如果代码里包含"某个 API 在特定环境下表现异常"或者"某个修复是为了兼容特定场景",必须在对应代码行上方用注释说明原因。

这个细节很关键:规则集的本质是"偏好表达",你花时间给它补充团队自己的案例,后期收益是复利的——每一次对话都在同一个偏好空间里生成。这个做法比任何"置顶消息"或"每次开头重申要求"都管用。

4. 拆开细看:这套规则对前端代码的具体约束长什么样

规则文件里的内容条数不少,但每条都有它对应的"AI 病态行为"。我挑几条实际效果最明显的,配合 AI 的原生表现和规则约束后的表现做个对照,你会更清楚这套东西为什么管用。

原生 AI 的典型行为规则约束后的表现影响面
每个函数上方写 JSDoc 注释,注释量与代码量比接近 1:3只在业务逻辑复杂、命名有歧义、有隐性约束的地方留注释全局可读性
组件内部用const handleXxx = () => {}定义大量事件函数,中间隔着一堆 return事件逻辑简单时直接内联在 JSX 中,复杂时提取为局部函数代码行数与阅读流畅度
函数式组件里一个 useState 对应一个状态,状态多了产生十几个 useState相关的状态用对象聚合,非相关状态才拆开状态管理可读性
一个取数据逻辑同时出现在多个组件中,AI 内置"提取自定义 Hook"的冲动Dan 原则:同一个逻辑出现第 3 次之前不做抽象避免过早抽象
命名全部"规范到无趣",filteredItemsprocessedDataupdatedList局部变量允许短名,全局变量保证语义完整代码个性
遇到任何重复片段都会立即提取公共组件,无论使用频率提取公共组件的条件是至少被 3 个位置使用,或者 2 个位置且有明确变更趋势组件粒度
在处理事件时同时考虑捕获冒泡、事件委托等高级话题默认采用最简单的事件绑定,除非有明确性能需求框架使用习惯
自动为所有函数添加@param@returns标记仅在文件顶层导出函数上保留必要 JSDoc注释精简
过度使用useMemouseCallback包裹所有函数默认不用,只有 Profiler 实测性能瓶颈后再考虑性能优化的"否则不优化"原则

这些约束用一句话总结:把 AI 从"教科书模式"切换成"业务老兵模式"

以一个实际的前端页面为例——用户管理列表页,功能包括搜索、分页、批量禁用、单条编辑弹窗。AI 原生生成这个页面,大概率是:一个巨型组件文件,顶部 import 至少五个 UI 组件,组件内部有const [loading, setLoading]系列状态、fetchUserList系列异步函数、handleSearch系列事件函数、一个搜索表单、一个数据表格、一个编辑弹窗。整体质量尚可,但读起来像一份"标准答案"。

应用规则之后,AI 会先问你几个问题:这个页面是独立页面还是弹窗内嵌?搜索参数需要同步到 URL 吗?编辑弹窗是复用同一个组件吗?拿到这些信息后,它生成的代码会更有针对性——比如搜索表单和表格状态可以放在一个自定义 Hook 里,弹窗组件单独提取,但只因为它在整个项目里会被二次使用;函数命名从handleSearchConfirm简化为searchonSearch;注释几乎为零,只在接口返回数据需要做兼容处理的地方留一句说明。

这两种代码的差别不是"质量高低"的差别,而是**"看起来像 AI 写的"和"看起来像团队里资深同事写的"的差别**。

5. 让 AI 代码更像"人写的":三个实战测试和真实效果

光说规则内容不够,我做了三个不同的实测场景,结果比较有说服力。

5.1 场景一:给 AI 一段项目代码,让它模仿风格写新功能

我准备了一个真实的项目文件——一个中后台系统的订单管理模块,包含列表、筛选、导出、详情抽屉。这个模块的特点是:函数命名趋向简洁、注释极少、业务逻辑集中在自定义 Hook 里、UI 层很薄。

我把这个文件作为参考上下文发给 AI,要求它在这个项目里实现一个类似的"退款管理"模块。没有规则时的输出:结构清晰,但注释偏多,变量命名过于"标准",处理逻辑全部堆在组件里,没有按照原项目的风格把数据逻辑抽到 Hook。有规则时的输出:函数命名跟原项目风格保持一致,注释只在退款异常分支里出现,数据请求逻辑抽到了useRefundListHook 中,整体融合度明显提升。

这个场景很实用——规则集不仅影响 AI 怎么写代码,还能让它更好地"模仿"你的项目风格,二选一的输出直接能说明问题。

5.2 场景二:同一需求用不同模型生成,对比结构差异

我用同一个需求,"实现一个带搜索和分页的用户列表页",分别在 Claude 和 Cursor 内置模型上测,一个带规则一个不带。

不带规则的两个版本,注释行数占总行数的 22% 和 19%,都出现了三处以上的"解释代码本身"的无效注释;变量命名几乎一样,fetchUserListuserListDatafilteredUsers——翻来覆去这一套。带规则之后,注释行数降到 5% 以下,命名在局部作用域出现了itemsrows这类短变量;结构上的最大变化是去掉了无意义的loading状态拆分,直接用单一状态对象管理页面态。

有意思的是,带规则生成的代码反而更短了。同一个功能,不带规则的版本平均 280 行,带规则版本大约 210 行,少了四分之一。这个减少全部来自冗余注释、不必要的状态拆分、过度抽象和样板代码。

5.3 场景三:让 AI 在"已有代码基础上改需求"

这是日常开发里最常遇到的场景。我给 AI 一段既有代码,要求"把列表的筛选条件从单选改为多选"。不带规则时,AI 直接把筛选逻辑改成了接收数组的方式,同时把相关的提交函数、重置函数、查询参数全部改成数组结构,连带接口调用参数都改了——它把改动波及面扩大了很多。

带规则后,AI 先评估了改动影响范围,选择了兼容做法:内部仍然使用字符串参数,在提交前把数组 join 成字符串。改动的代码行数从 40 行降到了 12 行,而且不影响其他调用方。

这个场景让我意识到一件事:规则集带来的最大收益不是代码风格的提升,而是"最小化改动"的思维。AI 在没有人提醒时,倾向于"重写"而不是"修改",这对一个庞大的老项目来说是非常危险的——你不知道改一个函数签名后面会牵连多少地方。规则集通过约束(当前任务未明确要求的部分不得改动)有效抑制了这种冲动。

6. 折腾四周后,这套规则的边界在哪里

我不太喜欢把开源项目说得神乎其神,尤其是提示词类工具——它的效果依赖上下文、工具版本、模型能力,甚至你写需求的方式。这套规则集我也发现了几个明显的边界和注意事项,给你的判断提供参考。

6.1 对代码质量的上限提升有限

规则集解决的是"风格"和"习惯"问题,不是"能力"问题。如果 AI 本身的理解能力不足,比如复杂的业务逻辑拆解、架构方案设计、跨模块影响分析,规则集帮不上太多忙。它就像一个严格的新人导师,能让新人不犯低级错误,但做不了高级设计决策。

我的判断标准是:如果 AI 生成的代码质量本身不到 75 分,规则集带来的收益可以忽略——这时候你更需要的是换一个更强的模型,而不是给它立规矩。规则集只对已经能写"好代码"、但带着"机器味"的模型有立竿见影的效果。

6.2 规则数量不是越多越好

我最早把它当作"兵书",把所有条款一次性全塞进上下文,效果反而变差。AI 在长上下文中的指令遵循是有"注意力上限"的,一条规则被遵守的概率跟它在文本中的位置和临近内容有很大关系。

我的经验是:一个项目的规则集控制在 15 条左右,超过 20 条就开始出现"某些规则被忽略"的现象。重点是抓最影响代码风格的核心维度,而不是把所有细枝末节都固化成规则。

6.3 规则需要"因地制宜"地改造

不同团队、不同项目的代码风格差异非常大。这套规则集描述的是"通用的人味",但你的团队可能有自己的特殊偏好。比如有的团队就要求所有函数必须有 JSDoc,因为要自动生成文档;有的团队内部已经约定用handleXxx作为所有事件函数前缀。

这种情况下,直接套规则反而会跟团队规范冲突。正确做法是把规则集当作底稿,把自己团队的代码规范文档喂给 AI,让它"学习"团队自己的风格。我更推荐的做法是:在规则集基础上,追加一份 100 到 200 字的"团队补充规范",描述你们特有的约定,效果比删改规则内的条款更稳定。

6.4 版本兼容问题

这套规则是围绕 Claude 的交互习惯设计的,在 Cursor 等工具上使用时要留意两个坑:一是部分工具的 Rules 文件默认注入位置在对话上下文的最前面,有些工具在尾部——位置不同,约束效果也会有差异,实测放在靠前的位置更有效;二是不同模型对 Markdown 格式的规则文件解析方式不同,如果你的模型对---分隔线、加粗标题解析不稳定,我建议把规则文件改成纯文本格式,一行一条,减少格式干扰。

7. 一套够用的规则,应该长成什么样

规则集的完整内容你可以直接在开源仓库里拿到,我不在这里全文复制。不过有一点我觉得值得做——在完整规则之外,我自己维护了一份"精简版",覆盖了日常开发中最影响代码"人味"的五条核心约束。这份精简版我贴在下面,你可以直接拿去用,作为最基础的规则起点:

1. 不解释代码在做什么,只注释代码为什么这样做。函数名和变量名应该已经说明了前者。 2. 注释只写三种:复杂业务逻辑的原因说明、隐性的接口约束和兼容性说明、命名无法消除歧义的地方。 3. 局部变量使用短命名,作用域越小名字越短。全局常量、Props、导出函数保持完整语义化名称。 4. 优先最简单直白的实现。同一个逻辑出现第三次之前,不做抽象,不提取公共组件。 5. 事件函数按业务语义命名,而不是统一用 handleXxx 前缀。比如打开弹窗就叫 openModal 而不是 handleModalOpen。

这五条看着简单,是我认为"人写代码"和"AI 写代码"最大的五个分野。你把这条精简版先放进 Cursor 试一天,再回到默认状态,立刻能感受到差别。

再强调一个容易被忽略的点:规则集要周期性维护。AI 编程工具的模型在快速迭代,模型的行为特征也在变化。三个月前管用的规则,新模型上可能已经不需要了;新模型可能会出现新的"机器味"行为,又要补充新规则。这套规则集在开源社区里能持续更新到 4.8K Star,说明作者一直在跟进模型的迭代节奏。

我个人的做法是每两周做一次"规则体检"——随便挑一个需求让 AI 生成一段代码,扫一眼有没有跑偏,有就跑偏的地方倒推回规则文件里改。这套反馈闭环比规则本身更重要,它能保证你的规则集始终跟 AI 的行为同步,而不是停留在某一个版本的快照上。

最后说个实在的:规则集不是银弹,它不会让 AI 一夜之间写出"人味十足"的代码,但它能把 AI 的默认行为从"标准答案"拉向"真实世界"。配合好的模型、清晰的需求、合理的 Review 流程,你完全能把 AI 从一个"效率高但格格不入的新人",调教成"干活不让人操心的老手"。这中间的差距,就是用这套规则一点点磨出来的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询