Codex 写的代码再让 Codex 查,我不太敢全信
OpenAI 这次发东西的方式有点怪。
代码先扔上 GitHub,公告一个字没发,结果被 Hacker News 上的人先扒了出来,官方账号才回过神来补了一条推。原话大概是这个意思,我们悄悄放出了开源的 Codex Security CLI,但 Hacker News 在我们来得及在这儿说之前就发现了它。
等我去翻仓库的时候,星标已经从发布当天的一千五涨到三千七,fork 两百多。一天翻了一倍还多。
好家伙,这就是「悄悄」。
东西本身一句话能讲完,一个命令行工具加一个 TypeScript SDK,用来找、验证、修代码里的安全漏洞。装法也简单得没什么好写的。
npm install @openai/codex-security
npx codex-security login
npx codex-security scan .
Apache-2.0 协议,要 Node.js 22 以上、Python 3.10 以上。CI 里不做交互式登录,改成环境变量塞 OPENAI_API_KEY 就行。
到这儿为止,是所有号今天都会写的那一段。我想聊的不在这儿。
我想聊的是,一个天天在你 IDE 里写代码的模型,现在要顺手把审查它自己产物的活也接过去了。以及,这工具的文档里藏着两个字段,坦白得让我有点意外。
静态扫描这块,积怨已久
先说点背景,不然后面那个转折没有重量。
代码安全扫描这行叫 SAST,静态应用安全测试,翻译成人话就是不跑代码,光读源码找漏洞。Semgrep、CodeQL、Bandit,做后端的多少都在流水线里见过其中一个。
这类工具的老毛病是什么,用过的都懂,误报。
它的工作方式是模式匹配,你写了一条规则说「拼接 SQL 字符串的地方标红」,那它就把所有拼字符串的地方都标红,管你那个变量是不是从环境变量里读出来的常量。规则写得松,一次扫描给你吐两千条,团队看两周就麻木了;规则写得紧,真漏洞从指缝里溜走。
我见过太多团队最后的选择是把它挂在流水线上但不阻断,红了就红了,反正没人看。安全部门有报表,研发有清净,各自安好。
这不是工具不行,是模式匹配这条路本身有天花板。一段代码到底危不危险,取决于它周围那一圈东西,谁调它、参数从哪来、有没有中间做过校验。这些信息模式匹配读不到。
Codex Security 的官方说法就是冲着这个来的,它不靠规则命中,靠模型做上下文分析,判断这段代码在它实际所处的环境里会怎么跑,然后给出有意义的发现,还直接产出一个你能 review 的补丁。
流程是三段,扫描、验证、修复。中间那个「验证」我觉得是关键,它是专门用来确认这条发现是不是真的,而不是丢给你一堆疑似让你自己甄别。
坦率讲,这个方向我是认的。误报问题拖了这行十几年,规则派已经卷到头了,换个思路是对的。
然后我在文档里看到了 unknown
上手部分我跳过,直接说文档里让我停了一下的地方。
一次扫描跑完,它会在你本地吐一堆产物文件。findings.json 是漏洞明细带严重级别和修复建议,report.md 是给人看的摘要,results.sarif 是标准格式导出,能直接喂给 GitHub Code Scanning 这类现成的看板。
这些都正常,直到我看到第三个文件,coverage.json。
覆盖率报告,状态分三档,complete、partial、unknown。
意思是这次扫描它自己知道哪些地方看全了,哪些只看了一部分,哪些它自己也不知道有没有看明白。文件里还会列出「未解答的问题」。
我盯着 unknown 这个词看了会儿。
传统扫描器从来不给你这个东西。CodeQL 跑完就是一份命中列表,没命中的地方默认就是干净的,它不会跟你说「这个模块的数据流我没跟下去」。这种沉默不是因为它更强,是因为规则引擎压根没有「我不确定」这个状态,规则匹上就是匹上,没匹上就是没匹上。
模型有。而且 OpenAI 选择把它暴露出来,而不是藏起来假装扫全了。
这是我今天看到最有诚意的一个设计,也是最劝退的一个。
有诚意,是因为它把不确定性明明白白摆在你面前,你至少知道自己的防线上哪块是虚的。
劝退,是因为你现在要面对一个以前不用面对的问题。绿灯不再等于安全,绿灯只等于「它扫过的那部分安全」。你得多看一个文件,才知道这次绿灯有几分成色。
很多团队接安全工具的心理预期是「装上,然后不用想了」。这工具从设计上就不让你这么干。

我是真的觉得这一点值得单拎出来说,因为它不只是一个字段的事。你手里所有让模型帮你干活的东西,其实都有这个 unknown,只是绝大多数没写出来。
扫一次要多少钱
第二个让我坐直的细节是 --max-cost。
这个参数用来设单次扫描的花费上限,防止模型用量失控。文档里还有个 --dry-run,本地校验输入,明确说了不触发 API 调用。
反过来读就是,正式扫描是要调模型的,是要花钱的,而且花多少事先不太好说,得给个天花板兜着。
这是 SAST 这行以前没有的成本模型。CodeQL 你想跑一万次也就是那台 runner 的电费,扫描成本约等于零,所以大家的习惯是每次 push 都全量扫一遍,反正不心疼。
现在这个习惯得改。
你要是把 scan . 挂在每个 PR 上全仓库跑,一个中等规模的仓库、一个活跃的团队,那个账单曲线自己想。
好在工具方也想到了,它给了四种扫描粒度,我觉得这几个才是真正决定你能不能用起来的东西。
标准扫描是全仓库分析,适合季度体检,不适合天天跑。 路径扫描只扫指定的服务或者包,改哪扫哪。 diff 扫描扫两个 git revision 之间的变更,这个是给 CI 准备的。 工作区扫描扫暂存区和工作区的改动,这个是给你提交前准备的。
还有一个 deep 模式做更宽的架构级审查,那个明显更贵,属于「重要版本发布前跑一次」的量级。
所以真要接进流水线,我的判断是这样的。
每个 PR 走 diff 扫描,只看这次改了什么,成本可控。全量扫描做成定时任务,一周或者一个月一次,跑在没人加班的时段。deep 模式留给大版本。
它还提供了 install-hook,装一个 pre-commit 钩子,高危发现直接卡住提交。这个我建议慎用,本地开发被一个网络请求卡住 commit 的体验,试过的应该都记得当时的心情。真要装,也是团队讨论过之后统一装,别一个人默默给自己上刑。
另外有个参数我觉得被低估了,--knowledge-base,可以把架构文档喂进去当上下文。
这个东西是模型驱动的扫描器才有的能力。你告诉它「我们这套服务前面有一层统一鉴权网关,所有请求进来都过了 JWT 校验」,它对内层服务那些看起来没做鉴权的接口的判断就完全不一样了。规则引擎理解不了这句话,模型能。
想少收一半误报,这个参数值得花半天写文档。
出题的和判卷的,是一家人
铺垫到这儿,说我最纠结的那一层。
你现在的日常大概率是这样的,用 Codex 或者别的什么让模型帮你写一坨代码,扫两眼觉得没大毛病,合了。
现在 OpenAI 告诉你,这坨代码的安全审查,也可以交给它。
同一家公司,同一个模型家族,写的是它,查的也是它。
我不是在暗示什么阴谋,OpenAI 没有动机故意放过自己写的漏洞,这生意不划算。我担心的是另一个东西,盲区是共享的。
模型的安全意识来自训练数据。它在生成代码的时候没意识到某类问题,是因为这类模式在它的认知里就不算问题。那么在审查的时候,同样的认知会让它同样看不见。
这跟人是一个道理。你写完一个函数自己 review 一百遍,都不如同事扫一眼有用,不是因为你不认真,是因为你脑子里那套假设在写的时候和读的时候是同一套。代码审查这个制度存在的全部意义,就是引入一双不共享你假设的眼睛。
现在这双眼睛,跟写代码那双是同一副瞳孔。

说实话我也不确定这个担心有多严重,我没有数据支撑,这更多是一个工程直觉。而且我得承认反过来的论证也成立,甚至可能更有力。
正因为它是写 AI 代码的那个模型,它可能反而最懂 AI 生成的代码会在哪儿出问题。模型写代码有非常固定的坏习惯,错误处理糊弄、边界条件想当然、把示例里的硬编码直接留在生产代码里。这些毛病一个熟悉自己产物分布的模型,理论上抓得比通用规则准。
OpenAI 自己的定位里就有这层意思,他们说这工具是给「大规模采用 AI 编码助手」的组织准备的,是为了更紧的反馈回路。翻译一下就是,我们知道我们的模型在你们仓库里生产了多少代码,所以我们来管管。
两种可能都存在,而且现在没人有数据判定哪个占上风。
我的结论很没劲,但我觉得是对的,把它当第二双眼睛,不要当唯一一双。
你现有的 Semgrep 或者 CodeQL 别撤,规则引擎有一个模型没有的优点,它的失败模式是确定的、可预测的、跟模型不相关的。两套东西的盲区不重合,这才是价值所在。Codex Security 支持导出 SARIF 格式,本来就是为了跟现有流水线并存,不是为了取代谁。
至于人工审查,那更是一点都不能撤。
这一轮大家都在卷刹车
再往外退一步看,会发现这不是一件孤立的事。
同一周,Google 给 Gemini API 的 Managed Agents 加了一个叫 environment hooks 的东西。官方博客写得很清楚,你可以在工具调用前后跑自定义脚本,配置放在 .agents/hooks.json 里,脚本可以直接拒绝这次操作,并且把拒绝的理由塞回模型的上下文里让它知道自己为啥被拦了。
同一批更新里还有 max_total_tokens 预算上限、可以查可以删的沙箱环境 API、定时触发。
你把这些和 Codex Security 的 --max-cost、coverage.json、pre-commit 钩子摆在一起看,会发现两家做的是同一件事。
都在给 agent 装刹车、装仪表盘、装预算表。
前两年这些平台比的是模型多能干,上下文窗口多大,跑分多高。今年下半年这一轮更新,比的东西明显换了,approval 模式怎么设计、任务中断了能不能续、成本怎么封顶、出了事怎么审计、你到底敢不敢让它自己跑完。
厉害了,这行终于开始聊工程了。
这个转向背后的现实很朴素。模型已经强到能自己干活,但企业不敢放,卡在信任上。而信任这个东西不是靠模型再强 10% 换来的,是靠可观测、可干预、可回滚这些无聊的工程能力换来的。
我给 AI 搭脚手架的那点日常,说到底也就是在干这个。让模型能干活的那层工程,八成的代码都不是在增强能力,是在兜住它可能翻的车。
所以看到这一轮平台竞争终于卷到控制面,我是有点高兴的。
那到底要不要装
回到最实际的问题。
如果你的团队现在大量用 AI 写代码,而安全审查还停留在「有个扫描器挂着但没人看报表」的状态,我觉得这东西值得花一个下午试。Apache-2.0,本地跑,--dry-run 先不花钱验证一遍配置,试错成本很低。
上手路径我建议这样,先对一个你最熟的服务跑一次路径扫描,不要一上来全仓扫。跑完先别看 findings.json,先打开 coverage.json,看它说自己看全了多少。这一步能让你对这工具的实际能力形成一个校准,比看多少条发现有用得多。
然后拿一两条它报的高危,人工去核一下是不是真的。核完你心里就有数了。
至于要不要接进 CI,我的建议是先接 diff 扫描,不阻断,跑两周攒数据。两周后拉出来看误报率和成本,再决定要不要升级成阻断。
千万别在还不知道它误报率的时候就设成 required check,那大概率会以整个团队集体绕过它收场,最后比不装还糟。
还有一条,扫描是要把代码送出去的。你们公司对源码出网有规定的话,这件事得先过合规,别自己偷偷装。这不是危言耸听,是很多团队真正卡住的地方。
最后
其实我挺喜欢 OpenAI 这次的姿态。
他们自己在推文里写的是「这是一次早期发布,我们在听你们的反馈」,而且是先扔出来才想起来发公告。文档里也老老实实留了 unknown 这一档。
这跟发布会上那套「全面提升、显著增强」的话术是两种东西。后者听着舒服但你不知道该信几分,前者难看但你知道边界在哪。
我一直觉得,工具告诉你它做不到什么,比告诉你它能做到什么更值钱。因为前者你能围着它做设计,后者你只能围着它做祈祷。
Codex Security 至少给了你一张标注了未探明海域的海图。
至于那片 unknown 里到底有没有礁石,那还得你自己开船进去看。
小心点开。