前两篇我分别讲了两件事:当前任务的提示词应该怎样做减法,以及前端项目的上下文应该怎样按需提供。

上下文给清楚以后,是不是就可以让 Codex 直接开始写代码了?

我的答案通常还是:先别改,先读。

原因并不是 Codex 不会 Vue3,也不是它不认识 Element Plus。恰恰相反,它越熟悉这些通用技术,越容易快速补出一套看起来合理的实现。

问题在于,通用上合理,不等于放进当前项目就正确。

一个成熟前端项目真正难读的部分,往往不在语法,而在那些没有写进需求、只存在于代码关系里的事实:

  • 状态到底由页面、组合式函数还是 Pinia 维护。

  • 接口参数在哪一层转换。

  • 公共组件的默认行为被哪些页面依赖。

  • 权限是在路由、指令还是按钮逻辑中判断。

  • 异常提示已经由请求层处理,还是需要页面自己处理。

  • 某个看似重复的方法,是否为了兼容不同业务路径而保留。

如果这些内容没看清,Codex 仍然能写出代码,而且经常写得很快。真正的风险是:它可能用一套更“标准”的实现,替换掉项目里已经形成的业务约定。

所以我说的“先读代码”,不是形式上的分析步骤,而是修改前建立工程证据。

AI 会写框架代码,不代表它已经理解当前项目

我会把这两种能力分开看。

第一种是技术能力:

  • 知道 Vue3 Composition API 怎样组织状态。

  • 知道 Element Plus 表单和表格怎样使用。

  • 知道 TypeScript 类型怎样定义。

  • 知道请求、Loading、异常和分页的一般处理方式。

第二种是项目理解:

  • 知道这个仓库选择了哪一种组织方式。

  • 知道相同能力已经封装在哪里。

  • 知道哪些旧行为不能在本次任务中改变。

  • 知道修改一个局部文件会影响哪些调用方。

  • 知道项目用什么方式证明改动没有破坏现有功能。

第一种能力让 Codex 能“写出来”,第二种能力才决定它能不能“写进去”。

前端项目里最常见的返工,很多不是代码不能运行,而是代码没有进入项目原有的系统。

例如,一个页面需要增加导出按钮。通用实现可能是直接请求文件流、创建下载链接,再在页面中处理成功与失败。可当前项目也许已经有统一下载方法,负责文件名解析、错误响应识别和权限提示。

如果不先读代码,新实现也许能够下载正常文件,却会绕开项目已有的错误处理。正常路径看起来完成了,异常路径则变成新的不一致。

这类问题仅靠“请遵守项目规范”解决不了。Codex 必须先找到规范在代码里的具体落点。

跳过阅读,最容易产生四类“局部正确”

我对 AI 生成代码的一个基本判断是:局部正确很容易,全局合适更难。

修改前不读代码,最容易出现下面四种结果。

第一类:语法正确,状态归属错了

假设要给订单列表增加一个状态筛选。下面只是演示场景,不代表真实项目。

Codex 看到页面后,可以很自然地新增一个响应式变量:

const orderStatus = ref('')

然后查询时把它加入请求参数。

单看这几行没有问题。但项目里也许已经把查询条件、页码和每页数量统一放在 queryParams 中,重置、翻页、缓存恢复都围绕这个对象工作。

新变量脱离了这条状态流,可能出现:

  • 重置时忘记清空。

  • 返回页面时无法恢复。

  • 导出仍从 queryParams 取值,导致查询和导出条件不一致。

  • 页面上的筛选值与请求对象出现两个来源。

AI 没写错 Vue,它只是没有读出“状态的唯一来源”。

第二类:功能正确,项目封装被绕开

前端项目常见的公共能力包括:

  • 请求方法。

  • 消息提示。

  • 弹窗。

  • Loading。

  • 权限指令。

  • 文件下载。

  • 日期和枚举转换。

如果只读目标页面,Codex 可能看不到这些封装,便会直接使用框架或组件库的原生能力。

结果是功能能用,却多出一套实现。

这种代码最容易在审查时被一句“项目里不是这么写的”打回来。问题不在 AI 不会复用,而在任务开始时没有让它查清楚“复用对象在哪里、谁正在使用、行为是什么”。

第三类:当前页面正确,调用方被破坏

修改公共组件时,目标页面只是一个使用者。

例如给公共表格组件增加默认空值展示,如果只看当前页面,直接把所有空值统一变成“--”似乎很合理。但其他调用方可能区分:

  • 数字 0 和空值。

  • 空字符串和未返回字段。

  • 可编辑单元格的空状态。

  • 插槽已经自行处理的内容。

公共组件内部的一处默认行为变化,可能让多个页面一起改变。

这时“读代码”不能停在组件文件本身,还要查 Props、Emits、Slots、默认值以及主要调用方。否则,局部页面上的优化可能是全局回归。

第四类:正常路径正确,异常路径丢了

AI 很容易从方法名和模板结构中识别正常流程,但项目中的异常约定经常藏在更深的位置。

比如:

  • 请求拦截器已经统一提示部分错误。

  • 页面只处理需要保留输入的业务失败。

  • 取消请求不应该显示错误。

  • 组件销毁后返回的旧请求不能覆盖新页面状态。

  • 权限变化需要重新获取数据,而不是只隐藏按钮。

如果只围绕“点击按钮后成功做什么”阅读,生成结果很可能只覆盖正常路径。

这也是为什么我不会把“编译通过”当成理解项目的证据。类型系统能发现一部分错误,却不能告诉我状态责任、异常边界和业务行为是否接对。

我让 Codex 先读的,不是整个仓库

“先读代码”很容易走向另一个极端:让 Codex 把整个项目分析一遍。

这同样没有必要。

修改一个用户列表,不需要先理解所有业务模块;调整一个弹窗,不需要把整个组件库逐个总结。阅读范围应该围绕当前行为逐层扩展。

我通常从下面六个入口开始。

1. 项目规则

先看当前任务适用的 AGENTS.md、本地 Skill 或目录规则,确认:

  • 哪些实现方式必须遵守。

  • 哪些检查必须执行。

  • 哪些目录或文件应优先阅读。

  • 哪些操作需要停下来确认。

规则负责告诉 Codex“怎样在这个仓库里工作”,但规则本身不能替代代码现状。

2. 技术与运行入口

查看 package.json、构建配置、入口文件和路由,确认:

  • 实际框架与关键依赖。

  • 可用的项目脚本。

  • 页面怎样进入。

  • 当前功能属于哪一个应用或子模块。

这里不是为了背版本号,而是防止读错构建体系、读错应用入口,或者执行一个项目根本不存在的检查命令。

3. 目标功能入口

从路由、菜单、页面或组件入口进入当前功能,确认:

  • 用户操作从哪里开始。

  • 页面由哪些子组件组成。

  • 数据在何时加载。

  • 哪些行为是页面自己负责的。

只要入口找错,后面读得越认真,方向越可能偏。

4. 数据和状态流

沿着一次真实行为继续查:

用户操作 → 事件处理 → 状态变化 → 参数转换 → 接口调用 → 响应处理 → 页面渲染

列表查询、弹窗提交、分页切换、权限控制,都可以沿这条链检查。

读到这里,Codex 应该能说清楚“谁拥有状态”和“状态在哪些节点变化”,不能只列出几个方法名。

5. 相近的正确实现

找一个当前项目里经过确认的参考页面或组件,比较:

  • 命名方式。

  • 组件组织。

  • 状态归属。

  • 请求和异常处理。

  • 加载与反馈。

  • 验证方式。

参考实现不是用来整段复制,而是用来识别项目已经做出的选择。

6. 影响范围和验证入口

最后查:

  • 目标组件或方法的调用方。

  • 相关类型和接口。

  • 现有测试。

  • 构建、类型检查和页面验证方式。

阅读到这里,才算从“怎样写”走到了“改完会影响谁、怎样证明没有破坏”。

OpenAI 当前的 Codex 代码库理解用例也采用相似思路:先限定要理解的功能区域,再追踪请求流、模块职责、校验、状态变化和潜在风险,最后指出下一批应该阅读的文件和需要执行的检查。

我认为其中最值得注意的一点是:有用的阅读结果应该是一张具体地图,而不是文件列表。

“我已经读过了”不能作为完成信号

Codex 可以很快总结文件内容,但总结不等于理解。

我不会用“已经阅读 8 个文件”判断阅读阶段是否完成,也不会因为它把目录结构复述了一遍就允许开始修改。

我会看它能不能回答下面六个问题:

  1. 本次行为从哪个入口触发?

  2. 核心状态由谁维护,唯一来源在哪里?

  3. 请求参数和响应数据在哪一层转换?

  4. 哪些公共能力必须复用?

  5. 这次修改可能影响哪些调用方和异常路径?

  6. 修改后用哪些现有检查和页面路径验收?

如果其中两三个问题仍然只能用“可能”“大概”“看起来”回答,就说明阅读还没结束。

这时应该继续查证,而不是把猜测写进修改计划。

我会要求阅读结果区分事实、推断和未知

这是我判断 AI 是否真正理解项目时最常用的一个动作。

阅读报告里的结论,应该分成三类:

已确认事实

能够指出文件、方法或调用关系作为依据。

例如:

用户列表的查询条件和分页均由 queryParams 维护;handleQuery 会先将 pageNum 设为 1,再调用 getList。

合理推断

代码表现出某种意图,但没有足够证据证明它是项目规则。

例如:

角色列表和用户列表都使用同一种重置顺序,推测这是当前后台列表的通用行为,但尚未找到明确规则。

尚未确认

业务或技术上存在多种答案,代码也不一致。

例如:

请求失败时是否保留表格旧数据,两个相近页面处理不同,需要业务确认。

这三类内容不能混在一起。

AI 最危险的不是有未知,而是把推断写成事实,再基于它连续修改多个文件。

一段“先读后改”的任务写法

我会把阅读阶段单独写成一个可验收任务:

## 当前阶段
​
只理解用户列表的查询与重置流程,暂时不要修改代码。
​
## 阅读入口
​
- 项目规则和当前任务适用的 Skill
- 用户列表路由与页面入口
- 用户接口模块
- 公共分页组件
- 一个已确认的相近列表页面
​
## 需要回答
​
1. 查询、重置和翻页的完整状态流。
2. 页面、公共组件和接口层分别负责什么。
3. 必须复用的现有方法或封装。
4. 本次修改可能影响的调用方和异常路径。
5. 项目实际提供的检查命令与页面验证路径。
​
## 输出要求
​
- 每个关键结论附对应文件或代码位置。
- 将结论分为已确认、推断和未知。
- 列出下一步建议阅读的文件及原因。
- 发现规则冲突或行为不一致时暂停,不要自行选一个实现。

这段任务不要求它写一行代码,但产物并不抽象。只要输出足够具体,我就能判断它是否找对了入口、读清了状态、发现了风险。

哪些任务不需要单独安排阅读阶段

不是所有修改都要先写一份项目分析报告。

改一处已经定位明确的文案、修正一个孤立的类型拼写、调整一个没有复用关系的局部样式,通常可以边读边改。

我会在下面几种情况中单独保留阅读阶段:

  • 任务跨越页面、组件、接口或状态层。

  • 目标文件存在多个相近实现。

  • 修改公共组件或公共方法。

  • 需求会改变状态流、权限或异常行为。

  • 当前项目不熟悉,或者历史代码风格不统一。

  • 一旦理解错误,会产生较大范围返工。

决定是否先读,不看任务描述有多长,而看错误理解的成本有多高。

先读代码,不是拖慢 AI,而是把错误暴露在代码产生之前

Codex 的实现速度很快,这也是为什么阅读阶段更重要。

方向没确认时,生成速度越快,错误假设扩散得也越快。一个状态归属判断错误,后面可能连着影响请求、重置、导出、缓存和测试。

在代码生成前发现“这里有两套分页模式”“这个组件还有六个调用方”“错误提示已经统一处理”,修正成本很低。

等代码改完再发现,面对的就不只是一个错误判断,而是一整片建立在它上面的差异。

所以我不会把“先读”理解成保守,也不会把“直接改”理解成高效。真正应该比较的是:

哪一种方式能用更低的总成本,得到可验证、可维护的结果?

对有状态、有调用关系、有项目规范的前端任务来说,先读相关代码,通常是控制总成本的一部分。

下一篇我会把这一步继续落细:让 Codex 读完以后,我会要求它先交一张“前端项目地图”。这张地图应该包含什么、怎样避免只做目录介绍、什么信号说明它已经足够支撑修改,我会给出一份可直接复用的模板。

本系列持续更新。Day 4 的第二篇会从“为什么先读”进入“读完应该交付什么”,继续把 AI 协作变成可验收的工程流程。

参考资料

更多推荐