# 对话驱动的多智能体工作流编排:开发设计说明 > 状态:阶段 A、Evidence Pack、Deep Research 写作接入和阶段 C 的首个“终态节点定点修订”闭环已实现;其余阶段仍为设计与待开发项(以 2026-08-31 的代码为基线) > 适用范围:工作流编辑器的“对话运行”页面、工作流运行时、深度研究报告能力 > 关联文档:[WORKFLOW_STUDIO_BACKEND_DEV_ZH.md](./WORKFLOW_STUDIO_BACKEND_DEV_ZH.md)、[ADR 0001](./adr/0001-workflow-studio-runtime.md) ## 1. 要解决的问题 用户在工作流页面输入一个自然语言任务后,系统应能理解意图、选择合适的工作流模板和智能体角色、并行收集信息、多角度分析、汇总证据,最后生成可追溯的高质量报告。整个过程不是“等所有模型返回后一次性展示”,而是可实时观察、可插话、可调整、可停止和可局部重跑的执行过程。 典型任务例如: > “分析本周销售下滑的原因,结合用户反馈和竞品投放,给出下周广告与产品体验改进建议,并整理成汇报报告。” 该任务应该被拆成可执行的子任务,而不是把原句依次发给多个 Agent: ```text 用户消息 │ ▼ 意图理解 / 计划生成 │ ├── 信息不足 ──► 用户协助卡片 ──► 同一运行恢复 ▼ 工作流模板与角色选择 │ ├── 销售/业务数据收集 ─┐ ├── 用户反馈收集 ├──► 证据归一化与校验 ─► 多视角分析 └── 竞品/投放信息收集 ─┘ │ ▼ 报告大纲与深度研究写作 │ ▼ 质检、引用、产物输出 ``` ## 2. 设计结论 采用“**薄总控智能体 + 候选流程选择/编辑 + 确定性工作流运行时 + 专项智能体/技能 + 专用报告写作管线**”的结构。 - 总控(Planner/Controller)只做语言理解、任务规划、候选流程/角色选择、缺失信息判断和变更影响评估。 - 总控一次给出 2–3 条可执行的候选流程;用户选择其中一条后,在右侧画布检查和修改,再显式确认执行。模板只是候选图的后端积木,不是系统静默替用户作出的最终选择。 - 工作流引擎仍是唯一的调度者:负责 DAG 依赖、并发、重试、暂停、恢复、取消、权限、事件持久化和状态归并。 - 专项 Agent 按明确角色执行收集、分析、审校等任务;它们不拥有全局调度权。 - Deep Research 写作能力作为一个可运行、可流式输出的专用节点接入,不把它的内部流程混进总控 Prompt。 因此,“总控智能体”不是一个包办所有事情的 God Agent。它产生受约束的计划;能否执行、执行什么副作用、如何重试,必须由可审计的后端运行时决定。 ## 3. 当前代码基线:已有能力与缺口 下表区分当前已有实现和本文建议新增的能力,避免把设计目标误认为已经实现。 | 范围 | 当前已有实现 | 仍需补齐 | | --- | --- | --- | | 工作流调度 | 自建持久化 DAG 运行时,支持依赖、并发、条件、循环、暂停/恢复、取消与事件日志。核心位于 `packages/harness/deerflow/workflows/runtime/engine.py`、`app/gateway/workflow_executor.py`。 | 计划版本、局部失效/重算、由计划驱动的模板实例化。 | | Agent 节点 | `workflow_agent_runner.py` 中的 Agent/Agent Skill 使用 `make_lead_agent`,并从 `agent.astream()` 转发文本增量与工具事件。 | 完整 Role Catalog、结构化计划校验、上下文与产物的统一输入输出契约。 | | Evidence Pack | `evidence_normalizer` 已是确定性节点:把并行研究节点的结果归一化为有来源节点、角色标签、缺口和截断标志的 `evidencePack`;不会将 Agent 文本伪装成已验证事实。并行调研候选图自动在汇总 Agent 前插入该节点。 | 证据去重、外部来源质量评分、事实校验、引用格式化。 | | 流式事件 | 运行事件可持久化并通过 SSE 推送;现有事件覆盖 run、node、output、tool、artifact、awaiting input 等;`deep_research_write` 会把安全的报告增量投影为 `node.output.delta`。 | 计划事件、变更/版本事件、跨工作节点的统一报告回放/去重指标。 | | 对话运行 | 普通发送先创建持久化 `WorkflowPlanningSession`,后端从当前草稿和已授权 Agent 节点构建 2–3 个候选图;指定 Agent 时仍会投影为 `start → agent → output` 的独立任务。用户选择候选卡片、在画布编辑并确认后,才创建正式 run。终态、无循环 run 的已完成 Agent/Skill 支持定点反馈:创建不可变 revision,复用不受影响的完成节点,目标和下游重新流式执行。运行中输入新方向时,前端会先停止旧 run,保留审计,并将原任务与调整交给 Planner 生成新候选图。 | 真正的连续会话上下文、运行中节点的交互式局部调整、循环图/其他节点类型的影响分析、版本对比界面。 | | 规划持久化 | `workflow_planning_sessions` / `workflow_planning_proposals`(migration `20260831_01`)分离保存 query、候选图、推荐理由、图 revision、选择和确认结果;重复确认返回同一 run。 | 规划会话的过期清理、候选方案差异视图、复杂任务的多轮补充信息。 | | 人机协作 | `human_input` 节点会持久化等待状态,并以一次性 `resumeToken` 通过同一 run 恢复;前端已按 `formSchema` 渲染协助卡片、结构化字段和自然语言补充。 | 恢复后按输入影响范围使下游局部失效、复杂多轮协助与卡片审计视图。 | | 深度研究 | `deep_research_write` 已经复用独立 Deep Research 的 session/job/event/source 持久化:Evidence Pack 转成选中且可追溯的素材,报告正文投影为工作流增量,完成后创建 Markdown artifact;取消也传给同一作业。前端可将完整 Markdown 调用既有 Word 导出接口下载,不改写原 artifact。 | 证据去重/质量评分、引用格式化、把 Deep Research 的多智能体计划暂停映射为工作流 `human_input`。 | | 前端可观测性 | 对话区、运行事件、节点状态已有基础;当前前端已开始将运行状态映射为节点高亮和连线动效。 | 计划摘要、待确认项、用户协助卡片、版本/重跑记录、产物引用的产品化界面。 | 说明:目前每个 Agent 节点默认使用独立线程 `wf-{run_id}-{node_id}`;只有显式 `threadMode: shared_run_thread` 才会共享 `wf-{run_id}`。这适合节点级隔离,但不能自动等价为“整个页面是一段持续对话”。 ## 4. 目标架构 ```text ┌──────────────────────────── Workflow Studio 前端 ────────────────────────────┐ │ 左:持续对话、计划摘要、用户协助卡片、节点定点反馈、产物预览 │ │ 右:可关闭的画布;按 SSE 状态高亮节点、激活连线、展示并发与等待状态 │ └────────────────────────────────────┬────────────────────────────────────────┘ │ HTTP + SSE ┌────────────────────────────────────▼────────────────────────────────────────┐ │ API / Run Gateway │ │ 创建运行、订阅事件、停止、恢复、提交协助信息、提出变更、局部重跑 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Planning Boundary(受约束的总控) │ │ Intent → TaskPlan;选择已发布模板/角色/能力;需要时请求用户补充信息 │ ├─────────────────────────────────────────────────────────────────────────────┤ │ Durable Workflow Runtime(唯一调度权) │ │ DAG、并发、输入绑定、权限、重试、暂停/恢复、取消、事件、版本、产物索引 │ ├───────────────┬──────────────────────┬───────────────────┬──────────────────┤ │ 专项 Agent │ 确定性节点 │ 人工协助节点 │ 报告写作适配节点 │ │ 收集/分析/QA │ HTTP/SQL/转换/合并 │ 表单/确认/选择 │ Deep Research │ ├───────────────┴──────────────────────┴───────────────────┴──────────────────┤ │ 数据、知识库、技能服务、深度研究任务、对象存储、运行/事件/产物数据库 │ └─────────────────────────────────────────────────────────────────────────────┘ ``` ### 4.1 职责边界 | 组件 | 负责 | 不负责 | | --- | --- | --- | | Planner/Controller Agent | 理解用户意图;输出受校验的计划;选择模板和角色;识别缺失输入;解释变更影响。 | 直接调度节点、绕过权限调用工具、任意构造可执行图。 | | 工作流运行时 | 根据图和快照调度;管理状态、并发、失败、暂停、恢复、取消、事件、审计。 | 猜测业务意图、生成报告正文。 | | 研究/分析 Agent | 在给定任务、输入和允许能力内收集或分析,输出结构化结果和引用。 | 修改全局计划或直接驱动其他节点。 | | 技能/工具节点 | 执行受控的 API、SQL、检索或计算,并返回可验证结果。 | 接收未经授权的模型任意参数。 | | Human Assist | 向用户收集缺失/确认信息,恢复同一 run。 | 新建无关联运行来“续聊”。 | | Report Writer | 根据 Report Spec 与 Evidence Pack 输出报告、引用和文件产物。 | 代替 Planner 选择业务流程。 | ## 5. 端到端运行流程 ### 5.1 首次发送 1. 用户在左侧对话框提交消息,前端创建 `planning session`,输入包含 `query`、附件/资源引用、可选上下文和当前工作流版本。 2. Planner 产生 2–3 个结构化 `WorkflowProposal`(每项含目标、角色、候选图、预估成本、缺失信息),而非只生成一段文字或静默启动一个模板。 3. 后端校验每个候选图是否只引用已发布的节点、角色、技能和数据源;不合法的候选图不能展示为“可执行”。 4. 前端在对话区展示候选流程选择卡片。用户点击卡片后,右侧画布加载该候选图;用户可拖拽节点、修改绑定、增删合法连接,再触发实时校验。 5. 用户点击“确认此流程并执行”后,后端冻结编辑后的 graph snapshot,创建正式 `workflow run`。这一步之后才开始收集、处理、分析、汇总和报告节点;可并行的节点并行执行。 6. 若确认前或运行中仍缺失关键条件,创建 `Human Assist` 暂停点,发送 `run.awaiting_input`;前端显示可填写的协助卡片。 7. 每一个状态变化和文本增量都写入事件流;前端即时更新对话消息、节点状态和画布连线。报告节点完成后发布正文、引用、文件/链接等 artifact。 ### 5.2 用户在运行中插话 用户消息必须区分为三种语义,不能全部当作“重新跑一遍”: | 用户动作 | 例子 | 后端处理 | | --- | --- | --- | | 补充输入 | “预算是 30 万,周期改成 4 周。” | 写入对应 Human Assist 或运行输入;使依赖该字段的节点继续/失效。 | | 定点反馈 | “竞品分析不要只看价格,补充渠道策略。” | 绑定到目标节点或输出 artifact,创建 `ChangeRequest`;仅重跑受影响的分析、合并、报告链路。 | | 改变任务 | “不要做广告方案了,改成用户留存诊断。” | Planner 评估影响;通常创建新的计划版本,必要时重新选择模板。 | 推荐产品动作是:消息气泡附带“发送给谁”的可选入口,默认交给 Planner 判断;在某个节点/输出旁点击“让该智能体调整”时,前端携带明确的 `targetNodeId` 或 `targetArtifactId`。没有指定目标的消息不应默认广播给所有 Agent。 ### 5.3 用户协助卡片 Human Assist 卡片必须代表持久化的等待状态,而不是普通聊天文本。它至少包含: - `runId`、`nodeRunId`、`requestId`; - 展示给用户的问题、字段定义、选项、校验规则、是否敏感; - 该输入会影响哪些下游节点; - 提交、稍后处理、取消运行三个动作。 点击提交时调用“恢复同一运行”的接口,带 `requestId` 与结构化答案。运行时写入 input binding,事件从 `awaiting_input` 变为 `node.resumed` / `node.running`,之后按已有 DAG 继续。绝不能用“新建一条普通聊天消息”替代恢复;那会丢失图快照、依赖、审计和已完成结果。 ### 5.4 停止、重试和局部重跑 - **停止**:取消 token 传到当前 Agent、工具和深度研究任务;run 标记为 `cancelled`,已完成 artifact 仍保留。 - **失败重试**:只在输入和上下文未变时重试原 node run,保留 `retryOf` 关系。 - **定点修改后重跑**:现有首个实现为 `POST /api/workflows/runs/{run_id}/feedback`,仅接受终态、无循环图中已完成的 `agent`/`skill` 节点。它从原 run 的冻结执行图计算下游闭包,创建带 `revisionOfRunId`/`feedback` 的新 run,复制闭包外已完成 node run;`feedback` 同时保留 affected/reused node ids 供历史和对话说明复用范围。反馈只加入目标节点的 `RunContext.env.nodeFeedback`,目标及下游重新流式执行,旧 run 不被覆盖。未传 `idempotencyKey` 时服务端按原 run、节点与文本生成稳定键。运行中流程应使用 `human_input` 或先停止;循环图、Deep Research/普通数据节点和副作用节点的定点改写仍需单独策略。 - **重新规划**:只允许 Planner 生成新的、经过校验的计划版本;用户可在 UI 看到“旧计划/新计划”差异。对于已经发出模型请求的运行中节点,前端不得声称把新文本插入了旧 prompt;首期采用“停止旧运行(保留审计)→ 原任务 + 新调整交给 Planner → 用户确认新版候选图”的安全语义。常规缺失字段仍优先走同一运行的 `human_input`。 ## 6. 关键数据契约(建议新增) 下面的对象是建议新增的业务协议,不表示当前接口已经提供。 ### 6.1 TaskPlan:总控输出 ```json { "schemaVersion": "1.0", "intent": "market_growth_diagnosis", "summary": "诊断销售下滑并给出广告与体验改进建议", "templateId": "growth-diagnosis-v1", "requiredInputs": [ { "key": "business_period", "label": "分析周期", "required": true }, { "key": "budget", "label": "投放预算", "required": false } ], "roles": ["sales_researcher", "voice_of_customer_researcher", "competitor_analyst", "strategy_analyst"], "allowedCapabilities": ["sales_sql", "feedback_search", "web_research"], "reportSpec": { "audience": "业务负责人", "format": "management_report", "sections": ["结论摘要", "证据", "原因分析", "行动建议", "风险与假设"], "citationRequired": true }, "confidence": 0.86, "needsHumanInput": false } ``` Planner 输出必须通过 JSON Schema / Pydantic 校验,并检查 `templateId`、`roles`、`allowedCapabilities` 是否都在租户已发布白名单中。不得以自然语言里的“调用某数据库/删除某文件”为依据直接执行。 ### 6.2 Evidence Pack:跨 Agent 的事实输入 所有研究 Agent 的输出先归一化为证据包,再给分析和报告节点使用。这样能减少“前一节点随手写一段话、下一节点盲目采信”的问题。 ```json { "items": [ { "id": "ev_01", "claim": "近四周新客转化率下降 12%", "source": { "type": "sql", "uri": "artifact://...", "retrievedAt": "2026-08-31T10:00:00Z" }, "excerpt": "...", "confidence": 0.92, "ownerNodeRunId": "nr_..." } ], "assumptions": ["竞品投放数据来自公开渠道,无法代表完整预算"], "gaps": ["缺少按城市拆分的销售数据"] } ``` ### 6.3 ChangeRequest:用户中途调整 ```json { "runId": "run_...", "baseRevision": 3, "kind": "node_feedback", "target": { "nodeId": "competitor_analysis" }, "message": "补充竞品渠道策略,不要只比较价格。", "attachments": [], "requestedBy": "user" } ``` 服务端返回影响范围(例如 `competitor_analysis → evidence_merge → report_writer`)和建议动作。涉及范围较大或成本较高时,先要求用户确认再执行。 ### 6.4 Report Spec:报告写作输入 报告写作节点的输入固定为 `ReportSpec + EvidencePack + 已确认的用户约束`。不要把整个聊天历史无筛选地塞进写作模型。 `ReportSpec` 至少包含受众、语言、篇幅、结构、格式、引用要求、语气、禁止项、产物格式(Markdown / DOCX / PDF)和质量标准。 ## 7. 图模型与模板策略 ### 7.1 第一阶段:候选流程优先,模板作为积木 Planner 从已发布的模板、节点角色和连接规则中组装 2–3 条候选流程,例如: - `quick-answer-v1`:少量检索 + 单 Agent 答复; - `growth-diagnosis-v1`:销售、VOC、竞品并行收集 → 策略分析 → 报告; - `market-research-v1`:多源研究 → 证据去重/校验 → 多视角分析 → 报告; - `deep-research-report-v1`:明确主题的研究与深度报告产出。 每张卡片至少展示:推荐理由、关键步骤、参与角色、数据源/技能、预计耗时与成本、尚缺输入、风险提示。默认给出“推荐方案”,但不自动启动;简单任务也至少显示一张可确认的轻量方案。 用户点击卡片后,候选图变成当前画布草稿。用户可以在受限的节点目录内修改节点、输入绑定和连接关系;每次修改调用现有图校验。确认时保存最终快照,再进入正式运行。这样既有智能规划,又不把图的控制权藏在模型内部。 候选方案在确认前不是 `workflow run`,建议使用独立、短生命周期但可恢复的 `WorkflowPlanningSession` / `WorkflowProposal` 持久化模型;不能在一个已启动的 run 中途直接替换整个 graph。Planner 的职责是产出受约束的候选图,而不是生成任意拓扑。 ### 7.2 后续阶段:受约束的动态子图 确实需要按任务动态增加并行研究视角时,可让 Planner 产出受限的 `PlanSpec`,由服务端编译为子图。要求: - 节点类型、角色、技能、连接规则来自白名单; - 设置最大节点数、最大并行数、最大预算和超时; - 编译后做 DAG/端口/类型/权限校验; - 保存最终 graph snapshot 与 plan revision,保证重放和审计; - 动态生成的是“已验证子图”,不是 Agent 直接操作数据库或调度器。 ## 8. 运行状态与流式协议 ### 8.1 状态模型 现有运行状态可继续作为基础:`queued`、`running`、`awaiting_input`、`completed`、`failed`、`cancelled`。节点状态要至少支持 `queued`、`running`、`completed`、`failed`、`awaiting_input`、`cancelled`。 建议为 revision 增加展示级状态:`stale`(旧版本保留但不再作为最新结果)、`invalidated`(输入变化导致必须重跑)、`reused`(在新版本中复用旧结果)。如需持久化,须在 schema migration 与 API 中显式加入,不能只在前端猜测。 ### 8.2 SSE 事件约定 现有事件链路应继续作为单一事实来源:运行和节点事件先持久化,再由 SSE 推送。前端断线后按最后事件序号恢复,不依赖内存中的临时 token。 建议在既有 `run.*`、`node.*`、`node.output.delta`、`artifact.*`、`run.awaiting_input` 之上增加: | 建议事件 | 含义 | 前端行为 | | --- | --- | --- | | `plan.ready` | Planner 产生并校验了 TaskPlan | 显示计划摘要、角色、待补充信息。 | | `plan.rejected` | 计划违反模板/能力/权限约束 | 展示可理解的原因,提示重新输入或人工选择。 | | `run.revision.created` | 用户变更创建了新版本 | 切换到新版本,保留旧版本可查看。 | | `node.invalidated` | 节点结果因变更失效 | 画布标记待重算,显示影响来源。 | | `node.reused` | 新版本复用了节点产物 | 展示复用,不播放“正在执行”的假动画。 | | `report.delta` | 写作服务持续输出报告正文 | 追加到报告消息,同时保留 node output 增量。 | 事件最小公共字段建议为:`eventId`、`seq`、`runId`、`revision`、`nodeRunId?`、`type`、`timestamp`、`payload`。`seq` 必须在一个 run/revision 范围内单调递增。 ### 8.3 前端实时表现 - `node.running`:节点高亮、对应入边/出边显示流动效果,左侧展示该节点的增量消息; - `node.output.delta`:立即写入该节点对应的 assistant 消息,使用节流批量渲染,不能等 `node.completed`; - `run.awaiting_input`:停止错误的“加载中”图标,显示协助卡片; - 并行节点:同时高亮多个节点,右侧执行摘要展示完成数量; - `completed/failed/cancelled`:停止动效并给出明确终态,不让旋转图标停在页面上。 画布可以被用户关闭以让对话区扩大,但不得卸载运行订阅或丢弃节点状态;重新打开时应从事件状态恢复。 ## 9. 后端改造建议 ### 9.1 新增节点类型与适配器 | 节点类型 | 输入 | 输出 | 实现建议 | | --- | --- | --- | --- | | `task_planner` | `query`、上下文、可用模板目录 | `TaskPlan` 或 Human Assist 请求 | 在 Agent Runner 之上增加严格结构化输出与服务端白名单校验。 | | `evidence_normalizer` | 多个研究结果 | `EvidencePack` | **已实现**:确定性转换、上游引用校验和长度上限;必要时后续增加独立事实校验节点。 | | `analysis_agent` | `TaskPlan`、Evidence Pack、角色提示 | 结构化分析与引用 | 继续复用 Lead Agent,但限制输入、技能和线程。 | | `human_assist` | 字段/问题/校验规则 | 已确认的结构化答案 | 复用现有 pause/resume,补全 requestId、表单 schema 与输入绑定。 | | `deep_research_write` | Report Spec、Evidence Pack、上下文 | 流式正文、引用、artifact | **已实现**:不经 HTTP 自调用,Evidence Pack 固化成选中素材后复用 `regenerate` Job;实时 `report_delta` 与持久 `report_chunk` 去重投影为 `node.output.delta`,取消转发给同一 Job。暂不嵌套 Deep Research `multi_agent` 的计划暂停。 | | `report_qa` | 草稿、引用、质量规则 | 通过/问题列表/修订建议 | 先用确定性规则,必要时再加审校 Agent。 | `callable_skill` 当前仍会返回“未可执行”的显式错误。若要用于这套流程,必须先建立技能注册表、输入 schema、权限校验、超时/取消、结果 schema 和审计;不能仅在 Planner 文本中列出技能名称。 ### 9.2 已落地接口与后续接口 当前已实现的候选规划接口如下。候选图仅能使用当前草稿中可用的 Agent 节点及固定的安全拓扑;服务端校验图和资源目录,并以 `graphRevision` 防止两个页面互相覆盖编辑。`POST .../runs` 是唯一创建正式执行的动作;未选择、校验失败或已绑定到其他 run 的候选都会被拒绝。 ```text POST /api/workflows/{workflow_id}/runs 对已选择的 graph snapshot 创建正式运行;body 传 planningSessionId + proposalId。 POST /api/workflows/{workflow_id}/planning-sessions 根据用户 query 生成候选 WorkflowProposal;返回会话、候选图和推荐原因。 GET /api/workflows/planning-sessions/{session_id} 读取可恢复的候选规划会话与选择/确认状态。 POST /api/workflows/planning-sessions/{session_id}/proposals/{proposal_id}/select 选择一条候选图,供右侧画布预览和编辑。 PATCH /api/workflows/planning-sessions/{session_id}/proposals/{proposal_id}/graph 保存用户在画布中编辑后的候选图;后端执行拓扑、端口、类型和资源校验。 ``` 以下接口仍是后续阶段,尚未把建议对象落地为公开 API: ```text GET /api/workflow-runs/{run_id}/events?after_seq={seq} SSE;支持断线续传与快照同步。 GET /api/workflow-runs/{run_id}/plan 获取当前 TaskPlan、revision 和待补充项。 POST /api/workflow-runs/{run_id}/human-requests/{request_id}/responses 提交用户协助卡片答案并恢复同一 run。 POST /api/workflow-runs/{run_id}/change-requests 创建定点反馈、补充输入或重新规划请求;返回影响范围和确认要求。 POST /api/workflow-runs/{run_id}/revisions/{revision}/apply 在需要确认时应用已计算的变更计划。 POST /api/workflow-runs/{run_id}/node-runs/{node_run_id}/retry 对原输入的失败节点重试;与“变更后的局部重跑”区分。 ``` 已落地的定点反馈接口使用现有运行命名空间,而不是上面的未来 `ChangeRequest` 协议: ```text POST /api/workflows/runs/{run_id}/feedback body: { nodeId, message, idempotencyKey? } 201: 新 revision run(revisionOfRunId、affectedNodeIds、reusedNodeIds) ``` 所有写接口都应携带租户/空间、操作人、幂等键与权限上下文。对于存在副作用的技能(写库、发送消息、外部发布),需要独立确认策略,不能因为用户说“继续”就自动执行。 ### 9.3 计划版本与局部重跑 长期建议新增逻辑对象:`WorkflowRunRevision`、`ChangeRequest`、`HumanRequest`。当前首个实现尚未新增表:revision 直接是一个普通 `workflow_runs` 行,`context.revisionOfRunId`、`context.feedback` 和 `retry_of_run_id` 指向源运行。一次用户修改的完整目标处理为: ```text ChangeRequest → Planner 评估影响(或规则引擎根据输入绑定计算) → 生成 proposed revision + affected nodes → 必要时要求确认 → 固化 revision、复制/复用可用产物 → 使受影响节点及其下游失效 → 从最早失效节点继续调度 ``` 不要就地覆盖旧 node run 的输入或输出。旧 revision 仍需可查看,才能解释“为什么报告改了”、支持回滚并满足审计。 ## 10. 前端交互规格 ### 10.1 页面布局 - 左侧为默认主工作区:持续对话、候选流程选择卡片、运行消息、协助卡片和报告预览;宽度可拖动,用户关闭画布后自动扩展。 - 右侧为可关闭的流程图:展示当前 graph snapshot 和执行状态;默认不抢占对话阅读空间。 - 执行详情为辅助信息,不能替代对话中的实时反馈。 - 输入框内使用图标发送按钮;发送中/等待人工输入/取消中有清晰且无歧义的状态。 ### 10.2 消息显示模型 消息不要只以 `user/assistant` 两类存储。建议前端 ViewModel 支持: - `user_message`:原始任务、补充、定点反馈; - `planner_message`:已理解的目标、选用模板、计划摘要; - `agent_stream`:某一节点的流式过程和最终摘要; - `human_request`:可提交的协助卡片; - `system_event`:开始、停止、失败、重跑、复用等可读状态; - `artifact`:报告预览、下载文件、引用和版本信息。 每个消息应带 `runId`、`revision`、`nodeRunId?` 和 `eventSeq`,SSE 重连时以这些键去重、补齐并排序。 ### 10.3 对话动作规则 - 默认“发送”创建任务或把补充内容交给 Planner。 - Planner 返回候选流程卡片而非直接执行;点击卡片加载右侧候选图,只有点击“确认并执行”才创建 run。 - 候选图编辑期间可以切换到另一张卡片或重新让 Planner 生成方案;未确认的方案不会消耗执行型技能预算。 - “发送给某智能体”是显式定点动作,显示目标名称和影响范围。 - 点击 Human Assist 卡片只恢复原 run;禁止额外创建 run。 - 点击节点可筛选该节点在左侧产生的消息、工具调用和产物。 - 在报告中选择一段文字并要求修改时,生成指向该 artifact/section 的 `ChangeRequest`。 - 终态后的新问题默认新建 run;“基于这次结果继续”则显式带 `parentRunId` 与所选 artifact,不能靠隐藏共享线程推断。 ## 11. 深度研究报告接入 Deep Research 是长时任务,应该保持其现有作业模型。工作流节点只做以下适配: 1. 提交 Job:将 `ReportSpec`、`EvidencePack`、可公开检索范围和已确认上下文提交给 Deep Research 服务; 2. 订阅 Job:把研究进度、正文增量、引用和文件状态映射成 run/node 事件; 3. 取消 Job:run 被停止或 revision 失效时向下传递取消; 4. 固化产物:报告正文、引用清单和生成文件写入 artifact 存储,供后续 QA、用户修改和下载复用; 5. 质量门:未达到引用/结构/敏感信息规则时,不直接标记为最终成品。 传给写作管线的重点是已筛选的证据与明确的报告要求,不是多个 Agent 的原始长对话拼接。这样才可控制上下文长度、降低幻觉、保留来源归因。 ## 12. 实施顺序 ### 阶段 A:先打通当前消息与运行链路(部分完成) 1. **已完成**:明确普通发送(候选规划)、指定 Agent、正式运行确认三种 API 语义; 2. **已完成**:修复用户 `query` 到 Agent 节点 prompt/input binding 的链路,支持 `inputBindings` 和目标 Agent 投影; 3. **已完成**:运行中的节点状态和 `node.output.delta` 映射到前端,终态清除 loading; 4. **已完成**:候选流程卡片、右侧画布加载/编辑、图校验、确认后冻结快照并创建唯一正式 run; 5. **已完成**:Human Assist 卡片按 `formSchema` 渲染、提交结构化值/自然语言补充,并用一次性令牌恢复原 run; 6. **待完成**:单 Agent、两并行 Agent、人工暂停工作流的浏览器端端到端验收。 ### 阶段 B:模板化多智能体研究(进行中) 1. **部分完成**:已有 Agent/技能/数据源权限目录;仍需补全 Role Catalog 的角色元数据与输入输出 schema; 2. **部分完成**:受约束 Planner 已只对固定安全策略排序和组图;尚未有独立 `task_planner` 节点类型; 3. **部分完成**:已引入 `EvidencePack` 与 `evidence_normalizer`,并接入并行调研候选图;仍需证据去重、质量评分和更丰富的多视角模板; 4. **已完成**:将 Deep Research 包装成 `deep_research_write` 节点,并接入并行调研候选图(`调研 → Evidence Pack → 综合分析 → 深度研究报告`);相同主题、证据快照和写作配置会复用同一持久化 Job,任一输入变化都不会复用旧报告; 5. **部分完成**:报告 Markdown 已作为 run artifact,并通过工作流 SSE 流式显示;前端可直接调用统一 Word 导出接口下载正式 `.docx`,不改写制品;仍需引用质量/去重和浏览器端端到端验收。 ### 阶段 C:可控的人机协同与修订 1. **部分完成**:已实现终态、无循环图的完成 Agent/Skill 的定点反馈;通过下游闭包重跑、上游 node-run 复用和稳定幂等键保留审计关系; 2. **部分完成**:运行中输入新方向已有安全的“停止旧 run → 原任务 + 调整重新规划”前端闭环;仍需 `ChangeRequest` / 独立 revision 表、同一运行内的局部调整、循环图、Deep Research/有外部副作用节点的专门确认策略,以及产物版本对比; 3. **部分完成**:对话区已在完成的智能体消息旁呈现“调整此分析”,提交后切换到新 revision run;仍需在历史/画布中显式展示复用与版本差异; 4. **部分完成**:已有取消、重试、断线重连、重复反馈的回归测试;仍需浏览器端端到端验收和多用户/有副作用技能覆盖。 ### 阶段 D:受约束的动态子图(可选) 仅当固定模板无法覆盖真实任务后再实施:引入 `PlanSpec` 编译器、配额限制、拓扑/权限校验和动态子图审计。不要把该阶段作为修复当前“消息走不通”的前置条件。 ## 13. 验收标准 ### 13.1 功能验收 - 用户发送一句任务后,任一正在运行 Agent 在数秒内出现状态变化,首个文本增量能在模型完成前显示; - 并行 Agent 同时高亮,连线动画只对应真实的 `running` 状态; - 用户补充预算/周期等字段后,能恢复同一 run,而非创建新 run; - 用户对某分析节点提出修改后,只有该节点、其下游合并和报告节点重跑,其他收集结果可复用; - 报告包含可回溯证据/引用,且可下载为 artifact; - 停止运行会取消进行中的子任务并让所有 loading 进入明确终态; - SSE 断开重连后,消息、节点状态和报告正文不重复、不缺失、顺序正确。 ### 13.2 安全与可运维验收 - Planner 无法调用未在当前空间授权的技能、数据源或模板; - 每一项外部副作用都有操作者、授权来源、输入摘要、输出和事件审计; - 每个 run/revision 都可还原 graph snapshot、计划、节点输入输出、人工提交和 artifact; - 并发数、单次运行成本、超时、重试次数、报告任务数量均有配额; - 失败事件向用户展示可理解原因,详细堆栈仅在受控诊断日志中可见。 ## 14. 最小闭环建议 先不要尝试让一个总控 Agent 任意编排所有节点。最小可用闭环应为: ```text 对话输入 → task_planner(选择固定“研究报告”模板) → [资料收集 Agent A || 资料收集 Agent B] → evidence_normalizer → analysis_agent → human_assist(仅在关键事实缺失时) → deep_research_write → report_qa / artifact 输出 ``` 这个闭环能直接验证当前最关键的产品承诺:用户输入确实进入节点、过程实时可见、用户可在中途补充或纠偏、最终能得到来源可追溯的报告。稳定后再扩展角色数量、技能生态和动态图能力。