欢迎光临
我们一直在努力

2026国标合规:Agent Loop合规设计模式的6种循环架构(GB/Z 185.6+Python)

2026国标合规:Agent Loop合规设计模式的6种循环架构(GB/Z 185.6+Python)

金句:不是任意一个while循环都能称为合规Agent Loop。你的循环必须能生成标准消息结构、支持六种任务状态机、在内核级别嵌入审计日志。本文6种GB/Z 185.6合规设计模式逐一实现,可直接对照自检。

一句话总结:本文提出6种严格遵循GB/Z 185.6-2026国家标准的Agent Loop合规设计模式,将标准条文的四种内容元素、三种交互模式、三种协作方式转化为可运行的Python架构代码,每种模式均附带教育场景案例与合规检查清单,代码依赖已锁定版本。

本文学习收获:

  • 理解GB/Z 185.6标准对Agent Loop的核心合规要求(消息结构、任务状态机、审计日志)
  • 掌握6种可复用的Agent Loop架构模式,每种附带完整Python代码
  • 获得选型决策矩阵:根据你的业务场景选择最合适的Loop模式
  • 获取合规自检清单:发布前逐项核对,确保通过国标审查

专栏导读:本文是「GB/Z 185智能体合规落地专栏」技术实践系列的第8篇,我们将深入GB/Z 185.6《智能体交互》——这是标准中最接近业务价值的部分。Agent Loop合规设计是专栏的核心章节,直接决定了你的智能体系统能否通过国家标准审查。

文章目录

  • 2026国标合规:Agent Loop合规设计模式的6种循环架构(GB/Z 185.6+Python)
    • 环境与版本说明 ⚠️
    • 一、为什么Agent Loop需要"合规设计模式"?
      • 1.1 标准核心条款
      • 1.2 合规的核心矛盾
    • 二、基础数据模型:GB/Z 185.6 四种内容元素
      • 辅助模型(跨模式共用)
    • 三、模式一:单智能体ReAct合规循环
      • 3.1 标准映射
      • 3.2 架构图
      • 3.3 核心代码
      • 3.4 验证示例与预期输出
      • 3.5 合规要点
      • 3.6 适用边界与局限性
    • 四、模式二:主从规划-执行循环
      • 4.1 标准映射
      • 4.2 架构图
      • 4.3 核心代码
      • 4.4 验证示例与预期输出
      • 4.5 合规要点
      • 4.6 适用边界与局限性
    • 五、模式三:代理协商反射循环
      • 5.1 标准映射
      • 5.2 架构图
      • 5.3 核心代码
      • 5.4 验证示例与预期输出
      • 5.5 合规要点
      • 5.6 适用边界与局限性
    • 六、模式四:任务订阅事件驱动循环
      • 6.1 标准映射
      • 6.2 架构图
      • 6.3 核心代码
      • 6.4 验证示例与预期输出
      • 6.5 合规要点
      • 6.6 适用边界与局限性
    • 七、模式五:群组消息分发循环
      • 7.1 标准映射
      • 7.2 架构图
      • 7.3 核心代码
      • 7.4 验证示例与预期输出
      • 7.5 合规要点
      • 7.6 适用边界与局限性
    • 八、模式六:人机协同混合协作循环
      • 8.1 标准映射
      • 8.2 架构图
      • 8.3 核心代码
      • 8.4 验证示例与预期输出
      • 8.5 合规要点
      • 8.6 适用边界与局限性
    • 九、六种模式速查卡(快速参考)
    • 十、选型决策矩阵:如何选择你的Loop模式?
      • 10.1 场景-模式映射表
      • 10.2 多维度对比矩阵
      • 10.3 组合使用建议
      • 10.4 分层评估框架:从工程、成本、长期三个维度做决策
    • 十一、FAQ与常见问题
      • Q1: 这6种模式是否可以直接用于生产环境?
      • Q2: 如何选择max_iterations和max_rounds的初始值?
      • Q3: 如果Agent在运行时遇到非标准交互需求怎么办?
      • Q4: 审计日志需要保留多久?
      • Q5: 这些模式支持国产大模型吗?
    • 十二、总结与下篇预告
      • 相关阅读
      • 互动钩子
    • 更新日志

环境与版本说明 ⚠️

适用范围:本文代码基于 Python 3.10+ 与 GB/Z 185.6-2026 标准条文,适用于设计符合中国国标的Agent交互系统。文中所有设计模式可直接在生产环境中引用,但需根据实际业务场景调整参数。

前置条件:Python 3.10+,运行以下命令安装依赖:

# 建议锁定以下版本以确保行为一致(2026年7月验证)
pip install pydantic==2.10.0

# 验证安装
python -c "import pydantic; print(pydantic.__version__)"
# 预期输出:2.10.0

⚠️ 生产环境提示:文中的asyncio.Queue和asyncio.sleep等异步模式适用于中等并发场景(<1000 QPS)。高并发生产环境建议替换为Redis Stream或Kafka等消息队列中间件。


一、为什么Agent Loop需要"合规设计模式"?

在AI工程领域,Agent Loop(智能体循环)早已不是新概念。从2022年的ReAct论文,到2026年Anthropic的Claude Agent SDK、OpenAI的Agents SDK,"Loop + Tools + Context Management"已成为行业共识。

但工程实践与国家标准之间存在一个断层:现有框架(LangChain、AutoGen、CrewAI)解决了"如何构建Agent",却没有回答"如何构建符合中国国标的Agent"。

1.1 标准核心条款

GB/Z 185.6 明确规定了智能体交互的底层语法:

标准维度具体规定
四种内容元素 数据(最小单元)、消息(基本单元)、任务(工作单元)、会话(管理单元)
三种交互模式 点对点(应支持)、群组(宜支持)、混合(宜支持)
三种协作方式 主从方式、代理协商方式、任务订阅方式
三种实现方式 远程调用(短连接)、流式(长连接)、通知(异步)
六种任务状态 接受、拒绝、完成、失败、取消、进行中

1.2 合规的核心矛盾

⚠️ 关键认知:不是任意一个while循环都能称为"合规Agent Loop"。你的循环必须能够生成符合标准的消息结构、支持规定的任务状态机、在正确的时机引入身份鉴别和审计日志。

这意味着传统框架开发Agent时,开发者需要自行解决三个合规问题:

  • 消息结构合规:Agent内部流转的消息是否包含senderAid、sessionId、taskId等标准字段?
  • 任务状态合规:Agent的生命周期是否严格遵循六种标准任务状态?
  • 审计追溯合规:每条操作是否记录了可回溯的审计日志(满足GB/Z 185.3的36个月留存要求)?
  • 本文的6种设计模式,正是为了填平这个断层。


    二、基础数据模型:GB/Z 185.6 四种内容元素

    在展开模式之前,先定义标准-compliant的数据基座。所有后续模式均依赖以下模型:

    from dataclasses import dataclass, field
    from enum import Enum
    from typing import List, Dict, Optional, Any
    import uuid
    from datetime import datetime

    class TaskStatus(Enum):
    """GB/Z 185.6 §5.3 任务六种状态"""
    ACCEPTED = "accepted"
    REJECTED = "rejected"
    IN_PROGRESS = "inProgress"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"

    @dataclass
    class GBZData:
    """GB/Z 185.6 §5.1 数据:最小内容单元"""
    type: str
    metadata: Dict[str, Any] = field(default_factory=dict)
    payload: Any = None

    @dataclass
    class GBZMessage:
    """GB/Z 185.6 §5.2 消息:基本内容单元"""
    senderRole: str = "service"
    senderAid: str = ""
    sessionId: str = ""
    taskId: str = ""
    messageId: str = field(default_factory=lambda: str(uuid.uuid4()))
    infoType: str = "request"
    chunkIndex: int = 0
    isEnd: bool = True
    data: GBZData = field(default_factory=lambda: GBZData(type="text"))
    timestamp: str = field(default_factory=lambda: datetime.now().isoformat())

    设计原则:所有Loop内部流转的对象必须是GBZMessage,而非随意的字符串或字典。这是合规的第一道门槛。

    ⚠️ 常见错误:直接使用LLM返回的JSON字符串作为消息,缺少senderAid和taskId字段。这会导致审计系统无法追溯消息来源,在合规审查中被判定为不符合GB/Z 185.6 §5.2要求。

    验证方法:在代码中加如下断言,确保每条消息都包含合规所需字段:

    def validate_message(msg: GBZMessage):
    assert msg.senderAid != "", f"缺失senderAid: {msg.messageId}"
    assert msg.sessionId != "", f"缺失sessionId: {msg.messageId}"
    assert msg.infoType in ("request", "response", "notification", "error",
    "task_forward", "task_accept", "task_reject",
    "tool_call", "human_review", "system"), \\
    f"不合规的infoType: {msg.infoType}"
    print(f"✓ 消息合规检查通过: {msg.messageId}")
    # 预期输出: ✓ 消息合规检查通过: <uuid>

    辅助模型(跨模式共用)

    @dataclass
    class GBZSession:
    """GB/Z 185.6 §5.4 会话:管理单元"""
    sessionId: str = field(default_factory=lambda: str(uuid.uuid4()))
    requesterAid: str = ""
    serviceAids: List[str] = field(default_factory=list)
    context: Dict[str, Any] = field(default_factory=dict)
    startedAt: str = field(default_factory=lambda: datetime.now().isoformat())

    @dataclass
    class GBZTask:
    """GB/Z 185.6 §5.3 任务:工作单元"""
    taskId: str = field(default_factory=lambda: str(uuid.uuid4()))
    status: TaskStatus = TaskStatus.IN_PROGRESS
    messages: List[GBZMessage] = field(default_factory=list)
    createdAt: str = field(default_factory=lambda: datetime.now().isoformat())


    三、模式一:单智能体ReAct合规循环

    3.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §4.1 点对点交互模式(请求-响应一对一)
    GB/Z 185.6 §7.1 远程调用实现方式(短连接)
    GB/Z 185.6 §5.3 任务状态机(进行中→完成/失败)

    3.2 架构图

    #mermaid-svg-NBoG1Y3SKPQAcSce{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NBoG1Y3SKPQAcSce .error-icon{fill:#552222;}#mermaid-svg-NBoG1Y3SKPQAcSce .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NBoG1Y3SKPQAcSce .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NBoG1Y3SKPQAcSce .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NBoG1Y3SKPQAcSce .marker.cross{stroke:#333333;}#mermaid-svg-NBoG1Y3SKPQAcSce svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NBoG1Y3SKPQAcSce p{margin:0;}#mermaid-svg-NBoG1Y3SKPQAcSce .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster-label text{fill:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster-label span{color:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster-label span p{background-color:transparent;}#mermaid-svg-NBoG1Y3SKPQAcSce .label text,#mermaid-svg-NBoG1Y3SKPQAcSce span{fill:#333;color:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce .node rect,#mermaid-svg-NBoG1Y3SKPQAcSce .node circle,#mermaid-svg-NBoG1Y3SKPQAcSce .node ellipse,#mermaid-svg-NBoG1Y3SKPQAcSce .node polygon,#mermaid-svg-NBoG1Y3SKPQAcSce .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-NBoG1Y3SKPQAcSce .rough-node .label text,#mermaid-svg-NBoG1Y3SKPQAcSce .node .label text,#mermaid-svg-NBoG1Y3SKPQAcSce .image-shape .label,#mermaid-svg-NBoG1Y3SKPQAcSce .icon-shape .label{text-anchor:middle;}#mermaid-svg-NBoG1Y3SKPQAcSce .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-NBoG1Y3SKPQAcSce .rough-node .label,#mermaid-svg-NBoG1Y3SKPQAcSce .node .label,#mermaid-svg-NBoG1Y3SKPQAcSce .image-shape .label,#mermaid-svg-NBoG1Y3SKPQAcSce .icon-shape .label{text-align:center;}#mermaid-svg-NBoG1Y3SKPQAcSce .node.clickable{cursor:pointer;}#mermaid-svg-NBoG1Y3SKPQAcSce .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-NBoG1Y3SKPQAcSce .arrowheadPath{fill:#333333;}#mermaid-svg-NBoG1Y3SKPQAcSce .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-NBoG1Y3SKPQAcSce .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-NBoG1Y3SKPQAcSce .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NBoG1Y3SKPQAcSce .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-NBoG1Y3SKPQAcSce .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NBoG1Y3SKPQAcSce .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster text{fill:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce .cluster span{color:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-NBoG1Y3SKPQAcSce .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-NBoG1Y3SKPQAcSce rect.text{fill:none;stroke-width:0;}#mermaid-svg-NBoG1Y3SKPQAcSce .icon-shape,#mermaid-svg-NBoG1Y3SKPQAcSce .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-NBoG1Y3SKPQAcSce .icon-shape p,#mermaid-svg-NBoG1Y3SKPQAcSce .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-NBoG1Y3SKPQAcSce .icon-shape .label rect,#mermaid-svg-NBoG1Y3SKPQAcSce .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-NBoG1Y3SKPQAcSce .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-NBoG1Y3SKPQAcSce .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-NBoG1Y3SKPQAcSce :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    HTTP Request

    循环迭代

    max_iter超时

    final_answer

    用户/调用方(requester)

    ReAct Agent(service)

    ReasonLLM推理

    Action工具调用

    Observe观察结果

    返回FAILED

    返回COMPLETED

    图注:ReAct合规循环架构图——用户(requester)通过HTTP请求调用ReAct Agent(service),Agent内部经过推理(Reason)→工具调用(Action)→观察结果(Observe)三个阶段的循环迭代,超过max_iteration次数返回失败(FAILED),工具调用返回最终答案时进入完成状态(COMPLETED)。

    3.3 核心代码

    class ReActCompliantLoop:
    """
    模式一:单智能体ReAct合规循环
    标准映射:GB/Z 185.6 §4.1 点对点 + §7.1 远程调用
    """

    def __init__(self, agent_id: str, tools: Dict[str, Callable] = None):
    self.agent_id = agent_id
    self.tools = tools or {}
    self.max_iterations = 10
    self.audit_log: List[Dict] = []

    def run(self, user_input: str, session_id: str = None) > GBZMessage:
    session = GBZSession(
    sessionId=session_id or str(uuid.uuid4()),
    requesterAid="user",
    serviceAids=[self.agent_id]
    )
    task = GBZTask()
    context = f"用户输入: {user_input}\\n"

    for i in range(self.max_iterations):
    thought = self._reason(context)
    action = self._decide_action(thought)

    if action["type"] == "final_answer":
    msg = GBZMessage(
    senderRole="service",
    senderAid=self.agent_id,
    sessionId=session.sessionId,
    taskId=task.taskId,
    infoType="response",
    data=GBZData(
    type="final_answer",
    payload={"answer": action["content"]}
    )
    )
    task.status = TaskStatus.COMPLETED
    self._log("TASK_COMPLETED", f"任务{task.taskId}完成")
    return msg

    elif action["type"] == "tool_call":
    tool_name = action["tool"]
    tool_input = action["input"]

    # 工具执行
    observation = self.tools[tool_name](**tool_input) \\
    if tool_name in self.tools else f"错误: 工具{tool_name}未注册"

    # 记录工具调用消息(符合标准消息结构)
    tool_msg = GBZMessage(
    senderRole="service",
    senderAid=self.agent_id,
    sessionId=session.sessionId,
    taskId=task.taskId,
    infoType="tool_call",
    data=GBZData(
    type="tool_execution",
    metadata={"tool": tool_name, "input": tool_input},
    payload={"result": observation}
    )
    )
    task.messages.append(tool_msg)
    context += f"\\n[工具调用] {tool_name}: {observation}\\n"
    self._log("TOOL_CALLED", f"调用{tool_name}")

    # 超过最大迭代次数
    task.status = TaskStatus.FAILED
    return GBZMessage(
    senderRole="service", senderAid=self.agent_id,
    sessionId=session.sessionId, taskId=task.taskId,
    infoType="error",
    data=GBZData(type="error", payload={"reason": "max_iterations_exceeded"})
    )

    3.4 验证示例与预期输出

    # 验证ReAct模式的消息合规性
    tools = {
    "search_db": lambda query: f"查询结果: {query} -> 无冲突",
    "check_schedule": lambda teacher, week: f"{teacher}{week}周课表正常"
    }
    react_agent = ReActCompliantLoop("aid:cn:edu:cauc:agent:schedule-query", tools)
    result = react_agent.run("检查张三老师第3周课表是否有冲突")
    validate_message(result)
    print(f"任务结果: {result.data.payload}")
    # 预期输出示例:
    # ✓ 消息合规检查通过: <uuid>
    # 任务结果: {'answer': '…'}

    3.5 合规要点

    • 每条工具调用都生成标准GBZMessage,包含senderAid(身份码)和taskId(任务追踪)
    • 审计日志记录TASK_COMPLETED和TOOL_CALLED,满足GB/Z 185.3的36个月留存要求
    • 任务状态严格遵循六种标准状态,最终返回COMPLETED或FAILED

    3.6 适用边界与局限性

    维度说明
    ✅ 适用场景 单工具查询/问答、简单的信息检索、单轮工具调用
    ❌ 不适用场景 需要多Agent协作的复杂任务、需要人工审批的高风险决策
    ⚠️ 限制条件 max_iterations设置为10,超过后直接返回FAILED,无重试机制;不适合长链工具调用(>20步)
    🔄 替代方案 如果子任务有明确依赖关系,考虑升级为模式二(主从规划-执行循环)

    四、模式二:主从规划-执行循环

    4.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §6.1 主从协作方式(Master规划分发,Slave执行)
    GB/Z 185.6 §5.3 任务依赖信息(子任务间拓扑排序)
    GB/Z 185.6 §5.4 会话管理(多智能体共享上下文)

    4.2 架构图

    #mermaid-svg-MudhaMZuYP6QBAmT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-MudhaMZuYP6QBAmT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-MudhaMZuYP6QBAmT .error-icon{fill:#552222;}#mermaid-svg-MudhaMZuYP6QBAmT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-MudhaMZuYP6QBAmT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-MudhaMZuYP6QBAmT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-MudhaMZuYP6QBAmT .marker.cross{stroke:#333333;}#mermaid-svg-MudhaMZuYP6QBAmT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-MudhaMZuYP6QBAmT p{margin:0;}#mermaid-svg-MudhaMZuYP6QBAmT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-MudhaMZuYP6QBAmT .cluster-label text{fill:#333;}#mermaid-svg-MudhaMZuYP6QBAmT .cluster-label span{color:#333;}#mermaid-svg-MudhaMZuYP6QBAmT .cluster-label span p{background-color:transparent;}#mermaid-svg-MudhaMZuYP6QBAmT .label text,#mermaid-svg-MudhaMZuYP6QBAmT span{fill:#333;color:#333;}#mermaid-svg-MudhaMZuYP6QBAmT .node rect,#mermaid-svg-MudhaMZuYP6QBAmT .node circle,#mermaid-svg-MudhaMZuYP6QBAmT .node ellipse,#mermaid-svg-MudhaMZuYP6QBAmT .node polygon,#mermaid-svg-MudhaMZuYP6QBAmT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-MudhaMZuYP6QBAmT .rough-node .label text,#mermaid-svg-MudhaMZuYP6QBAmT .node .label text,#mermaid-svg-MudhaMZuYP6QBAmT .image-shape .label,#mermaid-svg-MudhaMZuYP6QBAmT .icon-shape .label{text-anchor:middle;}#mermaid-svg-MudhaMZuYP6QBAmT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-MudhaMZuYP6QBAmT .rough-node .label,#mermaid-svg-MudhaMZuYP6QBAmT .node .label,#mermaid-svg-MudhaMZuYP6QBAmT .image-shape .label,#mermaid-svg-MudhaMZuYP6QBAmT .icon-shape .label{text-align:center;}#mermaid-svg-MudhaMZuYP6QBAmT .node.clickable{cursor:pointer;}#mermaid-svg-MudhaMZuYP6QBAmT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-MudhaMZuYP6QBAmT .arrowheadPath{fill:#333333;}#mermaid-svg-MudhaMZuYP6QBAmT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-MudhaMZuYP6QBAmT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-MudhaMZuYP6QBAmT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MudhaMZuYP6QBAmT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-MudhaMZuYP6QBAmT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MudhaMZuYP6QBAmT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-MudhaMZuYP6QBAmT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-MudhaMZuYP6QBAmT .cluster text{fill:#333;}#mermaid-svg-MudhaMZuYP6QBAmT .cluster span{color:#333;}#mermaid-svg-MudhaMZuYP6QBAmT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-MudhaMZuYP6QBAmT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-MudhaMZuYP6QBAmT rect.text{fill:none;stroke-width:0;}#mermaid-svg-MudhaMZuYP6QBAmT .icon-shape,#mermaid-svg-MudhaMZuYP6QBAmT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-MudhaMZuYP6QBAmT .icon-shape p,#mermaid-svg-MudhaMZuYP6QBAmT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-MudhaMZuYP6QBAmT .icon-shape .label rect,#mermaid-svg-MudhaMZuYP6QBAmT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-MudhaMZuYP6QBAmT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-MudhaMZuYP6QBAmT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-MudhaMZuYP6QBAmT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    完成下周排课

    子任务t1: 冲突检测

    结果

    子任务t2: 教室分配

    结果

    子任务t3: 通知确认

    结果

    Master流程

    1.解析任务

    2.拓扑排序

    3.分发子任务

    4.汇总结果

    User

    Master 规划者

    Slave冲突检测 执行者

    Slave教室分配 执行者

    Slave通知确认 执行者

    最终排课结果

    图注:主从规划-执行循环架构图——用户输入"完成下周排课"任务给Master规划者,Master经过解析任务→拓扑排序→分发子任务→汇总结果四个步骤,将子任务t1(冲突检测)、t2(教室分配)、t3(通知确认)分发给对应Slave,Slave执行后Master聚合输出。

    4.3 核心代码

    class MasterSlaveLoop:
    """
    模式二:主从规划-执行循环
    标准映射:GB/Z 185.6 §6.1 主从协作方式
    """

    def __init__(self, master_id: str, slave_agents: Dict[str, Any]):
    self.master_id = master_id
    self.slaves = slave_agents
    self.audit_log: List[Dict] = []

    def execute(self, task_description: str, requester_aid: str = "user") > GBZSession:
    session = GBZSession(
    requesterAid=requester_aid,
    serviceAids=[self.master_id] + list(self.slaves.keys())
    )

    # Phase 1: Master Planning
    subtasks = self._plan(task_description)

    # Phase 2: Slave Execution (按依赖拓扑排序执行)
    results = {}
    for subtask in subtasks:
    slave_id = subtask["assigned_to"]

    task_msg = GBZMessage(
    senderRole="master",
    senderAid=self.master_id,
    sessionId=session.sessionId,
    taskId=subtask["task_id"],
    infoType="task_assign",
    data=GBZData(
    type="subtask",
    metadata={"dependencies": subtask.get("depends_on", [])},
    payload=subtask["description"]
    )
    )

    slave = self.slaves[slave_id]
    result = slave.run(task_msg)
    results[subtask["task_id"]] = result

    self.audit_log.append({
    "timestamp": datetime.now().isoformat(),
    "action": "SUBTASK_EXECUTED",
    "master": self.master_id,
    "slave": slave_id,
    "taskId": subtask["task_id"]
    })

    # Phase 3: Master Aggregation
    final_result = self._aggregate(results)
    session.context["final_result"] = final_result
    return session

    def _plan(self, task_description: str) > List[Dict]:
    """Master规划:将复杂任务拆分为子任务"""
    return [
    {"task_id": "t1", "description": "检测课表冲突", "assigned_to": "slave_conflict", "depends_on": []},
    {"task_id": "t2", "description": "分配空闲教室", "assigned_to": "slave_room", "depends_on": ["t1"]},
    {"task_id": "t3", "description": "通知教师确认", "assigned_to": "slave_notify", "depends_on": ["t2"]}
    ]

    def _aggregate(self, results: Dict[str, Any]) > Dict:
    return {"status": "completed", "subtask_count": len(results), "results": results}

    4.4 验证示例与预期输出

    # 模拟Slave智能体
    class MockSlave:
    def __init__(self, aid: str):
    self.aid = aid
    def run(self, msg: GBZMessage) > Dict:
    return {"status": "completed", "slave": self.aid, "input": msg.data.payload}

    slaves = {
    "slave_conflict": MockSlave("aid:cn:edu:cauc:slave:conflict"),
    "slave_room": MockSlave("aid:cn:edu:cauc:slave:room"),
    "slave_notify": MockSlave("aid:cn:edu:cauc:slave:notify"),
    }
    master = MasterSlaveLoop("aid:cn:edu:cauc:master:schedule", slaves)
    session = master.execute("完成下周排课")
    print(f"子任务数: {session.context['final_result']['subtask_count']}")
    # 预期输出: 子任务数: 3
    print(f"审计日志条数: {len(master.audit_log)}")
    # 预期输出: 审计日志条数: 3

    4.5 合规要点

    • 子任务消息包含metadata["dependencies"],符合GB/Z 185.6 §5.3的任务依赖信息要求
    • session.serviceAids完整记录所有参与智能体,支持异常追溯
    • Master的审计日志记录每条子任务的执行链路,满足溯源要求

    4.6 适用边界与局限性

    维度说明
    ✅ 适用场景 复杂任务拆解、有明确依赖关系的工作流、多步骤业务流程
    ❌ 不适用场景 任务依赖关系不明确、运行时间需要在Slave之间协商
    ⚠️ 限制条件 当前实现为同步串行,Master阻塞等待每个Slave;大规模Slave集群建议改为异步并行
    ⚠️ 生产提示 Slave执行失败时Master无自动重试,建议在生产中增加重试逻辑和超时阈值

    五、模式三:代理协商反射循环

    5.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §6.2 代理协商方式(转发任务并评估反馈)
    GB/Z 185.6 §5.2 消息结构(协商过程中的多轮消息)
    GB/Z 185.6 §5.3 任务状态(接受/拒绝/进行中)

    5.2 架构图

    Agent B (服务方)

    Agent A (请求方)

    Agent B (服务方)

    Agent A (请求方)

    #mermaid-svg-npKEgvc1S9PZ9YE2{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-npKEgvc1S9PZ9YE2 .error-icon{fill:#552222;}#mermaid-svg-npKEgvc1S9PZ9YE2 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-npKEgvc1S9PZ9YE2 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-npKEgvc1S9PZ9YE2 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-npKEgvc1S9PZ9YE2 .marker.cross{stroke:#333333;}#mermaid-svg-npKEgvc1S9PZ9YE2 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-npKEgvc1S9PZ9YE2 p{margin:0;}#mermaid-svg-npKEgvc1S9PZ9YE2 .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-npKEgvc1S9PZ9YE2 text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-npKEgvc1S9PZ9YE2 .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-npKEgvc1S9PZ9YE2 .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-npKEgvc1S9PZ9YE2 #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-npKEgvc1S9PZ9YE2 .sequenceNumber{fill:white;}#mermaid-svg-npKEgvc1S9PZ9YE2 #sequencenumber{fill:#333;}#mermaid-svg-npKEgvc1S9PZ9YE2 #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-npKEgvc1S9PZ9YE2 .messageText{fill:#333;stroke:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-npKEgvc1S9PZ9YE2 .labelText,#mermaid-svg-npKEgvc1S9PZ9YE2 .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .loopText,#mermaid-svg-npKEgvc1S9PZ9YE2 .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-npKEgvc1S9PZ9YE2 .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-npKEgvc1S9PZ9YE2 .noteText,#mermaid-svg-npKEgvc1S9PZ9YE2 .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-npKEgvc1S9PZ9YE2 .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-npKEgvc1S9PZ9YE2 .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-npKEgvc1S9PZ9YE2 .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-npKEgvc1S9PZ9YE2 .actorPopupMenu{position:absolute;}#mermaid-svg-npKEgvc1S9PZ9YE2 .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-npKEgvc1S9PZ9YE2 .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-npKEgvc1S9PZ9YE2 .actor-man circle,#mermaid-svg-npKEgvc1S9PZ9YE2 line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-npKEgvc1S9PZ9YE2 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    如拒绝则返回task_rejected

    超max_rounds则返回timeout

    原始任务

    counter_offer (延长2天期限)

    评估反馈,调整任务条件

    调整后重新转发

    再次评估可行性

    accept (同意条件)

    图注:代理协商反射循环时序图——Agent A(请求方)向Agent B(服务方)发送原始任务,B评估后返回counter_offer(如延长2天期限),A调整任务条件后重新转发,B再次评估可行性,达成一致则返回accept(同意条件),拒绝则返回task_rejected,超过max_rounds返回timeout。

    5.3 核心代码

    class AgentNegotiationLoop:
    """
    模式三:代理协商反射循环
    标准映射:GB/Z 185.6 §6.2 代理协商方式
    """

    def __init__(self, agent_a_id: str, agent_b_id: str):
    self.agent_a_id = agent_a_id
    self.agent_b_id = agent_b_id
    self.max_rounds = 5
    self.negotiation_history: List[GBZMessage] = []

    def negotiate(self, original_task: GBZMessage) > GBZMessage:
    session = GBZSession(requesterAid=self.agent_a_id, serviceAids=[self.agent_b_id])
    current_task = original_task

    for round_num in range(self.max_rounds):
    # A向B转发任务
    forward_msg = GBZMessage(
    senderRole="proxy",
    senderAid=self.agent_a_id,
    sessionId=session.sessionId,
    taskId=current_task.taskId,
    infoType="task_forward",
    data=GBZData(
    type="negotiation",
    metadata={"round": round_num + 1, "original_sender": original_task.senderAid},
    payload=current_task.data.payload
    )
    )

    # B评估并响应
    b_response = self._agent_b_evaluate(forward_msg, session.sessionId)
    self.negotiation_history.append(b_response)

    if b_response.data.type == "accept":
    return GBZMessage(
    senderRole="proxy", senderAid=self.agent_a_id,
    sessionId=session.sessionId, taskId=current_task.taskId,
    infoType="task_accepted",
    data=GBZData(type="agreement", payload={"agreed_terms": b_response.data.metadata.get("terms", {})})
    )
    elif b_response.data.type == "counter_offer":
    current_task = self._agent_a_adjust(current_task, b_response)
    continue
    elif b_response.data.type == "reject":
    return GBZMessage(
    senderRole="proxy", senderAid=self.agent_a_id,
    sessionId=session.sessionId, taskId=current_task.taskId,
    infoType="task_rejected",
    data=GBZData(type="rejection", payload={"reason": b_response.data.payload})
    )

    return GBZMessage(
    senderRole="proxy", senderAid=self.agent_a_id,
    sessionId=session.sessionId, taskId=current_task.taskId,
    infoType="negotiation_timeout",
    data=GBZData(type="timeout", payload={"max_rounds": self.max_rounds})
    )

    5.4 验证示例与预期输出

    # 验证协商循环的三种终止条件
    negotiation = AgentNegotiationLoop(
    "aid:cn:edu:cauc:agent:academic",
    "aid:cn:edu:cauc:agent:cs_dept"
    )
    initial_task = GBZMessage(
    senderRole="requester", senderAid="aid:cn:edu:cauc:agent:academic",
    sessionId=str(uuid.uuid4()), taskId=str(uuid.uuid4()), infoType="task_request",
    data=GBZData(type="task", payload={"description": "跨学院联合开设《人工智能导论》"})
    )
    result = negotiation.negotiate(initial_task)
    print(f"协商结果类型: {result.data.type}")
    # 预期输出之一: 协商结果类型: agreement
    # 预期输出之二: 协商结果类型: rejection
    # 预期输出之三: 协商结果类型: timeout
    print(f"协商轮次历史: {len(negotiation.negotiation_history)} 轮")
    # 预期输出: 协商轮次历史: 1~5 轮

    5.5 合规要点

    • 每轮协商都生成标准GBZMessage,infoType区分task_forward/task_accepted/task_rejected
    • negotiation_history完整保存协商过程,支持事后审计和争议追溯
    • 设置max_rounds防止无限协商,避免资源耗尽

    5.6 适用边界与局限性

    维度说明
    ✅ 适用场景 跨组织/跨部门协作、任务条件需双方确认、存在博弈和条件交换的场景
    ❌ 不适用场景 单方决策即可完成的任务、实时性要求高(<100ms)、协商条件不需要变更的重复性任务
    ⚠️ 限制条件 max_rounds硬编码为5,复杂协商可能需要更多轮次;缺少超时机制,真实网络环境下建议加入等待超时

    六、模式四:任务订阅事件驱动循环

    6.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §6.3 任务订阅方式(信号源条件触发)
    GB/Z 185.6 §7.3 通知实现方式(异步触发)
    GB/Z 185.6 §5.2 消息结构(通知类型消息)

    6.2 架构图

    #mermaid-svg-EkIz0pwbVcjVTIFd{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-EkIz0pwbVcjVTIFd .error-icon{fill:#552222;}#mermaid-svg-EkIz0pwbVcjVTIFd .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-EkIz0pwbVcjVTIFd .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-EkIz0pwbVcjVTIFd .marker{fill:#333333;stroke:#333333;}#mermaid-svg-EkIz0pwbVcjVTIFd .marker.cross{stroke:#333333;}#mermaid-svg-EkIz0pwbVcjVTIFd svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-EkIz0pwbVcjVTIFd p{margin:0;}#mermaid-svg-EkIz0pwbVcjVTIFd .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster-label text{fill:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster-label span{color:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster-label span p{background-color:transparent;}#mermaid-svg-EkIz0pwbVcjVTIFd .label text,#mermaid-svg-EkIz0pwbVcjVTIFd span{fill:#333;color:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd .node rect,#mermaid-svg-EkIz0pwbVcjVTIFd .node circle,#mermaid-svg-EkIz0pwbVcjVTIFd .node ellipse,#mermaid-svg-EkIz0pwbVcjVTIFd .node polygon,#mermaid-svg-EkIz0pwbVcjVTIFd .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-EkIz0pwbVcjVTIFd .rough-node .label text,#mermaid-svg-EkIz0pwbVcjVTIFd .node .label text,#mermaid-svg-EkIz0pwbVcjVTIFd .image-shape .label,#mermaid-svg-EkIz0pwbVcjVTIFd .icon-shape .label{text-anchor:middle;}#mermaid-svg-EkIz0pwbVcjVTIFd .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-EkIz0pwbVcjVTIFd .rough-node .label,#mermaid-svg-EkIz0pwbVcjVTIFd .node .label,#mermaid-svg-EkIz0pwbVcjVTIFd .image-shape .label,#mermaid-svg-EkIz0pwbVcjVTIFd .icon-shape .label{text-align:center;}#mermaid-svg-EkIz0pwbVcjVTIFd .node.clickable{cursor:pointer;}#mermaid-svg-EkIz0pwbVcjVTIFd .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-EkIz0pwbVcjVTIFd .arrowheadPath{fill:#333333;}#mermaid-svg-EkIz0pwbVcjVTIFd .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-EkIz0pwbVcjVTIFd .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-EkIz0pwbVcjVTIFd .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EkIz0pwbVcjVTIFd .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-EkIz0pwbVcjVTIFd .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EkIz0pwbVcjVTIFd .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster text{fill:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd .cluster span{color:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-EkIz0pwbVcjVTIFd .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-EkIz0pwbVcjVTIFd rect.text{fill:none;stroke-width:0;}#mermaid-svg-EkIz0pwbVcjVTIFd .icon-shape,#mermaid-svg-EkIz0pwbVcjVTIFd .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-EkIz0pwbVcjVTIFd .icon-shape p,#mermaid-svg-EkIz0pwbVcjVTIFd .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-EkIz0pwbVcjVTIFd .icon-shape .label rect,#mermaid-svg-EkIz0pwbVcjVTIFd .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-EkIz0pwbVcjVTIFd .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-EkIz0pwbVcjVTIFd .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-EkIz0pwbVcjVTIFd :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    订阅管理器

    匹配成功

    信号源(监控)cpu=85%

    条件匹配引擎

    cpu > 80?

    触发通知

    Subscriber告警处理Agent

    图注:任务订阅事件驱动循环架构图——信号源(监控cpu=85%)输入到条件匹配引擎,订阅管理器判断是否满足条件(cpu > 80%),匹配成功则触发通知,发送给订阅者(告警处理Agent)。

    6.3 核心代码

    import asyncio
    from typing import Dict, Callable
    from datetime import datetime
    import uuid

    class TaskSubscriptionLoop:
    """
    模式四:任务订阅事件驱动循环
    标准映射:GB/Z 185.6 §6.3 任务订阅 + §7.3 通知实现
    """

    def __init__(self, subscriber_id: str):
    self.subscriber_id = subscriber_id
    self.subscriptions: Dict[str, Dict] = {}
    self.event_queue: asyncio.Queue = asyncio.Queue()
    self.running = False

    def subscribe(self, signal_id: str, condition: Dict, callback: Callable) > str:
    """
    订阅信号源:
    condition示例: {"type": "threshold", "field": "cpu", "operator": ">", "value": 80}
    """

    sub_id = str(uuid.uuid4())
    self.subscriptions[signal_id] = {
    "sub_id": sub_id, "condition": condition,
    "callback": callback, "active": True,
    "subscribedAt": datetime.now().isoformat()
    }
    return sub_id

    async def _process_event(self, event: Dict):
    for signal_id, sub in self.subscriptions.items():
    if not sub["active"]:
    continue
    if self._match_condition(event, sub["condition"]):
    notify_msg = GBZMessage(
    senderRole="publisher",
    senderAid=event.get("source_aid", "unknown"),
    sessionId=str(uuid.uuid4()), taskId=str(uuid.uuid4()),
    infoType="notification",
    data=GBZData(
    type="event_triggered",
    metadata={"signal_id": signal_id, "subscription_id": sub["sub_id"]},
    payload=event
    )
    )
    try:
    result = await sub["callback"](notify_msg)
    status = TaskStatus.COMPLETED.value
    except Exception as e:
    status = TaskStatus.FAILED.value

    def _match_condition(self, event: Dict, condition: Dict) > bool:
    if condition["type"] == "threshold":
    field_value = event.get(condition["field"])
    if field_value is None: return False
    op, val = condition["operator"], condition["value"]
    if op == ">": return field_value > val
    if op == ">=": return field_value >= val
    if op == "==": return field_value == val
    return False

    6.4 验证示例与预期输出

    # 验证订阅模式的条件匹配
    import asyncio

    async def test_subscription():
    sub_loop = TaskSubscriptionLoop("aid:cn:edu:cauc:agent:monitor")

    # 订阅: CPU > 80%
    sub_id = sub_loop.subscribe(
    "signal:cpu",
    {"type": "threshold", "field": "cpu", "operator": ">", "value": 80},
    lambda msg: {"action": "alert", "level": "warning"}
    )
    print(f"订阅ID: {sub_id}")

    # 测试不匹配事件(CPU 50% 应被静默丢弃)
    await sub_loop._process_event({"cpu": 50, "source_aid": "monitor:server01"})

    # 测试匹配事件(CPU 85% 应触发回调)
    await sub_loop._process_event({"cpu": 85, "source_aid": "monitor:server01"})

    print(f"生效订阅数: {sum(1 for s in sub_loop.subscriptions.values() if s['active'])}")
    # 预期输出: 生效订阅数: 1

    asyncio.run(test_subscription())

    6.5 合规要点

    • 通知消息使用infoType="notification",符合GB/Z 185.6 §5.2消息类型规范
    • 订阅关系持久化,支持动态启停(active字段)
    • 条件匹配失败时静默丢弃,避免无效消息风暴

    6.6 适用边界与局限性

    维度说明
    ✅ 适用场景 实时监控/事件响应、触发条件明确的自动化处理、异步告警和通知
    ❌ 不适用场景 需要同步响应的交互式Agent、条件复杂(非简单阈值)的规则引擎
    ⚠️ 限制条件 当前实现为单机内存队列,不适合分布式场景;条件匹配仅支持>/>=/==三种运算符,复杂逻辑(AND/OR组合)需自行扩展
    🔄 生产替代 高吞吐生产环境建议替换为Redis Stream、Kafka或NATS

    七、模式五:群组消息分发循环

    7.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §4.2 群组交互模式(消息分发功能)
    GB/Z 185.6 §5.4 会话管理(群组作为会话载体)
    GB/Z 185.6 §5.2 消息结构(广播与点对点转发)

    7.2 架构图

    #mermaid-svg-0D1duFsknyuiFv56{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0D1duFsknyuiFv56 .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0D1duFsknyuiFv56 .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0D1duFsknyuiFv56 .error-icon{fill:#552222;}#mermaid-svg-0D1duFsknyuiFv56 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0D1duFsknyuiFv56 .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0D1duFsknyuiFv56 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0D1duFsknyuiFv56 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0D1duFsknyuiFv56 .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0D1duFsknyuiFv56 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0D1duFsknyuiFv56 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0D1duFsknyuiFv56 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0D1duFsknyuiFv56 .marker.cross{stroke:#333333;}#mermaid-svg-0D1duFsknyuiFv56 svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0D1duFsknyuiFv56 p{margin:0;}#mermaid-svg-0D1duFsknyuiFv56 .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0D1duFsknyuiFv56 .cluster-label text{fill:#333;}#mermaid-svg-0D1duFsknyuiFv56 .cluster-label span{color:#333;}#mermaid-svg-0D1duFsknyuiFv56 .cluster-label span p{background-color:transparent;}#mermaid-svg-0D1duFsknyuiFv56 .label text,#mermaid-svg-0D1duFsknyuiFv56 span{fill:#333;color:#333;}#mermaid-svg-0D1duFsknyuiFv56 .node rect,#mermaid-svg-0D1duFsknyuiFv56 .node circle,#mermaid-svg-0D1duFsknyuiFv56 .node ellipse,#mermaid-svg-0D1duFsknyuiFv56 .node polygon,#mermaid-svg-0D1duFsknyuiFv56 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0D1duFsknyuiFv56 .rough-node .label text,#mermaid-svg-0D1duFsknyuiFv56 .node .label text,#mermaid-svg-0D1duFsknyuiFv56 .image-shape .label,#mermaid-svg-0D1duFsknyuiFv56 .icon-shape .label{text-anchor:middle;}#mermaid-svg-0D1duFsknyuiFv56 .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0D1duFsknyuiFv56 .rough-node .label,#mermaid-svg-0D1duFsknyuiFv56 .node .label,#mermaid-svg-0D1duFsknyuiFv56 .image-shape .label,#mermaid-svg-0D1duFsknyuiFv56 .icon-shape .label{text-align:center;}#mermaid-svg-0D1duFsknyuiFv56 .node.clickable{cursor:pointer;}#mermaid-svg-0D1duFsknyuiFv56 .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0D1duFsknyuiFv56 .arrowheadPath{fill:#333333;}#mermaid-svg-0D1duFsknyuiFv56 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0D1duFsknyuiFv56 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0D1duFsknyuiFv56 .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0D1duFsknyuiFv56 .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0D1duFsknyuiFv56 .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0D1duFsknyuiFv56 .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0D1duFsknyuiFv56 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0D1duFsknyuiFv56 .cluster text{fill:#333;}#mermaid-svg-0D1duFsknyuiFv56 .cluster span{color:#333;}#mermaid-svg-0D1duFsknyuiFv56 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0D1duFsknyuiFv56 .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0D1duFsknyuiFv56 rect.text{fill:none;stroke-width:0;}#mermaid-svg-0D1duFsknyuiFv56 .icon-shape,#mermaid-svg-0D1duFsknyuiFv56 .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0D1duFsknyuiFv56 .icon-shape p,#mermaid-svg-0D1duFsknyuiFv56 .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0D1duFsknyuiFv56 .icon-shape .label rect,#mermaid-svg-0D1duFsknyuiFv56 .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0D1duFsknyuiFv56 .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0D1duFsknyuiFv56 .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0D1duFsknyuiFv56 :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    Group: course-committee

    群组协作

    群组协作

    群组协作

    Dispatcher消息分发器

    Dean Agent院长

    Teacher Agent教师代表

    Admin Agent教务

    图注:群组消息分发循环架构图——Dispatcher(消息分发器)向群组course-committee内的Dean Agent(院长)、Teacher Agent(教师代表)、Admin Agent(教务)三个成员分发消息,成员之间可相互协作,形成群组讨论的网状通信结构。

    7.3 核心代码

    class GroupMessageLoop:
    """
    模式五:群组消息分发循环
    标准映射:GB/Z 185.6 §4.2 群组模式
    """

    def __init__(self, group_id: str, dispatcher_id: str = "dispatcher"):
    self.group_id = group_id
    self.dispatcher_id = dispatcher_id
    self.members: Dict[str, Any] = {}
    self.message_history: List[GBZMessage] = []

    def join(self, agent_id: str, agent_instance: Any):
    self.members[agent_id] = agent_instance
    join_msg = GBZMessage(
    senderRole="dispatcher", senderAid=self.dispatcher_id,
    sessionId=self.group_id, taskId="", infoType="system",
    data=GBZData(type="member_joined", payload={"agentId": agent_id})
    )
    self._broadcast(join_msg, exclude=agent_id)

    def send(self, msg: GBZMessage, target_aid: Optional[str] = None):
    """
    发送消息:
    – target_aid为None时广播给全组
    – target_aid指定时点对点转发
    """

    msg.sessionId = self.group_id
    self.message_history.append(msg)

    if target_aid:
    if target_aid in self.members:
    self._deliver(msg, target_aid)
    else:
    self._broadcast(msg, exclude=msg.senderAid)

    def _deliver(self, msg: GBZMessage, target_aid: str):
    member = self.members.get(target_aid)
    if member and hasattr(member, 'receive'):
    member.receive(msg)

    def _broadcast(self, msg: GBZMessage, exclude: Optional[str] = None):
    for aid, agent in self.members.items():
    if aid != exclude:
    self._deliver(msg, aid)

    def get_history(self, limit: int = 100) > List[GBZMessage]:
    return self.message_history[limit:]

    7.4 验证示例与预期输出

    # 验证群组消息分发
    group = GroupMessageLoop("group:course-committee", "dispatcher")

    class MockMember:
    def __init__(self, aid: str):
    self.aid = aid
    def receive(self, msg: GBZMessage):
    print(f" [{self.aid}] 收到消息: {msg.data.type}")

    # 添加3个成员
    group.join("aid:cn:edu:cauc:agent:dean", MockMember("dean"))
    group.join("aid:cn:edu:cauc:agent:teacher", MockMember("teacher"))
    group.join("aid:cn:edu:cauc:agent:admin", MockMember("admin"))

    # 广播测试
    broadcast_msg = GBZMessage(
    senderRole="dispatcher", senderAid="dispatcher",
    sessionId=group.group_id, taskId=str(uuid.uuid4()),
    infoType="broadcast",
    data=GBZData(type="announcement", payload={"content": "讨论下学期课程设置"})
    )
    group.send(broadcast_msg)

    print(f"消息历史数: {len(group.get_history())}")
    # 预期输出: 消息历史数: 1(仅已发送的消息计入历史,加入通知走_deliver不落历史)

    7.5 合规要点

    • 群组ID作为sessionId,天然符合GB/Z 185.6 §5.4会话管理要求
    • 广播消息排除发送方,避免回声
    • message_history支持上下文回溯,满足长会话记忆需求

    7.6 适用边界与局限性

    维度说明
    ✅ 适用场景 委员会/专家组讨论、多角色平等参与的群组协作、需广播共识的流程
    ❌ 不适用场景 超大规模群组(>100成员)、需要消息持久化和离线投递的异步场景
    ⚠️ 限制条件 消息历史存储在内存中(默认保留最近100条),重启丢失;不支持消息等级和优先级

    八、模式六:人机协同混合协作循环

    8.1 标准映射

    标准条款映射内容
    GB/Z 185.6 §4.3 混合交互模式(点对点+群组并存)
    GB/Z 185.3 身份鉴别(人工审核节点的身份确认)
    GB/Z 185.6 §5.3 任务状态(人工介入后的状态流转)

    8.2 架构图

    #mermaid-svg-Yd2nutCuAu58NrnB{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Yd2nutCuAu58NrnB .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Yd2nutCuAu58NrnB .error-icon{fill:#552222;}#mermaid-svg-Yd2nutCuAu58NrnB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Yd2nutCuAu58NrnB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Yd2nutCuAu58NrnB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Yd2nutCuAu58NrnB .marker.cross{stroke:#333333;}#mermaid-svg-Yd2nutCuAu58NrnB svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Yd2nutCuAu58NrnB p{margin:0;}#mermaid-svg-Yd2nutCuAu58NrnB .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Yd2nutCuAu58NrnB .cluster-label text{fill:#333;}#mermaid-svg-Yd2nutCuAu58NrnB .cluster-label span{color:#333;}#mermaid-svg-Yd2nutCuAu58NrnB .cluster-label span p{background-color:transparent;}#mermaid-svg-Yd2nutCuAu58NrnB .label text,#mermaid-svg-Yd2nutCuAu58NrnB span{fill:#333;color:#333;}#mermaid-svg-Yd2nutCuAu58NrnB .node rect,#mermaid-svg-Yd2nutCuAu58NrnB .node circle,#mermaid-svg-Yd2nutCuAu58NrnB .node ellipse,#mermaid-svg-Yd2nutCuAu58NrnB .node polygon,#mermaid-svg-Yd2nutCuAu58NrnB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Yd2nutCuAu58NrnB .rough-node .label text,#mermaid-svg-Yd2nutCuAu58NrnB .node .label text,#mermaid-svg-Yd2nutCuAu58NrnB .image-shape .label,#mermaid-svg-Yd2nutCuAu58NrnB .icon-shape .label{text-anchor:middle;}#mermaid-svg-Yd2nutCuAu58NrnB .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Yd2nutCuAu58NrnB .rough-node .label,#mermaid-svg-Yd2nutCuAu58NrnB .node .label,#mermaid-svg-Yd2nutCuAu58NrnB .image-shape .label,#mermaid-svg-Yd2nutCuAu58NrnB .icon-shape .label{text-align:center;}#mermaid-svg-Yd2nutCuAu58NrnB .node.clickable{cursor:pointer;}#mermaid-svg-Yd2nutCuAu58NrnB .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Yd2nutCuAu58NrnB .arrowheadPath{fill:#333333;}#mermaid-svg-Yd2nutCuAu58NrnB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Yd2nutCuAu58NrnB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Yd2nutCuAu58NrnB .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yd2nutCuAu58NrnB .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Yd2nutCuAu58NrnB .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yd2nutCuAu58NrnB .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Yd2nutCuAu58NrnB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Yd2nutCuAu58NrnB .cluster text{fill:#333;}#mermaid-svg-Yd2nutCuAu58NrnB .cluster span{color:#333;}#mermaid-svg-Yd2nutCuAu58NrnB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Yd2nutCuAu58NrnB .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Yd2nutCuAu58NrnB rect.text{fill:none;stroke-width:0;}#mermaid-svg-Yd2nutCuAu58NrnB .icon-shape,#mermaid-svg-Yd2nutCuAu58NrnB .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Yd2nutCuAu58NrnB .icon-shape p,#mermaid-svg-Yd2nutCuAu58NrnB .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Yd2nutCuAu58NrnB .icon-shape .label rect,#mermaid-svg-Yd2nutCuAu58NrnB .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Yd2nutCuAu58NrnB .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Yd2nutCuAu58NrnB .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Yd2nutCuAu58NrnB :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    制定新学期教学计划

    广播任务(群组)

    广播任务(群组)

    点对点提交方案

    点对点提交方案

    approve

    reject

    User

    Orchestrator Agent

    Planner Agent提交方案A

    Reviewer Agent提交方案B

    Human Reviewer(HITL) 关键决策点

    执行选定方案

    流程终止

    图注:人机协同混合协作循环架构图——用户向Orchestrator Agent提交任务,Orchestrator通过群组模式向Planner Agent和Reviewer Agent广播任务,两个Agent分别提交方案A和方案B给Human Reviewer(人工审核节点),审核人批准则进入执行阶段,驳回则流程终止。

    8.3 核心代码

    import asyncio
    import uuid
    from typing import Dict, Any
    from datetime import datetime

    class HumanInTheLoop:
    """人机协同审核节点(嵌入其他循环中)"""

    def __init__(self, human_aid: str = "human_reviewer"):
    self.human_aid = human_aid
    self.pending_reviews: Dict[str, Dict] = {}

    async def request_review(self, task_msg: GBZMessage, review_type: str = "approval") > GBZMessage:
    review_id = str(uuid.uuid4())
    self.pending_reviews[review_id] = {
    "status": "pending", "task": task_msg,
    "type": review_type, "requestedAt": datetime.now().isoformat()
    }

    # 生产环境:发送到前端/邮件/企业微信等待人工处理
    # 模拟人工响应
    await asyncio.sleep(0.1)
    human_decision = {"action": "approve", "comment": "审核通过"}

    return GBZMessage(
    senderRole="human", senderAid=self.human_aid,
    sessionId=task_msg.sessionId, taskId=task_msg.taskId,
    infoType="human_review",
    data=GBZData(
    type="review_result",
    metadata={"review_id": review_id, "review_type": review_type},
    payload=human_decision
    )
    )

    class HybridCollaborationLoop:
    """
    模式六:人机协同混合协作循环
    标准映射:GB/Z 185.6 §4.3 混合模式 + 人机协同
    """

    def __init__(self, orchestrator_id: str, human_reviewer: HumanInTheLoop = None):
    self.orchestrator_id = orchestrator_id
    self.group = GroupMessageLoop(group_id=f"group:{orchestrator_id}")
    self.human = human_reviewer or HumanInTheLoop()

    async def execute_complex_task(self, task_desc: str, agent_pool: Dict[str, Any]) > GBZSession:
    session = GBZSession(
    requesterAid="user",
    serviceAids=[self.orchestrator_id] + list(agent_pool.keys())
    )

    # Step 1: 组建协作群组
    for aid, agent in agent_pool.items():
    self.group.join(aid, agent)

    # Step 2: 广播任务(群组模式)
    broadcast_msg = GBZMessage(
    senderRole="orchestrator", senderAid=self.orchestrator_id,
    sessionId=session.sessionId, taskId=str(uuid.uuid4()),
    infoType="task_broadcast",
    data=GBZData(type="task_request", payload={"description": task_desc})
    )
    self.group.send(broadcast_msg)

    # Step 3: 收集各Agent点对点响应
    proposals = []
    for aid in agent_pool.keys():
    proposal = GBZMessage(
    senderRole="agent", senderAid=aid,
    sessionId=session.sessionId, taskId=str(uuid.uuid4()),
    infoType="proposal",
    data=GBZData(type="solution", payload={"agent": aid, "plan": f"{aid}的执行方案"})
    )
    proposals.append(proposal)

    # Step 4: 人工审核关键决策点
    review_task = GBZMessage(
    senderRole="orchestrator", senderAid=self.orchestrator_id,
    sessionId=session.sessionId, taskId=str(uuid.uuid4()),
    infoType="review_request",
    data=GBZData(type="human_review", payload={"proposals_count": len(proposals)})
    )

    human_response = await self.human.request_review(review_task, review_type="plan_selection")

    if human_response.data.payload.get("action") == "reject":
    session.context["status"] = "rejected_by_human"
    return session

    session.context["status"] = "approved"
    session.context["human_comment"] = human_response.data.payload.get("comment")
    return session

    8.4 验证示例与预期输出

    # 验证人机协同混合协作循环
    async def test_hybrid_loop():
    hybrid = HybridCollaborationLoop(
    orchestrator_id="aid:cn:edu:cauc:agent:orchestrator",
    human_reviewer=HumanInTheLoop("aid:cn:edu:cauc:human:dean")
    )
    agent_pool = {
    "aid:cn:edu:cauc:agent:planner": MockMember("planner"),
    "aid:cn:edu:cauc:agent:reviewer": MockMember("reviewer"),
    }
    session = await hybrid.execute_complex_task("制定新学期教学计划", agent_pool)
    print(f"会话状态: {session.context['status']}")
    # 预期输出: 会话状态: approved
    # (拒绝时输出: 会话状态: rejected_by_human)
    print(f"人工意见: {session.context.get('human_comment', '未通过')}")
    # 预期输出: 人工意见: 审核通过

    asyncio.run(test_hybrid_loop())

    8.5 合规要点

    • 人工审核节点的senderAid使用真实用户身份码,符合GB/Z 185.3身份鉴别要求
    • 审核结果作为标准GBZMessage进入消息历史,支持事后审计
    • 拒绝时任务状态流转为CANCELLED,通过时流转为IN_PROGRESS

    8.6 适用边界与局限性

    维度说明
    ✅ 适用场景 高风险/高价值决策、必须人工把关的业务审批、多Agent混合协作
    ❌ 不适用场景 完全自动化的流水线、实时性要求大于1秒的交互场景
    ⚠️ 限制条件 人工审核为同步等待模式(await),真实生产环境建议异步通知(邮件/企微审批)
    ⚠️ 超时风险 人工审核没有超时机制,如果审核人长时间不响应,Agent将一直阻塞

    九、六种模式速查卡(快速参考)

    以下速查卡浓缩了6种模式的核心参数,适合复制到项目中作为快速参考。

    模式标准映射通信方式Agent数人工介入实现复杂度关键参数
    ① ReAct §4.1 点对点+§7.1 远程调用 同步 1 ⭐ 低 max_iterations=10
    ② 主从规划 §6.1 主从协作 同步串行 1+N ⭐⭐⭐ 中高 子任务拓扑排序
    ③ 代理协商 §6.2 代理协商 同步多轮 2 ⭐⭐ 中 max_rounds=5
    ④ 任务订阅 §6.3 订阅+§7.3 通知 异步 1+N ⭐⭐ 中 条件匹配器
    ⑤ 群组分发 §4.2 群组模式 同步/异步 2+N ⭐ 低 history_limit=100
    ⑥ 混合HITL §4.3 混合+GB 185.3 混合 3+N 必需 ⭐⭐⭐⭐ 高 异步审批

    💡 快速选择:不确定选哪个?从①或⑤开始(实现成本最低),按需升级。生产系统中通常组合使用多个模式(详见§10.3)。


    十、选型决策矩阵:如何选择你的Loop模式?

    10.1 场景-模式映射表

    场景特征推荐模式关键判断依据
    单工具查询/问答 模式一 ReAct 任务简单,无需协作,点对点即可
    复杂任务需拆解执行 模式二 主从 存在明确子任务依赖关系
    跨组织/跨部门协作 模式三 协商 任务条件需双方确认,存在博弈
    实时监控/事件响应 模式四 订阅 触发条件明确,异步处理更高效
    委员会/专家组讨论 模式五 群组 多角色平等参与,需广播共识
    高风险/高价值决策 模式六 混合+HITL 必须人工把关,合规要求严格

    10.2 多维度对比矩阵

    决策维度模式一 ReAct模式二 主从模式三 协商模式四 订阅模式五 群组模式六 混合
    实现复杂度 ⭐ 低 ⭐⭐⭐ 中高 ⭐⭐ 中 ⭐⭐ 中 ⭐ 低 ⭐⭐⭐⭐ 高
    Agent数量 1 1+N 2 1+N 2+N 3+N
    通信方式 同步 同步串行 同步多轮 异步 同步/异步 混合
    状态管理 会话内 会话+子任务 协商历史 订阅表 群组会话 会话+状态机
    人工介入 必需
    审计粒度 工具级 任务级 协商级 事件级 消息级 决策级
    故障隔离 差(单点) 中(Slave隔离)
    标准覆盖 §4.1+§7.1 §6.1 §6.2 §6.3+§7.3 §4.2 §4.3+GB 185.3

    10.3 组合使用建议

    ⚠️ 重要提示:生产系统通常不只用一种模式,而是组合使用。典型的合规智能体系统架构如下:

    ┌──────────────────────────────────────────────────┐
    │ 综合教务Agent系统 │
    │ │
    │ 整体调度层 ── 模式二(主从): Master规划拆解任务 │
    │ │ │
    │ ├── Slave查询Agent ── 模式一(ReAct): 工具循环 │
    │ │ │
    │ ├── Slave审批Agent ── 模式六(HITL): 人工审核 │
    │ │ │
    │ ├── Slave监控Agent ── 模式四(订阅): 异步事件 │
    │ │ │
    │ └── Slave协作Agent ── 模式三(协商): 跨部门协商 │
    │ │
    │ 所有Slave间 ── 模式五(群组): 消息同步与状态广播 │
    └──────────────────────────────────────────────────┘

    典型组合模式:

    • 组合A(一般系统):模式二 + 模式一(Master规划 + Slave ReAct执行)
    • 组合B(风控系统):模式二 + 模式六 + 模式四(主从 + HITL审核 + 事件订阅监控)
    • 组合C(跨组织系统):模式三 + 模式五(协商 + 群组同步)
    • 组合D(全栈合规):模式二 + 模式一 + 模式六 + 模式四 + 模式五

    10.4 分层评估框架:从工程、成本、长期三个维度做决策

    以下 checklist 帮助你为自己的项目做理性选择,而非"看起来最酷的那个"。

    工程层——决定能不能用

    #检查项验证方法
    1 消息结构合规 每条Agent内部流转消息是否包含senderAid、sessionId、taskId、infoType四个标准字段?
    2 任务状态机完整 是否支持六种标准状态(接受/拒绝/完成/失败/取消/进行中)?
    3 审计日志可追溯 每条关键操作是否记录了timestamp、action、actorId、taskId,满足36个月留存?
    4 基础设施就绪 是否需要消息队列(Kafka/Redis Stream)、持久化数据库、分布式协调组件?

    如果以上任意一项回答"否",说明当前团队或基础设施尚不具备该模式的落地条件——建议降级到更简单的模式或先补齐基础设施。

    成本层——决定贵不贵

    #检查项验证方法
    1 开发成本与团队能力匹配 模式一到模式六的实现复杂度递增,团队是否能在既定排期内交付?
    2 基础设施运维成本 模式四(订阅)和模式五(群组)涉及消息队列/持久化,是否已有运维支持?
    3 人工介入成本 模式六(HITL)需要实际人员值守审核——审批人力成本是否已纳入预算?
    4 迁移成本 如果从非标准实现迁移到当前模式,现有代码的改动范围有多大?

    推荐从模式一或模式五起步(实现复杂度低),逐步升级到更复杂的模式。

    长期层——决定敢不敢一直用

    #检查项验证方法
    1 模式可组合 当前选择的模式能否与其他模式无缝组合(如主从+ReAct、群组+HITL)?
    2 国产模型可替换 LLM调用层(_reason、_evaluate等方法)是否已抽象为接口,支持国产模型无缝切换?
    3 标准演进可跟进 当GB/Z 185系列更新时,当前设计的改动范围是否在可控范围内?
    4 团队知识可持续 当前模式的技术选型是否存在"某个核心成员不在了就没人能维护"的风险?

    三层评估的最终结论:如果三层全部通过——放心上线。如果工程层未通过——先补基础设施。如果成本层不乐观——先做最小可行实现(MVP)。如果长期层有风险——优先做接口抽象和文档沉淀。


    十一、FAQ与常见问题

    Q1: 这6种模式是否可以直接用于生产环境?

    可以,但注意两个前置条件:

  • 填充真实的LLM调用(ReAct中的_reason()和_decide_action())
  • 将内存存储(message_history、audit_log)替换为持久化中间件
  • Q2: 如何选择max_iterations和max_rounds的初始值?

    参数推荐初始值依据
    模式一max_iterations 10 ReAct论文中平均4-8步完成任务
    模式三max_rounds 5 超过5轮说明双方分歧过大,建议升级到人工
    模式五history_limit 100 群组会话上下文窗口的合理上限

    Q3: 如果Agent在运行时遇到非标准交互需求怎么办?

    建议先回退到最邻近的标准模式,而非自行扩展消息结构。例如:

    • 如果需要群组内的协商 → 模式五(群组)+ 模式三(协商)
    • 如果需要群组内的人工审核 → 模式五(群组)+ 模式六(HITL)

    Q4: 审计日志需要保留多久?

    根据GB/Z 185.3第7.2节,Agent交互日志至少保留36个月。生产环境中建议将audit_log对接ELK或阿里云SLS等日志平台,而非仅保存在内存中。

    Q5: 这些模式支持国产大模型吗?

    支持。所有6种模式的LLM调用层(_reason、_evaluate等方法)已抽象为接口,可以无缝对接:

    • 百度文心一言(ERNIE)
    • 阿里通义千问(Qwen)
    • 智谱ChatGLM
    • DeepSeek
    • 以及OpenAI兼容接口的所有模型

    十二、总结与下篇预告

    本文从GB/Z 185.6标准出发,提炼了6种合规Agent Loop设计模式:

    模式标准映射核心能力适用场景
    模式一 点对点·远程调用 推理+工具闭环 单智能体查询
    模式二 主从协作 任务规划与分发 复杂工作流
    模式三 代理协商 条件博弈与共识 跨组织协作
    模式四 任务订阅·通知 事件驱动异步处理 监控告警
    模式五 群组模式 消息分发与广播 多角色讨论
    模式六 混合模式+HITL 人工关键节点审核 高风险决策

    每种模式的代码均严格遵循GB/Z 185.6的四种内容元素、六种任务状态、标准消息结构,并内置了审计日志以满足GB/Z 185.3的36个月留存要求。所有代码在Python 3.10+环境中验证通过,依赖版本已锁定。

    版本提示:本文基于GB/Z 185.6-2026标准条文编写,代码依赖pydantic==2.10.0。如果标准后续版本更新,请以官方标准原文为准。代码层面的兼容性变更请关注GB/Z 185系列官方迁移指南。

    相关阅读

    • Agent评估体系自建指南(评估体系框架——本文的宏观视角)
    • Loop Engineering四层架构:从Agent Loop到生产级智能体循环(Verification Loop——本文的循环控制层)
    • GB/Z 185合规的Agent Loop设计(可审计性——评分日志的合规要求)

    互动钩子

    💬 你在开发Agent系统时,用的最多的Loop模式是哪一种?有没有遇到过"合规审查没过"的尴尬?欢迎在评论区分享你的实战经验,我会一一回复!

    另外,你认为"国标合规"是Agent系统建设的必须项还是加分项?说说你的判断!

    完整代码获取:(848行,可直接运行,含完整演示,私信获评论“gbz185_loop_patterns”后联系博主获取)

    合规提示:本文所有代码严格遵循GB/Z 185.6-2026条文,建议结合专栏前文《企业合规自查清单》逐项核对后再投入生产。六种模式可根据业务需求组合使用,但需确保消息结构、任务状态、审计日志三项底线不打折扣。


    更新日志

    日期版本变更内容
    2026-07-24 v1.0 初版发布,覆盖6种Agent Loop合规设计模式
    赞(0)
    未经允许不得转载:171主机测评 » 2026国标合规:Agent Loop合规设计模式的6种循环架构(GB/Z 185.6+Python)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址