auto-sync: 2026-05-29 20:41:23

This commit is contained in:
cfdaily
2026-05-29 20:41:23 +08:00
parent 696730c250
commit da8d213977
+92
View File
@@ -957,6 +957,98 @@ route(task_info, action_type):
**当前 Mail Tab**: 是 moziplus v2 内置的飞鸽传书功能(`_mail` 虚拟项目),是全新的实现,与 sanguo_mail 无关。两者不是同一个系统。
### 12.3 Mail API 防御 + Prompt 约束 📋
> 来源:#02 Main Session + Delegation 设计过程中发现的 Mail 自环问题
#### 问题
Agent 回复邮件时把 `to` 写成自己,导致自环(mail-1780056763652 事件)。根因:
1. **API 层无防御**`send_mail` 不校验 `to` 的合法性,不自动推断回复收件人
2. **Prompt 层无约束**:回复模板中 `to` 字段要求 Agent 手动填写,Agent 容易写错
#### API 层防御(`mail_routes.py` `send_mail`
| # | 场景 | 校验逻辑 | 错误处理 |
|---|------|---------|----------|
| A1 | `from` 缺失/为空 | 必填校验 | 400"`from` 必填" |
| A2 | `to` 缺失/为空(非回复) | 必填校验 | 400:"`to` 必填" |
| A3 | `from == to`(自环) | 防自环 | 400:"不能给自己发邮件" |
| A4 | `to` 对应的 Agent 不存在 | 从注册 Agent 列表校验 | 400"`{to}` 不是有效的 Agent" |
| A5 | `in_reply_to` 指向不存在的邮件 | 原邮件存在性校验 | 400:"回复的邮件 `{id}` 不存在" |
| A6 | `in_reply_to` 存在,`to` 与原邮件 `from` 不一致 | **自动纠正** | 用原邮件 `assigned_by` 替换 `to`,响应中提示 |
| A7 | `in_reply_to` 存在,`to` 未传 | **自动填充** | 从原邮件取 `assigned_by` 作为 `to` |
| A8 | `in_reply_to` 存在,`from` 不是原邮件 `to` | 允许(第三方参与会话) | 正常处理 |
**A4 校验方式**:从 ticker 的 `self.agents` 或 Agent 注册表获取有效 Agent ID 列表。硬编码 6 个 Agentzhangfei-dev / guanyu-dev / zhaoyun-data / jiangwei-infra / pangtong-fujunshi / simayi-challenger)作为初始方案,后续改为从配置读取。
**自动纠正逻辑**A6 + A7 合并处理——有 `in_reply_to` 时,`to` 不传或传错都自动从原邮件取 `assigned_by`(原始发件者)。
#### Prompt 层约束(`spawner.py` 模板)
**当前问题**
1. 回复模板中 curl 命令的 JSON 双花括号转义,Agent 容易写错
2. 没有告诉 Agent "to 会自动推断"Agent 手动填写容易出错
3. 没有给 Agent "发新邮件" 的模板,Agent 自己猜格式
4. 没有列出有效 Agent IDAgent 可能给不存在的 agent 发邮件
**改动**
```python
MAIL_REQUEST_TEMPLATE = """你收到一封飞鸽传书,需要你处理并回复。
发件者: {from_agent}
主题: {title}
内容: {text}
### 如何回复发件者
curl -s -X POST http://localhost:8083/api/mail \\
-H 'Content-Type: application/json' \\
-d '{{"from": "{agent_id}", "in_reply_to": "{task_id}", "title": "回复: {title}", "text": "你的回复内容"}}'
⚠️ 不需要填 "to",系统自动回复给发件者。
### 如何给其他人发新邮件
curl -s -X POST http://localhost:8083/api/mail \\
-H 'Content-Type: application/json' \\
-d '{{"from": "{agent_id}", "to": "对方agent-id", "title": "标题", "text": "正文", "type": "inform"}}'
⚠️ to 必须是有效的 agent idzhangfei-dev / guanyu-dev / zhaoyun-data / jiangwei-infra / pangtong-fujunshi / simayi-challenger
⚠️ 纯通知用 type=inform,需要对方回复不填 type(默认 request
⚠️ 不能给自己发邮件
⚠️ 不要执行任何状态转换命令(标 working/done/review/failed 等),系统会自动处理。
"""
MAIL_INFORM_TEMPLATE = """你收到一封飞鸽传书(纯通知)。
发件者: {from_agent}
主题: {title}
内容: {text}
已阅即可。如需回复,同上用 in_reply_to 回复发件者。
⚠️ 不要执行任何状态转换命令。
"""
```
**关键改动**
1. 回复模板去掉 `to` 字段,告诉 Agent "系统自动回复给发件者"
2. 新增"给其他人发新邮件"模板,列出所有有效 Agent ID
3. 三条 ⚠️ 覆盖三种错误场景(自环 / 幻觉 agent / 状态误操作)
4. inform 模板也加上回复指引
#### 涉及文件
| 文件 | 改动 |
|------|------|
| `src/api/mail_routes.py` | `send_mail` 加 A1-A8 校验 + 自动推断 |
| `src/daemon/spawner.py` | `MAIL_REQUEST_TEMPLATE` + `MAIL_INFORM_TEMPLATE` 更新 |
#### 状态
📋 设计完成,待评审 → 实施 → 验收
---
## §13. 经验沉淀