这个项目是一次从”专用插件”到”通用桥接层”的架构重构。原始代码是一套绑定 OpenClaw 框架的微信通道插件,深度依赖 OpenClaw 的插件生命周期、配置系统和网关运行时;新设计的 Agent Bridge 则试图回答一个更通用的问题:如果我不想要一个完整网关框架,能不能让微信消息直接驱动本机的 Codex、Claude Code、Codebuddy 或任意 CLI 工具?
原始形态:OpenClaw 微信插件
src/ 与 cc-weixin/ 共同构成一套面向 OpenClaw 的微信通道实现。它的核心职责包括:
- 通过 iLink API 与微信 Bot 平台建立长轮询连接
- 二维码扫码登录、Token 续期与多账号管理
- 消息收发、媒体文件 CDN 上传与 AES-128-ECB 加密
- 深度嵌入 OpenClaw 的插件 SDK:注册
ChannelPlugin、实现gateway.startAccount/stopAccount、响应auth.login生命周期
这个形态的问题是耦合过深。如果你想让微信消息驱动 Claude Code,必须先安装 OpenClaw 网关、理解它的插件注册机制、配置它的账户体系。对于”只想在本机跑一个微信机器人”的场景来说,这太重了。
新形态:Agent Bridge
bridge/ 是一个独立运行的 Node.js CLI 工具,不依赖 OpenClaw,也不预设任何 Agent。它的设计可以用三个关键词概括:多对多、配置驱动、安全默认。
多对多:Channel ↔ Agent 解耦
Bridge 的核心抽象是两组接口:
ChannelAdapter:负责接入通讯软件。当前实现了WeixinChannel(iLink 长轮询)、CliChannel(终端 REPL),FeishuChannel预留。AgentProvider:负责驱动命令行 Agent。当前实现了codex、claude、codebuddy、opencode四个专用适配器,以及一个generic通用适配器。
BridgeRuntime 作为中间调度层,把 Channel 收到的 ChatMessage 路由到当前会话选中的 Agent。一个 Channel 可以切换不同 Agent,一个 Agent 也可以被多个 Channel 复用。这种解耦意味着新增 Agent 不需要改 Channel 代码,新增 Channel 也不需要改 Agent 代码。
配置驱动:从硬编码到插件系统
早期的原型直接把 codex 和 claude 写死在启动代码里。Bridge 把它们改成了配置驱动的注册表:
{
"agents": {
"codex": { "sandbox": "read-only", "approval": "never" },
"my-tool": { "type": "generic", "command": "my-ai-tool", "stdinPrompt": true }
}
}配置键名自动推断 Provider 类型(codex → codex provider),未知键名则回退到 generic。这种设计让”新增 Agent”变成纯配置行为,不需要重新编译 Bridge。
安全默认:本机执行的三道防线
因为 Agent 最终会在本机执行 shell 命令,Bridge 把安全当作默认行为而不是可选项:
- 用户白名单:
allowUsers为空时,Bridge 会拒绝所有消息,并回显发送者 ID 供管理员配置。 - 工作目录限制:
allowedWorkspaceRoots限定 Agent 可访问的目录范围,/cwd内置命令会校验路径是否落在允许范围内。 - 单会话串行:
KeyedQueue确保同一个 conversation 同时只能驱动一个 Agent,避免并发指令冲突。 - Agent 级沙箱:Codex 的
--sandbox read-only、Claude Code 的--permission-mode dontAsk等参数直接透传给底层 CLI,而不是由 Bridge 自行判断。
微信通道的重新实现
WeixinChannel 并非直接复用原始插件代码,而是基于同一套 iLink API 重新实现了一个更轻量的版本:
- 会话状态用本地 JSON 文件存储(
~/.agent-bridge/weixin-session.json),而不是 OpenClaw 的账户系统 - 长轮询、登录、消息去重、session 过期重连全部自包含在
WeixinChannel内部 notifyStart/notifyStop生命周期通过 API 显式通知微信服务端- 消息去重用
Map<string, number>维护最近 60 秒已见消息 ID,避免微信重复投递触发多次 Agent
CLI 交互模式
除了微信,Bridge 还提供了一个 CliChannel,让终端本身成为一个 Channel。这意味着你可以直接运行 agent-bridge chat --agent claude,在终端里与 Claude Code 交互,而不需要打开另一个窗口。这种统一入口的设计,让 Bridge 不只是”微信转接器”,而是所有 CLI Agent 的通用启动器。
关键取舍
为什么不直接复用原始插件代码?
原始代码与 OpenClaw 的耦合太深:它依赖 openclaw/plugin-sdk 的类型定义、依赖 OpenClaw 的配置树、依赖网关注入的 channelRuntime 和 abortSignal。要把这些全部剥离,工作量不亚于重写。Bridge 选择重写微信通道的核心 API 层,换取零外部依赖的独立可运行性。
为什么不做成 HTTP 服务或 WebSocket 网关?
Bridge 的定位是”本机桥接器”,不是”云端网关”。它的目标是让个人开发者能在自己的机器上,用微信消息驱动本地 CLI 工具。做成 HTTP 服务会引入端口监听、身份认证、网络暴露等额外复杂度,与”轻量”目标冲突。
为什么 Agent 适配器直接调用 CLI 而不是用 SDK?
因为 Codex、Claude Code、Codebuddy 这些工具的本机体验就是 CLI。它们的最稳定接口是命令行参数和 stdin/stdout,而不是某个可能会变的 API。Bridge 通过 runCommand 统一封装子进程调用、超时控制和 stdout 提取,让不同 Agent 的差异收敛在各自的 Provider 里。
仍待完善的方向
从 TODO.md 可以看到,Bridge 已经解决了配置校验、session 过期、优雅关停、typing 指示器、消息去重、测试覆盖等基础问题,但仍有几个明确的方向:
- 媒体消息支持:当前只能收发文本,图片/语音/文件全部丢弃
- Markdown 过滤:Agent 返回的 markdown 在微信中无法渲染,需要一套简化转换
- 智能路由:按任务类型/成本/能力自动选择最优 Agent,而不是靠用户手动
/agent - 跨 Agent 上下文桥接:切换 Agent 时保留对话摘要,而不是完全重置会话
来源:https://github.com/Kaikaikaifang/bridge
相关页面:agent-bridge · openclaw · ilink · agentic-systems · agent-computer-interface