ChatGPT、Codex实战:修改代码总失败?从权限、目录、依赖到测试的8项排查
第一次用Codex处理真实项目时,很多人的体验其实很割裂。
你会发现它明明已经:
看懂了代码,
找到相关函数,
分析出了可能的原因,
甚至已经告诉你准备修改哪些文件。
但任务真正执行下去,却很容易出现另一种情况:
代码改了一半停了。
Terminal命令执行失败。
同一个错误连续修改几轮。
原本只修一个Bug,最后改了十几个文件。
Codex说“已经完成”,重新运行项目问题却还在。
于是很多人开始把问题归结为:
是不是模型不够强?
但真正把Codex放进工程环境以后,会发现一个很重要的变化:
模型能力,只决定Agent“有没有可能知道怎么解决问题”;工程环境,则决定它“能不能真的把问题解决”。
现在的Codex并不是一个只生成代码片段的聊天窗口。它需要在真实文件、命令、测试和项目上下文之间连续执行任务,而OpenAI目前也通过Sandbox、Approval和权限规则限制Agent能够访问哪些文件、网络资源以及哪些动作可以直接执行。
所以,当Codex修改代码失败时,真正需要排查的已经不是一个单点问题。
而是一整条执行链:
理解任务
↓
找到正确项目
↓
读取相关文件
↓
获得必要权限
↓
理解依赖和环境
↓
定位根因
↓
修改代码
↓
运行验证
↓
判断是否完成
只要其中任何一层出现问题,最终给人的感觉都可能是:
Codex“不好用”。
但它们的根因完全不同。
下面按照真实工程执行顺序,把最常见的8类问题拆开。
一、第一步不是看Prompt,而是确认Codex到底站在哪个目录
很多Codex任务从一开始就已经错了。
不是代码错。
而是:
工作目录错了。
假设真正需要处理的项目是:
D:\Projects\shop-web
但当前打开的是:
D:\Projects
这个目录里还有:
shop-web
shop-api
admin-system
demo
legacy
scripts
此时你给Codex一句:
修复登录按钮点击没有反应的问题。
人类知道你正在做shop-web。
Agent并不知道。
它接下来只能先建立自己的项目地图:
寻找Git仓库
↓
查找package.json
↓
搜索login关键词
↓
判断前端和后端关系
↓
识别哪个目录才是当前项目
这就是很多人看到的:
Codex怎么一直在Search?
问题甚至还没有进入Bug分析阶段。
Workspace不是越大越好
传统IDE里,我们习惯直接打开整个仓库。
但对于Agent来说:
可见范围本身就是搜索空间。
一个任务只和:
src/features/login
相关,
却让Agent从一个包含几万个文件的大型Monorepo开始探索,相当于人为增加了大量不确定性。
所以真正开始任务之前,先确认三件事:
当前项目是什么?
任务真正涉及哪个模块?
哪些目录根本没有必要进入上下文?
这不是Prompt技巧。
这是最基础的:
Context Boundary。
二、第二个问题:Codex“知道怎么改”和“能够改”不是一回事
这是Agent和普通聊天模型最明显的区别之一。
假设Codex已经分析出:
问题位于auth.ts第87行。
但接下来修改失败。
此时模型推理可能没有任何问题。
真正失败的是:
Execution。
一个完整代码任务至少可能涉及四种能力:
Read
↓
Write
↓
Execute
↓
Network
而这四个能力不是天然等价的。
能读不能写
Codex可以:
读取文件,
解释问题,
给出Patch思路。
但不能真正落盘修改。
能写不能执行
Codex能够修改:
auth.ts
但不能运行:
pnpm test
最终结果就是:
代码写完了,但没有验证。
能执行但不能联网
项目本身缺少某个依赖。
Agent判断需要下载。
但网络访问被限制。
任务又会停下来。
OpenAI目前把这两个层次明确拆成Sandbox与Approval:Sandbox决定命令可以访问哪些文件和网络资源,而Approval决定某些动作是否需要在执行之前暂停并获取进一步批准。
因此,看到Codex失败以后,最没用的问题之一就是:
为什么它没做好?
更有效的问法应该是:
具体失败在哪一个动作?
Read?
Write?
Execute?
Network?
还是Workspace边界?
一旦把“任务失败”拆成具体动作,问题才开始变得可诊断。
三、第三个问题:Agent不是突然变笨了,而是任务范围漂移了
这是复杂项目里非常典型的一种失败。
开始时,任务可能非常简单:
登录按钮点击以后没有请求API。
第一次分析,Codex检查:
Login.tsx
没有明显问题。
然后检查:
auth-api.ts
接着发现认证状态可能有关。
于是继续读:
auth-store.ts
随后看到Token初始化。
继续进入:
router.ts
middleware.ts
config.ts
到了后面,一个原本只需要修改两三个文件的问题,已经演变成整个认证系统分析。
这就是:
Scope Drift。
任务范围正在自己向外扩张。
为什么Agent特别容易出现这种问题?
因为Agent的目标通常是:
完成任务。
只要它认为某个新文件可能和问题有关,就存在继续探索的理由。
如果任务没有边界,它最合理的行为就是:
不断扩大搜索范围,直到找到答案。
但工程上,这并不一定是我们想要的行为。
因此一个成熟任务不能只有:
Goal。
还应该有:
Scope。
例如:
当前问题:登录按钮没有发送请求。
优先检查Login.tsx和auth API。
不进行无关重构。
不升级依赖。
如果根因位于范围之外,先说明证据,再扩大检查范围。
这几句话真正解决的不是语言表达。
而是:
限制Agent的决策空间。
四、第四个问题:Codex正在修代码,但真正坏掉的是依赖
真实项目里,一个错误信息通常不等于一个代码Bug。
例如:
Module not found
看到这句话以后,可以有很多可能。
可能一:import路径错误
属于:
Code Layer。
可能二:Package没有安装
属于:
Dependency Layer。
可能三:当前运行的不是正确环境
属于:
Environment Layer。
如果没有先区分这三层,Agent非常容易进入一个错误循环:
测试失败
↓
认为源码有问题
↓
修改代码
↓
继续失败
↓
继续修改代码
但真正原因可能只是:
npm install
没有成功。
或者Python虚拟环境根本没有激活。
再比如:
项目要求Node 22,
实际环境还是Node 18。
这种情况下,即使Codex重新写十次业务逻辑,也无法从根本上解决运行环境问题。
所以看到错误以后,我更建议先做一个非常简单的判断:
代码问题?
依赖问题?
环境问题?
不要急着改代码。
一个非常重要的原则
Error发生在代码附近,不代表Root Cause就在代码里。
这是人类排查Bug时成立的原则。
对Agent同样成立。
五、第五个问题:没有Baseline,Codex甚至无法证明自己有没有修好
这是Agent工程里非常容易被低估的一点。
假设你告诉Codex:
修复当前测试失败。
它修改代码以后重新测试:
3 failed
126 passed
Codex告诉你:
仍有3个测试失败。
问题是:
修改之前是多少?
如果原来就是:
3 failed
126 passed
那么至少可以说明:
当前修改没有引入额外失败。
但如果原来是:
1 failed
128 passed
那么这次修改实际上把项目变得更差了。
这就是为什么Agent开始动代码之前,需要建立:
Baseline。
也就是修改前状态。
例如:
Tests: 3 failed / 126 passed
Lint: 2 warnings
Build: success
然后Agent执行修改。
完成以后再次运行完全相同的验证:
Tests: 0 failed / 129 passed
Lint: 2 warnings
Build: success
现在才有了真正意义上的:
Before / After。
这时我们才能说:
修改改善了项目状态。
否则“测试结果”只是一个孤立数字。
Agent时代,验证对象发生了变化
传统AI编程通常关注:
代码生成得对不对?
Agent开发进一步需要关注:
系统状态有没有按照预期发生变化?
所以Baseline并不是测试流程里的小技巧。
它实际上是Agent Verification的起点。
六、第六个问题:任务越模糊,Codex需要替你做的决策越多
看一个非常常见的Prompt:
帮我优化登录模块。
这句话看起来没什么问题。
但Agent真正执行时,会遇到大量未定义问题:
“优化”是指:
修Bug?
性能?
UI?
代码结构?
错误处理?
状态管理?
接口设计?
测试覆盖?
如果用户没有定义,Agent只能自己决定。
最终很容易出现这种结果:
本来想改:
Login.tsx
最后变成:
Login.tsx
AuthService.ts
router.ts
store.ts
api.ts
types.ts
package.json
这时候用户会觉得:
Codex怎么又乱改东西?
但从Agent角度看:
任务本身就允许它做这种判断。
一个工程任务至少应该定义四件事
Problem
到底哪里有问题。
Scope
应该重点看哪里。
Constraint
哪些事情不要做。
Done
什么结果算完成。
比如:
问题:
登录按钮点击后没有触发API请求。
范围:
优先检查Login.tsx和auth API。
限制:
不升级依赖。
不修改数据库。
不进行无关重构。
完成标准:
请求恢复正常;
相关测试通过;
列出修改文件。
它并不是什么“高级Prompt”。
但它解决了一个非常关键的问题:
把不该由Agent决定的事情提前决定掉。
七、第七个问题:一个任务里塞太多目标,会让因果关系越来越混乱
Agent能做长任务以后,很多人自然开始追求:
一次把事情全做完。
例如:
修复登录Bug,同时升级依赖,解决TypeScript错误,优化认证性能,补测试,再重构一下公共模块。
表面上看是一个Task。
实际上里面至少包含:
Bug Fix
Dependency Upgrade
Type Fix
Performance Optimization
Testing
Refactor
问题不是Codex绝对完成不了。
而是这些任务之间存在大量因果关系。
例如:
升级依赖
↓
产生新类型错误
↓
修改公共类型
↓
原测试失效
↓
继续修改测试
最终当项目出现新问题时,很难判断:
到底是哪一个修改引入的?
这会让调试成本急剧增加。
正确的长任务不是“大任务”
而是:
阶段化任务。
例如:
阶段1
修复登录Bug
↓
验证
↓
阶段2
处理TypeScript错误
↓
验证
↓
阶段3
升级依赖
↓
验证
每个阶段都形成自己的:
Input
↓
Change
↓
Evidence
OpenAI目前的Codex App也把不同Agent任务组织在独立线程和项目中,并支持直接查看Agent产生的修改和Diff,这种产品形态本身就体现了任务隔离与审查的重要性。
Agent能够并行,并不意味着所有目标都应该塞进一个上下文。
八、第八个问题,也是最重要的问题:Done到底是谁定义的?
Codex最后可能输出:
已完成。
这句话非常容易让人产生一个错觉:
任务已经结束了。
但实际上这里只能证明:
Agent认为自己的执行流程已经结束。
不能直接证明:
工程问题已经解决。
这是两个完全不同的判断。
一个可靠的任务闭环至少应该是:
Reproduce
↓
Diagnose
↓
Modify
↓
Test
↓
Review Diff
↓
Verify
其中任何一层缺失,都可能出现:
“修改完成,但任务没有完成。”
所以Codex说Done以后,我更关注四个问题
1. 改了什么?
具体哪些文件?
如果原本一个局部Bug却修改15个文件,需要重新检查Scope。
2. 为什么这样改?
关键Diff必须能够对应到Root Cause。
否则只是:
修改以后错误暂时消失。
这并不等于真正修复。
3. 跑了什么验证?
不是:
已完成测试。
而是具体执行过:
pnpm test
pytest
pnpm lint
npm run build
中的哪些。
4. 什么没有验证?
例如:
数据库没有运行;
缺少测试账号;
第三方服务不可访问;
生产配置不可用。
这些信息同样属于最终结果。
OpenAI目前的Codex工作流支持在线程内审查Agent修改、查看Diff,以及继续进入编辑器做人工调整;远程工作流中也会同步Terminal输出、Diff、测试结果和审批状态。
这说明Agent真正的交付物已经不应该只有:
Code。
还应该包括:
Evidence。
把8个问题放在一起,会发现Codex失败其实有四个层级
如果把前面的排查重新归类,会得到一个更清楚的结构。
第一层:Environment
包括:
目录、
Workspace、
依赖、
Runtime环境。
它解决的是:
Agent有没有站在正确的地方工作?
第二层:Permission
包括:
Read、
Write、
Execute、
Network。
它解决的是:
Agent有没有能力完成需要执行的动作?
第三层:Task
包括:
目标、
范围、
限制、
任务拆分。
它解决的是:
Agent到底应该做什么,以及不应该做什么?
第四层:Verification
包括:
Baseline、
Test、
Diff、
Evidence。
它解决的是:
怎么证明Agent真的完成了任务?
最终就形成了一条非常清楚的链:
Environment
↓
Permission
↓
Task
↓
Verification
很多所谓的:
Codex能力不够。
其实真正失败的可能只是其中某一层。
为什么排查顺序非常重要?
假设目录本身就错了。
你却开始优化Prompt。
没有意义。
假设依赖没有安装。
你却让Codex连续重写业务代码。
只会越改越复杂。
假设任务范围没有定义。
你却给它更大的权限。
Agent只会探索得更远。
所以我更建议以后直接使用下面这个顺序:
① 当前目录正确吗?
↓
② Workspace范围合理吗?
↓
③ Read / Write / Execute正常吗?
↓
④ 依赖完整吗?
↓
⑤ Runtime环境正常吗?
↓
⑥ Task Boundary明确吗?
↓
⑦ 修改前有Baseline吗?
↓
⑧ 修改后有Evidence吗?
这个顺序的价值就在于:
先排除基础层,再进入智能层。
而不是一出现失败,就把所有问题归因于模型。
一个更适合Codex的Bug任务结构
真正使用时,可以把任务整理成下面这种形式:
【问题】
登录按钮点击后没有发送API请求。
【检查范围】
src/login
src/api/auth.ts
相关测试
【禁止事项】
不要升级依赖。
不要修改数据库Schema。
不要重构无关模块。
【执行顺序】
1. 先复现问题;
2. 定位Root Cause;
3. 说明准备修改的位置;
4. 完成代码修改;
5. 运行相关测试;
6. 检查Diff。
【完成标准】
输出:
- 根因;
- 修改文件;
- 关键Diff;
- 执行过的测试;
- 测试结果;
- 未验证部分。
这里真正重要的并不是格式。
而是六个词:
Problem
Scope
Constraint
Action
Verification
Evidence
当这六件事逐渐固定以后,Agent的工作方式才会从:
尝试帮你解决问题。
变成:
按照工程协议完成任务。
从“代码生成”到“工程执行”,开发者真正要学的东西已经变了
AI编程刚开始普及时,大家主要比较:
哪个模型写代码更强?
谁生成函数更准确?
谁补全更快?
但Agent真正进入项目以后,问题已经发生变化。
因为现在决定最终结果的不只有:
Model Intelligence。
还有:
Execution Environment。
Permission Boundary。
Task Design。
Verification System。
所以未来真正拉开Codex使用差距的,很可能不是:
谁会写更复杂的Prompt。
而是谁能建立一套更稳定的Agent工程体系。
让Agent知道:
从哪里开始。
允许做到哪里。
哪些事情不要做。
什么状态才算完成。
完成以后拿什么证明。
当这些条件建立以后,Codex才真正从:
“会帮你写代码的AI”
变成:
“能够参与工程执行的Agent”。
而当Codex再次告诉你:
Done。
你真正应该关注的也不再是这一句话。
而是它后面有没有一条完整的:
Task
↓
Change
↓
Test
↓
Evidence
这才是真正可靠的完成。
当目录、权限、依赖和验证流程都处理好以后,Codex仍然可能出现另一类问题:任务越长,越容易偏离最初目标。
这时候问题已经不再是环境或权限,而是上下文污染、任务状态丢失和阶段性验证不足。下一步真正需要解决的,是如何让Agent在长任务中持续保持目标一致。
更多推荐




所有评论(0)