增长案例库 Maxed 归档 AI自动化综合

图工程详解:是什么、何时用、何时不用

Graph Engineering explained: what it is, when to use it and when not to

中文译文 · 23k 字

一句话摘要

图工程的概念与适用场景解析

图工程解析:它是什么、何时用它、何时不用 2026 年 7 月 24 日 · 21 分钟阅读 · 查看原文 ↗ Claude AI SEO 金融 大多数人使用 AI 时,只用到了它实际能力的 5% 到 10%。有一条更快的路,而且它比看上去更大。学会它,你就能优化庞大的流程,而不仅仅是个人的小任务。 这正是大公司里真正岗位背后的技能。做一份工作,和设计一百份工作怎么做,两者之间的区别。 我早期很幸运地接触到了它。当我在丹麦最好的大学之一读书时,我们有一整门课只讲一件事:如何把一个流程画成示意图,并让它尽可能高效。 当时它感觉很抽象。现在它正是顶级 AI 工程师在你的时间线上争论的那件事。 到本文结束时,你对图工程的理解,会超过你关注的几乎任何人:图到底是什么、那个立刻让你 AI 变快的测试、那个能自己回本的单一模式、这些东西在哪里悄悄坏掉、什么时候图是错的工具、以及如何用几分钟自己构建一张真正的图。 在我们进入正题之前,在 X 上关注我,并加入我刚创建的 Telegram 频道,我每天在那里发更多 AI 内容。两个都免费。 X - https://x.com/AnatoliKopadze Telegram - https://t.me/kopadzemp 内嵌帖子: 作者:Peter Steinberger 🦞 (@steipete) 帖子 ID:2078277297791189132 来源:https://x.com/steipete/status/2078277297791189132 回复对象:无 正文: > 我们还在聊循环,还是已经转向图了? 1 —— 这一切从哪来的。 一个月前,整个领域都在谈论循环。然后 Peter Steinberger 发了上面那行,互联网上刚刚学完循环的一个角落,一夜之间就宣布循环过时了。 这个玩笑之所以火,是因为它半真半假。如果你读过我的《循环》那篇文章,你已经有了地基。一个循环,是一个智能体反复改进一件事:试、查、调、再来。那是上个月的技能。 所有人转向的,不是一个更好的循环。而是一个由循环组成的图,一个网络,其中各个周期互相监视、互相纠正,而不是一个智能体独自追逐一个数字。 而工程师们几小时内就反驳了这股炒作,指出这是一个穿着新名字的、几十年前的想法。他们是对的,而这正是好消息。一个跑了三十年关键系统的模式,正是你愿意把工作托付给它的东西。 2 —— 图到底是什么。 一张图,只是为你 AI 工作画的一份计划,好让你能看见它。它回答两个问题:哪些任务需要发生,以及哪个任务必须等哪个。 它只有两个部分,把这两者搞对,就解决了大部分困惑。 一个方框叫节点(node)。它是一份工作:一个智能体做一个任务,一个东西进去,一个东西出来。研究一个竞品。写一份草稿。核对一个说法。 一根箭头叫边(edge)。它只是意味着一个任务需要另一个任务产出的东西,所以它必须等它。而且只有当真实的东西实际沿着它传递时,这根箭头才算数。 节点做思考。边搬运结果。这就是全部词汇。一旦你有了它,你就再也不需要定义了。 让一个节点在图里真正可用的东西,是契约(contract):一份有边界的任务、一个定义好的输入、一个定义好的输出。输出是一堵自由文本的节点,是一个只有人类能读的节点。输出形状固定的节点,是下一个节点无需猜测就能消费的节点,这才是全部意义。 ▸ 节点契约 任务:研究一个竞品的定价(一份任务,仅此而已) 输入:{ competitor: "name", url: "https://..." } ← 传进来,从不假设 输出:{ price: number, plan: string, source: url, date: "YYYY-MM-DD" } 模式:强制执行。如果 agent 返回自由文本,就拒绝并重试 为什么:定义好的输出,才能让下一个节点在没有人类夹在中间的情况下读取这个节点。这才是让它可接线的原因。 3 —— 找出假边的那个测试。 看你今天运行的 AI 工作流,一步一步走它。在每一步,问一件事:这一步真的需要上一步的结果吗? 如果答案是肯定的,这条边就是真的。保持顺序。如果答案是否定的,那就没有边,而这段等待是浪费的。那两个任务可以同时运行。 拿一个简单的例子:「检查文件 A 的 bug,然后检查文件 B 的 bug。」它读起来像个序列,但文件 B 的检查从来不看文件 A 返回了什么。它们一个接一个运行,仅仅是因为那是你输入它们的顺序。把它们并排跑,整件事会在较慢的那个单文件的时间里完成,而不是两者相加。 你几乎能在你画的任何工作流里找到两三条这样的假边。每一条都是你免费扔掉的时间。 4 —— 你当前的设置已经是一张图了。 当你把一个 agent 写成「做 A,然后 B,然后 C,然后 D」时,严格来说你已经画了一张图。只是它是最惨的一种:一条笔直的链,每个节点一根箭头进、一根箭头出。 它能正确运行。它也跑得慢、容易坏,因为一条链没有冗余。如果 C 卡住了,D 就永远不会发生,而 A 的工作被困在上游,无处可去。 图工程的第一个真正的技能,是重画那条链。拿你的线性工作流,对每一根箭头问那个假边问题。砍掉那些不搬运数据的箭头,那条线就塌缩成更宽的东西:几个能同时跑的独立任务,喂给一个需要它们全部的任务。 这件事重要的原因不是美观。一个有 40 步的线性工作流,有 40 个顺序失败点,以及全部 40 步相加的延迟。同样 40 个任务画成图,就只有实际存在的那么多真实依赖,通常是三到五个,并且以你最慢那一层的速度完成,而不是一切的总和。这就是一个五分钟的工作和一个十五秒的工作之间的区别,跑的是完全一样的事。 模型从来不是瓶颈。你画的那条线才是。 5 —— 那个回本的模式:菱形。 你不需要一百种形状。观察任何一个认真的 agent 系统工作,同一张图会一再出现。工作分裂,几个工人并排挖掘,某个东西检查他们找到的,然后一切合并回一个答案。 那张图叫菱形,而且它差不多是你今年唯一需要的模式。它的正式名字值得记住:扇出(fan out)、归约(reduce)、综合(synthesize)。 扇出去收集广度,用普通代码归约来压缩,用最后一个 agent 综合来写出答案。 Claude 里的 research 功能在生产环境里跑的正是这个。一个领队规划角度,工人们并行收集,发现被检查,然后才有一份报告到达你。一旦你能看见菱形,你就不会再问「我怎么让我的 agent 做更多步骤」,而开始问「分裂在哪,合并在哪」。第二个问题才是那个能放大的问题。 这是菱形在引擎盖下实际的样子。当你说「workflow」时,Claude 自己写下像这样的一个短脚本,并把协调当代码来跑,这就是为什么在 agent 之间传递结果不花任何额外的上下文。 // 一个市场扫描图 —— 菱形,Claude 在你说 "workflow" 时写下的 const angles = [ "pricing vs the top 3 competitors", "what buyers complain about in reviews", "the feature gaps in the category", "where the market moves in the next 12 months", ]; // 扇出 —— 每个角度一个研究员,全部同时进行 const raw = await parallel( angles.map(a => () => agent({ task: `research: ${a}. every claim needs a source url + date.`, schema: Finding, // 验证过的输出,不是自由文本 model: "cheap", // 无聊的节点 → 便宜的模型 })) ); // 归约 —— 普通代码,没有模型,没有 token const findings = dedupeBySource(raw.flat().filter(Boolean)); // 验证 —— 对每项发现一个全新的 skeptic,试图干掉它 const survivors = await parallel( findings.map(f => () => agent({ task: "try to disprove this. return keep | drop + why.", input: f, freshContext: true, // 从不复用研究员的聊天 model: "strong", // 判断节点 → 强模型 })) ).then(v => findings.filter((_, i) => v[i].verdict === "keep")); // 综合 —— 一个 agent 从存活者中写出答案 return agent({ task: "one report, ranked by confidence, sources attached.", input: survivors, model: "strong" }); 读一遍,整个手艺就都看见了:工作独立的地方做扇出,免费的代码做归约,全新的上下文做验证,无聊的节点用便宜模型、判断所在处用强模型,以及最后的一次综合。市场扫描、代码审查、或研究报告背后,是同一个骨架。换掉角度和提示词就行。 6 —— 检查者是整个诀窍。 现在讲几乎所有人都跳过、而它区分真正图与昂贵玩具的部分。 每一次对 AI 自我审查的严肃测试,都说着同一件事:模型会漏掉自己大部分错误。一个给自己的活打分的模型,对自己太宽容了。 所以你绝不让做了这活的 agent 去检查这活。 你在边上放一个独立的节点。它唯一的任务,就是在这项发现继续往前之前试图干掉它。如果它存活,就通过。如果不行,就在那死掉。 这里有个没人点破的坑:那个检查者需要干净的上下文。 给它和工人一样的聊天,它就不是在检查任何东西,它只是换了一种字体在对自己点头。共享一个上下文的 agent 图,只是一个穿了戏服的单个循环,而且它以同样的方式坏掉,只是更晚、更贵。 所以让验证者全新。自己的上下文。检查一个真实的信号,不是「agent 说它做完了没」,而是「这个测试真的通过没」。 然后把检查拆成三路。它正确吗?它是最新的吗?来源到底是真的吗?三个不同的镜头,抓住十个一模一样的镜头漏掉的东西。 ▸ 验证者节点 输入:来自工人的一项发现(只有发现,从不带工人的聊天) 上下文:全新且空的。它没见过它在评判的工作 检查:三个 skeptic 并行运行,各带一个不同的问题 1. 它正确吗?→ 这个说法真的站得住吗 2. 它是最新的吗?→ 来源是近期的,还是过时的东西 3. 来源是真的吗?→ 链接能解析到它所引用的说法吗 通过:只有当多数 skeptic 放它活时,才保留这项发现 失败:在它到达最终答案之前就丢掉 要记住的规则:一个工人和它的验证者绝不能共享上下文。它们一旦共享,你就退回了一个给作业打分的循环,只是账单更大。 7 —— 图实际在哪里坏掉。 1. 上下文崩塌。 扇出一千个节点,然后试图把全部一千个输出喂进最后一步,你在综合开始之前就把上下文窗口打爆了。 修复:分层扇入。把结果分批,总结每一批,然后合并总结,而不是那一大堆原始结果。 // 分层扇入 —— 永远别把 1,000 个原始输出倒进一个步骤 const batches = chunk(results, 40); // 每组 40 个 const summaries = await parallel( batches.map(b => () => agent({ task: "summarize this batch", input: b })) ); return agent({ task: "write the answer from the summaries", input: summaries }); // 最后一步读约 25 份总结,而不是 1,000 个原始输出 2. 假独立。 两个节点看起来独立,因为它们的提示词从不提到彼此,但它们都写同一个文件、或打同一个限速的 API。那是一条隐藏的边。 当 Bun 的团队第一次把一个大批量任务扇出到很多 agent 上时,它们共享一个工作空间,并互相覆盖了对方。 修复:给每个工人它自己隔离的空间,并且审计共享资源,而不只是共享数据。 // 隔离工人 —— 没有共享文件,没有共享工作空间 await parallel(files.map(f => () => agent({ task: `refactor ${f}`, worktree: true, // 每个 agent 在它自己的 git worktree 里工作 }))); // 它们无法互相覆盖,然后结果干净地合并 // 规则:任何两个写同一个文件的节点需要一条边,而不是并行 3. 静默的节点失败。 在链里,一次失败让一切停止,烦人但明显。在图里,两百个节点里的一个死节点,可以溜进一份看起来完整的报告。 修复:每个合并步骤,都把它收到的输入数量和它预期的数量核对,并标记出缺口,而不是在一半的数据上安静地继续跑。 // 扇入守卫 —— 抓住那个悄悄死掉的节点 const results = (await parallel(jobs)).filter(Boolean); // 丢掉的节点 = null if (results.length < jobs.length) { flag(`WARNING: ${jobs.length - results.length} of ${jobs.length} nodes returned nothing`); } // 绝不在一个不完整的集合上综合,然后称报告为完整 8 —— 你到底需不需要一张图? 按我这系列文章的传统,让我们诚实地盘一盘,这到底对谁有用。 一张图买的是广度。它买不到更好的判断力。 它是为宽度而生的工具,为一次完成的独立工作而生。当工作不宽时,那条线从来就不是问题。 在这些时候跳过图: 任务小或孤立。加一个函数,修一个 bug。协调纯粹是开销,单个 agent 更快更便宜。 你想批准每一步。图的全部意义,就是在没有你的情况下跑得够宽,所以一条紧的绳子会和它对着干。 你还不知道你在找什么。探索性工作想要一个你能驾驭的 agent,而不是一支锁死在计划里的舰队。 步骤真正互相依赖。把一张图强加到真正顺序性的工作上,只是加了成本,却零加速。 标志就是假边测试。如果你找不到两个之间没有边的任务,那就没有图可建。它是一个循环,而循环没问题。 9 —— 没人想听的部分:锚点。 这里有一个更深的坑,而它才是这整个转变真正的教训。 想象你建了完整的图。成对的检查者、审计节点、调校其他节点的元节点。每个节点监视另一个节点,而它们每一个都读报告。 审计把数字和财务数字核对,而财务数字首先来自同一个系统。 一切都一致。什么也没被验证。 这张图失败的方式,和那个单个循环完全一样,只是更晚、更贵,而且下坠的路上有更多绿灯。 拓扑本身买不到真相。图需要锚点(anchors):无法被反驳的节点。 真正跑过的测试,不是「应该通过」、而是确实通过的测试。真正落进银行账户的收入。真正留下来的客户。 而有些规则必须被冻结——那些优化器会想削弱它的规则,被保持在禁区,恰恰因为它们正是它为了赢会去弯曲的规则。 一张图,只有和它内部拒绝移动的那些东西一样诚实。 用无法反驳的数字评判它,它就接地气。让它给自己的报告打分,它就会自信地错着。 10 —— 在 Claude Code 里自己构建一张。 理论够了。如果你认定这是给你的,或者你只是想试试,我们来建一张。你可以在几分钟内构建一张真正的图,因为 Claude Code 直接内置了做这件事的工具,叫动态工作流(dynamic workflows)。 它归结为一个词:「workflow」。 把它放进你的提示词,Claude 就不再沿着单行步骤工作了。相反,它写一个短协调脚本,然后拉起一支协调的子 agent 舰队去运行它。 重要的一点是,协调是代码,不是对话。在 agent 之间传递结果,不会像聊天交接那样重新花掉你的上下文,这正是让一次运行能放大到整支舰队、而不淹没会话的原因。 打开一个你熟悉的真实仓库,粘贴这个: ▸ 图规格 目标:审计 src/routes/ 下的每一个路由文件,检查缺失的鉴权 扇出:每个文件一个 agent,全部并行运行 验证:对每项发现一个独立的检查者,带全新上下文 上限:这第一次运行 20 个文件 失败时:标记任何没返回的文件,绝不静默跳过 报告:一份合并后的、缺失鉴权的路由列表 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 运行它,发生的是这个。 首先,Claude 发信号说它正在构建一个工作流,而不是在普通聊天里回答,并在做任何事之前把计划给你看。你读它并批准。 然后舰队运行。每个文件一个 agent,全部同时进行,而你自己这个会话全程保持空闲。 而最后落下的,不是二十个要你翻的独立聊天。是一份报告。中间结果活在脚本里,从不在你的上下文里,所以你真正看到的只有最终答案。 那就是一张图。一句话,十几个 agent。当一次运行结果不错时,保存它,它就变成一条你可以永远按名字重跑的命令。 注意提示词里那个「20 个文件」的上限。它让你的第一次运行保持便宜,而且它暗示了每个演示都漏掉的东西:账单。 11 —— 你可以直接粘贴的现成图。 这里的每一个,都是同一张菱形,指向不同的工作。在一个真实文件夹里打开 Claude Code,把方括号里的部分换成你自己的,然后粘贴。「workflow」这个词就是告诉 Claude 去构建一支协调舰队、而不是单行步骤的那个信号。在任何东西发布之前,把自己留作最后那声「是」。 一个决策级研究台。取代一周的谷歌搜索、或一张昂贵的分析师发票。你的问题拆成角度,研究员们同时挖掘,一个 skeptic 攻击每一项发现,只有幸存者到达报告。 ▸ 图规格 目标:对 [你的问题] 做决策级研究 扇出:拆成 5 个不同角度,每个角度一个研究员,并行 规则:每项发现需要一条来源链接和一个日期 验证:一个 skeptic 攻击每项发现并试图反驳它,丢掉失败的 合并:幸存者合并成一份按置信度排序的报告 保存:research-report.md,然后把顶部发现给我看 人类门:在那之后,未经我询问,什么都不改 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 一个 SEO 内容机器。每次运行写出一份可以拿去排名的草稿,而且没有你它永远不发布。 ▸ 图规格 目标:一份关于 [主题] 的可排名草稿 并行任务(同时运行): 1. 当前排名靠前的页面覆盖了什么 2. 人们关于这个主题真正在问的问题 3. 那些顶部页面跳过了什么 合并:把三者合并成一份大纲,然后写一份完整草稿 验证:一个事实核查器,标记每一个没有来源的说法 保存:drafts/,被标记的说法列在顶部 人类门:永远不发布任何东西 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 一个上市套件。一次运行产出一整套发布物料,每一块都由你批准。 ▸ 图规格 目标:面向 [受众] 的 [产品] 完整发布套件 并行任务(研究,同时运行): 1. 描画买家,以及他们使用的原话 2. 摸清这些买家在网上哪里花时间 3. 收集竞品是怎么向他们推销的 合并:一页定位文档 人类门:在写之前,暂停并把定位文档给我看 并行任务(写作,基于那份文档): 1. 落地页文案 2. 一周的发布帖子 3. 一组外联消息 验证:一个检查者把每个资产和定位文档比对,标记任何偏离 保存:launch-kit/,在那之后未经我询问什么都不改 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 跨整个仓库的重构清扫。没有任何单个上下文能容纳的广度。 ▸ 图规格 目标:找出每一个超过 100 行的函数,并为每一个提出重构方案 扇出:每个文件一个 agent,并行 验证:对每个提出的重构一个独立的检查者,全新上下文 去重:把提议和一切已见过的比对 上限:这第一次运行 50 个文件 报告:有多少文件回来了,这样没有任何东西静默失败 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 一个规模未知的发现循环。用于那些你在深入之前不知道工作有多大的任务,比如一次 bug 清扫,找到一个 bug 会暴露另外三个。 ▸ 图规格 目标:在这个仓库里猎捕 [安全问题 / 坏掉的错误处理 / 死代码] 扇出:并行跑 finders 去重:把每一个新发现和一切已见过的核对 验证:对幸存者一个独立的检查者 循环:一直继续,直到连续两轮没发现新东西,然后停 上限:对 agent 总数设一个硬限制,好让它跑不掉 报告:按严重程度排序的最终列表 (以「workflow」这个词开始提示词,这样 Claude 会构建这张图) 先跑一个有范围的,看它花多少,然后加宽。当一次运行不错时,保存它,这里每一个都变成一条你按名字启动的命令。 12 —— 成本与监督。 一张图的成本,比一次普通聊天高。高得多。变便宜的是协调,不是工作本身。agent 仍然在烧 token,而一支 agent 舰队烧的是成堆的。 最清楚的例子是公开的。一个工程师用这套确切的设置重写了 Bun 运行时,把大约 535,000 行一种语言,翻译成另一种语言的一百多万行,用了大约十一天。手工做这接近一年的工作。 它跑了大约 50 个工作流,最多有 64 个 agent 同时进行。 它也花了大约 $165,000 的使用费,需要一个人类全程设计和盯着,还因为「这么多 AI 写的代码能否被安全审查」而受到了真正的批评。 这就是它诚实的形状。一张图能扇出到一千个 agent,啃掉任何单个上下文都容纳不下的工作。如果你把它指向错误的任务、或跳过锚点,它也能悄悄在后台花掉你的钱。 所以重型版本,是给那些有预算、有上限、有监控来运行它的团队的。如果那还不是你,你没有错过什么。从小处开始,看一次运行花多少,只有一次运行挣到了,才再放宽。 13 —— 这对你到底意味着什么。 这就是全貌。你现在知道图是什么、它在哪里发光、在哪里坏掉、以及它到底是为谁而生的。 你知道它的强项:广度,一次完成的独立工作。以及它的弱点:它买宽度,不买判断力,而且如果你把它指向错误的工作,它会花掉你的钱。 所以这个动作,不是把一切都图化。而是知道什么时候工作宽到需要一张图,什么时候一个简单的循环从头到尾就是答案。 我的建议:今晚就学假边测试。画出你当前的工作流,找出那些不搬运数据的边,删掉它们。这一个动作,就在你碰任何新工具之前,让你比大多数人更快。 大多数人会继续把步骤排成一条线。少数学会画图的人,会运营一支舰队。 **如果你想跟上 AI 里发生的一切,在 X 和 Telegram 上关注我: X - https://x.com/AnatoliKopadze Telegram - https://t.me/kopadzemp** 标签:# X # Claude # AI # SEO # 金融 # 指南 相关文章 10 个 SEO 外链 Claude 自动化,3 个月带来 61k AI 提及 外链建设就是试错。 SEO AI Claude 自动化

原文参考:https://maxed.wiki/posts/graph-engineering-explained-what-it-is-when-to-use-it-and-when-not-to/ (Maxed.wiki,本页为站内中文整理)