正文内容
Codex Agent 技能
将 Codex CLI 作为受管编码代理运行——从工作树(worktree)搭建,直至 PR 合并完成。
前置条件
codex --version # 验证是否已安装
# 安装方式:npm i -g @openai/codex 或 brew install codex
tmux -V # 全流程依赖 tmux
CLI 快速参考
| 标志 | 效果 |
|---|---|
exec "prompt" |
非交互式单次执行,完成后立即退出 |
--full-auto |
-s workspace-write 的别名(自动批准文件修改) |
-s workspace-write |
可读写工作区内的文件 |
-s read-only |
仅分析,禁止任何修改(exec 默认模式) |
-s danger-full-access |
全权限访问,包括网络与系统调用 |
--dangerously-bypass-approvals-and-sandbox |
跳过全部确认提示 + 禁用沙箱(在容器/虚拟机中安全) |
-m |
模型选择 — 仅当用户显式指定模型时使用(例如 gpt-5.1-codex-max)。省略则使用 Codex 默认模型。 |
-c "model_reasoning_effort=high" |
推理强度:low、medium、high
|
--json |
输出结构化 JSON Lines 格式 |
-o |
将最终输出写入指定文件 |
-C / --cd
|
设置工作目录 |
--add-dir |
允许向额外目录写入文件 |
--skip-git-repo-check |
在非 Git 目录中运行 |
resume --last |
使用新提示恢复上一个会话 |
完整工作流:任务 → 已合并 PR
第一步:创建 Worktree
为每个任务隔离独立的 worktree 和分支:
TASK_ID="feat-custom-templates"
BRANCH="feat/$TASK_ID"
REPO_ROOT=$(git rev-parse --show-toplevel)
WORKTREE="/tmp/worktrees/$TASK_ID"
git worktree add -b "$BRANCH" "$WORKTREE" origin/main
cd "$WORKTREE"
# 安装依赖(按实际技术栈调整)
pnpm install # 或:npm install / go mod tidy / pip install -r requirements.txt
第二步:在 tmux 中启动 Agent
以交互模式(不带 exec)启动 Codex,以便任务中途人工引导。
重要提示:使用 tmux pipe-pane 记录日志 —— 切勿使用 | tee,因为管道会将 stdout 转为非终端(non-TTY)流,导致 Codex 检测到 !isatty(stdout) 后禁用交互功能,从而破坏 send-keys 引导能力。
LOG_FILE="/tmp/worktrees/$TASK_ID/codex-output.log"
# 1. 创建会话(启动一个 shell,此时尚未运行 codex)
tmux new-session -d -s "$TASK_ID" -c "$WORKTREE"
# 2. 在启动 codex **之前**启用日志捕获 —— 防止丢失初始输出
# stdbuf -oL = 行缓冲写入,确保 tail -f 实时显示进度
# (普通 cat 写入文件时会全缓冲,造成监控延迟)
tmux pipe-pane -t "$TASK_ID" -o "stdbuf -oL cat >> $LOG_FILE"
# 3. 通过 send-keys 启动 codex —— 从第一条输出即被完整捕获
# 退出码追加至日志末尾,便于可靠判断执行状态(否则 tmux 关闭会话时会丢弃该值)
tmux send-keys -t "$TASK_ID" \
'codex -c "model_reasoning_effort=high" \
--dangerously-bypass-approvals-and-sandbox \
'"'"'你的详细提示内容。
任务完全完成后,请执行:
1. 使用描述性信息提交所有变更:git commit -am "..."
2. 推送分支:git push -u origin '"$BRANCH"'
3. 创建 PR:gh pr create --fill
4. 发送完成通知:openclaw system event --text "Done: '"$TASK_ID"'" --mode now'"'"' \
; echo "CODEX_EXIT=$?" >> '"$LOG_FILE" Enter
为何采用此顺序(session → pipe-pane → send-keys)?
-
避免竞态条件:若直接将命令传给
tmux new-session,pipe-pane启用前产生的输出将无法写入日志; -
捕获退出码:
echo "CODEX_EXIT=$?"显式追加退出码至日志,可明确区分成功与崩溃(否则 tmux 会话关闭时自动丢弃); -
行缓冲日志:
stdbuf -oL确保tail -f $LOG_FILE可实时响应。
为何必须使用交互模式(不带 exec)?
- 支持任务中途通过
tmux send-keys动态引导; - Agent 可随时重定向,无需终止并重启;
-
--dangerously-bypass-approvals-and-sandbox在容器/沙箱环境中是安全的。
第三步:注册任务
在 JSON 注册表中统一跟踪所有活跃任务:
mkdir -p "$REPO_ROOT/.clawd"
TASKS_FILE="$REPO_ROOT/.clawd/active-tasks.json"
# 若文件不存在则初始化
[ -f "$TASKS_FILE" ] || echo '{"tasks":[]}' > "$TASKS_FILE"
# 注册当前任务
jq --arg id "$TASK_ID" --arg branch "$BRANCH" --arg wt "$WORKTREE" \
'.tasks += [{
"id": $id,
"agent": "codex",
"branch": $branch,
"worktree": $wt,
"tmuxSession": $id,
"status": "running",
"startedAt": (now|floor),
"pr": null,
"retries": 0,
"checks": {}
}]' "$TASKS_FILE" > /tmp/tasks.$$.json && mv /tmp/tasks.$$.json "$TASKS_FILE"
第四步:监控与人工引导
# --- 状态检查
## 智能重试策略
Agent 失败时,**应分析失败原因并优化提示词**,而非盲目重试。
| 失败类型 | 表现 | 重试策略 |
|---|---|---|
| 上下文溢出 | Agent 循环输出、生成乱码或任务中途卡住 | 缩小范围:*"仅聚焦于文件 X、Y、Z"* |
| 方向错误 | Agent 实现了与原始意图无关的功能 | 明确纠偏:*"停止。客户需要的是 X,不是 Y。需求说明:..."* |
| 信息缺失 | Agent 对架构做出错误假设 | 补充上下文:*"认证使用 JWT,参见 src/auth/jwt.ts"* |
| CI 失败 | PR 合并后测试、Lint 或类型检查失败 | 附上 CI 日志:*"修复以下测试失败:..."* |
| 构建失败 | 依赖缺失或版本不兼容 | 重试前预装依赖 |
**最多重试 3 次。** 超过后需人工介入。
RETRY=$((RETRY + 1))
if [ "$RETRY" -gt 3 ]; then
openclaw system event --text "