)
大多数人试着搭建多步 agent 时最后都做成了一条直线步骤一、步骤二、步骤三——每一步都礼貌地等上一步做完才开始。十个人里有九个会发现这些步骤里有一半根本不需要等待。它们不路由route不分支branch不并行parallelize。它们只是排队——一个大脑head、一个上下文context、一次只做一件事——直到上下文窗口被填满智能体也忘了自己原本在做什么。这套 14 步路线图就是把那条单文件直线变成一张图graph一张能在整支智能体集群fleet中扇出fan out、自我验证发现、并收敛到一个单个智能体永远无法承载的结果的graph。这里有一个没人明说的思维转变提示词Prompt是一句话。循环Loop是一个环。执行框架Harness是智能体立足的地板。但工作本身的形状——什么先运行、什么可以同时运行、什么必须等待其他一切——那个形状是一张图。节点Node负责思考边Edge负责传递结果。Claude Code 已经推出了直接构建这些图的工具动态工作流Dynamic Workflows。Claude 会写一段纯 JavaScript 编排脚本然后生成一支协同的子智能体subagent集群去执行它——而这种协调本身不消耗任何模型 token因为它是代码不是对话。01 Node 是任务Edge 是流动的东西一张 graph 只有两样东西把它们分清大半困惑就消失了。Node 是一个工作单元——一个 agent、一份有边界的 job、一份 input 进、一份 output 出。Edge 是依赖关系它说的是「这个 node 的 output 喂给那个 node 的 input」。仅此而已。常见的错误是把然后and then当作edge。Summarize the file and then tell me the weather总结这个文件然后告诉我天气这两者之间没有edge——天气并不消费那份摘要。那只是两个互不连接的 node被线性脚本硬串在一起。只有当数据真正跨过去时edge 才存在。学会对 agent 里每一个「然后」发问下一步会不会读上一步的 output如果不会就没有 edge等待就是浪费。Draw it as boxes and arrows. A box is an agent() call. An arrow is a variable passed from one call’s return into another’s prompt. If you can’t draw the arrow - if no variable crosses - the two boxes are independent, and independence is the thing you’ll exploit for the rest of this course. // 把它画成方框和箭头。一个方框就是一次 agent() 调用。 // 一个箭头就是从一次调用的返回值传入另一次调用提示词的变量。 // 如果你画不出箭头——如果没有变量跨越——那这两个方框就是独立的 // 而独立性正是本课程后续内容中你要利用的核心。02 你的线性脚本是一张退化的 graph当你把 agent 写成「先做 A再做 B再做 C再做 D」你其实已经画了一张 graph——一条没有分支的单链。每个 node 恰好只有一条 edge 进、一条 edge 出。它能正确跑。但它也跑得慢、且脆弱因为链没有冗余——C 卡住D 永远不会发生A 的工作也被困在上游无处可去。Graph engineering 的第一项真正技能是重画这条链。拿你的线性 agent对每一条箭头问 Step 1 那个问题。多数链里会有两三条箭头根本不携带数据——只是你碰巧按那个顺序打字而已。剪掉那些箭头链就会塌成更宽的结构几个可以同时跑的独立 node共同喂给一个需要它们全部结果的 node。03 给每个 node 一份 contract一个你无法推理的node就是一个你无法并行化的node节点 。解决办法是契约contract有边界的输入、有边界的输出、只做一件事。Input 是 node 会读的一切——必须显式传入绝不假设来自某个共享的上下文窗口。输出是一种确定的结构最好经过校验这样下一个节点就能直接消费而不用去猜。在工作流workflow里这份contract是通过 schema强制执行的。当你给 Claude 的 agent() 调用配上一个 JSON schema 时Claude 生成的子智能体就被强制返回经过校验的结构化数据——校验发生在工具调用tool-call层所以一旦不匹配Claude 会重试而不是把一段自由文本甩给你让你自己去解析、去祈祷。这就是「Claude 能接进 graph 的 node」和「只有人类读 output 才管用的 node」之间的差别。// 一个有真正contract的节点输入有界、输出经校验、只做一件事。 const ITEM { type: object, additionalProperties: false, properties: { title: { type: string }, url: { type: string }, impact: { type: string, enum: [high, medium, low] }, }, required: [title, url, impact], }; const result await agent(source.prompt, { label: research:${source.key}, schema: ITEM, // forces validated structured output agentType: general-purpose, }); // result 现在是下一个节点可以信任的结构 —— 而不是自由文本。04 把 edge 当作 data contractEdge 不只是「B 在 A 之后」。它是关于什么会跨过去的承诺A 产出这个 shapeB 被设计成消费这个 shape。当你用数据而不是顺序来命名 edge 时两件事会立刻变容易。你能一眼看出 edge 是否真实数据是否真的在流动只要 shape 成立你就能替换任一端的 node 而不弄坏整张 graph。在实践中edge 活在普通 JavaScript 里。扇出fan-out与综合synthesis之间的归并步骤——拍平flatten、去重dedupe、过滤filter——只是对 node 返回的 shape 做运算的代码。这是图式思维的一个隐性红利人们烧掉大量模型 token 干的事其实很多只是 edge——而 edge 是免费的。The temptation is to spawn an agent to “combine the results.” Resist it. If combining means flatten-and-dedupe, that’s results.flatMap(...) and a Set — deterministic, instant, zero tokens. Save agents for judgment, not for plumbing. A graph where every edge is an agent is a graph paying rent on its own wiring. // 诱惑在于派生一个智能体来合并结果。请抵制这种诱惑。 // 如果合并只是扁平化加去重那就是 results.flatMap(...) 加一个 Set // —— 确定性的、瞬时的、零 token。把智能体留给需要判断力的事 // 而不是管道工程。一张每条边都是智能体的图 // 是在为自己的接线付租金。。05 用 parallel() 做 Fan out这是能让一切物有所值的关键动作。当你有 N 个独立节点——N 个需要检查的信息源、N 个需要审查的文件、N 条需要审计的路由——你不应该把它们串成链。你应该告诉 Claude 把它们Fan out并同时运行。在工作流中这就是 parallel()Claude 接收一个 thunk 数组为每个 thunk 生成一个子智能体全部并发执行然后把结果数组返还给你。两个细节让它足够稳健。第一parallel() 是一个屏障barrier——它会等待所有 thunk 完成才返回这样下一阶段看到的才是完整的结果集合。第二抛出异常的 thunk 会被解析为 null而不是让整个批次都失败所以一个不稳定的智能体不会拖垮整次运行。务必对结果执行 .filter(Boolean)。并发度大致以你的核心数为上限超出的部分会排队执行所以即使你传入上百个 thunk它们最终都会完成——只是每次只跑一小批。phase(Research); // 九个信息源九个智能体同时运行. const raw await parallel( SOURCES.map((s) () agent(s.prompt, { label: research:${s.key}, phase: Research, schema: ITEM_SCHEMA, // 每个节点返回经校验的 JSON agentType: general-purpose, }), ), ); const collected raw.filter(Boolean); // 丢弃失败智能体产生的 nullFan-out 存在于 Claude 编写的代码中而不是模型对话里。Claude 自己的上下文从不需要同时容纳九个信息源——每个子智能体携带自己的上下文只有最终答案会返回。这正是让 Claude 能把工作流扩展到数十甚至数百个子智能体而不淹没会话的原因。编排层消耗零 token因为它不是 Claude 的又一轮思考。06 在 barrier 处 Fan inFan-out 只有在有东西把结果收拢时才有用。Fan-in 就是那些 edge 汇合的 node——一个 agent或一段代码一次性看到所有上游结果并做需要「完整集合」才能做的事跨 source dedupe、按 impact 排序、总数为空就 early-exit。这是 barrier 唯一值得付出 wall-clock 成本的地方。让 graph 保持高效的规则只有当某阶段真的需要把先前所有结果凑在一起时才用 barrier。要跨所有 source 做 dedupe用 barrier——才是正解。// 这条edge纯 JS无智能体零 token。 const flat collected.flatMap((c) c.items); log( Collected ${flat.length} items); phase(Curate); // 屏障节点需要完整集合来去重 排序。 const curated await agent( Dedupe and rank these by impact:\n${JSON.stringify(flat)}, { phase: Curate, schema: CURATED_SCHEMA }, );只是 flatten 一个 list那是 edge直接内联处理就好。判断的准则很简单也很残酷如果你写出了 parallel → transform → parallel而中间那个 transform 并不存在跨条目依赖那你本该用流水线pipeline完全跳过这道屏障barrier。07 菱形拓扑拆分 → 处理 → 归并把 fan-out 和 fan-in 合在一起就得到每一张严肃智能体图的主力拓扑菱形Diamond一个节点拆分任务多个节点并行处理一个节点归并结果。这正是市场扫描、依赖审计、代码审查、研究报告背后的形状——换掉信息源和提示词同一套骨架依然适用。这个规范形式有一个值得牢记的名字扇出fan-out → 归约reduce → 综合synthesize。扇出fan-out 以获取广度用纯代码归约来压缩用最后一个agent综合来撰写答案。一旦你看懂了这个菱形你就不会再问如何让我的智能体做更多步骤而是开始问哪里拆分、哪里合并——这才是真正能扩展规模的问题。08 用条件语句在运行时路由edge不是所有graph都是固定的。有时该走哪条dege取决于某个节点发现了什么。路由router节点检查一个结果并决定哪条下游路径被触发——先对工单分类再分支到对应的处理器先检查 diff 的大小再决定是做一次快速审查还是启动一次完整审计。在工作流中这只是对某个节点已校验输出的一次 JavaScript if 或 switch 判断因为控制流本身就存在于在代码里。这正是确定性determinism成为优势而非局限的地方。路由器的判断可以由 Claude 驱动一个子智能体做分类但路由本身是 Claude 写下的代码——因此对同一个分类结果它每次都以相同方式运行。你在节点上获得 Claude 的判断力在edge上获得脚本的可靠性。不会出现Claude 突然决定跳过审计这种意外的涌现行为——因为要跳过必须先被写进graph里而它没有被写进去。// 路由器节点智能体做分类代码选edge。 const { severity } await agent( Classify this diffs risk:\n${diff}, { schema: { type: object, properties: { severity: { enum: [low, high] } }, required: [severity] } }, ); let review; if (severity high) { // 重路径全面并行审计 review await parallel(FILES.map((f) () agent( Audit ${f}))); } else { // 轻路径一次快速评审 review await agent( Quick review of ${diff}); }09 在edge放置一个验证器verifier一张graph真正的杠杆不在于更多的智能体——而在于你能围绕它们构建出的、用来产生信心confidence的结构。验证器节点verifier node坐在结果被允许流向下游之前的那条边上它唯一的工作就是尝试推翻这个发现。如果发现挺过去了就通过如果没有它永远到达不了最终答案。有三种模式值得你随手掌握。对抗式验证Adversarial verify对每一个发现生成 N 个相互独立的怀疑者专门被提示去反驳它只有当多数怀疑者仍未能推翻它时才保留。多视角验证Perspective-diverse verify给每个验证者一个不同的视角——正确性、安全性、能否复现——因为多样性能捕捉到 N 个相同检查永远抓不住的失败模式。评审团Judge panel从不同角度生成 N 次尝试用并行的评委给它们打分从获胜者中综合结果同时嫁接其他优秀方案里最好的部分。正是这种模式让一支真实团队成功把 Bun 运行时移植了过去并在循环中内建了对抗式代码审查。10 隔离节点避免一次失败污染整张graph在一条链里失败会级联传播——C 挂了D 永远不会运行整个流程停摆。而在一张graph里失败应该被限制在其所在的节点内。这一点在某种程度上已经实现了parallel() 内部抛出异常的 thunk 会被解析为 null所以八个正常的智能体依然会返回结果一个坏的会掉线。你的 .filter(Boolean) 就是那道containment隔离防线。设计每一个fan-in节点时都要能容忍缺失的输入而不是假设集合总是完整的。更隐蔽的失败是节点之间互相踩脚。当多个智能体并行写文件时它们可能会发生冲突。解决办法是隔离“worktree”——每个智能体在自己的 git worktree 中运行在一个沙盒里完成工作然后干净地合并回去。只有当节点确实需要并行写入时才使用它——它是那一种确实需要它的拓扑的安全带而不是每次运行都要默认缴纳的税。11 添加一个循环——但要确保它能收敛有时候任务有多大只有做起来才知道未知规模的发现型任务、一场 bug 排查找到一个 bug 却牵出另外三个。这就需要一个循环cycle——一条回到早期节点的受控edge。危险显而易见不收敛的循环就是一个无限循环它会不断派生智能体直到烧光你的Token预算。能够收敛的模式叫做循环直到枯竭loop-until-dry持续生成探测者节点直到连续 K 轮什么新东西都没发现然后停止。真正决定成败的一个细节——也是几乎所有人第一次都会犯的错误——是你拿什么去重。要针对所有见过的seen去重而不是只针对已确认的confirmed结果去重。否则被否决的发现会在每一轮重新出现循环永远跑不干你就造出了一台不断付费重新发现同样死胡同的机器。const seen new Set(); const confirmed []; let dry 0; while (dry 2) { // 连续 2 轮空手而归即停止 const found (await parallel( FINDERS.map((f) () agent(f.prompt, { schema: BUGS })) )).filter(Boolean).flatMap((r) r.bugs); const fresh found.filter((b) !seen.has(key(b))); if (!fresh.length) { dry; continue; } // 无新发现 → 趋向枯竭 dry 0; fresh.forEach((b) seen.add(key(b))); // 对 SEEN 去重而非 confirmed // 每个新发现在计入前先经多视角验证 const judged await parallel(fresh.map((b) () parallel([correctness, security, repro].map((lens) () agent(Judge ”${b.desc}” via ${lens} — real?, { schema: VERDICT }))) .then((v) ({ b, real: v.filter(Boolean).filter((x) x.real).length 2 })))); confirmed.push(...judged.filter((v) v.real).map((v) v.b)); }12 在各节点之间分层调配模型不是每个节点都需要你最好的模型。graph让这一点变得一目了然而单个智能体永远做不到有些节点有界且重复提取这个字段、给这个工单分类有些则承载真正的判断综合报告、裁定发现。把那些无聊的节点跑在更便宜的模型上把昂贵的 token 花在真正需要判断力的地方。在工作流中Claude 派生的每个子智能体默认继承你的会话模型除非脚本覆盖它——所以一次大型运行默认全按你的会话模型档位计费。单次 agent() 调用上的 model 选项可以告诉 Claude 把那一个节点路由到别的模型。大型运行前先检查 /model然后让 Claude 把 fan-out 里重复性 node 降到更便宜的 model合并节点保持高档。这是那根杠杆不改 graph 形状就能把吃 token 的 graph 从昂贵变成划算。13 拓扑结构决定你的成本与延迟Graph 的形状不是装饰——它是影响实际运行时间的最大杠杆。绊倒所有人的选择题是parallel() 还是 pipeline()。parallel() 的屏障会让所有任务等待最慢的节点完成下一阶段才能开始而 pipeline() 让每个条目独立地流经所有阶段没有屏障——条目 A 可以在第 3 阶段时条目 B 还在第 1 阶段。快的条目提前完成而不是在慢条目后面空等。默认使用 pipeline()。只有当一个阶段确实需要一次性拿到所有先前结果时才用屏障——例如跨集合去重、根据总数提前退出、或者一个需要与其他发现逐一比对的提示词。代码更干净和各阶段感觉是分开的都不是理由屏障造成的延迟是真实的、可测量的、被浪费掉的时间。分开separate不等于同步synchronized。让 Claude 自己画 graph——self-routing最后一招对那些你无法提前规划的活别再手动画 graph。借助动态工作流dynamic workflows你只需描述目标Claude 会自己写出编排脚本——拆解任务、选择fan-out方式、生成一支协同的子智能体集群、并综合出最终结果。你得到的是一张为这次运行量身定制的图而不是一张你只能寄望刚好适用的固定图。有三种入口。在提示词里说出workflow这个词Claude 就会为该任务写一个工作流。运行已保存或内置的工作流—— /deep-research 就是一张已在生产环境中交付的真实的图确定范围 → 并行搜索 → 抓取 → 对抗式验证 → 综合正是本课程讲的那副骨架。或者开启 ultracode让 Claude 为会话中每一项重大任务都规划一个工作流。当某次运行效果不错时按下 s 键即可把这段脚本保存进 .claude/workflows/ 目录——纳入版本控制、可按名字重新运行成为任何克隆了这个仓库的人都能启动的一张graph。› Run a workflow to audit every route under src/routes/ for missing auth. Spawn one agent per route file, then verify each finding before reporting. ● Claude wrote an orchestration script · launching in background… /workflows — auth-audit · running ✓ Scope 1/1 2.1k tok · 4s ✓ Fan-out 18/18 one agent per route file ◯ Verify 11/18 3-vote skeptics per finding… ○ Synthesize 0/1 waiting on verify session stays responsive — keep working while the fleet runs --- › 运行一个工作流审计 src/routes/ 下所有路由的鉴权缺失问题。 每个路由文件派生一个智能体每个发现上报前先经过验证。 ● Claude 已编写编排脚本 · 后台启动中… /workflows — auth-audit · running ✓ Scope 1/1 2.1k tok · 4s ✓ Fan-out 18/18 每个路由文件一个智能体 ◯ Verify 11/18 每个发现由 3 票怀疑者裁决… ○ Synthesize 0/1 等待验证完成 会话保持响应 —— 舰队运行时你可以继续工作本周就可以和 Claude 一起构建的六张图全路由安全扫描。Claude 为每个路由文件派生一个子agent各自排查缺失的鉴权检查再由验证器通道确认每个发现后才进入报告。这是任何单一上下文都无法承载的广度。用 /deep-research 生成带引用的报告。一张已随 Claude Code 交付的graph。Claude 把你的问题分解为不同角度运行并行搜索去重信息源然后用三票怀疑者对每条论断做对抗式验证最后才动笔。逐文件移植模块。Bun 的天花板缩放到你的仓库。Claude 把翻译工作fan-out到各个文件用测试套件作为每个文件的关卡gate把失败的循环回炉——对抗式评审能拦下单次遍历会带bug上线的东西。对 diff 的对抗式评审。Claude 按 diff 大小路由小改动一次快速评审大改动触发全面并行审计评审者各持不同视角——正确性、安全性、性能——最后由评审团综合。定时生态扫描。保存一次永远复用。Claude 并行检查多个信息源——发布、博客、讨论区——在屏障处按影响力排序写出摘要。版本控制在 .claude/workflows/ 中按名称即可启动。未知规模的探索。你不知道有多少个 Bug。Claude 并行运行发现者把每个新发现与所有已见过的去重验证存活者持续循环直到连续两轮一无所获——然后停止。结语:Prompter 问问题。Architect 画 graph。线性agent从来不是天花板——它只是第一种形状是每个人最先想到的那种因为它符合我们打字的方式。一行、一个大脑、一次只做一件事。一旦你能看清node 和 edge你就会停止要求智能体做更多步骤转而开始要求这张graph变得更宽在工作彼此独立的地方fan-out在需要信任度的地方在边上设卡验证在不需要判断力的地方分层调配模型。多数人会继续把步骤排成一条线。学会画 graph 的人会开一支集群——并且再也感觉不到其余人头顶那道天花板。学AI大模型的正确顺序千万不要搞错了2026年AI风口已来各行各业的AI渗透肉眼可见超多公司要么转型做AI相关产品要么高薪挖AI技术人才机遇直接摆在眼前有往AI方向发展或者本身有后端编程基础的朋友直接冲AI大模型应用开发转岗超合适就算暂时不打算转岗了解大模型、RAG、Prompt、Agent这些热门概念能上手做简单项目也绝对是求职加分王给大家整理了超全最新的AI大模型应用开发学习清单和资料手把手帮你快速入门学习路线:✅大模型基础认知—大模型核心原理、发展历程、主流模型GPT、文心一言等特点解析✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑✅开发基础能力—Python进阶、API接口调用、大模型开发框架LangChain等实操✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经以上6大模块看似清晰好上手实则每个部分都有扎实的核心内容需要吃透我把大模型的学习全流程已经整理好了抓住AI时代风口轻松解锁职业新可能希望大家都能把握机遇实现薪资/职业跃迁这份完整版的大模型 AI 学习资料已经上传CSDN朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费】