跳到主要内容

动态工作流

代码内规划的分发、对抗式验证、波次。

技能元数据​

来源可选 — 使用 hermes skills install official/autonomous-ai-agents/dynamic-workflow 安装
路径optional-skills/autonomous-ai-agents/dynamic-workflow
版本2.0.0
作者Teknium + Hermes Agent
许可证MIT
平台linux、macos、windows
标签orchestration、fan-out、subagents、delegation、verification、migration、audit、research、campaign
相关技能hermes-agent、simplify-code

参考:完整的 SKILL.md​

信息

以下为此技能被触发时 Hermes 加载的完整技能定义。这是技能激活时智能体所看到的指令。

动态工作流技能

将大规模的分发工作作为工作流运行:规划、循环和每一个中间结果都存在于脚本和磁盘上,因此父级上下文只保存经验证的结果。涵盖一次性分发、对抗式收敛(尝试 + 反驳者),以及整合数十个工作分支的多波次战役。它不会让 delegate_task 在重启后持久化;那是看板蜂群(kanban swarm)的职责。

何时使用​

当工作单元清晰(一个文件、一个端点、一条记录)且单元数量超过单个上下文所能容纳的数量时使用它。对于少于约 10 个单元或串行链的情况请跳过。对于针对 hermes-agent 本身的重构或修复战役,请同时加载 hermes-agent(开发工作流);此技能负责分发形态。

前置条件​

  • delegate_task 可用,且 delegation.max_concurrent_children 已按波次规模设置好(默认为 10;运行时会拒绝大于该值的 tasks=[],并给出明确的错误而非排队)。只有当子级必须自行分发时才需要 delegation.max_spawn_depth >= 2。
  • 一个可写的运行目录,从终端环境的临时目录($TMPDIR,否则为平台临时目录)解析得到。绝不要使用字面的 /tmp:Termux 没有 /tmp,原生 Windows 会因它而崩溃。使用 <tmp>/wf_<name>_<uuid>/,每次运行唯一,这样被中断的早期运行不会留下陈旧输出而被误读。
  • execute_code 用于确定性层(其内部只存在 web_search、web_extract、read_file、write_file、search_files、terminal、patch)。

如何运行​

两层,由一个真实的能力边界划分:

A 层 - execute_code 脚本B 层 - delegate_task 批次
用于确定性工作:获取 N 个 URL、解析 N 个文件、运行 N 条命令、模板化 N 个输出、构建清单、合并输出LLM 判断工作:对一个单元进行分类、审查、决策、写作、反驳、重构
保存循环、分支、中间变量无;一次调用带 tasks=[...],每个任务都有自己的隔离智能体
工具上述沙箱集合;它不能调用 delegate_task父级的工具集,原样继承(无逐任务收窄);子级失去 delegate_task、clarify、memory、send_message、cronjob_manage
并发由你掌控(ThreadPoolExecutor、批次)受 delegation.max_concurrent_children 约束
成本仅工具调用每个任务一棵完整的智能体树;线性倍增

先在第 A 层处理确定性部分,只在第 B 层分发不可约简的 LLM 步骤,并在父级做综合。

后台优先:结果以消息形式重新进入​

顶层 delegate_task 会立即返回,每个任务一个句柄;每个子级的结果在完成时作为新消息重新进入对话。你不能在调用后的下一行读取 out_*.csv。完成任何不依赖子级的工作,给出单行状态,然后结束你的回合;每个结果消息到达时再对其采取行动。普通的后续用户消息不会取消子级;/stop、/new 和进程退出会。只有由编排器子智能体(深度 > 0)发出的委派才是同步的。

快速参考​

  • 单元必须能在没有兄弟输出的情况下作答,否则它就是串行的。
  • 清单:在 <run>/manifest.jsonl 中每个单元一行;打印数量和运行目录。
  • 每个子级:约 8-12 处机械式编辑,或约 2-3k 行阅读量,或约 50-70 KB 语料;按最大的单元来确定大小。结构化输出写入文件,绝不写入 summary 字段(它在负载下会截断);使用分隔符分隔的行而非 JSON。
  • 父级在合并前验证文件数量和每次运行的新鲜度。
  • 一个"停滞"的子级通常已完成其写入;先检查文件系统。
  • 先做范围限定的切片(一个目录、20 条记录),报告 token 成本,然后扩展。

流程​

一次性分发​

  1. 分解为独立的单元。
  2. 第 A 层预运行写入清单。
  3. 根据上述限制确定分块大小;对于超过 max_concurrent_children 的任务,自行发出有界的波次。
  4. 第 B 层:一次 delegate_task(tasks=[...]);每个任务读取其切片,写入 <run>/out_<i>.csv,打印一个状态词,停止。
  5. 结束回合。随着结果消息到达,读取文件、验证、合并;横切综合留在父级。

对抗式收敛(发现质量问题的工作)​

  1. 独立尝试:将同一个问题发给 N 个子级(2-4 个),在每个 context 中采用不同的框定,每个子级将每条声明一行写入 <run>/attempt_<i>.md。只写有位置、可单独证伪的声明("src/routes/users.ts:142 中的 POST /api/users/:id/role 没有角色检查");反驳者无法攻破"认证层有问题"。
  2. 在父级合并并去重;记录每条声明的一致计数。
  3. 反驳者:第二批被要求用反证据攻破每条声明,发出 claim_idx|survives|counter_evidence。给他们来源,而不是尝试中的推理。
  4. 只呈现幸存项;抛弃被反驳的声明并附一行理由。
  5. 将第二轮的新声明再走一次反驳;当某一轮没有新增幸存项时停止,最多 3 轮。

同样的机制保护父级免受其自身错误前提的影响:当你交给子级一个启发式规则("外观上的每个补丁目标都是死缝")时,告诉他们在据此行动前用证据反驳它。四支小队这样做,将 647 处的全面重写变成了 59 处真实修复,并节省了 130+ 个通过的测试。

战役形态(数十个工作者、若干波次、数小时)​

一次性配方无法扩展到整个代码库的遍历。有效的方法是:

  1. 先测量(LOC、热点、死符号、预言机语料),写一份共享的 BRIEF.md 加上每个集群的 task_<cluster>.md。每个子级都读取两者。当完成群漂移时(子级削减文档字符串而非切代码),修补一次简报并引导;重新派遣的子级会继承修复。
  2. 独占所有权:每个工作者一个文件集群,其外的编辑在集成时被丢弃。单个文件内的子分发拥有行范围,并在其范围内定义辅助函数,以便差异干净地合并。
  3. 每个经验证的步骤提交一次,本地,不推送、不建 PR、子级不做变基。已提交状态是唯一的交接;每个在战役中途死掉的工作者恰好丢失其未提交的尾部。共享工作树索引的工作者只能用 git commit -- <paths> 提交;裸提交会顺手带上兄弟级已暂存的代码块。
  4. 完成群规模 12-16 并发。在单个 OAuth 授权上超过约 40 个进程时,每小时 token 刷新会蜂拥导致 401 并毁掉该波次。其余排队。
  5. 父级存活检测:一个子级报告 completed 且只有几十行日志,或其分支上 0 次提交,说明它尚未完成;查找其子分支,或用前驱的工作树和差异重新派遣它。
  6. 每轮集成:冻结一个基线 SHA,机械地对干净分支变基,给每个冲突分支分配自己的变基工作者("main 的行为胜出,在新结构内重新应用"),合并到一个集成分支,在合并后的树上运行完整套件。每个分支单独通过时都通过的碰撞只出现在这里。下一轮从集成提交处分支,使其工作者彼此不会冲突。
  7. 在宣布某轮已集成前:每个分支的 git rev-list --count <integration>..<branch> 都为 0。工作者会在你合并其顶端后继续提交;168 次提交横跨六个切片就曾以这种方式被留下。
  8. 测试运行:机器上恰好一个运行器,在锁文件之后,高 -j。许多并行的低 -j 运行器既更慢又互相杀死对方的进程组。红色文件在同一个 venv 中用裸 origin/main 工作树重新运行;相同的逐文件失败集是预先存在的,不是你的。
  9. 在最后做前向移植,而非每轮:冻结 main 的 SHA,按目录将冲突文件分发给编辑同一个合并工作树、不提交的工作者,然后父级提交一次该合并。CI 从不在冲突的 PR 上运行,所以在每次推送前重新合并 main。
  10. 实时 QA 是自己的一波:每个界面一支小队,隔离的 HERMES_HOME,检查前写期望,磁盘上有证据,只报告,只有 PR 与 main 的差异才算回归。绿色单元测试漏掉了唯一的 P0(一条无测试覆盖的已登录代码路径)。
  11. 审查者声明与子级声明受到同样对待:在"恢复"任何东西之前先对基线做 A/B。若干自信陈述的审查差异在基线上已是如此行为。
  12. 父级重启需要 HANDOFF.md:它为何死掉、哪些句柄已死、每个分支的记分卡(LOC 差值、导入冒烟、定向测试)以及确切的重派文本。先将每个脏工作树快照为 wip: 提交。

陷阱​

  • 在 execute_code 脚本内调用 delegate_task:不在沙箱中。
  • 在分发调用的同一回合做综合:文件尚不存在。
  • 从 delegate_task 承诺数天的后台持久性:它是有回合范围的,随进程消亡。持久图 = 看板蜂群;一次性 = cronjob。
  • 信任 summary 作为内容,或信任 status=completed 作为完成。
  • 每个"独立"尝试都采用同样框定:它们会坍缩为一个答案。
  • 在工作树战役中任何地方使用 git stash:refs/stash 在工作树之间共享,另一个工作者会弹出你的编辑。通过临时工作树做比较。
  • 在诚实的数字更低时报告一个命中目标。要说"目前 16%,下面是通向 30% 的路径",然后做下一轮。

验证​

  • 清单行数与预期单元数一致。
  • 每个 out_*.csv 都存在且是在本次运行中写入的。
  • 每条被抛弃的声明都有记录的反证据;每条被呈现的声明都经历过反驳。
  • 战役:每个分支的未合并提交为 0,在集成树上运行完整套件,红色对裸 main 进行分诊,每个界面有实时 QA 报告,在完整运行前在范围限定的切片上报告 token 成本。