拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

不敢让 Codex 直接改代码?我先让它只读分析一个 Node.js 项目

不敢让 Codex 直接改代码?我先让它只读分析一个 Node.js 项目

1. 为什么我让 Codex 先只读,而不是直接改代码

Codex 这类 CLI 编码代理最让人心里没底的地方,不是它不会写代码,而是它太会写代码了。你一句「帮我优化下这个接口」,它可能顺手把package.json的依赖升了、把测试文件重写了、把没让你碰的配置文件也改了。等你git diff一看,几十个文件变动,根本分不清哪些是它该动的、哪些是它自作主张的。

所以我给自己定了个规矩:新项目第一次交给 Codex,一律先跑 read-only 模式。让它只读目录、读源码、读 npm 脚本,把「它看到了什么、理解成什么」先讲清楚。这一步不产生任何写操作,风险为零,但能提前暴露两个关键问题——它有没有看错目录结构,它有没有把依赖关系理解反。

这篇就以一个真实的 Node.js 小项目为例,走一遍完整流程:npm init锁依赖 → 配置统一 Key/API 通道 → 用codex exec --sandbox read-only做只读分析 → 用 SHA-256 哈希验证「它真的没动文件」。全程可复制,Windows / macOS / Linux 都能跟。

适合谁看:手里有 Node.js 项目、想用 Codex 做代码审查或架构梳理、但又不放心直接给写权限的开发者。读完你能拿到一份可复制的config.toml骨架,以及一套「只读权限没被绕过」的检查动作。

2. 前置准备:TaoToken 统一 Key 与 API 通道

Codex CLI 本身只是个客户端,它要调模型,就得有一个能用的 API 入口和 Key。我这边统一走 TaoToken 的通道,好处是模型对话、Coding Plan、API Keys 都在一个后台管,不用在多个服务商之间来回切配置。

你需要先拿到两样东西:

  • 一个 API Key(在控制台里创建,形如sk-xxxxxxxx)
  • 一个 Base URL(统一入口,后面写进config.toml)

创建 Key 的入口在这里:

API Keys 管理:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite

如果你还没决定用哪个模型跑 Codex,可以先在模型对话页面试一下,确认模型对 Node.js 代码的理解符合预期,再写进 CLI 配置:

模型对话体验:https://taotoken.net/chat?utm_source=taotoken_aicg_blog_end&utm_content=model_chat&utm_campaign=rewrite

长期用 Codex 做编码和 Agent 任务的话,Coding Plan 比按次调用更划算,额度也更稳定:

Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

接入文档里有完整的 Base URL、模型名和参数说明,配置前建议扫一眼,避免模型名写错导致 404:

接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

API 统一入口是https://taotoken.net/api,这个地址不加任何查询参数,直接写进配置即可。

3. 可复制配置:npm 初始化 + config.toml 骨架

3.1 先建一个能跑的小项目

不要一上来就拿生产仓库试。我习惯先建一个 5 个文件以内的小项目,依赖为零,测试能跑通,这样 Codex 分析出错时你能一眼看出来是它的问题还是项目本身的问题。

mkdir tiny-books-api && cd tiny-books-api npm init -y

npm init -y会生成一个默认的package.json。接着手动补上启动和测试脚本,并锁定依赖——这一步很关键,只读分析时如果依赖是浮动的,Codex 可能会把「依赖版本不确定」当成风险点报出来,干扰判断。

{ "name": "tiny-books-api", "version": "1.0.0", "type": "module", "scripts": { "start": "node src/server.js", "test": "node --test test/" }, "dependencies": {}, "devDependencies": {} }

目录结构保持这样,一共 5 个文件:

tiny-books-api/ ├── README.md ├── package.json ├── src/ │ ├── books.js │ └── server.js └── test/ └── server.test.js

src/books.js只放内存数据:

export const books = [ { id: 1, title: "Node.js 实战" }, { id: 2, title: "CLI 工具设计" } ];

src/server.js提供两个 GET 接口:

import http from "node:http"; import { books } from "./books.js"; const server = http.createServer((req, res) => { if (req.url === "/health") { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify({ status: "ok" })); return; } if (req.url === "/api/books") { res.writeHead(200, { "Content-Type": "application/json" }); res.end(JSON.stringify(books)); return; } res.writeHead(404, { "Content-Type": "application/json" }); res.end(JSON.stringify({ error: "not found" })); }); server.listen(3000, () => console.log("listening on 3000"));

先跑一遍测试,确认项目本身没问题:

npm test

看到pass 2之类的输出就说明项目是健康的。这一步的意义是:后面 Codex 报出来的任何问题,都只可能是它理解层面的问题,而不是项目跑不起来。

3.2 config.toml 骨架

Codex CLI 的配置放在用户目录下的~/.codex/config.toml(Windows 是%USERPROFILE%\.codex\config.toml)。下面是我用的骨架,把 Key 和 Base URL 都指向 TaoToken 通道:

# ~/.codex/config.toml model = "gpt-5-codex" model_provider = "taotoken" [model_providers.taotoken] name = "TaoToken" base_url = "https://taotoken.net/api" env_key = "TAOTOKEN_API_KEY" wire_api = "responses" [sandbox] # 默认只读,需要写操作时再显式覆盖 mode = "read-only"

Key 不要写进config.toml,用环境变量传,避免配置文件被同步或截图泄露:

# macOS / Linux export TAOTOKEN_API_KEY="sk-你的Key" # Windows PowerShell $env:TAOTOKEN_API_KEY = "sk-你的Key"

注意:base_url用https://taotoken.net/api,不要在后面拼/v1之类的路径,具体路径由wire_api决定。模型名以接入文档当前页面为准,写错会直接 404。

4. 只读分析实战:codex exec --sandbox read-only

4.1 确认 CLI 支持哪些只读参数

先看帮助,确认当前版本支持哪些沙箱参数:

codex exec --help

我这边确认可用的三个关键参数:

参数作用
--sandbox read-only限制项目写入,只读文件系统
--skip-git-repo-check允许在非 git 目录运行
--ephemeral不保留本次会话文件

4.2 把项目文件打包成标准输入

我试过让 Codex 自己跑rg --files去列文件,但在 Windows 沙箱里启动子进程时返回了 1312 错误。后来改成把文件内容通过标准输入喂给它,并明确要求它不要调用任何工具,反而更稳。

PowerShell 下打包文件内容:

$root = (Get-Location).Path $files = Get-ChildItem -Recurse -File | Sort-Object FullName $bundle = ($files | ForEach-Object { $relative = [System.IO.Path]::GetRelativePath($root, $_.FullName) "`n=== FILE: $relative ===`n" Get-Content -Raw -LiteralPath $_.FullName }) -join "`n"

macOS / Linux 下等价写法:

bundle=$(find . -type f | sort | while read -r f; do echo "" echo "=== FILE: $f ===" echo "" cat "$f" done)

4.3 执行只读分析

把 prompt 和文件内容一起交给 Codex:

$prompt = @' 下面的标准输入包含当前 Node.js 项目的全部文件。 不要调用任何工具,不要创建、修改或删除文件,只根据标准输入分析。 请说明文件职责、npm 脚本、第三方依赖、GET /api/books 的调用路径, 并列出 3 个有文件依据的缺口。不要补全文件里没有的信息。 '@ $bundle | codex exec --sandbox read-only --skip-git-repo-check --ephemeral $prompt

三个参数缺一不可:--sandbox read-only保证不写文件,--skip-git-repo-check让它在独立目录能跑,--ephemeral保证不留会话残留。

5. 验证结果:分析输出 + 只读权限检查

5.1 Codex 实际分析出了什么

运行结束后,Codex 正确识别了 5 个文件的职责:

  • package.json:项目元数据、启动和测试脚本
  • README.md:接口、命令和端口说明
  • src/books.js:内存图书数据
  • src/server.js:HTTP 服务和路由
  • test/server.test.js:两个 GET 接口测试

它确认了启动命令是npm start、测试命令是npm test,并且项目没有第三方依赖。GET /api/books的调用路径也说对了:

http.createServer → 匹配 GET /api/books → 读取 books → JSON.stringify → response.end

更关键的是,它列出了三个有源码依据的缺口:

  1. request.url用的是精确匹配,/api/books?limit=1会返回 404
  2. 非 GET 的/api/books仍返回 404,没有区分 405
  3. 测试只检查状态码和数组长度,没检查响应内容、Content-Type和未知路由

这三条都能在源码里找到对应行,不是它编的。这正是只读分析的价值——它先证明自己读懂了,再谈改不改。

5.2 用 SHA-256 确认它没动文件

光信--sandbox read-only参数不够,我习惯用哈希做物理验证。运行前后各算一次:

Get-ChildItem -Recurse -File | ForEach-Object { $hash = (Get-FileHash -Algorithm SHA256 -LiteralPath $_.FullName).Hash "$hash $($_.FullName)" } | Sort-Object

macOS / Linux:

find . -type f -exec sha256sum {} \; | sort

对比两次输出,5 个文件的哈希完全一致,退出码为 0:

CODEX_EXIT=0 FILES_UNCHANGED=True

参数声明和实际文件结果对上了,这才叫「验证过」,而不是「相信它」。

6. 本篇常见错排查

6.1 报错 1312:沙箱启动子进程失败

现象:让 Codex 自己跑rg --files或ls时,Windows 沙箱返回 1312。

原因:沙箱限制了下级进程的创建权限。

解决:不要让它调工具,改成把文件内容通过标准输入喂进去,prompt 里明确写「不要调用任何工具」。这也是我上面用$bundle | codex exec的原因。

6.2 模型返回 404 或认证失败

现象:codex exec直接报模型不存在或 401。

排查顺序:

  1. 检查TAOTOKEN_API_KEY环境变量是否真的导出成功(echo $env:TAOTOKEN_API_KEY)
  2. 检查config.toml里base_url是否写成了https://taotoken.net/api,不要多拼路径
  3. 检查model字段的模型名是否和接入文档一致

接入文档:https://taotoken.net/doc?utm_source=taotoken_aicg_blog_end&utm_content=doc&utm_campaign=rewrite

6.3 分析结果里出现项目里没有的文件

现象:Codex 提到了你没写的文件或依赖。

原因:prompt 里没限制「只根据标准输入分析」,模型开始脑补。

解决:prompt 里加一句「不要补全文件里没有的信息」,并且把--ephemeral打开,避免上一次会话的上下文串进来。

6.4 哈希对不上

现象:运行前后哈希不一致。

排查:先确认是不是npm test自己生成了缓存文件(比如node_modules/.cache)。把哈希计算范围限定在源码目录,排除node_modules和临时文件。如果源码哈希真的变了,说明--sandbox read-only没生效,检查是不是被其他配置覆盖了。

7. 下一步:从只读分析到受控写入

只读分析跑通、哈希验证通过之后,我才愿意进入下一步:让 Codex 改一个小问题,再用git diff检查它到底动了什么。顺序不能反——先证明它读得对,再让它写得少。

如果你也想把这套流程固定下来,建议把 Key 和通道统一到 TaoToken 后台管理,模型对话、Coding Plan、API Keys 一个入口搞定,省得每次换项目都要重新配一遍:

API Keys:https://taotoken.net/api-keys?utm_source=taotoken_aicg_blog_end&utm_content=api_keys&utm_campaign=rewrite Coding Plan:https://taotoken.net/coding-plan?utm_source=taotoken_aicg_blog_end&utm_content=coding_plan&utm_campaign=rewrite

第一次让 Codex 读项目时,你更担心它看错目录、理解错依赖,还是权限没收住?我现在的答案是:先用哈希把权限这件事变成可验证的事实,剩下的担心就少了一大半。

返回列表