本页解决什么问题
接手一个陌生代码库时,最危险的第一步不是“不会写代码”,而是还没有形成系统模型,就开始改代码。你可能看到了一个报错文件,却不知道它由哪个入口触发;看到了一个函数,却不知道哪些调用方依赖它;看到了一个测试,却不知道它覆盖的是哪条业务路径。 本页只讲一件事:如何让 Codex 在只读边界内,从目录结构走到入口,再沿调用链走到测试映射,最后输出一份可供人核对的探索报告。 这里的“只读”是行为边界,不是让 Codex 少读几个文件。探索阶段可以广泛读取、搜索、运行不会改变项目状态的检查命令,但不修改源代码、测试、配置、依赖或生成物。等你确认了范围和事实,再决定是否切换到计划或实施工作流。 你将学会:- 如何先确认工作区、规则文件和项目入口。
- 如何从目录结构筛出真正值得阅读的文件。
- 如何找到 Web、CLI、任务队列和脚本等不同类型的入口。
- 如何用符号搜索和证据逐段追踪调用链。
- 如何把生产代码映射到测试文件、测试命令和缺失覆盖。
- 如何编写 Codex 探索提示词,让它报告证据而不是猜测。
- 什么时候继续只读探索,什么时候切入计划模式。
- 如何识别“目录摘要很漂亮但结论不可靠”等常见错误。
- 如何用一个真实项目演练完整的目录到测试映射流程。
本页使用的 Codex 命令和界面可能随版本变化。运行前以本机的codex --help、相关子命令的--help和官方文档为准。参考资料:参考/codex/02-core-concepts.md、参考/codex/14-workflows.md、参考/codex/11-agents-md.md。
先定边界:探索不是实现
“帮我了解这个项目”和“帮我修复登录问题”是两种不同任务。前者的产物是地图、证据和未知项;后者的产物是修改和验证。把两者混在一个会话里,Codex 很容易在你还没确认根因时提出并执行改动。 探索阶段的目标可以写成四个问题:
在提示词中明确以下非目标:
只读不等于盲目禁止命令
可以使用的证据命令通常包括:pwd、git rev-parse --show-toplevel:确认当前位置和项目根。git status --short --branch:确认工作区状态,不修改文件。find或rg --files:列目录和文件,不读取文件内容到磁盘。rg:搜索路由、符号、命令、测试名和配置键。git log、git blame:了解变更背景和责任边界。- 项目已有的
lint、typecheck、测试收集或构建信息命令,前提是它们不会写入工作区。
npm install、pnpm install、pip install、go generate等可能改变依赖或生成文件的命令。- 需要联网、访问云服务、读取生产数据或发送请求的命令。
- 会生成缓存、覆盖快照、写报告或启动长期运行服务的命令。
git clean、批量删除、迁移、格式化和自动修复命令。
git status、git diff --stat 证明没有意外改动。
第一步:确定工作区和起点
不要从聊天上下文中猜项目根。先让终端给出证据,再启动 Codex,或者在会话里明确要求它执行同样的检查。终端基线检查
在目标项目目录执行:- Codex 实际工作的绝对路径。
- Git 根目录,而不是编辑器当前打开的子目录。
- 当前分支和已有未提交修改。
- 项目使用的语言、包管理器和主要构建工具。
- 是否存在
AGENTS.md、AGENTS.override.md或配置中声明的备选规则文件。
启动只读 Codex
先查看本机支持的参数:AGENTS.md 的读取顺序
探索陌生项目时,规则文件本身就是第一批上下文。不要只打开仓库根目录的AGENTS.md 就认为规则读完了。
按照参考资料中的 Codex 发现机制,通常按以下顺序理解:
- 先看 Codex 主目录中的全局规则。默认是
~/.codex/,如果设置了CODEX_HOME,则以该环境变量指向的目录为准。 - 在全局层,如果同时存在
AGENTS.override.md和AGENTS.md,优先取AGENTS.override.md;这一层只取一个非空文件。 - 确定项目根后,从项目根目录向下走到当前工作目录。
- 每个目录依次查找
AGENTS.override.md、AGENTS.md,再查找配置中的project_doc_fallback_filenames备选文件名;每个目录最多取一个非空文件。 - 找到的项目级规则按“根目录到当前目录”的顺序合并。越靠近当前目录的规则越晚出现,冲突时通常以更具体的规则为准。
AGENTS.override.md只替换同一目录的候选文件,不会清掉其他目录已经合并的规则。AGENTS.md是指导来源,不是目录索引。它可能规定测试命令、禁止访问的目录、生成文件策略和代码库特有约定;这些内容必须进入探索计划的约束。
CODEX_HOME 是否改变、是否存在更近的 override、规则文件是否为空、配置中的备选文件名是否拼写正确。改动配置后需要重启 Codex,不能在原会话中假定新规则已经生效。
第二步:从目录建立结构地图
目录探索的目的不是把每个文件都读一遍,而是建立“边界和职责”的假设,再用入口和调用链验证假设。先看一级结构
先执行低成本命令:rg --files,不要把 .git、依赖目录、构建产物和覆盖率目录当成业务模块。
让 Codex 输出目录地图时,要求它区分证据和推断:
优先阅读的文件
不同项目的文件名会变化,但优先级通常稳定:
不要一开始读取所有锁文件、编译产物和大型数据文件。它们可能有用,但通常不能帮助你快速建立业务调用链。
目录不是架构结论
目录名只能产生候选假设。例如services/ 可能是领域服务,也可能只是 HTTP 客户端;utils/ 可能承载关键权限逻辑;tests/ 可能只包含端到端测试。报告中应使用“看起来”“候选”“待通过符号引用确认”等措辞,直到你读到定义和调用点。
错误的目录结论:
第三步:从目录找到真实入口
入口是“外部事件第一次进入业务代码的位置”。不同项目入口不同:
先问 Codex 找候选,不要直接让它“讲完整架构”:
第四步:沿调用链追踪
目录告诉你“可能在哪里”,入口告诉你“从哪里开始”,调用链则回答“实际经过什么”。一次有效的调用链追踪至少要完成这五件事:- 记录入口函数的定义和参数。
- 找出它直接调用的本地符号。
- 对每个关键符号继续追到实现,而不是停在导入语句。
- 标注条件分支、异常处理、外部调用和数据转换。
- 到达持久化、响应构造、消息发布或任务完成等终点。
先追一条主路径
不要同时追十条流程。先选择一个具体场景,例如“有效请求创建订单”,写清触发条件和预期终点:用符号搜索补齐链路
Codex 的叙述需要被搜索证据约束。常用命令:画出带证据的链路
探索输出不要只写一段散文。使用编号链路,读者可以从任一节点回到文件:追踪分支和副作用
只追成功主路径会漏掉最重要的行为。至少追加三条分支问题:- 依赖注入容器让构造函数里没有直接的实现名称。
- 装饰器、注解或元数据在运行时注册路由。
- 事件发布让调用关系从同步函数跳到消费者。
- 接口、抽象类或函数类型让实际实现由配置决定。
- 生成代码、宏或代码生成脚本隐藏了入口。
- 前端请求经过 API 客户端、状态管理和中间件后才到组件。
第五步:映射到测试
调用链完成后,马上问“哪些测试证明了这些节点”。测试映射不是只找同名文件,而是把生产路径的行为节点与测试类型对应起来。先识别测试体系
读取测试配置和项目脚本:建立映射表
推荐用下表记录,而不是只写“测试比较完整”:
“测试文件名看起来相关”不是覆盖证据。至少要看到调用目标、输入和断言;如果使用 fixture 或共享 helper,还要继续追 helper 最终做了什么。
反向从测试追生产代码
正向从入口到测试容易遗漏测试专用路径,因此再反向抽查:Codex 探索提示词工具箱
下面的提示词都以只读为前提。使用时把项目事实、路径和业务名替换成实际内容。目录地图提示词
入口定位提示词
调用链提示词
测试映射提示词
事实核验提示词
命令证据:让报告可以复查
高质量探索报告不是命令清单,而是“问题、命令、输出、结论”的对应关系。建议记录以下证据:
不要把完整终端日志未经整理地塞进报告。保留足以复查的关键输出,命令失败时保留退出码、错误文本和当时的工作目录。
有效和无效的命令证据
无效:什么时候继续探索,什么时候切计划
只读探索没有“读得越多越好”的原则。它的终点是关键事实足够支撑下一步决策。继续只读探索的信号
- 还不知道真正入口,只有目录名和猜测。
- 同一个符号有多个实现,运行时选择方式未确认。
- 调用链在依赖注入、事件总线或生成代码处断开。
- 关键分支、权限检查、事务边界或外部副作用未定位。
- 测试命令会写快照或启动未确认的外部服务。
- 结论和
AGENTS.md、README、代码证据互相矛盾。
可以切计划的信号
当下面几项都明确时,可以从只读探索切到计划:- 目标入口和关键调用链已经有路径、符号和调用证据。
- 需求影响范围和明确非目标已经写清楚。
- 相关测试命令、已有覆盖和缺口已经知道。
AGENTS.md中的项目规则和禁止操作已经纳入约束。- 仍然存在的未知项不会改变方案,或已经显式列为风险。
$plan 技能,具体名称以本机支持为准。计划不是批准书:看完计划后仍需检查文件范围、是否把未知项伪装成事实,以及验证步骤是否真正能证明目标行为。确认计划后,再启动可写工作流。
错误示例与修正
错误一:一上来就让它修
错误提示:错误二:只看目录就下架构结论
错误结论:错误三:把相似名称当调用关系
错误结论:错误四:把测试文件名当覆盖证明
错误结论:错误五:为了探索而运行会写文件的命令
错误做法:错误六:忽略更近的 AGENTS.override.md
现象:Codex 使用了和你看到的根规则不同的测试命令。 问题:当前子目录可能存在AGENTS.override.md,或全局 CODEX_HOME 指向了另一套规则。
修正:按全局、项目根到当前目录逐级列出实际文件,确认同级 override 的优先关系,再重启会话验证。
真实项目演练:从目录到测试映射
下面以一个常见的真实项目形态演练:一个使用 TypeScript、Express、PostgreSQL 和 Jest 的订单 API。项目名和路径是演练中的脱敏示例,重点是方法;不要把示例路径当成你本地项目的事实。场景和目标
目标是理解“创建订单”请求:- 不修改 API 行为。
- 不修复发现的缺陷。
- 不新增测试。
- 不启动真实支付服务,不访问生产数据库。
- 不安装依赖、不更新快照、不提交。
1. 读取规则和项目基线
在项目根执行:src/config/logger.ts 已经被修改。它不是本轮探索产生的结果,后续报告不要把它列入本轮变更。
读取 AGENTS.md 和 README.md 后得到项目规则:测试使用 pnpm test,类型检查使用 pnpm typecheck,禁止修改迁移历史,外部服务只能使用测试替身。这个规则会影响后续验证选择。
2. 看包配置和目录
读取package.json 的 scripts 和依赖:
src/server.ts创建 Express 应用并监听端口。src/api/routes/order-routes.ts注册订单路由。src/application/存放用例服务。src/infra/存放数据库和外部客户端。tests/api/测试 HTTP 行为,tests/application/测试业务用例,tests/infra/测试数据库适配层。
3. 定位订单入口
执行:POST /orders 先经过 auth,再调用 createOrderHandler。但还不能推断 auth 的拒绝行为,继续读取它的实现和测试。
4. 追踪成功主路径
搜索定义、导入和调用:- 空商品由
Order.create抛出EmptyOrderError。 - 库存不足由
inventoryClient.reserve转换为OutOfStockError。 - 请求 ID 由中间件传入,但
DuplicateRequestError的处理在order-service.ts,需要核对是否在写库前执行。 - 订单保存成功后
order-events.ts发布order.created,但事件发布发生在数据库事务提交后,消费者属于另一条异步链路。
5. 映射现有测试
先读取测试命令:
再反向检查
tests/api/order-route.test.ts 是否绕过了真实依赖。假设它通过 createTestApp() 注入内存 repository 和库存 mock,那么应写出限制:它能证明路由、中间件和响应映射,但不能证明生产数据库事务或真实库存客户端协议。
6. 输出本次探索结论
合格的演练报告可以收束为:src/config/logger.ts 修改,没有本轮新增文件或 diff。
探索输出模板
将以下模板贴给 Codex 或用于自己的笔记。它强制报告从目录到测试的证据链:验收清单
完成陌生代码库探索后,逐项核对:- 当前工作目录和 Git 根目录已由命令确认。
- 当前分支和探索前已有修改已记录。
- 全局到当前目录的
AGENTS.md读取顺序已确认。 - 规则中的测试命令、禁止操作和目录约束已进入报告。
- 顶层目录只作为候选假设,没有被直接当作架构结论。
- 目标功能至少找到一个真实入口,并有注册位置证据。
- 调用链包含定义、调用、参数变化和关键终点。
- 鉴权、校验、事务、异常和外部副作用已单独检查。
- 测试映射包含用例和断言证据,而不只是文件名。
- 单元、集成、端到端或契约测试的边界已区分。
- 动态分发、事件链和生成代码造成的不确定点已标出。
- 所有无法确认的内容写入未知项,没有为了完整而猜测。
-
git status和git diff --check证明只读探索没有产生改动。