增长案例库 Maxed 归档 AI自动化AI搜索优化

LOOP → GRAPH → HARNESS:一次搞定整条流水线

LOOP ⭢ GRAPH ⭢ HARNESS: build the whole pipeline in one sitting

中文译文 · 10k 字

一句话摘要

标题主题:按 Loop→Graph→Harness 一次搭建整条流水线

LOOP ⭢ GRAPH ⭢ HARNESS:一次坐定搭建整条流水线 2026年7月24日 · 10 分钟阅读 · 查看原文 ↗ Claude 营销 Loops 你的智能体每一轮都重读整张电子表格。整个代码库。整篇文档。 它找到什么,忘了,下一轮又找一次——而你要为那些 token 付两遍、三遍的钱。 本能反应是更大的窗口,或者更聪明的模型。两者都没用。 问题不是容量。问题是智能体碰过的所有东西都留存在它思考的那一个窗口里。 心智模型:三层,不是三项技能 一次单一模型调用回答一次,然后停下。一个智能体必须做三件更难的事,而每一件都是一层: 在一个受控的循环里完成一个工作单元——尝试、检查、重试,直到真的做对。这就是 loop(循环)。 把对一个循环来说太大的工作拆到许多循环里——并让每个循环的烂摊子不污染其他循环。这就是 graph(图)。 把所有这些跑在一个基底上,这个基底给每个循环递上它的工具、它自己干净的上下文,以及一条安全边界。这就是 harness(约束框架)。 它们不竞争。它们嵌套: 修复方法是一条三层流水线,而到本文结束时你会让它在本地跑起来。我们自底向上构建它: HARNESS —— 一切在其中执行的运行时(第 3 层) |__ GRAPH —— 若干循环,扇出并检查(第 2 层) |__ LOOP —— 一个工作单元:gather -> act -> verify(第 1 层) 现在就克隆成品版本,这样下面的代码是真实的,而不是伪代码。无需安装、无需密钥、无需网络: git clone https://github.com/Archive228/loop-graph-harness cd loop-graph-harness && ./run.sh 下面的每一句引用都是一次真实演讲的逐字原句,带着确切的时间码——这是整个利基里唯一能拿来和录像核对的东西。这些帖子大多数经不起这样的核对:他们引用的 16 个"课程"里有 9 个根本不存在视频。我们的有。 第 1 层——THE LOOP 一个循环不是"一个周期"。它是一个带三个具名部分的工作单元,而第三部分才是让它成为智能体而不是聊天机器人的那个: Gather context(收集上下文)——决定这一步把什么放进模型的窗口。太少它就瞎答;太多它就慢、贵、分心。 Take action(采取行动)——产出一个候选:代码、一次编辑、一次工具调用、一个答案。 Verify the work(验证工作)——一个检查决定接受还是再试一次。这是人人都在画、却没人去建的那一步。 > "这是智能体循环的三个部分:第一收集上下文,第二采取行动,第三验证工作。" 收集、行动、验证、重复直到被验证。整个纪律只有一条规则:验证器写在行动之前,而且循环不能越过它。而且验证器应该是一条朴素的规则,而不是一个模型给另一个模型打分: > "最好的验证形式是基于规则的……如果它不 lint 或不编译——尽可能多地塞进规则。" 这里是完整的循环。二十行;纪律在于验证器先存在(src/loop.py): def run_loop(material, act, verify, max_attempts=5): failures = [] for attempt in range(1, max_attempts + 1): candidate = act(material, failures) # ACT —— 把之前的失败作为上下文 report = verify(candidate) # VERIFY —— 基于规则,先写好 if report.passed: return LoopResult(True, candidate, attempt) failures = report.failures # 失败文本就是下一个上下文 return LoopResult(False) # 预算耗尽 -> 什么都不交付 为什么这不是玩具:这个演示是故意失败的。工作单元解析时长(1h52m、30m、0s……)。第 1 次尝试用的解析器在任何一个正常人想得到的输入上都是对的——却在 "0s" 上真的崩溃: def _parse_v1(text): h = re.search(r"(\d+)h", text); m = re.search(r"(\d+)m", text); s = re.search(r"(\d+)s", text) hours = int(h.group(1)) if h else 0 mins = int(m.group(1)) if m else 0 secs = int(s.group(1)) if s else 0 if hours or mins or secs: # 对 "0s" 来说这是 0 or 0 or 0 -> False return hours*3600 + mins*60 + secs return int(text) # ……所以 int("0s") 抛错。锯齿状。 这就是 Karpathy 警告过的"锯齿边缘"——模型在明显的输入上达到峰值,而在再往旁边一个输入的地方"边缘更毛糙"(片段 K1 · Karpathy 10:35)。你在代码审查里抓不到它。基于规则的验证器抓得到,而循环用一个无聊的、完备的解析器重试。当你运行这个仓库时你会看到它发生: PASS sheet-A: builds total=18420s attempts=1 PASS sheet-B: tests total=4830s attempts=2 <- 第 1 次尝试在 '0s' 上失败,循环重试 PASS sheet-C: deploys total=12600s attempts=1 这就是循环工程:一个程序在交付前必须批准的工作单元。 第 2 层——THE GRAPH 现在扩展循环。若干工作单元,各自负责一片,同时运行,交回小结果: > "多个读子智能体同时进行……这个智能体能读并总结第一张表吗?第二张表?第三张表?然后它们返回各自的结果,而智能体可能再次派生更多子智能体。" > "派生三个子智能体来做这个任务。而它就会这么做。" 再读一遍片段——他讲述扇出、扇入、再扇出,却从不说"图"这个词,因为从系统内部看,那不是你要去架构的一种拓扑,而是你要转的一个旋钮。在代码里,图只是接线;每个节点只是一个循环(src/graph.py): def fan_out(harness, worker, items): # 每个 (task, slice) 一个循环工作单元 —— 每个都在自己干净的上下文里运行 return [harness.spawn(worker, task, material) for task, material in items] 图节点的设计规则:在派生之前就决定返回什么。父级的上下文恰好按返回值增长,所以你先设计返回。如果你没法用一句话说清返回的形状——一个数字、一个列表、一个裁决——你就没有画出一条边界,你只是把自己的账单翻倍了。 一个你没检查过的返回答案,只是更快的污染,所以图以一个检查器收尾——而且它必须干净地运行,对产生它的工作没有忠诚: > "你甚至可能想要一个对抗性的……真正狠狠地折腾它,对已经完成的工作没有同情的关联。" > "随着模型在推理上变得更好,你可以让这些子智能体去检查主智能体的工作。" def adversarial_verify(harness, artifact, rules): def checker(ctx, tools, task, material): # ctx 是全新的;只看产物 broken = rules(artifact) # 不是它怎么被做出来的 —— 没什么好辩护的 return "REJECT: " + "; ".join(broken) if broken else "ACCEPT" verdict = harness.spawn(checker, "adversarially verify", repr(artifact)) return str(verdict).startswith("ACCEPT") 测试证明这道门有牙——交给它一个坏的合并,它会拒绝。一个没有这最后一个节点的图,只是一个配了更漂亮示意图的未验证系统。 第 3 层——THE HARNESS 上面两层一直在调用 harness.spawn(...)。这就是那个东西:一切在其中执行的运行时。工程师列出了里面有什么: > "在 harness 里你有工具。" > "你在循环里跑的工具,然后你有提示词,最后是文件系统。文件系统是一种上下文工程的方式。" > "研究、压缩、钩子、记忆——它们也都在 harness 周围的这些其他东西里。" "你在循环里跑的工具。"循环是 harness 的一个组件——这就是为什么这是一个栈,而不是三个对立的技能。harness 为你做两件事。 工作 1——让派生变得廉价。你思考要派生什么,而不是怎么派生: > "我们在 harness 里帮你处理所有这些,这样你就能思考:我需要派生哪些子智能体?" > "当你跑并行子智能体时……bash 会变得非常复杂——有很多竞态条件。我们在那里解决了很多工作。" 而且它偏好一个通用工具,而不是一抽屉定制工具: > "如果你在设计一个智能体 harness,你会有一个搜索工具、一个 lint 工具和一个执行工具。而现在,Claude 直接用 grep。" 工作 2——保持每个工作单元的上下文干净。这是承重的方法,也是让隔离成为现实的那条规则(src/harness.py): def spawn(self, worker, task, material): child = Context() # <-- 新的、空的。不是 self.parent。 child.add(task); child.add(material) # 重材料只进入 CHILD result = worker(child, self.tools, task, material) self.parent.add(str(result)) # 父级只按 RESULT 增长 return result > "主要的事情是避免上下文污染,所以你不会想要 fork 上下文。你会开一个新的上下文会话。" 把父级的窗口 fork 进子级,你就什么也没隔离——你复制了烂摊子。子级从空开始,在自己的窗口里读它的那片,交回一行。而当一群工作单元在跑 bash 时,harness 的最后一层就是那个把它装起来的东西: > "最后一层是沙箱化。假设有人恶意接管了你的智能体——它实际能做什么?" 跑起来,看着账单保持平稳 这就是流水线。自底向上:一个程序必须批准的循环,一个把循环扇出并干净检查的图,一个让两者都廉价并保持它们上下文隔离的 harness。./run.sh 打印出证明: HARNESS event log (父级上下文按 RESULTS 增长,而不是按表): spawn #1: child_ctx=58B parent +71B (sum sheet: sheet-A) spawn #2: child_ctx=57B parent +69B (sum sheet: sheet-B) spawn #3: child_ctx=53B parent +72B (sum sheet: sheet-C) spawn #4: child_ctx=81B parent +6B (adversarially verify) parent (main-agent) context size: 218 bytes —— 它从未持有一整张表。 处理了整整三张表。主智能体的上下文——你每一轮都要付钱的那个东西——最终只有 218 字节。没有更大的窗口,没有更好的模型。只有带返回类型的边界。这就是那位工程师一直绕着圈讲的全部要点: > "你永远不应该把整张电子表格读进上下文,因为那会太多。" > "我已经在做第五次 compact 了。我心想——什么?我以前几乎从没做过 compact。" 他几乎从不 compact,因为他几乎从不让窗口填满。这就是那个技能,而它现在正跑在你的机器上。 接下来去哪 演示生成器是脚本化的,所以它离线、确定性地运行。把 src/workers.py 的 act 换成一次真实的模型调用,别的什么都不用变——循环、图和 harness 不知道、也不在乎是什么产生了候选。这就是检验这分层是诚实的那道测试。 三个问题——边界在哪、返回类型是什么、你如何验证它。它们没有一个是"这三个词里哪个该写进你的个人简介"。 仓库:github.com/Archive228/loop-graph-harness —— 从一次干净的 clone 跑 ./run.sh,9 个测试。完整的时间码到文件映射在它的 LECTURE.md 里。 标签:# X # Claude # 营销 # Loops 相关文章 如何建一家 AI 原生公司:招聘、标准与节奏 *我们花了一年跑黑客松、AI 培训和办公时间。但直到我们把 AI 能力变成一项要求,一切才开始改变。* AI Loops Claude 营销

原文参考:https://maxed.wiki/posts/loop-graph-harness-build-the-whole-pipeline-in-one-sitting/ (Maxed.wiki,本页为站内中文整理)