
最近在 GitHub 上闲逛时频繁看到一个项目名“I do read AI code”。它起初看起来像是一句程序员对 AI 的赌气式回应但点开 README 后会发现这更像是一份面向 AI 时代开发者的“宣言”。随着 Claude Code、Cursor、各类 AI 编程助手逐渐进入日常开发流程这个项目引发讨论的时机非常微妙它表面上是“反 AI 生成代码”实际上是在提醒我们一个更底层的问题——在 AI 可以快速产出代码的时代你是否还具备认真阅读代码、判断代码质量的能力这篇文章不打算站队说“AI 代码好”或“AI 代码坏”而是围绕这个现象做一次系统拆解它到底说了什么、为什么引发开发者共鸣、它本身又为什么会成为一个值得玩味的文本样本。同时会结合代码审查、AI 编程工具使用、CI 拦截等工程实践给出一些可以落地的方法。适合正在使用 AI 编程工具、参与开源项目维护、或者对 AI 生成代码质量有困惑的开发者阅读。1. “I do read AI code” 是什么1.1 一个 README 引发的热议“I do read AI code” 这个项目本身是一个开源仓库但真正让它传播开来的是仓库 README 开头的一段声明。大意是作者表示自己确实会仔细阅读 AI 生成的代码而不是盲目接受 AI 给出的补丁或 PR同时呼吁其他维护者也保持同样的态度不要因为 PR 来自 AI 工具就放松审查标准。这个表述之所以能在开发者社区快速传播是因为它精准踩中了当下几个真实痛点开源维护者每天收到大量由 AI 生成的 PR数量上去了质量却参差不齐。企业团队全面引入 AI 编码工具后Code Review 的压力不降反升。很多 AI 生成的提交提交者本人甚至没看过 diff 内容就直接点了提交。从某种意义上说“I do read AI code” 并不是一句技术说明而是一种态度声明在大家都在讨论“AI 能不能写代码”的时候它把问题拉回到了“人还要不要负责”这个层面。1.2 它戳中了谁的痛点这个项目引发共鸣说明“阅读 AI 生成的代码”已经成为一类普遍需求开源维护者需要审查来自陌生人的 PR而 AI 工具降低了提 PR 的门槛也带来了大量低质量提交。团队技术负责人需要保证 AI 辅助编码不会破坏代码库的一致性和稳定性。刚入行的开发者往往会把 AI 生成的代码视为“标准答案”缺少验证和质疑的能力。需要注意的是这个项目并非反对使用 AI而是反对“不读代码就合并”的工作方式。这个区分很重要否则容易把问题简单理解成“AI 编程工具 vs 人类程序员”的对立。2. AI 生成代码的真实问题2.1 低质量 PR 的三个典型特征根据我在日常 Review 和开源社区观察到的现象AI 生成代码引发的低质量 PR 通常有三个典型特征特征一缺乏边界条件处理AI 模型擅长从训练数据中学习“主路径”代码也就是最常见的 happy path但往往忽略异常分支。比如一个读取 CSV 文件的函数AI 可能会处理正常数据却不会考虑文件为空、某列为空、或者列名大小写不一致的情况。特征二没有配套测试很多 AI 生成的代码只提供“功能实现”不提供单元测试或集成测试。在一些提交中即使函数逻辑有明显问题也因为没有任何测试而难以被发现。特征三不理解现有架构只是“拼”出能运行的代码AI 生成代码时往往会参考当前文件的上文和常见模板但它很难理解整个项目的分层架构、依赖方向、历史演进原因。结果就是代码能通过编译但放在项目里显得很“突兀”不符合现有设计风格。2.2 一个对比示例AI 生成 vs 人工修正为了更直观地说明问题这里用一个简单的场景做对比。假设我们需要一个函数从 CSV 文件中读取一列数值并返回平均值。AI 初版可能长这样# 文件路径src/stats.py import csv def average_from_csv(file_path, column_name): with open(file_path, moder, encodingutf-8) as f: reader csv.DictReader(f) values [float(row[column_name]) for row in reader] return sum(values) / len(values)这个版本在理想情况下可以运行文件存在、列名存在、所有值都是数字、文件非空。但只要任何一个前提不成立它就会抛出异常。比如CSV 文件为空len(values)为 0触发ZeroDivisionError。某一行的目标列是空字符串float()抛出ValueError。列名不存在访问row[column_name]抛出KeyError。人工修正后的版本# 文件路径src/stats.py import csv from statistics import mean from typing import List, Optional def read_numeric_column(file_path: str, column_name: str) - List[float]: 读取 CSV 中指定列转换为 float 列表。 会跳过空值遇到无法转换的数据时抛出自定义异常。 values [] with open(file_path, moder, encodingutf-8) as f: reader csv.DictReader(f) if column_name not in reader.fieldnames: raise ValueError(f列 {column_name} 不存在) for row in reader: raw row.get(column_name, ).strip() if not raw: continue try: values.append(float(raw)) except ValueError: raise ValueError(f无法将 {raw!r} 转换为数字) return values def average_from_csv(file_path: str, column_name: str) - Optional[float]: 计算 CSV 指定列数值的平均值。文件为空或没有有效数字时返回 None。 values read_numeric_column(file_path, column_name) if not values: return None return mean(values)对应的测试# 文件路径tests/test_stats.py import csv import tempfile from pathlib import Path from src.stats import average_from_csv def create_csv(tmp_dir: Path, rows): file_path tmp_dir / data.csv with open(file_path, w, encodingutf-8, newline) as f: writer csv.writer(f) writer.writerow([name, score]) writer.writerows(rows) return file_path def test_average_normal(): with tempfile.TemporaryDirectory() as tmp: file_path create_csv(Path(tmp), [(a, 90), (b, 80)]) assert average_from_csv(file_path, score) 85.0 def test_average_empty_column(): with tempfile.TemporaryDirectory() as tmp: file_path create_csv(Path(tmp), [(a, ), (b, 80)]) assert average_from_csv(file_path, score) 80.0 def test_average_no_valid_data(): with tempfile.TemporaryDirectory() as tmp: file_path create_csv(Path(tmp), [(a, ), (b, )]) assert average_from_csv(file_path, score) is None对比之后能明显看到修正版的代码量更大但处理了空值、缺列、无法转换等多种边界情况并且用测试把这些行为固定下来。这种差异在真实项目中会被放大当 AI 生成 500 行代码时如果没有边界处理和测试后续维护成本会非常高。2.3 为什么“能跑”不等于“能合并”很多人看到 AI 生成的代码能运行就觉得“可以了”。但在工程实践中“能跑”只是最低标准。真正的合并标准至少包括可读性代码结构和命名是否清晰其他人能否快速理解。可维护性后续修改时改动是否可控。边界完备性异常分支是否被考虑。安全性是否存在注入、敏感信息泄露等风险。测试覆盖核心逻辑是否有配套测试。架构一致性是否与现有模块划分和依赖方向一致。AI 工具目前最擅长的是“把输入转换成看起来正确的代码”它最不擅长的是判断这段代码在长期演变中是否合理。这个判断只能由人来完成。3. 有趣的分析这段“反 AI 声明”为什么像 AI 写的3.1 文本特征拆解这里有一个值得玩味的细节“I do read AI code” 的 README 本身如果从文本特征来看反而很像 AI 生成的内容。为什么这么说可以观察以下几方面情绪化标签重复声明中大量使用“人类”“真正”“盲目信任”“负责任”等词汇。这些词本身没有错但在文本中密集出现时会形成一种“口号感”。句式模板化典型结构是先描述 AI 代码泛滥的现象再表达担忧最后呼吁人类开发者承担责任。这种“现象—担忧—呼吁”的三段式结构在 AI 生成文本中非常常见。缺乏具体的项目细节一篇由真实维护者写的 README通常会有对项目本身的描述、使用方式、具体设计决策。但这段声明更像是一份独立的立场文件没有绑定到某个具体项目的技术细节。不是说作者真的是 AI而是说当 AI 学会了大量“批判 AI 生成代码”的语料后它也能生成类似风格的文本。这本身就反映了一个重要问题——我们很难仅凭文本风格判断一段内容是真人写的还是 AI 写的。3.2 当 AI 学到的“反对 AI”也成了模板AI 模型的训练数据来自互联网包括技术博客、GitHub README、讨论区。在这些数据里有大量关于“AI 生成代码需要人类审查”的讨论。因此当被要求“写一段反对盲目使用 AI 代码的声明”时模型很容易生成语气相似、立场相近的文本。这不是模型在“伪装”而是语言模型的固有特性它擅长的是概率性复现而不是基于真实经历下判断。讽刺点就在这里一段呼吁人类要认真负责的文本本身可能是由没有“认真负责”能力的模型生成的。3.3 这个案例给我们的提醒这个现象给开发者的真正提醒是无论是代码还是文档判断依据应该是内容本身的质量而不是作者标签。面对一段声明、一个 PR、一个技术方案要回到证据层面diff 是否合理、测试是否通过、设计是否成立。不要因为一段话说得“有道理”就全盘接受也不要因为某个项目标榜“我读代码”就认为它的代码一定可信。“我会读 AI 代码”是一句好的口号但口号不能替代具体的 Review 动作。4. AI 时代如何正确地“读代码”4.1 读代码的三个层次在 AI 生成代码逐渐成为日常的情况下“读代码”的能力需要被重新强调。我习惯把读代码分成三个层次第一层语法层这个层级的任务是确认代码能运行、没有低级错误。AI 工具在这层通常表现不错因为它擅长生成语法正确的代码。对人工审查来说这层只是起点。第二层逻辑层需要理解代码在什么条件下会走哪条分支状态如何变化边界条件是否覆盖。这一层需要阅读者具备一定的调试和推演能力。AI 生成的代码经常在这一层出问题。第三层架构层要看代码是否与现有项目风格一致是否有过度设计是否引入不应该出现的依赖是否破坏了模块边界。这一层需要阅读者对项目全局有理解也是目前 AI 工具最薄弱的环节。4.2 审查 AI 生成代码的清单如果你正在审查一个由 AI 生成或由 AI 辅助完成的 PR下面这份清单可以帮你提高效率检查维度具体问题通过标准业务前提代码是否满足真实业务场景而非理想输入能说出代码对应哪条业务链路异常处理空值、超时、网络抖动、资源缺失是否处理有明确的异常分支不依赖默认行为测试配套是否有单元测试或集成测试测试覆盖主路径和关键边界依赖控制是否引入了新的第三方库新依赖有明确理由无多余引入配置安全是否新增或修改了配置文件不包含密钥、Token、数据库密码等敏感信息架构风格是否遵循现有分层和命名规范代码放入正确模块不越层调用可读性函数名、变量名、注释是否清晰不需要向作者提问就能看懂意图4.3 给代码审查者的工作流建议实际操作中建议按照下面的顺序进行审查先读 PR 描述和关联 issue明确改动目的。只读 diff尝试判断每处改动的必要性。打开上下文文件确认改动在整体结构中的位置。运行相关测试观察是否覆盖关键逻辑。对不理解的地方要求提交者给出解释而不是自己猜测。如果 AI 生成的代码量较大要求提交者拆分成更小的 PR便于审查。5. AI 编程工具的正确使用姿势5.1 当前 AI 编程工具链概览目前常见的 AI 编程工具大致可以分为几类编辑器内生成工具如 Cursor、VS Code 中的 AI 插件在编码过程中提供自动补全和函数生成。终端代理工具如 Claude Code在命令行中根据自然语言指令完成跨文件修改。代码检索与问答工具帮助理解仓库结构、解释某段代码的逻辑。不同工具的配置方式差异较大版本更新也很快。这里不展开某个具体工具的安装步骤而是强调一个通用原则任何 AI 工具的输出都只是候选方案不是最终答案。如果你在配置 Claude Code 或 Cursor 时遇到问题建议优先查看官方文档而不是直接搜索博客上的旧教程因为 API 授权、模型版本、配置格式经常变化。5.2 推荐的工作流prompt 要求 CI 拦截 人工审查要让 AI 编程工具真正提升效率而不是制造更多“需要返工的代码”可以尝试下面的工作流。第一步在给 AI 的指令中明确要求测试和边界说明。一个有效 prompt 示例请为 src/order.py 新增函数 apply_discount(order, discount_rate)。 要求 1. 返回新订单对象不修改原对象。 2. discount_rate 必须在 0 到 1 之间否则抛出 ValueError。 3. order 为空时返回原订单。 4. 同时给出 pytest 单元测试覆盖正常折扣、边界值、非法值三个场景。第二步在 CI 中增加“必须通过测试”的拦截规则。以 GitHub Actions 为例# 文件路径.github/workflows/ci.yml name: CI on: pull_request: types: [opened, synchronize, reopened] jobs: test: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: 3.11 - name: Install dependencies run: pip install -r requirements.txt - name: Run tests run: pytest --covsrc --cov-fail-under80这个配置会在每个 PR 上自动执行测试并设置测试覆盖率阈值。如果某个 AI 生成的 PR 没有测试或者覆盖率不达标CI 会直接失败从而避免“无测试代码进入主干”。第三步人工审查仍然保留但审查者可以把注意力集中在架构、业务一致性和安全隐患上而不是逐行检查语法。5.3 本地配置 AI 代码助手的通用注意事项如果你要在本地配置 AI 代码助手有几点值得提醒API Key 不要写入代码仓库。建议使用环境变量或专门的配置文件并加入.gitignore。不要随意把生产环境数据粘贴给 AI 工具。例如数据库连接串、线上日志中的敏感信息都不应该直接作为 prompt 内容。不同网络环境下的访问方式不同。在配置时如果遇到网络连通问题应先确认是服务端限制、本地网络还是代理设置导致不要盲目修改系统代理。在团队中使用时要统一工具版本和规则。避免一部分人用的模型版本和参数与另一部分人差异过大导致团队内代码风格分裂。6. 常见问题与排查思路在实际使用 AI 编程工具和审查 AI 生成代码的过程中下面这些问题出现频率很高。问题现象常见原因解决思路AI 生成的代码在本地无法运行依赖版本不匹配或模型生成了过时的 API检查报错信息确认第三方库版本按官方文档修正测试通过但代码逻辑不符合业务需求只满足了 prompt 字面含义没有理解业务上下文人肉补充业务规则必要时重写核心逻辑审查时间反而变长AI 生成了大量代码且没有拆分成小 PR要求提交者拆细 PR或限制 AI 一次生成的代码量新依赖被无故引入模型为了简化实现引入了第三方库审查时检查依赖变更非必要不新增配置文件被修改了不该改的部分prompt 中没有明确限制修改范围在 prompt 中声明“只修改 XX 文件”并使用 Git diff 检查API Key 泄露到仓库配置时直接写入文件并提交立即吊销 Key删除仓库历史中的敏感信息加入 .gitignore这里特别想强调一点遇到 AI 生成代码报错时不要直接把报错信息原样抛给 AI 让它“自己改”而是先自己读一遍报错。很多时候报错信息已经说明了根因只是需要你去验证上下文。只有当你理解了报错原因你才能判断 AI 给出的修复方案是否真的合适。7. 工程实践建议让 AI 成为团队的可控变量7.1 团队制度层面如果团队准备全面使用 AI 编程工具建议先约定几条基本规则AI 参与生成的代码必须经过人工 Review。这是底线不能由 AI 自动合并。对 AI 生成的 PR提交者必须能解释每处改动。如果提交者自己看不懂说明他还没有完成审查的第一步。关键模块限制 AI 直接修改。涉及认证、支付、数据迁移、权限控制的代码应该由经验丰富的开发者亲自改动或者至少严格把关。统一 prompt 规范和代码风格规范。减少因 prompt 不一致导致生成结果五花八门的情况。7.2 个人能力层面对个人开发者来说在 AI 时代保持竞争力不是掌握更多 AI 提示词技巧而是提升以下几项能力阅读代码的能力能快速定位一个函数在项目中的调用链和依赖关系。写测试的意识在让 AI 写功能之前自己先想清楚哪些行为需要被测试固定下来。判断技术方案的能力面对 AI 给出的多种实现方案能根据项目实际选择最合适的一种。质疑输出的习惯对任何工具的输出保持合理怀疑不因为是“AI 写的”就降低标准。7.3 回到原点“I do read AI code” 这个项目之所以值得讨论不是因为它提出了多么高深的技术方案而是因为它用一句话点破了 AI 时代开发者最容易丢失的能力——认真读代码。AI 可以帮我们生成函数、写测试用例、搜索仓库、解释报错。但代码库最终要由人来维护架构决策要由人来承担后果。无论 AI 工具变得多强大“读代码”都会是程序员的基础能力之一。如果你正在尝试 AI 编程工具不妨从今天开始做个实验下一次 AI 生成代码后先不要急着运行而是逐行读一遍试着找出两到三处你希望修改的地方。你会发现这种“先读后跑”的习惯比任何提示词技巧都更能提升代码质量。打开一个 diff开始读吧。