把 Codex CLI 放进定时任务,听起来像是一个极客玩具,但实际用起来之后,它已经成了我每天工作流里不可缺的自动化角色。我现在每天会跑 3 个 Codex 定时任务:早上生成前一天的代码变更摘要,周日晚上生成周报初稿,深夜把零散阅读记录整理成结构化知识卡片。这三个任务都跑在 crontab 和 launchd 上,不依赖打开终端手动敲 prompt。
这篇文章会把这 3 个 Codex 定时任务的完整设计思路、Shell 脚本、cron 表达式、验证方式写出来,也会把调试过程中真正卡住我的几个问题整理成排错清单。你可以直接复制脚本改成自己的仓库和输出目录,也可以在理解原理之后,把它迁移到 Java 项目、xxl-job 或 Quartz 这类调度框架里。
1. 为什么要把 Codex CLI 改成定时任务
1.1 Codex CLI 不只有交互式对话一种用法
很多人在终端运行codex时,进入的是交互式对话界面:输入一句需求,Codex 给出修改建议或直接改文件。这种模式适合“我当时就在电脑前,能立刻检查结果”的场景。
但定时任务的场景完全不同:凌晨 1 点没有人在终端前,任务需要在固定时间自动启动,跑完之后把结果写到某个目录。这要求 Codex CLI 能支持非交互式执行。
Codex CLI 提供的exec子命令就是为这种场景设计的。它可以接收一段 prompt,执行完成后退出,而不是进入对话循环。常见的使用方式是把 prompt 通过管道传给codex exec,或者直接把 prompt 放在参数里。
codex exec "用一句话解释什么是 HTTP 状态码 429"这条命令会输出 Codex 对 prompt 的回复,然后退出。定时任务要做的就是:把要处理的数据整理成 prompt,在固定时间触发codex exec,再把标准输出重定向到 Markdown 文件。
1.2 定时执行解决的是“人机协作频率”问题
手动使用 Codex 时,工作模式通常是“我现在有一个想法,立刻打开终端问一次”。这种模式下,Codex 的价值取决于你什么时候想起来用它。
定时任务改变了这个逻辑。它把“想起用 Codex”从人脑判断变成了系统行为。每天固定时间点,脚本自动收集 git 提交、文件变更、阅读记录,把这些数据整理成 prompt,再调用 Codex 生成结构化结果。人只需要在早上或周末花几分钟确认结果,而不是从零开始回忆、梳理、写作。
从工程角度拆解,Codex 定时任务本质上是一条流水线:
- 数据源:git 仓库、文件系统、Markdown 文件。
- 收集脚本:用
git log、find、cat等命令把原始数据提取出来。 - prompt 构造:把原始数据包进一段明确的指令文本。
- 执行体:
codex exec调用模型。 - 输出层:Markdown 文件、日志文件、错误捕获。
后文三个任务都是这套流水线的不同实例。任务之间的差别不是工具不同,而是“数据源不同、prompt 意图不同、输出规范不同”。
2. 环境准备:先让 Codex 在非交互模式下跑通
在写任何定时任务之前,必须先确认三件事:Codex CLI 已安装、已登录、能在非交互模式下执行并返回结果。这三件事有一个没确认,后面所有定时任务都会在凌晨静默失败。
2.1 安装、登录与版本确认
不同系统安装 Codex CLI 的方式略有差异。常见的全局安装命令是 npm 方式:
npm install -g @openai/codex具体包名和版本要以你当前使用的 Codex 文档为准,因为 CLI 版本更新很快,包名或参数可能调整。安装完成后,先确认可执行文件存在:
codex --version如果命令不存在,说明全局 npm bin 目录没有加入 PATH,或者安装阶段出了问题。检查方式:
which codex正常输出应该是一个绝对路径,例如/usr/local/bin/codex或$HOME/.local/bin/codex。如果which没有输出,先检查 npm 全局目录:
npm config get prefix ls -la "$(npm config get prefix)/bin"登录步骤也要提前完成。Codex CLI 使用前需要完成身份认证,认证方式以官方文档为准。登录成功后,Codex CLI 会保存凭据,后续非交互命令不需要重复登录。
2.2 先跑一条最小 prompt,验证全链路
安装完成不是终点,必须用exec子命令验证一次非交互调用,因为定时任务和交互模式的调用路径不同。执行:
codex exec "只回答:链路通"如果能正常输出结果,说明 CLI 本身没问题。如果提示exec不是有效子命令,说明当前版本的主命令结构不同,需要执行codex --help查看当前支持的命令。
这里要注意一个关键点:不要跳过这一步直接配置 cron。定时任务最大的问题是“没有现场可调试”,一旦失败,你只能看日志。提前在终端跑通,等于排除了命令行本身的问题,后续故障只会出现在定时环境、PATH、模型名或数据源上。
2.3 记录 codex 二进制绝对路径
定时任务运行时,环境变量来自 crontab 或 launchd,不是你的交互 shell。它会使用最小 PATH,可能不包含 npm 的全局 bin 目录。为了避免“终端能跑、cron 不能跑”的经典问题,在准备阶段就记录下codex的绝对路径。
command -v codex得到的路径,例如/usr/local/bin/codex,后面写脚本时可以直接引用,或写进脚本开头的 PATH 里。这是一个很小的准备动作,但能省掉大量排查时间。
3. 任务一:每天早上生成前一天的代码变更摘要
3.1 思路与数据源
这个任务要解决的是“每天早上打开仓库,想快速知道昨天改了什么”。手动做这件事需要执行git log、git diff,再逐条看提交信息,遇到不规范的提交信息还要翻代码。Codex 定时任务把这一步完全自动化。
数据源只有一个:目标仓库的 git 历史。脚本固定进入仓库目录,用git log拉取最近 24 小时的提交记录,再用git diff --stat拉取文件变更统计。两部分文本拼接成 prompt,交给codex exec生成中文摘要。
目录结构如下:
~/.codex-jobs/ ├── daily_summary.sh ├── weekly_report.sh ├── knowledge_card.sh └── logs/所有脚本放在~/.codex-jobs下,日志统一输出到logs/,方便排查。
3.2 脚本实现
#!/usr/bin/env bash set -euo pipefail REPO_DIR="${1:?用法: $0 /path/to/repo}" OUTPUT_DIR="${CODEX_OUTPUT_DIR:-$HOME/Documents/codex-daily}" TODAY="$(date +%F)" LOG_DIR="$HOME/.codex-jobs/logs" LOG_FILE="$LOG_DIR/daily-$TODAY.log" mkdir -p "$OUTPUT_DIR" "$LOG_DIR" if [ ! -d "$REPO_DIR/.git" ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] REPO_DIR 不是 git 仓库: $REPO_DIR" >> "$LOG_FILE" exit 1 fi cd "$REPO_DIR" COMMIT_LOG=$(git log --since="24 hours ago" --pretty=format:'%h %s (%an)' --date=short 2>>"$LOG_FILE") DIFF_STAT=$(git diff --stat HEAD~1 2>>"$LOG_FILE" || true) if [ -z "${COMMIT_LOG:-}" ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] 最近 24 小时没有提交" >> "$LOG_FILE" echo "最近 24 小时没有新的代码提交。" > "$OUTPUT_DIR/daily-$TODAY.md" exit 0 fi PROMPT="你是一个技术负责人。请根据下面的 git 提交记录和变更统计,生成一份面向开发者的每日代码变更摘要。 要求: 1. 按模块或功能点分类,不要逐条翻译 commit message。 2. 先写总变更趋势,再写关键变更点。 3. 如果提交涉及 bug 修复、接口变化、数据库变更,单独标注。 4. 输出 Markdown 格式,中文回答。 以下是原始 git 数据: ----- commit log ----- $COMMIT_LOG ----- diff stat ----- $DIFF_STAT" { echo "$PROMPT" } | codex exec > "$OUTPUT_DIR/daily-$TODAY.md" 2>>"$LOG_FILE" echo "[$(date '+%Y-%m-%d %H:%M:%S')] 生成完成: $OUTPUT_DIR/daily-$TODAY.md" >> "$LOG_FILE"脚本里几个关键点:
set -euo pipefail:一旦某条命令失败,脚本立即退出,避免输出一个半截文件。git diff --stat HEAD~1:用上一次提交作为对比点,比依赖 reflog 的HEAD@{1}更稳定,尤其适合 cron 环境。- 空提交判断:如果 24 小时没有提交,直接生成提示文件,不调用 Codex。这样可以避免把手写提示词错误当作“生成结果”。
- 重定向策略:正常输出写入 Markdown 文件,错误输出追加到日志文件。
3.3 cron 配置与验证
假设每天早上 8 点 30 分执行,编辑 crontab:
crontab -e加入一行:
30 8 * * * /bin/bash /Users/yourname/.codex-jobs/daily_summary.sh /path/to/your/repo >> /Users/yourname/.codex-jobs/logs/cron-job1.log 2>&1注意三个细节:
- 使用
/bin/bash显式指定解释器,避免调度环境默认 shell 不同。 - 所有路径都用绝对路径。
- 脚本自身的日志追加到
cron-job1.log,方便和 Codex 的运行日志分开排查。
验证方式有两种。第一种是手动执行一次脚本本体:
bash /Users/yourname/.codex-jobs/daily_summary.sh /path/to/your/repo执行后打开$HOME/Documents/codex-daily/daily-$(date +%F).md查看结果。第二种是等待 cron 到点执行后,查看日志文件:
cat /Users/yourname/.codex-jobs/logs/daily-$(date +%F).log4. 任务二:每周日生成一份周报初稿
4.1 思路:复用每日摘要,不重复收集 git 数据
如果周报也调用一次 git,会得到一周的提交记录,但输出可能和每日摘要大量重复,而且信息密度低。更合理的做法是让周报消费“每日摘要文件”而不是再次分析 git。
这时的数据源不再是一个 git 仓库,而是~/Documents/codex-daily/目录下最近 7 天的 Markdown 文件。脚本收集这些文件内容,让 Codex 汇总成一封周报初稿。这样每日摘要和周报形成两级结构:每天做原始数据清洗,每周做信息再聚合。
4.2 脚本实现
#!/usr/bin/env bash set -euo pipefail DAILY_DIR="$HOME/Documents/codex-daily" OUTPUT_DIR="$HOME/Documents/codex-weekly" LOG_DIR="$HOME/.codex-jobs/logs" TODAY="$(date +%F)" LOG_FILE="$LOG_DIR/weekly-$TODAY.log" mkdir -p "$OUTPUT_DIR" "$LOG_DIR" WEEK_FILES=$(find "$DAILY_DIR" -maxdepth 1 -name 'daily-*.md' -mtime -7 | sort) if [ -z "$WEEK_FILES" ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] 最近 7 天没有每日摘要文件" >> "$LOG_FILE" echo "最近 7 天没有可用的每日摘要。" > "$OUTPUT_DIR/weekly-$TODAY.md" exit 0 fi COMBINED_CONTENT="" for FILE in $WEEK_FILES; do COMBINED_CONTENT="$COMBINED_CONTENT ===== $(basename "$FILE") ===== $(cat "$FILE") " done PROMPT="你是一名技术组长。请基于下面的每日代码变更摘要,生成一份周报初稿。 要求: 1. 合并同类项,不要保留每日摘要的逐条内容。 2. 分成四个部分:本周核心进展、关键技术决策、风险与阻塞、下周计划。 3. 保留具体信息,如模块名、功能点、技术栈,不要写成泛泛的套话。 4. 输出 Markdown 格式,中文回答。 以下是每日摘要内容: $COMBINED_CONTENT" { echo "$PROMPT" } | codex exec > "$OUTPUT_DIR/weekly-$TODAY.md" 2>>"$LOG_FILE" echo "[$(date '+%Y-%m-%d %H:%M:%S')] 周报生成完成: $OUTPUT_DIR/weekly-$TODAY.md" >> "$LOG_FILE"这里使用find ... -mtime -7筛选最近 7 天修改的每日摘要文件,按文件名排序后逐个拼接。排序很重要,它保证 Codex 看到的每日摘要是按时间顺序排列的,生成的周报才有时间线感。
4.3 避免重复统计
-mtime -7是按文件修改时间筛选,而不是内容里的日期。如果某一天没有生成摘要文件,周报会少一天;如果补跑了一个旧文件,它的修改时间会变成现在,也会被统计进去。
实际使用中可以根据自己的容错需求调整。更精确的筛选方式是直接用文件名里的日期,例如把daily-2025-06-01.md转换成日期,再与当前日期比较。这样更稳,但脚本会稍微复杂。下面这段是纯文件名日期过滤的思路,可以按需使用:
DAILY_DIR="$HOME/Documents/codex-daily" TODAY="$(date +%F)" WEEK_FILES="" for FILE in "$DAILY_DIR"/daily-*.md; do [ -e "$FILE" ] || continue FILE_DATE="${FILE##*daily-}" FILE_DATE="${FILE_DATE%%.md}" # 这里需要把 FILE_DATE 与 7 天前日期比较,date 命令在 mac/linux 上写法不同 WEEK_FILES="$WEEK_FILES $FILE" done注意:macOS 的date -v-7d和 Linux 的date -d '7 days ago'语法不同,跨平台脚本需要单独处理。如果只在 Linux 服务器上跑,直接使用find -mtime最省事。
5. 任务三:深夜把零散阅读记录整理成知识卡片
5.1 思路:用 inbox 文件收集碎片
这个任务解决的是“碎片信息堆积”问题。平时看到一段代码思路、一个架构方案、一句有启发的话,往往随手记在一个临时文件里,但之后很少再整理。专门整理又太浪费时间。
我采用一个统一的inbox.md作为入口。白天往文件里追加一行记录,深夜由 Codex 定时任务把新增内容转成结构化知识卡片,追加到knowledge-base.md,然后清空inbox.md。
文件位置:
~/Documents/codex-inbox/inbox.md ~/Documents/codex-inbox/knowledge-base.mdinbox 每行是一个待整理条目。允许一行内有自己的描述,Codex 会负责补全背景和结构化。
5.2 脚本实现
#!/usr/bin/env bash set -euo pipefail INBOX="$HOME/Documents/codex-inbox/inbox.md" KNOWLEDGE_BASE="$HOME/Documents/codex-inbox/knowledge-base.md" LOG_DIR="$HOME/.codex-jobs/logs" TODAY="$(date +%F)" LOG_FILE="$LOG_DIR/knowledge-$TODAY.log" mkdir -p "$(dirname "$INBOX")" "$LOG_DIR" touch "$INBOX" "$KNOWLEDGE_BASE" if [ ! -s "$INBOX" ]; then echo "[$(date '+%Y-%m-%d %H:%M:%S')] inbox 为空,跳过整理" >> "$LOG_FILE" exit 0 fi CONTENT=$(cat "$INBOX") PROMPT="你是一名技术编辑。下面是一个技术碎片清单,每行一个条目。 请把它们整理成知识卡片,追加到 Markdown 文档中。 要求: 1. 每个条目输出一个 H3 卡片。 2. 卡片包含:核心观点一句话、适用场景、原理或依据、可操作的下一步。 3. 如果条目本身信息不足,不要编造细节,可以补充“待验证”标记。 4. 输出 Markdown 格式,字体清晰,结构一致。 raw input: $CONTENT" { echo "$PROMPT" } | codex exec > "$HOME/Documents/codex-inbox/_new_cards.md" 2>>"$LOG_FILE" if [ -s "$HOME/Documents/codex-inbox/_new_cards.md" ]; then { echo "" echo "## 整理日期:$TODAY" cat "$HOME/Documents/codex-inbox/_new_cards.md" } >> "$KNOWLEDGE_BASE" # 清空 inbox > "$INBOX" echo "[$(date '+%Y-%m-%d %H:%M:%S')] 知识卡片已追加,inbox 已清空" >> "$LOG_FILE" else echo "[$(date '+%Y-%m-%d %H:%M:%S')] 生成结果为空,未清空 inbox" >> "$LOG_FILE" fi这个脚本的关键是“只有生成结果非空才清空 inbox”。如果 Codex 调用失败或输出为空,inbox 仍然保留,避免数据丢失。
5.3 验证知识卡片格式
脚本执行后,可以检查知识库文件末尾:
tail -n 40 ~/Documents/codex-inbox/knowledge-base.md正常情况会看到类似这样的结构:
## 整理日期:2025-06-01 ### 如何避免日志记录里面的敏感信息泄漏 - 核心观点:日志脱敏不能依赖开发人员手动判断。 - 适用场景:微服务请求日志、错误堆栈、SQL 慢查询日志。 - 原理或依据:常见处理方式是提前配置脱敏字段,在日志输出层统一处理。 - 下一步:整理公司内部日志框架的脱敏插件选型。如果格式不统一,可以调整 prompt 里的输出规范,比如新增“每个 H3 卡片必须包含四个字段”这类硬性要求。Codex 对明确的格式约束响应更好。
6. 挂到后台之后,真正麻烦的是这几个问题
定时任务从“手动能跑”到“挂上 cron 也稳定”,中间会碰到几个高频问题。这里按排查路径从输入到输出排序。
6.1 unable to locate the codex cli binary
出现的典型现象是:终端直接运行 codex 没问题,但 Codex 桌面端、IDE 插件或某个自动化脚本启动时,报错:
unable to locate the codex cli binary. set codex cli path or ensure the executable is in PATH这句话的意思是:调用方(可能是 Codex 桌面应用、编辑器插件,也可能是 cron 脚本)找不到codex可执行文件。原因通常是调度环境或插件进程的 PATH 与终端 shell 不一致。
排查步骤:
- 在终端执行
command -v codex,拿到绝对路径。 - 执行
echo $PATH,确认该路径位于 PATH 中。 - 检查 cron 脚本或桌面端的
Codex CLI Path设置项,直接填入绝对路径。 - 在定时脚本内部显式导入 PATH,而不是依赖外部环境:
export PATH="$HOME/.local/bin:/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:$PATH"这行代码要放在脚本最前面,再执行codex。
6.2 model is not supported 这类模型不匹配问题
定时任务里如果显式指定了模型,或者 Codex CLI 配置的默认模型和当前使用的模式不匹配,可能出现类似:
the 'gpt-5.6-sol' model is not supported when using codex with a...这是一个提示性的错误:你请求的模型名在当前 Codex 模式下不可用。排查方向不是去搜索引擎复制这条错误,而是先确认当前环境支持的模型列表。
codex models如果当前版本没有models子命令,就查看配置文件:
cat ~/.codex/config.toml配置里通常有model或model_provider字段。把它改成当前环境支持的模型名,或者在调用codex exec时通过--model参数指定。
这个坑最常见的触发点是你把“网上看到的模型名”直接写进脚本,但你的 Codex CLI 版本或账号并不支持该模型。落地前先执行codex models。
6.3 脚本在终端正常,在 crontab 里不执行
这是定时任务最经典的问题。脚本手动执行正常,cron 到点时日志文件没有新内容,或运行时报command not found: codex。
原因在于 cron 环境是极简环境。它不加载你的.bash_profile、.zshrc,PATH 通常只有/usr/bin:/bin,npm 全局 bin 目录不在里面。另一个常见问题是脚本里使用了$HOME之外的相对路径,但 cron 执行时工作目录不是仓库目录。
应对方式:
- 脚本开头显式定义 PATH。
- 脚本内部所有路径使用绝对路径。
- cron 命令里使用
/bin/bash /full/path/to/script.sh。 - 脚本对关键参数做校验,例如:
if [ ! -d "$REPO_DIR/.git" ]; then echo "$(date): REPO_DIR 不是 git 仓库" >> "$LOG_FILE" exit 1 fi6.4 任务重叠和日志缺失
cron 只负责在固定时间启动命令,不负责“上一次还没结束就不要启动下一次”。如果 Codex 生成结果比较慢,而 cron 周期又短,就可能出现两个 codex 进程同时运行。轻则浪费配额,重则两个进程写同一个输出文件,内容互相覆盖。
处理方式是在脚本入口加flock锁。以任务一为例:
exec 9> /tmp/codex-daily-summary.lock flock -n 9 || { echo "$(date): 上一次任务未结束,跳过本次执行" >> "$LOG_FILE"; exit 1; }这样同一时间只会有一个任务实例运行。日志缺失的解决方式更简单:cron 命令最后统一追加>> /path/to/log 2>&1,并且脚本内部每次关键节点都写一行带头部时间戳的日志。
下面是一个按现象到处理建议的排查表:
| 现象 | 常见原因 | 检查方式 | 处理建议 |
|---|---|---|---|
| crontab 完全没有输出 | 脚本路径错误或未执行 | 在 cron 命令里先执行echo start写日志 | 确认绝对路径;查看/var/mail或重定向日志 |
| unable to locate the codex cli binary | PATH 未包含 codex | command -v codex | 在脚本顶部注入 PATH,或填写绝对路径 |
| model is not supported | 模型名不匹配 | codex models,检查 config.toml | 使用当前支持的模型名 |
| 任务重复执行 | 上一次未结束 | ps -ef | grep codex | 使用 flock 锁 |
| 输出文件为空 | prompt 输入为空或 codex 失败 | 查看日志文件中的错误输出 | 增加输入判空;重定向 stderr 到日志 |
| 脚本在终端正常 cron 报错 | cron 环境变量不完整 | 手动执行env -i /bin/bash script.sh | 在脚本内定义 PATH、HOME、LANG |
7. 个人电脑用 cron,什么时候才需要 Quartz、xxl-job
7.1 三种调度方案的适用范围
如果定时任务只跑在自己的电脑上,crontab 是最直接的选择。它不需要额外依赖,配置简单,适合“单机、固定周期、少量任务”的场景。缺点也很明显:没有失败重试、没有任务追踪界面、没有分布式能力,跨机器管理要自己另想办法。
进入 Java 项目后,常见的选择有两个:Quartz 和 xxl-job。Quartz 是 Java 进程内调度器,适合嵌在单个服务内部执行定时任务。xxl-job 是调度中心加执行器的架构,调度逻辑和执行逻辑分离,适合多服务、集群场景,自带日志和失败重试。
| 维度 | crontab | Quartz | xxl-job |
|---|---|---|---|
| 运行形态 | 操作系统进程 | Java 进程内 | 调度中心 + 执行器 |
| 集群支持 | 无 | 需要自己实现分片和竞争锁 | 内置多种调度策略 |
| 失败重试 | 无 | 可通过 JobListener 实现 | 调度中心内置 |
| 日志追踪 | 依赖文件重定向 | 应用日志 | 调度中心自带执行日志 |
| 依赖复杂度 | 零额外依赖 | 需引入 Quartz 依赖 | 需部署调度中心 |
| 适合场景 | 个人脚本、单机自动化 | 单服务内部定时任务 | 多服务、分布式、需要可视化调度 |
7.2 在 Java/Spring 项目里调用 Codex 自动化任务时的选型建议
如果你需要把“Codex 生成代码摘要”这类能力接到 Spring Boot 项目里,不要直接在业务请求路径里调用 Codex CLI。更稳妥的做法是:
- 用定时调度框架(
@Scheduled、Quartz、xxl-job 任一)触发任务。 - 任务把请求发送到消息队列。
- 队列消费者异步执行 Codex 自动化任务。
- 结果写入数据库或对象存储。
这样即使 Codex 调用变慢,也不会阻塞业务请求。用@Scheduled时还要注意默认就是单线程执行,多个任务相互影响时要用@Async或配置线程池。xxl-job 的典型优势是执行日志和调度记录不需要自己开发,失败重试也比较完整,适合团队协作场景。
选择标准可以简单记成一句话:任务只有一个、跑在单机、不需要运维界面,用 crontab 或@Scheduled;任务分散在多个服务、需要中心化调度和失败重试,用 xxl-job;任务嵌在 Java 进程内部、需要定制触发规则,用 Quartz。
8. 最佳实践:让 Codex 定时任务长期稳定运行
8.1 脚本里必须做好的 6 件事
一个稳定的 Codex 定时任务,不只是“调一下 codex exec”,而是要把脚本当成小型流水线来对待。下面 6 件事,我在每个脚本里都强制执行:
- 使用
set -euo pipefail,让未定义变量和管道错误直接暴露。 - 所有输出目录先
mkdir -p,避免首次运行崩溃。 - 所有日志写入统一目录,文件名带日期,便于回溯。
- 对输入做空值判断,输入为空时不调用 Codex,直接生成提示文件。
- 使用绝对路径,或脚本开头注入 PATH,不依赖 cron 环境变量。
- 使用
flock防止任务重叠,保证输出文件不会被并发覆盖。
8.2 把任务升级成 CI 或框架任务时可以怎么扩展
并不一定要依赖本地电脑的 cron。如果仓库托管在支持 CI 的平台上,可以用仓库自带的 schedule 功能每天触发一个 workflow,在 CI 容器里安装 Codex CLI,然后执行同样的脚本。优势是即使本地电脑关机,任务也能执行,而且执行日志由 CI 平台统一管理。
如果走这条路,脚本里的输出目录要改成 CI 工作目录,或者直接输出到构建产物目录。注意 CI 环境也需要完成 Codex 登录或配置访问凭据,这一步要和你的凭据管理方式对齐。
如果团队已经用 xxl-job 这类框架,也可以把“收集 git 数据 + 调用 Codex + 写 Markdown”封装成一个 Java 执行器,把调度交给框架,把模型调用放在执行器内部。核心算法和本文章的 Shell 脚本思路一致,只是把git log、find等命令换成 Java 代码或 JGit 调用。
这三个任务真正有价值的地方,不是它们用了多复杂的 AI 接口,而是它们把 Codex 从“每次都要手动对话”变成了“按节奏自动产生交付物”。如果你现在只手动使用 Codex,建议先选一个每天都会重复的动作,做成定时任务,跑一周。根据每天的日志和输出结果调整 prompt,稳定之后再考虑迁移到后端调度框架或 CI 里。从最小闭环开始,比一开始就搭建复杂调度体系更实际。