From 06fef3be44d44b28d322e529116d1abac8a7879a Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 12 Aug 2026 13:52:20 +0000 Subject: [PATCH] Add six-pattern toolbox to s16 with composition walkthrough Introduce Classify-And-Act through Loop Until Done after primitives, map each onto agent/parallel/pipeline, show review-changes as a fanout+verify composition, and add a matching six-panel SVG. Co-authored-by: Xinlu Lai --- s16_workflow_runtime/README.ja.md | 45 +++-- s16_workflow_runtime/README.md | 45 +++-- s16_workflow_runtime/README.zh.md | 45 +++-- .../images/six-workflow-patterns.svg | 159 ++++++++++++++++++ .../six-workflow-patterns.svg | 159 ++++++++++++++++++ 5 files changed, 423 insertions(+), 30 deletions(-) create mode 100644 s16_workflow_runtime/images/six-workflow-patterns.svg create mode 100644 web/public/course-assets/s16_workflow_runtime/six-workflow-patterns.svg diff --git a/s16_workflow_runtime/README.ja.md b/s16_workflow_runtime/README.ja.md index a3768cbb..a5bc37d0 100644 --- a/s16_workflow_runtime/README.ja.md +++ b/s16_workflow_runtime/README.ja.md @@ -88,17 +88,38 @@ results = await ctx.pipeline(DIMENSIONS, audit, verify) confirmed = [f for r in results if r for f in r["confirmed"]] ``` -## パターンは、元が取れるときだけ +## レシピが書けるようになったら -カタログを暗記する必要はありません。サンプルが何をしているかに気づけば、手元に三つのスタイルがあります。 +上の動詞は小麦粉と火加減です。人が何度も発明し直すのは、少数の*形*——dynamic agentic workflow のよくあるパターンです。道具箱だと思ってください。必点メニューではありません。痛みが出たときに手を伸ばし、残りは壁に掛けておきます。 -変更を review の各 dimension へ**広げ**、きれいな机で進め、一つの確認リストへ**まとめ**ます。fan-out-and-synthesize です。かけらが一つの騒がしい context で混線するときに効きます。 +![Six Workflow Patterns](images/six-workflow-patterns.svg) -verify の内側では、第二の助手が各 finding をあえて疑います。adversarial verification——自分の宿題に甘くならないための、構造からの答えです。 +*人が何度も発明する六つの形。トポロジーは script が持ち、このレッスンでは `agent` / `parallel` / `pipeline` / `phase` / journal で各形を話します。* -残るのは、生成したものへのフィルタです。Generate-and-filter。候補が入り、通ったものだけが出ます。 +**Classify-And-Act。** 痛み: 万能の助手は何でもそこそこ。形: classifier がタスクを見て、専門家 A / B / C へ振り分ける。このレッスンでは、だいたい `agent({schema})` がラベルを返し、script の `if`/`match` が続く `agent`(または入れ子の `workflow`)を呼びます。全部が本当に同じ扱いでよいなら、使わない——振り分けは儀式になります。 -同じ道具箱には classify-and-act、tournament、loop-until-done もあり、あとで出会います。余分なコストが、安くは手に入らない明瞭さや安全を買うときだけ、スタイルを借りてください。 +**Fanout-And-Synthesize。** 痛み: 五十ファイルは一つの疲れた context に入らず、押し込めば混線する。形: 仕事を分け、多くの agent を走らせ、barrier で待ち、まとめる。各 item に自分の stage があるなら `pipeline`、次が全結果を要すなら `parallel`。まとめは gather のあとのふつうの Python。関連ファイルが三つか五つで一通しで足りるなら、使わない。 + +**Adversarial Verification。** 痛み: 狐が鶏小屋を採点する。形: worker が出す。独立した verifier が反証や負荷をかける。生き残ったものだけ残る。写し方は、生産の `agent`、それから verifier `agent` の `parallel`(できれば schema 付き)、そのあと filter。`phase` で “Review” と “Verify” を分ける。間違えても安いなら使わない——すべてのメモに法廷は要らない。 + +**Generate-And-Filter。** 痛み: 欲しいのは選択肢であり、最初に賢く聞こえた案ではない。形: 多くの generator がアイデアを rubric + dedupe の filter に流し、best を残して残りを捨てる。写し方は generator の `parallel`、そのあと script 側の filter(または schema 付きの審判 `agent`)。生成が高いとき journal / resume が効く。良い答えの空間がもともと狭いなら使わない。 + +**Tournament。** 痛み: 味や順位では絶対スコアがぼやける(「この名前はどれくらい良い?」)。形: ペアごとの審判、トーナメント表、勝者——比較判断は孤独な採点に勝る。写し方は、script 内で pairwise 審判 `agent` の `parallel` を回し、一つ残るまで続ける。鋭い rubric が一通しで勝者を決めるなら使わない。 + +**Loop Until Done。** 痛み: 坑道にまだ何巡あるか分からない。形: 「新しい発見?」が yes のあいだ spawn し続け、空振りや完了条件で止まる。写し方は `while` で `agent`/`parallel` を包み、schema 付きの停止チェックと硬い `budget` を置く。長い掘りが止まるなら journal resume と組む。仕事量が分かっているなら、固定の `pipeline` の方が単純で安全。 + +いくつか顔が付いたあと、道具箱は一目で収まります。 + +| パターン | プリミティブの素描 | 手を伸ばすとき | +|----------|--------------------|----------------| +| Classify-And-Act | `agent` → 分岐 → `agent` | 項目ごとに違う専門家が要る | +| Fanout-And-Synthesize | `pipeline` / `parallel` → 統合 | きれいな机がたくさん、そのあと一つの要約 | +| Adversarial Verification | 生産 → `parallel(verify)` → filter | 間違えると高い | +| Generate-And-Filter | `parallel(gens)` → rubric filter | まず選択肢、それから味 | +| Tournament | pairwise 審判 `agent` の bracket | 順位/味に鋭い物差しがない | +| Loop Until Done | `while` + 停止チェック + `budget` | どれだけ埋まっているか不明 | + +組み合わせはふつうです。深い調査はしばしば fanout → filter → verify → synthesize と重ねます。私たちのサンプルは、すでに二つの音の小さな和音です。 ## 次の段が受け取れる答え @@ -141,18 +162,22 @@ journal: [A ✓] [B ✓] [C ✓] [D ✓] resume: A hit → B hit → C 変更 → D は live ``` -## `review-changes` を歩く +## `review-changes` を歩く — ひとつの composition -四つの dimension が同じ二段の道を共有します——広げ、敵対的に確かめ、残ったものを残す。 +サンプルは「一つのパターン」ではありません。**Fanout-And-Synthesize** の中に **Adversarial Verification** が入り、終わりで軽く generate-and-filter がかかる——`isReal` の finding だけが残ります。 ```text correctness ── audit ── verify ──┐ security ── audit ── verify ──┤── 確認済みの finding performance ── audit ── verify ──┤ style ── audit ── verify ──┘ + fanout synthesize + └── 各 finding: 懐疑的 verify ──┘ ``` -Review は各 auditor を自分の机に置き、correctness の雑談が security へ流れ込まないようにします。Verify は各 finding を、著者ではない懐疑者へ渡します。本物だけが残り、severity で並びます。三つの癖が、お気に入りの席を失う感触が、そこにあります。 +`pipeline(DIMENSIONS, audit, verify)` が各 dimension に机を渡し、correctness の雑談が security へ流れないようにします。`verify` 内の verifier agent の `parallel` が敵対の和音です。ふつうのリスト filter が synthesize。`phase` が Review と Verify を印し、journal が各 `agent()` を覚えるので、止まっても audit をやり直さない。 + +三つの癖がお気に入りの席を失う感触があります。艦隊は二つの dimension で止められず、著者は審判ではなく、トポロジーは途中で漂いません。 ```python async def sample_workflow(ctx, args): @@ -205,4 +230,4 @@ Review が Verify に道を譲るのを見てください。完全な resume で s16 はバッチの回し方です。[s17 Goal Loop](../s17_goal_loop/) は戸口で別の問いをします。止めるべきか、もう一ターンか。繰り返せるレシピに硬い「完了」も要るときは、そちらと組んでください。 - + diff --git a/s16_workflow_runtime/README.md b/s16_workflow_runtime/README.md index 2e61641e..1f8ddd72 100644 --- a/s16_workflow_runtime/README.md +++ b/s16_workflow_runtime/README.md @@ -88,17 +88,38 @@ results = await ctx.pipeline(DIMENSIONS, audit, verify) confirmed = [f for r in results if r for f in r["confirmed"]] ``` -## Patterns, when they earn their keep +## Once you can write the recipe -You do not need a catalog. Notice what our sample already does, and you have three styles in hand. +The verbs above are flour and heat. What people keep reinventing are a handful of *shapes* — common patterns for dynamic agentic workflows. Think of them as a toolbox, not a mandatory menu. Reach for one when its pain shows up; leave the rest on the pegboard. -It **fans out** the change across review dimensions, each on a clean desk, then **synthesizes** one confirmed list. That is fan-out-and-synthesize — useful when pieces would contaminate each other in one crowded context. +![Six Workflow Patterns](images/six-workflow-patterns.svg) -Inside verify, a second helper tries to knock each finding down. That is adversarial verification — the structural answer to grading your own homework. +*Six shapes people keep reinventing. The script owns the topology; `agent` / `parallel` / `pipeline` / `phase` / journal are how each shape is spoken in this lesson.* -What survives is a filter over what was generated. Generate-and-filter: candidates in, only the ones that pass out. +**Classify-And-Act.** Pain: one generic helper is mediocre at everything. Shape: a classifier looks at the task, then routes to specialist A, B, or C. In this lesson that is usually one `agent({schema})` that returns a label, then an `if`/`match` in the script that calls the right follow-up `agent` (or a nested `workflow`). Skip it when every item truly needs the same treatment — routing is just ceremony then. -The same toolbox holds other cuts you will meet later — classify-and-act, tournament, loop-until-done. Borrow a style only when the extra cost buys clarity or safety you could not get cheaper. +**Fanout-And-Synthesize.** Pain: fifty files will not fit one tired context, and they contaminate each other if they try. Shape: split the work, run many agents, wait at a barrier, merge. Map it with `pipeline` when each item has its own stages, or `parallel` when the next step needs every result together; put the merge in ordinary Python after the gather. Skip it for three related files a single pass can hold. + +**Adversarial Verification.** Pain: the fox grades the henhouse. Shape: a worker produces; independent verifiers try to refute or stress-test; only survivors remain. Map it with a produce `agent`, then `parallel` of verifier `agent`s (ideally `schema`’d), then a filter. Phases help (“Review” then “Verify”). Skip it when the cost of a wrong answer is low — not every note needs a tribunal. + +**Generate-And-Filter.** Pain: you need options, not the first idea that sounded clever. Shape: many generators spill ideas into a rubric + dedupe filter; best stay, rest go. Map it with `parallel` over generators, then script-side filter (or one judge `agent` with a schema). Journal/resume matter when generation is expensive. Skip it when the space of good answers is already tiny. + +**Tournament.** Pain: absolute scores are mushy for taste and ranking (“how good is this name?”). Shape: pairwise judges, a bracket, a winner — comparative judgment beats lonely scoring. Map it with rounds of `parallel` judge `agent`s over pairs, looping in the script until one remains. Skip it when a clear rubric already picks a winner in one pass. + +**Loop Until Done.** Pain: you do not know how many passes the mine still holds. Shape: keep spawning while “new findings?” is yes; stop on dry rounds or a done condition. Map it with a `while` over `agent`/`parallel`, a schema’d stop check, and a hard `budget` so the loop cannot eat the house. Pair with journal resume when a long dig may pause. Skip it when the work has a known size — a fixed `pipeline` is simpler and safer. + +After a few of those have a face, the toolbox fits in one glance: + +| Pattern | Primitive sketch | Reach for it when… | +|---------|------------------|--------------------| +| Classify-And-Act | `agent` → branch → `agent` | Items need different specialists | +| Fanout-And-Synthesize | `pipeline` / `parallel` → merge | Many clean desks, then one summary | +| Adversarial Verification | produce → `parallel(verify)` → filter | Wrong answers are expensive | +| Generate-And-Filter | `parallel(gens)` → rubric filter | You need options, then taste | +| Tournament | pairwise judge `agent`s in a bracket | Ranking / taste without a sharp scale | +| Loop Until Done | `while` + stop check + `budget` | Unknown amount of buried work | + +Compositions are normal. Deep research often stacks fanout → filter → verify → synthesize. Our sample is already a small chord of two notes. ## Answers the next stage can hold @@ -141,18 +162,22 @@ journal: [A ✓] [B ✓] [C ✓] [D ✓] resume: A hit → B hit → C changed → D runs live ``` -## Walking `review-changes` +## Walking `review-changes` — a composition -Four dimensions share one two-stage path — fan out, verify adversarially, keep what survives: +The sample is not “one pattern.” It is **Fanout-And-Synthesize** with **Adversarial Verification** inside — and a light generate-and-filter at the end when only `isReal` findings survive. ```text correctness ── audit ── verify ──┐ security ── audit ── verify ──┤── confirmed findings performance ── audit ── verify ──┤ style ── audit ── verify ──┘ + fanout synthesize + └── each finding: skeptical verify ──┘ ``` -Review puts each auditor at its own desk so correctness talk does not bleed into security talk. Verify hands every finding to a skeptic who was not the author. Only the real ones remain, sorted by severity. You can almost feel the three failure modes losing their favorite seats. +`pipeline(DIMENSIONS, audit, verify)` gives each dimension its own desk so correctness talk does not bleed into security. Inside `verify`, `parallel` of verifier agents is the adversarial chord. Ordinary list filtering is the synthesize step. Phases mark Review then Verify; the journal remembers every `agent()` so a pause does not redo the audits. + +You can almost feel the three failure modes losing their favorite seats: the fleet cannot stop after two dimensions, the author is not the judge, and the topology does not drift mid-run. ```python async def sample_workflow(ctx, args): @@ -205,4 +230,4 @@ Watch Review give way to Verify. Watch agents flip from `done` to `cached` on a s16 is how a batch runs. [s17 Goal Loop](../s17_goal_loop/) asks a different question at the door: should we stop, or take another turn? Pair them when a repeatable recipe also needs a hard “done.” - + diff --git a/s16_workflow_runtime/README.zh.md b/s16_workflow_runtime/README.zh.md index 4063e355..9242e105 100644 --- a/s16_workflow_runtime/README.zh.md +++ b/s16_workflow_runtime/README.zh.md @@ -88,17 +88,38 @@ results = await ctx.pipeline(DIMENSIONS, audit, verify) confirmed = [f for r in results if r for f in r["confirmed"]] ``` -## 模式:用得着才拿 +## 会写菜谱之后 -不必背目录。看清示例在干什么,手里就有三种风格。 +上面那些动词是面粉和火候。人们反复发明的,是少数几种*形状*——动态 agentic workflow 的常见模式。把它们想成工具箱,不是必点菜单。痛点出现再伸手;其余的留在挂板上。 -它把改动**分发**到各个审查维度,每人一张干净桌子,再**汇总**成一份确认列表——fan-out-and-synthesize。碎片若挤在同一个嘈杂上下文里会互相串味时,这一招值钱。 +![六种 Workflow 模式](images/six-workflow-patterns.svg) -验证阶段里,第二个帮手专门来挑每条 finding 的刺——adversarial verification,结构上回答“别给自己的作业打高分”。 +*人们反复发明的六种形状。脚本掌管拓扑;本课里用 `agent` / `parallel` / `pipeline` / `phase` / journal 把每种形状说出来。* -留下来的,是对生成物做过滤。Generate-and-filter:候选进来,过关的留下。 +**Classify-And-Act(分类再行动)。** 痛点:一个万金油帮手样样稀松。形状:分类器看一眼任务,再路由到专家 A、B 或 C。本课里多半是一次带 `schema` 的 `agent` 返回标签,脚本里 `if`/`match` 再叫对的后续 `agent`(或嵌一层 `workflow`)。每件东西其实都该同样处理时,就别用——路由只是仪式。 -同一工具箱里还有 classify-and-act、tournament、loop-until-done,以后都会遇见。只有额外成本能买到更清楚或更稳妥的结果时,才去借一种风格。 +**Fanout-And-Synthesize(分发再汇总)。** 痛点:五十个文件塞不进一个疲倦的上下文,挤在一起还会串味。形状:拆开、多 agent 跑、在屏障处等齐、再合并。每件有自己阶段时用 `pipeline`;下一步必须凑齐全部结果时用 `parallel`;合并写在 gather 之后的普通 Python 里。三五个相关文件一趟就能看完时,就别用。 + +**Adversarial Verification(对抗验证)。** 痛点:狐狸给鸡窝打分。形状:工人产出;独立验证者来反驳或施压;只留下幸存者。映射:一次生产用的 `agent`,再 `parallel` 一组验证 `agent`(最好带 `schema`),然后过滤。`phase` 标出 “Review” 再 “Verify”。答错代价很低时就别用——不是每张便条都要法庭。 + +**Generate-And-Filter(生成再过滤)。** 痛点:你要的是选项,不是第一个听起来机灵的念头。形状:许多生成器把想法倒进“量尺 + 去重”的过滤器;最好的留下,其余丢掉。映射:`parallel` 生成,再在脚本里过滤(或一个带 schema 的裁判 `agent`)。生成很贵时,journal/续跑特别有用。好答案空间本来就很小,就别用。 + +**Tournament(锦标赛)。** 痛点:品味和排序上,绝对分数糊成一团(“这个名字有多好?”)。形状:两两比较的裁判、淘汰支架、冠军——相对判断胜过孤独打分。映射:脚本里多轮 `parallel` 的 pairwise 裁判 `agent`,直到剩一个。清晰量尺一趟就能选出赢家时,就别用。 + +**Loop Until Done(接到完为止)。** 痛点:你不知道矿里还要挖几轮。形状:只要“还有新发现?”为是就继续派工;连续空轮或完成条件出现就停。映射:`while` 包着 `agent`/`parallel`,用带 schema 的停止检查,再加硬性 `budget`,免得循环把家吃空。长挖可能暂停时,配上 journal 续跑。工作量已知时,固定 `pipeline` 更简单也更安全。 + +几种有了面孔之后,工具箱一眼就能看清: + +| 模式 | 原语速写 | 什么时候伸手 | +|------|----------|--------------| +| Classify-And-Act | `agent` → 分支 → `agent` | 条目需要不同专家 | +| Fanout-And-Synthesize | `pipeline` / `parallel` → 合并 | 许多干净桌子,再一份摘要 | +| Adversarial Verification | 产出 → `parallel(verify)` → 过滤 | 答错很贵 | +| Generate-And-Filter | `parallel(gens)` → 量尺过滤 | 先要选项,再要品味 | +| Tournament | 两两裁判 `agent` 搭支架 | 排序/品味却没有锋利刻度 | +| Loop Until Done | `while` + 停止检查 + `budget` | 埋着不知多少活 | + +组合是常态。深度调研常常叠成:分发 → 过滤 → 验证 → 汇总。我们的示例,已经是两个音符的一小段和弦。 ## 让下一阶段接得住的答案 @@ -141,18 +162,22 @@ journal: [A ✓] [B ✓] [C ✓] [D ✓] 续跑: A 命中 → B 命中 → C 改过 → D 实跑 ``` -## 跟着 `review-changes` 走一圈 +## 跟着 `review-changes` 走一圈——一种组合 -四个维度共用一条两阶段路径——先铺开,再对抗验证,留下活下来的: +示例不是“一种模式”。它是 **Fanout-And-Synthesize**,里面嵌着 **Adversarial Verification**——结尾再轻轻做一层 generate-and-filter:只留下 `isReal` 的 finding。 ```text correctness ── 审计 ── 验证 ──┐ security ── 审计 ── 验证 ──┤── 确认过的问题 performance ── 审计 ── 验证 ──┤ style ── 审计 ── 验证 ──┘ + 分发(fanout) 汇总(synthesize) + └── 每条 finding:怀疑式验证 ──┘ ``` -Review 让每个审计员坐自己的桌子,正确性的闲聊不至于淌进安全性。Verify 把每条 finding 交给不是作者的怀疑者。只留下真的,再按严重程度排好。那三种走偏,会感觉自己最爱的座位被撤了。 +`pipeline(DIMENSIONS, audit, verify)` 给每个维度自己的桌子,正确性的闲聊不至于淌进安全性。`verify` 里对验证 agent 做 `parallel`,就是对抗那一和弦。普通的列表过滤是汇总。`phase` 标出 Review 再 Verify;journal 记住每次 `agent()`,暂停也不会重做审计。 + +那三种走偏,会感觉自己最爱的座位被撤了:舰队不能在两个维度后收工,作者不当裁判,拓扑也不会在中途漂移。 ```python async def sample_workflow(ctx, args): @@ -205,4 +230,4 @@ python s16_workflow_runtime/code.py resume # 同一 runId;期待缓存命中 s16 讲一批活怎么跑。[s17 Goal Loop](../s17_goal_loop/) 在门口问另一个问题:该停,还是再来一轮?可重复的菜谱若还需要硬性的“做完”,可以和它一起用。 - + diff --git a/s16_workflow_runtime/images/six-workflow-patterns.svg b/s16_workflow_runtime/images/six-workflow-patterns.svg new file mode 100644 index 00000000..220cce6a --- /dev/null +++ b/s16_workflow_runtime/images/six-workflow-patterns.svg @@ -0,0 +1,159 @@ + + Six Workflow Patterns + A toolbox of six common dynamic workflow shapes: Classify-And-Act, Fanout-And-Synthesize, Adversarial Verification, Generate-And-Filter, Tournament, and Loop Until Done. + + + + + + + + + + + Six Workflow Patterns + a toolbox - not a mandatory menu. Compose with agent / parallel / pipeline + + + + + + + + + + + + + Classify-And-Act + + task + + + classifier + + + + + A + + B + + C + route to the right specialist + agent ' branch ' agent + + + Fanout-And-Synthesize + + task + + + + + + + + + + + + + + barrier + + + synthesize + parallel / pipeline ' merge + + + Adversarial Verification + + worker + + + + + verify + + verify + + verify + independents stress-test the work + agent ' parallel(verifiers) + + + Generate-And-Filter + + + + gen + gen + gen + + + + + + + + + + + filter + rubric+dedupe + + + + best + + drop + parallel(gens) ' filter + keep what survives the test + + + Tournament + + + + + a + b + c + d + + + + + + + judge + judge + + + + final + + + winner + pairwise agent judges + + + Loop Until Done + + agent + + + new? + findings + + + done + + yes - + spawn + stop when dry rounds appear + while + agent + budget + + Script owns the topology; agents judge inside each step. + diff --git a/web/public/course-assets/s16_workflow_runtime/six-workflow-patterns.svg b/web/public/course-assets/s16_workflow_runtime/six-workflow-patterns.svg new file mode 100644 index 00000000..220cce6a --- /dev/null +++ b/web/public/course-assets/s16_workflow_runtime/six-workflow-patterns.svg @@ -0,0 +1,159 @@ + + Six Workflow Patterns + A toolbox of six common dynamic workflow shapes: Classify-And-Act, Fanout-And-Synthesize, Adversarial Verification, Generate-And-Filter, Tournament, and Loop Until Done. + + + + + + + + + + + Six Workflow Patterns + a toolbox - not a mandatory menu. Compose with agent / parallel / pipeline + + + + + + + + + + + + + Classify-And-Act + + task + + + classifier + + + + + A + + B + + C + route to the right specialist + agent ' branch ' agent + + + Fanout-And-Synthesize + + task + + + + + + + + + + + + + + barrier + + + synthesize + parallel / pipeline ' merge + + + Adversarial Verification + + worker + + + + + verify + + verify + + verify + independents stress-test the work + agent ' parallel(verifiers) + + + Generate-And-Filter + + + + gen + gen + gen + + + + + + + + + + + filter + rubric+dedupe + + + + best + + drop + parallel(gens) ' filter + keep what survives the test + + + Tournament + + + + + a + b + c + d + + + + + + + judge + judge + + + + final + + + winner + pairwise agent judges + + + Loop Until Done + + agent + + + new? + findings + + + done + + yes - + spawn + stop when dry rounds appear + while + agent + budget + + Script owns the topology; agents judge inside each step. +