最近一直在使用 cc-connect,把 OpenCode 接到飞书等 IM 平台。
最初的问题很简单:
除了 cc-connect,还有没有更合适的 Agent Bridge?
我的场景主要有两个:
- AI Coding
- 企业自部署的第三方 Agent 应用
一开始,我是在比较框架;后来发现,更重要的是先明确自己想解决什么问题。
Workspace 是工作的中心
我更希望 Agent Runtime 绑定一个 workspace,而且这个 workspace 本身就是一个 Git Repo。
例如:
merchandise-planning/
├── AGENTS.md
├── skills/
├── tools/
├── knowledge/
├── docs/
├── deliverables/
└── .git/这个 repo 决定了 Agent 的工作范围、工具、规则和产物。
可以把两者简单类比为:
Workspace 是职位 / 工位,Agent Runtime 是坐在这里工作的员工。
于是:
crypto-research/ → Quant Research Agent
merchandise-planning/ → Merchandise Planning Agent
company-kb/ → Knowledge AgentIM、Terminal、Web 都只是入口:
Terminal ─┐
Feishu ───┼──→ Agent Runtime → Workspace
Web ──────┘这也是 cc-connect 吸引我的地方:它主要负责连接,真正执行工作的还是 OpenCode、Codex、Claude Code 这类 Coding Agent。
问题出在群聊
私聊里:
User message ≈ Prompt通常没什么问题。
群聊则不同。
例如:
A: 上海库存最近很低
B: 昨天有促销
C: 调拨还没到
A: @Agent 帮忙看看如果 Bridge 只把包含 @Agent 的那条消息交给 Runtime,前三句话就会丢失。
reply_all 也无法完整解决这个问题,因为:
Bot 看到消息和:
Bot 需要回复消息属于两种不同的判断。
更合适的做法是把消息分成:
ignore
observe
trigger普通群消息进入一个短期 conversation buffer,不调用 Agent。
真正触发时,再由 Gateway 组装当前工作语境:
上一轮回复后,群里有这些消息:
A: 上海库存最近很低
B: 昨天有促销
C: 调拨还没到
此时 A @了你:
A: 帮忙看看
请结合上述上下文处理当前请求。这段内容属于一次 invocation 的附加上下文,不进入 Agent Memory。
Session 和 Workspace 分开
同一个 workspace 可以对应多个 session:
Workspace
├── 飞书私聊 → Session A
├── 群聊 → Session B
├── Thread → Session C
└── Web → Session D它们不需要共享聊天历史。
需要长期保留的内容应进入 workspace:
docs/
deliverables/
src/
.git/更准确地说:
Files are the durable truth.
Runtime Session 负责当前 conversation 的工作上下文。
Gateway 只负责当前 IM 场景。
这种划分也能避免额外设计复杂的跨 session memory。
/new 和 Thread
/new 应该真正创建一个新的 Runtime Session,旧 session 保留,之后可以通过 /switch 切回去。
Thread isolation 遵循同样的思路:
主群 → Session A
Thread → Session BSession B 第一次启动时,可以带入一部分主群近期聊天作为 bootstrap context,后续独立发展。
Gateway 只需要提供简单、可配置的 history limit,例如 max_messages / max_tokens;长期 compaction 仍由 Agent Runtime 自己处理。
Bot 和 Workspace
我最开始也考虑过一个 Bot 内部绑定多个 workspace。
但在飞书这类平台上,我更倾向于为不同 workspace 建立独立的 Bot/App:
商品计划 Bot → merchandise-planning/
技术 Bot → engineering/
知识库 Bot → company-kb/这样,Bot 身份本身就承担了一部分 routing 和权限语义。
开发环境里,让不同 workspace 使用不同的 session / cwd 就够了。
正式部署时,再通过 Docker、Sandbox、OS User 等方式进行安全隔离。这些属于部署层面的问题,不必混入 conversation 设计。
再看几个框架
有了这个区分,再比较 cc-connect、OpenClaw、AstrBot,差异就清楚很多。
cc-connect
cc-connect 的核心模型与这个思路比较接近:
Workspace
↓
External Agent Runtime
↓
Runtime Session目前的短板主要在于 Conversation Layer 太薄。
当前更接近:
message
↓
trigger?
↓
Agent我需要的流程是:
message
↓
conversation buffer
↓
trigger?
↓
context assembly
↓
Agent因此,如果继续使用 cc-connect,方向就很明确:保留它的 Project / Runtime / Session 模型,重做 conversation management。
OpenClaw
OpenClaw 在 conversation 管理上明显成熟得多。
它已经支持类似 pending group history、thread scope、parent context 等机制,和上面的模型很接近。
OpenClaw 的职责也不止 Gateway。
它还包含:
Agent Runtime
Workspace
Session
Memory
Tools
Skills
TUI如果再接入 OpenCode,需要先明确:
谁做决策?
谁管 Session?
谁管 Permission?
谁拥有 Workspace?另一种路径是直接把 OpenClaw 作为主要 Runtime,此时讨论重点就会转向 OpenClaw 与 OpenCode 的组合。
AstrBot
AstrBot 更强调 conversation、chatbot 和 application runtime。
乍看之下,这与 workspace-first 的思路存在冲突。
不过,它现在提供了独立的 Agent Runner,可以把 Dify、DeerFlow 这类完整 Agent Runtime 放在后面。
理论上也可以这样连接:
Feishu
↓
AstrBot
↓
OpenCode Runner
↓
OpenCode
↓
Workspace这时 AstrBot 负责:
IM
conversation
commands
attachments
context assemblyOpenCode 负责:
task planning
runtime session
files / shell / tools
workspace
execution permission因此,关键问题在于:
为了让 OpenCode 成为真正的 Runtime,需要绕开多少 AstrBot 自己的 Agent / Conversation 机制?
如果只需要一个 OpenCode Runner,并做少量 conversation 调整,它可能很合适。
如果还需要重写 history、session、permission、streaming、tool events,改造成本未必低于修改 cc-connect。
LangBot 和 NoneBot
LangBot 更像:
IM → Pipeline → AI Backend它比较适合连接 Dify、n8n 一类系统。在 Git Workspace + Coding Runtime 这类模型下,目前没有看到特别明显的优势。
NoneBot 更薄,只负责把不同平台消息抽象成 Event。
它足够干净,但后面的 conversation、session、streaming、permission、coding events 基本都要自己实现,最后很容易走向重新实现一个 cc-connect。
Chatbot 和 Coding Bot
到这里,几个框架背后的差异可以归结为两种起点。
Chatbot 更自然的起点是:
Conversation First
Conversation
↓
Agent
↓
Workspace / Tools / Knowledge它首先关心:
- 谁在说话
- 谁在回复谁
- 前面聊了什么
- 当前群聊是什么语境
Coding Agent 更自然的起点是:
Workspace First
Conversation
↓
Work Context
↓
Agent
↓
Workspace它首先关心:
- 当前 repo
- 任务是什么
- 有哪些文件和工具
- 当前状态是什么
- 怎么完成并验证任务
在单用户场景下,两者差别很小。
到了多用户场景,差异才会明显。
Coding Agent 本身不会自动理解多人 conversation,需要先由其他层把 conversation 转换成清晰、可执行的工作语境。
这正是当前需要解决的层次。
最终选择 fork cc-connect、采用 AstrBot + OpenCode Runner,还是使用 OpenClaw,仍然需要在同一个场景下实际运行后再判断。