Files
sanguo_moziplus_v2/docs/research/v2.6-research-02-eventdriven-context.md
T
2026-05-15 09:31:37 +08:00

31 KiB
Raw Blame History

调研报告:事件驱动架构 + 上下文管理策略

版本: v1.0 作者: 庞统(副军师) 日期: 2026-05-15 范围: moziplus v2.6 AI Native DevOps 平台


课题 2:事件驱动架构 + 并行/串行决策

1. 已有经验(知识库/wiki

~/.openclaw/sanguo_projects/sanguo_moziplus/docs/design/ 中有完整的架构设计文档:

文档 关键内容
architecture-v2.6.md 当前 v2.6 使用 60s polling tick 轮询黑板,Daemon tick 读取黑板状态→发现需要介入的→spawn agent
technical-design-v2.6.md Daemon ticker.py 实现了 tick 循环主逻辑,含 @mention 解析、session 管理、健康检查

当前痛点

  • Agent 被 @mention 后最多等 60 秒才知道(polling 间隔)
  • Daemon tick 是重量级操作(读全量黑板、检查所有任务、处理所有 mention)
  • 没有即时响应能力,用户紧急操作只能靠手动触发 tick

2. 业界优秀实践对比表

项目 通知机制 事件类型 依赖解析 并行/串行决策 亮点
open-multi-agent 事件驱动 TaskQueuetask:ready 事件自动触发下游) task:ready, task:complete, task:error 拓扑排序(topological sort),complete→自动解锁下游 pending 任务 依赖声明驱动depends_on 声明后自动判断并行/串行 3 个运行时依赖,零基础设施,纯 TypeScript EventEmitter
Network-AI 原子黑板信号(propose→validate→commit + file-backed mutex propose, validate, commit, rollback 无显式依赖图,通过原子提交保证一致性 Agent 自行判断并行(信号锁机制防竞态) 零外部依赖,251 个测试,12 框架适配器
Hermes Kanban Dispatcher 60s polling tick(与 v2.6 相同) 状态变化 + comment + mention 7 状态完整状态机 Dispatcher 调度决定并行/串行 成熟稳定,但同样受限于 polling 延迟
Claude Code Agent Teams 共享任务列表 + 直接消息(SendMessage tool task:claimed, task:completed, message 无显式依赖图 Agent 自主认领(先到先得) 每个 agent 独立 1M token context window,通过消息通信
GSD (Get-Shit-Done) Wave-based 执行,阶段式推进 Plan 级事件(phase complete Plan 中声明 depends_onwave 编号 Wave 执行:同 wave 并行,跨 wave 串行 每个 executor 独立 200K token 新鲜上下文,消除 context rot
Confluent 事件驱动模式 Kafka 事件流 AgentTaskSubmitted, AgentResultPublished DAG 依赖声明 Event Router 根据依赖图路由 4 种模式:链式、广播-聚合、动态路由、竞技
Azure Agent Patterns 多种:顺序/并发/群聊/交接 按模式定义 Workflow pattern 支持依赖图 编排模式选择sequential vs concurrent vs group-chat 最完整的模式分类

3. 重点项目深度分析

3.1 open-multi-agent — 事件驱动 TaskQueue

核心机制TaskQueue 是一个可变、事件驱动的队列,支持拓扑依赖解析。

// queue.ts 核心逻辑
// Tasks enter in 'pending' state.
// Queue promotes them to 'blocked' when unresolved dependencies exist.
// When dependencies resolve → back to 'pending', firing 'task:ready'
// When task completes → auto-unlock downstream dependent tasks

关键设计

  1. 事件类型task:ready(依赖满足)、task:complete(任务完成)、task:error(任务失败)
  2. 自动解锁:当 task complete 时,自动检查所有依赖于它的 pending 任务,如果依赖全部满足,触发 task:ready
  3. 并行决策:纯依赖声明驱动——没有依赖关系的任务自然并行执行
  4. 零基础设施:纯 EventEmitter,不依赖 Redis/Kafka/数据库

对我们的启示

  • complete→auto-unlock 是核心模式,替代 polling tick 的"检查依赖是否满足"
  • 依赖声明优于 Agent 自行判断并行性
  • 事件驱动不一定要引入消息队列基础设施

3.2 Network-AI — 原子黑板信号

核心机制propose→validate→commit 三阶段原子提交,file-backed mutex 防竞态。

1. Agent 调用 propose(key, value) → 写入 .proposed 文件
2. validate() → 检查约束条件(其他 agent 没有冲突 propose
3. commit() → 原子性写入最终状态
4. 失败 → rollback() → 清理 .proposed 文件

关键设计

  1. 信号机制:通过文件系统信号(.proposed.committed)通知其他 Agent
  2. 原子性保证:flock 文件锁 + 三阶段提交 = 无竞态
  3. 零外部依赖:不需要 Redis/数据库做分布式锁
  4. 251 个测试:竞态条件覆盖充分

对我们的启示

  • 我们的 SQLite CASclaim_task 的原子 UPDATE WHERE)已经实现了类似功能
  • 三阶段提交模式适合"产出审核"场景(propose 产出 → 庞统 validate → commit 到黑板)
  • 文件系统信号可以作为轻量级通知机制的灵感

3.3 Hermes Kanban — 当前 v2.6 的参考

核心机制Dispatcher 60s tick + SQLite 黑板 + 7 状态机。

Dispatcher loop (every 60s):
  1. Reclaim stale claims(超时回收)
  2. Promote ready tasks(依赖满足 → 推进状态)
  3. Atomically claim(原子认领)
  4. Spawn assigned profilesspawn agent

与 v2.6 的对比:我们的设计直接参考了 Hermes,但 Hermes 本身也有 polling 延迟问题。Hermes 提供了 Nudge dispatcher 手动触发来缓解。

4. 事件类型定义

基于所有调研项目,我们需要的核心事件类型:

事件类型 触发条件 消费者 优先级
task_created 任何 Agent 创建任务 Daemon(检查是否需要 spawn
task_claimed Agent 认领任务 Daemon(更新 agent 状态)
task_completed Agent 完成任务 Daemon(解锁下游依赖 + spawn 下一环)
task_failed Agent 任务失败 Daemon(重试逻辑 + 通知庞统)
task_blocked Agent 请求帮助 Daemonspawn 被提及的人)
comment_added 评论写入 Daemon(检查 @mention
output_written 产出写入 Daemon(通知相关方)
@mention 评论中提及 Agent Daemon(立即 spawn 被提及者) 最高
user_action 用户在黑板上的操作 Daemon(立即响应) 最高

5. 通知机制对比

方案 延迟 复杂度 依赖 适用场景
Polling(当前) ≤60s 最低 简单场景,容忍延迟
SQLite update_hook ~0ms(进程内) sqlite3 C API Daemon 内部事件触发
文件系统 watchinotify/FSEvents ~ms OS 原生 跨进程通知
SQLite WAL file watch ~ms fswatch/watchdog 跨进程 SQLite 变更通知
Unix socket / Named pipe ~ms 本地进程间通信
Redis pub/sub ~ms Redis 分布式场景
Signal file + polling ≤1s 最低 混合方案
asyncio.Event(进程内) ~0ms 最低 Daemon 进程内部

6. 推荐方案:分层事件驱动(结合 AI Native 目标)

6.1 核心思路:不引入重依赖,进程内事件 + 轻量跨进程信号

┌─────────────────────────────────────────────────┐
│                Daemon (Python asyncio)           │
│                                                   │
│  ┌─────────────┐    ┌──────────────────────┐    │
│  │ EventBus    │    │ Tick Loop (fallback)  │    │
│  │ (asyncio)   │    │ 30s 轮询兜底          │    │
│  └──────┬──────┘    └──────────────────────┘    │
│         │                                         │
│  Agent 操作黑板时:                                │
│  1. 写入 SQLite(当前逻辑不变)                    │
│  2. 写入 signal file(通知 daemon                │
│  3. Daemon 检测到信号 → 立即触发事件处理            │
└─────────────────────────────────────────────────┘

6.2 具体实现

Layer 1:进程内 EventBusasyncio

import asyncio
from enum import Enum
from dataclasses import dataclass
from typing import Callable, Awaitable

class EventType(str, Enum):
    TASK_CREATED = "task_created"
    TASK_CLAIMED = "task_claimed"
    TASK_COMPLETED = "task_completed"
    TASK_FAILED = "task_failed"
    TASK_BLOCKED = "task_blocked"
    COMMENT_ADDED = "comment_added"
    OUTPUT_WRITTEN = "output_written"
    USER_ACTION = "user_action"

@dataclass
class Event:
    type: EventType
    task_id: str | None
    agent: str | None
    detail: dict | None

class EventBus:
    def __init__(self):
        self._handlers: dict[EventType, list[Callable]] = {}
        self._queue: asyncio.Queue[Event] = asyncio.Queue()
    
    def on(self, event_type: EventType, handler: Callable):
        self._handlers.setdefault(event_type, []).append(handler)
    
    async def emit(self, event: Event):
        await self._queue.put(event)
    
    async def start(self):
        """主事件循环"""
        while True:
            event = await self._queue.get()
            handlers = self._handlers.get(event.type, [])
            for handler in handlers:
                try:
                    await handler(event)
                except Exception as e:
                    logger.error(f"Event handler error: {e}")
    
    async def emit_from_blackboard_op(self, event_type: EventType, task_id: str, 
                                       agent: str, detail: dict = None):
        """黑板操作后触发事件"""
        await self.emit(Event(type=event_type, task_id=task_id, agent=agent, detail=detail))

Layer 2Signal File 跨进程通知

import os
from pathlib import Path

SIGNAL_DIR = Path("~/.sanguo_projects/sanguo_moziplus_v2/signals")

async def write_signal(event_type: str, task_id: str = None, agent: str = None):
    """Agent(外部进程)写入信号文件"""
    signal_file = SIGNAL_DIR / f"{event_type}.signal"
    payload = f"{task_id or ''}:{agent or ''}:{time.time()}"
    signal_file.write_text(payload)

async def watch_signals():
    """Daemon 监听信号文件"""
    while True:
        for signal_file in SIGNAL_DIR.glob("*.signal"):
            if signal_file.exists():
                payload = signal_file.read_text()
                parts = payload.split(":")
                event_type = signal_file.stem
                await event_bus.emit(Event(
                    type=EventType(event_type),
                    task_id=parts[0] or None,
                    agent=parts[1] or None,
                    detail=None
                ))
                signal_file.unlink()  # 处理完删除
        await asyncio.sleep(0.5)  # 500ms 检查间隔(比 60s 好 120 倍)

Layer 3Fallback Tick30s 兜底)

保留简化版 tick 循环,30s 一次(从 60s 降为 30s),只处理:

  • 健康检查(zombie 检测、stale 任务回收)
  • 信号遗漏兜底(万一 signal file 处理失败)

6.3 事件处理优先级

# 高优先级事件:立即 spawn
HIGH_PRIORITY = {
    EventType.TASK_COMPLETED,    # 解锁下游
    EventType.TASK_FAILED,       # 触发重试
    EventType.TASK_BLOCKED,      # 请求帮助
    EventType.COMMENT_ADDED,     # 可能含 @mention
    EventType.USER_ACTION,       # 用户操作
}

# 低优先级事件:排队处理
LOW_PRIORITY = {
    EventType.TASK_CREATED,
    EventType.TASK_CLAIMED,
    EventType.OUTPUT_WRITTEN,
}

7. 并行/串行决策推荐

7.1 决策矩阵

场景 并行/串行 决策依据 示例
无依赖任务 并行 depends_on 为空 赵云下载数据 + 庞统写方案
有依赖任务 串行 depends_on 声明 先下载数据 → 再回测
同一任务冲突 串行(先到先得) SQLite CAS 张飞和关羽抢同一个 review
产出审核 串行(完成→审核→通过) 状态机 张飞完成 → 司马懿审核
独立研究 并行 无交集的子任务 多个因子独立调研
同文件修改 串行 文件路径冲突检测 不能两人同时改同一个文件

7.2 推荐策略:依赖声明优先,Daemon 辅助仲裁

  1. 显式依赖:任务创建时声明 depends_on(庞统/创建者负责声明)
  2. 自动并行depends_on 为空且 assignee 不同的任务,自动并行 spawn
  3. 自动串行:有 depends_on 的任务,上游完成事件触发下游 spawn
  4. 冲突检测:如果两个任务的 files_modified 有交集,Daemon 警告并建议串行
  5. 庞统仲裁:争议场景 spawn 庞统决定
async def on_task_completed(event: Event):
    """任务完成 → 解锁下游依赖"""
    task_id = event.task_id
    
    # 查找所有依赖于该任务的 blocked 任务
    downstream = db.query(
        "SELECT * FROM tasks WHERE status='pending' AND depends_on LIKE ?",
        (f'%{task_id}%',)
    )
    
    for task in downstream:
        deps = json.loads(task['depends_on'])
        # 检查所有依赖是否都完成了
        all_done = all(
            db.query("SELECT status FROM tasks WHERE id=?", (d,))[0]['status'] == 'done'
            for d in deps
        )
        if all_done:
            # 自动解锁:触发 task:ready
            await event_bus.emit(Event(
                type=EventType.TASK_READY,
                task_id=task['id'],
                agent=task['assignee'],
            ))
            # 立即 spawn 对应 agent
            await spawn_agent(task['assignee'], f"任务 {task['id']} 依赖已满足,请查看并认领。")

课题 10:上下文管理策略

1. 黑板信息量具体测算

基于 architecture-v2.6.md 中的 SQLite Schema,逐项测算:

1.1 一个任务基础信息(tasks 表)

字段                    典型内容                              估算 tokens
─────────────────────────────────────────────────────────────────────
id                     "task-001"                            1
title                  "动量因子策略回测"                       5
description            "对动量因子进行历史回测,验证策略有效性"  20
status                 "working"                             1
assignee               "zhangfei-dev"                        2
assigned_by            "pangtong-fujunshi"                   2
depends_on             ["task-001", "task-002"]              5
parent_task            "task-000"                            1
priority               5                                     1
task_type              "coding"                              1
created_at             "2026-05-15 09:00:00"                 3
updated_at             "2026-05-15 10:30:00"                 3
claimed_at             "2026-05-15 09:05:00"                 3
started_at             "2026-05-15 09:10:00"                 3
deadline               "2026-05-16 18:00:00"                 3
retry_count            0                                     1
─────────────────────────────────────────────────────────────────────
小计(结构化格式)                                            ~50-60 tokens

一个任务基础信息 ≈ 50-60 tokens

1.2 评论(10 条,comments 表)

每条评论典型内容:
  "张飞,你的实现方案我看了,回测数据量大时内存会爆。关羽,从风控角度也看看?
   @关羽 @张飞"
  + author + created_at + mentions JSON
  ≈ 30-50 tokens/条

10 条评论 ≈ 300-500 tokens

1.3 产出(5 个,outputs 表)

每个产出典型内容:
  output_type: "code"
  title: "分批加载实现"
  content_path: "task-001/output-zhangfei-v2.md"
  summary: "实现分批加载,单批50万条"
  metadata: {"files_changed": 3, "lines_added": 150}
  + agent + created_at
  ≈ 30-50 tokens/个

5 个产出 ≈ 150-250 tokens

1.4 事件日志(10 条,events 表)

每条事件:
  event_type: "task_claimed"
  agent: "zhangfei-dev"
  detail: {"from": "pending", "reason": null}
  + created_at
  ≈ 15-25 tokens/条

10 条事件 ≈ 150-250 tokens

1.5 决策记录(3 条,decisions 表)

每条决策:
  decision: "使用分批加载而非流式"
  rationale: "流式需要改底层框架,分批只需改回测模块"
  alternatives: ["流式加载", "内存映射"]
  ≈ 40-80 tokens/条

3 条决策 ≈ 120-240 tokens

1.6 观察记录(3 条,observations 表)

每条观察:
  severity: "warning"
  body: "止损逻辑在分批模式下可能漏触发"
  ≈ 20-30 tokens/条

3 条观察 ≈ 60-90 tokens

1.7 总计

组件 数量 估算 tokens
任务基础信息 1 个 50-60
评论 10 条 300-500
产出 5 个 150-250
事件日志 10 条 150-250
决策记录 3 条 120-240
观察记录 3 条 60-90
总计 830-1390 tokens
+ JSON 格式开销(花括号、引号) ~150-200 tokens
+ 提示词格式(标题、分隔符) ~100-150 tokens
实际传给 LLM 的总量 ~1100-1750 tokens

关键结论:一个典型任务的全量黑板信息约 1100-1750 tokens。

极端情况(30 条评论、10 个产出、50 条事件):

  • 评论:30 × 40 = 1200 tokens
  • 产出:10 × 40 = 400 tokens
  • 事件:50 × 20 = 1000 tokens
  • 总计约 3000-4000 tokens

即使极端情况也在 4000 tokens 以内,远小于 200K context window。

但是——如果有多个任务(比如庞统规划了 5 个子任务),5 个任务 × 1500 tokens = 7500 tokens,仍然可控。

真正的问题不是单个任务的黑板信息,而是

  1. 产出物文件内容(code diff、分析报告)可能很大
  2. 长讨论线程(30+ 评论来回讨论)
  3. Agent 的 system prompt + SOUL.md + skill 文件已经占用大量 context

2. 业界优秀实践对比表

项目 上下文策略 核心机制 优点 缺点
Claude Code Auto-compact + file reference 1) 自动压缩:接近 context limit 时先清 tool output,再 summarize 对话 2) /compact 手动压缩 3) @file 引用而非内联 4) CLAUDE.md 持久记忆 成熟稳定,官方支持 压缩可能丢失细节;单一 session 内累积
Claude Code Agent Teams 每个 Agent 独立 1M token context 隔离 context window + 共享任务列表 + SendMessage 直接通信 天然隔离,无 context rot 问题 跨 agent 通信开销
GSD (Get-Shit-Done) Wave Execution:每个 plan 独立新鲜 200K context 1) Plan 分 wave 执行 2) 每个 executor 新鲜 context 3) 原子 git commit 4) 主 context 保持 30-40% 彻底消除 context rot 需要精确的 plan 分解
Network-AI 原子黑板(数据在黑板,不在 context) Agent 只读黑板摘要,详细数据在文件中 context 极小 需要额外读取操作
Hermes Kanban kanban_show() 按需读取 Agent 只看当前任务看板,不全量读取 简单有效 可能遗漏全局信息
Agent Chorus Checkpoint + 跨 Agent 消息 Standup drain inbox + conclude broadcast + checkpoint 状态广播 跨框架兼容 复杂度较高
Opal-Bridge Cross-agent session translator Claude Code ↔ Codex CLI 格式转换 多工具协作 范围有限
MindStudio 三层内存:工作/短期/长期 Working(当前会话)+ Short-term(任务级)+ Long-term(项目级) 分层清晰 需要额外基础设施

3. 重点项目深度分析

3.1 Claude Code — Auto-compact + File Reference

核心机制

  1. 自动压缩(Auto-compact

    • 当 context 使用接近 limit 时,先清除旧 tool output
    • 然后自动 summarize 对话历史
    • 用户可通过 CLAUDE.md 自定义压缩策略(如 "压缩时保留修改文件列表和测试命令")
    • /compact 手动触发,/compact "保留所有类型定义" 可带自定义指令
  2. 文件引用(@-reference

    • @file_path 引用文件内容,而非内联到对话中
    • LLM 按需读取,避免全量加载
  3. CLAUDE.md 持久记忆

    • 项目级(CLAUDE.md+ 用户级(~/.claude/CLAUDE.md
    • 每次 session 启动自动加载
    • 相当于 L1 核心信息

对我们的启示

  • 产出的详细内容不应放在黑板 context 中,只放摘要 + 文件路径引用
  • Agent 读取产出时应按需 read 文件,不全量注入 context

3.2 GSD (Get-Shit-Done) — Wave Execution

核心机制

/gsd:execute-phase N
├── 分析 plan 依赖关系
├── Wave 1(无依赖的 plan):
│   ├── Executor A(新鲜 200K context)→ commit
│   └── Executor B(新鲜 200K context)→ commit
├── Wave 2(依赖 Wave 1):
│   └── Executor C(新鲜 200K context)→ commit
└── Verifier(检查所有产出)

关键数据

  • 主 context 始终保持在 30-40%(因为重活在 subagent 中做)
  • 每个 executor 独立 200K token,不做压缩(新鲜 context 不需要)
  • 每个 plan 一个原子 git commit(可回滚)

对我们的启示

  • 我们的 Agent spawn 模式天然就是 Wave ExecutionDaemon spawn 隔离 session,每个 agent 独立 context
  • 关键是 spawn 时传多少上下文——传太多浪费,传太少丢信息
  • 产出写入黑板摘要 + 文件路径,下一个 agent 按需读取

3.3 Opal-Bridge — Cross-Agent Session Translator

核心机制:将 Claude Code 的 session 格式转换为 Codex CLI 的格式,实现跨工具接力。

Fidelity 概念(从 cross_agent_session_resumer 项目借鉴):

  • Native fidelity:保留原始格式的完整信息
  • Lossy export:转换为通用格式时丢失部分信息
  • Checkpoint:关键节点快照

对我们的启示

  • Agent 之间的"接力"需要定义标准化的交接格式
  • 不是所有信息都需要完整传递——关键是决策、产出摘要、未完成事项

4. 推荐方案:分层传递策略

4.1 三层信息架构

┌─────────────────────────────────────────────────────┐
│  L1: 核心信息(必须传入,~200-400 tokens            │
│  ─────────────────────────────────────────────────── │
│  • 任务 ID + 标题 + 状态                              │
│  • 任务描述(description                            │
│  • 我的角色 + 触发原因(为什么 spawn 我)              │
│  • 依赖任务的状态摘要(1 行/任务)                     │
│  • 最近 3 条评论摘要                                  │
│                                                       │
│  传递方式:spawn message 中直接写入                    │
│  保证:任何 Agent 都能在 L1 信息下开始工作              │
├─────────────────────────────────────────────────────┤
│  L2: 扩展信息(按需读取,~500-1500 tokens           │
│  ─────────────────────────────────────────────────── │
│  • 完整评论线程                                       │
│  • 产出摘要列表(title + summary,不含详细内容)       │
│  • 决策记录                                          │
│  • 观察记录                                          │
│  • 其他相关任务摘要                                   │
│                                                       │
│  传递方式:Agent 通过 CLI 按需读取                     │
│  CLI: blackboard.py read --task task-001 --level L2   │
├─────────────────────────────────────────────────────┤
│  L3: 全量信息(按需读取,不限制大小)                  │
│  ─────────────────────────────────────────────────── │
│  • 产出物文件完整内容                                  │
│  • 完整事件日志                                      │
│  • 所有子任务详情                                     │
│                                                       │
│  传递方式:文件路径引用,Agent 用 read 工具读取         │
│  黑板只存 content_path,不存文件内容                   │
└─────────────────────────────────────────────────────┘

4.2 Agent Spawn 时的上下文模板

def build_spawn_message_L1(task_id: str, agent_id: str, trigger: str) -> str:
    """L1 核心:~200-400 tokens,直接写入 spawn message"""
    task = get_task(task_id)
    deps_status = []
    for dep_id in json.loads(task['depends_on'] or '[]'):
        dep = get_task(dep_id)
        deps_status.append(f"  {dep_id}: {dep['status']} - {dep['title']}")
    
    recent_comments = get_comments(task_id, limit=3)
    comments_str = ""
    for c in recent_comments:
        comments_str += f"  [{c['created_at'][:16]} {c['author']}] {c['body'][:100]}\n"
    
    return f"""黑板任务通知(L1):
任务:{task['title']}{task['id']}
状态:{task['status']}
类型:{task['task_type']}
触发原因:{trigger}
描述:{task['description'] or '(无)'}

依赖状态:
{chr(10).join(deps_status) if deps_status else '  (无依赖)'}

最近评论:
{comments_str if comments_str else '  (无评论)'}

请使用以下命令获取更多信息:
  L2(扩展):blackboard.py read --task {task_id} --level L2
  L3(全量产出):blackboard.py read --task {task_id} --type outputs
"""

4.3 黑板上的信息分层规则

信息类别 存储位置 黑板上展示 说明
任务元数据 黑板 tasks 表 完整 ID、标题、状态、描述、分配、依赖
评论 黑板 comments 表 完整 所有评论保留,L2 读取
产出摘要 黑板 outputs 表 title + summary + path 详细内容在文件中
产出详细内容 文件系统 仅文件路径 Agent 按需 read
决策记录 黑板 decisions 表 完整 L2 读取
观察记录 黑板 observations 表 完整 L2 读取
事件日志 黑板 events 表 仅最近 10 条 L3 按需查询

4.4 后接 Agent 无缝接力的关键

  1. 产出物标准化:每个产出必须包含 summary(一句话摘要)+ content_path(文件路径),不存大段文本
  2. 决策必须记录Agent 的关键决策写入 decisions 表,后继者可通过 L2 了解"为什么这么做"
  3. 未完成事项显式化:Agent 结束前在评论中写 "未完成:XXX",后继者一目了然
  4. 触发原因明确Daemon spawn 时必须说明为什么 spawn@mention / 依赖满足 / 用户指令)

5. Context 预算分配建议

假设使用 128K context window 的模型(如 gpt-4o / claude-3.5):

组件 预算 说明
System Prompt + SOUL.md + IDENTITY.md ~3000-5000 tokens 固定开销
Skills + AGENTS.md ~2000-4000 tokens 固定开销
L1 spawn message ~300-500 tokens 任务核心信息
L2 黑板扩展信息(按需) ~500-1500 tokens 完整讨论、决策
L3 产出物文件(按需) ~2000-10000 tokens 代码/报告内容
工作空间(Agent 思考+输出) ~30000-50000 tokens 预留给 Agent 实际工作
总计 ~40K-70K tokens 远小于 128K,安全

关键结论:我们的黑板信息量远小于 context window 限制,不需要做复杂的压缩/摘要。核心策略是:

  1. L1 必传~300-500 tokens,任何场景都负担得起
  2. L2 按需:Agent 自己决定是否需要深入了解讨论/决策
  3. L3 文件引用:大内容只在文件中,黑板只存路径

总结与行动建议

课题 2 行动建议(事件驱动)

优先级 行动 工作量
P0 实现 asyncio EventBus 进程内事件总线 1 天
P0 实现 Signal File 跨进程通知(Agent→Daemon 0.5 天
P1 事件处理:task_completed → 解锁下游依赖 0.5 天
P1 事件处理:comment_added → @mention 检测 0.5 天
P2 保留 30s fallback tick(健康检查) 0 天(简化现有 tick
P2 files_modified 冲突检测 1 天

预期效果

  • @mention 响应从 ≤60s 降到 ≤1s
  • 任务依赖解锁从 ≤60s 降到 ~0ms(进程内事件)
  • 不引入任何新依赖

课题 10 行动建议(上下文管理)

优先级 行动 工作量
P0 定义 L1/L2/L3 分层读取 API 0.5 天
P0 实现 L1 spawn message 模板 0.5 天
P1 产出物只存摘要+路径的规范落地 0 天(已在 schema 中)
P2 blackboard.py read --level L2 实现 0.5 天
P2 Agent 规范:结束前写未完成事项 0 天(文档规范)

核心原则

  • 黑板是索引(做什么 + 在哪找),不是仓库(详细内容)
  • 产出物在文件中,黑板只存路径
  • Agent spawn 时传最小充分上下文(L1),按需获取更多(L2/L3)
  • 不做复杂压缩——信息量本身就很小

参考项目索引

项目 URL 关键参考价值
open-multi-agent github.com/JackChen-me/open-multi-agent 事件驱动 TaskQueue + 依赖自动解锁
Network-AI github.com/jovanSAPFIONEER/Network-AI 原子黑板 propose→validate→commit
Hermes Kanban github.com/NousResearch/hermes-agent 60s tick + SQLite 黑板 + 状态机
GSD (Get-Shit-Done) github.com/gsd-build/get-shit-done Wave Execution + 新鲜 context
Claude Code code.claude.com Auto-compact + file reference + agent teams
Agent Chorus github.com/cote-star/agent-chorus 跨 Agent checkpoint + 消息传递
Azure Agent Patterns learn.microsoft.com 编排模式分类(sequential/concurrent/handoff
Confluent 事件驱动 confluent.io/blog 4 种事件驱动多 Agent 模式