Claude Code 的完整图工程(Graph Engineering)实战指南

@Gyome1_
英语1天前 · 2026年7月23日
146K
443
59
6
1.1K

TL;DR

深入探讨 AI 领域的图工程,详细介绍如何利用节点、边和屏障,将多个 Claude Agents 编排成一个可靠且结构化的系统。

大多数人仍然像使用一个非常昂贵的实习生一样使用 Claude Code。

他们给它一个任务,等一个答案,然后手动决定下一步做什么。

但那些从 AI 中获得最大杠杆的团队,正在构建更接近一个小型分布式系统的东西。

Gyomei - inline image

一个 Agent 负责界定问题范围。

五个更便宜的 Agent 并行搜索。

一个确定性脚本去除重复项。

三个持怀疑态度的 Agent 试图推翻这些发现。

一个顶级模型做出最终判断。

这就是图工程。

在继续阅读之前:

收藏本指南,这样当你开始构建自己的 Claude 工作流时,可以随时回到这些图模式。

并且关注

@Gyome1_ -

我会拆解 Claude Code、AI Agent,以及将单个模型转化为可靠工程工作流的系统。

我花了数周时间剖析真实的 Agent 架构、工作流图和生产模式,将图工程重新构建成一本实用的操作手册。

与其写一个更长的提示词,不如设计信息在系统中流动的路径:

线性 → 扇出 → 归约 → 验证 → 综合

每个 Agent 成为一个节点,承担有限的工作。每条边携带结构化数据。路由器决定哪个分支运行。验证器拒绝弱输出。循环持续进行,直到图不再发现任何新内容。

重要的转变是,Claude Code 不再需要像单个智能体那样,在一个巨大的检查清单中逐项工作。

它可以生成编排代码,派出一组专门的子 Agent,将其输出路由到不同的模型,并仅在证据通过验证后才组合最终结果。

Gyomei - inline image

这些基本模式并不新鲜。软件工程师几十年来一直在使用 DAG、管道、屏障、MapReduce 和分布式工作节点。

改变的是每个节点内部现在放置的是什么。

一个节点可以搜索仓库、审计迁移、挑战架构决策、检查测试失败,或将五十个独立的发现综合成一个带有引用的报告。

本指南将整个系统从最简单的线性 Agent 分解到菱形图、路由器节点、对抗性验证器面板、收敛循环、模型分层,以及直接在 Claude Code 内部生成的动态工作流

到最后,你将能够面对一个大型任务,不再问:

“我应该写什么提示词?”

1. 图工程从账单开始

图工程通常被呈现为一种运行更多 Agent 的方式。

但这种框架忽略了成本高昂的部分。

你可以启动二十个 Claude Agent 针对同一个仓库,得到二十份重叠的报告、重复的上下文、相互矛盾的结论,以及一张大得多的 API 账单。

一个有用的图控制计算发生在哪里、每个决策由哪个模型处理、以及不确定的发现如何在工作流中移动。

想象一下让 Claude Code 准备一个生产迁移:

Gyomei - inline image

检查仓库,找到所有依赖,提出迁移方案,识别风险,验证计划,并撰写最终简报。

在一个提示词内部,这变成了一个漫长而不透明的过程。Claude 搜索代码库,将发现存储在上下文中,设计迁移,审查自己的计划,并生成最终报告。

当报告失败时,很难定位失败的原因。Claude 可能漏掉了一个文件,误解了一个依赖,丢失了早期的一个细节,或者在验证过程中接受了一个薄弱的假设。

每个阶段也可能都在同一个昂贵的模型上运行,即使任务的部分内容涉及简单的提取或排序。

图工程打开了这个工作流,让每个决策都有可见的位置。

检查分支同时运行,因为它们使用相同的界定任务,并且不依赖彼此的输出。

它们的发现在一个归约阶段会合,在那里重复项消失,证据被压缩成更小的数据集。

然后一个路由器读取严重性。常规变更通过轻量级审查。高风险发现经过几个独立审查者的深入分析,然后才到达最终模型。

结果是一个工作流,其中延迟、模型成本、上下文大小和验证深度都通过图的结构得到控制。

一个节点应该做一件事

一个有用的节点有明确的职责范围。

找到所有对已弃用 API 的调用。 将每个迁移风险分类为低、中或高。 测试回滚计划中的失败情况。

每个节点需要清晰的输入、明确的输出和有限的决策面。一个搜索仓库、估算业务影响、设计修复方案并撰写建议的节点,仍然包含几个隐藏的阶段。调试仍然困难,因为中间推理被埋没在一个模型调用中。

更小的边界揭示了证据在何处进入系统,以及其含义在何处发生变化。

一条边应该携带证据

一条边表示下一个节点所需的数据。

扫描器可以返回一个可预测的对象:

Gyomei - inline image
text
1{
2 "file": "src/auth/session.ts",
3 "lines": [84, 119],
4 "dependency": "legacySessionClient",
5 "confidence": 0.94,
6 "evidence": "两个调用点都依赖于已弃用的 refresh 方法。"
7}

风险分类器现在为每个发现接收相同的字段。它可以拒绝不完整的结果,对相关文件进行分组,并将不确定的证据路由到另一个审查。

Schema 减少了节点之间的解释偏差。自由格式的段落会迫使每个下游 Agent 重建前一个 Agent 的含义。经过几个阶段,小的歧义可能会改变最终结论。

结构化输出使证据在图中移动时保持稳定。

有些节点就是普通代码

假设八个搜索 Agent 返回了八十个发现。

工作流需要合并数组、丢弃空响应、删除重复项,并对剩余项进行排序。

这些操作有确定性的答案:

text
1const uniqueFindings = [
2 ...new Map(
3 results
4 .flatMap(batch => batch ?? [])
5 .map(item => [`${item.file}:${item.lines.join("-")}`, item])
6 ).values()
7];

一个 JavaScript 转换可以立即处理这个操作,并且每次运行产生相同的输出。将同样的任务发送给另一个模型会增加令牌成本,并创造另一个可能丢失证据的地方。

模型节点应围绕搜索、分类、比较、审查和综合。代码可以处理验证、去重、排序、显式路由规则和其他可预测的转换。

这种划分成为图的基础。

每个模型调用都应该对应一个真正需要判断的决策。

2. 菱形:真实 Agent 图如何移动工作

大多数严肃的 Agent 图最终都会呈现相同的形状。

一个任务从一个共享范围开始,分裂到几个独立的工作节点,等待它们的输出,压缩证据,然后将结果传递给最终决策。

这个形状就是菱形。

Gyomei - inline image

左侧是扇出

所有分支汇合的中点称为屏障

右侧是扇入

一旦一个任务对于一个上下文窗口来说变得太大,这种模式就无处不在。

仓库审计可以按子系统拆分。市场报告可以按来源拆分。研究任务可以按假设拆分。迁移审查可以按 API 使用、数据库更改、部署风险、测试覆盖率拆分。

每个工作节点接收相同的范围,但分配更窄的任务。

然后图等待,直到有足够有用的证据返回。

扇出应该创建独立的工作

当一个分支可以从共享输入开始,并且无需读取另一个分支的输出就能产生有用结果时,它就应该属于扇出。

对于安全审计,拆分可能如下所示:

Gyomei - inline image

Claude Code 可以使用诸如 parallel() 这样的屏障原语并发启动这些调用:

text
1const findings = await parallel(
2 checks.map(check => async () => {
3 return agent({
4 task: check.task,
5 context: auditScope,
6 schema: FINDING_SCHEMA
7 });
8 })
9);

编排保持在普通 JavaScript 中。每个分支接收一个有限的任务,并返回一个验证过的对象。

结果作为一组输出到达,可以过滤、检查并传递到下一个阶段。

一个大的扇出仍然需要为每个分支提供理由。

将一个模糊的任务拆分成十二个几乎相同的 Agent,通常会产生重复的发现,只是措辞略有不同。有用的并行性来自不同的来源、视角、代码区域或假设。

屏障创建一个决策点

屏障会暂停下一个阶段,直到所需的分支完成。

这个暂停很重要,因为某些决策依赖于完整集合。

当一半的仓库仍在检查时,排名节点无法识别最重要的漏洞。当部署审查仍在运行时,综合模型无法编写完整的迁移计划。

在屏障处,图有机会检查运行的状态:

text
1const completed = findings.filter(Boolean);
2
3if (completed.length < MIN_REQUIRED_RESULTS) {
4 throw new Error("审计覆盖率不足");
5}

这就是部分失败变得可见的地方。

一个工作节点可能超时、返回格式错误的数据或没有结果。过滤掉 null 值可以让运行继续进行,但生产工作流通常需要更清晰的策略:

  • 需要多少个成功分支;
  • 哪些分支是强制性的;
  • 失败节点是否应重试;
  • 最终结果是否应标记为不完整。

因此,屏障是可靠性模型的一部分,而不仅仅是同步机制。

在综合之前先归约

扇出之后,图中可能包含数十个重叠的发现。

将它们全部直接发送到一个顶级模型会创建大量的上下文,重复相同的证据,并使重要细节更难区分。

归约阶段准备证据。

一些归约可以在代码中完成:

text
1const unique = deduplicateByKey(
2 completed.flatMap(result => result.findings),
3 finding => `${finding.file}:${finding.line}:${finding.type}`
4);

下一层可能需要判断:

text
1const curated = await agent({
2 task: `
3 将相关发现分组。
4 保留所有文件和行引用。
5 按运营影响对每组进行排名。
6 为每个结论返回最有力的证据。
7 `,
8 input: unique,
9 schema: CURATED_FINDINGS_SCHEMA
10});

归约控制着到达最终模型的内容。

一个好的归约器在保留证据的同时移除重复。一个激进的归约器可能会将几个不同的风险压缩成一个模糊的摘要,抹去验证所需的细节。

最安全的模式是保持每个归约后的声明与其源项之间的链接。

text
1{
2 "risk": "迁移后会话刷新可能失败",
3 "severity": "high",
4 "sourceFindingIds": ["AUTH-04", "API-11", "TEST-07"],
5 "evidence": [
6 "三个服务调用已弃用的 refresh 方法",
7 "不存在回退路径",
8 "缺少集成测试覆盖"
9 ]
10}

现在,综合节点接收一个更小的数据集,而不会丢失可追溯性。

3. 可靠性是图的一部分

一个图可能快速完成,但仍然产生错误的答案。

一旦多个 Agent 开始搜索、分类和审查同一个任务,主要问题就变成了控制。

系统需要规则来决定哪些发现值得深入工作,哪些输出应该被拒绝,以及工作流何时搜索得足够多。

按风险路由

路由器节点读取结构化输出并选择下一个分支。

Gyomei - inline image

分类可以来自模型,而分支本身在代码中保持显式。

text
1const route =
2 finding.severity === "high"
3 ? runFullAudit(finding)
4 : runQuickReview(finding);

这使昂贵的审查集中在具有重大影响的发现上。

一个有用的路由器依赖于图可以检查的字段:严重性、置信度、受影响的系统、财务风险或缺失证据的存在。

添加独立验证

一个 Agent 审查自己的结论,会在两个阶段中携带相同的假设。

一个更强的图将重要发现发送给几个具有不同任务的审查者。

Gyomei - inline image

审查者不应收到改进原始答案的指令。他们的任务是寻找可能不完整或错误的理由。

图可以要求达成一致后,发现才能向前推进:

text
1const accepted = votes.filter(vote => vote.approve).length >= 2;

隔离修改代码的 Agent

当并行编码的 Agent 编辑同一个工作目录时,它们可能会相互干扰。

一个 Agent 可能在另一个 Agent 仍在读取文件时将其覆盖。测试可能针对一组不相关的更改运行。

Git 工作树为每个分支提供其自己的仓库副本。

text
1主仓库
2
3 ├→ worktree/auth-fix
4 ├→ worktree/db-migration
5 └→ worktree/test-repair

每个 Agent 可以在自己的环境中修改文件并运行测试。后续节点比较补丁、检查冲突,并选择应合并的内容。

这使隔离成为图的一部分,而不是手动清理步骤。

让发现收敛

有些任务无法在一次遍历中完成。

仓库审计可能发现一个指向另一个包的依赖。那个包可能揭示另一个调用点。图需要一种可控的方式继续搜索,而不重复已经看到的一切。

text
1const seen = new Set();
2let dryRounds = 0;
3
4while (dryRounds < 2) {
5 const findings = await discoverNext([...seen]);
6 const fresh = findings.filter(item => !seen.has(item.id));
7
8 fresh.forEach(item => seen.add(item.id));
9 dryRounds = fresh.length === 0 ? dryRounds + 1 : 0;
10}

重要的细节是针对之前见过的每个项目进行去重。

仅针对已确认的发现进行去重,会导致被拒绝或不确定的项目在下一轮返回,并消耗同样的工作。

循环在几个空轮次、固定预算或最大迭代次数后停止。生产图通常需要所有这三个条件。

将模型与节点匹配

并非每个节点都需要最强可用的模型。

提取、基本分类和狭窄搜索通常可以在更快的层级上运行。架构审查、对抗性验证和最终综合可能需要更强的模型。

Gyomei - inline image

模型分层成为图的另一个属性。

预算由运行多少个节点、循环重复多少次、每条边传递多少上下文,以及每个阶段由哪个模型处理来决定。

一个包含二十个廉价搜索调用的图,仍然可能比一个强模型调用花费更多。架构在需要另一个分支之前,需要一个令牌预算。

知道何时停止画图

小任务很少需要路由器、投票面板、工作树和收敛循环。

图的开销包括编排代码、Schema、重试、日志记录、中间存储以及更多需要调试的失败状态。

当一个模型可以容纳相关上下文,任务几乎没有独立分支,并且错误答案的成本较低时,线性工作流通常就足够了。

图工程在任务具有并行工作、昂贵决策、大型证据集或有意义的验证需求时变得有用。

完整的工作流最终可能看起来像这样:

Gyomei - inline image

价值在于使工作的移动变得可见。

每个节点都有有限的职责。每条边都携带结构化证据。每个分支都有存在的理由。每个循环都有停止条件。

在这一点上,Claude Code 不再是一条长长的指令。

它正在执行一个工程化的系统。

一键保存

使用 YouMind AI 深度阅读爆款文章

保存原文、追问细节、总结观点,并在一个 AI 工作空间里把爆款文章沉淀成可复用笔记。

了解 YouMind
写给创作者

把你的 Markdown 变成干净的 𝕏 文章

图片上传、表格、代码块,往 𝕏 上手动重排太痛苦。YouMind 把整篇 Markdown 一键转成干净、可直接发布的 𝕏 文章草稿。

试试 Markdown 转 𝕏

更多可拆解样本

近期爆款文章

探索更多爆款文章