Codex + 自建中转站,用不完的token+GPT5.4 做成了一个AI机器人
Codex + 自建中转站,用不完的token+GPT5.4 做成了一个AI机器人
最近因为gemini实在太贵,订阅了两个月后还是和团队一起搞了自建中转站,这也正是高龄程序员的痛,所以也想着给自己多搞个退路,对于AI,我的第一感受是如何让AI把一件真正麻烦的事做顺了,做准确了,于是,我准备试一试codex和gpt,全程AI,没有古法编程。
核心是企鹅登录态、NapCat / OneBot 消息协议、OpenAI 兼容网关、本地会话记忆、知识库召回、桌面化运维控制台串成了一个可运行、可排障、可交付的完整链路。
如果你也有想独立开发的想法,这个项目一定很有参考价值,如果有需要使用的我的中转站的,可以后台call我,不是无偿,但绝对最优惠。
下面是一个开发的思路:
- 想把 企鹅号接到自己的 AI 能力上,做私聊或群聊机器人
- 想把 GPT-5.4 接到本地业务,而不是只在网页里聊天
- 想做一个“开发可用、交付也可用”的桌面客户端,而不是只会在命令行里跑
这篇文章我会按“核心功能 -> 技术栈 -> 架构设计 -> 关键实现 -> AI系统提示词”的顺序,把这个项目拆开讲清楚。
1. 项目一句话概括
本质上是一个运行在 Windows 上的企鹅 AI 桥接控制台:
- 前端形态是
Electron桌面客户端 - 消息入口是
NapCat / OneBot 11 - 服务端核心是
Node.js + Express - AI 能力通过
OpenAI 兼容协议接入 - 会话、日志、运行状态通过
SQLite本地持久化 - 还额外做了
二维码登录辅助、QQ 绑定校验、多 Bot Profile、知识库召回
2. 这个项目的核心功能
先说结论,这个项目最有价值的不是某一个单点,而是下面这几块组合起来之后的完整性。
2.1 企鹅号与目标 Bot 账号绑定校验
很多同类项目只要OneBot / get_login_info能返回用户信息,就认为系统可用了。
但这个项目更严格,它会校验:
- 当前 OneBot 登录的 企鹅是谁
- 这个 企鹅 是否等于配置里的
BOT_SELF_ID - 如果扫错号,是否要重置登录流程并重新生成二维码
这意味着它解决了一个很实际的问题:
不是“登录了某个 账号 就行”,而是“必须登录到我指定的那个机器人 账号”才算成功。
2.2 自动拉起 NapCat / 企鹅
项目启动时,不只是起一个 HTTP 服务,而是会做完整的启动编排:
- 清理旧的桥接进程、NapCat 进程和冲突端口
- 启动本地桥接服务
- 检查 NapCat 是否已可用
- 必要时自动拉起 NapCat
- 必要时自动拉起 企鹅
- 轮询 OneBot 登录状态
这部分的价值在于,它把“人工点来点去”的流程尽量程序化了。
2.3 二维码登录链路可视化
这个项目不是只等你自己去 NapCat 看日志,而是主动从多个位置提取二维码信息:
- 从 NapCat 日志里提取二维码 URL
- 解析二维码内容
- 在终端直接打印字符二维码
- 在 Electron 桌面端渲染二维码图像
这对实际使用体验非常关键,因为登录失败的第一现场,通常就卡在二维码这一段。
2.4 接收消息 -> AI 回复 -> 回发消息
核心主链路非常标准,但实现得比较完整:
- NapCat 把消息事件
POST到/onebot/event - 服务端判断是否要处理这条消息
- 按私聊 / 群聊 + 用户维度构造会话 ID
- 读取上一次
response_id,续接上下文 - 召回知识库片段
- 请求 OpenAI 兼容模型生成回答
- 再通过 OneBot API 发回 企鹅
- 自定义系统提示词,给机器人赋予灵魂,这里参考了龙虾的soul.md
所以我定义了一个能安慰人的机器人
它支持:
- 私聊自动回复
- 群聊只在被
@时回复 - 群聊全量回复模式
/reset或中文重置命令清空当前上下文
2.5 本地轻量知识库
这个项目没有上向量数据库,而是做了一个很轻的本地知识库方案,支持:
.md.txt.json.pdf
它的思路是:
- 先按段落切块
- 对中文做单字和双字切分
- 对英文做 token 抽取
- 用词命中做打分
- 取 TopK 片段拼进系统上下文
这不是“最重”的 RAG,但非常适合本地桥接项目:
- 成本低
- 部署简单
- 没有额外服务依赖
- 对 FAQ、资料型问答已经足够实用
2.6 桌面运维控制台
Electron 客户端不是摆设,它做了很多“可交付”层的事情:
- 图形化编辑
.env - 启动 / 停止 / 重启桥接服务
- 查看二维码
- 查看运行状态
- 查看最近对话
- 查看日志
- 跑配置诊断
- 拉取可用模型列表
- 多 Bot Profile 管理
这说明项目定位不是 Demo,而是希望把运维门槛压低。
3. 技术栈一览
| 层次 | 技术栈 | 作用 |
|---|---|---|
| 桌面端 | Electron | 提供图形化控制台 |
| 服务端 | Node.js + Express | 接收 OneBot 事件、转发 AI 回复 |
| 协议层 | NapCat + OneBot 11 | 打通 QQ 消息收发 |
| 模型接入 | OpenAI-compatible API | 兼容官方接口或自建中转站 |
| 持久化 | node:sqlite / SQLite | 存会话、消息、运行快照、诊断记录 |
| 知识库 | pdf-parse + 本地文件切块 | 做轻量召回 |
| 二维码 | jsqr + pngjs + qrcode-terminal + qrcode | 二维码识别、终端打印、桌面显示 |
| 打包 | electron-builder | 输出 Windows 便携版和安装版 |
从依赖选择上看,它整体遵循的是一个非常务实的原则:
优先保证本地可运行、可交付、可维护,而不是为了“技术先进”引入一堆额外中间件。
4. 架构怎么设计的
整个系统我建议你把它理解为“两套状态机 + 一条消息链路”。
4.1 一条消息链路
4.2 两套状态机
第一套状态机是应用登录态:
- 应用是否已启动
- NapCat 是否已启动
- OneBot 是否可达
- 当前登录企鹅是否等于目标企鹅号
- 是否需要二维码
- 是否需要回收旧登录流程
第二套状态机是AI 会话态:
- 当前消息属于哪个会话
- 上次模型返回的
response_id - 当前 Bot 配置是否变化
- 当前知识库指纹是否变化
- 是否需要重置上下文
这两个状态机是拆开的,这一点非常重要。
因为登录态解决的是“这个机器人能不能工作”,会话态解决的是“这个机器人说话是否连贯”。很多项目把这两件事混在一起,导致一出问题就很难排障。
5. 核心模块拆解
5.1bootstrap.js:先起服务,再后台等登录
这个项目有一个很不错的工程决策:
先把 HTTP 服务起起来,再在后台等待 企鹅 / OneBot 登录完成。
这样做的好处是:
healthz很早就可用- Electron 能立刻拿到状态
- 启动阶段不是黑盒
- 用户知道系统卡在“服务未起”还是“未登录”
很多桌面端程序会反过来做,结果就是前面一长段时间界面没有状态,只能等。
5.2startup.js:真正的启动编排中心
这个模块是项目里最有“工程味”的部分,基本承担了整套 Windows 侧自动化:
- 清理旧进程与端口
- 写入 NapCat 的 OneBot 配置
- 检查 OneBot 是否可达
- 自动拉起 NapCat / 企鹅
- 解析日志里的 WebUI 地址和二维码链接
- 从 PNG 中识别二维码
- 打印终端二维码
- 校验当前登录 企鹅 是否匹配目标 Bot
- 不匹配就回收并重启登录流程
如果你以后也要做类似桥接项目,这个模块的设计思路比“消息回复逻辑”更值得学。
5.3server.js:消息处理主入口
server.js主要做五件事:
- 暴露
/healthz - 接收
/onebot/event - 根据
self_id匹配当前 Bot Profile - 过滤无效事件和群聊触发模式
- 调用知识库与模型生成回复
这里还有几个细节值得注意:
- 支持
OneBot Post Secret做签名校验 - 群聊默认只在被
@时触发,避免刷屏 - 会话 ID 是按
bot + 私聊/群聊 + 用户粒度构建的 - 日志不仅打印在控制台,还会写入持久化层
5.4openai-client.js:兼容层做得很实用
这是我个人比较喜欢的一块。
它不是简单写死某一个接口,而是做了两层兼容:
- 优先走
/responses - 如果中转站不支持,再回退到
/chat/completions
这非常适合“官方接口 + 第三方兼容网关 + 自建中转站”混用场景。
另外它还做了这些增强:
- 自动规范化
OPENAI_BASE_URL - 支持多个 base URL 候选
- 支持拉取
/models - 支持
reasoning.effort - 支持不同 Bot 使用不同模型配置
一句话评价:
这不是只为了“能用”,而是为了“你换供应商时别改一堆代码”。
5.5knowledge-base.js:轻量 RAG 的正确打开方式
这个模块非常适合中小项目抄作业。
它没有上:
- 向量数据库
- Embedding 服务
- 复杂召回链路
而是用了一个更接地气的思路:
- 文件切块缓存
- 基于文件大小和修改时间做缓存键
- 中文单字 / 双字 + 英文 token 混合分词
- 命中打分
- TopK 拼接
如果你的目标是“给 机器人加一点本地知识”,这种方案的性价比是很高的。
5.6persistence.js:把“能跑”升级成“能追踪”
项目把很多运行时数据都落进了 SQLite:
sessionsmessagesruntime_snapshotsdiagnostics_runs
这带来的价值非常直接:
- 程序重启后还能知道上次状态
- 最近对话可回看
- 诊断结果可留痕
- 旧的
sessions.json还能迁移进来
同时它开启了WAL模式,这对桌面本地数据库是一个比较合理的选择。
5.7bot-profiles.js:从单 Bot 走向多 Bot
这个模块说明作者已经不满足于只服务一个账号。
它支持:
- 多 Bot Profile
- 激活某个 Bot
- 每个 Bot 拥有独立的模型、System Prompt、群聊模式、知识库配置
- 将活动 Bot 的关键配置镜像回
.env
这意味着项目后面很容易扩成:
实际上已经实现了
- 多个 企鹅 号
- 不同业务人格
- 不同知识库
- 不同模型策略
6. 为什么这个实现思路是对的
如果让我用工程视角总结这个项目的实现思路,我会概括成下面 4 句话。
6.1 把“消息服务”与“登录运维”分层
聊天回复只是表面功能,真正让系统稳定的是:
- 登录流程可视化
- 绑定状态可确认
- 异常流程可回收
这类项目一旦没有这层,线上运维会非常痛苦。
6.2 把“OpenAI 官方接口”抽象成“兼容网关”
项目没有把模型供应商写死,而是统一收口到:
OPENAI_BASE_URLOPENAI_API_KEYOPENAI_MODEL
这一步非常关键,因为你后续无论接:
- 官方 OpenAI
- Azure 风格兼容层
- 自建中转站
- 第三方代理网关
整体代码都不用大改。
6.3 先解决交付问题,再追求算法复杂度
从轻量知识库、本地 SQLite、Electron 控制台这些点可以看出,项目优先级是:
- 能装起来
- 能跑起来
- 能排障
- 再逐步增强智能度
这是很典型、也很正确的工程化思路。
6.4 尽量把“状态”变成可观测对象
项目里很多设计都围绕“状态透明”展开:
/healthz- 最近会话
- 运行快照
- 诊断报告
- QR 状态
- 当前登录企鹅号
这让桌面端不再只是个壳,而是真正的运维面板。
7. 那么其中大模型消耗的token从哪来
当然是自建中转站啦,当然有需要的后台call我,很优惠!
这部分是我认为这篇文章最适合扩展的地方。
因为这个项目天然就是一个OpenAI-compatible 接入层,所以它非常适合接在“自建中转站”后面。
7.1 一个推荐的角色分工
我建议把三者这样分工:
Codex:负责开发阶段,写代码、补测试、改 Prompt、做运维脚本、生成知识库资料GPT-5.4:负责线上问答阶段,承担 应用 里的高质量回复自建中转站:负责统一鉴权、路由转发、额度隔离、模型切换、日志审计
这样做的好处是:
- 开发和生产用的 Token 不混用
- 线上服务稳定性更高
- 模型切换不需要改客户端逻辑
- 不同 Bot 可以挂不同的模型策略
7.2 这个项目为什么特别适合接中转站
因为它本身就已经做了兼容层设计:
- 统一收口
OPENAI_BASE_URL - 支持
/models - 优先
/responses,失败回退/chat/completions - 每个 Bot 可以独立配置模型
这意味着你完全可以把:
OPENAI_BASE_URL=https://你的中转站域名/v1OPENAI_API_KEY=你的中转站令牌OPENAI_MODEL=gpt-5.4
作为项目主配置,而不是把官方地址硬编码进项目。
7.3 一个实用的 Token 搭配策略
如果你真的要把它落地,我建议按“开发 Token”和“生产 Token”拆开。
方案 A:最稳的搭法
- Codex 用一套专门的开发 Token
- 应用桥接服务用一套专门的生产 Token
- 中转站里给生产 Token 设置更严格的限流和额度
适合:
- 自己开发,机器人稳定跑在线上
- 不希望开发调试把线上额度打爆
方案 B:多模型分流
- 私聊高质量问答走
gpt-5.4 - 群聊高频消息走更便宜的兼容模型
- 复杂场景再切回
gpt-5.4
适合:
- 群聊流量大
- 成本敏感
- 需要把高质量能力用在更有价值的消息上
方案 C:多 Bot Profile 分工
- Bot A:客服 / FAQ,挂知识库,模型偏稳
- Bot B:娱乐闲聊,模型偏便宜
- Bot C:开发群助手,Prompt 更技术化
这个项目的bot-profiles设计,天然适合做这一层扩展。
8. 项目最值得借鉴的 5 个点
8.1 真正把“绑定正确”当成一等公民
不是“能登录就行”,而是“必须登录到目标 Bot 才行”。
8.2 对第三方网关兼容做得很务实
/responses不行就降级/chat/completions,很适合国内复杂的中转环境。
8.3 本地可交付性强
Electron + SQLite + Electron Builder 的组合,让它更像一个产品,而不是脚本。
8.4 轻量知识库方案非常接地气
不依赖额外服务,适合个人项目、小团队、内网环境。
8.5 可观测性做得不错
运行状态、二维码、消息记录、诊断报告都有对应落点,不容易“黑盒化”。
用 Electron 做控制台,用 OneBot 做协议桥,用 OpenAI-compatible 做模型抽象,用 SQLite 做本地持久化,再用 Codex + GPT-5.4 + 自建中转站把开发效率和生产能力真正打通。
AI是一个生产工具,很多年前出现了新的生产工具,淘汰了那些看不起它的人,现在新的生成工具出现了!
