Skip to content

Epic:四类 L1 数据采集节点、Variadic Merge 与多 Agent 安全编辑 #38

Description

@2233admin

背景

OpenCLI Admin 当前已有数据采集、工作流运行、事件持久化和原生 HDA 能力,但用户在 Studio 画布中仍无法用清晰、稳定、可组合的 L1 业务节点完成通用数据采集。

当前体验存在以下问题:

  • 数据采集节点的业务颗粒度和命名混乱,A 股示例、OpenCLI、HDA、数据集等概念混在一起。
  • 网页、API、RSS、CLI 没有作为四类独立的 L1 采集节点暴露。
  • 一个节点无法自然管理多个同类来源。
  • CLI 采集仍存在自由文本命令入口,不符合安全和可发现性要求。
  • Merge 使用固定输入端口,不能像 Houdini Merge 一样连接任意数量的上游。
  • 节点缺少按来源的成功、失败、新鲜度和重试反馈。
  • AI 编辑能力没有形成可审阅、可并发、不会覆盖人工修改的节点级提案流程。

本 Epic 将工作流主路径统一为:

开始 → 网页/API/RSS/CLI 采集 → Merge → 清洗 → 结束

其中四种采集节点均为 L1 业务节点;底层 L2 能力继续封装实现细节。股票数据仅作为真实测试项目,不进入通用产品模型。

目标

  1. 在节点工具架提供四类清晰独立的 L1 采集节点:网页、API、RSS、CLI。
  2. 每个采集节点实例允许配置多个同类型来源。
  3. 提供可直接人工编辑的节点配置体验,并支持 Agent 生成结构化修改提案。
  4. 统一采集输出、来源级执行状态、数据新鲜度和部分成功语义。
  5. 将 Merge 改造成可连接任意数量上游的纯合并节点。
  6. 以增量、兼容、可回滚方式上线,不破坏旧工作流和下游图谱/仿真链路。

非目标

  • 本期不扩展图谱、Persona、仿真、访谈、报告或报告问答功能。
  • 本期不把清洗、去重、摘要、分类或推理塞入 Merge。
  • 本期不允许 CLI 节点执行用户输入的任意 Shell、脚本或命令行。
  • 本期不做破坏性数据库迁移,也不批量重写已保存工作流。
  • 本期不把 A 股字段或网站写入通用节点契约。

产品与交互设计

节点工具架

新增四个一级节点条目:

Catalog ID 展示名称 用途
collection.source.web 网页采集 从多个网页或站点配置采集内容
collection.source.api API 采集 从多个 HTTP API 配置采集结构化数据
collection.source.rss RSS 采集 从多个 RSS/Atom Feed 采集条目
collection.source.cli CLI 采集 从已注册 OpenCLI 工具目录选择工具并运行

节点命名只表达业务动作和来源类型,不在名称中混入 OpenCLI、HDA、项目名或数据集名。

节点编辑

选中采集节点后,右侧 Inspector 提供来源列表编辑器:

  • 添加、删除、启用、停用和排序同类型来源。
  • 每个来源显示名称、配置摘要、认证状态和最近验证状态。
  • 支持“测试此来源”和“测试全部来源”。
  • 支持逐来源重试失败项。
  • 支持手动保存;运行前进行确定性校验。
  • 预览最多展示 50 条采集结果,同时显示成功数、失败数、新鲜度和来源状态。

各节点只暴露本类型字段:

  • 网页:URL、抓取模式、选择器/提取规则、分页或时间窗口、凭证引用。
  • API:URL、方法、查询参数、Header 模板、Body 模板、分页、响应映射、凭证引用。
  • RSS:Feed URL、时间窗口、条目限制。
  • CLI:已注册 adapterNodeId、目录中声明的 typed arguments、凭证引用。

CLI 编辑器必须从 OpenCLI 工具目录选择已注册工具,不提供自由文本 Shell 输入。以下字段不得进入可保存节点配置:shellcommandLinescriptTextrawCommand、明文 token、password、cookie 或 authorization。

Agent 编辑

Agent 不能直接并发写画布。Agent 只生成节点级结构化 Proposal:

type CollectorNodeProposal = {
  proposalId: string
  nodeId: string
  baseRevision: string
  summary: string
  operations: CollectorPatchOperation[]
}

交互规则:

  • 多个 Agent 可以基于同一版本并行生成提案。
  • 用户逐条查看差异并接受或拒绝。
  • 接受时使用 baseRevision 做 CAS 校验。
  • 版本未变化则原子应用。
  • 版本已变化则重新验证;可安全重放时生成 rebased proposal,否则展示冲突。
  • 禁止静默覆盖人工修改或其他已接受提案。
  • 手动编辑必须先完整可用;Agent 是增强入口,不是必需路径。

数据契约

节点参数

四类节点共享外层结构,并用 kind 形成 discriminated union:

type CollectorNodeParams = {
  version: 1
  execution: {
    concurrency?: number
    timeoutMs?: number
    retry?: {
      maxAttempts: number
      backoffMs?: number
    }
  }
  sources: SourceDefinition[]
}

SourceDefinition 分为 web | api | rss | cli。单个节点中的每个来源必须与节点类型一致,并拥有稳定 sourceId

成功数据

type CollectedItemV1 = {
  itemId: string
  sourceId: string
  sourceType: "web" | "api" | "rss" | "cli"
  title?: string | null
  url?: string | null
  content?: string | null
  data?: unknown
  publishedAt: string | null
  fetchedAt: string
  lineage: Record<string, unknown>
}
  • publishedAt 表示来源实际发布/发送时间;来源未提供时为 null
  • fetchedAt 表示系统获取时间。
  • 两者禁止相互 fallback。

来源执行结果

type SourceExecutionResult = {
  sourceId: string
  status: "completed" | "failed" | "skipped"
  itemCount: number
  attempts: number
  startedAt: string
  finishedAt: string
  error?: {
    code: string
    message: string
    retryable: boolean
  }
}

节点标准输出:

type CollectorOutputV1 = {
  items: CollectedItemV1[]
  sourceResults: SourceExecutionResult[]
}

规则:

  • items 仅包含成功采集的数据。
  • 单个或部分来源失败时,节点继续输出成功数据并记录失败。
  • 所有启用来源均失败时,节点执行失败并阻断下游。
  • 停用来源记录为 skipped
  • 重试只针对失败且 retryable=true 的来源。

Merge 契约

Merge 是纯合并节点:

  • 输入端口 cardinality=many,最少连接 1 个上游,不保存 in1/in2/in3/in4 这类固定端口 schema。
  • 运行时读取所有实际入边,按确定性顺序拼接成功 items。
  • 汇总并保留全部 sourceResults 和 lineage。
  • 不执行清洗、去重、排序、摘要、分类或隐式字段改写。
  • 旧固定双输入 Merge 继续可加载和运行;保存为新格式时采用兼容升级,不做全库迁移。

兼容与回滚

  • 新节点和新契约采用 additive v1。
  • site + command OpenCLI 配置在运行时归一化为单条 legacy source,不修改原始已保存图。
  • 旧来源节点和旧工作流保持可加载、可编辑、可运行。
  • 下游只在边界增加 CollectorOutputV1 适配,不修改图谱/仿真等业务逻辑。
  • 使用 feature flag 控制四类新节点的工具架入口;关闭后隐藏新建入口,但不影响已保存节点运行。
  • 不进行破坏性迁移,不删除旧节点类型。

实施拆分

子任务 1:强类型采集契约与兼容层

  • 前后端定义 CollectorNodeParams、四类 SourceDefinitionCollectorOutputV1
  • 加入 schema 校验、版本字段和禁止字段校验。
  • 实现旧 site + command 到单条 legacy source 的只读归一化。
  • 为下游建立统一输出适配边界。

子任务 2:四类节点目录与人工编辑器

  • 注册网页/API/RSS/CLI 四个 L1 节点。
  • 复用现有工具架、命令面板、Inspector 和模板创建链路。
  • 实现多来源列表编辑、类型专属字段、验证和测试操作。
  • CLI 只允许目录选择和 typed args。

子任务 3:四类运行时与多来源 fan-out

  • 为四类节点绑定运行时执行器。
  • 同一节点内按配置并发/限流执行多个来源。
  • 统一生成 items、时间字段和 lineage。
  • 凭证只通过 credential reference 解析,不写入节点配置和执行输出。

子任务 4:部分成功、重试与可观测性

  • 生成逐来源 sourceResults
  • 实现部分成功、全失败、跳过和可重试语义。
  • Run Trace 与 Inspector 预览展示来源状态、失败原因、attempts 和新鲜度。
  • 支持只重试失败来源。

子任务 5:Variadic Merge

  • 将 Merge 契约改为 many-cardinality。
  • 画布支持同一目标端口的多条入边。
  • 运行时按实际入边合并。
  • 保留旧双输入图兼容。

子任务 6:节点级多 Agent Proposal/CAS 编辑

  • 定义结构化 patch operation 白名单。
  • Proposal 绑定 nodeId + baseRevision
  • 实现差异预览、逐条接受/拒绝、CAS、rebase 和冲突展示。
  • Agent 不获得直接写画布权限。

子任务 7:下游兼容、端到端验证与回滚演练

  • 验证清洗及后续现有链路可消费统一输出。
  • 建立四类来源、部分失败、全失败、Merge、多 Agent 冲突和旧工作流的 E2E。
  • 验证 feature flag 回滚和无破坏升级。

依赖关系:

1 → {2,3} → 4 → 5 → 7

2 → 6 → 7

验收标准

  1. 工具架只以“网页采集、API 采集、RSS 采集、CLI 采集”展示四类新 L1 节点。
  2. 每个节点可配置至少 2 个同类型来源,并可增删、停用、排序和保存。
  3. 不同类型来源不能被保存到错误的节点类型中。
  4. CLI 节点只能选择已注册工具及 typed args;任意 Shell/命令文本在 UI 和 API 层均被拒绝。
  5. 节点运行输出严格包含 items[]sourceResults[]
  6. publishedAt 缺失时保持 nullfetchedAt 始终为实际采集时间,两者不互相替代。
  7. 一个来源失败、另一个成功时,成功 items 继续进入下游,失败来源可在 Trace 中定位并单独重试。
  8. 所有启用来源失败时,节点失败且下游不执行。
  9. Inspector 预览最多显示 50 条,明确展示成功数、失败数、来源状态和数据新鲜度。
  10. Merge 可连接 1 个、2 个和 5 个上游,保存模型不生成固定 in3/in4 字段。
  11. Merge 仅拼接数据并保留 lineage/sourceResults,不执行隐式清洗或去重。
  12. 两个 Agent 基于同一 revision 提案时,第一个可接受;第二个不得覆盖新状态,必须安全 rebase 或展示冲突。
  13. 旧来源节点、旧双输入 Merge 和旧 site + command 工作流仍可加载和运行。
  14. 关闭 feature flag 后,新节点从创建入口隐藏,已保存的新节点仍可运行。

测试计划

  • Schema 单元测试:四类合法配置、跨类型配置、禁止 CLI 字段、旧格式归一化。
  • Runtime 单元测试:单来源、多来源、部分失败、全失败、跳过、重试、时间字段和 lineage。
  • Merge 单元测试:1/2/5 上游、确定性顺序、空输入、错误传播、旧双输入兼容。
  • Proposal/CAS 单元测试:正常接受、陈旧 proposal、可重放 patch、冲突、拒绝和幂等回放。
  • 前端组件测试:工具架创建、来源列表编辑、CLI 目录选择、预览 50 条边界、失败重试。
  • API/集成测试:节点保存校验、凭证引用、运行事件、来源结果持久化和恢复。
  • 端到端测试:真实 Web/API/RSS/CLI 各至少一个来源,经 Merge 和清洗到结束节点。
  • 回归验证:后端全量测试、前端测试、TypeScript、ESLint、生产构建和真实 Chrome 核心路径。

完成定义

  • 以上 14 条验收标准全部自动化或人工验证通过。
  • 新增测试覆盖所有新契约分支和关键失败路径。
  • 后端全量测试、前端测试、TypeScript、ESLint 和生产构建通过。
  • 至少完成一次真实 Chrome 端到端演练和一次 feature flag 回滚演练。
  • 独立代码审查和架构边界审查无阻断项。
  • 规格、兼容策略、运行输出和用户操作文档同步完成。

主要代码落点

  • frontend/lib/workflow/node-catalog.ts
  • frontend/lib/workflow/node-contracts.ts
  • frontend/lib/workflow/node-templates.ts
  • frontend/components/flow/inspector.tsx
  • frontend/components/flow/workflow-node.tsx
  • frontend/components/flow/workflow-editor.tsx
  • frontend/components/flow/command-palette.tsx
  • frontend/lib/workflow/to-react-flow.ts
  • frontend/lib/workflow/proposal.ts
  • frontend/lib/workflow/workflow-agent-proposal.ts
  • backend/schemas/workflow.py
  • backend/workflow/runtime_contracts.py
  • backend/workflow/runtime_registry.py
  • backend/services/opencli_hda_tracer.py
  • backend/pipeline/normalizer.py
  • backend/models/source_credential.py
  • backend/models/workflow_run.py

风险

  • 画布当前只渲染首个 target handle,Variadic Merge 需要同时修正 UI 连线和运行时契约。
  • 现有来源执行输出以节点为粒度,需要保证来源级状态不会破坏事件回放和崩溃恢复。
  • API/Web 配置可能包含敏感认证信息,必须只持久化凭证引用并对日志、Trace 和 Proposal 做字段过滤。
  • Agent Proposal 的 rebase 仅对明确白名单操作开放;不确定的 patch 必须进入冲突状态。
  • 旧节点兼容必须以测试固定,避免保存新版工作流时无意重写旧配置。

Metadata

Metadata

Assignees

No one assigned

    Labels

    ready-for-agentFully specified and ready for an implementation agent

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions