Skip to content

生成工作流产物二次开发指南

本篇面向两类开发者:一类需要在 Workflow Builder 生成后继续增强某一个业务子工作流;另一类需要判断某项改动是否应回流当前 Workflow Builder 母工作流。文中的“产物根”指业务构建工作区下的 workflow/,“母根”指 examples/workflow_builder/。

生成工作流是可独立使用、检查和迁移的交付物,不是不可修改的黑盒。但对它进行二次开发时,必须保持输入输出契约、Tool/Checker 注册、GuideDoc 指导、Make 目标和评估/增量能力之间的一致性。只修一份 Python 文件而不修它的 spec、测试和文档,会使本次手工运行可能成功,后续增量维护却无法理解这项改动。

二次开发目标

产物二次开发的目标是为一个已经生成的具体业务增加或调整能力,同时保留可运行、可检查、可评估、可回滚和可迁移性。典型任务包括:增加新业务 Tool,对既有 Tool 增加格式或算法,新增阶段或调整阶段输入输出,增加能证明新需求的 Checker,扩充业务知识库、GuideDoc 或用户文档,以及为新系统配置外部依赖。

不属于产物二次开发的事情包括:修改 UCAgent 核心来绕过一份业务 config 错误;为了让 Checker 通过而手工伪造报告;直接覆盖结构化 eval/*.json;在 wfgen/、产物根或源码目录散落临时脚本;以及把所有业务特例都反向写进母生成器。

母工作流修改入口

产物中的错误如果在多个无关业务中重复出现,或者根因是 Workflow Builder 的通用模板、schema、路径规则、生成状态、评估控制或阶段指导,就应回到母根修改。对应入口为 tools/workflow_builder/core.py、tools/workflow_tool_generator/core.py、tools/workflow_checker_generator/core.py、tools/workflow_config_generator/core.py、tools/workflow_guidedoc_generator/core.py、tools/workflow_evaluation_control/ 与 Guide_Doc/。

如果变更只属于一个业务的算法、字段、知识、文体、网站视觉规则、音频处理策略或专用外部工具,应保留在产物根。要让未来同类业务可复用时,优先把通用能力表达为母 workflow spec 能接收的模板/spec,只在多个业务的协议和算法都稳定后才把实现上移为母模板。

产物根的组件和数据所有权

不同业务可以增加目录,但标准产物通常包含以下责任区。二次开发前先读产物 README 和 docs/02输入输出.md,因为具体子工作流可以将 input/<TARGET>/ 再细分为需求、源数据、专业知识和可选资源。

产物组件 所有权与作用 修改时的主要联动
config.yaml 主运行阶段、任务、reference/output、Tool、Checker 和 GuideDoc 注册 stage 顺序、文件可达性、参数签名、GuideDoc、Make run/check 和 flow evaluation。
config/inc.yaml 或同等增量配置 业务内容的续写/更新流程,不是 Workflow Builder 的外层 inc.yaml 业务状态、版本、输入契约、Checker 和用户文档。
tools/ 业务 Tool、参数模型、共享运行库和 MCP adapters tool spec、config ex_tools、fixture/tests、requirements、GuideDoc 和 docs/04开发者文档-tools.md。
Checker 源码目录 业务不变量、输出完整性和阶段验收 checker spec、config checkers、args、fixture/tests、GuideDoc 和 docs/05开发者文档-checkers.md。
.workflow/ 生成器 spec、fixture、生成状态和确定性测试支撑,属于可维护元数据 修改真实源码时同步中心 spec 和 state 策略,避免下次 generator 运行覆盖或跳过。
Guide_Doc/ 子 Agent 的阶段操作指导、业务约束和失败恢复 config guide_docs、Tool/Checker 真实签名、输入输出与业务知识索引。
docs/ 人类用户和后续开发者文档 README 目录、快速启动、输入输出、阶段检查、Tool/Checker 真实源码分析。
knowledge_base/ 或业务知识目录 工作流交付的通用业务知识,可由 Agent 按索引读取 索引、来源/许可、版本、GuideDoc 读取策略和相关 Checker;不要把全库注入每阶段。
Makefile、setup.py、ucagent_setup.sh、requirements.txt 运行入口、跨系统配置、受控环境更新和依赖安装 环境 schema、变量优先级、Make help/check/test/migration、非 Python 安装注释和 eval_env。
input/<TARGET>/ 业务用户每次运行提供的数据、需求与可选专业知识 输入 schema、快速启动样例、缺失文件错误和路径边界;Tool 不得反写用户输入。
output/ 业务运行结果和结构化中间产物 output contract、原子写入、哈希/可解析验证、Checker 和清理策略。
tmp/ 唯一允许存放调试、浏览器 profile、下载缓存、候选案例和临时输出的根 运行开始/结束清理、并发 lock 容错和需要保留的版本历史;不得清除尚在使用的 profile。

Builder 生成边界的代码分析

母工作流的 tools/workflow_builder/core.py 使用 BuildReport 记录物化操作,并通过安全路径函数限制产物目标。二次开发者不应把这些内部母类复制到子工作流,但需要理解生成状态为什么会区分 created/skipped/warnings:

1
2
3
4
5
6
7
8
@dataclass
class BuildReport:
    workflow_name: str = ""
    created_dirs: list[str] = field(default_factory=list)
    created_files: list[str] = field(default_factory=list)
    skipped_files: list[str] = field(default_factory=list)
    warnings: list[str] = field(default_factory=list)
    errors: list[str] = field(default_factory=list)

一个已经由用户修改的产物被标记 skipped,通常表示 preserve 策略正在保护它,不是生成器一定失败。若需让 spec 更新重新生效,应使用生成器支持的 replace 或增量候选部署,先保存旧版并运行回归。不要删除整个 .workflow/ 来强迫生成,那会一并丢失 spec、fixture 和漂移证据。

Tool 产物的扩展步骤

修改工具前,先在 .workflow/tool_specs/ 或产物实际的中心 spec 目录找到该工具。如果 spec 存在,它应是名称、描述、入参、输出、错误、实现、注册和测试的共同源;先改 spec,再通过产物中的生成器或 Workflow Builder 增量流程更新真实源码。若该产物没有保留可重放 spec,需在修改记录中明确这是手工维护文件,避免未来 generator 误覆盖。

每个 Tool 的稳定返回应让后续阶段不需要解析终端文字:

1
2
3
4
5
6
7
return {
    "ok": True,
    "data": {"artifact": "output/result.json", "records": record_count},
    "errors": [],
    "warnings": warnings,
    "meta": {"tool": self.__class__.__name__, "schema_version": 1},
}

新增参数时同步 Args/Pydantic 模型、Tool 签名、spec input schema、config 注册、GuideDoc 调用示例和正反 fixture。新增输出时同步 output schema、后续 reference、Checker 和文档。引入第三方库时同步 requirements.txt;引入 Verilator、FFmpeg、LibreOffice 等非 Python 工具时,在 requirements 中以注释说明 Linux/macOS 安装命令、版本确认和不存在时的失败/降级行为。

工具写入必须限制在明确的 output/state/tmp 根,对路径先 resolve() 再检查归属。涉及网络获取素材时,需把域名白名单、协议、响应大小、MIME、重定向、许可记录和缓存放在可检查契约中;不应把“可以从网上寻找”实现成任意 URL 下载器。

Checker 产物的扩展步骤

新 Checker 必须回答一个可验证命题,例如“输出 JSON 可解析,所有必需记录有稳定 id,且错误总数与摘要一致”,而不是“检查输出”。类 docstring 说明检查对象和通过条件,方法 docstring 说明调用与返回。构造参数只接受 workflow-relative 路径和结构化阈值,config 中 args 必须与签名精确一致。

检查方法推荐返回 (passed, evidence),evidence 包含错误码、目标路径、失败字段/规则和有限上下文。文件不存在、不可解析、结构错、业务语义错和 Checker 自身异常应可区分。每项规则至少有一个正向 fixture 和一个只破坏该规则的负向 fixture。空壳 return True 不应通过全部测试。

修改 Checker 后还要检查它所在阶段的产物时序。某文件将在后三个阶段生成,当前 Checker 就不能将其作为必需输入。路径比较要在规范化后完成,不得因 .//workflow/a 与 workflow/a 字符串不同而误判。reference/output 中需列出具体文件,只有 Checker 构造参数明确支持目录遍历时才能传目录,这不改变阶段文件契约。

config 与阶段的扩展步骤

增加新 stage 前,先画出输入文件、输出文件、调用工具、通过 Checker、指导文档与失败恢复。任务中的表述性内容使用中文,类名、字段、命令和文件路径保留原文。新阶段不应只是“再做一次认知”、“再写一份 spec”或“再检查一次”;如果它不产生新状态、新产物或独立验收证据,应合并到已有阶段。

阶段引用要做闭包审计:reference 文件要么来自用户输入,要么由之前阶段明确输出;output 必须是具体文件,不使用一个目录代表未知结果;Tool 和 Checker 的注册类可 import,args 一致;GuideDoc 文件存在且只注入必要文档;任何 {NAME} 占位符都有明确定义、默认或启动参数来源。

修改 config 后至少完成 YAML 解析、未知占位符、引用可达性、目录文件契约、Tool/Checker import 和 Make dry-run 检查。然后选择一份最小业务输入执行相关 stage,不要等完整长流程运行几十分钟才发现第一个 reference 不存在。

GuideDoc、docs 与知识库的扩展步骤

GuideDoc 面向执行子工作流的 Agent,应说明本阶段目标、具体输入输出、工具参数、检查条件、最小可通过结构、常见完整示例和失败恢复。用户 docs 面向人,应介绍快速启动、输入输出、每个阶段和 Checker;开发者 docs 应对每个 Tool 和 Checker 引用真实业务源码,解释参数、核心算法、写入、错误、注册与测试。

知识库用于保存子工作流本身需要的通用专业知识,用户每次补充的项目专有知识仍应放在输入或约定的 resources 目录。知识库必须有索引,标注主题、适用范围、来源、许可、版本和相关文件。Agent 先查索引,再按当前任务读直接条目;不要在每个 stage 开头读完全部知识,否则长工作流容易在压缩后重复阅读而空转。

环境、Makefile 与 setup 的扩展步骤

生成工作流的 setup.py 应读自己的环境 schema,交互式定义或更新本机值,再受控更新 Makefile 或 ucagent_setup.sh 的标记区块。默认用户应能运行它,但秘密、Token 和代理凭据不应落入可提交文件。Make 变量优先级通常是命令行最高、本机配置其次、?= 代码默认最后,修改 include 顺序前必须用 dry-run 确认。

新增外部命令时,同步 environment schema、setup 提示和验证、requirements 注释、Make 变量/目标、Tool 白名单、Checker 安装探测、QuickStart 与 eval_env。外部命令必须用参数数组执行,设置 cwd、timeout 和输出上限,不把用户输入拼成 shell。一个业务需要并行生成多个独立产物时,可以并行执行不相交的写集;config、注册、共享 state 和聚合报告必须串行提交。

评估与增量交付的兼容

子工作流产物的二次开发完成后,应先运行自身 make check、make test_tools 和相关业务样例,再从外层 Workflow Builder 运行对应 eval_tools、eval_checkers、eval_flow 或 eval_env。评估报告不修改产物,用户在控制台批准 finding 或提出 suggestion 后,外层 inc.yaml 才在本轮候选目录修改、检查、备份和部署。正式文件的原子部署入口是 IncrementalChangeDeployer,普通文件工具和评估 Agent 不得代替它写入 workflow/。

如果人工二次开发绕过增量部署器直接修了产物,后续 inc 仍可以工作,但开发者必须将当前文件视为新基线,检查 generator state 与 spec 是否漂移,并自行提供 Git 或另一个版本备份。不能把外层 tmp/change_history/ 当成永久版本库;它用于增量部署恢复,用户仍应用 Git 管理长期业务源码。

一次产物二次开发的完整顺序

  1. 在产物根运行既有 make check 并记录基线,阅读 README、输入输出文档、目标 stage GuideDoc 与相关 Tool/Checker 开发文档,不做无目标全库扫描。
  2. 写清需求 id、当前行为、预期行为、输入输出、不变量、影响组件、最小正反样例和验收命令。
  3. 决定变更只属于当前产物,还是暴露了母模板/生成器的通用缺陷;两者都需时,先修母机制并补回归,再用增量流程修历史产物。
  4. 先修中心 spec/manifest,再修 Tool、Checker、config、GuideDoc、docs 和 requirements。临时测试数据只放 tmp/,正式 fixture 放契约规定的测试目录。
  5. 按语法、单元/fixture、Tool direct/MCP、Checker 正反、config 闭包、文档和 make check 顺序验证;某一层失败先修该层,不重复运行没有状态变化的同一长命令。
  6. 运行对应评估并审查报告,高风险问题必须有具体证据。通过增量流程部署时,确认每个 approval 有 change mapping、旧版备份、新哈希和正式回归结果。
  7. 更新产物的版本、变更说明和迁移包,在新临时根执行配置与检查,确认没有依赖开发机绝对路径。

失败、回滚与回归策略

语法失败、Tool 直接调用失败、Checker 负例误通过、config 引用不可达和正式 make check 失败都不能被文档或报告中的“已知问题”替代。候选尚未部署时,继续修候选;已部署且同一批准范围内可修时,保存新一版旧文件后继续修复;需要超出批准范围时,回滚或报告需新批准。不得在已部署回归失败时停在 pending 并无限重复同一命令。

产物级回归至少包含:全部 Python 源码编译;YAML/JSON 可解析与 schema;每个 Tool 的正常、边界、失败、路径和重复运行;每个 Checker 的 import、args、正例和单错负例;阶段引用闭包;GuideDoc 与真实签名;Make dry-run/check;setup 首次、重复、非法值和命令行覆盖;迁移到新根后的最小运行。外部依赖不存在要清楚标记 skip/unavailable,不伪装为业务成功。

完成定义

一项生成工作流的二次开发只有在以下条件同时满足时才完成:用户需求有稳定 id 和追踪映射;spec/源码/config/GuideDoc/docs 一致;Tool 真正可直接和通过 UCAgent 调用;Checker 正反证据有效;make check 对正式产物返回 0;旧版可恢复;评估没有未处理阻断问题;迁移到新目录不依赖原绝对路径。

如果修改解决了一个通用母机制缺陷,还要在 Workflow Builder 母根增加确定性回归、更新对应 Guide_Doc/ 和本组开发者文档。这样修复才会在下一个无关业务中自动生效,而不是只在当前历史工作区中存在。

继续阅读

需要回到母工作流修改具体组件时,从工作流程简介定位阶段,再分别阅读 Tool 简介、Checker 简介、指导文档简介、评估与增量控制 和测试与回归。