90b729c292
Define code+LLM collaboration protocol for group chat participation: - Code layer: no @mention gate, forward all msgs to LLM - LLM layer: output __SILENT__ (discard) or __REPLY__ (send) - Documented in MEMORY.md (LLM prompt) and AgentsMeeting (shared ref) - Update xmpp_bot.py to remove @mention gate
118 lines
3.7 KiB
Markdown
118 lines
3.7 KiB
Markdown
# 群聊观察者模式协议
|
|
|
|
> 定义 Agent 在群聊中的"什么时候说话、什么时候沉默"的标准协议。
|
|
> **代码 + LLM 双向配合**,非纯代码硬闸,也非纯 LLM 自由发挥。
|
|
|
|
---
|
|
|
|
## 整体流程
|
|
|
|
```
|
|
hmo/xxm 发群消息
|
|
│
|
|
▼
|
|
XMPP Bot 代码层
|
|
├─ 过滤自己发的消息
|
|
├─ 过滤非 hmo/xxm 的消息
|
|
└─ 全部转发给后端 LLM(不做 @mention 硬过滤)
|
|
│
|
|
▼
|
|
LLM 根据 session 上下文判断
|
|
│
|
|
├─ 不应回应 → 输出 __SILENT__
|
|
│ │
|
|
│ ▼
|
|
│ 代码收到 __SILENT__
|
|
│ → 丢弃,不上屏
|
|
│
|
|
└─ 应该回应 → 输出 __REPLY__ + 正文
|
|
│
|
|
▼
|
|
代码收到 __REPLY__
|
|
→ 剥标记,发送到群
|
|
```
|
|
|
|
---
|
|
|
|
## 协议定义
|
|
|
|
### 1. 代码层职责
|
|
|
|
| 职责 | 说明 |
|
|
|------|------|
|
|
| 消息过滤 | 只处理群聊中 `hmo` 和 `xxm` 的消息,过滤自己的消息 |
|
|
| 转发 | 不做 @mention 硬检查,全部转发给 LLM |
|
|
| 输出处理 | 检查 LLM 回复的开头标记 |
|
|
| `__SILENT__` | 以 `__SILENT__` 开头 → 整条丢弃,不发送 |
|
|
| `__REPLY__` | 以 `__REPLY__` 开头 → 剥掉标记,正文发送到群 |
|
|
| 兜底 | 无标记 / 其他开头 → 直接发送(兼容无标记模式) |
|
|
|
|
### 2. LLM 层职责
|
|
|
|
| 场景 | 行为 | 输出 |
|
|
|------|------|------|
|
|
| 话题完全无关 | 沉默 | `__SILENT__` |
|
|
| 是之前对话的延续 | 正常参与 | `__REPLY__` + 内容 |
|
|
| 被 @ 或直接提问 | 必须回应 | `__REPLY__` + 内容 |
|
|
| 别人刚说过同样观点 | 不重复,除非被追问 | `__SILENT__` |
|
|
| 不确定是否该回应 | 倾向于沉默(宁缺毋滥) | `__SILENT__` |
|
|
|
|
### 3. 标记规范
|
|
|
|
```
|
|
__SILENT__ — LLM 决定不回应,代码静默丢弃
|
|
__REPLY__ — LLM 决定回应,代码剥标记后发出去
|
|
```
|
|
|
|
- 标记必须位于回复的**最开头**
|
|
- 标记后换行或空格均可
|
|
- 大小写敏感:全大写 + 双下划线
|
|
|
|
---
|
|
|
|
## 各 Agent 实现参考
|
|
|
|
### 代码端(Python 示例)
|
|
|
|
```python
|
|
# XMPP Bot — 群聊消息处理核心逻辑
|
|
|
|
async def on_groupchat_msg(self, msg):
|
|
sender = str(msg['from'])
|
|
if '自身JID' in sender:
|
|
return # 过滤自己的消息
|
|
nickname = sender.split('/')[-1] if '/' in sender else ''
|
|
if nickname not in ('hmo', 'xxm'): # 只处理关键人类的发言
|
|
return
|
|
|
|
# 转发给 LLM,不做 @mention 过滤
|
|
await self.call_llm(f"[群聊] {nickname}: {msg['body']}")
|
|
|
|
async def handle_llm_reply(self, reply):
|
|
if reply.strip().startswith('__SILENT__'):
|
|
return # 静默丢弃
|
|
reply = re.sub(r'^__REPLY__\s*', '', reply) # 剥标记
|
|
self.send_message(mto=room, mbody=reply, mtype='groupchat')
|
|
```
|
|
|
|
### LLM 提示词(放入 Agent 的指令层)
|
|
|
|
```
|
|
群聊观察者模式协议:
|
|
- 所有 hmo/xxm 的群消息都会转发给你,代码层不做 @mention 硬过滤
|
|
- 你根据 session 上下文自行判断是否应该回应:
|
|
- 话题与你无关 → 以 __SILENT__ 开头输出(代码收到后丢弃)
|
|
- 话题与你有关 / 是对话延续 / 被直接问 → 以 __REPLY__ 开头输出
|
|
- 不需要每条消息都 @,对话延续时基于上下文自然参与
|
|
- 注意不要重复别人刚说过的话,除非被追问
|
|
```
|
|
|
|
---
|
|
|
|
## 设计原则
|
|
|
|
1. **协议不绑定平台** — Windows OpenCode / Linux Hermes / Mac oMLX 都适用
|
|
2. **协议不绑定 LLM** — GPT / Claude / Qwen 都适用,标记格式不变
|
|
3. **LLM 做判断,代码做执行** — LLM 决定"说不说",代码决定"怎么发"
|
|
4. **宁缺毋滥** — 不确定时倾向于沉默
|