-
Notifications
You must be signed in to change notification settings - Fork 20
ops codex
最后更新:2026-07-18
交流群:点击加入 QQ 群【雪主任的工坊】
想在 QQ 里让服务器上的 Codex 帮你查目录、改代码、跑测试?用这个。
一句话版:
/ops codex <你的任务描述>
机器人会立刻回一个任务 ID,Codex 在固定工作目录和固定沙箱里异步干活。任务超过 45 秒还在跑时,会低频推送“仍在运行”;干完再把真实结果推回原会话。
先泼两盆冷水:
- 权限很高,默认关闭
- 只适合完全信任的管理员
- 不是给普通聊天用户的功能
- 通用权限、固定命令和安全模型,先看 用
/ops在 QQ 里做运维
用机器人实际运行账号执行:
command -v codex
codex --version
codex exec --help把 command -v codex 打出来的绝对路径,后面填进 program。NVM 安装常见长这样:
/home/bot/.nvm/versions/node/v24.0.0/bin/codex
NVM 版 Codex 经常靠 /usr/bin/env node 启动,而 systemd 服务的 PATH 往往不带 NVM。
好消息:/ops codex 会把规范化后的固定 program 父目录塞到 Codex 子进程 PATH 最前面。
只要 node 和 codex 在同一个 bin 目录,通常不用改机器人进程全局 PATH。
这只影响 Codex,不影响普通 /ops 固定命令。
再多一句安全建议:Codex / Node 请装在工作区外面,比如独立的 NVM versions/<node版本>/bin。
用 workspace-write 时,配置加载会拒绝 program 父目录落在 working_directory 里面的写法,包括靠 .. 或符号链接绕进去;路径关系搞不清时也会直接拒绝启动。
在部署运行目录:
cp config/ops.example.toml config/ops.toml
chmod 600 config/ops.toml先把总开关和会话范围打开。私聊示例:
enabled = true
[private]
enabled = true
allowed_user_ids = ["从私聊 /ping 获取的稳定 user_id"]
[group]
enabled = false
allowed_group_ids = []再写 Codex 段:
[codex]
enabled = true
program = "/absolute/path/to/codex"
working_directory = "/absolute/path/to/workspace"
timeout_seconds = 1800
max_prompt_bytes = 8000
max_stdout_bytes = 32768
max_stderr_bytes = 16384
profile = "qq-maid-ops"
sandbox = "workspace-write"
cancellable = true
max_concurrent_tasks = 1字段怎么理解:
| 字段 | 人话解释 |
|---|---|
program |
Codex CLI 的绝对路径,聊天消息改不了 |
working_directory |
Codex 唯一固定工作根;可以是发布目录,也可以不是 Git 仓库 |
profile |
固定 Codex profile,建议单独给机器人运维建一份 |
sandbox |
只认 read-only 或 workspace-write
|
timeout_seconds |
单任务最长跑多久 |
max_prompt_bytes |
任务描述最多多长 |
max_stdout_bytes / max_stderr_bytes
|
最终回执保留多少输出 |
cancellable |
能不能取消正在跑的任务 |
max_concurrent_tasks |
并发上限,建议先从 1 开始 |
发布目录常常没有 .git。入口固定会带:
codex exec --skip-git-repo-check --ephemeral
所以没 Git 也能跑,而且这次任务不会持久化 Codex session。
这两个参数只负责“跳过 Git 检查”和“不留 session”,不会放宽工作目录、profile 或沙箱。
./botctl.sh restart
./botctl.sh status然后在机器人会话里依次发:
/ops
/ops codex 只读取当前工作目录并概括它的用途,不修改文件
/ops list
受理回执大概长这样:
Codex 任务已受理
任务 ID:ops-a82f31c4
取消:/ops cancel ops-a82f31c4
任务结束后,你会收到成功、执行失败、超时、取消或启动失败这些真实状态。
模型嘴里说“成功了”不算数,以进程退出状态为准。
长任务进度怎么推:
- 45 秒内结束:不会多发过程通知
- 超过 45 秒还在跑:先发第一条“仍在运行”
- 之后最多每 120 秒一条
- 进度里只有任务 ID、仍在运行、已运行时间、取消命令
- 没有原始 stdout/stderr、命令参数、任务描述或文件内容
- 进度和最终结果用不同的 Outbox 去重键;任务一结束会停掉进度,并取消还没发出去的旧快照
- Outbox 重试只重发已保存快照,不会重新执行 Codex
补充几条体验细节:
- Codex 正常跑时,进度、插件告警、工具日志常写到 stderr
- 成功任务只把最终 stdout 推到聊天
-
失败 / 超时 / 取消时,stderr 会落到权限受限的
logs/ops/<任务ID>.log,聊天只提示服务器日志路径 - 如果独立日志写失败,最终结果会直接附带一段脱敏、限长的 stderr 摘要,不会硬叫你去看一份空日志
- 写日志前会做任务描述的字面脱敏
- 普通
/ops固定命令还是 stdout + stderr 原样回
最终输出会走项目现有的 QQ 安全 Markdown 渲染:
-
http:///https://链接可以保留 - 指向
/root/...这类服务器本地文件的 Markdown 链接,QQ 里打不开,所以只展示标签,不发内部绝对路径
/ops list
/ops cancel ops-a82f31c4
/ops list 只看当前机器人进程里还在跑的任务。
首期注册表不跨进程恢复;机器人一重启,重启前还在跑的任务不会继续帮你收结果。
stop / kill / close 只是 cancel 的兼容别名;帮助文案优先展示 /ops cancel <任务ID>。
意思是:working_directory 不是 Git 工作树,而旧版本入口又没带 --skip-git-repo-check。
换带这个参数的新版本再试。别为了绕过报错在发布目录里临时 git init。
多半是 NVM 版 codex 需要同目录的 node,但服务没加载交互式 Shell 的 NVM 环境。
部署会把 program 所在目录塞进 Codex 子进程 PATH 的版本后重试,并确认这两个文件真在同一目录:
ls -l "$(dirname "$(command -v codex)")/codex"
ls -l "$(dirname "$(command -v codex)")/node"检查:
-
program是不是现有文件的绝对路径 - 机器人账号有没有执行权限
-
working_directory是不是现有目录
启动失败不会把内部路径或系统错误详情甩到聊天里。必要时在服务器上用同一账号跑:
codex --version先看回执里的退出码,再按提示去服务器读:
logs/ops/<任务ID>.log
如果独立日志写入失败,就看回执里那一段有限 stderr 摘要。
常见原因:
- Codex profile 不存在
- 认证不可用
- 模型服务挂了
- 任务里某条命令返回非零
stdout 里写了“成功”也不算成功。错误日志不会自动上传,清理策略你自己定。
可选插件、系统 keyring、MCP Server 初始化失败,不一定等于主任务失败。
以任务退出状态和最终 stdout 为准。
比如某个 MCP 报了 Python ModuleNotFoundError,任务仍可能直接读本地文件并成功退出。
成功回执不会把这些进度日志推到聊天;要不要修插件 / MCP 环境,看你服务器侧需要。
先发 /ops list 看任务是不是还在跑,再查 Notification Worker、平台连接、发送权限。
Outbox 重试只重发已保存结果,不会重新执行 Codex。
- 只给完全信任的管理员,优先私聊
-
working_directory只指向你真的允许 Codex 读 / 写的目录 - Codex / Node 装在工作区外;
workspace-write时program父目录不能落在工作区里 -
sandbox不要配成danger-full-access,框架也不接受 - 任务描述里别塞 token、secret、API Key、真实用户 ID、群 ID、聊天记录
- 任务描述始终作为
--后的单个 argv 传递,不经 Shell;精确的-会被拒绝,避免触发 stdin 语义 - 错误诊断会替换任务描述完整文本及其非空行的字面匹配,但识别不了转义、变形或模型改写后的敏感内容
- Unix 上超时 / 取消会终止独立进程组;Windows 当前只保证干掉直接子进程
代码更新并按项目流程发布后,至少确认:
make deploy-remote- 服务重启成功,
botctl.sh status显示进程还活着 -
/ops codex能返回任务 ID,不再卡在 Git 信任目录或 Node PATH - 只读测试任务能收到真实成功结果
- 任务结束后,
/ops list不再显示它 -
/ops cancel <任务ID>能取消一个明确允许取消的测试任务