简体中文 | English
如今 AI 的能力越来越强,很多程序员已经很少手写代码了。我本人也一直在使用 OpenAI 家的模型,但是长期使用下来,还是发现现在的模型远没有达到把代码当成“黑箱”,只提需求就能让项目稳定运转的程度。
就我使用 GPT 系列模型的体验而言,它确实能完成很多当下的任务。互联网上也有很多人晒出用 GPT 做的各种作品,看起来非常惊艳。但是自己拿它做一个需要长期维护的项目,就会发现:做出一个可以演示的“玩具”,和做出一个能上线给别人使用、还能持续迭代的产品,中间还有很长的路。
B 站上有一个视频:《GPT 6 Astra:一个平庸、沉闷、没有品味的模型》。这个评价很贴近我的使用感受。让我觉得 GPT “平庸”的地方,是它经常只顾着完成眼前的任务,缺少工程师对整个项目的长远考虑。它可以用一堆代码把功能实现出来,但是代码应该怎么组织,哪些概念应该放在一起,哪些地方应该留下清楚的边界,它往往考虑得不够。需要添加功能,就继续打补丁;发现 bug,也在局部打补丁。每次看起来都解决了问题,整个代码仓库却越来越难读、越来越难改。
这会带来一个严重的问题:AI 的能力也是有限的。当它面对一个严重的“屎山”时,分析和拆解代码本身就会占用大量精力。关系越混乱,它越容易只理解局部,再往局部添加补丁。最后,在同一个代码仓库里,后续生成的代码质量越来越差,直到连原本能够完成的任务也做不动了。我认为代码的可读性会直接影响人和 AI 接下来还能不能继续把这个项目做好。
我认为现在模型的“软实力”还没有得到足够的重视。这里的软实力,包括模型的审美能力。我说的审美,是设计代码时有没有合理的编排,变量命名能不能表达含义,函数的职责和排布是否清楚,主流程能不能一眼看懂。这些都关系到别人接手时能不能读懂,以及下一次修改需要付出多大的代价。
大家都在刷榜,都在强调模型的“硬实力”:能解多难的题,能完成多少任务。每次模型发布,官方都在宣布能力有了怎样的飞升,互联网上也到处是“一轮对话生成 xxx”。但是实际工程中的使用体验,和这些展示经常差得很远。我觉得其中一个原因,就是展示里的任务完成了,工程里的事情却才刚刚开始。一个真正能提升生产力的工具,需要经得起长时间的修改、扩展和打磨。没有一个良好的审美,又怎么能把产品持续迭代下去?
所以,在模型还不能让我们完全不看代码就做出优秀产品的阶段,人仍然需要介入审查,确认功能实现是否符合预期。这就要求模型至少能写出“便于人类阅读的代码”。但是长期使用 GPT 的体验是,它在不受约束的情况下,经常把代码写得很难读:函数名称隐晦,没有实际意义的封装带来反复跳转,大量 try/except 和重复检查穿插在主逻辑中。功能看起来做出来了,读代码的人却要先绕过一层层防御和包装,才能找到程序真正想完成的工作。
我希望更多开发者和 AI 公司在评估、训练模型时能够“用两条腿走路”。能把任务做出来很重要,能把代码写得让人愿意接手、愿意继续维护,也让模型在多轮迭代之后还能维护,同样重要。不要顾此失彼。
Readable Code 包含两个可以分别安装的 skills:
readable-code-generate:生成与修改约束。 在写代码的时候提醒模型保持主流程清楚、状态容易追踪、封装有实际收益,避免无依据的防御和自建校验。对异常、hash、SDK 能力、留白和修改范围给出具体判断方法。readable-code-review:阶段评审。 在一个阶段完成后,让模型按八个维度检查已经交付的代码,给出分数、源码证据和整理建议。
两个 skills 可以配合使用:写的时候保持清楚,写完后再回头检查。readable-code-generate 允许自动调用,列表描述要求模型每次编写或修改代码前读取。readable-code-review 关闭自动调用,需要用户显式指定。日常生成不需要每次输出一张评分表;阶段评审需要真正读代码、核实关系,再作判断。
readable-code-review 是一个在开发阶段结束后使用的代码可读性评审 skill。我把经典软件设计书籍、作者博客和工程规范里的原则整理成了八个维度,让模型回过头检查自己交付的代码:名称是不是表达了真实职责,主流程是不是清楚,状态是不是容易追踪,函数和模块的划分到底有没有帮到读代码的人。
我希望它能把“这段代码看着不舒服”变成一个可以讨论、可以修改的问题。模型需要指出具体代码,说明它让读者多做了什么工作,再给出分数和整理建议。比如,一个辅助函数只是把参数转交给下一层,那么就要解释这层包装有没有独立的含义;一段异常处理穿插在主流程中,也要先看它有没有实际用途,再看它的摆放是不是妨碍阅读。
目前这套标准以 Python 为起点,可以评审一个文件、几个模块,也可以评审整个代码库。检查范围是可读性和结构维护成本,功能正确性与测试另外处理。完整指令在 SKILL.md,详细标准在 八维评价体系。
这些问题早就有很多优秀的工程师讨论过。我主要参考了以下材料:
- Dustin Boswell、Trevor Foucher 的《The Art of Readable Code》:名称、控制流、表达式和注释怎样帮助读者理解代码。出版社目录与预览
- John Ousterhout 的《A Philosophy of Software Design》:好的设计应该减少读者需要同时掌握的信息,让重要依赖容易找到。一个接口有没有价值,要看它隐藏了多少有用的细节。作者书籍页、复杂性讲义
- Robert C. Martin 的《Clean Code》与 Martin Fowler 的《Refactoring》:名称表达意图,职责应该清楚。提取函数和内联函数都有适用场景,关键是整理之后有没有更容易理解。两位设计作者的讨论、Fowler 重构目录
- David Thomas、Andrew Hunt 的《The Pragmatic Programmer》:DRY 关注的是同一知识有没有被多处表达、需要同步维护。两段代码长得一样,并不自动意味着应该合并。DRY 官方节选
- Kent Beck 的《Tidy First?》:按阅读需要整理代码顺序,把声明和初始化放在一起,让紧密相关的内容一起被看到。代码拆得太碎时,也可以先合起来重新看清关系。Reading Order、One Pile
- David L. Parnas 关于模块分解的论文:模块应该围绕需要隐藏的知识和设计决定划分,让其他部分可以单独理解。原论文
我还参考了 Martin Fowler 关于领域语言和流式接口的文章、Carson Gross 的行为局部性、Casey Muratori 的语义压缩、Dan McKinley 关于技术复杂性成本的讨论,以及 Google 代码评审指南和 PEP 8。具体出处与采用方式整理在 来源说明。
这些作者也有分歧。例如函数应该多短,注释应该写多少,什么时候该拆分、什么时候该合并,就很难用一个固定数字回答。我采用的判断方式是:这份代码让接手者少猜了什么、少记了什么、少来回跳转了什么?
八个维度具体检查的是:
| 维度 | 标准 | 怎么检查 |
|---|---|---|
| D1 命名与含义 | 名称是否表达职责、角色、单位和领域概念 | 对照定义、完整实现和使用位置,检查同词多义、含糊名称,以及名称没有覆盖的实际职责。 |
| D2 主流程与控制流 | 正常路径和阶段能否顺着读下来 | 从入口追踪主要操作,检查分支、校验、异常处理和回调是否迫使读者反复拼接流程。 |
| D3 数据与状态表达 | 数据含义、状态归属和变化位置是否清楚 | 追踪关键值的建立、更新和使用,检查隐含位置约定、分散状态与不易发现的副作用。 |
| D4 抽象与职责 | 函数、类和模块的边界有没有实际收益 | 一起阅读调用者与实现,检查封装隐藏了什么,调用者又必须知道哪些内部约定。 |
| D5 共享规则与局部修改 | 同一知识的来源和修改位置是否容易找到 | 找出真正共享的规则及其使用点,检查是否需要多处同步,也检查集中化会不会增加新的负担。 |
| D6 实现直接性与机制必要性 | 额外检查、包装、分发和回退是否值得存在 | 根据当前任务、输入边界和已有保证判断用途,比较机制带来的收益与新增的理解成本。 |
| D7 注释与文档的信息价值 | 文字有没有补充理解需要的信息 | 检查原因、背景和接口约定是否容易找到,以及复述语法的文字有没有盖住重点。 |
| D8 局部表达与逻辑分段 | 表达式、语句分组和阅读顺序是否帮助理解 | 检查读者需要在脑中拆解哪些关系,相关语句是否放在一起,中间变量和留白是否表达了阶段。 |
八维的划分、检查步骤和评分档位,是我根据这些材料整理出的工作标准。分数采用 0—3 四档:
| 分数 | 含义 |
|---|---|
| 3 | 重要含义与关系清楚,没有发现实质阅读障碍。 |
| 2 | 整体能理解,但存在实质的局部阅读负担。 |
| 1 | 重要关系需要明显的额外追踪,影响接手和维护。 |
| 0 | 核心含义或组织严重不清楚,基本理解很困难。 |
不适用或缺少必要背景的维度会单独说明,分数记为 null。八项分别报告,我更关心哪一处关系需要整理,不把它们平均成一个总分。
使用 skills.sh 的安装工具,可以一次安装两个 skills:
npx skills add Chengyf2004/readable-code也可以分别安装:
npx skills add Chengyf2004/readable-code --skill readable-code-generate
npx skills add Chengyf2004/readable-code --skill readable-code-review在 Codex 中,也可以让内置安装器安装对应目录:
$skill-installer 请安装 https://github.com/Chengyf2004/readable-code/tree/main/skills/readable-code-generate
$skill-installer 请安装 https://github.com/Chengyf2004/readable-code/tree/main/skills/readable-code-review
也可以把需要使用的目录复制到项目的 .agents/skills/ 下,保留 SKILL.md、agents/ 和 references/ 的相对位置。
阶段评审会消耗一定量的 token,也会多花一轮检查的时间。但是我认为,这部分成本对于后期维护一个项目是必要的。把本来就该理清的关系提前整理好,后面就能少花一些时间和 token 去反复猜测代码、追踪调用、修补局部。所谓“磨刀不误砍柴工”。
生成 skill 在日常写代码时要求模型先读取;也可以在提示词中点名。我建议在项目的一个阶段结束时调用评审 skill:一个功能已经写完、准备继续加功能,或者一轮修改之后开始觉得代码越来越绕,都是适合回头检查的时候。
完整指令分别在 生成 skill 和 评审 skill。在 Codex 中,把需要使用的 skill 整个目录放在项目的 .agents/skills/ 下,就可以通过对应名称调用。官方 skill 使用说明
生成与修改时可以这样用:
使用 $readable-code-generate 完成这次 Python 实现。
保持主要步骤和数据变化容易阅读,只处理当前任务涉及的代码。
阶段结束后再评审:
使用 $readable-code-review 评审本阶段的代码。
范围是 src/ 目录,按八个维度分别给出分数、源码位置、阅读负担和整理建议。
遇到跨函数或跨文件关系时,一起阅读相关实现。
先给评审结果,暂不修改代码。
如果使用的工具没有 skill 机制,也可以让模型阅读对应的 SKILL.md 和它引用的文件,再提供代码与任务背景。两个目录都可以独立使用。
你可以让模型检查自己写的代码,有两个模型时也可以交叉检查。在我的几次试评中,GPT 会指出自己代码里的可读性问题,有些维度给自己的分数还比 DeepSeek 给的低。所以我觉得阶段自查值得做。条件允许时,可以另开会话,只提供代码、任务背景和标准,让评审集中在当前实现上。
我最看重的是它指出的问题是否成立,以及整理之后是不是真的更容易读。 模型应该告诉你哪里需要来回追踪、哪个名字容易误解、哪层封装没有帮到调用者。一个可以改得更好的地方,是否已经造成实质负担,也需要说明清楚。只给一个分数,或者泛泛地说“建议提高模块化”,很难帮助你继续维护代码。
看完评审后,可以再让模型处理你认可的问题:
根据这份评审,优先整理影响主流程和状态追踪的问题。
保留现有功能、接口和失败处理策略,只修改相关代码。
完成后复核涉及的维度,说明哪些阅读负担减少了。
我希望这能成为一个长期使用的习惯:写完一个阶段,回头看一遍,把关系理清楚,再继续往前走。让代码一直保持在人和模型都能接手的状态,项目才有机会越做越好。
MIT。两个独立安装的 skill 目录都附有许可证。