首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Workflow 驱动多 Agent 协作 从子流程拆解到人机决策闭环的工程实践

Workflow 驱动多 Agent 协作 从子流程拆解到人机决策闭环的工程实践

原创
作者头像
OneCode
发布2026-07-24 11:59:55
发布2026-07-24 11:59:55
1430
举报
文章被收录于专栏:ooderAgentooderAgent

0引言:智能体协作的"控制悖论"

在 AI 应用落地的深水区,我们常常面临一个棘手的悖论:大模型赋予了系统无限的创造力,却也让流程控制变得难以捉摸。一个智能体可能因为陷入逻辑死循环而耗尽企业预算,一个自动化流程可能因为外部系统的微小延迟而彻底卡死。在传统的 BPM(业务流程管理)中,规则是刚性的;而在纯粹的 LLM 应用中,行为又是概率性的。

如何将这两者融合,打造一个既"聪明"又"可控"的 Workflow Agent?这个命题在 workflow agent 流程定义属性——用户故事场景说明 一文中被拆解为 15 个用户故事,覆盖流程级守卫、上下文装载、知识绑定、子模式编排、人机操作、外部事件与路由控制七大维度。本文不重复罗列属性定义,而是以这 15 个故事为线索,聚焦"多 Agent 协作"这一核心主题,回答三个工程问题:

Q1 · 拆解:当多个 Agent 需要协同时,Workflow 用什么结构切分它们?子流程与场景流程各自的边界在哪? Q2 · 节拍:Agent 之间、Agent 与人之间、Agent 与外部系统之间,如何用统一机制对齐"谁先动、谁等待"? Q3 · 闭环:Hooks(钩子)和用户决策,如何不被散落在各处,而是收敛到一条可观测、可兜底的主线?

本文结合近期 BPM Designer 重构的真实经验——activitysSet 字段补齐、SwimLane 退役、SceneGroupExecutionEngine 调度链审计、三层会话渲染、human_confirm 闭环与 guard_escalation 超时兜底——把"故事书"变成"工程笔记"。重点 UI(时间轴、事件通知、用户交互)将以 SVG 细致绘制,让架构落到像素上。

1用户故事全景:15 个故事的归纳与分类

原文以标准用户故事格式 US-XX [优先级] [分类] 作为 <角色>,我希望 <能力>,以便 <业务价值> 驱动每个属性的语义。每个故事包含"故事陈述 → 场景描述 → 属性配置 → 三层对齐验证 → 验收标准"五段链路。下表把 15 个故事按分类归纳,并标注其与"多 Agent 协作"的关联度。

编号

分类

主题

优先级

核心属性

协作关联

US-01

流程级守卫

LLM 轮次防爆

P0

guardConfig.processLevel.maxLlmRounds

防 Agent 死循环

US-02

流程级守卫

Token 预算控制

P0

maxTotalTokens/ tokenWarnAt

成本上限

US-13

流程级守卫

回退超限例外介入

P0

maxBackwardCount

★ 协作兜底

US-03

上下文策略

DeepSeek 缓存优化

P0

contextLoadPolicy.staticLayers

多 Agent 共享上下文

US-04

上下文策略

深度设计模式

P1

loadLevels.deepDesign

深度协同上下文

US-05

知识绑定

意图层知识注入

P1

knowledgeBindings[].layer

知识分发

US-06

TASK 子模式

技能编排(SKILLS)

P0

taskMode=SKILLS/ config.skills

★ Agent 编排

US-07

TASK 子模式

场景组驱动(SCENE_GROUP)

P0

taskMode=SCENE_GROUP/ sceneGroupId

★★ 场景拆解

US-08

LLM 子模式

多 Agent 协同(HARNESS)

P1

llmMode=HARNESS/ config.harness

★★ 单活动内多 Agent

US-09

HUMAN 操作

人工确认

P0

humanMode=CONFIRM

★ 用户决策

US-10

HUMAN 操作

退回与特送

P0

BACKWARD/ SPECIAL_FORWARD

★ 路由决策

US-11

HUMAN 操作

委托流转

P0

DELEGATE

★ 责任转交

US-12

AGENT_EVENT

外部事件等待与合并

P0

type=AGENT_EVENT/ waitConfig

★★ 异步握手

US-14

路由控制

排他分支与默认兜底

P0

exclusiveGateway/ defaultFlow

协作分流

US-15

路由控制

回退重试

P0

BACKWARD路由

协作纠错

把"协作关联"列做一次聚类,可以得到本文后续三章的

"多 Agent 协作"不是单一故事,而是四条主线交织——① 用子流程/场景流程把协作"拆"开(US-06/07/08);② 用 Agent-Event 把外部世界"接"进来(US-12);③ 用 HUMAN 把人"嵌"进决策点(US-09/10/11);④ 用守卫把整条链"兜"住(US-13)。本文第三、四章正是沿这四条主线展开。

2多 Agent 协作的拆解哲学:子流程与场景流程

当多个 Agent 需要协同时,第一性问题不是"怎么通信",而是"怎么切分"。把所有 Agent 塞进一个活动里,会得到一个无法观测、无法干预的"黑盒大脑";把每个 Agent 拆成独立流程,又会让协作上下文在流程边界处断裂。原文给出了三种切分粒度,正好对应三个递进的子模式。

2.1 TASK 子模式:技能编排(US-06)——最细粒度的"工具箱"

SKILLS 模式是最轻量的协作单元。一个 TASK 活动配置 taskMode=SKILLS,通过 config.skills 声明一组技能 ID,运行时由 ActivityExecutor 顺序调用。它不引入新的 Agent 实体,本质是"一个 Agent 顺序使用多个工具"。

代码语言:javascript
复制
{
  "type": "TASK",
  "taskMode": "SKILLS",
  "config": {
    "skills": ["skill-req-collect", "skill-domain-extract"]
  }
}

💡 三层对齐要点(US-06)

L1(JSON):parseActivity 读 taskMode 顶层字段优先,缺失时回退读 config.taskMode 兜底,兼容旧数据。L2(面板):SubModePanelPlugin 对 TASK 类型显示 taskMode 选择器。L3(运行时):executeTaskActivity() 按 getTaskMode() 分派到技能执行器。

2.2 TASK 子模式:场景组驱动(US-07)——"流程嵌流程"的协作骨架

SCENE_GROUP 是本文的核心。它把一个 TASK 活动变成"流程嵌流程"的入口:活动本身只负责"触发并注入上下文",真正的多 Agent 协作发生在被引用的场景组(SceneGroup)内部。

以 intent-dispatch 流程为例,ic_dispatch_to_sg 活动触发 rad 场景组,注入 5 个上下文变量:

代码语言:javascript
复制
{
  "type": "TASK",
  "taskMode": "SCENE_GROUP",
  "sceneGroupId": "rad",
  "sceneGroupContextInjection": {
    "userIntent": "${intent}",
    "matchedFlowId": "${matchedFlowId}",
    "executionPlan": "${executionPlan}",
    "confirmedIntent": "${confirmed}",
    "dispatchSource": "intent-dispatch"
  },
  "llmConfigInherit": "SCENE_GROUP",
  "config": {
    "sgHumanStrategy": "AUTO_HANDLE",
    "skills": [
      {"skillId": "sg_rad_intent_resolve", "priority": 1},
      {"skillId": "sg_rad_design_orchestrate", "priority": 2}
    ],
    "sgKnowledgeBindings": [
      {"bindingId": "sg_rad_intent_kb", "layer": "INTENT",
       "scopeKeys": ["radIntentDictionary"],
       "sourceRef": "knowledge/scenes/rad-intent.json"}
    ],
    "sgLlmConfig": {"provider": "openai", "model": "gpt-4-turbo",
                    "temperature": 0.3, "maxTokens": 8000}
  }
}

这里有四个设计决策值得展开,它们共同定义了"场景流程"作为协作单元的语义:

决策一:上下文注入而非上下文继承

父流程不把整个上下文丢给子场景组,而是通过 sceneGroupContextInjection 显式声明要注入哪些变量。这避免了"上下文污染"——子场景组只看到它该看的,父流程的内部状态不会泄漏。injectContext() 把这些变量写入 sg.businessContext,成为子场景组内所有 Agent 共享的"协作黑板"。

决策二:LLM 配置继承源可切换

llmConfigInherit 有两个值:PROCESS(继承父流程配置)和 SCENE_GROUP(用 SG 自己的 sgLlmConfig)。这意味着同一个场景组可以被不同父流程复用,而每次复用可以指定是否替换底层模型。比如 rad 场景组在 intent-dispatch 下用 GPT-4,在另一个轻量分发流程下可以继承父流程的 DeepSeek。

决策三:SG 内 HUMAN 策略解耦父流程

sgHumanStrategy 有三档:AUTO_HANDLE(自动处理,不阻断父流程)、SCENE_DRIVE(场景驱动)、CRITICAL_PAUSE(关键暂停,阻断父流程)。当设为 AUTO_HANDLE 时,子场景组内部的人机交互只写 auditLog,不向上冒泡暂停。这是"场景流程"区别于"子流程"的关键——它默认是自治的,父流程不需要为它的内部决策负责。

决策四:技能与知识在 SG 层独立绑定

config.skills 和 config.sgKnowledgeBindings 让场景组拥有自己的"工具箱"和"知识库",与父流程完全隔离。sg_rad_intent_resolve(意图解析技能)和 sg_rad_design_orchestrate(设计编排技能)只在 rad 场景组内可见,避免技能污染父流程的技能命名空间。

2.3 LLM 子模式:HARNESS 多 Agent 协同(US-08)——单活动内的"圆桌会议"

如果说 SCENE_GROUP 是"流程嵌流程",那 HARNESS 就是"活动内嵌多 Agent"。architect-pipeline 的 llm_architect_design 活动配置 llmMode=HARNESS,协调"架构师 Agent"与"评审 Agent"交替推理,直到达到共识(consensusThreshold=0.85)或达到 maxRounds=3。

HARNESS 的精妙之处在于它复用了 pause+wait FC-Loop 路径。L3 层通过 _llmMode / _harnessConfig 把配置传播到 ChatScene/FC-Loop,由 FC-Loop 的循环结构驱动实际的"轮次交替"。这意味着 HARNESS 不需要新建一套调度引擎,它只是 FC-Loop 的一个"特化配置“。

2.4 子流程 vs 场景流程:两种拆解范式的边界

这是工程实践中最容易被混淆的一对概念。下表把它们对齐到六个维度,帮助判断"这个协作该用哪种拆解":

维度

子流程(SUBPROCESS)

场景流程(SCENE_GROUP)

触发方式

显式 calledElement 调用,父流程同步等待

TASK + sceneGroupId 触发,可异步

上下文

默认继承父流程上下文(需手动映射 IO)

显式注入 sceneGroupContextInjection,隔离干净

LLM 配置

继承父流程

llmConfigInherit可切 PROCESS/SCENE_GROUP

内部 HUMAN

默认冒泡暂停父流程

sgHumanStrategy三档控制,默认 AUTO_HANDLE 不阻断

资源隔离

共享父流程技能/知识命名空间

独立 skills / sgKnowledgeBindings

语义定位

"我要同步等子流程跑完"

"我把这块自治地交给场景组"

✅ 选型决策树

用子流程:当子逻辑的产出是父流程下一步的直接输入,且需要父流程同步等待(例如"先算报价再下单")。

用场景流程:当子逻辑是一个自治的业务域,有自己的技能/知识/模型配置,父流程只关心"它跑完了"而不关心它内部怎么决策(例如"分发到 rad 设计域")。

用 HARNESS:当多个 Agent 需要在同一活动内交替推理达成共识,不需要跨流程边界(例如"架构师+评审圆桌会议")。

2.5 重构经验:SwimLane 退役与 activitysSet 兜底

理论讲完,落到代码总会遇到历史包袱。近期 BPM Designer 重构中遇到两个典型问题,正好印证了上述拆解哲学。

问题一:SwimLane(泳道)的退役

旧版本用 SwimLane(泳道)来"分组"活动,本质是想表达"这一组活动属于同一个角色/Agent"。但泳道只是视觉分组,不携带执行语义,反而让流程定义变重。重构中废弃了 SwimLaneDefinition.java,把 7 个流程里的 12 个泳道活动迁移到顶层,并通过 migrate-swimlanes-to-top-level.js 生成备份。迁移后,"谁负责"的语义改由 activityCategory 从 activityType 派生(ActivityDef._deriveCategory),而不是靠泳道这种纯视觉容器。

⚠️ 踩过的坑:activityCategory 默认 'HUMAN'

迁移后发现 LLM_AGENT/TASK/AGENT_EVENT 节点错误地显示了 HUMAN 的"执行者/权限"面板。根因是 Canvas.js / ActivityDef.js / PanelInitializer.js 中 activityCategory 默认值是 'HUMAN',而遗留插件用 activityCategory 过滤面板分组。修复:activityCategory 必须从 activityType 派生,不得默认 'HUMAN'。这是"把视觉分组(泳道)换成执行语义(category)"迁移中必须同步修复的连带问题。

问题二:activitysSet 字段补齐

场景组配置需要 activitysSet 字段来声明"场景组包含哪些子场景活动"。但旧版 ActivityDef.js 在解析和序列化时漏了这个字段,导致拖拽保存的场景节点丢失配置。重构中补齐了 activitysSet 的解析与序列化,并在 SubModePanelPlugin.js 新增 _renderActivitysSetExtra 方法渲染场景组配置 UI。

这两个问题的共同教训是:拆解范式的切换(泳道→category、单层→activitysSet)必须同步打通"定义→面板→运行时"三层,任何一层漏改都会表现为"配置丢失"或"面板错配"。这正是下一章 L1/L2/L3 三层对齐要解决的。

3Agent-Event 与 HUMAN:Hooks 与用户决策的统一处理

拆解解决了"多 Agent 怎么组织",但协作要真正跑起来,还需要解决"节拍"问题——Agent 之间、Agent 与人之间、Agent 与外部系统之间,如何对齐"谁先动、谁等待、谁决策"。原文用 pause+wait FC-Loop、AGENT_EVENT、HUMAN 三套机制回答了这个问题,而它们最终收敛到同一个统一处理模式:把所有"需要外部输入才能继续"的点,都建模成一个可暂停、可观测、可兜底的活动。

3.1 pause+wait FC-Loop:协作的"心跳节拍器"

FC-Loop(Function Calling Loop)是整个协作体系的节拍器。它的本质是一个 pause → wait → resume 循环:

  1. pause
  2. :当前活动执行到需要外部输入(LLM 工具调用、人工确认、外部事件)时,暂停流程,状态置为 WAITING。
  3. wait
  4. :通过 SSE 向前端推送等待事件(如 human_confirm、event_waiting),同时启动超时计时器(默认 180s)。
  5. resume
  6. :收到外部响应(用户点击确认、外部事件到达、超时自动确认)后,注入 confirmId,恢复流程执行。

近期重构中对 FC-Loop 做了三项关键加固:

  • confirmId 预注入
  • :在 pause 阶段就生成 confirmId 并随 SSE 下发,确保前端回传的确认能被正确路由到对应的等待点(避免"确认了但流程没动")。
  • SSE 转发完整性
  • :所有 human_confirm / guard_escalation 事件必须经 SseEventPushListener 完整转发,不丢失载荷字段。
  • 180s 超时自动确认
  • :避免流程因前端未响应而永久卡死,超时后走兜底策略(自动确认或升级)。
  • 下一轮需要外部输入时回到 ①超时 180s 兜底直通

3.2 AGENT_EVENT:外部世界的异步握手(US-12)

多 Agent 协作不只在"Agent 之间",还包括"Agent 与外部系统之间"。当一个 Agent 需要等待外部系统(如 CI/CD 完成、第三方审批、消息队列事件)时,就用 AGENT_EVENT 活动类型。它通过 waitConfig 声明等待什么事件、等多久、收到后如何合并。

AGENT_EVENT 的关键设计是"等待即活动"——把"等外部事件"建模成一个一等公民的活动节点,而不是塞在某个 Agent 的代码里 sleep。这样做有三个好处:① 等待状态可被前端观测(时间轴上能看到"正在等待 X 事件");② 等待可被守卫兜底(超时升级而非卡死);③ 多个事件可合并(waitConfig.mergeStrategy)。

3.3 HUMAN 三态:确认 / 退回特送 / 委托流转(US-09/10/11)

HUMAN 活动是"把人嵌进决策点"的标准方式。原文定义了三种 humanMode,覆盖了人机协作中最常见的三类决策:

故事

humanMode

语义

典型场景

US-09

CONFIRM

确认/拒绝当前产出

架构方案确认、意图确认

US-10

BACKWARD/ SPECIAL_FORWARD

退回重做 / 特送跳转

方案不合格退回需求阶段

US-11

DELEGATE

委托给他人/他 Agent

当前 Agent 处理不了,转交专家

这三种模式共享同一套 pause+wait FC-Loop 基础设施——它们都是"暂停流程,等待用户在 UI 上操作,再恢复"。区别只在于用户操作后路由的去向:CONFIRM 往前走,BACKWARD 往回跳,SPECIAL_FORWARD 跳到指定节点,DELEGATE 把控制权交给另一个执行者。这种统一建模让前端的交互组件可以复用(同一个确认弹窗,只是按钮不同)。

3.4 守卫升级:例外介入的统一兜底(US-13)

这是整个协作体系最精彩的设计。当流程因为反复回退超过 maxBackwardCount(默认 3 次)、或路由无匹配、或全局回退超限时,系统不会让流程卡死,而是合成一个 HUMAN 活动,把控制权交给人工。

具体机制:RouteToEngine 每次 BACKWARD 路由递增 globalBackwardCount,超限触发 handleHumanEscalation(),该函数会:

  1. 创建合成 HUMAN 活动(intervene-{actId}-{ts}),humanMode=EXCEPTION_INTERVENTION;
  2. 调用 fireGuardEscalation() → SseEventPushListener.onGuardEscalation() 推送 guard_escalation SSE 事件;
  3. 事件载荷含 failedActivityId / interventionActivityId / reasonCode(no_route_matched / backward_exhausted / global_backward_exceeded)/ availableOperations=[INTERVENE_EXCEPTION, RESUME, TERMINATE, SEND]。

🎯 核心洞察:把"异常"统一建模为"HUMAN 决策"

这是整个协作体系的哲学统一点。无论是用户主动确认(US-09)、用户退回(US-10)、用户委托(US-11),还是系统检测到异常需要人工介入(US-13),最终都收敛到"合成一个 HUMAN 活动 + 推送 SSE + 等待用户操作"这一条主线。前端的交互组件、后端的 FC-Loop、守卫的兜底逻辑,全部围绕这个统一模型构建。Hooks(钩子)和用户决策,不是散落在各处的 if-else,而是同一种"暂停-等待-恢复"活动

4重点 UI:时间轴 + 事件通知 + 用户交互

前面三章讲的是后端编排哲学,但"聪明又可控"最终要落到用户看得见的界面上。近期重构中,会话渲染从单层升级为三层架构,专门用于承载多 Agent 协作的可观测性。本节是全文重点,三个核心 UI 组件将以 SVG 细致绘制。

4.1 三层渲染架构总览

多 Agent 协作会产生三类截然不同的信息流:① 计划骨架(流程开始前 LLM 预测的工具调用序列);② 实时事件流(运行中 SSE 推送的步骤、技能、工具、思考过程);③ 历史归档(已完成活动的折叠摘要)。单层 UI 无法同时表达这三类信息的时序与层级,因此重构为三层

💡 设计修正记录

初版设计把"已完成项"放在顶部展开、"未完成项"折叠,导致用户看不到当前在做什么。修正后:未完成项顶部展开(聚焦当下),完成项折叠到下方(归档可追溯)。这是"可观测性优先于完整性"的典型取舍。

4.2 时间轴:activityInst 生命周期可视化

时间轴是实时事件流(Layer 2)的核心载体。它把一个活动实例(activityInst)从"开始 → 各类子事件 → 完成"的完整生命周期,以垂直时间线呈现。每个事件节点携带类型图标、时间戳、状态、详情摘要,并支持点击展开。近期重构中修复了一个关键 BUG:HUMAN 确认框必须在 activityInst 内部渲染,而不是浮在顶层导致用户看不到上下文图 7 · 时间轴组件:垂直时间线 + 事件卡片 + 状态徽章 + 内嵌人工确认框

✅ 关键修复:HUMAN 确认框内置渲染

初版 human_confirm 弹窗浮在顶层,用户看不到"在确认什么"。重构后确认框作为时间轴的一个事件节点内嵌渲染(图 7 节点 5),用户能同时看到上下文(前面的技能执行、Agent 协同结果)和操作按钮。这是"上下文连续性"原则的体现。

4.3 事件通知:SSE 事件流与 guard_escalation

事件通知组件负责实时推送 SSE 事件,并在守卫触发时高亮告警。它和时间轴的关系是:时间轴是"结构化展示",事件通知是"即时提醒"。前者按活动实例组织,后者按时间顺序流式呈现,两者互补。近期重构中优化了深色主题下的文字可读性,并把"执行日志"这种不友好标题改为可点击的状态徽章。图 8 · 事件通知组件:严重事件置顶高亮 + 多类型图标 + 状态徽章 + 倒计时

4.4 用户交互:human_confirm 弹窗与操作栏

用户交互组件是"人机闭环"的最后一公里。当 human_confirm 或 guard_escalation 事件到达时,前端需要弹出一个承载完整决策上下文的交互面板。这个面板的设计直接影响用户能否"快速理解、果断决策"。近期重构中简化了过厚的边框、对齐了深色主题、并确保操作栏根据 availableOperations 动态生成按钮。

💡 组件复用要点

两个弹窗共享同一套渲染基础设施(human_confirm SSE → 弹窗组件 → 操作回调 → FC-Loop resume)。区别仅在:① 头部颜色(绿/红);② 操作按钮集(由 availableOperations 动态生成);③ 上下文区域是否显示 reasonCode 横幅。这种"同构不同态"的设计,让 Hooks(守卫升级)和用户决策(常规确认)在前端也实现了统一处理。

5工程难点与解法:L1/L2/L3 三层对齐

回看全文,最难的不是单点设计,而是"定义层、面板层、运行时层"三层必须始终对齐。原文每个用户故事都包含"三层对齐验证"段落,这不是文档模板,而是工程纪律。下表把三层职责和常见错位归纳如下:

载体

职责

典型错位

L1 · JSON 定义

definition.json/ VfsFlowDefinitionLoader

流程属性的权威来源

旧对象 Map 形态未归一化为数组(US-05)

L2 · 面板编辑

SubModePanelPlugin/ ProcessAdvancedPanelPlugin

可视化编辑,保存回 L1

activityCategory默认 'HUMAN' 导致非 HUMAN 节点错配面板

L3 · 运行时消费

ActivityExecutor/ ProcessGuard / SceneGroupExecutionEngine

读取属性驱动执行

isSceneGroupMode()读错字段(config vs 顶层)导致场景组不触发

5.1 三类高频错位与修复模式

近期重构中遇到的三类错位,可以作为"三层对齐"的活教材:

错位一:字段读取来源不一致(US-07 缺口 #2)

isSceneGroupMode() 原本只读 config.taskMode,而 executeTaskActivity() 读 getTaskMode()(顶层优先 + config 兜底)。结果:面板配置写在顶层,运行时却读 config,导致场景组模式不触发。修复:isSceneGroupMode() 改为与 executeTaskActivity 同源读取。教训:同一字段的读取入口必须全局统一。

错位二:形态不统一(US-05 缺口 #7)

知识绑定旧 JSON 是对象 Map({"INTENT": "xxx.json"}),新数据是数组。VfsFlowDefinitionLoader 必须按 instanceof 分派:JSONArray 走数组解析,JSONObject 走 Map 转数组。教训:历史数据形态迁移必须在加载层兜底,不能要求手工改 JSON。

错位三:视觉分组与执行语义混淆(SwimLane 退役)

泳道是纯视觉分组,不携带执行语义;而 activityCategory 是执行语义。退役泳道时必须同步把"谁负责"的语义迁移到 activityCategory,并修复所有默认值。教训:视觉容器的退役要同步处理它承载的隐式语义。

5.2 上下文装载:多 Agent 协作的"共享黑板"工程化

多 Agent 协作的核心难题是上下文如何共享而不污染。原文 US-03/US-04 给出的方案是"静态前缀 + 动态后缀"分层装载,结合 DeepSeek 前缀缓存规则(从第 0 个 token 开始完全匹配才命中,最小 64 tokens):

  • 静态层
  • (SYSTEM/PROCESS/KNOWLEDGE):流程定义不变时内容完全相同,最大化缓存命中,按 90% 折扣计费。
  • 动态层
  • (HISTORY/WORKING):按需装载,standard 级别只装最近 3 轮,deepDesign 级别装 10 轮 + detail 实例数据。

这套策略与场景组的 sceneGroupContextInjection 形成互补:静态层解决"全局共享上下文的成本",注入变量解决"跨流程边界的上下文传递"。两者结合,让多 Agent 协作既"看得见彼此"又"不互相污染"。

5.3 路由控制:协作的"分流与纠错"

US-14(排他分支与默认兜底)和 US-15(回退重试)看似是路由问题,实则是协作问题。排他分支让一个 Agent 的产出决定"下一个 Agent 是谁",defaultFlow 兜底避免"无人接手";回退重试让协作可以纠错,而 maxBackwardCount + 守卫升级则防止"无限纠错"。三者构成协作的"路由-纠错-兜底"完整链路。

6结语:把概率性关进确定性的笼子

回到开篇的悖论——大模型赋予系统创造力,却让流程控制难以捉摸。本文从 15 个用户故事出发,结合近期 BPM Designer 重构经验,给出了一套可落地的解法。把它浓缩成三句话:

拆解:多 Agent 协作不是"一个大脑管一切",而是按粒度切分——SKILLS(工具箱)、SCENE_GROUP(自治场景域)、HARNESS(圆桌会议)三层递进,分别对应"一个 Agent 用多工具"、"流程嵌流程"、"活动内嵌多 Agent"。 节拍:所有需要外部输入的点——无论是用户确认(US-09)、退回特送(US-10)、委托流转(US-11)、外部事件(US-12),还是守卫升级(US-13)——都收敛到 pause+wait FC-Loop 这一套"暂停-等待-恢复"基础设施,配 confirmId 预注入和 180s 超时兜底。 统一:Hooks 和用户决策不是散落的 if-else,而是同一种"合成 HUMAN 活动 + 推送 SSE + 等待操作"的统一模型。前端三层渲染(计划骨架 / 实时事件流 / 历史归档)+ 三大 UI 组件(时间轴 / 事件通知 / 交互弹窗)让这套机制可观测、可干预。

重构过程中最深的体会是:"聪明又可控"的本质,是把 LLM 的概率性行为关进 Workflow 的确定性笼子。笼子的骨架是 L1/L2/L3 三层对齐(定义→面板→运行时),笼子的锁是守卫升级(异常自动转人工),笼子的窗户是三层 UI(让用户随时看见里面在发生什么)。近期踩过的坑——activityCategory 默认 'HUMAN'、isSceneGroupMode() 读错字段、SwimLane 退役连带语义丢失、HUMAN 确认框浮在顶层——无一不是"笼子某处没焊好"的体现。

下一步的演进方向已经清晰:① 把 LLM 预测从"预测活动"改为"预测工具调用序列"(LLM 不擅长预测活动却擅长预测工具),计划骨架展示"必要工具清单"而非"活动列表";② 完善 C2/C3 前端监听(skill_progress + file_read/write 的实时埋点);③ 把 V1 EVENT_WAITING history 补齐,让外部事件等待也能在时间轴上回溯。这些都是在"确定性笼子"上继续开窗、让协作更透明的工作。

最后,借用原文前言的话作结:如何将这两者完美融合,打造出一个既"聪明"又"可控"的 Workflow Agent,是我们一直在探索的终极命题。15 个用户故事是这个命题的拆解,本文则是拆解的工程注脚——愿它能为同样在 AI 落地深水区跋涉的同行,提供一张可参照的地图。

📚 全文核心要点速览

  • 四条主线
  • :拆解(子流程/场景流程)、节拍(FC-Loop)、统一(合成 HUMAN)、兜底(守卫升级)。
  • 三种拆解粒度
  • :SKILLS(最细)、SCENE_GROUP(流程嵌流程,自治)、HARNESS(活动内多 Agent)。
  • 三层 UI
  • :计划骨架(flow_plan)/ 实时事件流(activityInst 时间轴)/ 历史归档(折叠摘要)。
  • 三层对齐
  • :L1 JSON 定义 / L2 面板编辑 / L3 运行时消费——任何一层漏改都是 bug。
  • 两个统一
  • :后端"异常即 HUMAN 决策",前端"确认弹窗同构不同态"。

Workflow 驱动多 Agent 协作:从子流程拆解到人机决策闭环的工程实践

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 0引言:智能体协作的"控制悖论"
  • 1用户故事全景:15 个故事的归纳与分类
  • 2多 Agent 协作的拆解哲学:子流程与场景流程
  • 2.1 TASK 子模式:技能编排(US-06)——最细粒度的"工具箱"
  • 2.2 TASK 子模式:场景组驱动(US-07)——"流程嵌流程"的协作骨架
  • 决策一:上下文注入而非上下文继承
  • 决策二:LLM 配置继承源可切换
  • 决策三:SG 内 HUMAN 策略解耦父流程
  • 决策四:技能与知识在 SG 层独立绑定
  • 2.3 LLM 子模式:HARNESS 多 Agent 协同(US-08)——单活动内的"圆桌会议"
  • 2.4 子流程 vs 场景流程:两种拆解范式的边界
  • 2.5 重构经验:SwimLane 退役与 activitysSet 兜底
  • 问题一:SwimLane(泳道)的退役
  • 问题二:activitysSet 字段补齐
  • 3Agent-Event 与 HUMAN:Hooks 与用户决策的统一处理
  • 3.1 pause+wait FC-Loop:协作的"心跳节拍器"
  • 3.2 AGENT_EVENT:外部世界的异步握手(US-12)
  • 3.3 HUMAN 三态:确认 / 退回特送 / 委托流转(US-09/10/11)
  • 3.4 守卫升级:例外介入的统一兜底(US-13)
  • 4重点 UI:时间轴 + 事件通知 + 用户交互
  • 4.1 三层渲染架构总览
  • 4.2 时间轴:activityInst 生命周期可视化
  • 4.3 事件通知:SSE 事件流与 guard_escalation
  • 4.4 用户交互:human_confirm 弹窗与操作栏
  • 5工程难点与解法:L1/L2/L3 三层对齐
  • 5.1 三类高频错位与修复模式
  • 错位一:字段读取来源不一致(US-07 缺口 #2)
  • 错位二:形态不统一(US-05 缺口 #7)
  • 错位三:视觉分组与执行语义混淆(SwimLane 退役)
  • 5.2 上下文装载:多 Agent 协作的"共享黑板"工程化
  • 5.3 路由控制:协作的"分流与纠错"
  • 6结语:把概率性关进确定性的笼子
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档