Codex 多项目怎么管理?Profile 切模型和 Key、Git worktree 与 GitHub Actions 实测配置

Codex 同时用于多个项目时,用 ~/.codex/项目名.config.toml 做 Profile 切模型,每把 Key 配一段 provider 由 Profile 选择,并行任务用 Git worktree 隔离,CI 用 Secret 生成 config.toml。附实测报错原文。

8 分钟阅读
Codex 多项目怎么管理?Profile 切模型和 Key、Git worktree 与 GitHub Actions 实测配置

只有一个 Codex 项目时,一个模型、一把 Key、一个目录就够了。项目一多,问题就来了:为了 A 项目改了全局配置,B 项目跟着变;两个 Codex 任务在同一个目录里同时改代码;所有项目共用一把 Key,出了问题不知道是谁在调用;最后又把 Codex 接进 GitHub Actions。

这篇按四层来拆:配置用 Profile 分开,Key 按项目分开,文件用 Git worktree 分开,CI 用 Secret 注入 Key 并收紧权限。配置写法都在 Codex CLI 0.162.1 上接 AI Code With 实际跑过。

本文参数说明都附了 OpenAI 官方文档出处,主要来自 Codex Advanced Configuration 和 Codex Configuration Reference。

1. 四层隔离:配置、Key、文件、权限

隔离层解决什么问题用什么
配置层不同项目用不同模型或参数Codex Profile(--profile)
Key 层知道是哪个项目在调用,出问题只停一把每个项目一个 provider、一把 Key
文件层并行任务互不覆盖Git worktree
权限层自动化只拿到必要的能力GitHub Secret + 最小 permissions

这四层不能互相替代:Profile 能切模型,但挡不住两个任务同时改同一批文件;worktree 能隔离文件,却不会帮你分开 Key。

2. 先写好全局 config.toml

第一步,在控制台为每个项目各创建一把 Key,名字能看出用途,例如 codex-site-dev、codex-admin-dev:

创建 API Key →

第二步,打开 ~/.codex/config.toml(Windows 是 %USERPROFILE%\.codex\config.toml),写入完整的基础配置。默认用 aicodewith 这个 provider:

toml
model_provider = "aicodewith"
model = "gpt-6.1-sol"

[model_providers.aicodewith]
name = "aicodewith"
base_url = "https://api.aicodewith.ai/chatgpt/v1"
wire_api = "responses"
experimental_bearer_token = "sk-你的Key"

用本站不需要设 API Key 环境变量,Key 直接写在 experimental_bearer_token 里。各字段的含义见《Codex config.toml 配置指南》,环境变量和这个文件冲突时谁生效见《Codex 环境变量怎么配》。

官方文档原文:model_provider 是「Provider id from model_providers」;experimental_bearer_token 是「Direct bearer token for the provider」。出处:Configuration Reference。

3. 第一层:用 Profile 给每个项目切模型

Profile 是 config.toml 旁边的一个单独文件

现在的 Codex 里,Profile 不是写在 config.toml 里的 [profiles.xxx] 小节,而是 ~/.codex 下一个名为「项目名.config.toml」的文件,里面只写和基础配置不同的那几项。

官方文档原文:「When you pass --profile profile-name, Codex loads ~/.codex/config.toml, then overlays ~/.codex/profile-name.config.toml. Profile names can contain letters, numbers, hyphens, and underscores.」出处:Advanced Configuration · Profiles。

比如官网项目用 gpt-6.1-sol,后台项目用 gpt-5.6-terra,就建两个文件。第一个是 ~/.codex/site.config.toml:

toml
model = "gpt-6.1-sol"

第二个是 ~/.codex/admin.config.toml:

toml
model = "gpt-5.6-terra"

在各自项目目录里用 --profile 启动,交互模式和 codex exec 都可以:

bash
codex --profile site
codex exec --profile admin "检查这次改动"
实测:两个 profile 各跑一次 codex exec,启动信息里分别显示 model: gpt-6.1-sol 和 model: gpt-5.6-terra,都正常回复,用时分别为 2.7 秒和 9.6 秒。

旧写法 [profiles.xxx] 会直接报错

很多旧教程还在 config.toml 里写 [profiles.xxx]。官方说明 0.134.0 起已经不再读取:

官方文档原文:「In Codex 0.134.0 and later, --profile no longer reads [profiles.profile-name] from config.toml, and the top-level profile = "profile-name" selector is no longer supported.」出处:Advanced Configuration · Profiles。

实测在 config.toml 里留着 [profiles.legacy],再运行 codex exec --profile legacy,Codex 不启动,直接报错(路径换成了 ~ 写法):

text
Error loading config.toml: --profile `legacy` cannot be used while ~/.codex/config.toml contains legacy `profile = "legacy"` or `[profiles.legacy]` config; move those settings into ~/.codex/legacy.config.toml and remove the legacy profile selector/table.

按提示把内容搬到 ~/.codex/legacy.config.toml,再删掉 config.toml 里的 [profiles.legacy] 即可。

profile 名写错不会报错

这是最容易踩的坑。实测运行 codex exec --profile proj-x,而 ~/.codex 下并没有 proj-x.config.toml:Codex 没有任何报错或提示,直接按基础配置跑完了。所以每次启动后看一眼开头的 model: 和 provider: 两行,确认是不是你要的那个项目。

4. 第二层:每个项目用自己的 Key

一个项目一个 provider,Profile 负责选

不同项目用不同 Key,做法是在 config.toml 里给每把 Key 配一段 provider,再由 profile 文件里的 model_provider 选择。在第 2 节的基础配置后面追加一段:

toml
[model_providers.aicodewith_admin]
name = "aicodewith"
base_url = "https://api.aicodewith.ai/chatgpt/v1"
wire_api = "responses"
experimental_bearer_token = "sk-后台项目的Key"

然后把 ~/.codex/admin.config.toml 改成同时指定 provider 和模型:

toml
model_provider = "aicodewith_admin"
model = "gpt-5.6-terra"

这样运行 codex --profile admin 时用的就是后台项目那把 Key;不带 --profile 时仍然用默认的 aicodewith。

实测:给一个 profile 指向一段故意填错 Key 的 provider,启动信息显示 provider: aicodewith_b,请求返回 401;同一台机器上指向正确 Key 的 profile 正常回复。说明 profile 确实切换了 Key。

profile 文件里也能直接覆盖 Key

profile 文件是叠在 config.toml 上面的一层,所以也可以在里面直接改写同一个 provider 的 Key:

toml
[model_providers.aicodewith]
experimental_bearer_token = "sk-另一把Key"

实测这样写同样生效(用错误 Key 测试时返回 401)。不过两种写法里,「一个项目一段 provider」更清楚:打开 config.toml 就能看到一共有几把 Key,profile 文件里不放 Key,复制给同事也不会带出去。

Key 命名和日常核对

Key 的名字至少要能回答:哪个工具、哪个项目、哪个环境,例如 codex-site-dev、codex-admin-dev、codex-ci-review。每周看一次各 Key 的调用记录:调用的模型对不对、最近还有没有在用,没人用的 Key 及时停用。项目不多时按项目拆;项目很多时可以按风险合并,生产独立,临时实验共用一把测试 Key。

5. 第三层:并行任务不要共用同一个工作目录

配置和 Key 分开以后,还有文件。两个 Codex 任务在同一个目录同时改代码,危险的不只是最后合并冲突,而是其中一个任务一直建立在另一个任务改到一半的状态上。Git worktree 让每个任务有自己的目录和分支,又共享同一个仓库的 Git 数据。

给每个任务一个 worktree

bash
git worktree add ../project-task-a -b codex/task-a main
git worktree add ../project-task-b -b codex/task-b main
git worktree list

然后让每个 Codex 任务只在自己的目录里工作。目录名对应任务,不要叫 tmp1、tmp2。给 Codex 的任务说明里写清楚允许改的路径、验收命令和不能碰的共享配置。

worktree 只隔离文件

两个 worktree 仍可能抢同一个 3000 端口、同一个开发数据库、同一个测试账号。并行前列一张共享资源表:哪些能分配不同端口或测试数据,哪些只能有一个任务写入。lockfile、数据库迁移和代码生成结果最容易冲突,可以指定一个任务为唯一写入者。

合并前先让每个任务成为可验证的提交

bash
git -C ../project-task-a status
git -C ../project-task-a diff --check

在 worktree 里看完 diff、跑完项目自己的测试再提交,回主分支审查后再 merge 或 cherry-pick。两个任务有依赖时,先合基础改动,再让后面的分支 rebase 并重新跑测试。

用完清理

bash
git worktree remove ../project-task-a
git worktree prune

确认提交已经进了目标分支、目录里没有要保留的改动再清理。直接删文件夹的话,Git 里还会留着 worktree 记录。

6. 第四层:在 GitHub Actions 里用 Codex

最小写法:用 Secret 生成 config.toml

在仓库的 Settings → Secrets and variables → Actions 里新建一个 Secret,名字叫 AICODEWITH_API_KEY,值是专门给 CI 建的那把 Key。然后在 workflow 里先装 Codex,再用一个步骤从 Secret 生成 config.toml:

yaml
name: codex-review
on: pull_request

permissions:
  contents: read

jobs:
  review:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v5
      - run: npm install -g @openai/codex
      - name: Configure Codex
        env:
          AICODEWITH_API_KEY: ${{ secrets.AICODEWITH_API_KEY }}
        run: |
          mkdir -p ~/.codex
          cat > ~/.codex/config.toml <<EOF
          model_provider = "aicodewith"
          model = "gpt-6.1-sol"

          [model_providers.aicodewith]
          name = "aicodewith"
          base_url = "https://api.aicodewith.ai/chatgpt/v1"
          wire_api = "responses"
          experimental_bearer_token = "${AICODEWITH_API_KEY}"
          EOF
      - name: Run Codex
        run: codex exec "只检查本次改动的错误处理,列出发现和证据,不修改文件。"
实测:把 Configure Codex 这一步的脚本放在一个干净的 HOME 下运行,Key 由环境变量传入,生成的 config.toml 接着跑 codex exec,2.9 秒返回正常回复。

几个要点:

  • Key 只出现在 Secret 和运行时生成的文件里,不写进仓库,也不要 echo 到日志。
  • permissions 从 contents: read 开始。GitHub 的 permissions 管 workflow 的 token 能对仓库做什么,Codex 自己的沙箱管它运行的命令能碰哪些文件,两层都要收紧。
  • 来自 fork 的 pull request 默认拿不到仓库 Secret,不要为了让它能跑就改成更宽的触发方式。
GitHub permissions 字段的说明见 GitHub Docs:Authenticate with GITHUB_TOKEN。

写权限跟着任务一起加

只读审查只需要读。要让 Codex 改文件、提交补丁或发评论时,再加对应的权限,而且只加这次任务需要的那一项。更稳的流程是:Codex 先产出报告或补丁,人或独立步骤检查 diff 和测试,再由受控流程提交。

Prompt 写成验收标准

在 CI 里写「优化一下代码」几乎没法验收。写清楚目标范围、不能改的区域、必须跑的检查和输出格式。规则很长时放进仓库里的文件,这个文件本身也要经过 Review。

7. 完整例子:三个项目加一个 CI

场景启动方式Key(provider)文件隔离
官网开发codex --profile sitecodex-site-dev(aicodewith)独立 worktree
后台开发codex --profile admincodex-admin-dev(aicodewith_admin)独立 worktree
SEO 脚本codex --profile seocodex-seo-ops(aicodewith_seo)独立分支
PR 审查GitHub Actionscodex-ci-review(Secret 注入)CI 的 checkout

配置差异靠 Profile,调用归属靠 Key,并行改代码靠 worktree,CI 用独立 Secret 和只读权限,最后交付仍然以 diff、测试和 Review 为准。

8. 常见报错

401:请在请求中提供有效的 API Key

profile 指向的 provider 里 Key 填错或已失效时,实测输出:

text
ERROR: unexpected status 401 Unauthorized: {"error":"请在请求中提供有效的 API Key。"}, url: https://api.aicodewith.ai/chatgpt/v1/responses

先看启动信息里的 provider: 是哪一段,再去 config.toml 里核对那一段的 experimental_bearer_token。更多情况见《Codex 401 Unauthorized 怎么解决》。

模型不存在或未上线

profile 里写了本站没有的模型名时,实测输出:

text
ERROR: {"error":"模型 gpt-5.5 不存在或未上线,请前往 https://aicodewith.com/zh/dashboard/pricing 查看可用模型列表 (request_id: ...)"}

把 profile 文件里的 model 改成控制台模型列表里有的名字,例如 gpt-6.1-sol。

--profile 报 legacy 配置错误

config.toml 里还留着 [profiles.xxx] 时会报这个错,原文和处理方法见第 3 节。

常见问题

Profile 能不能单独换 Key?

能。推荐给每把 Key 配一段 provider,在 profile 文件里用 model_provider 选;也可以在 profile 文件里直接覆盖同一个 provider 的 experimental_bearer_token。两种实测都生效。

为什么我写的 [profiles.work] 不生效?

0.134.0 起 Codex 不再读 config.toml 里的 [profiles.xxx]。把内容挪到 ~/.codex/work.config.toml,并删掉原来的小节。

--profile 名字打错了会怎样?

实测不会报错,Codex 直接按基础配置运行。启动后看开头的 model: 和 provider: 两行确认。

多个项目要设 API Key 环境变量吗?

不用。Key 写在 config.toml 各 provider 的 experimental_bearer_token 里,profile 负责选择。只有 CI 里是先用 Secret 注入环境变量,再生成 config.toml。

只有一把 Key,Profile 还有用吗?

有。可以只用 Profile 切模型,比如日常用 gpt-6.1-sol,简单任务换一个更快的模型。

其他工具(OpenCode、WorkBuddy)也要分项目吗?

思路一样。具体配置见《Codex、OpenCode、WorkBuddy 模型怎么配》。

免费注册 AI Code With,给 Codex 配一个专用 Key →

相关阅读

资料来源