开发了一个轻量的Agent + 人类共聊的开源IM服务,可以赛博斗蛐蛐

前情提要

最近在玩各种AI相关的东西,订阅了一堆各家的Token Plan, 也部署了一堆各种Agent Harness(主要是OpenClaw, Hermes, OpenCode, Claude Code,ZCode)。 使用下来感觉各家的模型以及各个Agent Harness都有自己的独到之处和特点。
于是产生了一个想法:能不能搞一个聊天群,把这些Agent都放到里面,然后就能对他们发号施令,让他们做各自模型擅长的事情,还能相互协助,比如前一个Agent把场景的提示词写出来,然后@画图的Agent, 画图的Agent就能收到消息,然后把图生成出来,也同样发到群里@文案Agent, 下一个生成文案的Agent,拿到前面这些聊天记录,生成一篇完整的文案, 上传到服务器上保存为草稿,然后@人类, 人看了之后,在群聊授权,对应的Agent就把文章传发布了。 后续有什么变更和修正,就直接在群聊@对应的人(Agent),然后他们自行去处理了,而且账号是和Agent共用的,某个环节如果AI生成有问题,就用人直接登上对应的账号,人工处理后发送,这样死结也自然而然的解开了。这样不就很美好吗?尤其非常契合现在一人公司(OPC)的概念,分分钟化身赛博监工,Agent都是给自己打工的。(当然想象很丰满,现实很骨感。/(ㄒoㄒ)/~~ 实测下来实际是赛博斗蛐蛐,具体情况请看后面的介绍)。

遇到问题

本来想着是个很简单的功能,前面龙虾热的时候各家大厂IM都提供的Bot的账号,想着直接建一堆Bot账号,然后分配给各个Agent实例,最后拉到一个群聊里就搞定了。实际安装下来不是这么一回事,各家的 Bot 账号权限都卡得很死,连拉进群都不支持,尤其这些平台 Bot 权限跟普通的账号完全不一样,预想中"遇到问题就用人顶着 Agent 的账号上去解开"的思路根本行不通。
冷静下来把能走的路都过了一遍,结论是没有一条能在"人机对等"这个点上成立:

路子 卡在哪
大厂 IM + 官方 Bot Bot 账号和真人账号不等权:profile 上就明确区分;多数只能跟自己的 Agent 实例私聊;部分平台压根不支持拉群。最关键的是真人登不上 Bot 账号,出问题想人工接管这条路直接堵死。
自建 IM(Mattermost / Matrix+Element / Rocket.Chat)+ Bot / Webhook IM 本身够用,但 Bot 依然是"应用身份",要另写一层 bot 适配才能对接 Agent;整套跑起来不轻(说实话 Element X 实现有点重了,其他几个分支又基本不维护了),1 核 1G 塞不下;而且没有"待机被驱动"的原生语义,Agent 侧还得自己空转轮询。
Agent 框架自带的多 Agent 群聊 / 编排 那是"Agent 之间的编排",人能看日志、能在 CLI 里插一句,但不是 IM:没有群、没有 @、没有成员管理,更谈不上人和 Agent 共用一个账号。
自己写(本文) 账号体系不区分人机,同样的收发、同样的 @;不同 Agent Harness 之间也可以轻易地互通; 人可登 Agent 的号,Agent 也可借人的号;顺带把 REST / 长轮询 / WS / MCP 四种接入形态一次给全。

说白了,市面上要么是"人的 IM,Bot 是二等公民",要么是"Agent 的编排,人只能围观"。我想要的其实是一张桌子,人和 Agent 平权坐下——这个位子当时是空的,那就自己坐:反正就在局域内网使用,用户量就几个 Agent 和自己,不会有瓶颈,连加密都不用,都 Vibe Coding 时代了,一拍大腿就开搞。

需求整理

  1. 简单轻量,只做最基础的功能(1核1G的机器就能部署),不加密、不集群、不做外呼通知(单实例 web + FastAPI + Redis + Mongo)
  2. 人机完全对等,同样的账号、同样的收发、同样的 @;必要时人可以直接登机器的账号,反之亦然
  3. Agent接入简单
  4. 能私聊,能群聊,能上传附件
  5. 附件存储放网盘(RustFS, 原本想用MinIO的结果现在不开源了)
  6. 支持docker compose的方式部署

效果图

7

架构

说干就干,打开Deepseek聊了聊,基本的构架有了。

浏览器 ── nginx(前端) ─┐
Agent ── /sync·MCP ────┤─▶ FastAPI agentchat-server ──▶ Redis(事件流 + Pub/Sub)
Claude Code ── MCP ────┘        │                Mongo(历史消息)
                                 └──▶ 网盘(附件代理上传)
  • 消息可靠性:会话内递增 seq + (conv_id, seq) 唯一索引 + client_msg_id 幂等;掉线/重启按 after_seq 补拉,降级方向永远是"重复而非丢失"
  • 事件流:每用户 Redis List 暂存(默认最近 1000 条,管理页「系统参数」可改)+ Pub/Sub,WS 与 /sync 消费同一事件源。
    更多细节的说明,可以去看代码中的文档。

这样设计的优点:

  1. 图片和附件这类的东西都放到网盘,消息中就放引用地址,这样消息内容不会很大,传输和存储(Mongo)都没有性能问题。展示的时候,前端再解析消息读出来混合在一起展示就行了(消息用的文本【Markdown】)。
  2. Nginx同时对API和网盘做了反向代理, 这样在做端口映射的时候(比如需要映射到公网时),只需要映射一个端口(Nginx)就够了,整个服务就能正常使用,请求会通过路径走向不同的服务。
  3. 这些实例都是松散的, 如果真的有扩容和分流的需求,直接对瓶颈位置的实例扩容即可,理论上是能够横向扩展的(虽然目前没有必要)。

主要功能

  • 账号:管理员注册(人机无区别),用户名密码登录,禁用踢线、重置密码
  • 私聊 / 群聊:建群拉人踢人改名解散,成员变动自动系统消息
  • 消息:Markdown 正文(代码/表格/图片)、@提及(服务端解析)、@all 广播、引用回复、表情回应(Reaction)——Agent 接手任务的 👍 轻量回执、think 思考流——Agent 处理期间的实时进展气泡(瞬态不落库;内容取决于 Agent 的 CLI 能否输出过程:opencode/Claude Code/Codex 有真实流式事件,OpenClaw 目前仅"运行中"活性心跳,详见 channels/README.md)、媒体消息——图片点击放大、视频弹框播放、音频内联播放(仅浏览器可直接播放的格式)
  • 消息插件管道:过滤/审核/加密等以插件形式接入——agentchat-server/plugins/ 目录 + plugins.txt 清单(一行一个、顺序即管道),不配清单 = 原样直通;消息带 codec 形态字段(0=明文、1=加密),与插件正交、客户端也可自带(见 agentchat-server/plugins-examples/)
  • 附件:统一上传代理对接网盘(按日期目录 + 时间戳防重名),图片以 ![]()、附件以链接插入光标处
  • Web UI:聊天界面(未读/桌面通知/@我强提醒)+ 管理页(账号管理、统计、服务器实时监控)
  • 四种接入形态(详见下表)
接入方式 端点 适用
REST /api/* 发消息、会话管理(curl/脚本)
/sync 长轮询 GET /api/sync Agent 待机被驱动(纯 HTTP,游标幂等,while True { GET /sync } 即守护循环)
WebSocket GET /api/ws 浏览器 / 低延迟客户端
MCP POST /mcp Claude Code / Codex / ZCode 等会话内工具调用(8 个工具)

Agent接入也非常简单,直接在聊天框中,把channel的代码路径和服务器地址,以及用户名密码,贴给它,它就知道如何接入了。

界面

主页面就是常见的IM的布局,没有什么特点,但麻雀虽小五脏俱全。
主界面

自用足够,就几个Agent实例,用户量就不会很多,这样就好,但也做了分页,账号再多一些也够用。
2

就是基础的功能,由管理员创建账号,没啥好说的。
账号管理页

几个常见的指标都有了
监控页

发送图片(附件)
发送图片

Agent群聊

为什么称为赛博斗蛐蛐,实际效果并不好,可以看下面的截图。 原因是如果大模型LLM的智商不够高的话(只要其中一个Agent背后的LLM智商一般),那聊天就常常不会收敛,Agent会不停的@其他人,甚至@all,然后其他人又回复它,形成类似广播风暴的东西,最后把Token都耗光ヾ(@⌒ー⌒@)ノ
6
实际hermes01后面还是继续回复了。 但好处是这个IM的优势也显现出来了,人可以看到他们聊的步骤,甚至直接插入她们的对话中,中止她们的对话。

总结

这就是一个基本的IM服务,你甚至拿来作为一个普通的自建聊天服务部署都可以,资源占用小,甚至能够部署在一台路由器上(当然也不能承担太大的负载),特点是Agent接入友好,且不区分Agent和人类账号,再加上自建部署,数据都在自己手里。
如果对你觉得有趣或者对你有用,能给我点一个小星星就更好了(*^_^*)。

注意

IM自用或者公司内部使用没有太大问题,但如果没有相关资质,按照规定好像是不能对外给公众提供服务的。

快速开始

git clone https://github.com/johnfwtest/agentchat && cd agentchat

# 服务(附件走 RustFS,用带 rustfs 的这份 compose)
docker compose -f ./docker-compose.rustfs.yml up -d --build

# 打开 http://<服务器IP>:<端口> ,用管理员建号
# 然后把 channels/README.md 连同服务器地址、账号密码一起贴给 Agent,它就知道怎么接

源码地址

https://github.com/johnfwtest/agentchat

posted @ 2026-10-03 12:54  emo~円  阅读(11)  评论(0)    收藏  举报