环境:Codex CLI 0.153.4 | Windows | 2026-09-05

这套机制解决什么问题

在一个已经存在本地改动的项目中,直接执行 git add .git commitgit push 容易把无关文件一起提交,也可能漏掉提交身份、敏感信息和远端分支检查。

当前配置增加了一个名为 git-delivery 的自定义子代理,专门负责 Git 提交与推送:

  1. 主代理继续负责修改代码、文章或配置。
  2. 用户明确要求“提交并推送”后,主代理把任务交给 git-delivery
  3. git-delivery 检查仓库、改动文件、提交身份和远端信息。
  4. 检查通过后,它只暂存指定文件,创建提交并推送到指定分支。
  5. 主代理等待子代理完成,然后向用户转述简短结果。

这样可以把“开发修改”和“Git 发布”分开处理。git-delivery 不负责修改业务内容,也不会继续调用其他子代理。

配置文件放在哪里

个人使用的自定义代理放在:

1
~/.codex/agents/

Windows 中通常对应:

1
C:\Users\<用户名>\.codex\agents\

本例使用以下文件:

1
~/.codex/agents/git-delivery.toml

如果只希望某个项目使用,也可以放在项目目录的:

1
.codex/agents/git-delivery.toml

git-delivery配置

下面是当前机制使用的配置示例。示例没有包含真实用户名、邮箱、仓库地址或认证信息。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
name = "git-delivery"
description = "检查敏感隐私信息、确认提交身份,然后提交并推送,只返回简短最终结果。"
model = "gpt-6-astra"
model_reasoning_effort = "high"

developer_instructions = '''
你是负责 Git 提交并推送的子代理。按用户确认的范围执行,不再调用其他子代理。

1. 检查 git、gh 的实际路径和版本。
2. 核对仓库绝对路径、远端、目标分支和需要提交的文件。
3. 检查候选文件、暂存内容和待推送提交中的敏感信息。
4. 读取最终生效的 Git 作者与提交者姓名、邮箱及配置来源。
5. 如果用户本次尚未确认提交身份,请主代理转交确认请求并等待答复。
6. 运行与改动相关的构建或测试。
7. 只暂存用户确认的明确文件,不使用 git add . 或 git add -A。
8. 检查暂存文件列表、暂存差异和空白错误。
9. 创建提交后核对提交哈希、标题、身份和文件范围。
10. 普通推送到已经确认的远端分支,不强制推送,不改写历史。
11. 查询远端分支哈希,确认推送结果。

发现敏感信息、身份未确认、暂存内容无法区分、检查失败或远端不明确时停止。
最终只返回成功或失败、提交哈希与标题、检查结果、推送状态和剩余改动。
'''

namedescriptiondeveloper_instructions 是自定义代理的必填字段。modelmodel_reasoning_effort 可以省略;省略后会根据当前 Codex 会话和全局代理设置选择模型与推理强度。

配置中的模型名称必须是当前账号和客户端可用的模型。如果指定模型不可用,可以删除 modelmodel_reasoning_effort 两行,让子代理使用当前会话的设置。

在AGENTS.md中设置调用条件

只有创建自定义代理文件,还不能保证每次 Git 操作都使用它。项目的 AGENTS.md 还需要写明何时调用,以及主代理必须传递哪些信息。

1
2
3
4
5
6
# Git 与 GitHub

- 用户明确要求 Git 提交并推送时,调用自定义子代理 `git-delivery`
- 调用时传入任务说明、仓库绝对路径、文件范围和已经确认的提交身份。
- 主代理等待子代理完成,只向用户转述必要的身份确认、失败原因或最终结果。
- 子代理执行期间,主代理不在同一仓库中并行执行 Git 写操作。

这里的触发条件是“提交并推送”。如果用户只要求检查改动、修改文章或运行构建,不应该提前调用该子代理。

实际执行过程

1. 用户明确提出提交和推送

例如:

1
将本次文章修改提交并推送到 origin/main,只包含指定文章文件。

这句话同时说明了操作、远端分支和文件范围。范围越明确,越不容易把工作区中的其他改动带入提交。

2. 主代理传递任务

主代理调用 git-delivery 时,至少传递:

  • 仓库的规范化绝对路径;
  • 需要暂存的准确文件列表;
  • 目标远端和分支;
  • 计划使用的提交标题;
  • 用户本次是否已经确认提交身份;
  • 项目要求执行的构建或测试命令。

文件列表应当逐项写出,不能使用通配符,也不能用“全部当前改动”代替可以确认的路径。

3. 子代理执行只读检查

git-delivery 先读取以下信息:

1
2
3
4
5
6
7
git rev-parse --show-toplevel
git status --short --branch
git diff --cached --name-status
git remote -v
git branch -vv
git config --show-origin --get user.name
git config --show-origin --get user.email

这些命令用于确认仓库、分支、现有暂存内容、远端地址和 Git 身份。检查过程不应输出令牌、密码、Cookie、私钥或其他认证内容。

普通 Git 推送使用 Git 自己的凭据助手。只有任务需要操作 Pull Request、Release、Actions 等 GitHub 功能时,才必须检查 gh 的登录状态。缺少 gh 不应直接阻止普通 git push

4. 确认提交身份

提交身份包括作者和提交者的姓名、邮箱。子代理会读取实际生效的配置及其来源,但不会擅自修改全局 Git 配置。

如果用户没有在本次任务中确认身份,子代理会暂停,并通过主代理询问:

1
本次提交将使用以下 Git 身份:<姓名> <邮箱>。是否确认?

用户确认后,主代理再让同一个 git-delivery 子代理继续执行,不需要重新创建另一个子代理。

5. 构建并检查暂存内容

子代理先运行项目要求的检查。例如 Hexo 网站可以运行:

1
npm run build

构建成功后,只暂存指定文件:

1
git add -- "blog/source/_posts/2026/示例文章.md"

然后检查实际暂存内容:

1
2
3
git diff --cached --name-status
git diff --cached
git diff --cached --check

此时检查的重点包括:

  • 暂存文件是否与用户确认的列表一致;
  • 是否混入原有改动、生成文件或无关文档;
  • 示例中是否出现真实账号、邮箱、本机路径或内部地址;
  • 是否包含令牌、密码、私钥、Cookie 或带凭据的 URL;
  • 删除、重命名和大文件是否在用户确认的范围内。

任何一项不符合要求,都应该停止提交。

6. 创建提交并推送

检查通过后,子代理创建一个普通提交:

1
git commit -m "[ADD] 添加Git推送子代理说明"

提交成功后,再次核对提交哈希、标题、作者、提交者和文件列表,然后执行普通推送:

1
git push origin main

推送后还要查询远端分支的哈希,确认远端已经指向刚创建的提交。只看到 git push 没有报错,还不能代替这一步检查。

主代理与子代理分别负责什么

操作 负责者
修改文章、代码和配置 主代理
确认要提交的文件范围 主代理与用户
检查仓库、身份和敏感信息 git-delivery
运行提交前构建或测试 git-delivery
暂存、提交和普通推送 git-delivery
核对远端提交哈希 git-delivery
向用户说明最终结果 主代理

主代理在子代理执行期间不应同时暂存、提交或推送同一个仓库,否则暂存区和分支状态可能发生变化,子代理此前的检查也会失效。

不会自动执行的操作

当前 git-delivery 只处理用户明确要求的提交和普通推送,不会自动执行以下操作:

  • 强制推送;
  • 修改旧提交;
  • 变基或压缩提交;
  • 创建或删除标签;
  • 创建 Release;
  • 创建、合并或关闭 Pull Request;
  • 修改 GitHub Secrets;
  • 删除远端分支;
  • 自动修改构建失败的代码;
  • 自动确认网站已经部署完成。

对于使用 GitHub Actions 部署的网站,推送成功通常会触发工作流,但“远端已有提交”和“网站部署成功”是两件事。如果需要等待 Actions 并检查线上页面,必须在任务中单独说明。

常见问题

找不到git-delivery

依次检查:

  1. 文件是否位于 ~/.codex/agents/git-delivery.toml 或项目的 .codex/agents/ 中;
  2. TOML 中是否存在 namedescriptiondeveloper_instructions
  3. name 是否准确写为 git-delivery
  4. 修改配置后是否重新打开了 Codex 会话;
  5. AGENTS.md 中的代理名称是否与 name 一致。

Codex 按 TOML 中的 name 识别代理,文件名只是便于管理的命名方式。

子代理停在身份确认

这是正常行为。回复确认当前姓名和邮箱后,主代理应继续调用原来的子代理,让它完成提交和推送。

推送失败但已经创建提交

本地提交不会因为推送失败自动消失。子代理应明确报告本地提交哈希、失败原因和当前分支状态。解决认证、网络或远端分歧问题后,可以在新的明确请求中再次推送,不需要重复创建同一个提交。

工作区还有其他改动

只要指定文件能够与其他改动清楚区分,子代理可以只提交指定文件。已有暂存内容无法确认归属时,应该停止,而不是擅自清空暂存区或把它一起提交。

参考资料