用飞书机器人远程控制Codex

1. 为什么要用飞书远程控制 Codex?

Codex 是一个能够理解代码、修改文件、运行命令并协助完成工程任务的 AI 编程助手。但在常见的使用方式中,我们通常需要坐在电脑前,通过终端、IDE 或桌面客户端与它交互。

这在开发时没有问题,但很多任务并不一定发生在电脑旁。

例如,人在外面时突然发现服务器上的服务异常;通勤路上想让 Codex 检查一段代码;开会时想到一个功能,希望先让它分析实现方案;或者睡前提交一个耗时任务,让它在服务器上完成检查、修改和测试。

于是我开始思考:能不能把 Codex 接入一个随时可以打开、输入体验足够好、又适合管理长期对话的聊天工具?

飞书正好具备这些特点。

首先,飞书的聊天管理体验比较完整。消息记录、引用回复、表情状态、多端同步和会话搜索都很成熟。每个任务天然就是一条消息,机器人的处理过程和最终结果也能直接回复在原消息下面。相比在手机上操作远程终端,这种方式更清晰,也更容易回顾。

其次,飞书的语音输入体验很好,尤其适合中文。很多复杂需求用键盘输入可能要花几分钟,但通过语音可以直接说出来。例如:

检查一下服务器上这个项目为什么启动失败,先查看日志,找到原因后修复,并确认服务恢复正常。

在手机上说完这句话,机器人就可以把任务交给服务器上的 Codex。对于描述需求、补充细节和临时调整方向来说,语音输入明显降低了使用门槛。

更重要的是,远程控制让 Codex 不再局限于“坐在电脑前使用”。只要能打开飞书,就可以在权限允许的范围内让它:

  • 阅读和修改项目代码;
  • 检查服务器状态与日志;
  • 运行测试和构建;
  • 调查故障原因;
  • 生成文档、图片或其他文件;
  • 执行部署和维护工作;
  • 持续处理较长时间的工程任务;
  • 完成后把结果直接发回飞书。

因此,飞书在这里不只是一个聊天界面。它同时承担了远程任务入口、异步任务队列、进度通知中心和操作记录的角色。

这就是 lark-codex-bot 项目诞生的原因。

2. 这个项目是什么?

lark-codex-bot 是一个自行托管的飞书机器人项目,用来连接飞书自建应用和 OpenAI Codex CLI。

用户在飞书中向机器人发送文字、图片或引用消息,机器人把内容整理成任务,交给部署机器上的 Codex。Codex 在指定工作目录中读取文件、执行命令、修改项目并完成验证,最后将结果回复到原来的飞书会话中。

项目已经以 MIT 许可证开源:

GitHub:Raytto/lark-codex-bot

它不是把服务器 Shell 直接暴露到飞书,而是在飞书和 Codex 之间增加了一层任务管理与安全控制,包括身份白名单、消息队列、会话状态、执行进度、任务取消和沙箱配置等。

3. 主要特性

1. 在飞书里直接提交 Codex 任务

机器人支持普通文字、富文本、引用消息和图片输入。

你可以直接描述一个完整任务,也可以引用之前的消息补充要求。需要检查界面问题时,还可以把截图发给机器人,让 Codex 将图片和文字放在同一个任务上下文中处理。

这种方式特别适合移动端。无需打开远程桌面,也不必在手机终端里输入复杂命令。

2. 每个会话保留独立的 Codex 上下文

机器人会为不同的飞书会话保存对应的 Codex Thread。

在同一个聊天中继续发送消息时,Codex 可以恢复此前的任务上下文,而不是每次都从零开始。这样就可以进行连续协作:

  1. 先让它调查问题;
  2. 再要求按照调查结果修改;
  3. 接着补充新的限制;
  4. 最后让它运行测试并整理总结。

会话和消息状态保存在本地 SQLite 数据库中,即使机器人重启,也可以继续识别已有会话。

如果需要完全重新开始,可以使用 /new/clear 创建新的 Codex 会话。

3. 明确显示模型和思考深度

每个任务的第一次机器人回复,都会先说明当前实际使用的模型和思考深度,例如:

当前使用模型:gpt-5.6-sol;思考深度:high。

第一次回复可能是处理中通知,也可能是任务很快完成后的正式结果。无论是哪一种,用户都能立刻确认当前任务使用了什么模型配置,避免机器人实际运行参数不透明。

模型和思考深度通过部署环境统一配置,并在启动 Codex Thread 和每个 Turn 时显式传入。

4. 长任务进度通知

真实的工程任务经常需要运行数分钟甚至更长时间。如果机器人一直没有回复,用户很难判断它是在工作、排队,还是已经卡住。

因此,项目为长任务增加了定期进度回复。机器人会根据 Codex 返回的可见事件,整理出安全、简短的进度信息,例如:

  • 正在读取项目文件;
  • 正在执行第几条命令;
  • 正在修改文件;
  • 正在运行自动化测试;
  • 正在等待工具返回结果;
  • 已经处理了多长时间。

进度通知不会泄露模型的隐藏思考内容,只展示适合用户查看的任务状态。

5. 排队、优先级和防重复处理

为了避免多个消息同时操作同一个工作区,机器人使用串行任务队列处理普通任务。

如果用户连续发送多条消息,它们会依次执行。通过 /priority 命令,还可以让自己的下一条消息移动到等待队列前方。

机器人会按照飞书的 message_id 去重,并处理消息编辑带来的更新。如果一条消息还在队列中,用户修改了它,机器人会在任务真正开始前重新读取最新内容,尽量避免执行已经过期的旧版本。

6. 运行中实时调整任务

项目支持 Codex app-server 模式,并提供 /steer 命令。

当 Codex 正在执行一个较长任务时,可以先发送 /steer,然后发送一条新的指导消息。这条消息不会作为新的排队任务,而是尝试直接加入当前正在运行的 Codex Turn。

例如,Codex 正在重构一个模块时,可以临时补充:

不要修改现有数据库结构,保持接口向后兼容。

这比取消整个任务再重新开始更加高效,也让飞书里的交互更接近真正的实时协作。

7. 支持停止、撤回和重试

如果发现任务方向不对,可以发送 /stop,机器人会取消当前运行的 Codex 进程。

飞书消息撤回也会参与任务控制。如果对应任务还未执行,机器人可以将它从等待队列中移除;如果已经开始执行,则可以触发取消。

对于模型繁忙、容量不足等适合重试的错误,机器人还提供了退避重试机制。重试会尽量沿用同一个 Codex Thread,减少上下文丢失,同时避免无边界地反复执行。

8. 将生成图片直接发回飞书

Codex 不仅可以回复文字,也可以把本地生成的图片上传到飞书。

项目约定了一种简单的结果协议。只要 Codex 在最终回复中输出:

FEISHU_IMAGE: outputs/result.png

机器人就会检查该文件,上传图片,并回复到对应的飞书消息中。

为了防止任意读取服务器文件,公开版本要求返回的图片必须位于项目工作目录内部。

这项能力适合界面截图、测试结果、示意图、数据图表和其他视觉产物。

4. 常用机器人命令

项目内置了几条简单的控制命令:

  • /new/clear:创建新的 Codex 会话;
  • /stop:停止当前任务;
  • /priority:让下一条消息优先进入等待队列;
  • /steer:让下一条消息实时指导当前运行中的任务;
  • /status:查看当前会话和队列状态;
  • /help:显示命令帮助。

任务处理过程中,机器人还会添加飞书消息表情:开始处理时显示 Get,成功完成后切换为 DONE,让用户无需打开每条回复也能快速判断任务状态。

5. 简单的技术实现

整个项目可以概括为下面这条数据链路:

飞书消息
   ↓
飞书长连接或 HTTPS Webhook
   ↓
发送者 open_id 白名单检查
   ↓
消息解析、引用读取和图片下载
   ↓
串行任务队列
   ↓
Codex CLI / Codex app-server
   ↓
本地项目文件、命令和测试
   ↓
文本或图片结果
   ↓
回复到原飞书消息

项目主体使用 Python 编写,通过飞书官方 SDK 接收事件和发送消息。

在 Codex 一侧,项目支持两种运行方式:

  • 通过 Codex CLI 的 JSONL 输出读取任务事件;
  • 通过 Codex app-server 的双向通信接口管理 Thread、Turn 和实时 /steer

机器人会跟踪 Codex 返回的事件,将命令执行、文件修改、计划更新和任务完成等信息转换为用户可读的进度。飞书会话与 Codex Thread 的对应关系,以及消息处理状态,则保存在 SQLite 中。

默认的飞书接入方式是长连接,因此不一定需要准备公网回调地址。如果使用 Webhook 模式,则需要配置 HTTPS 回调、验证令牌和加密密钥。

Codex CLI 的安装与登录方式可以参考 OpenAI Codex CLI 文档

6. 安全设计

这是整个项目中最需要认真对待的部分。

一条飞书消息最终可能让 Codex读取文件、修改代码并运行命令。因此,部署时不能只考虑“机器人能不能收到消息”,还必须明确“什么人可以让它执行任务”和“任务可以影响哪些资源”。

项目首先使用飞书用户的 open_id 做严格白名单检查。未在白名单中的消息,会在内容解析、保存、排队和发送给 Codex之前直接丢弃。

公开版本还采用了相对保守的默认配置:

CODEX_SANDBOX_MODE=workspace-write
CODEX_APPROVAL_POLICY=never
CODEX_WORKSPACE_NETWORK_ACCESS=false

在默认设置下,Codex 的写入范围被限制在当前工作区,沙箱内的网络访问也处于关闭状态。

如果部署环境确实需要访问服务器上的其他目录、管理系统服务或执行完整运维操作,可以显式启用更高权限。但这意味着安全边界会明显扩大,适合部署在专用服务器、专用系统账户或隔离环境中,而不应作为公开机器人的默认设置。

比较稳妥的部署原则包括:

  • 使用专用机器、容器或操作系统账户;
  • 只允许明确可信的飞书用户访问;
  • 为机器人准备独立工作目录;
  • 不把密码、Token 和私钥写进提示词或仓库;
  • 按实际需要开放文件、网络和系统权限;
  • 对生产部署保留日志、备份和回滚能力。

7. 如何开始使用

项目要求 Python 3.11 或更高版本,同时需要 Node.js、npm、飞书自建应用,以及已经安装并完成认证的 Codex CLI。

基本流程如下:

git clone https://github.com/Raytto/lark-codex-bot.git
cd lark-codex-bot

python -m venv .venv
python -m pip install -r requirements.txt

然后复制 .env.example.env,配置飞书应用凭据、允许使用机器人的 open_id、Codex 模型和思考深度:

LARK_APP_ID=cli_your_app_id
LARK_APP_SECRET=your_app_secret
LARK_ALLOWED_OPEN_IDS=ou_your_open_id

CODEX_MODEL=gpt-5.6-sol
CODEX_REASONING_EFFORT=high

最后运行:

python app.py

飞书应用还需要启用机器人能力,并授予收发消息、读取引用内容、管理消息表情、下载和上传图片等必要权限。

完整配置方式可以查看项目仓库中的 README。

8. 未来的扩展空间

目前这个项目已经能够承担日常的远程 Codex 任务,但它仍有很大的扩展空间。

多项目路由

可以根据飞书群聊、命令或消息标签,将任务分发到不同仓库和服务器。例如一个群对应前端项目,另一个群对应后端服务,运维群则连接服务器知识库。

更细的权限系统

现在主要通过发送者白名单控制访问。未来可以继续增加角色权限,例如:

  • 只允许部分用户读取和分析;
  • 允许开发者修改代码但不能部署;
  • 只有管理员可以操作生产服务;
  • 针对不同项目配置不同的目录和网络权限。

定时任务和主动通知

除了用户发送消息触发任务,还可以增加定时检查:

  • 每天检查 Codex CLI 是否发布新版本;
  • 定期运行项目测试;
  • 检查服务器磁盘、证书和服务状态;
  • 发现异常后主动发送飞书通知;
  • 自动整理日报、更新记录和故障摘要。

这样机器人就会从被动的远程助手,逐渐变成持续工作的工程自动化代理。

更丰富的结果形式

后续可以支持飞书卡片、代码差异、测试报告、文件附件、日志摘要和部署确认按钮,使结果比普通文本更加直观。

多机器和隔离执行

对于团队使用场景,可以增加任务调度层,把不同任务发送到不同容器、虚拟机或执行节点。这样既能并行处理,也能让每个项目拥有独立的安全边界。

项目知识库与专用工作流

Codex 可以结合项目文档、AGENTS.md、Skills 和部署规则,理解每个工程自己的目录结构、测试方式和发布流程。

最终,每个飞书群都可以拥有一个熟悉该项目的专用工程助手,而不是每次都从通用提示词开始。

9. 写在最后

lark-codex-bot 解决的并不是“怎样在飞书里执行一条命令”,而是“怎样让一个本地 AI 工程助手以可管理、可持续、可远程使用的方式进入日常工作流”。

飞书提供了优秀的中文输入、消息组织和多端体验;Codex 提供了理解工程、操作文件、运行工具和完成复杂任务的能力。把两者连接起来之后,手机上的一条文字或语音消息,就可以成为一个真实工程任务的起点。

它不能代替所有开发工具,也不能消除服务器权限带来的风险。但在做好身份限制、运行隔离和权限配置的前提下,它可以显著扩大 Codex 的使用场景:不必一直守在电脑前,也能随时提交任务、调整方向、查看进度并接收结果。

项目地址:

发表评论