一句话摘要
标题主题:按 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,本页为站内中文整理)