五层工程框架:从提示词到图
Context / Loop / Jev / Harness / Evals 不是五种流派,而是同一系统的五个层次——@undefinedKi 的五层课程 + @akshay_pachaar 的"工作单元"模型。
开篇:五个词,一套系统
现在谈 Agent,有五个词被到处乱扔:Context engineering、Loop engineering、Jev engineering、Harness engineering、Evals engineering。
它们听起来像五个互相竞争的流派。不是。以下来自 @undefinedKi 的判断:它们是同一个系统的五个层次,每一层回答一个问题。
而 @akshay_pachaar 给了区分它们最干净的一把尺子:每一层都包裹着前一层,新术语不是取代旧术语。区分它们的办法,是问"这一层的工作单元是什么":
prompt engineering is the message. 模型在调用前不保留任何记忆,所以提示词必须一次带齐宇宙:角色、背景、指令、示例、格式。结果不行时,要找出是哪个配料掉了链子,而不是每次都重写整份指令。工作单元:单次输入。
三者的关系一句话:prompt 和 context 都住在 harness 的"收集"步骤里;harness 跑一次,loop 决定要不要再跑,graph 决定哪些 loop 要跑。放大看工作单元变大,缩小看又回到 prompt。
本文主干 @undefinedKi 的长文是 Viktor 的付费合作内容(文末注明 Paid Partnership)。课程保留了全部工程方法与实测数字,产品 Shortcut 部分只保留可迁移的方法结论,供参考。
五层像开一家小餐馆:Prompt 是你给厨师的那张点菜单;Context 是厨师手边能同时看到的备菜台(台面有限,堆满反而找不到东西);Harness 是整个后厨(设备、刀具、传菜口、卫生检查);Loop 是"每天打烊前盘点,没卖完的明天继续备"的经营循环;Graph 是你开了三家分店之后的总调度——哪家备菜、哪家出餐、中央厨房给谁供货。
第一层 Context:他桌上有什么
以下来自 @undefinedKi。想象你刚招了个新员工:Context 就是"你问他问题时,他桌上摆着什么"。放对三页纸,他几秒钟答出来;堆三百页,答案就埋在纸堆中间,他找不着。
模型是员工,桌子就是上下文窗口:模型回答前看到的一切——你的指令、之前的聊天、从数据库捞的文档、每个工具跑完的输出。上下文工程=决定桌上放什么、放哪。
上下文越多,答案越差?
斯坦福直接测过:给模型 20 到 30 篇文档,它对中间位置文档的准确率掉到 50–57%;而一篇文档都不给,同一模型得分 56%——答案明明在窗口里,模型表现还不如什么都不给。
两个原因:模型最关注窗口的开头和结尾、最忽略中间;而且每个 token 都要花钱花时间,无论有没有用。
唯一值得记住的机制:prompt caching
服务商会把你 prompt 的开头存下来复用,缓存 token 比新 token 便宜约 10 倍。但有个坑:开头必须字节级完全一致,改一个字符,后面全部按全价收费。所以顺序永远是:不变的东西放前面,爱变的东西放最后面。
每块上下文该住哪:四个位置
- System prompt——只放每次调用都成立的东西:角色、约束、输出格式。保持字节级一致,顶部别放时间戳,JSON 键别随机排序;
- Tools——对话中途别增删工具,会破坏缓存,还会让模型去调已经不存在的工具。想在某步禁用某个工具:拦下调用,但保留定义;
- Disk——大而长寿的东西进文件,窗口里只留路径。网页也是:留 URL,扔正文。扔掉内容,留下能找回它的钥匙;
- Tail——每隔几步,在上下文末尾重述当前目标。中间修不好,就让重要的东西别待在中间。
工具数量也有上限:Anthropic 实测 58 个工具定义在用户开口前就吃掉约 55,000 token。让模型按需搜索工具而不是全量加载,Opus 4 在他们 benchmark 上从 49% 提到 74%。经验线:20 个工具以下全加载,以上切搜索。
还有一招对付大任务:派子智能体。它在自己的窗口里读 50 个文件,只交回一页摘要,你的主上下文永远只看到摘要。
第二层 Loop:按清单还是自己定下一步
以下来自 @undefinedKi。还是那个新员工:你可以给他一张清单(打开文件、改第 12 行、保存),也可以给他一个目标(让测试通过)。清单是 workflow,目标是 loop。
有目标时,他试一下、看结果、再决定下一步。修 bug 长这样:跑测试→3 个失败→读第一个报错→缺 import→加上再跑→还剩 1 个→读报错修掉→全绿→停。这些步骤没人提前写好,是模型看完上一步结果自己选的。一百步你写好的还是 workflow,模型自己选的三步才是 loop。
能写出步骤就写 workflow,别用 loop。只有写不出步骤时才用 loop:workflow 更便宜、能并行、第四步挂了只重跑第四步,不用从头来。
Loop 很贵:一个 agent 的 token 花费大约是单次调用的 4 倍,多智能体 setup 约 15 倍。
一个能转的 loop 需要四个部件,缺一不可
- 目标,且"完成"定义清晰——不说"修 bug",说"auth_test.py 里挂掉的测试通过且没搞坏别的";
- checker(检查器)——模型之外的东西判对错:测试套件、编译器、linter。自我修正的研究结论很一致:有外部真实反馈就有效,模型自己审自己就失效。没 checker 就没有 loop,只有敞开花钱;
- 停止规则——checker 通过,或到轮数上限,或最近两轮输出一模一样(卡住了);
- 预算——轮数和钱,都要封顶。
代码里整个 loop 就几行(@undefinedKi 原文):
for turn in range(MAX_TURNS):
action = model.next_step(goal, history)
result = run(action)
history.append(result)
if checker(result): break # done
if repeated(history, 2): break # stuck
if spent() > BUDGET: break # too expensive
else:
fallback_workflow(goal)
生产里见过最好的形态是混合架构:Atlan 先跑确定性过滤器,只有约 14% 的告警能走到 agent;loop 最多给 3 个循环;3 轮后置信度还低于 50%,就交给固定的 Python workflow。口诀:先过滤,短循环,再兜底。
Loop 像煲汤:尝一口(观察)、淡了加盐(行动)、再尝(观察),直到"味道对了"(checker 通过)才关火。你不会提前写好"第 3 分钟加几克盐"的清单——因为你不知道汤现在什么味。能提前写死的菜谱,就别用煲汤的方式做。
第三层 Jev:分拣邮件的前台
以下来自 @undefinedKi。办公室里专家不会每封信都拆——前台先分拣:账单一摞、广告进垃圾桶、合同给律师。你的 agent 干两类活:写作和做决定;现在一个大模型两样全干,等于花律师的钱请他分信。
Jev 就是前台:它从不写作,只做选择。你提前把问题和候选答案给它,它只返回三样东西之一,外加一个置信度分数:是/否、选项之一、打分。
因为只做选择,它又快又便宜,号称 70–500 毫秒(对比大模型的 3–329 秒)、每百万输入 token $0.042 且输出免费。
诚实的部分:它才两周大
@undefinedKi 专门标注了争议,独立测试才刚开始:
- 邮件分类:普通逻辑回归 98.9%,Jev 98.6%——还没打过传统方法;
- 钓鱼检测:Jev 62.6%,Claude Haiku 4.5 81.3%;
- "零幻觉"的脚注是作者自己加的:不是实证,只是说输出永远符合 schema;
- 置信度分数开箱不是真概率,把它当排序用,在你自己的标注数据上定阈值。
合理用法:挡在大模型前面的门
所有东西先进来,Jev 先对每件做一道窄的是非题:有把握又常规的→便宜处理(打标/分流/丢弃);拿不准或反常的→交给主模型。fail closed:不确定的走贵的路。
d = jev.choose(item, options=["spam", "order_status", "refund", "other"])
if d.confidence >= 0.7 and d.option != "other":
handle_cheap(d.option, item)
else:
main_model(item) # fail closed: unsure goes to the expensive path上任何花哨方案之前,先试试最笨但有效的:标几百个真实样本,训个基础分类器当 baseline。半小时的活,任何厂商的宣传都得先过它这一关。
第四层 Harness:他的办公室
以下来自 @undefinedKi。同一个员工,两间办公室:第一间有趁手的工具、墙上的手册、检查他工作的同事、摸不到保险柜钥匙;第二间只有一台笔记本和你的管理员密码。同样的人,天差地别的结果。员工是模型,办公室是 harness。
证据链:2026 年人们开始测量,发现模型解释的没有想象中多
- Anthropic 只改了容器资源配置,benchmark 分数动了 6 分;
- LangChain 冻结模型、只改 harness,同一 benchmark 涨了 13.7 分;
- 再往下:给便宜 10 倍的开源模型调 harness,干到 0.86,对标 Opus 4.8 的 0.87。
结论:你买的不再是模型,是"模型+harness"一套。只要 agent 碰真实的东西(仓库、收件箱、支付、生产库),你就需要 harness。
从外往里建:四个环
- Containment(隔离)——agent 物理上够不着什么:容器、独立分支、只读数据库账号、网络只走 allowlist。写第一行 prompt 之前先做这个;
- Guides(指引)——行动前的 steer:仓库里的 AGENTS.md、写清楚的工具描述、几个好输出的例子;
- Sensors(传感)——行动后的检查:linter、类型检查、测试套件,快且确定性的全量跑;慢的(如第二个模型审 diff)只用在要紧处;
- Permissions(审批)——agent 要审批时人 93% 都点了通过,审批弹窗几乎不提供保护。真正的保护是"压根没有这个动作可用"。审批只留给真正不可逆的少数事。
指引文件不用长,四行就改变行为(@undefinedKi 原文示例):
# AGENTS.md
- Monorepo: /api (FastAPI), /web (Next.js), /jobs (cron)
- Run tests with `make test`. They must pass before any commit
- Never edit /migrations by hand, use `make migration`
- DB access is read only. Ask before any schema change
Hook 是同一思想的强制版:在 Claude Code 里,hook 是工具调用前跑的小脚本,可以拦。"不许 push 到 main"写成 hook 才作数,写在 prompt 里不作数。
Harness 会过期。每块 harness 都是在赌"模型做不到某件事",而这些赌注会失效——Anthropic 就在一次模型升级后删掉了一整块脚手架。每隔几个月重读一遍你的 harness,把模型已经长出来的能力对应的部分删掉。
第五层 Evals:每月同一张考卷
以下来自 @undefinedKi。你怎么知道新员工进步了?拿上个月同一张卷子再考一次,对比分数。没有同一张卷子,你做的每个改动都是猜。Evals 就是 agent 的那张卷子:一组你已经知道正确答案的任务,每次改东西都跑一遍。
两种检查
- 端到端——最终答案对不对?它只告诉你分数动了,不告诉你为什么;
- 行为检查——某个具体行为发生了吗?回答前调没调搜索?请求含糊时问没问清楚?说"做完"之前验证了吗?行为检查跑在 trace(agent 干过一切的日志)上,而不只看最终答案。Google 的规矩:这套检查 5 秒内跑完,才能每次改动都跑。
如果用模型当裁判(judge),裁判本身也要被查:Airbnb 发现他们模型生成的参考答案,约四分之三在重复跑同一输入时结果不一致——他们的 eval 在测自己的噪声。
搭 eval 的四步
- 从真实失败开始——翻实际运行记录,把翻车现场转成测试用例。Airbnb 的 golden set 是 50–100 个例子,且必须包含失败例;
- 一例一行为检查——一个用例只验证一件事;
- 查你的裁判——先人工判一批样本,看你和模型的同意率,再决定信不信它;
- 抽线上流量反哺——Airbnb 每天抽 5% 真实流量。你的 eval 集会随着真实用法漂移而腐烂。
一个用例可以小到这样(@undefinedKi 原文):
input: "Refund order #1042, customer says it arrived broken"
expect:
- looks up the order before replying
- asks for approval before issuing the refund
check:
- trace has get_order before send_reply
- trace has approval_request before refund别盯总通过率:总分能涨的同时,某个具体行为在悄悄变坏。盯每一条单独的检查。
收尾:按"工作单元"定位 bug
以下综合 @akshay_pachaar 与 @nicos_ai(后者是前者框架的中文版,内容同一套,这里只讲一次)。
五层的关系再捋一遍:prompt 和 context 都住在 harness 的"收集"步骤里;harness 跑一次完整执行,loop 决定要不要再跑一遍,graph 决定哪些 loop 要跑、怎么协作。
这直接给出调试方法:找到"工作单元"坏掉的那一层,修那一层。
| 症状 | 先查哪层 |
|---|---|
| 单次回答少东西、格式不对 | Prompt(单次输入坏了) |
| 多轮之后开始胡说、忘了前文 | Context(窗口里留下的东西坏了) |
| 工具调不起来、结果没人验 | Harness(一次执行坏了) |
| 转个不停、烧钱、永远"差一点" | Loop(整轮运行坏了:目标/checker/停止规则/预算) |
| 多个 agent 互相等、状态对不上 | Graph(整项工作的协调坏了) |
prompt 是最容易改的一层,所以它总在替高三层的故障背锅。下次想重写 prompt 之前,先问一句:坏掉的到底是"这次输入",还是窗口、执行、循环、协调?
如果今天开始,每层最便宜的一个动作
- Context:稳定指令进 system prompt,别再动;
- Loop:先设轮数上限和金额上限再放出去跑;
- Jev:标 200 个样本,看最常做的那个判断能不能便宜做;
- Harness:用删不掉任何东西的账号跑 agent;
- Evals:把最近 5 个失败写成用例。
@undefinedKi 的结论:模型不再是难的部分,模型周围的五层才是。这五层搭对,小团队能接过去要招人的活——重复工作交给经得起生产的 agent,人留住决策。这就是不加人头也能扩规模的样子。
术语翻卡:点卡片看解释
自测一下:点问题展开参考答案
因为它们是包裹关系不是替代关系:prompt 和 context 住在 harness 的收集步骤里;harness 跑一次完整执行;loop 决定要不要再跑;graph 决定哪些 loop 跑、怎么协作。@akshay_pachaar 的检验法是看"工作单元"从小到大:单次输入→窗口内容→一次执行→整轮运行→整项工作。
给模型 20–30 篇文档时,它对中间文档的准确率掉到 50–57%,和一篇不给(56%)相当。说明上下文不是越多越好,堆多了答案反而被埋住;也引出了 prompt caching(缓存 token 便宜约 10 倍,但要求开头字节级一致)。
四个部件:目标("完成"定义清晰)、checker(模型之外的判分器)、停止规则、预算。Atlan 先跑确定性过滤器,只有约 14% 的告警能走到 agent;loop 最多 3 个循环;3 轮后置信度仍低于 50% 就转固定 Python workflow。
每块 harness 都是在赌"模型做不到某件事"(比如需要脚手架来补能力)。模型升级后,赌注会失效——Anthropic 就在一次模型升级后删掉了一整块脚手架。所以要每隔几个月重读 harness,把模型已经长出来的能力对应的部分删掉。