feat(maf): Phase 5 - action coordinator, approval flow, frontend MAF roundtable pages
- Backend: action_coordinator, capability_snapshot, event_normalizer, tool_executor updates - Backend: approved_tool_executor with write guard, action leases, migration script - Frontend: maf-roundtable module (API client, event timeline, approval cards, fact flow panel) - Frontend: MafRoutes, MafSessionsPage, MafRunDetailPage - Tests: action_leases, migration_phase5, phase5_entry_e2e, real_write_e2e/http_e2e - Docs: update implementation plan Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
1 parent
21c4c898e7
commit
f82363d81f
55 files changed
+6304
-167
No files matched your search
@@ -1,17 +1,87 @@
|
||||
# Microsoft Agent Framework 多智能体会商对照页实施计划
|
||||
|
||||
> 文档状态:实施中;阶段 1(独立后端骨架与持久化)已验收通过
|
||||
> 更新时间:2026-08-01
|
||||
> 文档状态:实施中;已按当前工作区代码重新盘点,阶段 5 安全闭环处于收口验收,阶段 4 动态会商仍未达到退出标准
|
||||
> 更新时间:2026-08-02
|
||||
> 目标版本:实验性独立功能,不替换现有多智能体会商
|
||||
> 建议页面名称:`MAF 会商(实验)`
|
||||
|
||||
## 0. 当前实施状态与前后端隔离决议
|
||||
|
||||
### 0.1 已完成并验收的阶段 1
|
||||
### 0.1 代码盘点结论(以 2026-08-02 当前工作区为准)
|
||||
|
||||
新的后端骨架已经独立落在 `/api/maf-roundtable` 及 `maf_roundtable_*` 专用表中;会话、运行、事件、审批、用户隔离、启动/取消原子事务与配置校验均不复用旧会商的持久化状态。当前验收证据为:78 项 MAF 后端回归测试通过,且 Harness → App 导入边界检查通过。
|
||||
本节的状态以当前 `master-dev`、尚未提交的 MAF 改动和本次实际运行结果为准,不沿用同事口头的阶段编号或测试数量。`已实现`不等于`退出验收通过`;只有满足本阶段退出标准、测试证据完整且没有 P0/P1 缺口时才能进入下一阶段的正式验收。
|
||||
|
||||
阶段 1 完成并不表示功能已对用户开放:`maf_roundtable.enabled` 继续默认关闭,直到后续 MAF 编排和新前端页面均完成验收。
|
||||
| 阶段 | 当前状态 | 已有代码/证据 | 尚未满足的退出条件 |
|
||||
|---|---|---|---|
|
||||
| 0 依赖 Spike | 部分完成 | `agent-framework-core` 已锁定到 lock 中的 `1.13.0`;真实 SDK `WorkflowBuilder` 路径可由测试运行。 | 尚无当前部署模型的 OpenAI 兼容流式实测、离线 wheelhouse 全新安装实测和正式 Spike 记录。 |
|
||||
| 1 独立后端骨架 | 代码完成 | `/api/maf-roundtable`、独立 `maf_roundtable_*` 表、事务化启动/取消、事件序号、用户隔离、管理员只读诊断均已实现。 | 本工作区缺少文档提及的 `tests/test_harness_boundary.py`,需在 CI 或恢复该用例后补一份边界验证证据。 |
|
||||
| 2 DeerFlow Agent Adapter | 代码完成,集成验收待补 | 独立 thread、用户 principal、运行参数、SSE 标准化、事件脱敏、取消级联、seat-run 持久化均已实现;相关单测覆盖。 | 尚未用已部署模型和真实 MCP/技能完成一条从 API 到 DeerFlow Runtime 的人工验收记录。 |
|
||||
| 3 固定流程编排 | 代码完成,测试通过 | `WorkflowBuilder` 的 planner → 并行席位 → 交叉审查 → 审批 → finalizer、事实账本、格式修复、checkpoint/恢复与 `execution_stage` 身份均已实现。 | 需在真实模型/真实能力快照下完成一次演示验收;不阻塞阶段 5 的安全收口。 |
|
||||
| 4 动态 Group Chat | 部分实现,不能验收 | `group_chat` 模式能走真实 SDK 工作流路径,且会写 `manager.decision` 事件。 | 当前实质是 `WorkflowBuilder` 的单次 round-robin:没有主持人 Agent selector、没有多轮同席位发言策略、没有完整的总超时/弱模型收敛测试;详见阶段 4。 |
|
||||
| 5 外部写入与审批 | 框架闭环完成,UAT/部署待输入 | 已有可信工具元数据、WriteGuard、加密参数、审批超时、服务端派生的目标租约、原子一次执行、`unknown` 失败关闭、审计 API、真实 `ToolNode` outbox 及 HTTP 决策→恢复全链路测试。 | 尚未指定 UAT 写入工具、最小权限凭据和核验/补偿协议;生产部署尚未注入 `MAF_ACTION_SECRET_KEY`。 |
|
||||
| 6 前端工作台 | 原型已存在,未按新约束验收 | 独立 `/page/maf/*` 路由、健康门、会话/运行页、纯轮询、审批卡、事件代次隔离已实现;前端逻辑测试 19 项通过。 | 现有可视组件主要仍使用旧的本地 shadcn/Radix 封装,未改为用户指定的 `tdesign-react`;仍直接引用旧会商目录中的脱敏 hook;恢复/失败重试和组件级 API 验收未完成。 |
|
||||
| 7 对比评测 | 未开始 | 无。 | 依赖阶段 4、5、6 的正式验收。 |
|
||||
| 8 测试、离线打包与灰度 | 未开始 | 无。 | 依赖可验收版本。 |
|
||||
|
||||
本次重新运行的证据:
|
||||
|
||||
- 后端安全闭环重点用例:`293 passed in 140.10s`(包含真实入口 ToolNode/outbox、能力快照、WriteGuard、审批过期与目标租约、旧 DeerFlow 回归)。
|
||||
- 后端编排重点用例:`40 passed in 5.46s`(真实 SDK structured/group_chat 路径、Agent Adapter、阶段 3 主持人流程)。
|
||||
- 前端 MAF 逻辑用例:`19 passed`;`pnpm build` 通过。
|
||||
- 全量 `test_maf_*.py` 已在无短时命令限制的终端完成,最终结果为 `293 passed in 140.10s`;PowerShell 下使用文档中的文件枚举方式展开测试文件。
|
||||
|
||||
阶段 1 完成并不表示旧会商被替换。当前配置已打开新的 MAF 功能开关;前端入口由健康检查和权限控制。旧 DeerFlow、旧 roundtable、AI 写作不携带 `maf_run_id`,因此不进入 MAF WriteGuard 分支。
|
||||
|
||||
### 0.3 阶段 5:真实工具、技能与外部写入审批闭环(当前收口)
|
||||
|
||||
本阶段已补齐以下安全边界:
|
||||
|
||||
- `use-maf-events.ts` 为每次 `runId`、`enabled`、`polling`、`resetSignal` 变化分配请求代次;旧请求返回后不能污染新 run,终态补拉不会被旧请求阻塞。
|
||||
- 能力快照的工具副作用元数据只从服务端读取,优先级为 MAF 专用精确工具名配置、已有 `ToolConfig.extra`、内置白名单、保守默认 `write/R3`。浏览器、会话请求和模型输出不能提供或覆盖这些字段。
|
||||
- 生产写工具登记时,必须在同一服务端元数据中配置 `target_key_fields`(稳定的顶层租户/业务对象字段)和可选 `target_key_namespace`;这些字段只参与服务端稳定哈希,禁止直接提交 `target_key`。未登记或无法识别对象的写操作共用保守串行目标,并在 `unknown` 后保持人工核验屏障。
|
||||
- 当前真实发现的只读 MCP 工具名为 `weknora-retrieval_weknora_list_knowledge_bases` 和 `weknora-retrieval_weknora_search`,已按精确名称登记为 `read/R0`;不按 server 名或名称前缀猜测。
|
||||
- 测试环境提供真实 LangGraph `ToolNode` 写工具 `maf_test_outbox_write`,只写临时 outbox;它经过真实 WriteGuard、加密参数、审批、`execute_approved_tool` 和一次性执行器。生产外部写入目标仍需业务方指定,不能用检索 MCP 代替,也不能擅自猜测业务系统。
|
||||
- `write_guard.enabled=true` 后,缺少 `MAF_ACTION_SECRET_KEY` 时只读工具和技能仍可工作,外部写入在执行前失败关闭;健康检查只返回 `enabled`、`ready`、`secret_configured` 和状态码,不返回密钥。
|
||||
|
||||
本轮框架代码已完成阶段 5 的可自行实现项;下列项目必须由业务方/运维补齐后才能将阶段 5 标记为完整完成:
|
||||
|
||||
- `maf_test_outbox_write` 是测试专用写工具,已经证明真实 LangGraph `ToolNode` 与一次性执行器可用,但不等于已接入业务系统。
|
||||
- 当前机器未注入生产 `MAF_ACTION_SECRET_KEY`,健康状态会显示 `missing_secret`;这符合失败关闭设计,但不能用于生产写入验收。
|
||||
|
||||
上线前必须由部署环境注入 `MAF_ACTION_SECRET_KEY`,不得写入仓库、`config.yaml`、前端、事件、checkpoint 或模型上下文。当前测试验收命令为:
|
||||
|
||||
```powershell
|
||||
$env:PYTHONPATH="."
|
||||
$env:MAF_ACTION_SECRET_KEY="仅测试环境临时值"
|
||||
$mafTests = Get-ChildItem tests -Filter "test_maf_*.py" | ForEach-Object FullName
|
||||
uv run --extra maf pytest $mafTests -q -W error
|
||||
uv run ruff check app/maf_roundtable packages/harness/deerflow
|
||||
```
|
||||
|
||||
### 0.3.1 同事 A:MAF-05-03A / 03B / 04A / 08A 收口记录
|
||||
|
||||
本轮已完成前阶段 5 的代码与自动化验收项,但按约定仍不将阶段 5 标记为最终验收完成:真实 UAT 写入系统、测试租户、最小权限凭据、核验 API/补偿协议以及生产环境密钥注入仍待业务方和运维提供。
|
||||
|
||||
- `MAF-05-03A`:Action 服务层使用公开白名单 DTO;`target_key` 与 `idempotency_key` 仅留在持久层和内部仲裁路径,不能通过两个 actions GET 接口、事件或前端类型返回。目标键只读取服务端登记的稳定标量字段,并使用 `MAF_ACTION_SECRET_KEY` 做域隔离 HMAC-SHA-256;缺少密钥时真实写入失败关闭。
|
||||
- `MAF-05-03B`:`scripts/migrate_maf_roundtable_phase5.py` 按数据库方言生成 DDL:PostgreSQL 使用 `TIMESTAMP WITH TIME ZONE`,MySQL/MariaDB 使用 `DATETIME(6)`,SQLite 使用 `DATETIME`。迁移可重复执行,表、缺失索引和可安全补齐的列会自动补齐;已覆盖 SQLite 实际迁移以及三种方言 DDL 测试。
|
||||
- `MAF-05-04A`:Gateway lifespan 启动和关闭 MAF 专用审批过期扫描任务,间隔由 `maf_roundtable.approval_scan_interval_seconds` 配置。扫描使用已有条件式过期 CAS,然后只对受影响 run 调用 `dispatcher.resume()`;普通审批 GET 保持只读,决定/恢复仍在操作前执行失败关闭过期检查。
|
||||
- `MAF-05-08A`:入口级测试从 HTTP 创建 session/run 开始,确定性假实现只位于模型边界;真实 Agent Runtime、WriteGuard、LangGraph ToolNode、加密参数和 outbox 均参与执行。覆盖 HTTP 审批后恰好一次写入,以及同目标并发时第二个 run 的 `waiting_target_lease` 与显式 resume。
|
||||
|
||||
本轮证据:全部 `test_maf_*.py` 共 `293 passed`;阶段 5 定向回归 `15 passed`;`git diff --check` 通过。仓库现有的全目录 Ruff 基线仍有与本轮无关的历史问题,提交前需在 CI 中单独清理;本轮新增/修改文件已做定向检查。
|
||||
|
||||
### 0.4 下一批开工顺序与责任边界
|
||||
|
||||
当前应正式进入**阶段 5 收口**;阶段 4 的动态会商可与其中不依赖业务系统的任务并行。不要把阶段 6 原型继续扩展成正式页面,直到阶段 5 的动作一致性契约固定。
|
||||
|
||||
| 工作包 | 对应任务 | 难度 | 是否可立即开始 | 交付边界 |
|
||||
|---|---|---:|---|---|
|
||||
| WP-F1 目标一致性 P1 收口 | `MAF-05-03A`、`MAF-05-03B` | D4/D5 | 已完成 | 已封闭 `target_key`/内部幂等键公开边界,并使 Phase-5 迁移兼容 PostgreSQL/MySQL;真实 UAT 目标仍由 WP-F3 负责。 |
|
||||
| WP-F2 审批恢复验收补强 | `MAF-05-04A`、`MAF-05-08A` | D4/D5 | 已完成 | 已完成主动过期、并发/重启补扫,以及从真实工作流入口生成审批到 HTTP 决策、ToolNode/outbox 的全链路验收。 |
|
||||
| WP-F3 真实 UAT 工具 | `MAF-05-05`、`MAF-05-09`、`MAF-05-10` | D5 | 需业务方输入 | 仅在拿到目标系统、最小权限凭据、幂等与查询核验协议后实施;这是唯一不能自行假设的工作包。 |
|
||||
| WP-E 动态会商 | `MAF-04-01` ~ `MAF-04-07` | D5 | 可以并行 | 真实多轮 selector、上下文/终止状态机和弱模型收敛测试;不得修改阶段 5 的 Action Coordinator。 |
|
||||
| WP-G 前端重构准备 | `MAF-06-00` | D3 | 可以并行 | 仅拆除对旧会商 hook 的直接依赖、固定 API view-model 和测试基线;TDesign 页面重构等阶段 5 契约稳定后开始。 |
|
||||
|
||||
WP-F1、WP-F2 与 WP-E 必须分别使用独立分支/提交;公共 `config.yaml`、Gateway 注册和前端路由由集成人统一合并。WP-F3 进入开发前需由业务方书面确认第一个写入目标,缺少该信息时应保持阻塞状态而不是接入猜测的 MCP。
|
||||
|
||||
### 0.2 新前端页面的强制隔离原则
|
||||
|
||||
@@ -42,7 +112,7 @@
|
||||
|
||||
### 2.1 本期必须实现
|
||||
|
||||
- 新页面:`/page/strategy/qa/maf-roundtable`。
|
||||
- 新页面:`/page/maf/*`(当前已落地为独立顶级菜单,不嵌入旧会商页)。
|
||||
- 两种 MAF 编排模式:
|
||||
- `structured`:专家并行分析 → 交叉审查 → 主持人综合。
|
||||
- `group_chat`:主持人动态选择下一位发言人,多轮讨论后收敛。
|
||||
@@ -79,7 +149,7 @@
|
||||
|
||||
### 2.4 新前端与新后台的对接边界
|
||||
|
||||
新前端页面固定使用独立路由 `/page/strategy/qa/maf-roundtable`,并且只允许请求以下新接口前缀:
|
||||
新前端页面固定使用独立路由 `/page/maf/*`,并且只允许请求以下新接口前缀:
|
||||
|
||||
```text
|
||||
GET /api/maf-roundtable/health
|
||||
@@ -278,6 +348,18 @@ flowchart LR
|
||||
|
||||
快照用于审计和复现,不代表运行期间复制工具实例。
|
||||
|
||||
MAF 的副作用分类是服务端可信配置,不由上述请求体或模型生成的能力描述决定。部署配置使用实际运行时工具名作为键,例如:
|
||||
|
||||
```yaml
|
||||
maf_roundtable:
|
||||
tool_metadata:
|
||||
weknora-retrieval_weknora_search:
|
||||
side_effect: read
|
||||
risk_level: R0
|
||||
```
|
||||
|
||||
未登记工具保持保守的 `write/R3`,避免未知外部工具被误放行。技能可以继续使用,但技能触发的实际外部副作用必须落到已分类工具调用,不能绕过 WriteGuard。
|
||||
|
||||
### 6.2 技能接入
|
||||
|
||||
- 继续使用 Agent 当前技能白名单。
|
||||
@@ -313,6 +395,8 @@ Action Coordinator 只负责执行一致性,不替代工具:
|
||||
|
||||
这套分级不禁止外部写入,而是保证它在不同运行策略下可控、可恢复、可审计。
|
||||
|
||||
当前已完成的可执行验收工具是测试专用 `maf_test_outbox_write`(`R2/write`),副作用限制在 `MAF_E2E_OUTBOX_DIR` 指定的临时目录。生产验收还需要业务方明确目标系统、测试租户、最小权限凭证和幂等/核验接口;在此之前不得宣称已经完成生产业务写入接入。
|
||||
|
||||
### 6.4 沙箱与产物冲突
|
||||
|
||||
- 一个席位一个 thread,一个 thread 一个沙箱上下文。
|
||||
@@ -559,7 +643,7 @@ offline-backend-20260512/backend/
|
||||
|
||||
### 10.0 独立前端模块、路由和状态
|
||||
|
||||
新增目录固定为 `frontend-web/src/maf-roundtable/`,其 API client 只能封装 `/api/maf-roundtable/*`。新页面根组件为 `MafRoundtablePage.tsx`,路由仅新增 `/page/strategy/qa/maf-roundtable`;不得替换、重命名、迁移或修改旧 `multi-agent-roundtable` 路由及其页面组件。
|
||||
新增目录固定为 `frontend-web/src/maf-roundtable/`,其 API client 只能封装 `/api/maf-roundtable/*`。当前页面根路由为 `MafRoutes.tsx`,路由仅新增 `/page/maf/*`;不得替换、重命名、迁移或修改旧 `multi-agent-roundtable` 路由及其页面组件。
|
||||
|
||||
入口展示前先读取 `GET /api/maf-roundtable/health`:`enabled=false` 时隐藏入口并禁止创建会商;开启后页面必须明确展示“实验版 / 独立后端”标识。TanStack Query 的 key 使用独立命名空间,例如 `['maf-roundtable', 'sessions', ...]`,不得复用任何旧 `roundtable`、`draft` 或 `job` key。所有页面本地状态、事件 reducer、轮询/补拉游标、取消控制器和历史恢复逻辑也必须归属于 MAF 模块。
|
||||
|
||||
@@ -745,15 +829,17 @@ frontend-web/src/maf-roundtable/
|
||||
前置依赖:阶段 2;建议先完成阶段 3 以复用事实账本和恢复机制
|
||||
主要评价点:弱模型条件下能否收敛、上下文是否准确、硬终止是否可靠
|
||||
|
||||
当前代码状态:`workflow_factory.py` 已为 `group_chat` 建了真实 MAF `WorkflowBuilder` 图,`CoordinatorExecutor` 会写 `manager.decision`,并有一条 SDK 路径测试。但它目前按 round-robin 让每个席位最多发言一次;这只是可运行的占位编排,不是本阶段承诺的动态多轮会商。
|
||||
|
||||
任务:
|
||||
|
||||
- [ ] `MAF-04-01`(D3)使用 `GroupChatBuilder` 建立主持人和参与席位。
|
||||
- [ ] `MAF-04-02`(D4)实现确定性 selector 与主持人 Agent selector 两种选择方式。
|
||||
- [ ] `MAF-04-03`(D4)实现最大轮次、连续发言限制、总超时和单席位超时。
|
||||
- [ ] `MAF-04-04`(D5)实现完整上下文同步、长工具输出裁剪、引用保真和 token 预算。
|
||||
- [ ] `MAF-04-05`(D4)实现主持人完成判定、schema 校验和结构化终稿。
|
||||
- [ ] `MAF-04-06`(D3)把主持人调度原因写入 `manager.decision` 事件。
|
||||
- [ ] `MAF-04-07`(D5)构造弱模型不结束、错误选人、重复发言等测试并保证工作流可收敛。
|
||||
- [ ] `MAF-04-01`(D4)改为使用锁定 MAF 版本实际提供的 Group Chat 编排 API;若该版本没有名为 `GroupChatBuilder` 的公开类,必须在设计说明中给出等价的官方 API、版本和最小可运行证明。禁止把手写 `WorkflowBuilder` 分支称为已完成的 Group Chat。
|
||||
- [ ] `MAF-04-02`(D5)实现两种 selector:可复现的确定性 selector,以及由主持人 Agent 根据已验证事实账本选择下一发言人的 selector。两者均须验证候选席位、返回结构和失败降级,不能相信模型随意返回的 agent id。
|
||||
- [ ] `MAF-04-03`(D4)实现最大轮次、连续发言上限、总超时和单席位超时;状态必须持久化到 checkpoint,恢复后继续计数而不是重置。
|
||||
- [ ] `MAF-04-04`(D5)以事实账本和摘要引用作为群聊输入来源,保留已执行/待审批/失败动作语义;超长工具结果只传播摘要和可追溯引用,并执行明确 token/字符预算。
|
||||
- [ ] `MAF-04-05`(D4)由主持人显式输出完成判断与结构化终稿;不合法输出仅允许一次定向修复,仍失败时走确定性降级并留下原因事件。
|
||||
- [x] `MAF-04-06`(D3)已写入 `manager.decision` 事件;后续须把现有 `round_robin` 原因扩展为 selector 类型、候选集、拒绝原因和终止依据。
|
||||
- [ ] `MAF-04-07`(D5)新增弱模型不结束、幻觉席位、重复选人、席位超时、空输出和恢复后继续轮次的测试;至少包含一次真实 SDK 的多轮(同一席位可在合规策略下再次发言)验收。
|
||||
|
||||
退出标准:
|
||||
|
||||
@@ -771,14 +857,22 @@ frontend-web/src/maf-roundtable/
|
||||
|
||||
任务:
|
||||
|
||||
- [ ] `MAF-05-01`(D3)建立工具风险元数据、默认分类和覆盖规则。
|
||||
- [ ] `MAF-05-02`(D3)实现 `auto`、`confirm_high_risk`、`confirm_all_writes` 策略解析。
|
||||
- [ ] `MAF-05-03`(D5)实现 Action Coordinator、唯一幂等键、状态机和目标租约锁。
|
||||
- [ ] `MAF-05-04`(D5)实现审批暂停、决策、checkpoint 恢复及过期处理。
|
||||
- [ ] `MAF-05-05`(D5)实现网络结果未知时的核验流程与可选补偿动作。
|
||||
- [ ] `MAF-05-06`(D4)实现凭据、参数、结果和异常日志脱敏,并编写泄漏测试。
|
||||
- [ ] `MAF-05-07`(D3)实现审计查询页面所需 API。
|
||||
- [ ] `MAF-05-08`(D5)实现并发/重启/重复事件故障注入测试,证明外部写入不会重复。
|
||||
- [x] `MAF-05-01`(D3)已建立服务端可信的工具风险元数据、精确名称覆盖和未知工具 `write/R3` 保守分类;会话请求、浏览器和模型输出均不可覆盖它。
|
||||
- [x] `MAF-05-02`(D3)已实现 `auto`、`confirm_high_risk`、`confirm_all_writes` 策略解析,并在 WriteGuard 之前执行分类。
|
||||
- [x] `MAF-05-03`(D5)服务端目标租约与一次性执行核心已实现,并已完成 03A/03B 的公开边界和跨数据库迁移收口;阶段 5 仍受真实 UAT 工具与部署输入约束,不能据此标记为最终验收完成。
|
||||
- [x] `MAF-05-03A`(D4,分配同事 A)已封闭目标租约键的公开边界:`target_key` 与内部 `idempotency_key` 仅留在持久层和内部仲裁路径,两个 actions GET、事件、日志和前端类型均不返回;目标键只接受服务端登记的稳定标量业务字段,并使用域隔离 HMAC-SHA-256 派生。HTTP 回归同时证明存储层仍能使用目标键完成租约仲裁。
|
||||
- [x] `MAF-05-03B`(D4,分配同事 A)已修复 `migrate_maf_roundtable_phase5.py` 的跨数据库 DDL:PostgreSQL 使用 `TIMESTAMP WITH TIME ZONE`、MySQL/MariaDB 使用 `DATETIME(6)`、SQLite 使用 `DATETIME`;表、缺失索引和可安全补齐列可重复自动补齐。已覆盖 SQLite 实际迁移及 PostgreSQL/MySQL DDL 测试。
|
||||
- [x] `MAF-05-04`(D5)审批创建时写入部署级超时,到期后在同一事务内标记 Approval=`expired`、Action=`rejected` 和审计事件。已覆盖真实 HTTP:`POST /approvals/{id}/decision` → `dispatcher.resume()` → `WorkflowRunner.resume()` → `ToolExecutor` → LangGraph `ToolNode` → 测试 outbox;重复决策/恢复仍只执行一次。
|
||||
- [x] `MAF-05-04A`(D4,分配同事 A)已将审批过期收口为 Gateway lifespan 中可取消的 MAF 周期扫描任务;间隔可配置,扫描使用条件式 CAS 后恢复受影响 run,普通 GET 保持只读。已覆盖并发扫描、重复/重启补扫、决策并发和过期后 Action 拒绝且工具执行次数为零,测试不使用 `sleep`。
|
||||
- [ ] `MAF-05-05`(D5)为指定的第一个真实写工具实现结果未知核验:外部请求必须携带业务幂等 operation id;网络超时/断连后先调用目标系统查询接口核验,再决定 `succeeded`、`failed` 或保留 `unknown`。补偿动作必须独立审批,不能由通用框架自动猜测或自动重试。
|
||||
- [x] `MAF-05-06`(D4)参数加密、API/事件/日志脱敏和泄漏测试已覆盖;继续在新增真实工具适配器中复用,禁止把明文凭据或原始参数放进 checkpoint、事件或模型上下文。
|
||||
- [x] `MAF-05-07`(D3)已提供按 run 查询 actions、approvals、事件及健康状态的 API,前端原型可显示审批和外部动作审计信息。
|
||||
- [x] `MAF-05-08`(D5)已覆盖两个 Agent 同目标租约串行、进程重启后的过期租约 `unknown` 恢复、外部成功但本地终态落库失败时禁止重放、审批超时、HTTP 决策全链路、并发占用、重复 `resume()`、拒绝、缺失/损坏密钥、真实 ToolNode/outbox 与旧 DeerFlow 不回归。
|
||||
- [x] `MAF-05-08A`(D5,分配同事 A)已补齐入口级验收:测试从 HTTP 创建 MAF session/run 和真实工作流入口开始,仅在模型边界使用确定性假实现;真实 WriteGuard、ToolNode、加密参数、HTTP 审批和测试 outbox 均参与,单次写入恰好一次。同目标双 run 覆盖 `waiting_target_lease`,第一个完成后第二个只能显式 `/runs/{id}/resume`,且无重复执行;公开 API 同时断言没有 `target_key`/内部幂等键。
|
||||
- [ ] `MAF-05-09`(D5,需业务方输入)接入首个真实 UAT 写工具/MCP。开始前必须明确工具名与参数 schema、目标 UAT 地址/租户、最小权限凭据的注入方式、目标键提取规则、外部幂等键、查询核验 API、可选补偿边界和回滚联系人;未提供这些信息不得猜测并接入生产系统。
|
||||
- [ ] `MAF-05-10`(D3)在部署环境通过环境变量注入 `MAF_ACTION_SECRET_KEY`,重启后确认 `/api/maf-roundtable/health` 返回 `write_guard_ready=true`;密钥不得提交到仓库或写入 `config.yaml`。
|
||||
|
||||
阶段 5 的当前可交付边界:测试专用 `maf_test_outbox_write` 已验证 WriteGuard → 审批超时/决策 → dispatcher → checkpoint 恢复 → 目标租约 → 直接受控 ToolNode 执行一次的链路,03A、03B、04A、08A 的框架代码与自动化验收项已完成。该结论仍仅代表**框架核心已实现**:真实 UAT 写工具、业务系统查询/补偿协议、最小权限凭据和生产 `MAF_ACTION_SECRET_KEY` 注入尚未提供,因此阶段 5 不得写为“验收完成”,也不得在生产执行真实外部写入。部署时先运行 `PYTHONPATH=. uv run python scripts/migrate_maf_roundtable_phase5.py`;它只证明框架安全性,不替代 `MAF-05-09` 的真实业务系统验收。
|
||||
|
||||
退出标准:
|
||||
|
||||
@@ -787,40 +881,68 @@ frontend-web/src/maf-roundtable/
|
||||
- 并行 Agent 写同一目标时不会互相覆盖。
|
||||
- 高风险写入在相应策略下能暂停和恢复。
|
||||
- 每个外部动作可追溯到用户、会商、run、Agent 和工具调用。
|
||||
- `target_key`、内部幂等键和明文目标标识均不从公开 API、事件、日志或前端状态泄露;Phase-5 迁移能在项目支持的 SQLite、PostgreSQL、MySQL 上幂等执行。
|
||||
- 审批即使无人刷新页面也会在到期后被后台任务关闭,且完整工作流入口到 HTTP 决策、真实 ToolNode 的链路经一次性测试验证。
|
||||
|
||||
### 阶段 6:前端工作台
|
||||
|
||||
阶段难度:**D4(较难)**
|
||||
建议负责人:熟悉 React、TanStack Query、SSE 状态归并和复杂工作台交互的中高级前端开发
|
||||
建议负责人:熟悉 React、TanStack Query、轮询事件归并和复杂工作台交互的中高级前端开发
|
||||
前置依赖:阶段 1 已验收的 API 基线与正式事件契约;reducer 可使用本地 fixture 开发,但不得依赖公开 mock 事件接口;可与阶段 2–5 并行开发
|
||||
主要评价点:事件状态准确、刷新恢复、审批交互、复杂状态下 UI 不误导用户
|
||||
|
||||
任务:
|
||||
|
||||
- [ ] `MAF-06-00`(D4)新建 MAF 专属目录、独立 query key、独立路由与 feature-flag 入口;确认旧会商页面、hooks、store、草稿与路由零改动。
|
||||
- [ ] `MAF-06-01`(D2)新增路由、菜单、特性开关和实验标识。
|
||||
- [ ] `MAF-06-02`(D3)实现创建会商、模型配置和席位选择。
|
||||
- [ ] `MAF-06-03`(D2)实现 MAF 两种模式及写入策略切换。
|
||||
- [ ] `MAF-06-04`(D5)实现支持断线、补拉、去重和乱序保护的 SSE reducer。
|
||||
- [ ] `MAF-06-05`(D3)实现 Agent、工具、技能和外部动作时间线卡片。
|
||||
- [ ] `MAF-06-06`(D4)实现审批卡片、澄清输入及并发操作防重。
|
||||
- [ ] `MAF-06-07`(D3)实现事实账本、最终结论和产物展示。
|
||||
- [ ] `MAF-06-08`(D4)实现取消、恢复、失败重试及对应状态禁用逻辑。
|
||||
- [ ] `MAF-06-09`(D4)实现刷新恢复、历史列表和跨页面返回。
|
||||
- [ ] `MAF-06-10`(D3)为 reducer 和关键交互编写前端测试。
|
||||
组件与实现约束:
|
||||
|
||||
- 新 MAF 工作台保持独立路由和独立目录,**不修改**原多智能体会商的页面、组件、状态或视觉。
|
||||
- 所有新增的可视 UI 组件优先使用项目本地已安装的 `tdesign-react`(React TDesign);可沿用项目既有的 TDesign 用法与主题配置。
|
||||
- 不得接入远程 UI 组件库、CDN 样式/脚本、在线组件生成服务或运行时远程加载的组件。图标、样式和交互资源必须随前端构建产物离线交付。
|
||||
- 第一版实时更新采用已确定的**纯前端轮询**:基于 `GET events?after_seq=N` 补拉、去重和游标推进;本阶段不新增 SSE 端点。若后续改用 SSE,另立任务并保持轮询回退路径。
|
||||
- 使用 TDesign 时应复用 `Dialog`、`Form`、`Input`、`Select`、`Checkbox`、`Button`、`Tag`、`Card`、`Timeline`、`Loading`、`Message` 等本地组件;业务状态、权限判断、事件归并仍由 MAF 专属 hooks/API 层负责,不能写入组件内部的临时全局状态。
|
||||
|
||||
当前代码状态:已有独立 `frontend-web/src/maf-roundtable/`、`MafRoutes.tsx`、`/page/maf/*`、会话/运行页、轮询事件 hook、审批卡和 19 项逻辑测试。这些只能视作可编译原型,不能直接作为阶段 6 交付:当前页面主要使用既有 shadcn/Radix 封装,且直接引用 `roundtable-planning/lib/use-desensitize-subtree`,均与本阶段的独立性和 React TDesign 约束不一致。
|
||||
|
||||
任务:
|
||||
|
||||
- [ ] `MAF-06-00`(D4,部分完成)保留已有 MAF 专属目录、query key 和 `/page/maf/*`,把直接引用旧会商目录的脱敏 hook 抽到中性共享位置或通过公共服务使用;证明旧会商页面、hooks、store、草稿与路由零改动。
|
||||
- [ ] `MAF-06-01`(D3,部分完成)保留现有独立菜单、健康门和实验标识,但把新增可视 UI 统一迁移到项目已安装的本地 `tdesign-react`;不加载任何远程 UI/CDN/在线资源。
|
||||
- [ ] `MAF-06-02`(D3,部分完成)以 TDesign `Dialog`/`Form`/`Input`/`Select`/`Checkbox` 重做创建会商、模型配置和席位选择;保留经理与席位互斥、智能体 loading/error/empty 状态和 1–64 轮次校验。
|
||||
- [ ] `MAF-06-03`(D2,部分完成)以 TDesign 表单控件呈现 `structured`/`group_chat` 与写入策略;后端配置默认值必须可见,前端不得自行伪造能力快照或风险等级。
|
||||
- [x] `MAF-06-04`(D5)纯轮询事件归并已实现:断线重试、分页补拉、按 seq 去重、游标推进、终态补拉和 run/generation 隔离均已有逻辑测试。后续 UI 改造不得改弱这些语义。
|
||||
- [ ] `MAF-06-05`(D3,部分完成)以 TDesign `Timeline`/`Card`/`Tag` 重做 Agent、工具、技能和外部动作时间线;事件展示必须只读取 MAF API,且不得显示原始敏感参数。
|
||||
- [ ] `MAF-06-06`(D4,部分完成)以 TDesign `Card`/`Dialog`/`Button` 重做审批卡;批准/拒绝必须禁用重复提交、以实际 run id 刷新 actions/approvals,并展示后端的失败关闭/未知状态。澄清输入仅在后端提供正式 `waiting_input` 契约后接入,不能先造假接口。
|
||||
- [ ] `MAF-06-07`(D3,部分完成)以本地 TDesign 呈现事实账本、最终结论和产物;明确区分“候选事实”“已确认事实”“待审批动作”“已执行动作”和“失败/未知动作”。
|
||||
- [ ] `MAF-06-08`(D4)补齐取消、审批后恢复、失败后创建新 run/重试的交互与状态禁用;不存在的后端 retry 接口不得由前端伪造为已恢复。
|
||||
- [ ] `MAF-06-09`(D4,部分完成)完成刷新恢复、会话历史、run 深链和跨页面返回;切换 run 时不串台,终态页面必须补齐完整历史。
|
||||
- [ ] `MAF-06-10`(D4,部分完成)保留现有 19 项纯逻辑测试,并新增挂载 hook/组件级 API mock 测试:慢请求切换 run、终态补拉、审批重复点击、health 缺密钥提示、取消/恢复和错误状态。完整 `pnpm typecheck` 的既有非 MAF 错误需单独基线记录,不能以它们掩盖 MAF 新错误。
|
||||
|
||||
退出标准:
|
||||
|
||||
- 刷新、切页、重新登录后能恢复当前运行。
|
||||
- 工具和技能调用过程可见。
|
||||
- 外部写入状态不会仅显示在聊天文本中。
|
||||
- 页面不请求或加载任何远程 UI 组件、CDN 样式或脚本;断网环境下仍可完整呈现 MAF 工作台。
|
||||
- 新增工作台 UI 组件来自本地 `tdesign-react` 或项目已有本地基础组件,未引入第二套远程 UI 依赖。
|
||||
- 原会商页面视觉和交互没有变化。
|
||||
|
||||
### 阶段 6.5:旧会商体验融合(阶段 6 验收后)
|
||||
|
||||
阶段难度:**D4(较难)**
|
||||
建议负责人:熟悉现有会商产品交互、React 状态边界和 React TDesign 的中高级前端开发
|
||||
前置依赖:阶段 5 的审批闭环验收、阶段 6 的独立工作台验收
|
||||
主要评价点:保留用户认可的体验,不把旧业务状态或旧 API 重新耦合进 MAF
|
||||
|
||||
目标是让 MAF 页面借鉴旧会商的视觉层级、意图理解入口和“总控智能体派活”的可理解性,而不是把旧页面或其数据层搬过来。技术 session/thread 是 MAF 内部实现,普通用户不需要看见“创建线程”。
|
||||
|
||||
- [ ] `MAF-06.5-01`(D3)梳理旧会商的用户已认可布局、文案、信息层级和关键交互,形成只读视觉/交互对照清单;不复制旧的 store、jobs、草稿或 API 调用。
|
||||
- [ ] `MAF-06.5-02`(D4)以本地 `tdesign-react` 重构 MAF 创建入口:用户输入任务/意图后,由 MAF 后端静默创建 session、冻结能力快照并启动 run,不展示底层 thread 创建步骤。
|
||||
- [ ] `MAF-06.5-03`(D4)把旧体验中的“意图理解 → 总控智能体分工 → 席位执行 → 会商结论”映射到 MAF 的 planner/manager、事实账本和事件时间线;映射只在 MAF view-model/API adapter 层完成。
|
||||
- [ ] `MAF-06.5-04`(D4)对照旧会商完成视觉和交互回归:新旧两个入口、路由、草稿和运行状态完全独立;关闭 `maf_roundtable.enabled` 后旧会商零变化。
|
||||
|
||||
### 阶段 7:对比评测
|
||||
|
||||
阶段难度:**D3(中等)**
|
||||
建议负责人:具备数据分析意识、理解 Agent 错误分类的全栈/测试开发/算法工程师
|
||||
前置依赖:阶段 3、阶段 4;指标接口可提前开发
|
||||
前置依赖:阶段 3、阶段 4、阶段 5、阶段 6;指标接口可提前开发
|
||||
主要评价点:对照是否公平、指标是否可解释、是否能区分模型/工具/编排错误
|
||||
|
||||
任务:
|
||||
@@ -944,24 +1066,26 @@ frontend-web/src/maf-roundtable/
|
||||
## 15. 发布与回退
|
||||
|
||||
- 配置项 `maf_roundtable.enabled` 控制后端 API 与前端入口。
|
||||
- `write_guard.enabled` 已设为 `true`,但只有带 `maf_run_id` 的新 MAF 会商进入 WriteGuard;旧 DeerFlow、旧 roundtable 和 AI 写作保持透传。
|
||||
- 上线前由启动环境注入 `MAF_ACTION_SECRET_KEY`;不在仓库或配置文件保存该值。访问 `/api/maf-roundtable/health`,确认 `write_guard_status=ready`、`write_guard_ready=true` 后,才允许验证真实外部写入。
|
||||
- 上线顺序:先部署只读 MAF 与精确工具元数据 → 注入密钥并检查健康状态 → 在 UAT/测试租户启用已指定的真实写工具 → 验证审批、恢复、拒绝、重启和 unknown 场景 → 再扩大灰度。
|
||||
- 首期仅管理员或指定白名单可见。
|
||||
- 关闭入口时,已有运行可选择继续完成或管理员取消。
|
||||
- 回退只需关闭特性开关和停止新 MAF jobs;旧 roundtable 不需要迁移或回滚。
|
||||
- 出现异常时先关闭 `maf_roundtable.enabled` 停止新的 MAF 写入;必要时再关闭 `write_guard.enabled`。若密钥或外部系统异常,保持 MAF 开启也会因失败关闭而拒绝写操作。旧 roundtable 不需要迁移或回滚。
|
||||
- MAF 独立表保留用于审计,不在代码回退时删除。
|
||||
- MAF SDK 使用延迟导入,关闭功能时不影响 Gateway 启动。
|
||||
|
||||
## 16. 推荐开发顺序与工作量级
|
||||
|
||||
建议严格按以下顺序推进:
|
||||
完整项目的依赖顺序仍是阶段 0 → 8;但基于当前代码盘点,**当前恢复开发的顺序**调整为:
|
||||
|
||||
1. 依赖/模型/离线 wheel Spike。
|
||||
2. 独立 session、event 和 SSE 骨架。
|
||||
3. DeerFlow AgentAdapter,先跑通真实工具、技能和一次外部写入。
|
||||
4. 固定流程编排。
|
||||
5. 动态 Group Chat。
|
||||
6. Action Coordinator、审批和恢复。
|
||||
7. 前端完整工作台。
|
||||
8. 对比评测、回归和灰度。
|
||||
1. 阶段 5:先完成 target-key 租约锁和 HTTP 审批恢复全链路;真实 UAT 工具仅在业务方提供协议后接入。
|
||||
2. 阶段 4:与阶段 5 的无外部依赖任务并行,补齐真实多轮 Group Chat、selector 和弱模型收敛。
|
||||
3. 阶段 6:在阶段 5 的动作/API 契约稳定后,将现有原型改为本地 React TDesign 工作台并完成组件级测试。
|
||||
4. 阶段 6.5:以独立 MAF view-model 复用旧会商的视觉与交互思路,隐藏技术 session/thread,不复用旧状态。
|
||||
5. 阶段 0 遗留项和阶段 1–3 的真实环境演示验收可穿插进行,但不再阻塞上述代码收口。
|
||||
6. 阶段 7:在两种编排和前端均验收后做公平对比。
|
||||
7. 阶段 8:最后完成全量回归、离线安装、灰度和观测。
|
||||
|
||||
在熟悉当前代码的前提下,这是一个中等偏大的完整功能,建议按 3 个可演示里程碑交付:
|
||||
|
||||
|
||||
Reference in new issue
Block a user