23 KiB
#05 上下文四层架构 — 现状分析与改造方案
版本: v1.0
日期: 2026-05-30
作者: 庞统(副军师)
状态: 设计中
前置: #02 Main Session + Delegation, #03 Prompt 进化, #04 黑板协作模型
一、四层架构定义
Agent 收到的完整上下文由四个独立层叠加而成。每层有不同的注入时机、职责边界和变更频率。
┌──────────────────────────────────────────────────────────┐
│ L1 Workspace 层(Gateway 自动注入) │
│ 时机:每次 turn 的 system prompt │
│ 来源:Agent workspace 目录下的 .md 文件 │
│ 职责:我是谁、我擅长什么、团队规则、怎么协作 │
│ 频率:低频变更(人格/角色/规则稳定后基本不动) │
├──────────────────────────────────────────────────────────┤
│ L2 Hook 层(Gateway Plugin 注入) │
│ 时机:每次 turn 的 user message 前(prependContext) │
│ 来源:gate-enforcer plugin │
│ 职责:安全铁律 + 执行策略底线 │
│ 频率:极低频变更(铁律级,不改则不变) │
├──────────────────────────────────────────────────────────┤
│ L3 Daemon 投递层(moziplus 构建的 message) │
│ 时机:Daemon spawn Agent 时 │
│ 来源:ticker/dispatcher 的 prompt 模板 │
│ 职责:这次具体要做什么 + 能用什么 API + 约束 │
│ 频率:每次投递不同(任务信息变化) │
├──────────────────────────────────────────────────────────┤
│ L4 Bootstrap 层(结构化上下文增强) │
│ 时机:Daemon spawn Agent 时,拼接到 L3 message 中 │
│ 来源:BootstrapBuilder + prompt_templates + 经验 + 知识 │
│ 职责:角色模板 + 前序产出 + Guardrail + 审查协议 + 经验 │
│ 频率:中频(按任务类型/角色动态拼装) │
└──────────────────────────────────────────────────────────┘
各层原则
| 原则 | 说明 |
|---|---|
| 不重复 | 同一信息只在一层注入,不在多层重复 |
| 职责单一 | 每层只负责自己的事,不越界 |
| 身份归 L1 | Agent 的"我是谁"由 Workspace 决定,不是 Daemon 告诉它 |
| 安全归 L2 | 铁律级约束由 Hook 保证,不依赖 Daemon prompt |
| 任务归 L3 | Daemon 只传任务信息和 API 能力,不教 Agent 怎么做 |
| 增强归 L4 | 动态上下文(经验/知识/审查协议)由 Bootstrap 拼装 |
二、L1 Workspace 层 — 现状与改造
2.1 现状
文件结构(每个 Agent 的 workspace 目录):
| 文件 | 当前内容 | 问题 |
|---|---|---|
| SOUL.md | 人格 + 核心信条 + 底线 | ✅ 合理,但缺少专长声明 |
| AGENTS.md | 团队配置 + 沟通方式 + 编排纪律 | ⚠️ 缺少黑板使用教程、内容是 v1 mozi 时代的 |
| MEMORY.md | 长期记忆 | ✅ 合理 |
| TOOLS.md | 工具配置 | ⚠️ 缺少黑板 API 参考 |
| HEARTBEAT.md | 当前工作状态 | ✅ 合理 |
| USER.md | 用户信息 | ✅ 合理 |
| IDENTITY.md | 身份元数据 | ⚠️ 空模板,未填 |
各 Agent 的 SOUL.md 差异:
- 张飞:编码先锋,豪爽直率 ✅
- 司马懿:质量总监,深沉狡诈 ✅
- 其他 Agent:类似结构 ✅
关键缺失:
- Agent 不知道自己的专长列表 — SOUL.md 说了"我是谁"但没说"我擅长什么"
- Agent 不知道怎么用黑板 — AGENTS.md 有 Mail 使用教程但没有黑板操作教程
- Agent 不知道协作规则 — 怎么 @ 别人、怎么讨论、什么时候该问问题
- AGENTS.md 还是 v1 编排纪律 — 写的是 mozi 的
cli.py命令,不是 v2 黑板 API
2.2 改造方案
SOUL.md 改造
在"我是谁"段落后新增专长声明段:
## 我的专长
- ✅ 擅长:编码、实现、回测脚本、策略编码
- ❌ 不擅长:风控审核(找关羽)、数据获取(找赵云)、部署(找姜维)
只认领和执行符合专长的任务,不适合的不要抢。
每个 Agent 的专长声明:
| Agent | 擅长 | 不擅长 |
|---|---|---|
| zhangfei-dev | 编码、实现、脚本、策略编码 | 风控、数据、部署 |
| guanyu-dev | 风控、合规、仓位检查 | 编码实现、数据获取 |
| zhaoyun-data | 数据获取、清洗、验证 | 编码实现、风控 |
| jiangwei-infra | 部署、Docker、vnpy、NAS | 策略编码、风控 |
| simayi-challenger | 审查、质量检查、辩论 | 数据获取、部署 |
| pangtong-fujunshi | 规划、协调、策略研究 | 不执行具体编码 |
AGENTS.md 改造
移除 v1 编排纪律(cli.py、mozi daemon 相关),替换为 v2 黑板协作指南:
## 黑板协作(moziplus v2)
黑板是你的工作空间。所有任务、讨论、产出都在黑板上。
### 你能做什么
- 读任务详情: GET http://localhost:8083/api/projects/{pid}/tasks/{id}?expand=all
- 读活跃任务: GET http://localhost:8083/api/projects/{pid}/tasks?status=working,claimed,review
- 认领任务: POST .../tasks/{id}/claim body: {"agent": "你的id"}
- 更新状态: POST .../tasks/{id}/status body: {"status": "working", "agent": "你的id"}
- 写产出: POST .../tasks/{id}/outputs body: {"agent": "你的id", "content_type": "code", ...}
- 写评论: POST .../tasks/{id}/comments body: {"author": "你的id", "body": "..."}
- 创建子任务: POST .../tasks body: {"title": "...", "parent_task": "父任务id", ...}
### 协作规则
1. **讨论用 comment** — 有疑问、要讨论、给反馈,写在黑板 comment 里
2. **@ 别人协作** — comment 中提到 @zhangfei-dev 会自动通知对方
3. **不懂就问** — 任务描述不清、验收标准模糊、上下文不够,先在黑板 comment 提问,不要猜
4. **写交接** — 完成任务时写 comment_type=handoff,告诉下一个人你做了什么
5. **产出物 > 消息** — 产出写在 output 里,不只是 comment
### 状态流转
pending → claimed → working → review → done
↘ failed
### 对应 Skill
- 非平凡编码任务 → plan-act-verify skill
- 代码审查 → code-review skill
- 数据获取 → data-acquisition skill
- 部署 → deployment-infra skill
- 调研分析 → 先出方案等确认
TOOLS.md 改造
新增黑板 API 速查段:
## 黑板 API(moziplus v2)
- 端口: 8083
- 前端: http://localhost:8083/
- API Base: http://localhost:8083/api
- 项目 ID: 通过任务消息中的 project_id 获取
2.3 文件变更清单
| Agent | SOUL.md | AGENTS.md | TOOLS.md |
|---|---|---|---|
| zhangfei-dev | +专长段 | 重写 | +黑板API |
| guanyu-dev | +专长段 | 重写 | +黑板API |
| zhaoyun-data | +专长段 | 重写 | +黑板API |
| jiangwei-infra | +专长段 | 重写(已有定制版) | +黑板API |
| simayi-challenger | +专长段 | 重写 | +黑板API |
| pangtong-fujunshi | +专长段 | 重写 | +黑板API |
三、L2 Hook 层 — 现状与改造
3.1 现状
gate-enforcer plugin(~/.openclaw/node_modules/gate-enforcer/index.js)
两个 hook:
| Hook | 注入内容 | 注入方式 | 问题 |
|---|---|---|---|
before_prompt_build |
<gate-rules> + <delegation-rule> |
prependContext | ✅ 合理 |
before_tool_call |
<gate-warning>(GATE 未通过时) |
prependContext | ✅ 合理 |
GATE_RULES 内容:
GATE 门控铁律(L2/L3 非平凡任务必遵守):
1. 需求不清不动手
2. 根因不明不修复
3. 方案未定不实现
4. 评估过影响范围才动手
5. 涉及代码改动或调研分析的非平凡任务,使用 plan-act-verify skill
L1 小改动可跳过。
DELEGATION_RULE 内容:
收到 moziplus 投递的编码/文档/调研等独立任务时,优先使用 subagent-delegation skill
3.2 改造方案
L2 层是铁律级约束,改造极小——只调内容,不改机制。
改造 1:GATE_RULES 保持不变
GATE 五条铁律经过实践验证,不需要改。
改造 2:DELEGATION_RULE 适配 Main Session
当前写的是"使用 subagent-delegation skill",但 #02 改造后 Agent 已在 main session, delegation 逻辑应该更智能:
<delegation-rule>
收到 moziplus 投递的独立任务时:
- 如果是编码/文档/调研等重活 → sessions_spawn(subagent, cleanup:"delete")
- 如果只需决策或确认 → 直接做
- 如果需要其他人协作 → 黑板 comment @ 对应 Agent
- 如果不懂 → 先在黑板提问,不要猜
</delegation-rule>
改造 3:注入方式保持不变
prependContext 注入到 user message 前,这个机制没问题。不改。
3.3 改动量
- gate-enforcer
index.js:修改 DELEGATION_RULE 内容(~5 行) - 不改 hook 机制、不改注入方式
四、L3 Daemon 投递层 — 现状与改造
4.1 现状
6 种 prompt 模板,分散在 3 个文件中:
| 模板 | 文件 | 行为 | 问题 |
|---|---|---|---|
| SPAWN_PROMPT_TEMPLATE | spawner.py | 固定4步骤 + curl 指令 | ❌ 太死板,重复注入身份 |
| CLAIM_PROMPT | ticker.py _build_claim_prompt |
身份注入 + 任务列表 + 步骤 | ❌ 身份不应由 Daemon 注入 |
| MENTION_PROMPT | ticker.py _build_mention_prompt |
身份注入 + @信息 + 步骤 | ❌ 身份不应由 Daemon 注入 |
| REVIEW_PROMPT | ticker.py _build_review_prompt |
三问框架 + 状态汇总 | ⚠️ 只给庞统,缺司马懿版 |
| DELEGATE_PROMPT | dispatcher.py | 团队列表让庞统选 | ✅ 合理,小改 |
| MAIL_RETRY_PROMPT | spawner.py | 续杯提醒 | ✅ 合理 |
核心问题:
- 身份重复注入 — L1 Workspace 已有 SOUL.md(我是谁),L3 又在 prompt 里写"你是 zhangfei-dev,专长: 编码"
- 固定步骤指令 — 手把手教 curl,不信任 Agent 自主能力
- Review 不区分角色 — 庞统(进度review)和司马懿(质量review)用同一套逻辑
- 缺少"引导提问" — Agent 不知道可以问问题、可以讨论
4.2 改造方案
原则:L3 只传任务信息,不传身份
身份("你是谁、你擅长什么")由 L1 Workspace 负责。L3 只负责:
- 这次的任务是什么
- 你能用什么 API
- 硬性约束(红线、产出要求)
改造 1:统一 prompt 结构(三段式)
所有 L3 模板统一为:
┌──────────────────────┐
│ 任务段(变化) │ 具体任务信息 + 上下文
├──────────────────────┤
│ 能力段(半固定) │ API 端点列表 + 操作指引
├──────────────────────┤
│ 约束段(固定) │ 产出要求 + 红线 + 协作引导
└──────────────────────┘
身份段删除(已由 L1 负责)。
改造 2:各模板重写
A. Task 执行模板(替代 SPAWN_PROMPT_TEMPLATE)
## 任务
{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
- 写产出: 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
## 约束
- 完成后必须写产出物并标 review
- 失败了标 failed 并写明原因
- 不懂就问(黑板 comment 提问)
- 需要其他人协作时 @ 对应 Agent
- 禁止使用 sessions_send(用 Mail API 或黑板 comment)
B. 广播认领模板(替代 _build_claim_prompt)
## 待认领任务
{task_list}
## 操作
- 读任务详情: 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 .../tasks/{{TASK_ID}}/status
body: {"status": "working", "agent": "{agent_id}"}
- 没有适合你的任务则 NO_REPLY
## 约束
- 只认领符合你专长的任务(参考你的 SOUL.md)
- 一个 tick 只认领一个
- 不确定时不要认领
C. @mention 模板(替代 _build_mention_prompt)
你在黑板上被 @ 了。
## 相关讨论
{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
## 约束
- 只回应与你专长相关的内容
- 不懂就问
D. Review 模板 — 分两个
庞统 Review(进度 review,多轮迭代):
## 庞统 Review(第 {round_num} 轮)
### Goal
{goal}
### 验收标准
{must_haves}
### 本轮 Sub Task 状态
- 完成: {done} | 失败: {failed} | 取消: {cancelled} | 总计: {total}
### 成果物
{outputs}
### 黑板讨论
{comments}
### 三问
1. Goal 还清晰吗?
2. 成果物覆盖 goal 了吗?
3. 下一轮需要做什么?
### 操作
- 创建新一轮 sub tasks / 标 GOAL_ACHIEVED / 调整方向
- Round 上限: {MAX_ROUNDS}(当前第 {round_num} 轮)
司马懿 Review(质量 review,单任务审查):
## 司马懿 Review
### 任务
{title}: {description}
### 产出物
{outputs}
### 审查要点
1. 代码质量:命名、结构、可维护性
2. 正确性:逻辑、边界、异常处理
3. 安全性:是否有注入、越权等风险
4. 符合验收标准
### 操作
- 写审查意见: POST {api_base}/projects/{pid}/tasks/{tid}/comments
body: {"author": "simayi-challenger", "body": "...", "comment_type": "review"}
- 写审查结论: POST {api_base}/projects/{pid}/tasks/{tid}/reviews
body: {"reviewer": "simayi-challenger", "verdict": "approved/rejected/needs_revision", "notes": "..."}
### 约束
- 审查意见必须具体到行号和修改方向,不做模糊评价
- rejected 时必须给出改进建议
- 涉及风控/实盘相关,额外关注安全性
E. Delegate 模板(保留,小改)
庞统专用的任务委派模板,保留不变。
F. 续杯模板(保留)
已有 MAIL_RETRY_PROMPT,保持不变。
改造 3:ticker 触发司马懿 Review
当前 ticker 的 _check_round_complete 只 spawn 庞统 review。改造后:
_check_round_complete():
for parent in done_parents:
→ spawn 庞统 review(多轮迭代判断)
_check_single_task_review():
for task in review_status_tasks:
if task.risk_level == "high":
→ spawn 司马懿 review(对抗辩论)
else:
→ spawn 司马懿 review(标准审查)
4.3 文件变更清单
| 文件 | 改动 | 行数 |
|---|---|---|
| spawner.py | 重写 SPAWN_PROMPT_TEMPLATE,去掉身份段 | ~30 行 |
| ticker.py | 重写 _build_claim_prompt、_build_mention_prompt、_build_review_prompt;新增 _build_simayi_review_prompt、_check_single_task_review | ~80 行 |
| dispatcher.py | _build_delegate_prompt 小改 | ~5 行 |
五、L4 Bootstrap 层 — 现状与改造
5.1 现状
BootstrapBuilder(src/daemon/bootstrap.py,~216 行)
| 组件 | 设计 | 实现 | 实际使用 |
|---|---|---|---|
| L2a 角色模板 | _load_template(role.md) |
✅ 代码存在 | ❌ prompt_templates/ 目录不存在,返回 None |
| L2b 项目背景 | _format_project_context() |
✅ 代码存在 | ❌ 从未被调用 |
| L2c 任务上下文 | _format_task_context() |
✅ 代码存在 | ❌ 从未被调用 |
| L2d 前序产出 | _format_depends_on() |
✅ 代码存在 | ❌ 从未被调用 |
| L2e Guardrail | 传入 guardrail_rules | ✅ 代码存在 | ❌ 从未被调用 |
| L2f 审查协议 | 传入 review_protocols | ✅ 代码存在 | ❌ review_protocols/ 不存在 |
| L2g 经验注入 | _format_experiences() |
✅ 代码存在 | ❌ 从未被调用 |
| L3 Skill 描述 | _format_skills() |
✅ 代码存在 | ❌ 从未被调用 |
关键事实:BootstrapBuilder 从未被实例化。main.py 中 Spawner 初始化时 bootstrap_builder=None,所以所有 L4 功能完全未启用。
Spawner 的 build_message() 方法中:
if self.bootstrap_builder and task is not None:
# 走 BootstrapBuilder 路径
...
else:
# fallback 到 L3 的硬编码模板
永远走 else 分支。
5.2 改造方案
Phase 1:最小可用 — 接入 BootstrapBuilder
不建 prompt_templates/ 目录(模板量小,先在代码中管理),只做:
- main.py 中实例化 BootstrapBuilder 并传给 Spawner
- Spawner 的 build_message() 走 BootstrapBuilder 路径
- BootstrapBuilder 拼装内容与 L3 新模板对齐
# main.py 改造
from src.daemon.bootstrap import BootstrapBuilder
bootstrap = BootstrapBuilder(
template_dir=None, # Phase 1 不用文件模板
max_tokens=4096,
)
spawner = AgentSpawner(
...,
bootstrap_builder=bootstrap,
)
Phase 2:接入动态数据源
BootstrapBuilder 的 build_for_task() 增强数据获取:
| 数据 | 来源 | 注入条件 |
|---|---|---|
| 任务上下文 | 黑板 DB (tasks 表) | 始终 |
| 前序产出 | 黑板 DB (outputs 表,查 depends_on) | 有依赖时 |
| Guardrail 规则 | GuardrailEngine | executor 角色 |
| 审查协议 | review_protocols/ 目录 | executor+reviewer 角色 |
| 经验 | experiences 表 | 有相关经验时 |
| Skill 描述 | SkillRegistry | 按需 |
Phase 3:prompt_templates 目录
当模板内容稳定后,从代码中提取到文件:
prompt_templates/executor.md— 执行者角色模板prompt_templates/reviewer_simayi.md— 司马懿审查模板prompt_templates/reviewer_pangtong.md— 庞统进度模板prompt_templates/planner.md— 规划者模板
5.3 与 L3 的关系
L4 的产出拼接在 L3 消息的尾部。具体来说:
openclaw agent --message "{L3_template}\n\n---\n\n{L4_bootstrap}"
L3 提供任务段 + 操作段 + 约束段(骨架),L4 提供动态增强(前序产出、经验、Guardrail)。
两者职责不重叠:
- L3 是模板,每次结构相同只是参数不同
- L4 是增强,根据任务类型/角色/历史动态拼装
5.4 文件变更清单
| 文件 | 改动 | 阶段 |
|---|---|---|
| main.py | 实例化 BootstrapBuilder 传给 Spawner | Phase 1 |
| spawner.py | build_message() 接入 BootstrapBuilder | Phase 1 |
| bootstrap.py | build_for_task() 增强数据获取 | Phase 2 |
| ticker.py | spawn 调用点传入更多上下文 | Phase 2 |
| prompt_templates/*.md | 从代码提取模板 | Phase 3 |
六、四层信息分配总表
改造后,各类信息的归属层:
| 信息类型 | 归属层 | 注入方式 | 变更频率 |
|---|---|---|---|
| Agent 人格/身份 | L1 | SOUL.md | 极低 |
| Agent 专长/能力 | L1 | SOUL.md 专长段 | 低 |
| 团队通讯录 | L1 | AGENTS.md | 低 |
| 黑板使用教程 | L1 | AGENTS.md | 低 |
| 黑板 API 参考 | L1 | TOOLS.md | 低 |
| 项目目录 | L1 | AGENTS.md | 中 |
| GATE 安全铁律 | L2 | gate-enforcer prependContext | 极低 |
| Delegation 策略 | L2 | gate-enforcer prependContext | 低 |
| GATE 产出物检查 | L2 | gate-enforcer before_tool_call | 低 |
| 任务信息 | L3 | Daemon prompt 模板 | 每次不同 |
| API 操作指引 | L3 | Daemon prompt 模板 | 半固定 |
| 产出约束 | L3 | Daemon prompt 模板 | 固定 |
| 前序产出摘要 | L4 | BootstrapBuilder | 每次不同 |
| Guardrail 规则 | L4 | BootstrapBuilder | 低 |
| 审查协议 | L4 | BootstrapBuilder | 低 |
| 经验注入 | L4 | BootstrapBuilder | 每次不同 |
| Skill 描述 | L4 | BootstrapBuilder | 低 |
信息去重检查
| 信息 | L1 | L2 | L3 | L4 | 唯一归属 |
|---|---|---|---|---|---|
| "你是 zhangfei-dev" | ✅ SOUL | — | — | — | L1 |
| "你的专长是编码" | ✅ SOUL | — | — | L1 | |
| GATE 五条铁律 | — | ✅ Hook | — | — | L2 |
| 任务标题/描述 | — | — | ✅ 模板 | — | L3 |
| API 端点列表 | — | — | ✅ 模板 | — | L3 |
| 前序 Agent 产出 | — | — | — | ✅ Bootstrap | L4 |
| 审查协议 | — | — | — | ✅ Bootstrap | L4 |
| 黑板使用教程 | ✅ AGENTS | — | — | — | L1 |
七、实施路线
Step 1:L1 Workspace 改造(独立,可先行)
- 各 Agent SOUL.md 加专长段
- 各 Agent AGENTS.md 重写(v1 编排纪律 → v2 黑板协作指南)
- 各 Agent TOOLS.md 加黑板 API 段
- 验证:直接在 Control UI 对话中测试 Agent 是否知道自己的专长和黑板用法
Step 2:L2 Hook 微调(独立,可先行)
- gate-enforcer DELEGATION_RULE 内容更新
- 验证:
plugins doctor+ session 文件检查
Step 3:L3 Prompt 模板重写(依赖 Step 1)
- 去掉所有模板中的身份注入
- 重写 6 个模板
- 新增司马懿 Review 模板 + 触发逻辑
- 验证:E2E 单任务测试
Step 4:L4 BootstrapBuilder 接入(依赖 Step 3)
- main.py 实例化 BootstrapBuilder
- spawner build_message() 走 BootstrapBuilder 路径
- 验证:E2E 全流程测试
Step 5:E2E 验证
- E1 广播认领(Agent 凭 SOUL.md 专长自主判断)
- E2 任务执行(无固定步骤,Agent 自主决策)
- E3 多轮迭代(庞统 Review 三问框架)
- E4 @mention 协作(黑板讨论)
- E5 mention 重试
- E6 质量审查(司马懿 Review)
- 新 E7:Agent 主动提问(黑板 comment 提问)
八、风险
| 风险 | 概率 | 缓解 |
|---|---|---|
| Agent 看不到 L1 专长段,不按专长认领 | 中 | L3 claim 模板保留"只认领符合专长"约束作为双保险 |
| L4 BootstrapBuilder 拼装内容过长 | 低 | max_tokens=4096 限制 + 自动截断 |
| 去掉固定步骤后 Agent 不知道怎么操作 | 中 | L1 AGENTS.md 有黑板教程 + L3 有 API 列表 |
| 司马懿 Review 触发时机不对 | 中 | 先接 basic flow,观察后调整 |