Files
sanguo_moziplus_v2/docs/design/03-prompt-evolution.md
T
2026-05-30 10:21:15 +08:00

417 lines
14 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 03-prompt-evolution.md — Prompt 进化:从固定步骤到自主决策
**日期**: 2026-05-30
**作者**: 庞统
**状态**: 已修订 v1.1(根据司马懿 2026-05-30 评审意见)
**前置**: `02-main-session-delegation.md`#02 统一走 main session
**来源**: architecture-v3.0.md §10.4 Prompt 进化
---
## 一、问题:现有 Prompt 是固定步骤指令,不 AI Native
### 现状
系统中有 **6 种 prompt 模板**,构建方式各不相同:
| 模板 | 位置 | 行为模式 | 问题 |
|------|------|---------|------|
| `SPAWN_PROMPT_TEMPLATE` | spawner.py L62 | 固定 4 步骤(标 working → 干活 → 写产出 → 标 review) | ❌ 不信任 Agent 自主能力,curl 硬编码,冗长 |
| `DISCUSSION_PROMPT_TEMPLATE` | spawner.py L148 | 开放式(你是自主的) | ✅ 方向正确,但与 SPAWN 模板风格断裂 |
| `CLAIM_PROMPT` | ticker.py `_build_claim_prompt` | 固定 4 步骤(读黑板 → claim → 标 working → 执行) | ❌ 没注入 Agent 身份/能力,庞统会抢张飞的活 |
| `REVIEW_PROMPT` | ticker.py `_build_review_prompt` | 三问框架 | ✅ 设计合理,小优化即可 |
| `MENTION_PROMPT` | ticker.py `_build_mention_prompt` | 固定步骤 | ❌ 过于机械 |
| `DELEGATE_PROMPT` | dispatcher.py `_build_delegate_prompt` | 列出团队成员让庞统选 | ✅ 可以保留 |
### 核心问题
1. **SPAWN_PROMPT 太长太死板**~100 行,手把手教 curl,Agent 像执行脚本而非自主决策
2. **CLAIM_PROMPT 不注入身份**:广播时不告诉 Agent 自己擅长什么,导致争抢
3. **模板碎片化**:6 个模板散布在 3 个文件中,风格不统一
4. **curl 硬编码**Agent 已经有工具(read/write/exec),不需要 curl
5. **不区分 Mail 路径 vs Task 路径**Mail 模板已精简(inform/request),Task 模板还是老式
### v3.0 设计方向回顾(architecture-v3.0.md §10.4
> 从"固定步骤指令"变成"身份 + 目标 + 能做什么 + 约束 + 交接责任"
```markdown
# 你的身份
你是 {agent_name}{agent_role}。擅长 {agent_capabilities}。
# 你的任务
{task_title}: {task_description}
类型: {task_type} | 风险: {risk_level}
必要条件: {must_haves}
# 你能做什么
通过 API 操作黑板({api_base}:
- 读任何任务详情: GET /api/projects/{pid}/tasks/{id}?expand=all
- ...
# 约束
- 完成后必须写产出 + 标 review
- 安全红线: {guardrails_summary}
```
---
## 二、方案:统一 Prompt 架构
### 2.1 设计原则
1. **信任 Agent** — Agent 有 SOUL.md、workspace、工具能力,不需要手把手教
2. **身份先行** — 每个 prompt 开头注入 Agent 身份和能力,让 Agent 知道自己能干什么、不该干什么
3. **目标清晰** — 告诉 Agent 要做什么,不告诉怎么做
4. **约束为底线** — 红线是硬约束,其余让 Agent 自主
5. **Mail 不动** — Mail 模板(inform/request)已经在 v1.0 验证过,保持不变
### 2.2 Agent 能力画像注入
从 Router 的 AgentProfile 中提取,注入到 prompt
```
你是 {agent_id}{role}。
你的专长: {capabilities}
```
| Agent | capabilities 注入 |
|-------|-------------------|
| zhangfei-dev | 编码、实现、脚本 |
| simayi-challenger | 审查、质量检查、辩论 |
| guanyu-dev | 风控、合规、仓位检查 |
| zhaoyun-data | 数据获取、清洗、验证 |
| jiangwei-infra | 部署、基础设施、Docker、vnpy |
| pangtong-fujunshi | 规划、协调、策略、升级处理 |
### 2.3 统一 Prompt 结构
所有 Task 路径的 prompt 统一为三段式:
```
┌─────────────────────────────┐
│ 1. 身份段(固定) │ Agent ID + 专长 + 角色
├─────────────────────────────┤
│ 2. 任务段(变化) │ 具体任务信息 + 上下文
├─────────────────────────────┤
│ 3. 约束段(固定) │ 红线 + 产出要求 + API 摘要
└─────────────────────────────┘
```
Mail 路径的 prompt 不变(inform/request 模板已精简)。
---
## 三、新模板设计
### 3.1 Task 执行模板(替代 SPAWN_PROMPT_TEMPLATE
```markdown
你是 {agent_id},专长: {capabilities}。
## 任务
{title}
{description}
项目: {project_id} | ID: {task_id}
类型: {task_type} | 优先级: {priority}
验收标准: {must_haves}
{retry_context}
## 你能做什么
- 读任务详情(含依赖、讨论、产出): GET {api_base}/projects/{project_id}/tasks/{task_id}?expand=all
- 读所有活跃任务: GET {api_base}/projects/{project_id}/tasks?status=working,claimed,review
- 写产出: POST {api_base}/projects/{project_id}/tasks/{task_id}/outputs
- 写评论/交接: POST {api_base}/projects/{project_id}/tasks/{task_id}/comments
- 更新状态: POST {api_base}/projects/{project_id}/tasks/{task_id}/status
- 创建子任务: POST {api_base}/projects/{project_id}/tasks
- 认领任务: POST {api_base}/projects/{project_id}/tasks/{{id}}/claim
## 约束
- 完成后必须写产出物(output)并标 review,不能无产出就提交
- 失败了标 failed 并写明原因
- 产出物 handoff comment ≥ 50 字符(用于系统验证)
- 禁止使用 sessions_send 直接发消息(用 Mail API 或黑板 comment
- 安全红线: {guardrails_summary}
### API 请求体示例
写产出: POST .../outputs
```json
{{"agent": "{agent_id}", "content_type": "code", "title": "产出标题", "content_path": "/path/to/file", "summary": "简要说明"}}
```
写评论: POST .../comments
```json
{{"author": "{agent_id}", "body": "评论内容(≥50字符)", "comment_type": "handoff"}}
```
```
**关键变化**
- 删掉固定 4 步骤(标 working → 干活 → 写产出 → 标 review),让 Agent 自主决策
- 删掉 curl 硬编码,改为 API 端点列表(Agent 有工具能力)
- 加身份注入(capabilities
- 加约束底线
### 3.2 广播认领模板(替代 _build_claim_prompt
```markdown
你是 {agent_id},专长: {capabilities}。
## 待认领任务
{task_list}
## 规则
- 只认领符合你专长的任务。你的专长是 {capabilities},不适合的任务不要认领
- 不确定时不要认领,留给更合适的 Agent
- 认领后必须写产出物再转 review
## 你能做什么
- 读任务详情: GET {api_base}/projects/{project_id}/tasks?status=pending
- 认领: POST {api_base}/projects/{project_id}/tasks/{{TASK_ID}}/claim
body: {{"agent": "{agent_id}"}}
- 认领后标 working: POST {api_base}/projects/{project_id}/tasks/{{TASK_ID}}/status
body: {{"status": "working", "agent": "{agent_id}"}}
- 没有适合你的任务则 NO_REPLY
## 约束
- 一个 tick 只认领一个任务
- 禁止使用 sessions_send 直接发消息
```
**关键变化**
- 加身份+专长注入,明确告诉 Agent "你的专长是 X,不适合的不要认领"
- 从"建议"变成"约束"
- 简化操作指引
### 3.3 @mention 模板(替代 _build_mention_prompt
```markdown
你在黑板上被 @ 了。
## 你的身份
你是 {agent_id},专长: {capabilities}。
## 相关讨论
{mentions_text}
## 任务上下文
- 项目: {project_id}
- 任务: {task.title}
- 描述: {task.description}
## 你能做什么
- 读完整上下文: GET {api_base}/projects/{project_id}/tasks/{task.id}?expand=all
- 回应: POST {api_base}/projects/{project_id}/tasks/{task.id}/comments
- 如果讨论收敛到可执行任务,可以创建 sub task
## 约束
- 只回应与你专长相关的内容
- 禁止使用 sessions_send 直接发消息
```
### 3.4 Review 模板(保留,小幅优化)
Review 模板已经合理(三问框架),只做两处优化:
1. 加身份注入:"你是 pangtong-fujunshi,任务协调员。"
2. 删掉 curl 硬编码,改为 API 端点列表
### 3.5 Delegate 模板(保留)
`_build_delegate_prompt` 保留不变。它只给庞统用,且设计合理(列出团队成员让庞统选)。
### 3.6 Discussion 模板(保留)
`DISCUSSION_PROMPT_TEMPLATE` 方向正确("你是自主的"),保留不变。
### 3.7 Mail 模板(不变)
Mail 路径的 inform/request 模板已在 v1.0 验证,保持不变。
---
## 四、能力注入机制
### 4.1 数据来源
从 Router 的 `AgentProfile.capabilities` 提取。Router 已在初始化时加载所有 Agent 画像:
```python
# router.py
self.agent_profiles = {
"zhangfei-dev": AgentProfile(capabilities=["coding", "implementation", "scripting"], ...),
"simayi-challenger": AgentProfile(capabilities=["review", "quality_check", "debate"], ...),
...
}
```
### 4.2 中文映射
Agent 需要中文的能力描述,不是英文标签:
```python
CAPABILITY_LABELS = {
"coding": "编码",
"implementation": "实现",
"scripting": "脚本",
"review": "审查",
"quality_check": "质量检查",
"debate": "辩论",
"deploy": "部署",
"infrastructure": "基础设施",
"docker": "Docker",
"vnpy": "vnpy框架",
"risk": "风控",
"compliance": "合规",
"position_check": "仓位检查",
"data": "数据",
"acquisition": "获取",
"cleaning": "清洗",
"verification": "验证",
"planning": "规划",
"coordination": "协调",
"escalation": "升级处理",
"strategy": "策略",
}
```
### 4.3 注入位置
`spawner.py` 中新增方法 `_inject_agent_identity(agent_id)` → 返回身份段字符串。所有 prompt 构建方法调用此方法获取身份段。
---
## 五、兜底机制
### 5.1 无人认领兜底(已实现)
广播认领路径已有兜底:
```
_broadcast_claim():
for task in pending:
if retry_count >= 3:
→ escalated(升级庞统)
else:
→ 广播给 idle agents
```
3 轮广播无人认领 → 任务标 `escalated` → 庞统接手(走 delegate 路径)。
### 5.2 Claim 并发保护(已实现)
`claim_task()` 是原子 CAS 操作:
```sql
UPDATE tasks SET status='claimed', assignee=? WHERE id=? AND status='pending'
```
多个 Agent 同时 claim 同一个任务,只有第一个成功(`rowcount=1`),其余返回 False。Agent 在 prompt 中被告知:「如果 claim 失败说明已被别人认领,NO_REPLY 退出」。
**不需要两步**claim + working)。claim 成功即标 `claimed`Agent 再标 `working` 时黑板校验 `status=claimed`,不存在竞态窗口。
---
## 六、占位符定义
### 6.1 `{guardrails_summary}`
**来源**: `GuardrailEngine.rules` 中的 6 条红线摘要。
**注入方式**: spawner 在构建 prompt 时从 `GuardrailEngine.rules` 提取 `rule_name`,拼接为逗号分隔的字符串。
```python
def _get_guardrails_summary(self) -> str:
if not self.guardrails:
return "无特殊限制"
return "".join(r["name"] for r in self.guardrails.rules[:6])
```
**当前 6 条红线**PRD §10.1):
1. 禁止操作生产环境数据库
2. 禁止执行未审核的外部代码
3. 禁止绕过风控规则
4. 禁止修改系统配置
5. 单次交易不得超过限额
6. 禁止未授权的资金操作
**没有 guardrails 时**: 填 "无特殊限制"。
### 6.2 `{retry_context}`
**来源**: `tasks.retry_count` 字段 + 上次执行的 outputs/comments。
**注入逻辑**(复用现有 `_build_retry_context`,增强):
```python
def _build_retry_context(self, task) -> str:
if (task.retry_count or 0) == 0:
return ""
parts = ["⚠️ 这是重试(第 {} 次尝试),之前的执行失败了。".format(task.retry_count + 1)]
# 可选:注入上次失败原因(从 comments 中取 system 写的失败记录)
return "\n".join(parts)
```
**首次执行时**: 填空字符串,不渲染重试段。
---
## 七、改动范围
| 文件 | 改动点 | 改动量 |
|------|--------|--------|
| `spawner.py` | 重写 `SPAWN_PROMPT_TEMPLATE`;新增 `_inject_agent_identity()`;修改 `_build_spawn_message()` | ~60 行 |
| `ticker.py` | 重写 `_build_claim_prompt()`;重写 `_build_mention_prompt()`;小改 `_build_review_prompt()` | ~50 行 |
| `dispatcher.py` | `_build_delegate_prompt()` 加身份注入 | ~5 行 |
**总改动量**: ~115 行,涉及 3 个文件。
### 不改的
- `MAIL_INFORM_TEMPLATE` / `MAIL_REQUEST_TEMPLATE` — 已精简,不变
- `DISCUSSION_PROMPT_TEMPLATE` — 方向正确,不变
- `router.py` — 只读 capabilities,不改
- `prompt_templates/` 目录 — 暂不创建(模板代码量小,直接在 Python 中管理更方便调试)
---
## 八、收益
| 维度 | 改善 |
|------|------|
| **Token 节省** | SPAWN_PROMPT 从 ~100 行 → ~30 行,每次 spawn 节省 ~70 行 |
| **Agent 自主性** | 从"固定步骤"到"目标+约束"Agent 自主决策执行路径 |
| **争抢问题** | 身份+专长注入,Agent 明确知道"我不该认领这个" |
| **风格统一** | 6 个模板统一为三段式结构 |
| **curl 消除** | 不再硬编码 curl,Agent 用自己的工具能力 |
---
## 九、风险
| 风险 | 缓解 |
|------|------|
| **Agent 过度自主** | 约束段保留硬性底线(必须写产出、必须标 review) |
| **身份注入不够强** | 用"只认领符合你专长的任务"而非"建议" |
| **API 端点不熟悉** | 每个模板都列出完整 API 列表,Agent 不需要猜 |
| **Review 模板改坏** | Review 只做小改(加身份+去 curl),不动三问框架 |
---
## 十、实施计划
### Phase 1Task 执行模板 + 身份注入
1. 新增 `_inject_agent_identity()` 到 spawner.py
2. 重写 `SPAWN_PROMPT_TEMPLATE`
3. 重写 `_build_claim_prompt()`
4. 部署 + 单任务 E2E 验证
### Phase 2:其他模板统一
1. 重写 `_build_mention_prompt()`
2. 小改 `_build_review_prompt()`
3. `_build_delegate_prompt()` 加身份注入
4. 全量 E2E 验证