Claude Code 图工程完整打法手册

The complete Graph Engineering playbook for Claude Code

中文译文 · 15k 字

一句话摘要

Claude Code 图工程的完整手册

Claude Code 的完整图工程(Graph Engineering)实战手册 2026 年 7 月 23 日 · 12 分钟阅读 · 查看原文 ↗ Claude AI 金融 大多数人还在把 Claude Code 当做一个非常昂贵的实习生来用。 他们给它一个任务,等一个答案,然后手动决定下一步做什么。 但从 AI 里榨出最大杠杆的团队,构建的东西更接近一个小型分布式系统。 一个 agent 界定问题范围。 五个更便宜的 agent 并行搜索。 一个确定性脚本去重。 三个持怀疑态度的 agent 试图推翻这些发现。 一个顶级模型做最终判断。 这就是图工程(graph engineering)。 在继续往下读之前: 收藏这份指南,这样当你开始搭建自己的 Claude 工作流时,可以回来翻这些图模式。 > 并且关注 @Gyome1_ —— 我拆解 Claude Code、AI agent,以及那些把单个模型变成可靠工程工作流的系统。 我花了几周时间剖析真实的 agent 架构、工作流图和生产模式,把图工程重建成了这一份实操手册。 与其写一条更长的提示词,你设计的是信息穿过系统的路径: 线性 → 扇出(fan-out)→ 归约(reduce)→ 验证 → 综合(synthesize) 每个 agent 变成一个职责有界的节点。每条边承载结构化数据。路由器决定哪条分支运行。验证器拒掉弱输出。循环持续运行,直到图再也找不到新东西。 关键转变在于:Claude Code 不再需要表现得像一个单一智能体,在一张巨型清单上逐项打勾。 它可以生成编排代码,派出一支由专门化子 agent 组成的队伍,把它们的输出路由到不同的模型,并且只有在证据熬过验证之后,才组装最终结果。 这些基础模式并不新鲜。软件工程师用 DAG、管线、屏障(barrier)、MapReduce 和分布式 worker 已经几十年了。 变了的是现在每个节点里面装的东西。 一个节点可以搜索一个代码库、审计一次迁移、挑战一个架构决策、检查测试失败,或者把五十个独立发现综合成一份带引用的报告。 这份指南把整个系统从最简单的线性 agent 一路拆到钻石图、路由器节点、对抗式验证面板、收敛循环、模型分层,以及直接在 Claude Code 内部生成的动态工作流。 读完它,你就能面对一个大任务,不再问: "我该写什么提示词?" 1. 图工程从账单开始 图工程常常被呈现为一种"跑更多 agent"的方式。 那个框架漏掉了最贵的那部分。 你可以对同一个代码库放出二十个 Claude agent,然后收到二十份重叠的报告、重复的上下文、互相冲突的结论,以及一张大得多的 API 账单。 一个有用的图控制着:计算发生在哪里、每个决策由哪个模型处理、不确定的发现如何穿过工作流。 想象让 Claude Code 准备一次生产迁移: > 检查代码库,找出每一个依赖,提出迁移方案,识别风险,验证计划,写出最终简报。 在一个提示词内部,这变成一个漫长而不透明的过程。Claude 搜索代码库、把发现存在上下文里、设计迁移、审查自己的计划、产出最终报告。 当报告失败时,失败的源头很难定位。Claude 可能漏了一个文件、误解了一个依赖、丢了前面某个细节,或者在验证时接受了一个薄弱的假设。 每一个阶段也可能跑在同一个昂贵的模型上,即便任务的某些部分只是简单的提取或排序。 图工程把这个工作流打开,给每一个决策一个可见的位置。 检查分支同时运行,因为它们用的是同一个有界任务,而且不依赖彼此的输出来。 它们的发现在归约阶段汇合,重复被去除,证据被压缩成一个更小的数据集。 然后一个路由器读取严重程度。常规变更走轻量审查。高风险发现从几个独立审查者那里获得更深分析,之后才抵达最终模型。 结果是一个这样的工作流:延迟、模型成本、上下文大小、验证深度都通过图的结构来控制。 一个节点应该只做一个决策 一个有用的节点有有界的职责。 > 找出每一个对已废弃 API 的调用。 > > 把每一个迁移风险分类为低、中、高。 > > 测试回滚计划对失败场景的应对。 每个节点需要一个清晰的输入、一个明确的输出、以及一个有限的决策面。 一个既搜索代码库、又估算业务影响、又设计修复方案、又写建议的节点,仍然藏着几个隐藏阶段。调试依旧困难,因为中间推理被埋在一次模型调用里。 更小的边界能揭示证据从哪里进入系统,以及它的含义在哪里发生了变化。 一条边应该承载证据 一条边代表下一个节点所需的数据。 扫描器可以返回一个可预测的对象: { "file": "src/auth/session.ts", "lines": [84, 119], "dependency": "legacySessionClient", "confidence": 0.94, "evidence": "Both call sites depend on the deprecated refresh method." } 风险分类器现在对每一条发现收到相同的字段。它可以拒掉不完整的结果、把相关文件分组、把不确定的证据路由进另一次审查。 Schema 减少节点之间的解读漂移。自由格式的段落强迫每一个下游 agent 去重建上一个 agent 的意图。跨过几个阶段之后,微小的歧义就可能改变最终结论。 结构化输出让证据在穿过图的过程中保持稳定。 有些节点就是普通代码 假设八个搜索 agent 返回八十条发现。 工作流需要合并数组、丢弃空响应、去重、给剩余条目排序。 这些操作有确定性的答案: const uniqueFindings = [ ...new Map( results .flatMap(batch => batch ?? []) .map(item => [`${item.file}:${item.lines.join("-")}`, item]) ).values() ]; 一个 JavaScript 变换瞬间完成这件事,且每次运行产出相同的结果。把同样任务发给另一个模型,只是增加 token 成本,还多了一个证据可能消失的地方。 模型节点应该放在搜索、分类、比较、审查、综合周围。代码可以处理校验、去重、排序、显式路由规则,以及其他可预测的变换。 这个划分成为图的基础。 每一次模型调用都应该对应一个真正需要判断的决策。 2. 钻石图:真实的 agent 图如何移动工作 大多数严肃的 agent 图最终都会收敛成同一种形状。 一个任务从一个共享范围开始,在几个独立 worker 之间拆分,等待它们的输出,压缩证据,然后把结果送进一个最终决策。 那个形状就是钻石。 左侧是扇出(fan-out)。 所有分支汇合的中点就是屏障(barrier)。 右侧是扇入(fan-in)。 一旦任务大到一个上下文窗口装不下,这个模式就到处出现。 一次代码库审计可以按子系统拆分。一份市场报告可以按来源拆分。一个研究任务可以按假设拆分。一次迁移审查可以横跨 API 使用、数据库变更、部署风险、测试覆盖来拆分。 每个 worker 收到同一个范围,配上更窄的指派。 然后图等待,直到足够的可用证据返回。 扇出应该创造独立的工作 当一个分支能从共享输入开始、且无需读另一个分支的输出就能产出有用结果时,它才属于扇出。 对一次安全审计来说,拆分可能是这样的: Claude Code 可以用一个像 parallel() 这样的屏障原语并发发起这些调用: const findings = await parallel( checks.map(check => async () => { return agent({ task: check.task, context: auditScope, schema: FINDING_SCHEMA }); }) ); 编排留在普通 JavaScript 里。每个分支收到一个有界的任务,返回一个经过校验的对象。 结果以一组输出的集合到达,可以被过滤、检查、送进下一阶段。 一个大的扇出仍然需要每一个分支背后都有理由。 把一个模糊的指派拆成十二个几乎一模一样的 agent,常常产生措辞略不同的重复发现。有用的并行来自不同的来源、视角、代码区域或假设。 屏障制造一个决策点 一个屏障让下一阶段暂停,直到必需的分支完成。 这个暂停很重要,因为有些决策依赖全集。 当代码库还有一半没被检查时,一个排序节点无法识别最重要的漏洞。当部署审查还在跑的时候,一个综合模型无法写出完整的迁移计划。 在屏障处,图有机会检查本次运行的状态: const completed = findings.filter(Boolean); if (completed.length < MIN_REQUIRED_RESULTS) { throw new Error("Insufficient audit coverage"); } 这就是部分失败变得可见的地方。 一个 worker 可能超时、返回畸形数据、或者没有产出发现。过滤空值能让运行继续,但生产工作流通常需要更清晰的政策: 需要多少个成功分支; 哪些分支是强制的; 一个失败的节点是否应该重试; 最终结果是否应该被标记为不完整。 因此屏障是可靠性模型的一部分,而不只是一个同步机制。 综合之前先归约 扇出之后,图里可能堆着几十条重叠的发现。 把它们全部直接送进一个顶级模型,会造成一个大上下文、重复同样的证据、让重要细节更难分辨。 归约阶段准备证据。 有些归约可以在代码里做: const unique = deduplicateByKey( completed.flatMap(result => result.findings), finding => `${finding.file}:${finding.line}:${finding.type}` ); 下一层可能需要判断: const curated = await agent({ task: ` Group related findings. Preserve all file and line references. Rank each group by operational impact. Return the strongest evidence for every conclusion. `, input: unique, schema: CURATED_FINDINGS_SCHEMA }); 归约控制着到达最终模型的内容。 一个好的归约器在保留证据的同时去除重复。一个激进的归约器可能把几个不同的风险压缩成一条模糊的总结,抹掉验证所需的细节。 最稳妥的模式,是在每一条被归约的结论和它的来源条目之间保留一个链接。 { "risk": "Session refresh may fail after migration", "severity": "high", "sourceFindingIds": ["AUTH-04", "API-11", "TEST-07"], "evidence": [ "Three services call the deprecated refresh method", "No fallback path exists", "Integration coverage is missing" ] } 现在综合节点收到一个更小的数据集,且没有丢失可追溯性。 3. 可靠性是图的一部分 一张图可以很快跑完,却仍然产出错误答案。 一旦几个 agent 开始搜索、分类、审查同一个任务,主要问题就变成了控制。 系统需要规则来决定:哪些发现值得深挖、哪些输出应该被拒掉、以及工作流什么时候搜得够了。 按风险路由 一个路由器节点读取结构化输出,选择下一条分支。 分类可以来自模型,而分支本身保持在代码里显式。 const route = finding.severity === "high" ? runFullAudit(finding) : runQuickReview(finding); 这把昂贵的审查集中在有实际影响的发现周围。 一个有用的路由器依赖图可以检查的字段:严重程度、置信度、受影响系统、财务敞口,或缺失证据的存在。 加入独立验证 一个 agent 审查自己的结论,会把同样的假设带进两个阶段。 一个更强的图把重要发现发给几个带不同任务的审查者。 审查者不应该收到"改进原答案"的指令。他们的任务是寻找它可能不完整或错误的原因。 图可以要求达成一致之后,一条发现才能继续前进: const accepted = votes.filter(vote => vote.approve).length >= 2; 隔离会改代码的 agent 并行的编码 agent 在编辑同一个工作目录时会互相干扰。 一个 agent 可能在一个文件仍被另一个 agent 读取时覆盖它。测试可能跑在一堆互不相关的改动混合体上。 Git worktree 给每个分支一份自己的代码库副本。 main repository │ ├→ worktree/auth-fix ├→ worktree/db-migration └→ worktree/test-repair 每个 agent 可以在自己的环境里改文件、跑测试。后面一个节点比较补丁、检查冲突、选择该合并什么。 这把隔离变成图的一部分,而不是一个手动清理步骤。 让发现收敛 有些任务无法一次完成。 一次代码库审计可能挖出一个指向另一个包的依赖。那个包又可能暴露另一个调用点。图需要一种受控的方式继续搜索,而不重复它已经见过的每样东西。 const seen = new Set(); let dryRounds = 0; while (dryRounds < 2) { const findings = await discoverNext([...seen]); const fresh = findings.filter(item => !seen.has(item.id)); fresh.forEach(item => seen.add(item.id)); dryRounds = fresh.length === 0 ? dryRounds + 1 : 0; } 重要细节是:对每一个之前见过的条目去重。 只对已确认的发现去重,会让被拒绝或不确定的条目在下一轮回来,再次消耗同样的工作。 循环在几轮空转、一个固定预算、或一个最大迭代次数之后停下。生产图通常三者都需要。 让模型匹配节点 不是每个节点都需要最强的可用模型。 提取、基础分类、窄搜索,常常可以在更快的层级上跑。架构审查、对抗式验证、最终综合,可能值得一个更强的模型。 模型分层变成图的另一个属性。 预算由以下因素决定:多少个节点在跑、循环重复多少次、多少上下文穿过每条边、每个阶段由哪个模型处理。 一个有二十次便宜搜索调用的图,仍然可能比一次强调用更贵。架构在需要另一条分支之前,先需要一个 token 预算。 知道什么时候停止画图 小任务很少需要路由器、投票面板、worktree 和收敛循环。 图的开销包括编排代码、schema、重试、日志、中间存储,以及更多需要调试的失败状态。 当一个模型能装下相关上下文、任务几乎没有独立分支、且错误答案的成本很低时,一个线性工作流通常就足够了。 当任务获得并行工作、昂贵决策、大证据集、或有意义的验证需求时,图工程才变得有用。 完整工作流最终可能长这样: 价值来自让工作的移动变得可见。 每个节点有有限的职责。每条边承载结构化证据。每条分支有存在的理由。每个循环有停止条件。 到那一步,Claude Code 就不再是在执行一条长长的指令。 它是在执行一个被工程化出来的系统。 标签:# X # Claude # AI # 金融 # 指南 相关文章 循环工程:/loop 的小白指南 TL;DR:任何人如何用循环把自己的 Claude 生产力提升 10 倍——哪怕你完全不懂技术。Claude AI 循环 金融

原文参考:https://maxed.wiki/posts/the-complete-graph-engineering-playbook-for-claude-code/ (Maxed.wiki,本页为站内中文整理)