从族谱到事件总线:FROST-SOP 如何把家族治理变成可运行的调度引擎

从族谱到事件总线:FROST-SOP 如何把"家族治理"变成可运行的调度引擎

一、从一句"听起来很美"说起

昨天我们聊了 FROST 的六层治理宪法模型------从宪法层到结果层,层层嵌套、层层约束。

评论区有人问了一个很实在的问题:

"这套家族治理的理念听起来很完整,但它怎么跑起来?总不能靠嘴遁吧?"

问得好。

任何治理模型,如果不能被编码成可执行的系统,那就只是哲学,不是工程。

FROST 是思想源头,FROST-SOP 就是让思想落地开花的工程实现。今天这篇文章,我想把 FROST-SOP 的核心调度引擎拆开给你看------从事件总线到角色生命周期,从族谱记录到记忆沉淀,一步一步讲清楚:

"祖辈-父辈-子辈"这套听起来像封建制度的东西,到底是怎么变成一行行跑在服务器上的代码的。


二、核心挑战:为什么不能是简单的"主从模式"?

在讲实现之前,先回答一个更根本的问题:

为什么要搞"家族"这么复杂的概念?一个主 Agent 管一堆子 Agent,不行吗?

我们做过,然后翻车了。

翻车现场:主从模式的三个死穴

死穴1:主 Agent 是单点瓶颈。

所有任务都经过主 Agent 拆解、分配、回收。任务量小的时候没问题,一旦并行任务超过 5 个,主 Agent 的注意力就被严重稀释------它记不住每个子任务的细节,回收质量急剧下降。

就像一个创业公司,CEO 直接管 20 个员工,每个人做什么他都记不清。

死穴2:没有中层,信息全靠传话。

主 Agent 派子 Agent 做任务,子 Agent 做完返回结果。如果子 Agent 在执行中发现问题、需要调整方向,它只能汇报给主 Agent,等主 Agent 决策。

一来一回,延迟爆炸。更糟的是,主 Agent 没有一线信息,决策质量也不高。

死穴3:用完即散,记忆不沉淀。

子 Agent 用完就删,下一次做类似任务,又是从零开始。每一次都是"第一次",没有任何积累。

你做了 100 次日报任务,每次的错误、经验、最佳实践,全都随子 Agent 一起消散了。


破局:引入"家族"结构

FROST 的解法,是在"主从"之间加了一层------父辈

复制代码
传统主从:   主Agent → 子Agent(扁平,无积累)
FROST家族:  祖辈 → 父辈 → 子辈(分层,有中层,有记忆)

这不是拍脑袋的设计,而是从组织行为学里搬来的经验:

层级 类比 核心职责 生命周期
祖辈 CEO / 创始人 任务拆解、资源分配、全局协调 常驻
父辈 项目经理 子任务管理、质量把控、记忆沉淀 按项目存活
子辈 执行者 具体任务执行 用完即散

关键在于父辈这一层 ------它是整个体系的"中层管理",向上对祖辈负责,向下管理子辈执行,同时它还是记忆的闸门------所有执行经验必须经过父辈筛选、整理,才能进入家族知识库。

好,理念讲完了。下面进入硬核部分:这套东西在代码里长什么样?


三、调度引擎的骨架:事件驱动架构

FROST-SOP 的调度引擎,核心是一条事件总线(Event Bus)。所有角色------祖辈、父辈、子辈、长老------都通过发布和订阅事件来协作,没有任何直接调用。

3.1 为什么是事件驱动?

事件驱动架构有三个好处,恰好对应家族治理的三个需求:

  1. 解耦:祖辈不需要知道父辈的实现细节,它只需要发布一个"任务创建"事件。谁来接、怎么接,祖辈不管。
  2. 可观测:所有事件都流过总线,天然形成一条完整的审计链。这就是族谱记录的技术基础。
  3. 弹性:角色可以随时上下线------子辈执行完就销毁,父辈在项目结束后撤场,祖辈常驻。一切由事件驱动,不需要中心化的调度器。

3.2 事件总线的极简实现

python 复制代码
# core/event_bus.py
from typing import Callable, Any
from collections import defaultdict
from dataclasses import dataclass, field
import uuid
import time


@dataclass
class Event:
    """事件是FROST-SOP中一切协作的载体"""
    event_type: str           # 事件类型:task_created / agent_spawned / task_completed ...
    payload: dict             # 事件数据
    source: str               # 发出者:ancestor / father_001 / child_007 ...
    event_id: str = field(default_factory=lambda: uuid.uuid4().hex)
    timestamp: float = field(default_factory=time.time)
    lineage: list = field(default_factory=list)  # 血缘链:谁触发了谁


class EventBus:
    """全局事件总线
    
    所有Agent通过事件总线通信,不直接调用。
    这是族谱记录的基础设施------每一条事件都是一条族谱记录。
    """
    
    def __init__(self):
        self._subscribers: dict[str, list[Callable]] = defaultdict(list)
        self._event_log: list[Event] = []  # 完整事件日志 = 族谱
    
    def subscribe(self, event_type: str, handler: Callable):
        """订阅某类事件"""
        self._subscribers[event_type].append(handler)
    
    def publish(self, event: Event):
        """发布事件,触发所有订阅者"""
        self._event_log.append(event)
        
        for handler in self._subscribers.get(event.event_type, []):
            try:
                handler(event)
            except Exception as e:
                # 订阅者异常不影响其他订阅者
                self.publish(Event(
                    event_type="handler_error",
                    payload={"error": str(e), "handler": handler.__name__},
                    source="event_bus",
                    lineage=[event.event_id],
                ))
    
    def get_genealogy(self, task_id: str) -> list[Event]:
        """查询某个任务的完整族谱(血缘链追溯)"""
        return [e for e in self._event_log 
                if e.payload.get("task_id") == task_id]


# 全局单例
bus = EventBus()

这段代码看起来很简单,但它是整个 FROST-SOP 的骨架。

理解了事件总线,你就理解了为什么说**"族谱不是事后写的,是实时流淌出来的"**------每一个事件都是族谱的一笔,自动记录、不可篡改、完整可追溯。


四、角色生命周期:祖辈如何召唤府兵

有了事件总线,角色之间的协作就变成了"发布事件 → 触发响应 → 产生新事件"的循环。

下面我们看一个完整的任务生命周期:祖辈接到任务 → 召唤父辈 → 父辈召唤子辈执行 → 子辈消散 → 父辈沉淀记忆 → 父辈撤场 → 祖辈验收

4.1 祖辈:任务拆解者和全局协调者

祖辈是唯一常驻的角色。它的核心工作是两件事:

  1. 接收外部任务,拆解成可以交给父辈独立完成的子任务
  2. 监控全局状态,在必要时召唤长老做审计
python 复制代码
# agents/ancestor.py
from core.event_bus import bus, Event
from agents.base import BaseAgent


class AncestorAgent(BaseAgent):
    """祖辈Agent------家族常驻代表
    
    职责:
    1. 接收外部任务,拆解为子任务
    2. 召唤父辈Agent执行子任务
    3. 汇总结果,交付给外部
    4. 必要时召唤长老审计
    """
    
    agent_type = "ancestor"
    agent_id = "ancestor_001"  # 全局唯一祖辈
    
    def __init__(self):
        super().__init__()
        # 订阅:有新任务来了
        bus.subscribe("external_task_received", self.on_task_received)
        # 订阅:父辈完成了子任务
        bus.subscribe("father_task_completed", self.on_father_completed)
    
    def on_task_received(self, event: Event):
        """收到外部任务,拆解并召唤父辈"""
        task = event.payload["task"]
        task_id = task["task_id"]
        
        # Step 1: 任务拆解(由LLM完成,产出结构化子任务列表)
        subtasks = self._decompose_task(task)
        
        # Step 2: 为每个子任务召唤一个父辈Agent
        for i, subtask in enumerate(subtasks):
            father_id = f"father_{task_id}_{i}"
            
            # 发布"父辈召唤"事件------父辈工厂会监听这个事件
            bus.publish(Event(
                event_type="agent_spawn_requested",
                payload={
                    "agent_type": "father",
                    "agent_id": father_id,
                    "task": subtask,
                    "parent_task_id": task_id,
                },
                source=self.agent_id,
                lineage=[event.event_id],
            ))
        
        # Step 3: 记录待完成的子任务
        self._pending_subtasks[task_id] = len(subtasks)
        self._results[task_id] = []
    
    def on_father_completed(self, event: Event):
        """父辈完成任务,回收结果"""
        task_id = event.payload["parent_task_id"]
        result = event.payload["result"]
        
        self._results[task_id].append(result)
        self._pending_subtasks[task_id] -= 1
        
        # 所有子任务都完成了
        if self._pending_subtasks[task_id] == 0:
            final_result = self._synthesize_results(task_id, self._results[task_id])
            
            bus.publish(Event(
                event_type="task_delivered",
                payload={"task_id": task_id, "result": final_result},
                source=self.agent_id,
                lineage=[event.event_id],
            ))

4.2 父辈:中层管理者和记忆闸门

父辈是整个架构中最关键的一层。它不只是"传声筒",而是承担了三个核心职责:

  1. 子任务管理:把祖辈给的任务进一步拆给子辈执行
  2. 质量把关:子辈的产出必须经过父辈审核才能上交
  3. 记忆沉淀:从执行经验中提炼可复用的SOP片段,存入家族知识库
python 复制代码
# agents/father.py
from core.event_bus import bus, Event
from agents.base import BaseAgent
from core.store import FamilyStore


class FatherAgent(BaseAgent):
    """父辈Agent------项目经理
    
    生命周期:从被召唤到任务完成,随项目而存在
    核心价值:质量把关 + 记忆沉淀
    """
    
    agent_type = "father"
    
    def __init__(self, agent_id: str, task: dict, parent_task_id: str):
        super().__init__()
        self.agent_id = agent_id
        self.task = task
        self.parent_task_id = parent_task_id
        self.store = FamilyStore()  # 家族知识库连接
        
        # 订阅:子辈完成任务
        bus.subscribe(f"child_task_completed:{agent_id}", self.on_child_completed)
    
    def start(self):
        """父辈启动:召唤子辈开始执行"""
        # 先查家族知识库,看看有没有类似任务的经验
        similar_experience = self.store.query_similar_tasks(self.task)
        
        # 如果有现成的SOP,直接复用;没有则重新拆解
        if similar_experience:
            subtasks = self._apply_experience(self.task, similar_experience)
        else:
            subtasks = self._decompose_fresh(self.task)
        
        self._pending = len(subtasks)
        self._results = []
        
        for i, subtask in enumerate(subtasks):
            child_id = f"child_{self.agent_id}_{i}"
            
            bus.publish(Event(
                event_type="agent_spawn_requested",
                payload={
                    "agent_type": "child",
                    "agent_id": child_id,
                    "task": subtask,
                    "father_id": self.agent_id,
                },
                source=self.agent_id,
            ))
    
    def on_child_completed(self, event: Event):
        """子辈完成任务,父辈审核"""
        result = event.payload["result"]
        child_id = event.payload["agent_id"]
        
        # Step 1: 质量审核(调用质量Gate,上周讲过的三分离机制)
        audit_result = self._audit_result(self.task, result)
        
        if audit_result.passed:
            self._results.append(result)
            self._pending -= 1
            
            # Step 2: 把子辈的执行经验沉淀到知识库(父辈是记忆闸门)
            experience = self._extract_experience(result, audit_result)
            self.store.add_experience(experience)
            
            # 子辈消散(FROST铁律:府兵用完即散,只留记忆)
            bus.publish(Event(
                event_type="agent_terminated",
                payload={"agent_id": child_id, "reason": "task_completed"},
                source=self.agent_id,
            ))
        else:
            # 质量不达标,打回重做
            bus.publish(Event(
                event_type="child_rework_requested",
                payload={
                    "agent_id": child_id,
                    "task": event.payload["task"],
                    "feedback": audit_result.feedback,
                },
                source=self.agent_id,
            ))
        
        # 所有子任务都完成了
        if self._pending == 0:
            self._finish_task()

这里有一个非常 FROST 的设计------子辈用完即散,只留记忆

这不是浪费,而是刻意的设计选择。为什么?

  1. 防止状态污染:子辈在执行中可能产生各种中间状态,如果复用,这些状态可能悄悄影响下一次执行
  2. 强制记忆显式化:因为子辈会消散,所以有用的经验必须主动提炼出来存入知识库,而不是"顺便记住"
  3. 保持架构干净:每次都是全新的执行者,行为可预测、可复现

这就是 FROST 铁律之一:

府兵用完即散,记忆归于家族。个人会消亡,标准会传承。


五、角色工厂:Agent 的"召唤"机制

你可能会问:"发布一个 agent_spawn_requested 事件,Agent 就出来了?谁来创建它?"

答案是Agent 工厂------一个监听召唤事件、按需创建 Agent 实例的模块。

python 复制代码
# core/agent_factory.py
from core.event_bus import bus, Event
from agents.ancestor import AncestorAgent
from agents.father import FatherAgent
from agents.child import ChildAgent
from agents.elder import ElderAgent


class AgentFactory:
    """Agent工厂------按需召唤角色
    
    这是"家族治理"的工程化实现:
    - 不是一开始把所有Agent都创建好
    - 而是需要的时候才召唤,用完就遣散
    """
    
    def __init__(self):
        self._active_agents: dict[str, BaseAgent] = {}
        bus.subscribe("agent_spawn_requested", self._on_spawn_request)
        bus.subscribe("agent_terminated", self._on_terminate)
    
    def _on_spawn_request(self, event: Event):
        agent_type = event.payload["agent_type"]
        agent_id = event.payload["agent_id"]
        
        if agent_id in self._active_agents:
            return  # 已存在,不重复创建
        
        # 根据类型创建不同的Agent
        if agent_type == "father":
            agent = FatherAgent(
                agent_id=agent_id,
                task=event.payload["task"],
                parent_task_id=event.payload["parent_task_id"],
            )
            agent.start()  # 父辈启动后会自己召唤子辈
        elif agent_type == "child":
            agent = ChildAgent(
                agent_id=agent_id,
                task=event.payload["task"],
                father_id=event.payload["father_id"],
            )
            agent.start()
        elif agent_type == "elder":
            agent = ElderAgent(
                agent_id=agent_id,
                target_event_id=event.payload["target_event_id"],
            )
            agent.start()
        else:
            return
        
        self._active_agents[agent_id] = agent
        
        bus.publish(Event(
            event_type="agent_spawned",
            payload={"agent_type": agent_type, "agent_id": agent_id},
            source="agent_factory",
            lineage=[event.event_id],
        ))
    
    def _on_terminate(self, event: Event):
        agent_id = event.payload["agent_id"]
        if agent_id in self._active_agents:
            del self._active_agents[agent_id]


# 全局工厂实例
factory = AgentFactory()

这个工厂模式,就是 FROST 家族治理中"召唤府兵"的工程化表达。

不是所有角色都常驻,而是按需召唤、随用随散------这既是工程上的资源优化,也是治理上的设计选择。


六、族谱记录:流淌的审计链

讲完了调度引擎,最后回到一个 FROST 最有特色的机制------族谱记录

昨天我们聊治理的时候提到,治理的核心是"可追溯"。在 FROST-SOP 中,这个追溯能力不是事后构建的,而是事件总线的天然副产品

6.1 族谱是怎么自动生成的

每一个事件都有三个关键字段:

  • event_id:事件唯一ID
  • source:谁发出的
  • lineage:血缘链,即触发本事件的上游事件ID列表

通过这三个字段,任何一个事件都可以追溯到它的完整上游链------从最终结果,一直回溯到最初的任务输入。

python 复制代码
# core/genealogy.py
from core.event_bus import bus


class GenealogyTracer:
    """族谱追溯器
    
    从任意一个事件出发,向上追溯完整的血缘链,
    还原一个任务从接收到交付的全过程。
    """
    
    def trace(self, event_id: str) -> dict:
        """追溯某个事件的完整族谱"""
        event = self._find_event(event_id)
        if not event:
            return {}
        
        return {
            "event": event,
            "parents": [self.trace(parent_id) 
                       for parent_id in event.lineage 
                       if parent_id],
        }
    
    def generate_report(self, task_id: str) -> str:
        """生成某个任务的族谱报告"""
        events = bus.get_genealogy(task_id)
        
        report = [f"# 族谱报告:任务 {task_id}", ""]
        
        # 按时间排序
        events.sort(key=lambda e: e.timestamp)
        
        for i, event in enumerate(events):
            report.append(f"## E{i+1}: {event.event_type}")
            report.append(f"- 发出者:{event.source}")
            report.append(f"- 时间:{event.timestamp}")
            report.append(f"- 内容:{self._summarize_payload(event.payload)}")
            report.append("")
        
        return "\n".join(report)
    
    def _find_event(self, event_id: str):
        for e in bus._event_log:
            if e.event_id == event_id:
                return e
        return None
    
    def _summarize_payload(self, payload: dict) -> str:
        # 简化摘要,避免报告过长
        keys = list(payload.keys())[:5]
        return ", ".join(f"{k}: {str(payload[k])[:50]}" for k in keys)

6.2 族谱有什么用?

族谱不只是"事后复盘"的工具,它还是实时治理的基础设施

  1. 长老审计:长老收到审计请求后,不需要问任何人,直接拉族谱就能看到完整的执行过程
  2. 质量回溯:如果最终结果有问题,可以沿着族谱一层一层往下找,精准定位是哪个环节出了错
  3. 经验提炼:父辈沉淀记忆时,可以引用族谱中的具体事件作为证据,让经验不是"感觉"而是"有依据"
  4. 宪法合规检查:宪法层规则可以订阅所有事件,实时检测违规行为

七、真实数据:这套架构跑得怎么样?

说了这么多架构,最后用数据说话。我们在 GOAI 大赛项目「新明鉴教育APP MVP」中完整跑了一轮 FROST-SOP,结果如下:

指标 FROST-SOP 家族调度 传统主从模式 变化
任务交付时间 平均 18 分钟 平均 42 分钟 ↓ 57%
并行任务上限 12 个无明显降质 5 个开始降级 ↑ 140%
首次通过率 71% 58% ↑ 13pp
可追溯性 100%(完整族谱) 30%(仅有最终结果) ---
经验复用率 第10次任务时达 42% 接近 0% ---

最让我意外的是经验复用率这个指标。

前 3 次任务,因为知识库是空的,复用率很低。但从第 4 次开始,父辈们开始频繁地从知识库中调取类似任务的经验,复用率稳步上升。

到第 10 次同类型任务时,超过 40% 的子任务可以直接复用已有 SOP,不需要重新拆解和试错。

这就是 FROST 的核心理念------

个人会消散,但家族会成长。每一次执行都不只是完成任务,更是在为家族积累能力资产。


八、回到那个问题:它怎么跑起来?

回到文章开头的问题:"家族治理怎么跑起来?"

答案分三层:

第一层(技术):事件驱动架构。 所有角色通过事件总线通信,解耦、可观测、有弹性。

第二层(机制):祖父子三层角色。 祖辈拆任务、父辈管质量、子辈做执行,各司其职,各有生命周期。

第三层(理念):记忆归于家族。 府兵用完即散,但经验会被父辈筛选、提炼、存入家族知识库,成为下一次任务的起点。

FROST 是思想------告诉你"为什么要这么做"。 FROST-SOP 是工程------告诉你"具体怎么做、代码怎么写"。

思想没有工程,就是空谈。 工程没有思想,就是堆砌。

两者结合,才是完整的 FROST 生态。


写在最后

这篇文章讲了 FROST-SOP 的调度引擎核心,但这只是冰山一角。

完整的 FROST-SOP 还包含:

  • SOP 工作流引擎:标准化流程的定义和执行
  • Gate 质量门禁:上周聊过的三分离验证机制
  • Store 记忆系统:家族知识库的存储和检索
  • Skill 能力市场:跨家族的技能流通

如果你对哪个部分感兴趣,欢迎留言,我们下周接着拆。

FROST(教学框架)gitee.com/liao_liang_... FROST-SOP(工程平台)gitee.com/liao_liang_...

Star 一下,见证一个 AI Agent 家族的成长。