← 返回学习中心 · Agent 工程OiOi Academy
AGENT 理论 · 01

五层工程框架:从提示词到图

Context / Loop / Jev / Harness / Evals 不是五种流派,而是同一系统的五个层次——@undefinedKi 的五层课程 + @akshay_pachaar 的"工作单元"模型。

原作者 @undefinedKi / @akshay_pachaar / @nicos_ai 来源 X 发布 2026-09-28 / 2026-07-26
🧭

开篇:五个词,一套系统

现在谈 Agent,有五个词被到处乱扔:Context engineering、Loop engineering、Jev engineering、Harness engineering、Evals engineering。

它们听起来像五个互相竞争的流派。不是。以下来自 @undefinedKi 的判断:它们是同一个系统的五个层次,每一层回答一个问题。

原文配图:Agent 的五个层次总览(@undefinedKi)
原文配图:Agent 的五个层次总览(@undefinedKi)

而 @akshay_pachaar 给了区分它们最干净的一把尺子:每一层都包裹着前一层,新术语不是取代旧术语。区分它们的办法,是问"这一层的工作单元是什么":

prompt engineering is the message. 模型在调用前不保留任何记忆,所以提示词必须一次带齐宇宙:角色、背景、指令、示例、格式。结果不行时,要找出是哪个配料掉了链子,而不是每次都重写整份指令。工作单元:单次输入。

原文配图:五层
原文配图:五层"工作单元"模型图解(@akshay_pachaar)

三者的关系一句话: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 倍。但有个坑:开头必须字节级完全一致,改一个字符,后面全部按全价收费。所以顺序永远是:不变的东西放前面,爱变的东西放最后面。

每块上下文该住哪:四个位置

  1. System prompt——只放每次调用都成立的东西:角色、约束、输出格式。保持字节级一致,顶部别放时间戳,JSON 键别随机排序;
  2. Tools——对话中途别增删工具,会破坏缓存,还会让模型去调已经不存在的工具。想在某步禁用某个工具:拦下调用,但保留定义;
  3. Disk——大而长寿的东西进文件,窗口里只留路径。网页也是:留 URL,扔正文。扔掉内容,留下能找回它的钥匙;
  4. Tail——每隔几步,在上下文末尾重述当前目标。中间修不好,就让重要的东西别待在中间。

工具数量也有上限:Anthropic 实测 58 个工具定义在用户开口前就吃掉约 55,000 token。让模型按需搜索工具而不是全量加载,Opus 4 在他们 benchmark 上从 49% 提到 74%。经验线:20 个工具以下全加载,以上切搜索。

还有一招对付大任务:派子智能体。它在自己的窗口里读 50 个文件,只交回一页摘要,你的主上下文永远只看到摘要。

原文配图:Context 层示意(@undefinedKi 图2)
原文配图:Context 层示意(@undefinedKi 图2)
记住:Context 层最便宜的动作:把稳定的指令搬进 system prompt,然后别再动它。
🔁

第二层 Loop:按清单还是自己定下一步

以下来自 @undefinedKi。还是那个新员工:你可以给他一张清单(打开文件、改第 12 行、保存),也可以给他一个目标(让测试通过)。清单是 workflow,目标是 loop。

有目标时,他试一下、看结果、再决定下一步。修 bug 长这样:跑测试→3 个失败→读第一个报错→缺 import→加上再跑→还剩 1 个→读报错修掉→全绿→停。这些步骤没人提前写好,是模型看完上一步结果自己选的。一百步你写好的还是 workflow,模型自己选的三步才是 loop。

避坑
能写出步骤就写 workflow,别用 loop。只有写不出步骤时才用 loop:workflow 更便宜、能并行、第四步挂了只重跑第四步,不用从头来。

Loop 很贵:一个 agent 的 token 花费大约是单次调用的 4 倍,多智能体 setup 约 15 倍。

一个能转的 loop 需要四个部件,缺一不可

  1. 目标,且"完成"定义清晰——不说"修 bug",说"auth_test.py 里挂掉的测试通过且没搞坏别的";
  2. checker(检查器)——模型之外的东西判对错:测试套件、编译器、linter。自我修正的研究结论很一致:有外部真实反馈就有效,模型自己审自己就失效。没 checker 就没有 loop,只有敞开花钱;
  3. 停止规则——checker 通过,或到轮数上限,或最近两轮输出一模一样(卡住了);
  4. 预算——轮数和钱,都要封顶。

代码里整个 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。口诀:先过滤,短循环,再兜底。

原文配图:workflow 还是 loop?决策图(@undefinedKi 图3)
原文配图:workflow 还是 loop?决策图(@undefinedKi 图3)
高中生类比
Loop 像煲汤:尝一口(观察)、淡了加盐(行动)、再尝(观察),直到"味道对了"(checker 通过)才关火。你不会提前写好"第 3 分钟加几克盐"的清单——因为你不知道汤现在什么味。能提前写死的菜谱,就别用煲汤的方式做。
记住:Loop 层最便宜的动作:放出去跑之前,先设好轮数上限和金额上限。
📥

第三层 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。半小时的活,任何厂商的宣传都得先过它这一关。
原文配图:Jev 回答的三类问题(@undefinedKi 图4)
原文配图:Jev 回答的三类问题(@undefinedKi 图4)
记住:Jev 层最便宜的动作:把你的 agent 最常做的那个判断,标 200 个样本。
🏢

第四层 Harness:他的办公室

以下来自 @undefinedKi。同一个员工,两间办公室:第一间有趁手的工具、墙上的手册、检查他工作的同事、摸不到保险柜钥匙;第二间只有一台笔记本和你的管理员密码。同样的人,天差地别的结果。员工是模型,办公室是 harness。

记住:Agent = model + harness。harness 是除模型之外的一切:工具、权限、沙箱、讲清项目的文档、对输出的检查。

证据链:2026 年人们开始测量,发现模型解释的没有想象中多

  • Anthropic 只改了容器资源配置,benchmark 分数动了 6 分;
  • LangChain 冻结模型、只改 harness,同一 benchmark 涨了 13.7 分;
  • 再往下:给便宜 10 倍的开源模型调 harness,干到 0.86,对标 Opus 4.8 的 0.87。

结论:你买的不再是模型,是"模型+harness"一套。只要 agent 碰真实的东西(仓库、收件箱、支付、生产库),你就需要 harness。

从外往里建:四个环

  1. Containment(隔离)——agent 物理上够不着什么:容器、独立分支、只读数据库账号、网络只走 allowlist。写第一行 prompt 之前先做这个;
  2. Guides(指引)——行动前的 steer:仓库里的 AGENTS.md、写清楚的工具描述、几个好输出的例子;
  3. Sensors(传感)——行动后的检查:linter、类型检查、测试套件,快且确定性的全量跑;慢的(如第二个模型审 diff)只用在要紧处;
  4. 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,把模型已经长出来的能力对应的部分删掉。
原文配图:Harness 的四个环(@undefinedKi 图5)
原文配图:Harness 的四个环(@undefinedKi 图5)
记住:Harness 层最便宜的动作:给你的 agent 一个删不掉任何东西的账号去跑。
📝

第五层 Evals:每月同一张考卷

以下来自 @undefinedKi。你怎么知道新员工进步了?拿上个月同一张卷子再考一次,对比分数。没有同一张卷子,你做的每个改动都是猜。Evals 就是 agent 的那张卷子:一组你已经知道正确答案的任务,每次改东西都跑一遍。

两种检查

  • 端到端——最终答案对不对?它只告诉你分数动了,不告诉你为什么;
  • 行为检查——某个具体行为发生了吗?回答前调没调搜索?请求含糊时问没问清楚?说"做完"之前验证了吗?行为检查跑在 trace(agent 干过一切的日志)上,而不只看最终答案。Google 的规矩:这套检查 5 秒内跑完,才能每次改动都跑。

如果用模型当裁判(judge),裁判本身也要被查:Airbnb 发现他们模型生成的参考答案,约四分之三在重复跑同一输入时结果不一致——他们的 eval 在测自己的噪声。

搭 eval 的四步

  1. 从真实失败开始——翻实际运行记录,把翻车现场转成测试用例。Airbnb 的 golden set 是 50–100 个例子,且必须包含失败例;
  2. 一例一行为检查——一个用例只验证一件事;
  3. 查你的裁判——先人工判一批样本,看你和模型的同意率,再决定信不信它;
  4. 抽线上流量反哺——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
避坑
别盯总通过率:总分能涨的同时,某个具体行为在悄悄变坏。盯每一条单独的检查。
原文配图:好的评估用例从哪来(@undefinedKi 图7)
原文配图:好的评估用例从哪来(@undefinedKi 图7)
记住:Evals 层最便宜的动作:把你最近 5 个失败写成测试用例。
🔧

收尾:按"工作单元"定位 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,人留住决策。这就是不加人头也能扩规模的样子。

原文配图:五层框架中文版图解(@nicos_ai,与 @akshay_pachaar 同一框架)
原文配图:五层框架中文版图解(@nicos_ai,与 @akshay_pachaar 同一框架)
词

术语翻卡:点卡片看解释

上下文工程
Context engineering
决定模型每次回答前"桌上摆什么":放什么、放哪、放多少。放多了反而变差。
循环工程
Loop engineering
给目标不给步骤,让模型自己试、看结果、定下一步;必须有目标、检查器、停止规则、预算。
Jev 工程
Jev engineering
只做选择不写作的"前台":把便宜、常规的判断从大模型手里接过来。
Harness 工程
Harness engineering
除模型之外的一切:工具、权限、沙箱、项目说明文档、对输出的检查。Agent = 模型 + harness。
评估工程
Evals engineering
每月同一张考卷:一组已知正确答案的任务,每次改动都跑,盯行为不只盯总分。
提示缓存
Prompt caching
服务商复用你 prompt 开头的机制,缓存 token 便宜约 10 倍,但要求开头字节级一致。
工作单元
Unit of work
@akshay_pachaar 区分五层的尺子:从单次输入、窗口内容、一次执行、整轮运行,到整项工作逐层变大。
黄金集
Golden set
评估用的标准测试集,如 Airbnb 的 50–100 例,且必须包含失败用例。
测

自测一下:点问题展开参考答案

因为它们是包裹关系不是替代关系: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,把模型已经长出来的能力对应的部分删掉。