github@openai/codex 里,模型生成的 diff 是什么格式,udiff 吗?

创建于:2025年9月27日

使用 GPT-5 Thinking 回答 Chat01

问题

github@openai/codex 里,模型生成的 diff 是什么格式,udiff 吗?

思考

Explaining custom patch format

The tool isn't rendering text content, but we can still cite the search result sources. The answer should clarify that the model uses a custom "apply_patch" format, not udiff. I'll provide an example snippet, but remember citations can't go inside the code block—I'll note them in the text. Hunks in "Update File" are similar to unified diff with @@ headers and +/- lines. I'll verify this.

Providing patch format example

Here's a minimal example of the custom "apply_patch" format:

text
*** Begin Patch *** Add File: hello.txt +Hello *** Update File: src/app.py @@ -print("Hi") +print("Hello") *** Delete File: old.txt *** End Patch

Remember, no citations should be inside the code block—place them after the paragraph. It's a simplified, file-oriented format that’s easy to parse, safe to apply, and uses unified diff style in its hunks. I'll also link to the relevant documentation later.

Providing concise technical answer

Codex uses a custom "apply_patch" format instead of standard unified diff (udiff). The format has a clear structure, with headers like "Begin Patch" and "End Patch". Hunks are similar to those in udiff, using '@@', '+' and '-' lines, with "Move to:" for renames. References: Codex Docs (website), open issue (website), gpt-oss doc (website), aider doc (website).

Thought for 48s

回答

不是标准的 unified diff(udiff)。在 GitHub 的 openai/codex 仓库里,代码编辑是通过一个为 AI 助手设计的自定义 apply_patch 补丁格式完成的:它用“*** Begin Patch…*** End Patch”作为包裹,并在里面按文件进行操作(Add File / Delete File / Update File 等)。(GitHub)

这个格式在“更新文件”时会用到与 udiff 相似的“hunk”语法:以 @@ 引导的区块头,行首 +/- 表示增删,但整体仍属于 Codex 的自定义封装(还支持如 Move to: 的重命名声明)。(GitHub)

需要注意的是,社区里也提到过该格式的细节标记曾有过调整(例如 *** Begin Patch 标记的变体),说明它在迭代中,但本质仍是上述自定义“apply_patch”而非纯 udiff。(GitHub)

作为对比,像 Aider 这类工具使用的是改良的 udiff 编辑格式——这与 Codex 的 apply_patch 不是一回事。(Aider)

简化示例(示意):

text
*** Begin Patch *** Add File: hello.txt +Hello, world! *** Update File: src/app.py @@ -print("Hi") +print("Hello, world!") *** Delete File: obsolete.txt *** End Patch

(上例为 Codex 自定义“apply_patch”风格,并非标准 udiff。)

问题

codex 是如何 apply 那个 patch 的?

思考

Explaining apply_patch tool

The apply_patch tool is invoked within the CLI, meaning no external binary is used. It can either be structured as a tool call or intercepted by the CLI as a pseudo-shell command with the --codex-run-as-apply-patch flag. The applier handles file operations like adding, updating, deleting, and moving files. There are safety checks with approval modes, requesting confirmation unless set to auto. I’ll reference issues, like 2235 and 2030, for specific examples.

Describing patch process details

The apply_patch tool includes approval workflows, and security guardrails are mentioned in issue 802 for user approvals. In Windows, workspace boundaries are checked, with prompts appearing as needed. The Rust crate uses "similar::TextDiff" for diffing hunks, helping with near-matches and fuzzy searches. I'll cite relevant module usage and documentation for clarity.

Explaining patch tool functions

The tool uses "similar::TextDiff" and a "seek_sequence" helper to locate hunk positions, as referenced in the lib.rs file. Although we couldn't view the content, a snippet on the GitHub page confirms the usage. I'll cite the source with careful language, ensuring not to go beyond what’s supported. The tool aborts and prints an error if a hunk fails to apply, as seen in issue 2295.

Explaining patch tool summary and invocation range

The tool may print a brief Git-style summary via the "print_summary" function, as listed in the agcodex-apply-patch documentation. It's safer to say, "the Rust applier can print a Git-style summary" while referencing docs.rs. Also, the CLI detects apply_patch in Heredoc forms, as noted in issue 2235.

Thought for 1m 39s

回答

简短说:Codex 并不会真去调用系统里的 apply_patch 可执行文件。当模型生成补丁时,它把补丁作为“虚拟工具调用”交给 Codex CLI,CLI 用内置的 Rust 实现去解析→校验→写盘;必要时再向你请求批准。(GitHub)

下面按实际流水线讲清楚它“如何 apply”:

  1. 触发方式
    模型会发出一条“像 shell 一样”的调用(例如 shell {"command": ["apply_patch","<PATCH>"]})。CLI 会拦截这类命令并在进程内处理,或者以 --codex-run-as-apply-patch "<PATCH>" 模式自调用;所以你在 bash 里不会找到真正的 apply_patch 二进制。(GitHub)

  2. 解析补丁
    补丁是 Codex 的自定义封装格式:最外层 *** Begin Patch … *** End Patch,里面由若干“文件操作段”组成:

  • *** Add File: <path>(创建并写入 + 行)
  • *** Update File: <path>(使用 @@ 区块 + +/- 行做行级修改)
  • *** Delete File: <path>
  • 可选 Move to: <new-path>(文件移动/改名)
    这些写在官方说明与 issue 示例里。(GitHub)
  1. 安全与审批
    在只读工作区或需要审批的模式下,CLI 会阻止直接写盘并提示你授予写入/批准;也做路径规范化来防止目录穿越等风险。(GitHub)

  2. 应用逻辑(Update File 的核心)
    CLI 的 Rust 库把文件内容读入后,按 @@ hunk 逐段匹配上下文并应用增删行;当行号/上下文有轻微偏移时,它会用相似度/序列寻位算法尽量找到合适位置再贴合(源码里能看到使用 similar::TextDiff 以及 seek_sequence 帮助定位)。定位失败则报错并中止当前文件的打补丁。(GitHub)

  3. 写盘与结果
    成功时写回磁盘并更新会话状态;失败时你会在日志里看到诸如“Failed to apply patch / Failed to write file …”之类的报错。(GitHub)

  4. 无需你手动跑 git apply
    官方建议把改动交给 apply_patch 来做(便于回滚/审阅),并配合 Git 的分支与小步提交来管理这些补丁。(OpenAI Developers)

一个最小例子(模型实际会用“工具调用”,这里仅示意):

text
shell {"command": ["apply_patch", "*** Begin Patch *** Update File: src/app.py @@ -print('Hi') +print('Hello, world!') *** End Patch "]}

这会触发 Codex CLI 的内置补丁器去定位并改写 src/app.py;若工作区是只读或审批未通过,就会被拦下并提示处理。(GitHub)

如果你要在 CI/无人值守里启用它,确保配置里打开 include_apply_patch_tool(近期有修复让 exec 模式正确读取该开关)。(GitHub)

需要我给你一份可复制的“最小补丁模板”和常见失败排查清单吗?

问题

我自己有一个程序想复用他这个 apply_patch 流程,他提供独立的实现吗

思考

Clarifying apply_patch availability

The official implementation isn’t available as a separate library or CLI tool; it’s embedded within the Codex monorepo. You can reuse it by either adding it as a Git submodule or vendoring the code, all under the Apache-2.0 license. Citations should include the instructions document and relevant issue tracking this information.

Providing code path and license details

For non-Rust programs that want to reuse the tool, there are two options:

  1. Call the Codex binary with the --codex-run-as-apply-patch flag. Set config to auto-approve and ensure "include_apply_patch_tool = true".

  2. Use the community-maintained packages like "codex-apply-patch" (PyPI) or on GitHub. Be mindful of CRLF line-ending issues where applicable.

Also, check the relevant spec document for implementation details.

Answer summary

This is

Thought for 1m 30s

回答

短答:官方没有单独发布一个“apply_patch”可执行文件或独立库;它是 Codex CLI 里的“虚拟工具”,实现代码在 monorepo 的 Rust 子包中。你可以通过两种方式复用:要么调用 Codex 可执行文件的专用入口,要么直接复用/移植那段 Rust 实现;此外也有社区打包的独立实现可用。(GitHub)

怎么选:

  1. 最省事:外部调用 Codex 可执行文件
    直接把补丁文本交给 Codex 二进制:codex --codex-run-as-apply-patch "<PATCH_TEXT>"(Codex 内部会解析并写盘;无需系统里有真正的 apply_patch 命令)。配置里记得启用 include_apply_patch_tool。(GitHub)

  2. 嵌入式:复用官方 Rust 实现
    代码在 codex-rs/apply-patch/src/lib.rs,仓库为 Apache-2.0 许可,可以按需要 vendor 或用 Git 依赖方式复用(官方没在 crates.io 单独发布包)。(GitHub)

  3. 社区独立实现(非官方)

    • PyPI:codex-apply-patch(含 CLI 与 Python 绑定,基于 OpenAI 原实现扩展而来)。(PyPI)
    • GitHub:nikhil-pandey/codex_apply_patch(Rust 核心 + PyO3 绑定,支持内存中打补丁等功能)。(GitHub)
    • Rust crate(第三方):agcodex-apply-patch,提供 parse_patch / apply_patch 等函数。(Docs.rs)

额外提示

  • 补丁格式与用法见官方说明文档(*** Begin Patch/*** End Patch 封装 + 按文件操作 + @@ hunk)。(GitHub)
  • 近期改动包括 CRLF 安全处理等,若自研/移植实现,注意与最新行为对齐。(GitHub)

如果你告诉我你的运行环境(语言/运行时),我可以给你对应的最小集成示例(shell/Rust/Python 皆可)。

分享这个问答