将 WorkTool 消息回调交给 Codex 处理的 FastAPI 服务。收到消息后立即回复 “收到🫡,正在处理。”,Codex 执行完成后再通过 WorkTool 发送最终结果。
这是一个面向单个用户或单个公司的自部署服务,不是 SaaS 多租户系统。
主要能力:
- 支持多个 WorkTool 机器人,数据按机器人 ID 隔离
- 群聊按
groupRemark(没有备注时按groupName)保持 Codex 上下文 - 单聊按
receivedName保持上下文 - SQLite 持久化 Codex thread,服务重启后继续
resume - 非流式回复,回调接口立即响应,任务在后台执行
- 支持 OpenAI-compatible Responses API
本项目按单个用户或单个公司独立部署设计。一个实例可以运行多个机器人,它们的
会话和工作目录按机器人 ID 区分,但仍共享同一宿主机、Docker 环境、网络出口和
Compose 挂载的 /root/.ssh。需要在互不信任的客户之间隔离时,请分别部署实例。
要求:Docker 20.10+,推荐安装 Docker Compose v2。
git clone YOUR_GITHUB_REPOSITORY_URL
cd wechat-codex
cp .env.example .env编辑 .env,至少填写:
PUBLIC_BASE_URL=https://your-domain.example.com
OPENAI_API_KEY=your-api-key
OPENAI_BASE_URL=https://api.openai.com/v1
CODEX_MODEL=gpt-5
# 必须替换为随机长字符串
ADMIN_TOKEN=replace-with-a-long-random-token可以用以下命令生成管理令牌:
openssl rand -hex 32请将 .env 权限设为 600,不要把它提交到 Git:
chmod 600 .env启动并检查状态:
docker compose up -d --build
docker compose ps
curl http://127.0.0.1:8000/health管理控制台地址:http://127.0.0.1:8000/admin。输入 .env 中的
ADMIN_TOKEN 后可以查看机器人、工作目录、会话记录,并导入提示词和 Skill。
如果修改了 HOST_PORT,请将地址中的端口一起替换。
项目的 src/ 源码目录以只读方式挂载在容器 /app,.env、Git 元数据、测试
和本地数据不会随源码挂载进去。在宿主机修改或拉取新代码后,挂载内容会同步
更新,直接重启即可生效:
git pull
docker compose restart app只有依赖或 Dockerfile 变化时才需要重新构建:
docker compose up -d --build公网服务启动后,为每个机器人执行一次:
docker compose exec app python manage_robot.py YOUR_ROBOT_ID可以指定更直观的短工作目录名:
docker compose exec app python manage_robot.py YOUR_ROBOT_ID --workspace robot-a未指定时会使用机器人 ID 前 8 位加 6 位哈希,例如 wt1qqzsk-a1b2c3,
既缩短路径又避免不同机器人前缀相同时发生目录冲突。
程序会注册并绑定以下专属地址:
${PUBLIC_BASE_URL}/worktool/callback/YOUR_ROBOT_ID
多个机器人可以共用一个服务。出站发送、Codex thread、会话锁和 SQLite 记录都包含机器人 ID,应用层不会混用会话上下文;宿主机和 SSH 等系统资源仍由 同一实例共享。服务不做消息去重,每次 WorkTool 回调都会完整处理一次。
| 变量 | 默认值 | 说明 |
|---|---|---|
PUBLIC_BASE_URL |
无 | WorkTool 可访问的公网地址,绑定机器人时必填 |
HOST_PORT |
8000 |
映射到宿主机的端口 |
ADMIN_TOKEN |
空 | 管理控制台 API 访问令牌,公网部署必须设置;为空会关闭管理 API 鉴权 |
OPENAI_API_KEY |
无 | OpenAI-compatible API key |
OPENAI_BASE_URL |
https://api.openai.com/v1 |
Responses API 基础地址 |
CODEX_MODEL |
gpt-5 |
Codex 使用的模型 |
CODEX_REASONING_EFFORT |
medium |
推理强度 |
CODEX_SANDBOX |
full-access |
Codex 执行权限;默认允许宿主机和网络访问(包括 SSH) |
CODEX_WORKSPACE_ROOT |
/workspaces |
每个机器人独立工作目录的根目录 |
CODEX_SESSION_DB |
/data/codex_sessions.sqlite3 |
状态数据库路径 |
CODEX_BASE_INSTRUCTIONS |
空 | 预设 Codex 上下文/基础指令 |
CODEX_INSTRUCTIONS_FILE |
空 | 从挂载文件读取多行基础指令,优先于上面的变量 |
WORKTOOL_ROBOT_ID |
空 | 仅供旧版无 robot ID 回调路径使用 |
PIP_INDEX_URL |
官方 PyPI | Docker 构建使用的 Python 镜像源 |
LOG_LEVEL |
INFO |
日志级别 |
Docker 启动脚本会根据这些变量生成容器内的 /root/.codex/auth.json 和
/root/.codex/config.toml,不依赖宿主机的 Codex 配置目录。Codex 状态由
codex_state volume 持久化。SSH 密钥仍由 Compose 显式挂载 /root/.ssh;
如果不需要远程 SSH,可以删除该挂载。
openai_compatible 是程序内部的 Codex provider 名称,使用者无需配置。
工作目录按机器人 ID 自动创建:
/workspaces/
robot-a/ # robot-a 下的所有群聊共享文件
robot-b/ # 与 robot-a 完全隔离
Codex thread 仍按“机器人 ID + 群聊”区分,因此同一机器人下的不同群聊共享 工作文件,但不会共享对话历史。
可以在具体机器人的目录放置 instructions.md,仅作为该机器人的预设上下文:
/workspaces/WORKSPACE_NAME/instructions.md
也可以挂载一个所有机器人共用的全局规则文件:
volumes:
- ./instructions.md:/app/instructions.md:ro
environment:
CODEX_INSTRUCTIONS_FILE: /app/instructions.md修改模型或工作目录根路径后,新消息会使用新配置;已有 thread 会继续保留历史上下文。 如需完全开始新会话,删除对应机器人/会话的 SQLite 映射后再发送消息。
Compose 使用以下 named volumes:
| Volume | 内容 |
|---|---|
codex_data |
SQLite 数据库 |
codex_workspaces |
机器人工作目录和 Skill |
codex_state |
Codex thread、rollout 和内部运行状态 |
删除容器不会删除这些数据;docker compose down -v 或删除 volume 会永久清除
对应数据。建议定期备份 SQLite、工作目录和 codex_state。
docker compose logs -f app
docker compose exec app python manage_robot.py --helppython3 -m venv .venv
. .venv/bin/activate
pip install -r requirements.txt
python -m uvicorn app:app --app-dir src --host 0.0.0.0 --port 8000本地运行时需要自行准备 ~/.codex/auth.json 和 ~/.codex/config.toml,或先
通过 Docker 入口脚本使用环境变量生成配置。
pip install -r requirements-dev.txt
pytest -q- 部署前更换
ADMIN_TOKEN,保护好.env,公网入口建议使用 HTTPS - 多个机器人会共享挂载的
/root/.ssh;不需要 SSH 时可删除该挂载 CODEX_SANDBOX=full-access允许 Codex 执行网络和 SSH 操作- 不要将互不信任的用户或公司部署在同一个实例中