Claude 图工程:从 0 到图架构师的 14 步路线图(完整课程)

发布于 2026年07月27日 11:34 #AI#Claude 原文链接

Claude 图工程:从 0 到图架构师的 14 步路线图(完整课程) 封面图
  • 将线性代理重画为图,切断无数据依赖的箭头,独立节点可并行运行
  • 给每个节点定义有界输入输出契约,通过 JSON 模式强制验证结构化数据
  • 使用 parallel()扇出独立任务,屏障处扇入归约,构建钻石拓扑
  • 在边上放置验证器节点,用对抗性验证和多样化视角确保结果可靠性
  • 根据节点复杂度分层模型,用 pipeline()替代屏障减少延迟,让 Claude 自路由

大多数尝试构建多步代理的人最终都得到一条直线。第一步、第二步、第三步,每一步都在礼貌地等待上一步完成后才开始。

十分之九的人会注意到,这些步骤中有一半根本不需要等待。

它们不需要路由,不需要分支,不需要并行化。它们只是排队,一个头、一个上下文、一次做一件事,直到窗口填满,代理忘记了自己在做什么。

关注我的 Substack 获取最新 AI 前沿内容:movez.substack.com

这是一份 14 步路线图,它能把那条单一的直线变成一张图:一张能够横跨整个舰队展开工作、自我验证发现、并聚合出单个代理永远无法承载的结果的图。

Claude 图工程架构概览
Claude 图工程架构概览

这里有一个没有人明说的转变。提示是一个句子。循环是一个周期。框架是代理立足的地板。

但工作本身的形状,什么在什么之前运行,什么可以同时运行,什么必须等待其他所有事情完成,这个形状就是一张图。节点进行思考。边传递结果。

Claude Code 已经发布了直接构建这些图的工具:动态工作流。

Claude 编写一个简单的 JavaScript 编排脚本,然后生成一个协调的子代理舰队来执行它,而协调本身消耗零模型令牌,因为它是代码,不是对话。

动态工作流示例
动态工作流示例

01. 节点是任务,边是流动的内容

一张图只有两样东西,把它们搞清楚就能解决大部分困惑。节点是一个工作单元,一个代理、一个有边界的任务、一个输入一个输出。

边是一种依赖关系:它表示这个节点的输出会送入那个节点的输入,仅此而已。

节点与边的关系
节点与边的关系

人们常犯的错误是把「然后」当作边。「总结文件,然后告诉我天气」这句话中,两者之间没有边,因为天气不需要消耗摘要。

这是两个被线性脚本无谓串联起来的断开节点。只有当数据真正穿过时,边才存在。

学会对你代理中的每一个「然后」提出这个问题:下一步是否读取了上一步的输出?如果没有,就没有边,等待就是浪费。

识别虚假依赖
识别虚假依赖
边的数据流验证
边的数据流验证

02. 你的线性脚本是一张退化的图

当你把一个代理写成「做 A,然后 B,然后 C,然后 D」时,你已经画了一张图:一条没有分支的单链。每个节点恰好有一条边入和一条边出。

它能正确运行,但也运行得缓慢且脆弱。因为链条没有冗余:如果 C 停滞,D 永远不会发生,A 的工作被困在上游,无处可去。

线性链与并行对比
线性链与并行对比

图工程的第一个真正技能是重画这条链。拿出你的线性代理,对每个箭头,问自己第一步的问题。

大多数链条有两三个不携带数据的箭头,它们只是你碰巧输入的顺序。

切断那些箭头,链条就会展开成更宽的形状:几个独立节点可以同时运行,供给一个需要它们全部的单个节点。

链到图的转换
链到图的转换

03. 给每个节点一份契约

一个你无法推理的节点,是一个你无法并行化的节点。解决方案是一份契约:有界的输入、有界的输出、恰好一项工作。

输入就是节点读取的任何内容,必须明确传入,永远不能假设来自共享窗口。输出是一个定义好的形状,最好经过验证,这样下一个节点可以直接使用而不需要猜测。

节点契约示例
节点契约示例

在工作流中,这份契约通过模式来强制执行。当你给 Claude 一个带有 JSON 模式的 Agent() 调用时,Claude 生成的子代理会被强制返回经过验证的结构化数据。验证发生在工具调用层,所以 Claude 会在不匹配时重试,而不是给你需要解析和祈祷的自由文本。

这就是 Claude 能够连接到图中的节点,与只有人类读取输出时才能工作的节点之间的区别。

JSON Schema 验证
JSON Schema 验证
验证流程
验证流程

04. 把边当作数据契约

边不只是「B 在 A 之后」。它是一个关于什么穿过的承诺:A 产生这个形状,B 被构建来消费这个形状。当你用数据而不是顺序来命名边时,两件事会变得更容易。

边作为数据契约
边作为数据契约

你可以立即看到边是否真实(数据真的在移动吗?),而且只要形状保持不变,你可以交换两端的节点而不会破坏图。

实际上,边存在于普通的 JavaScript 中。扇出和合成之间的归约步骤包括扁平化、去重、过滤,这只是对节点返回的形状进行操作的代码。

不需要代理。图思维的一个安静胜利是:人们大量消耗模型令牌的工作中有很大一部分实际上是边,而边是免费的。

边处理代码
边处理代码
边的可视化
边的可视化

05. 用 parallel() 进行扇出

这是为一切买单的一步。当你有 N 个独立节点时,N 个要检查的来源、N 个要审查的文件、N 个要审计的路由,你不需要串联它们。

你告诉 Claude 把它们扇出并立即运行。在工作流中,这就是 parallel():Claude 接受一个 thunk 数组,每个 thunk 生成一个子代理,全部并发执行,然后把结果数组交还给你。

parallel() 扇出示意图
parallel() 扇出示意图

有两个细节让它变得鲁棒。首先,parallel() 是一个屏障,它会等待每个 thunk 完成后才返回,所以下一阶段会看到完整的集合。其次,一个抛出异常的 thunk 会解析为 null,而不是拒绝整个批次,所以一个不可靠的代理不会毁掉整个运行。

永远记得对结果使用 .filter(Boolean)。并发上限大约是你的核心数,超过的会排队,所以你可以传入一百个 thunk,它们都会完成,只是一次处理几个。

扇出存在于 Claude 编写的代码中,而不是模型对话中。Claude 自己的上下文永远不会同时容纳九个来源,每个子代理携带自己的上下文,只有最终答案回来。

这就是让 Claude 能够将工作流扩展到几十个或几百个子代理而不会淹没会话的原因。编排层消耗零令牌,因为它不是 Claude 思考的另一轮。

扇出代码示例
扇出代码示例

06. 在屏障处扇入

扇出只有在有东西收集它时才有用。扇入是边汇聚的节点,在这里一个代理或一段代码一次性看到所有上游结果,并做一些需要完整集合的事情:跨来源去重、按影响排名、如果总数为空则提前退出。这是屏障值得它的墙上时钟成本的唯一地方。

保持图快速的规则是:只有当一个阶段真正需要每个先前结果在一起时,才使用屏障。跨所有来源去重?屏障,正确。

只是扁平化一个列表?那是边,内联完成。这个嗅觉测试残酷而简单:如果你写了 parallel → transform → parallel,而中间的转换没有跨项依赖,你应该使用 pipeline 并完全跳过屏障。

07. 钻石拓扑:拆分 → 工作 → 合并

把扇出和扇入放在一起,你就得到了每个严肃代理图的主力拓扑:钻石。

一个节点拆分任务,许多节点并行工作,一个节点合并。这是市场扫描、依赖审计、代码审查、研究报告背后的形状,交换来源和提示,同一个骨架就能适应。

标准形式有一个值得记住的名字:扇出 → 归约 → 合成。扇出来获取广度,用普通代码归约来压缩它,用最终代理来合成并写出答案。

一旦你看到了钻石,你就不再问「我如何让我的代理做更多步骤」,而是开始问「哪里拆分,哪里合并」,这才是真正扩展的问题。

08. 运行时用条件路由边

不是每张图都是固定的。有时走哪条边取决于节点发现了什么。路由器节点检查结果并决定触发哪条下游路径,分类工单,然后分支到正确的处理程序;检查差异大小,然后要么进行快速审查,要么启动完整审计。

在工作流中,这只是对节点验证输出的 JavaScript if 或 switch,因为控制流存在于代码中。

这就是确定性成为特性而非限制的地方。路由器的决定可以由 Claude 驱动,一个子代理进行分类,但路由是 Claude 编写的代码,所以对于相同的分类,它每次都以相同的方式运行。

你在节点得到 Claude 的判断,在边得到脚本的可靠性。不会出现「Claude 决定跳过审计」这样的意外,因为跳过必须被写入图中,而它并没有。

09. 在边上放一个验证器

图的真正杠杆不是更多的代理,而是你可以围绕它们构建来产生信心的结构。

验证器节点位于结果被允许向下游传递之前的边上,它唯一的工作就是试图杀死这个发现。如果它存活下来,就通过;如果没有,它永远不会到达答案。

有三个模式值得你掌握。

对抗性验证:对于每个发现,生成 N 个独立的怀疑论者,提示他们反驳它;只有大多数存活时才保留它。

视角多样化验证:给每个验证者一个不同的视角,正确性、安全性、是否可复现,因为多样性会捕获 N 个相同检查永远不会发现的失败模式。

评判小组:从不同角度生成 N 次尝试,用并行评判者打分,从获胜者那里合成,同时嫁接亚军的最佳部分。

这正是让一个真实团队将 Bun 运行时移植成功的模式,他们在循环中内置了对抗性代码审查。

10. 隔离节点,让一个失败不会毒化整张图

在链条中,失败会级联,C 死亡,D 永远不会运行,整个事情停止。在图中,失败应该被限制在它的节点。

这已经部分成立了:parallel() 内部抛出的 thunk 会解析为 null,所以八个好的代理仍然返回,而一个坏的退出。你的 .filter(Boolean) 就是遏制。

设计每个扇入来容忍缺失的输入,而不是假设有完整的集合。

更微妙的失败是节点互相踩到。当代理并行写入文件时,它们可能会冲突。

解决方案是隔离:「worktree」,每个代理在自己的 git 工作树中运行,在沙箱中完成工作,并干净地合并。

只在节点实际并行写入时使用它。这是需要它的那个拓扑的安全带,而不是每次运行的默认税。

11. 添加循环,但让它收敛

有时你直到进入工作中才知道任务有多大:未知大小的发现,一个漏洞扫描,找到一个漏洞会揭示三个更多。这需要一个循环,一个受控的边回到更早的节点。

危险是显而易见的:一个不收敛的循环是一个无限循环,它会生成代理直到你的预算耗尽。

收敛的模式是循环直到干涸:持续生成发现者,直到连续 K 轮没有新发现,然后停止。决定成败的一个细节,也是几乎每个人第一次都会犯的错误,是你去重的依据。

根据所有看到的内容去重,而不仅仅是确认的结果。否则被拒绝的发现每轮都会重新出现,循环永远不会干涸,你就建造了一台机器,付钱让它永远重新发现同样的死胡同。

12. 在节点之间分层模型

不是每个节点都需要你最好的模型。图以单个代理永远不会的方式使这一点变得明显:一些节点是有界和重复的,提取这个字段、分类这个工单,一些节点承载真正的判断,合成报告、裁决发现。

在更便宜的模型上运行无聊的节点,把你昂贵的令牌花在真正需要判断力的地方。

在工作流中,Claude 生成的每个子代理都会继承你的会话模型,除非脚本覆盖它,所以默认情况下,一次大运行完全按照你的会话层级计费。单个 Agent() 调用上的模型选项告诉 Claude 只将该节点路由到别处。

在大运行前检查 /model,然后让 Claude 将扇出的重复节点路由到更便宜的模型,同时保持合并节点在高级模型上。这是一个杠杆,它在不触及形状的情况下,将消耗大量令牌的图从昂贵变成经济。

13. 拓扑就是你的成本和延迟

图的形状不是装饰性的,它是墙上时钟时间的最大单一杠杆。绊倒每个人的选择是:parallel() 与 pipeline()。parallel() 屏障让一切都等待最慢的节点,然后下一阶段才开始。

pipeline() 独立地将每个项目流式传输通过所有阶段,没有屏障,项目 A 可以在阶段 3,而项目 B 仍在阶段 1。快速项目提前完成,而不是在慢速项目后面空转。

默认使用 pipeline()。只有当一个阶段真正需要每个先前结果在一起时,才使用屏障,跨集合去重、对总数的提前退出、一个比较「其他发现」的提示。「代码更干净」和「阶段感觉分开」不是理由;屏障延迟是真实的、可测量的、浪费的时间。分开不等于同步。

14. 让 Claude 画图:自路由

最后一步是,对于你无法提前计划的工作,停止手工画图。

使用动态工作流,你描述目标,Claude 自己编写编排脚本,分解任务、选择扇出、生成一个协调的子代理舰队,并合成结果。你得到一张为这次运行量身定制的图,而不是你希望适合的固定图。

有三种进入方式。在你的提示中说「workflow」这个词,Claude 会为这个任务写一个。运行一个保存的或捆绑的工作流,/deep-research 是一个已经在生产中发布的真实图:范围界定 → 并行搜索 → 获取 → 对抗性验证 → 合成,正是本课程中的精确骨架。

或者打开 ultracode,Claude 会为会话中的每个实质性任务规划一个工作流。当运行良好时,按 s 将其脚本保存到 .claude/workflows/,版本控制、可按名称重新运行,任何克隆仓库的人都可以启动的图。

本周用 Claude 构建的六张图

  • 每条路由的安全扫描。Claude 为每个路由文件生成一个子代理,每个都在寻找缺失的身份验证检查,然后验证器通过确认每个发现,然后才到达报告。这是单个上下文无法承载的广度。
  • 使用 /deep-research 的引用报告。一个已经在 Claude Code 中发布的图。Claude 将你的问题分解成不同的角度,运行并行搜索,去重来源,然后在写作前用三票怀疑论者对抗性地验证每个主张。
  • 逐个文件移植模块。Bun 的上限,扩展到你的仓库。Claude 在文件之间扇出翻译,在每个文件上运行测试套件作为门,并将失败循环回去,对抗性审查捕获单次通过会发送损坏的东西。
  • 差异的对抗性审查。Claude 根据差异大小路由:小改动得到一次快速通过,大改动触发完整的并行审计,评审人员使用不同的视角,正确性、安全性、性能,然后一个评判小组进行合成。
  • 按计划进行的生态系统扫描。保存一次,永远重新运行。Claude 并行检查许多来源,版本、博客、讨论,在屏障处按影响排名,并撰写摘要。版本控制在 .claude/workflows/ 中,可按名称启动。
  • 未知大小的发现。你不知道那里有多少错误。Claude 并行运行发现者,对每个新发现与所有看到的内容进行去重,验证幸存者,并持续循环直到两轮没有新发现,然后停止。

结论

提示者提出问题。架构师画出一张图。

线性代理从来不是天花板,它只是第一个形状,是每个人都能到达的形状,因为它匹配我们打字的方式。一行,一个头,一次一件事。

一旦你能看到节点和边,你就不再要求代理做更多,而是开始要求图做得更宽:在工作独立的地方扇出,在信心重要的地方门控边,在不需要判断的地方分层模型。

大多数人会继续排队步骤。那些学会画图的人将运行一支舰队,并且永远不会注意到其他人被困在下面的天花板。

评论互动

© 2026 王若风的技术博客 · Powered by Astro