AGENT  /  自学手册
00 / 10  ·  INTRO

十章 · 2026.11

智能体与 AI 系统优化AGENT一本自学手册

这本手册把 agent 当作一个系统问题来讲解:模型决定能力上限,harness 决定实际表现,服务系统和 GPU 决定成本与速度。前八章讲解 agent 怎样使用与设计,包括循环、工具、上下文、记忆、多智能体、可靠性、评估和降本;后两章讲解 LLM 推理与 GPU 的基本原理。每章先列要点,再展开内容,然后给出「用到工作里」的具体做法,最后附上自测题。

SCROLL

01第 1 章

全景:AI 系统与智能体系统The big picture: AI systems and agentic systems

要点

  1. AI 系统主要研究怎样大规模训练和运行模型,核心目标是快、省、稳、可持续。本书所说的 AI 系统,专指大语言模型(LLM)系统。
  2. 智能体(agent)依靠模型进行思考、调用工具并逐步行动,直到完成任务。可以把它视作一台新计算机:LLM 相当于 CPU,上下文相当于内存,工具相当于外设,harness 相当于操作系统。
  3. 智能体的运行时是一条「推理、调工具、再推理」的长链。这种负载的每一个特征,都对应着一个需要解决的系统难题。
  4. 系统真正需要优化的不是每秒生成多少 token,而是在延迟、成本、资源、可靠性和安全的约束下,尽量把任务顺利做成。

先认识几个全书都会用到的核心词汇。

token 是模型读写文字的最小单位,大致相当于一个词或词的一部分。系统的计费和速度都按 token 计算。

harness 是包裹在模型外层的那套控制程序。它把用户的输入和文件整理好后提交给模型,负责执行模型要求的工具调用,检查操作权限,再把工具执行结果返回给模型。同一个模型搭配不同的 harness,实际表现会有很大差距。

AI 系统与传统计算机系统的五点不同

维度 要点
计算 CPU 和 GPU 各自分工:CPU 负责分词、启动 GPU 上的计算程序(kernel)、搬运数据和执行工具调用;GPU 则负责大规模矩阵乘法。模型读入整段提示的阶段叫 prefill,受算力瓶颈限制;之后逐个吐出 token 的阶段叫 decode,受显存读取带宽限制。单次请求的计算耗时取决于最终输出长度,事先无法预知,因此难以进行排队调度
非确定性 即使输入完全相同,两次运行的结果也可能不一样。这是因为浮点数加法只要调换计算顺序,就会产生微小差异;第 7 位小数的微小偏差,就可能改变下一个生成的 token。这些差异来自运行时(如 GPU 线程组 warp 的调度顺序、单批同时处理的请求数量)、软件层(如乘加是否合并为一步 FMA、自动调优选用的算法)以及硬件层(如使用普通核心还是 tensor core、是否采用 FP8 等低精度格式)。在工程上,这种近似是可以接受的
内存、存储与通信 模型权重通常从几 GB 到几 TB 不等。KV cache 是模型为已读过的每个 token 保存的中间结果,用来避免重复计算,每个 token 会占用几十到几百 KB;prefix cache 则让开头相同的请求共享这份缓存。系统真正的性能瓶颈往往在数据搬运,而不是计算本身。当单台机器容纳不下模型时,需要将模型拆分到多张 GPU 上运行(可按层、按矩阵、按专家或按上下文拆分),高度依赖 NCCL、NVLink、InfiniBand 和 RDMA 等高速互连技术
快速演化 注意力机制(即模型在上下文里检索相关信息的机制)经历了快速迭代,其结构从 MHA 演化到 GQA、MLA、NSA 和线性注意力,大方向都是为了节省显存和计算开销。系统的工作负载也从多轮对话、长推理、检索增强(RAG)进一步演进到智能体。智能体的上下文更长、重度依赖 prefix cache,并且需要在多个模型和机器之间进行路由与负载均衡
可靠性与功耗 GPU 的年故障率为 9%,在一个拥有 16K 张 GPU 的大型集群中,大约每 3 小时就会损坏一张卡;单卡功耗在 700 至 1000 W 之间,单台服务器的功耗也从 800 W 攀升到了 6000 W

GPU 服务器的功耗约为 CPU 服务器的 8 倍

单台服务器功耗,W

  1. CPU 服务器800 W
  2. GPU 服务器6,000 W
原始讲义

这些细节会在第 9、10 章进一步展开。眼下只需记住一点:模型输出的内容越长,耗时就越久、费用就越贵,而且两次运行的结果不保证完全一样。

什么是智能体

智能体是一个自主运行的软件系统。它以既定目标为核心,调用 AI 模型进行思考,通过使用外部工具(例如搜索、读写文件、运行代码、调用接口)执行多步操作,直到完成全部任务。

它的工作流程可以拆解为五个步骤:

01计划:把任务拆成子步骤
02行动:调用外部工具
03观察:读懂工具返回的结果
04调整:按新信息修订计划
05交付:返回最终结果

之所以需要智能体,是因为当前 LLM 的各项能力很不均衡。

在知识回忆、语言表达、模式匹配、编写代码以及跨领域联想上,LLM 超越了大多数人类。然而,它记不住上一次对话的内容,无法可靠地理解超长上下文,容易一本正经地编造虚假信息(产生幻觉),无法察觉自己的知识盲区,并且很容易被恶意输入带偏。

智能体正是为了弥补这些短板:用外部工具补足「动手能力」,用记忆模块补足「记性缺陷」。

我们可以把智能体看作一种新型计算机:LLM 对应 CPU,上下文窗口(模型单次能读取的全部文本)对应内存,外部工具对应外设,harness 对应操作系统,而智能体本身则对应上层应用程序。无论是在编写方式还是在出错模式上,它都与传统计算机完全不同。

为什么智能体是系统问题

传统的 LLM 服务通常是一次性完成的,交互模式表现为「请求、推理、响应」。

智能体的执行过程则是一串漫长的调用链,表现为「推理、调用工具、再推理、再调用工具、检索、再推理……」的循环往复。

完成一次任务往往需要跨越 GPU、CPU、存储、网络以及外部服务,由此引发了六个突出的系统问题: - 后续步骤高度依赖前序步骤的输出; - 每个步骤的执行耗时差异极大; - 系统需要频繁挂起,停下来等待外部工具执行完毕; - 运行状态和上下文数据会越积越多; - 系统需要支持并发执行,并提前推测下一步动作; - 漫长调用链上的任何一个环节都可能发生故障。

智能体负载的特征 对应的系统问题
轨迹长(一次任务几十上百步) 状态与上下文管理
上下文大 内存分层与检索
前缀重复(每步都带着同样的系统提示和历史) prefix caching
推理会分叉 推测执行
工具之间有依赖 依赖感知的调度
用到不同模型 路由
工具耗时不定 异步执行
会对外部产生影响(发邮件、改数据库) 安全与隔离
多个智能体 编排与通信
任务运行时间长 检查点与容错

从系统架构上看,整个系统自上而下可以分为六层: - 应用与用户层; - 智能体与 harness 层(负责规划、上下文管理、记忆、工具调用和子智能体),横向连接着网页、文件、API、人等外部环境与工具; - 模型层; - 服务系统层(负责把请求打包批处理、排队调度、路由以及缓存); - 运行时与 kernel 层(包括 CUDA、Triton 和多卡通信); - 硬件层(包括 GPU、CPU、内存、网络和存储)。

优化什么

对智能体系统而言,吞吐量(每秒生成多少 token)是一个错误的优化目标。

系统真正的目标,是在延迟、成本、资源占用、可靠性和安全性的多重限制下,尽可能把任务顺利做成。

真正要优化的指标

  • 任务成功率与准确率
  • 从提交到拿到结果的总耗时
  • 每个任务消耗的 token
  • 每个成功任务的成本(美元)
  • 每个成功任务的能耗

有用但不够的指标

  • TTFT(首 token 时间)与 TPOT(每 token 时间)
  • 工具调用耗时
  • GPU 利用率

即使每秒生成的 token 更多,智能体整体上依然可能更慢、花费更贵——例如它在执行过程中多绕了十步路。

因此,系统的可观测性是头等大事。一次任务必须能够展开为层层嵌套的完整调用记录(包括会话、轮次、智能体步骤、模型请求、工具调用以及子智能体)。如果无法清晰观察内部运行过程,性能优化就无从谈起。

贯穿全书的问题

批处理与延迟为什么把请求打包处理能提高吞吐量,却会拖慢智能体?什么时候该换更大的模型?
状态放在哪里KV cache 和共用的前缀应放在哪里?同一个智能体的多个请求该怎样排队?
重叠与分工等工具的时候模型能不能先干别的?什么时候该派出子智能体?
路由与恢复怎样在不同的 GPU 和模型之间分配请求?跑了 30 分钟的任务中途失败,怎样接着跑?
优化目标怎样优化「每个成功任务的成本」,而不是「每秒 token 数」?

本书重点关注推理系统工程,不涉及模型训练(当前推理已占据了主要的算力需求)、模型结构设计、多机通信算法、功耗控制以及新型硬件设计。

用到工作里

  1. 01先给任务定义「做成了」的判定标准,比如测试全部通过、报告字段齐全、数字与源表一致。如果没有明确的判据,就无法算出成功率和每个成功任务的成本。
  2. 02按完整任务记账,而不是按单次模型调用记账:为每个任务记录消耗的总 token、花费、耗时以及最终是否做成。比较两个智能体或两种提示词时,核心依据是这些综合数据,而不是看谁单次回复更快。
  3. 03遇到耗时过长或费用过高的任务时,打开智能体的运行日志或链路追踪记录,将其展开为一步一步的具体工具调用过程;先找出最慢、最贵、重复调用最多的一步,再着手优化。
  4. 04参考下方的「六个层级」,合理决定对智能体的放手程度:建议先从层级 3 开始,交付一个范围明确的任务并人工审查结果;等到验收流程可以自动化(例如具备自动化测试和校验脚本)之后,再升级到层级 4。
  5. 05并不是所有事情都需要引入智能体。对于规则固定、单步就能直接完成的任务,编写脚本或使用简单机器人成本更低、运行也更稳定,第 8 章会详细讲解判断方法。
附:AI 编码的六个层级,以及智能体、助手与机器人
层级 含义
0 不用 AI,纯手写代码
1 辅助:AI 自动补全
2 受监督:AI 写函数,人工审查
3 限定范围:交付明确任务,审查生成代码
4 目标驱动:AI 编写全部代码,由测试验证
5 并行智能体:多个子智能体分工协同
智能体 助手 机器人
目的 自主、主动地执行任务 协助用户完成任务 自动化执行简单任务或对话
能力 执行多步复杂动作,具备学习与自主决策能力 响应提示词并提供建议,最终由用户决策 依循预设规则执行,学习能力有限
交互 主动发起,面向既定目标 被动响应,依据用户请求行动 被动响应,依据事件触发或固定指令运行

自测

评估一个智能体时,最该盯住的是哪一项?

自测

智能体负载的这些特征,各自对应哪个系统问题?

每一步都带着同样的开头
工具耗时不定
会改动外部数据
任务一跑就是半小时


02第 2 章

Agent 如何工作:循环、记忆与扩展How an agent works: the loop, memory and extensions

要点

  1. 你的一句话会展开成多次模型调用和工具执行:模型提出要做什么,harness 检查权限后执行,结果写回上下文,再进入下一轮。
  2. 上下文是租来的工作记忆,会话一结束就会消失。项目说明文件和自动记忆是持久文件,每次会话都会重新加载;过时的记忆比没有更糟。
  3. 四种扩展各司其职:skill 管「怎样做」,MCP 管「能碰到什么」,hook 管「到某个时刻自动做什么」,plugin 管「打包分享」。

一个编程用的 agent 本质上就是一个循环:

01收集上下文:你的提示、相关文件、上一步工具结果
02模型生成动作:例如「运行 pytest」
03harness 检查权限并执行
04结果写回上下文,回到第一步

循环中的几个事实

  • 你还没开口,上下文里已有 1 万多 token。 这里面先放入了系统指令、项目环境和记忆(项目说明文件)。接着是可用工具的说明,包括读文件、编辑、执行命令、按名称找文件、搜内容、上网与派子智能体。之后还会放入 skill 与 MCP 的名称及简介,最后才是你的提示词。其中,skill 与 MCP 起初只占用名字和一句话简介,真正用到时才会加载全文。
  • 不会把整个代码库发给模型。 代码库始终留在磁盘上,模型只按需提取片段。例如搜索「authentication」时,只会带回匹配的几行。
  • 模型只提议,harness 才执行。 模型发出工具请求后,harness 会解析请求、检查权限并在本机执行,最后把执行结果(tool result)放回模型的上下文。每一次新的请求,都建立在上一次推理和工具结果之上。
  • 权限层夹在「想做」和「去做」之间。 工具请求只是提议,必须先由你或另一个模型批准(见下表)。
  • 上下文会越来越长,然后被压缩。 目前常见的上下文长度是 1M token,年初多为 256K。调用花费的大部分来自读取已缓存的前缀(prefix cache)。当窗口快满时,agent 会执行压缩(compaction):把旧的执行过程总结成一段摘要,再重新放回项目说明文件和记忆。
权限模式 含义
手动 每一步都由你确认
接受编辑 改文件自动通过,其他操作仍需确认
跳过权限 全部直接执行
自动 由一个小模型审查每个请求

每个请求的结果有三种:允许(命令运行)、询问(先由你确认)、拒绝(什么都不发生)。

记忆:上下文是租来的,记忆是自己的

agent 在两次运行之间什么都不记得,每个会话都会从零开始。

所谓记忆,本质上是会话启动时加载的文件。上下文属于临时的工作记忆,会话结束就会消失;持久记忆则保存在会话之外,下次启动时重新加载。

需要持久记忆主要有四个原因: - 同样的指令被重复说了多次; - 同样的探索被重复做了多次; - 上下文压缩后,丢失了最初的决定和理由; - 不同的会话对同一件事做出了不一致的选择。

记忆的作用,就是把一次次的叮嘱固定为惯例。

项目说明文件 自动记忆
谁来写 你 agent
内容 指令与规则 学到的经验与模式
范围 项目、个人或组织 每个代码库一份;同一库的不同工作目录共享
加载 每个会话 每个会话;只加载开头一部分,例如前 200 行或 25KB
用途 规范、工作流程、架构 偏好、纠正、项目背景

项目说明文件是一份 Markdown 文件,agent 每次启动时都会读取。具体的文件名和存放位置,取决于你所使用的 agent 文档。

它通常分为四层,按范围从大到小依次加载。层级越具体,读取越晚,优先级也越高: 1. 组织策略:由组织统一制定,个人无法关闭; 2. 个人全局设置:适用于个人的所有项目; 3. 项目文件:存放在代码库中,随项目共享给团队; 4. 本地个人文件:仅保存在本地供个人使用,不进入版本库。

应写进项目说明文件

  • 命令:怎样跑测试、构建、代码检查(lint)
  • 硬约束:不直接提交到 main,不改自动生成的文件
  • agent 很难自己低成本查到的事实:目录怎么分、谁负责哪块、有哪些坑

不该写进去

  • 模型本来就知道的语言或框架知识
  • 代码检查和格式化工具已经强制的风格
  • 长篇说明、变更记录、任何机密

每个说明文件建议控制在 200 行以内,尽量使用 Markdown 标题和列表。规则要写得具体明确,切忌自相矛盾。

如果内容过长,可以按主题拆分成多个规则文件。若所用的 agent 支持为规则配置生效路径,应设置成仅在访问匹配文件时才加载。

自动记忆由 agent 自动编写,通常每条记录会标注一个类型: - user:记录你的角色与偏好; - feedback:记录你纠正过或确认过的做法; - project:记录进行中的工作,以及代码中未体现的决策; - reference:记录项目外部资料的存放位置。

agent 会维护一个索引文件列出所有条目,每次启动只加载开头一部分。对应具体主题的文件,仅在涉及相关任务时才读取。

多数 agent 都提供了对应的管理命令,用于完成以下操作: - 浏览、编辑或关闭记忆; - 查看当前加载了哪些说明文件; - 自动生成说明文件初稿; - 检查说明文件中是否包含不当内容。

记忆有代价:常驻的每个 token 都是每次会话开头付的租金,还和任务抢同一个窗口。过时的记忆比没有记忆更糟,因为它会主动误导。像对待代码一样审查、修剪记忆,并纳入版本控制。

工具与四种扩展机制

核心工具 作用
读取 打开文件、查看状态,用得最多
搜索 按内容(grep)或文件名(glob)查找,不必全部通读
抓取 拉取网页或文档,会把不可信的文字带进上下文
编辑 / 写入 修改文件,第一个会产生实际后果的工具
命令行 运行构建、测试与 git 等命令;不加沙箱时,等于把整台机器交出去
委派 派出子智能体,带回一份摘要

模型会根据任务自主决定调用哪个工具。如果想让 agent 具备更多能力,可以使用以下四种扩展机制:

机制 解决的问题 挂在循环的哪一处
Skill agent 应当怎样完成某类任务(知识与流程) 模型推理
MCP 能碰到哪些外部数据与动作 工具选择
Hook 在某个时刻自动发生什么 任意阶段,可以检查、拦截或响应
Plugin 扩展怎样打包和分享 把前三者打成一个可安装的包

以发布流程为例(准备发布、验证、发布到 GitHub、通知团队):

01Skill:按发布步骤执行
02MCP:在 GitHub 上创建 release
03Hook:测试失败时阻止发布
04Plugin:把整套配置分享给团队

Skill 本质上是一个文件夹。其中包含一份说明文件(名称和简介决定 agent 何时选用该 skill,正文则规定具体流程),以及相关的参考资料和脚本。

会话开始时,系统只加载 skill 的简介;真正执行任务时,才会加载完整正文。它的调用方式有两种: - 模型自主调用:当任务内容与简介匹配时触发; - 手动显式调用:由你通过一条斜杠命令指定调用。

对于会产生副作用的操作流程,建议要求手动调用。将各个 skill 的简介编写清晰且避免功能重叠,可以有效减少误调用。从本质上看,skill 是一种对上下文的管理手段。

MCP(Model Context Protocol,模型上下文协议)提供了一套统一的标准协议,用来连接 GitHub、数据库、监控、Figma、Slack 和浏览器等外部服务。

一次典型的 MCP 调用分为六步: 1. agent 判断需要执行一个外部动作; 2. MCP 客户端发起工具调用; 3. MCP 服务器处理连接; 4. 外部服务执行具体操作; 5. 操作返回结构化结果; 6. agent 评估返回的结果。

MCP 在使用体验上与本地工具几乎一致,区别仅在于它运行在另一个独立的进程中。

Hook 是挂在事件上的自动化动作。它只要触发预设事件就会执行,不靠模型的主动记忆。需要注意的是,模型推理本身并不是事件。

Hook 可以用来运行命令、发 HTTP 请求、调用 MCP 工具、向上下文插入一段提示,或者启动子智能体。

01会话开始:加载上下文、记录
02你提交提示:校验或补充
03工具调用前:检查或拦截
04工具调用后:格式化、测试、记录
05停止前:确认测试通过

Plugin 将 skill、hook、子智能体定义、MCP 配置以及代码语言服务配置打包成一个整体。它带来了以下优势:单条命令安装、版本固定、避免命名冲突、方便团队复用,以及可以通过市场分发。

项目中的 agent 配置目录通常包含以下几个部分: - 记忆层:说明文件与规则文件; - 控制层:设置文件,负责管理权限、hook 与环境变量; - 工作流:skill 和自定义命令; - 护栏与委派:子智能体与 hook。

个人主目录下也有同样的结构,作用于你的所有项目。当规则冲突时,项目设置优先于个人设置。

需求 用什么
遵守公司 API 规范 Skill
从 Jira 读取 issue MCP
每次编辑后运行格式化 Hook
引导多步部署 Skill
完成后发送通知 Hook 加 MCP
阻止写入生产环境 Hook 或策略
跨代码库共享全部配置 Plugin

用到工作里

  1. 01为你最常用的项目写一份说明文件:先列出测试、构建、检查的命令;再写两三条硬约束;最后注明目录结构和已知的坑。写完后删掉模型本来就会的内容,控制在 200 行以内。
  2. 02如果同一件事纠正了 agent 两次以上,就把它写进说明文件,或让 agent 记进记忆。这是成本最低的提效方法。
  3. 03按实际需求选用扩展:一套反复使用的流程写成 skill;读写外部系统接入 MCP;必须每次都发生、不能指望模型记得的事(如自动格式化、拦截危险命令)配置为 hook;要给整个团队使用时打成 plugin。
  4. 04权限模式建议从「手动」或「接受编辑」开始。「跳过权限」只在沙箱、容器或可以随时丢弃的环境中开启。
  5. 05定期翻一遍自动记忆和说明文件,删掉过时的条目。改动应纳入版本控制,像审查代码一样审查它们。
延伸:MCP 的细节

在 MCP 出现之前,N 个 AI 客户端连接 M 个服务,需要维护 N×M 套集成方案。

MCP 是一个开放且无状态的协议。在这一架构中,宿主应用(host,例如你用的 agent)会为每个服务运行一个 MCP 客户端,而 MCP 服务器则把具体的系统能力封装暴露为工具。

MCP 原语 是什么 例子
tools 可调用的动作 create_issue(…)
resources 可读取的数据;例如一个 issue 或数据表结构 github://issues/123
prompts 服务器提供的提示模板;由你决定何时使用 在 agent 里显示为一条斜杠命令,例如「分诊 issue」

这三者可以互相配合。例如在分诊 issue #123 时:prompt 提供组织的分诊流程,resource 提供 issue 内容,tool 则负责拉取当前的诊断信息。

使用 MCP 时需注意以下安全要点: - 最小权限原则:访问令牌仅授予必需的仓库、数据表或频道; - 读写分离:写操作严格设置人工审批; - 警惕不可信输入:不要直接把外部工具的输出当成系统指令; - 审查第三方服务:安装第三方服务器前先审查,防止其中夹带提示注入(藏在内容里、诱导模型执行恶意的指令)。

在连接任何外部服务前,建议先问两个问题:这个服务器能读什么?又能改什么?

MCP 网关是 AI 客户端和多个 MCP 服务器之间的控制层,负责汇总、路由、执行策略、代表用户身份认证、观测和扩容。

当用户、agent、服务器数量众多,或合规规则复杂时,引入网关能够统一管控。但网关本身就是信任边界,伴随以下潜在风险:凭据范围过宽、丢失最终用户身份、工具重名、日志泄露机密,以及存在单点故障风险。

2026-07-28 版规范是协议发布以来最大的一次修订,主要改动如下: - 核心改为无状态设计,任何请求都可以分发至任意一台实例处理; - 新增 Mcp-Method 请求头,让网关无需读取请求正文即可完成路由; - 工具列表支持按有效期进行缓存; - 长时间任务(Tasks)和由服务器渲染的界面(MCP Apps)以扩展形式提供支持。

自测

设计练习:每个需求该用哪种机制?

遵守公司 API 规范
从 Jira 读取 issue
每次编辑后运行格式化
引导多步部署
阻止写入生产环境
跨代码库共享全部配置

自测

下面哪一项应该写进项目说明文件?


03第 3 章

多智能体用法与 Programming 3.0Multi-agent use and Programming 3.0

要点

  1. 只改指令就能改变 agent 的工作方式:Superpowers 用 skill 加会话启动 hook 规定开发流程,Caveman 用 skill、hook、MCP 和本地代理从读、写两个方向压缩 token。
  2. 扩展规模有三条路:并行智能体省下等待时间,子智能体换来专注,长时运行扩大一次能做的范围;多个 agent 组队只在工作需要彼此讨论时才值得。
  3. Programming 3.0 的核心是不确定性:不要指望 agent 每次都一样,要让它周围的系统可靠,放手程度与风险匹配。
  4. 一线数据显示,交给 agent 的任务半年内明显变大,但任务越长,不用人插手就做成的比例越低。

案例一:Superpowers

Superpowers 是一个面向软件开发的 plugin。默认情况下,agent 拿到需求就会直接开始写代码,往往依赖反复试错来修正。安装 Superpowers 后,开发流程会规范为:

01人输入需求
02澄清问题
03批准设计
04写详细计划
05测试驱动开发:先写会失败的测试,再写代码让它通过
06审查与验证
07完成或合并分支

它由九个 skill 组成:

Skill 职责
using-superpowers 何时发现、调用哪个 skill 的规则
brainstorming 把需求变成获批的设计
writing-plans 把设计拆成具体任务
using-git-worktrees 建立互不干扰的工作区
test-driven-development 红(测试失败)、绿(测试通过)、重构
systematic-debugging 先找根因,再提修复
requesting-code-review 对照计划审查实现
verification-before-completion 报告「完成」之前要拿出证据
finishing-a-development-branch 合并、提 PR、保留或清理分支

一个 skill 文件通常包含六个部分:名称、简介、指令、检查点、参考资料与脚本。如果是流程型 skill,还可以进一步写明进入条件、必做动作、禁止动作、需要人工批准的关口、验证要求,以及下一步应该调用的 skill。

仅仅安装 skill,并不能保证 agent 会主动读取。Superpowers 的解决办法是添加一个在会话启动时运行的 hook。每次会话启动、清空或压缩之后,脚本都会读取一个「引导 skill」的全文,并直接注入到上下文中,提醒 agent 遵循这套流程。

设计问题 Superpowers 的做法
复杂行为怎样表示 小而可组合的 skill
agent 怎样记得用 由会话 hook 注入一个引导 skill
上下文怎样保持可控 各任务的 skill 只在相关时加载
各阶段怎样衔接 每个 skill 写明关口和下一个 skill
用户怎样安装 全部打包成 plugin
是否必须有命令或 MCP 不必,需要时再加

案例二:Caveman

Caveman 从读和写两个方向来压缩 agent 的 token。这主要出于三个原因: 第一,日志、diff(代码改动对比)和工具输出会严重挤占上下文; 第二,每一轮交互都要为这些 token 支付费用,并消耗等待时间; 第三,如果等上下文占满后再统一压缩,容易裁掉关键细节。

例如,它可以把 786 行测试输出压缩成一句:「3 个测试失败:client.ts:88 处 ETIMEDOUT」。

65%报告的输出 token 降幅;skill 本身会增加输入 token,整段会话的节省更少
2压缩方向:skill 改变模型怎样写,代理改变模型读到什么
5MCP 工具:压缩、按原样取回、统计、JSON 与 TOON 格式互转

Caveman 用到了全部五种扩展机制,外加一个本地代理(运行在 agent 与模型服务之间、能够改写每个请求的小程序):

  • skill:规定简洁文风。保留术语、命令、路径、代码、报错、数字、单位与否定词;删去填充语、重复表述、客套话与含糊说法。
  • 命令:用于选择压缩档位,例如 /caveman ultra、/caveman off。
  • 会话启动 hook:决定并保存当前会话的档位,并在压缩后恢复规则;提交提示词时的 hook 则用来检测会话途中的档位切换。
  • MCP:提供内容压缩与按原样取回功能。
  • plugin:负责打包分发。
  • 本地代理:按内容类型进行针对性压缩。日志保留报错、调用栈与首尾;代码保留 import、函数签名与类型;diff 保留文件名、改动块头部与改动行;JSON 则保留键名与结构。
Hook 能拦截请求,但不能悄悄改写发给模型的内容,所以要用代理。代理拦下每一个请求并改变上下文;MCP 只在被调用时运行,改变不了上下文。如果你自己写 harness,可以直接在里面做。

三种扩展方式

并行智能体 子智能体 长时运行
做法 多个独立任务,各用一个 worktree 把边界清楚的任务交给一个新上下文,拿回摘要 一个大任务连续跑很多步
换来 省下等待时间,不提高答案质量 省时间又专注:主对话里看不到中间的杂乱过程 范围:一次做更多,你插手更少

手动并行。 git worktree 允许同一个代码库拥有多个独立的工作目录。每个目录都有独立的文件和分支,同时共享提交历史。目录之间彼此互不影响,既不需要暂存未提交的改动,也不需要重新克隆一份代码。

很多 agent 都支持用一条命令为每个会话创建一个 worktree。例如,一个会话负责开发支付功能,另一个会话负责修复登录 bug。如果只开三个会话,人脑还能记住整体规划;但一旦开到二十个会话,管理难度就会骤增:所有计划全凭人脑记忆,各会话之间彼此看不见,分支全靠人工合并,而且整个过程缺乏记录,无法重新运行。

子智能体 是拥有独立上下文、工具集和权限的专门助手。它的核心用途有五个: 1. 保护主上下文,避免被冗长内容塞满; 2. 严格限制当前任务可用的工具和模型; 3. 在多个项目之间复用能力; 4. 并行处理任务; 5. 控制成本(例如指定使用小模型)。

自定义子智能体通常保存在一个 Markdown 文件中,存放在项目或个人的配置目录里。文件开头注明名称、简介、可用工具与选用模型,正文就是它的系统提示词。

子智能体还可以继续派生下级子智能体,但调用层级存在上限,通常保持在 2 至 3 层最为合适。需要注意的是,子智能体自身必须拥有「委派」工具,才具备继续派生的能力。

常见的内置子智能体 用途
探索型 只读搜索代码库,不能写入或修改;每次调用可以设定检索深度
计划型 在规划阶段进行调研,把中间的探索过程隔离在主窗口之外
通用型 负责既需要调研探索又需要动手实现的复杂多步任务

为了提升速度并节省成本,探索型和计划型子智能体在启动时会跳过项目说明文件与 git 状态。

调用子智能体的方式,按控制力度从弱到强可分为:

  1. 01用自然语言点名:由 agent 决定要不要委派,只作用于这一次
  2. 02用专门的语法点名:这次任务一定交给它
  3. 03让整个会话以这个子智能体的身份运行:采用它的提示、工具和模型
留在主对话 交给子智能体
反复来回的迭代 之后不会再用的冗长输出
多个阶段要共用上下文 需要限制工具或权限
快速、定点的修改 自成一体、只需返回摘要的工作
要求快 并行、独立的工作;简单活交给小模型

Agent 团队(部分 agent 提供的实验性功能)由一名负责人和多位队友组成。负责人分派任务、协调进度并汇总成果;每位队友都是一个独立的 agent 实例;团队成员共享同一张任务列表并自主认领;每个 agent 都有专属邮箱,队友之间可以直接通信。

队友不会继承主对话的历史记录,但会自动加载项目说明文件与 skill。

这种模式非常适合多角度代码审查、彼此独立的模块开发、多假设并行排查的调试,以及前后端跨层协作。如果任务具有强先后顺序、需要同时修改同一个文件,或者步骤间依赖很重,则应该改用单个会话或子智能体。

子智能体 Agent 团队
通信 只向调用者汇报 队友之间直接通信
协调 负责人管理 共享任务列表
适合 只要结果的任务 需要讨论的工作
token 成本 较低 较高

动态工作流 是指在后台通过脚本编排大量子智能体协同工作。它适合全代码库排查 bug、涉及 500 个文件的大规模迁移、需要交叉核对的技术调研,以及从多个角度制定实施方案。

长时运行。 一种实现方式是「目标模式」:向 agent 交付一个结果可验证的终态,例如要求「代码检查命令以零错误退出」。评估器会在 agent 每次尝试后进行复查,一旦满足条件或用完最大尝试次数就会自动停止。「所有集成测试通过」可以作为明确目标,但「重构代码」不行,因为系统无法自动判断它是否真正完成。

另一种实现方式是「定时循环」:每隔固定时间重复执行同一条提示词,例如每隔 5 分钟执行一次「检查 CI,哪里坏了就修」,直到人工叫停为止。

案例三:16 个 agent 写出一个 C 编译器

16并行 agent,约 2,000 个会话,历时两周
~10 万行 Rust 代码,能在 x86、ARM、RISC-V 上构建 Linux 6.9
2B / 140M输入 / 输出 token,API 费用略低于 2 万美元
~99%主要测试套件通过率

该项目的协调完全依赖通用的基础工程设施:

  • 每个 agent 都在独立的容器中运行,并拥有专属的代码副本。
  • 通过指定目录下的锁文件来认领任务,避免两个 agent 同时处理同一件事。
  • 某个任务开发并测试完成后,agent 先拉取最新代码,完成合并并推送后,再释放文件锁。
  • 每次启动新会话时,读取一份统一的进度文档来恢复上下文。
  • 安排专门的 agent 负责编写文档、优化性能、把控质量以及去除重复代码。
  • 借助自动化测试的反馈,让所有 agent 明确当前的整体进展。

整个过程既没有复杂的 agent 间聊天,也没有专门充当经理角色的统筹 agent。

该方案也存在不足:代码合并冲突频繁;当所有 agent 同时卡在某一个特定的 Linux 内核编译错误时,并行机制就会失效;16 位 x86 架构相关部分仍然依赖 GCC;最终生成的机器码执行效率也不及 GCC。

Programming 3.0 与不确定性

一种划分 人写什么 经过什么 变成什么
Programming 1.0 机器指令或汇编 硬件执行
Programming 2.0 编程语言 编译器 机器指令
Programming 3.0 用自然语言说清目标 agent 编程语言,再到机器指令

演进阶段越靠后,整体生产力就越高,面临的不确定性也随之放大。

Karpathy 提出的 Software 3.0 给出了另一种视角的划分:1.0 时代的程序是人类编写的源代码;2.0 时代变成了神经网络权重(通过收集数据并训练优化而来);3.0 时代则是提供给大语言模型的提示词(自然语言)。在实际工程中,准确判断一项任务究竟适合用 1.0、2.0 还是 3.0 的方式来解决,是一项至关重要的工程能力。

软件工程中的不确定性由来已久。硬件层面的架构差异(32 位与 64 位、字节序)、环境层面的并发竞争与不可靠网络,以及软件层面的编译器版本与依赖静默升级,都是经典的不确定性来源。在 2.0 时代,业界的应对手段包括引入固定宽度的数据类型、内存一致性模型、支持安全重试的幂等接口,以及在版本升级前进行全面的回归测试。

到了 3.0 时代,系统又新增了数种不确定性:GPU 计算本身的非确定性与浮点数精度差异、模型生成代码时对运行环境的直接篡改、采样机制带来的随机性,以及一句话提示词本身的含糊不清。

在 3.0 体系中,不确定性主要分布在五个层面: - 自然语言层:模型可能偏离人类的真实意图; - 检索与上下文层:检索结果变动、索引更新滞后,或内容遭到截断; - 模型生成层:采样机制以及底层软硬件带来的非确定性; - agent 与工具循环层:调用外部工具失败,或运行环境发生动态变化; - 生成的程序层:生成后的代码运行表现通常确定,除非它在运行时仍需调用外部模型或工具。

  1. 01定义:先把假设说出来,含糊之处让模型动手前先确认;交出的是结果而不是一句提示,即需求、不变量(任何时候都必须成立的条件)、约束和验收测试
  2. 02控制:把「提议」和「执行」分开,计划先验证再提交;主动管理上下文,掌握记忆、来源和检索,让过时信息失效
  3. 03验证与治理:把「生成、验证」的循环收紧,频繁而便宜的检查胜过最后一次昂贵的审查;往深一层测量,准备测试、多个指标和能推演的模拟负载

不要指望 agent 本身是完全确定的,而要确保围绕它构建的外围系统足够稳健可靠。对 agent 的放手程度,应当始终与潜在的风险相匹配。

来自一线的证据:Codex 与 OpenAI 内部

交给 Codex 的任务在半年内明显变大

处理该类任务的用户占比,%,2025 年 12 月对比 2026 年 5 月;人时指人完成该任务所需的小时数

  1. ≥ 1 人时 · 2025.1235.4%
  2. ≥ 1 人时 · 2026.0570.2%
  3. ≥ 8 人时 · 2025.122.1%
  4. ≥ 8 人时 · 2026.0525.6%
OpenAI Codex 报告(2026 年 6 月)

处理整日任务的用户比例增加了 12 倍。2026 年上半年,Codex 活跃用户增长超过 5 倍。从渗透率来看,过去 28 天内使用过 Codex 的个人用户尚不足 1%,组织用户占比为 17.3%,而 OpenAI 内部员工则几乎全员使用。

28.6%OpenAI 用户一周内同时运行 5 个以上 agent
~2.5中位员工每天的 agent 运行时长(小时)
~71第 99 百分位员工每天的 agent 运行时长(小时),比 4 月增长 88%
3.14×2026 年 9 月研究部门里,agent 工作日与人的工作日之比

在 2026 年 6 月之前,agent 的运行时长尚低于人类的工作时长,但此后便完成了反超。目前,多数研究员同时推进 4 条以上的并行工作线;工程师人均修改的代码行数,已接近 2025 年前平均水平的 8 倍。在此背景下,人类工程师的角色全面转向了规划、委派、监控、审查与整合。

任务越长,不用人插手就做成的比例越低

无需人工介入即成功的任务占比,%,按人完成该任务所需时间分组

  1. 86%<15m
  2. 76%15–30m
  3. 69%30m–1h
  4. 61%1–2h
  5. 57%2–4h
  6. 43%4–8h
  7. 40%8–16h
  8. 23%16–32h
  9. 13%32–64h
  10. 16%64–128h
OpenAI 报告(2026 年 9 月)

委派阶梯从低到高可划分为五级: 1. 聊天机器人:AI 负责回答,人类负责动手; 2. 助手:人类与 AI 协作推进; 3. agent:人类把整块独立工作完整交接出去; 4. 多 agent 协作者:人类负责统筹协调多个 agent; 5. 系统化工作流:完全由 skill 和 agent 驱动运行整个业务流程。

即使按这把阶梯来衡量,目前 OpenAI 员工整体也仍处于相对较低的几个层级。

用到工作里

  1. 01先让一个 agent 把事情跑通,再考虑并行。并行只用于彼此独立的任务(不同模块、不同 bug),每个任务一个 worktree;会改同一个文件的任务不要并行。
  2. 02冗长的搜索、读日志、查资料交给子智能体,只让它带回摘要;给它最少的工具,只需要读就只给读。
  3. 03交给 agent 的长任务,一律写成「可以自动检查的终态」:一条命令加期望结果,例如「测试命令退出码为 0」「报表里 12 个月份都有数」。说不出怎么检查,就先别交出去。
  4. 04任务越长越容易失败。人做要好几个小时的活,拆成几个各自能验收的小任务,逐个交出、逐个检查。
  5. 05把自己反复用的流程拆成几个小 skill,每个写明进入条件、禁止动作和下一步;改生产数据、对外发送这类节点设人工批准。
  6. 06工具输出太长时,学 Caveman 的规则让 agent 只看要紧的部分:日志看报错和首尾,diff 看改动行,JSON 看键和结构。
附:CLI 编码 agent 概览(2026 年 7 月)
类别 代表
模型厂商自带 Codex CLI、Antigravity CLI、Grok Build、Mistral Vibe、Kimi Code、Qwen Code
平台型 Copilot CLI、Cursor CLI、Amp、Auggie、Droid、Junie CLI、Qoder、CodeBuddy
开源,自带密钥 OpenCode、Crush、Goose、Aider、Cline、Kilo、Continue、OpenHands 等
极简内核 Pi、oh-my-pi、mini-SWE-agent、gptme、Open Interpreter
维度 两端
开源与闭源 开源:Codex CLI、OpenCode、Goose、Cline、Pi;闭源:Copilot CLI、Cursor、Droid、Junie
绑定厂商与自带密钥 只能用单一厂商的模型:Antigravity CLI、Grok Build;可接任意模型服务:OpenCode 支持 75 家以上提供方,Kilo 支持 500 多个模型
沙箱与权限提示 用操作系统沙箱隔离:Codex CLI、Copilot CLI、OpenHands 用容器;逐项弹出权限提示:多数工具
本地与云端 本地优先、不上报使用数据:Goose、Nanocoder、gptme;可交给云端继续:Copilot CLI、Codex、Mistral Vibe
大而全与极简 功能最全:oh-my-pi;只有四个工具:Pi、mini-SWE-agent(约 100 行 Python)

自测

这类工作该留在主对话,还是交给子智能体?

反复来回的迭代
之后不会再用的冗长输出
快速、定点的修改
需要限制工具或权限
要求快
并行、独立的工作

自测

用「目标模式」交出长任务时,哪一个可以当目标?



04第 4 章

智能体设计 I:循环、工具与上下文Agent design I: the loop, tools and context

要点

  1. 智能体等于模型乘以 harness。只改动 harness,同一个模型在两个 SWE-bench 版本上解决的任务数就能提升到原来的 1.7 至 2.3 倍。
  2. 设计工具本质上就是设计上下文:工具精简且不重叠,输出节省 token,报错信息能指引模型修正。
  3. 上下文具有成本、延迟和注意力三重代价。当关键答案位于中间位置时,模型最容易遗漏。
  4. 窗口过大时,应依次采用准入、卸载和变换三种手段,让大模型做摘要压缩是最后的兜底方案。

ReAct 与智能体循环

ReAct(reason + act,边想边做)把推理和行动放进同一个循环。这个循环包含三个环节:思考(明确已知内容、缺少的信息以及下一步计划)、行动(发出环境能够执行的结构化调用,例如“搜索某个函数名”)、观察(获取环境返回的客观事实)。

如果只推理不行动,没有任何机制检验推理的正确性,微小的偏差会逐渐累积成自信的幻觉。如果只行动不推理,工具调用背后缺少规划,模型容易在原地打转。ReAct 让思考引导下一次行动,同时让观察结果修正下一次思考。这一循环会持续进行,直到获取的观察足以回答问题,或者触发了停止规则。

用代码逻辑表示,一个最小的 agent 循环如下:

  1. 01消息列表以系统提示和用户请求开始
  2. 02在步数上限内循环:调用模型,把回复追加到消息列表
  3. 03如果模型给出最终答案,返回
  4. 04否则对每个工具调用:检查参数、执行工具、把结果转成文字作为一条工具消息追加
  5. 05超过步数上限,报错退出

作为 harness 的设计者,主要需要完成四项任务:编写工具定义(明确告知模型有哪些工具及其参数要求);组装输入上下文;检查调用请求、核对权限并执行;可选地处理执行结果并管理上下文。

在设计编码 agent 时,三个核心组件需要协同考量,因为它们共享同一个上下文窗口: - 模型与执行循环; - 工具与配套护栏(包含权限控制、沙箱隔离及审批机制); - 运行时状态(包含当前窗口中的内容,以及跨步骤传递的信息)。

工具设计:搜索与读取

方法 靠什么找代码 适用 主要成本
glob / grep 按文件名模式或字面内容匹配 名字已知或可推测 每次搜索都会消耗一轮交互与上下文;换了表述的代码无法通过字面匹配找到
语义索引 将代码块转为表示语义的向量(嵌入)后按意图检索;或参考 Aider 生成 repo map(包含文件树及按重要性排序的函数名与类名) 你的说法与代码中的实际写法不一致 需要预先建立索引,并随代码变更保持同步
外部线索 报错调用栈、失败的测试用例、git 历史提交 已有明确报告指向特定代码 依赖前置信息,仅部分任务具备该条件
语言服务器(LSP) 基于编译器掌握的符号关系:定义位置、被谁引用、类型信息 代码修改必须同步更新所有关联引用,例如重命名 每种语言都需要常驻一个服务进程,启动较慢

在工程实践中,建议先使用 grep;当名称不足以定位目标时,再引入语义索引或 LSP。

工具设计:编辑

方法 做法 风险
整文件重写 模型重新生成完整文件 输出随文件长度增长;长文件中未打算修改的代码也可能被悄悄改动
统一 diff / patch 模型输出改动补丁,由工具解析并应用 一旦行号或上下文代码已过时,补丁中的改动块(hunk)就无法套用
搜索替换 提供一段精确的原文作为定位锚点,并给出替换内容 若锚点文本不唯一、代码已过时或空白字符对不上,替换就会失败
结构化 / AST 编辑 直接对抽象语法树(AST,即代码的结构化表示)上的符号下达指令,如重命名或新增参数 每种语言都需要专门的工具支持,能够表达的改动类型有限;但从构造机制上能保证不产生语法错误

工具设计:执行与其他

Shell(命令行)是能力最强、同时也最危险的工具。单次调用即可完成命令串联、数据过滤、循环与重试,能直接访问文件系统、网络、包管理器及各类程序。此外,shell 留下的文件与进程在调用结束后依然存在;可以说,shell 能做的事情,agent 都能做。

在设计 shell 工具时,必须重点想清楚五个方面: - 隔离:明确命令在何处运行,以及能访问哪些资源; - 失败信号:提供 agent 能够理解、并能据此采取行动的错误提示; - 输出控制:保证信息足够支持判断,但不过量堆积; - 运行耗时:合理处理耗时较长的任务与后台进程; - 预算上限:明确重试次数,达到上限后及时停下来交由人工接管。

此外还有五类常用工具: - 记忆与笔记:确保关键计划在上下文被压缩后依然留存; - 子智能体:独立完成探索后仅返回一份候选清单,避免把多达 40 次读文件的全过程塞入主上下文; - 网页搜索与抓取:优先查阅本地已安装的代码实现,确有需要时再上网检索; - 浏览器与视觉反馈:将页面截图传回给模型查看,辅助确认界面状态; - 向用户提问:发起一次低成本的澄清提问,远胜过直接提交一个自信却错误的补丁。

少而不重叠功能重叠的工具会让模型犹豫该选哪一个
专用而非万能search_orders(customer_id) 胜过直接执行 SQL 的 run_sql
输出省 token截断、分页、摘要;设计工具本质上就是设计上下文
报错要能教人返回如何修正的具体指引,而不仅仅是提示「参数无效」
默认幂等同一个调用执行两次与执行一次的效果相同,便于安全重试

专为 agent 设计的接口比只给 shell 解决更多问题

SWE-agent 消融实验(逐项去掉某个设计、看效果变化),GPT-4,解决率,%

  1. 专用 SWE-agent 接口18%
  2. 保留完整交互历史15%
  3. 整文件查看12.7%
  4. 只给 shell11%
  5. 无专用编辑器10.3%
SWE-agent 消融实验,原始讲义

SWE-bench 是使用真实 GitHub issue 评测 agent 能力的基准测试:向 agent 提供代码库和问题描述,检验其生成的补丁能否让测试通过。

从提示工程到目标工程

时期 名称 问题 关注
2023–2024 提示工程 怎样指示模型 提示措辞、示范样例、输出格式
2025–2026 上下文工程 模型应该看到什么 检索召回、记忆系统、历史记录、上下文压缩
现在 harness 工程 agent 应该怎样运行 运行循环、工具集成、沙箱隔离、重试与停止机制
下一步 目标工程 什么算成功 目标设定、评判标准、边界约束、权衡取舍
提示技巧 做法 何时用 何时换下一种
零样本 仅给出任务指令 任务常见,且格式要求能用文字清晰说明 当规则难以用文字说清时,切换为少样本
少样本 给出指令并附带几个示例 输出结构特殊,文字规则不如范例好懂 当任务需要推导步骤时,切换为思维链
角色与人设 为模型指定一个角色身份 语气风格或判断标准关键,且受众明确特定 当任务需要推导步骤时,切换为思维链
思维链 先写出推理步骤,最后给出答案 任务确实具有逻辑步骤,主要错误源于跳步 当存在多条可行路径时,切换为思维树
思维树 展开多条思路分支,分别打分并剪掉差的分支 多条路线皆可行,且分支打分成本较低 当只有一个确定答案时,切换为自洽
自洽 对同一问题多次采样作答,最后投票聚合 答案唯一且出错代价高;当得票数不足(如低于 3/5)时转交人工 当任务可拆解为明确阶段时,切换为提示链
提示链 每次调用只聚焦一件事,交接前执行检查 工作流程分阶段推进且每段可独立质检;哪一段不合格就只重试该段 当需要调优提示词本身时,切换为元提示
元提示 让模型自行迭代改写其提示词 拥有一套可量化打分的评测集 当优化收益陷入停滞时,回头重新审视架构选择

提示设计包含四条通用原则: 1. 从简单方案起步,按需补充上下文; 2. 分区编写,将上下文、指令、工具说明与输出要求清晰分开,按「指令、分隔符、数据」的顺序排列; 3. 表述具体且简洁,避免无意义的花哨措辞; 4. 将复杂大任务拆解为小任务,不要一开始就堆砌复杂度。

需要注意的是,提示的写法往往因模型而异,更换底层模型就需要重新调优;许多针对早期模型的旧技巧,对新一代模型已经不再适用。

上下文工程:上下文是有限资源

Karpathy 将上下文工程定义为:为智能体的下一步恰好提供所需信息的艺术与科学。

上下文的使用伴随着三重代价: - 成本代价:执行循环的每一步,都需要把整个窗口重新发送一遍; - 延迟代价:提示内容越庞大,预填充(prefill)和解码(decode)的速度就越慢; - 注意力代价:窗口越满,模型的有效记忆越差,其中位于中间部分的信息最容易被模型忽略。

答案位于上下文中间时,准确率最低

答案在 20 篇文档中的位置与回答准确率,%

  1. 76%第 1 篇
  2. 61%第 5 篇
  3. 55%第 10 篇
  4. 59%第 15 篇
  5. 71%第 20 篇
Liu et al., “Lost in the Middle”, TACL 12 (2024)

上下文长度增加本身也会带来性能下降:在 Chroma 的 Context Rot 测试中,输入从 1K token 增至 400K token 时,简单查找任务的准确率下降到 73%;一旦加入干扰内容,准确率进一步降至 46%。

以一轮对话的示意 token 预算为例:系统提示约 2K,工具定义约 6K,项目环境信息约 8K,检索来的内容约 25K,而消息历史记录约 80K 且一直在持续增长。

当窗口过大时,可依序采用四种管理手段。这四种手段从预防性、无损处理,逐步走向有损裁剪与不可逆压缩:

前三种手段在不做摘要的情况下,把上下文缩小 75% 至 98%

示例,处理前后的 token 数

  1. 准入 · 原始网页 DOM48,000
  2. 准入 · 只留抽取结果900
  3. 卸载 · 60 个工具定义42,000
  4. 卸载 · 索引加 3 个定义3,100
  5. 变换 · 保留全部结果96,000
  6. 变换 · 只留最新状态24,000
原始讲义示例
手段 做法
准入 在入口处严格把关:开展定向检索,只取需要的字段而不抓取整篇内容;预先将工具输出整理为精简格式,无法整理时再执行截断;将庞大的原始数据交给子智能体单独处理
卸载 仅在需要时动态加载:工具定义实行分级加载;引入工具检索机制,平时只留一份索引,用到哪个工具再按需读取其完整定义(即 schema);工具输出只返回一个句柄,后续凭句柄再读取全文;将任务清单写在磁盘上;持久化记忆在上下文中仅保留精简索引
变换 有选择地丢弃历史信息:对对象状态执行去重,每个对象只保留最新状态;遮蔽过往的观察结果,剔除 N 步之前的工具输出;采用滑动窗口机制,仅保留开头设定和最近几轮交互
压缩 作为最后的兜底手段,调用 LLM 进行压缩:生成滚动摘要;达到窗口上限时执行全量摘要;利用自动记忆机制将关键事实沉淀到窗口之外。压缩时要为模型输出预留空间,保留系统前缀设定,并在压缩完成后重新注入关键事实

上下文引发的失败主要有五种表现。只要明确叫出对应的名字,修复思路就清晰了: - 投毒:模型生成的幻觉进入了上下文窗口,并在后续交互中被当作既定事实反复引用; - 分心:交互历史过长,agent 开始机械地模仿自己过去的动作; - 混淆:引入了无关的工具定义和参考文档,把推理答案带偏; - 冲突:新旧信息互相矛盾,却未作清理而同时保留在窗口中; - 漂移:真正的核心目标被细节掩盖,不知不觉被替换成了附近的某个子目标。

同一个模型在只改动 harness 的情况下,在两个基准测试上解决的任务数均显著增加:SWE-bench Verified 由 43/169 增至 72/169,SWE-bench Pro 由 31/316 增至 72/316。改动仅有四项:压缩旧的工具输出、让最近的观察保持可见、检测重复和停滞、在卡住时主动介入。一部分表面上看似「模型不行」的问题,本质上是上下文管理和控制循环设计的问题。

用到工作里

  1. 01给 agent 接入新工具(例如查订单、查库存的接口)时,对照五项原则检查:功能与已有工具是否重叠;名称和参数是否清晰专用;默认返回是否精简并支持分页;报错信息是否说明了如何修正;重复调用是否具备幂等安全性。
  2. 02agent 答非所问或执行越跑越偏时,先对照五种上下文失败排查原因:是否引用了之前的错误结论(投毒);是否陷入自我重复(分心);是否被无关文件带偏(混淆);是否新旧说法互相打架(冲突);是否遗忘了原本的目标(漂移)。
  3. 03把最关键的信息放在开头或结尾,不要埋在一大段材料的正中间;给 agent 的参考材料只保留相关段落,切忌整篇粘贴。
  4. 04在长会话中,对于处理完的大段日志、网页和数据,引导 agent 存入文件并只保留文件路径句柄,或者交给子智能体读取并只带回最终结论。
  5. 05选择提示技巧时从零样本起步,对照前文表格逐级升级;若有固定格式要求就提供两到三个示例,若任务包含多个阶段就拆解为提示链,每一段检查通过后再交给下一段。
延伸:ReAct 之外

各种架构在循环设计上各有侧重: - ReAct:每一步都在推理与行动的交替中循环; - Reflexion:在任务失败后触发反思循环(包含尝试、评估、反思与重试); - Plan-and-execute:在执行偏离原计划时触发重排循环(包含计划、执行与重新规划); - 树搜索:不进行逐步循环,而是一次性展开多个分支并行探索,最终仅保留表现最好的一条路径。

自测

这些做法属于哪一种上下文管理手段?

只取需要的字段,不取整篇
只留工具索引,用到再加载完整定义
每个对象只保留最新状态
到上限时让 LLM 总结历史
把原始数据交给子智能体处理
去掉 N 步之前的工具结果

自测

「历史太长,agent 开始模仿自己过去的动作」属于哪种上下文失败?


05第 5 章

智能体设计 II:多智能体系统Agent design II: multi-agent systems

要点

  1. 多智能体不是默认选项。值得拆分的理由只有四个:专门化、隔离、并行和管住上下文。
  2. 每种架构都在回答三个问题:谁来协调、怎样拆分任务、怎样通信。真实系统都是几种架构的混合。
  3. 子任务要写清目标、边界、输出格式和完成标准。只有省下的工作量超过协调开销,并行才划算。
  4. agent 之间的通信本质上是分布式系统问题:控制信息和内容要分开,用幂等键和回滚路径应对超时。

三张图与八种架构

每种架构背后都要理清三张图: - 控制图:解决谁来协调的问题。可以是一个主管、逐层主管,或者没人管;还要考虑运行中是否需要交接。 - 任务图:解决怎样拆分的问题。可以由规划者预先拆好,由大家竞价认领,或者按局部规则自发形成。 - 通信图:解决怎样通信的问题。可以直接发消息、全员广播,或者共用一个工作区。

类别 架构 核心思想 适合 弱点
集中式 主管与工人 一个规划者,多个执行者 可拆分、可并行的子任务 主管容易成为瓶颈;其上下文涨得最快
集中式 层级式 主管再管子主管 本身可以一层层往下拆的任务 错误会被逐级放大;每一层交接传多少上下文很难确定
集中式 流水线 / DAG 每个阶段的输出喂给下一个,交接处约定好数据格式 阶段清楚、顺序固定 错误会向下游传递,无法回头;但最容易调试
去中心 市场与拍卖 agent 按能力、成本、速度竞标 动态分配,任务落到最便宜的合格者手里 报价由自己申报,可能夸大能力
去中心 黑板 通过共享状态(数据库、文件系统、git 仓库)协调 大家围绕同一个产物工作 状态容易过时;需要处理一致性、并发、来源、版本与清理
去中心 委员会与辩论 先各自作答,再由裁判或投票裁决 需要判断的任务 群体思维;使用同一模型、相同上下文时,盲点也一样
去中心 蜂群 没有固定协调者,彼此直接协商 局部协商 消息数随 agent 数量平方增长(n 个 agent 约 n² 条);冲突难解;产品中少见
混合 动态拓扑 运行中增删或重连 agent 事先不知道任务结构;希望简单任务保持便宜 每次形状不同,失败难以复现

DAG(有向无环图)是一张只往前、不绕回的任务依赖图。例如:B 要等 A 做完才能开始,C 和 D 则可以同时进行。

真实系统通常都是混合架构。例如:规划 agent 按一张随时可调整的任务 DAG,把工作分派给编码、调研、测试、审查几个 agent。大家共用一个 git 仓库,必要时重新规划。这同时用到了主管、层级、共享内存和流水线。

01规划 agent
02随时可调整的任务 DAG
03编码 · 调研 · 测试 · 审查
04共用的 git 仓库
05必要时重新规划

任务分解

拆分的维度有六种: - 按数据:每个 agent 处理一部分文档。 - 按专长:分别负责安全、性能、正确性、法务。 - 按阶段:划分为计划、实现、测试、审查。 - 按假设:每个 agent 调查一种可能的解释。 - 按工具:分别使用网页、数据库、代码执行工具。 - 按权限:划分不同的管理范围。

例如审查一个修改了 200 个文件的 PR 时,可以先按文件拆分,再按安全和性能拆分。

一个好的子任务,需要明确写清以下内容:目标;输入与相关上下文;边界与排除项;可用工具与权限;输出格式(schema,规定返回哪些字段和类型);完成标准;预算与期限;依赖哪些别的任务。

差的子任务

  • 「调研存储系统」

好的子任务

  • 「找出 2026 年发表的存储相关论文,返回标题、日期、系统贡献、评测规模和一手来源链接,排除数据库查询优化」

任务粒度需要权衡。粒度太大就无法并行;粒度太小,调度和通信开销就会占大头。

多智能体的总耗时,约等于规划时间、关键路径时间(最长那条依赖链)、通信时间与合并时间的总和。只有省下的串行工作超过这些开销,并行才有用。例如,与其派 20 个 agent 各做一次一行的查询,不如合并成 4 个子任务。

拆分方式可以是静态的(执行前就知道,如总结 5 个 PDF);动态的(发现死链就派发一个查询任务);递归的(审查 agent 为每个子领域再派子智能体);或者机会式的(空闲的 agent 主动认领下一份未标注的文档)。

对于动态拆分,必须设置派生数量上限、预算、深度上限和终止条件,否则委派可能会无限递归下去。

常见拆分失败 例子
重叠 两个 agent 总结了同一篇论文
缺口 一个管「2020–2023」,一个管「2025–2026」,漏了 2024
隐藏依赖 定价需要先估算规模,运行时才发现
无法合并 一个返回自由文本,一个返回 JSON
丢失全局上下文 每一节单看都没问题,整份报告自相矛盾
掉队者 六个 agent 20 秒完成,一个用了 4 分钟,大家都在等它

通信

维度 选项 经验法则
拓扑(谁能和谁说话) 主管与工人、点对点、网状 照着任务的依赖关系来
介质(信息怎样交换) 消息传递(队列或总线)、共享内存(如共享任务列表)、文件与产物(含数据库) 每条链路只用一种介质
信道(信息怎样传递) 点对点、广播、发布订阅、共享黑板、请求响应、交付产物 只有所有人都必须知道时才广播
格式与含义 自然语言加控制字段 按字段路由,不按文字内容路由

自然语言灵活但含糊;结构化消息容易校验,但表达力偏弱。实用的做法是两者结合:在消息里带上 task_id、type、status、claim(主张)、confidence(把握)、evidence(证据)、artifact(产物)等控制字段。

把控制信息与内容分开后,运行时只需要识别有限的几种操作:DELEGATE(委派)、QUERY(询问)、REPORT(汇报)、HANDOFF(交接)、UPDATE(更新)、CANCEL(取消)、ACK(确认收到)、ERROR(出错)、COMPLETE(完成)。这样运行时不用去问 LLM「这条消息什么意思」,就能直接进行路由、重试和停止。

通信本质上是困难的分布式系统问题。例如 agent A 让 B「购买 8 个 GPU 实例」,网络超时且没有收到回复:B 到底有没有执行?系统该重试还是放弃?是保证「至多执行一次」(可能漏买),还是「至少执行一次」(可能重复购买)?能否做到「恰好一次」?解决办法是用 task_id 做幂等键(同一个 ID 只会生效一次,重发也不会重复购买),同时准备补偿和回滚路径,并事先明确重复购买由谁负责。

多智能体系统继承了分布式系统的全部难题: - 并发与非确定性; - 不可靠的网络(延迟、丢包、乱序、重复); - 没有统一的时钟; - 部分失败(分不清一个 agent 到底是变慢了还是挂掉了); - 多份状态之间的一致性; - 调试与可观测性(各机器时钟有偏差时,日志很难对齐)。

此外还要解决调度(谁下一个运行、运行多久)、资源分配(模型、CPU)和状态管理(检查点、记忆、来源、版本),而且请求流并不是预先排好的。

叠加 LLM 的黑盒特性后,问题更加棘手:

问题 表现
信息丢失 摘要丢掉了执行者知道的细节
上下文污染 关键信息被淹没
过时信息 X 已经改成 5,B 还按 X=3 行动
信念冲突 A 说安全,B 说有漏洞
没人负责 每个 agent 都以为别人在管
通信绕圈 A 问 B,B 问 C,C 又问 A
难以诊断 说不清为什么失败

A2A 与 MCP

A2A(agent-to-agent)是 agent 之间的通信协议。每个 A2A 服务器都在 /.well-known/agent-card.json 发布一张 Agent Card(名片),写明身份、技能、地址、能力(如是否支持流式返回)和认证方式。

协议包含三个基本概念:消息(客户端与 agent 之间的一来一回)、任务(有 ID、有生命周期的一项工作)、产物(任务的输出)。后续消息都会归入同一个任务。

任务的生命周期包括:提交、工作中;中途可以停在「需要输入」或「需要认证」状态,恢复后再继续;最终状态为完成、失败、拒绝或取消。

跟进长任务有三种方式:轮询(适合短任务)、流式(适合边做边看输出)、推送通知(适合要跑几个小时的任务)。

需要注意,A2A 只负责统一通信方式,不负责编排。谁委派给谁、怎样拆分、何时停止,依然由 harness 决定。

01提交
02工作中
03需要输入或认证时暂停,之后恢复
04完成 · 失败 · 拒绝 · 取消
MCP A2A
主要对象 能力 / 工具 agent / 任务
连接的是 agent 和服务 agent 和 agent
能发现什么 工具、资源、提示 对方 agent 的能力
一次工作 一次工具调用 一个长时任务
内部状态 公开能力接口 最好不对外公开
类比 设备或 API 接口 服务之间的远程调用(RPC)

一个 A2A 远程 agent 内部可能调用二十个 MCP 服务器。MCP 具体暴露什么能力,由 host 决定,而不是由模型决定。

设计原则

  1. 01先问是否真的需要多智能体:单个 agent 够用时,多智能体通常只会增加开销
  2. 02按任务依赖决定拓扑,尽量减少通信
  3. 03找出信息丢失的地方:做汇总的节点就是细节丢失的地方
  4. 04划定失败隔离的边界,确保一处卡住不会拖死整个系统

稠密的网状结构很少是好的默认选择。通信越多,上下文压力越大,却不一定能换来更多有用信息。

用到工作里

  1. 01动手拆之前先试单个 agent。只有出现下面情况之一才拆:上下文装不下;需要不同权限或工具;子任务彼此独立、并行能明显省时间;需要不同专长分别把关。
  2. 02给每个子任务写一张「任务单」:目标、输入、不做什么、可用工具、返回格式(列出字段)、怎样算完成、预算与期限。返回格式统一,最后才合并得起来。
  3. 03拆完逐项检查六种失败:范围有没有重叠、有没有缺口(时间段、地区、产品线之类最容易漏)、有没有没写出来的依赖、返回格式能不能合并、整体是否一致、有没有一个特别慢的子任务需要再拆。
  4. 04最后合并时安排一个人或一个 agent 通读全文,专门找各部分之间的矛盾,因为汇总处最容易丢细节。
  5. 05会花钱、发消息、改数据的动作,都带上唯一的任务编号,执行前先查这个编号是否已经执行过,超时后宁可查询状态也不要直接重试。

自测

这类任务最适合哪种架构?

可拆分、可并行的独立子任务
阶段清楚、有固定顺序
需要判断的任务
把任务动态分配给最便宜的合格者

自测

两个 agent 分别负责「2020–2023」和「2025–2026」,结果漏了 2024。这是哪种拆分失败?


06第 6 章

智能体设计 III:记忆与可靠性Agent design III: memory and reliability

要点

  1. 记忆的每一环都是权衡取舍:写不写、存成什么样、放在哪里、何时取用、怎样归纳、何时忘掉。
  2. 每条记忆都要带上有效时间和来源,「遗忘」和「记住」一样是必备操作。
  3. 每步成功率 95% 时,50 步的任务只有 8% 能全程不出错。错误不仅会累积,还会往下游传递。
  4. 故障来自五个地方:任务描述、harness、模型、工具和环境,每一处都有对应的防御方法。

记忆的六个设计问题

01写入还是跳过:值得留下吗
02编码与组织:存成什么形式
03存储:放在哪里
04检索:这个任务需要它吗
05反思与归纳:能总结出什么更广的结论
06保留、更新、删除:它还成立吗

写入。 如果每次交互都记下来,关键信息虽然不会漏,但会带来大量噪声;如果有选择地记录,内容虽然更准确,却可能遗漏上下文。

判断写不写的依据通常包括:用户明确要求、预设的固定规则、轻量分类器,或者定期让 LLM 统一复查。

组织形式 例子 特点
原始事件 「我们把服务从 vLLM 迁到了 SGLang。」 保真度高;但体积大且内容冗余
非结构化摘要 「用 SGLang 做模型服务。」 紧凑省空间;但可能丢失上下文细节
结构化状态 serving_engine = SGLang 检索方便;但受限于预设的字段定义
知识图谱 项目 → 使用 → SGLang 实体互相关联;能表达随时间产生的变化
存储后端 例子 擅长
纯文件 项目说明文件、草稿本 方便人工查看、对比改动和搜索
键值或关系数据库 Redis、SQLite、Postgres JSONB 精确查找、条件过滤和事务保障
向量库 pgvector、Chroma、Pinecone 语义相似度搜索
图数据库 Neo4j、FalkorDB(Graphiti) 关系查询;沿着关系进行多步遍历
何时用记忆 做法 优点 缺点
自动 每轮对话都执行搜索、调用 LLM 并写入 行为可预测,流程简单 增加响应延迟;容易带入无关内容
由运行时控制 只有满足特定条件时才搜索或写入 更有针对性,节省资源 需要编写规则或训练分类器
由模型控制 把搜索、新增、更新、遗忘做成工具交给 LLM 按需灵活调用 模型可能在需要时未读,该记时未写

很多系统会混合使用这些方式,读取和写入的策略也可以完全不同。

检索。 检索的基础流程是:拿当前问题去查,通过向量搜索找出相似度最高的前 k 条内容,然后放进提示词中。

然而,「意思相近」只是一个参考信号。检索时还需要综合评估多个维度: - 范围:是否属于同一个用户、项目、对象或任务; - 重要性:漏掉关键记忆或带错信息的代价有多大; - 有效性:该信息此时此刻对当前任务是否依然成立; - 来源:信息出自哪里,确信度有多高,有哪些证据支持。

反思。 反思是指从多次行为中提炼高阶结论。比如用户多次询问 vLLM、SGLang、TRT-LLM 和 LLM 调度,系统可以归纳出「对 LLM 推理系统有持续兴趣,把握中等」。

归纳提炼适合在攒够新证据之后进行(例如每记录 N 个事件,或上下文占满时),也可以在发现事实冲突或重复时触发。为了不影响交互体验,这部分工作应尽量放在后台处理。

遗忘和记住同样重要。 需要遗忘的原因包括:信息过时、记录错误或相互矛盾、涉及隐私与安全,以及控制存储和检索成本。

常见的处理方法有:标记为失效、永久物理删除、设置生存时间到期自动清理(TTL),或者分层存放并从常用记忆中移出。

每条记忆都应该带上有效时间和来源。例如 2026 年 4 月记的是「用 vLLM 服务」,到了 6 月它被「用 SGLang 服务」取代,同时注明该信息出自第 28 段对话。

归谁管。 记忆的管理通常有两种方式:

一种由 agent 自己管理。记忆存放在 harness 内部的文件中,比如项目说明文件、草稿本或任务笔记,并由 harness 负责存盘。

另一种是交给专门的外部记忆系统。agent 将其作为一项独立服务来调用,记忆由此成为跨 agent、跨会话共享的公共接口。

记忆系统 类型 怎样存、怎样取
Mem0 以事实为中心 按用户、agent 或单次运行划分范围;通过向量搜索加过滤;可选配图记忆
Graphiti 带时间的知识图谱 从对话片段中抽取实体和带有效期的事实;结合语义、关键词与图检索进行混合搜索
supermemory 画像、记忆与文档 同时维护用户画像、记忆和文档;自动关联数据来源与时间
记忆的失败模式 表现
检索遗漏 相关的记忆明明存在,检索时却没有找到
上下文污染 引入了过多无关记忆,占满了上下文窗口
记忆幻觉 把推测当成事实存入,比如把「在 A 大学读书」记成「A 大学访问学生」
过时 旧的事实没有被更新,继续压制新信息
隔离失败 租户隔离失效,一个用户的记忆泄漏给了另一个用户
过度泛化 把一次偶然发生的操作,误当成长期的固定偏好
持久化的提示注入 未经清洗的不可信内容被存入记忆,未来重新读出时以指令身份执行
无限增长 数据越存越多,导致检索成本越来越高、准确度越来越低

评估一套记忆系统通常关注四个维度: - 检索质量:找得准不准、召回全不全; - 写入与更新:写得准不准、全不全,过时记忆的占比有多高; - 数据治理:该清理的内容删除了没有,不同范围之间有没有做到严格隔离; - 系统表现:引入的额外延迟、多消耗的 token 数量,以及存储空间的增长速度。

端到端的基准测试主要评估 agent 能否在超长的对话历史中进行回忆与推理。测试场景覆盖了信息回忆、时间时序推理、事实更新、偏好提取,以及在信息不足时该拒答就拒答。常见基准包括: - LoCoMo(ACL 2024):包含 10 段长对话,共 1,540 题; - LongMemEval(ICLR 2025):考察 5 种记忆能力,共 500 题; - BEAM(ICLR 2026):测试长度最长可达 1000 万 token,共 2,000 题。

搭建记忆系统通常有两种架构:一种是构建独立的记忆层,由 agent 运行时配合 Mem0 或 Letta 这类记忆管理系统,底层接入向量库、SQL、图数据库或对象存储;另一种是直接把记忆放在 harness 内部,由运行时自行管理,存成 Markdown 文件。

可靠性:误差会累积

每步成功率 95% 时,50 步的任务只有 8% 全程无错

全程无错的概率,%,按任务步数,假设各步互相独立

  1. 95%1 步
  2. 77%5 步
  3. 60%10 步
  4. 36%20 步
  5. 8%50 步
按 0.95 的 n 次方计算

一个复合任务只有在每一步都执行成功时,整体才算成功。在实际执行中,前一步产生的错误还会继续向后传递并累积,因此真实情况往往比理论估算更糟糕。

整体来看,系统故障通常来自五个环节:任务描述、harness、模型、工具、环境。

失败 例子 修法
目标含糊 「修复登录 bug」,结果修的是三个 bug 里不对的那一个 明确写明相关文件、错误症状和复现方法
替代目标 要求「让测试通过」,它直接把失败的测试删了 禁止擅自修改测试,严格审查每次代码变更
没说出口的约束 要求「加快搜索」,结果破坏了现有的对外接口 事先明确写明哪些部分不能改动
没有完成标准 要求「整理一下解析器」,于是一直重构停不下来 提供明确的验收测试和停止规则
目标冲突 要求「改动最小,同时覆盖所有边界情况」,它悄悄放弃了边界情况 明确不同目标之间的先后优先级
任务描述:把「完成」写成测试事先给出验收测试,明确列出不能改动的范围
harness:给每次运行设上限限制步数、成本和时间;设立检查点以便及时回滚
模型:要求拿证据说话每个推论都要有明确证据并做验证,必要时更换更强的模型
工具:失败要明确报错明确字段类型,严格区分空结果与执行失败
环境:固定依赖并做好隔离每次运行使用全新且版本固定的沙箱,遇到偶发失败先重试再判断

对于在生产环境中大规模运行的 agent,业界目前的了解仍然有限,沉淀下来的成熟最佳实践也较少。

用到工作里

  1. 01交任务前先核对五个问题:目标是否具体(涉及哪个文件、什么症状);是否存在被「钻空子」的可能(例如直接删掉测试);哪些内容绝对不能变动;达成什么标准才算完成;几个目标发生冲突时谁更优先。将这些答案明确写入任务描述中。
  2. 02给每次运行设定三个上限:最多跑多少步、最多花多少钱、最长运行多久;在关键节点设置检查点,遇到失败及时退回上一个稳定状态。
  3. 03要求 agent 拿证据说话:声称「测试通过」必须附带测试运行日志,声称「已修复」必须附带复现步骤的前后对比。
  4. 04为记忆管理立好规矩:每条记录都打上日期和来源;推测得出的结论必须标注「推断」;涉及个人信息的数据设置到期失效时间;定期清理陈旧和互相矛盾的条目。
  5. 05任务执行步数越多越容易出错,能拆分的任务尽量拆分:拆成若干段并逐段验收,远比一口气跑完复杂的长链路可靠得多。
  6. 06排查失败时按五个来源逐项核对:先看任务描述是否存在歧义,再检查 harness 的上限与状态,接着分析模型的行为,最后排查工具和环境。

自测

这些故障出在哪里?

要求「让测试通过」,结果删掉了失败的测试
没有步数或成本上限,跑了 200 步毫无进展
说「测试应该能过」,却什么都没运行
日期没带时区,任务差了 8 小时
遇到闰年就失败

自测

每步成功率 95%,各步互相独立,20 步全程无错的概率约为多少?



07第 7 章

智能体设计 IV:评估Agent design IV: evaluation

要点

  1. 被评估的对象从单个模型变成了模型、提示、工具与 harness 的整体,打分依据变成测试结果和环境的最终状态。
  2. 八个代表性基准各测一种环境:问答、函数调用、网页、桌面、代码仓库、客服、终端和模拟公司。
  3. 难点有三:数据泄漏有四种途径;一次给全指令的考法奖励瞎猜;只看成功率会忽略成本和安全。
  4. 基准被「刷满」的速度越来越快;评价一个真实的 agent,要同时看能力、成本和速度。

基准(benchmark)就是一套公开的标准考题,大家用同一套题来比较不同模型或 agent。

简史与评估目标

评估 agent 主要有两条路径: 一是分组件评。主要测试规划与任务拆分,记忆的抽取、整合与检索,工具的发现、选择与参数填写,以及出错后的恢复能力。 二是端到端评。主要考察整体成功率、每个任务的成本和完成用时。

基准的发展方向是:覆盖范围更大、给定指令更不具体、测试场景更真实、考题更新更频繁。

时期 代表基准 关注
2018 年前 Penn Treebank、WikiText、LAMBADA、SQuAD 语言建模与单一窄任务
2018–2019 GLUE、SuperGLUE、ARC、HellaSwag、WinoGrande 迁移学习与通用理解
2020–2022 MMLU、BIG-bench、GSM8K、MATH、HumanEval、TruthfulQA、HELM 基础模型能力
2023–2024 MT-Bench、Chatbot Arena、IFEval、LongBench、MMMU、GPQA、AgentBench、WebArena、GAIA、SWE-bench、OSWorld、τ-bench agent 与工具、长上下文、多模态
2024–2025 MMLU-Pro、LiveBench、LiveCodeBench、FrontierMath、Humanity’s Last Exam 难度、鲁棒性、题目新鲜
2025–2026 GDPval、BrowseComp、Terminal-Bench、ARC-AGI-3 范围更大,更接近真实使用
评估目标 代表基准 「成功」的含义
预测文本 PTB、WikiText 对真实出现的文本给出高概率
给出正确答案 MMLU、GSM8K、GPQA、HLE 与标准答案一致
给出受欢迎的回答 Arena、AlpacaEval、MT-Bench 得到人或评审模型的好评
写出能运行的代码 HumanEval、LiveCodeBench、SWE-bench 通过可执行的测试
完成交互任务 WebArena、OSWorld、τ-bench、Terminal-Bench 环境达到要求的状态

指标方面,早期常用困惑度、准确率、F1 分数或偏好胜率。其中,困惑度用来衡量模型对没见过的文本有多「意外」,数值越低越好。

评估 agent 能力时,常用 pass@k 和 pass^k 两个指标。pass@k 表示跑 k 次至少有一次通过;pass^k 由 τ-bench 提出,要求跑 k 次全部通过。

评估成本时,人们大多只看 LLM 费用。工具调用费以及缓存未命中多花的前,常常被忽略。

评估延迟时,同样不能只看模型的响应延迟,整个系统的交互耗时也要算在内。

一次基准评测的标准流程如下: 评测前,先将任务环境重置到初始状态。 随后在未结束、未超预算的前提下循环执行:首先观察环境;agent 根据指令、观察结果、历史记录和可用工具选择一个动作;环境执行该动作。 最后,评估器根据最终答案、环境最终状态以及整个执行过程综合打分。

八个代表性基准

基准 agent 所在环境 典型动作 打分依据 要点
GAIA 网页、文件、代码工具 搜索、看文件、计算 简短的最终答案 466 道人工编写的题目,分为 3 级(不超过 5 步、5 到 10 步、不限步数);评测整个 agent 系统;不考察发邮件、订票这类动作
BFCL 函数与 API 接口 结构化的函数调用 调用、参数和结果状态 用语法树比对或实际执行来检查;常见错误包括编造 ID(应该询问用户)以及多余调用;应关注分项得分而不是总分
WebArena 自己搭建的网站 点击、输入、跳转 网站或后台的状态 包含 812 个任务,涵盖购物、后台管理、Reddit、GitLab、地图、维基;agent 看到的是页面的无障碍树(一份结构化的页面元素清单);Verified 版去掉了 LLM 评审,改为对 HTTP 请求记录做确定性检查
OSWorld 完整的桌面虚拟机 鼠标、键盘、操作应用 文件、应用和系统状态 包含 369 个任务,agent 看到的是截图;OSWorld 2.0(2026)有 108 个长流程任务,耗时往往超过 1 小时,设置约 27 个检查点来给部分分
SWE-bench 软件仓库 查看、编辑、运行测试 补丁能否通过测试 变体包括 Verified(人工核验)、Lite(300 题)、Multilingual(9 种语言)、Multimodal、Pro(更难、跨多个文件)
τ-bench 客服 API 与对话 和用户对话、调用 API 数据库状态与回复 用户由 LLM 扮演,agent 需要遵守航空公司政策;总得分是动作分乘以回复分;只读调用可以和标准答案不同,但只要多出一次写入就算失败
Terminal-Bench 隔离的终端容器 任意 shell 命令 每个任务专属的验证测试 涵盖编程、运维、数据处理、训练模型、安全、科学计算流程;TB 2.0 有 89 题,TB 4.0 剔除已被刷满的题目后剩 66 题,每题超时时间为 8 小时
TheAgentCompany 模拟的软件公司 用网页应用、写代码、和同事沟通 过程检查点与最终状态 包含 175 个任务,涵盖软件、项目管理、数据科学、人事、财务;部分分计算公式为:0.5 × 得分比例 + 0.5 × 是否完全完成

Terminal-Bench 介于 SWE-bench 和 OSWorld 之间。agent 在容器里用 shell 执行命令并查看终端输出。任务从环境配置、调试、修复到构建全都有,不需要猜测鼠标点击位置,专门考验长链推理以及与系统的交互能力。

在指标要求上,pass^k 比 pass@k 严格得多:后者只要 k 次独立运行中成功一次就算通过,前者则要求 k 次独立运行全部成功。

评估为何困难

训练泄漏题目或它的人工修复出现在训练数据里
评估时泄漏agent 上网搜到并照抄了「未来」才发布的修复
环境泄漏沙箱里露出了之后的代码提交或隐藏的测试
对基准过拟合提示和脚手架是对着公开测试集反复调出来的

agent 的表现大致由 LLM、提示、脚手架、工具、检索器、记忆和环境共同决定。其中任何一个组件,都可能把答案泄漏进来: 微调时用了基准答案当示范过程;检索库里收录了答案;记忆里存着以前做过的尝试;或者研究者对照失败的题目反复调试系统。 所以,仅做到「模型没在测试集上训练过」是远远不够的。评估 agent 需要引入真实的工具,而真实工具又让泄漏的途径变得更多。

一次给全指令。 多数基准只给一条完整指令。输入提示后直接等待最终状态,中间没有人类参与。 真实工作却往往含糊不清、经常变更需求,并且随时可能被打断。 这种考法容易奖励盲目猜测。因为向用户提问澄清既要消耗步数,又不会加分。 评测应当补充测试三件事:目标不清时会不会主动询问;中途被纠正后会不会重新规划;能不能跨轮次记住约束条件。

其他挑战: 只看成功率并不够。跑了 200 步、花了 40 美元,和只用 12 步、花了 0.30 美元,都被算作「成功」,实际效果却不可同日而语。 测试结果存在随机性,只跑一次得到的分数往往只是噪声。 现有的基准缺乏惩罚机制,不会惩罚运行途中随意删文件、发邮件或乱花钱的行为。 评测还面临两难:只看最终结果,容易放过侥幸蒙对或过程不安全的操作;如果强行要求过程和标准答案一致,又会误判合理但不同的做法。

前沿模型追上基线的时间越来越短

从基准发布到前沿模型达到所标基线所用的月数

  1. GLUE(2018)· 人类水平 87.114 个月
  2. MMLU(2020)· 专家水平 89.839 个月
  3. GPQA Diamond(2023)· 博士专家 69.710 个月
  4. SWE-bench Verified(2024)· 33% → 95%22 个月
  5. ARC-AGI-2(2025)· 普通人 6011 个月
  6. ARC-AGI-3(2026)· 0.5% → 62.7%6 个月
原始讲义

基准被模型「刷满」的速度越来越快。 截至 2026 年 9 月,SQuAD、GLUE、SuperGLUE、MMLU、MATH、HumanEval、Chatbot Arena、MT-Bench、WebArena、SWE-bench Verified、GPQA Diamond、MMMU、OSWorld 等基准已趋于饱和。 FrontierMath、Humanity’s Last Exam、ARC-AGI-2/3、Terminal-Bench、GDPval、SWE-bench Pro、Remote Labor Index、OSWorld 2.0 仍未饱和。 这里的「饱和」,指最强的模型已经达到人类基线水平,或者顶尖模型之间已经拉不开差距。

维度 过去 现在的前沿
评估对象 基础模型 模型、提示、工具与 harness 的整体
交互 静态、一次 有状态、长链
打分者 精确匹配或概率 测试、环境状态、人或评审模型
数据集 固定、公开 新鲜、隐藏、动态生成或防污染
主要指标 平均准确率 成功率之外,还有可靠性、质量、成本、延迟
主要关注 换一批题还答得对 在真实约束和安全要求下稳稳做完
评价真实世界的 agent,要同时看能力、好用程度、成本和速度。 一个实用的方法是按「帕累托支配」排名:如果方案 A 在所有指标上都不比方案 B 差,而且至少有一项更好,就说 A 支配 B。没有被任何对手支配的那一组方案,就构成了帕累托前沿,排在最前面。

用到工作里

  1. 01在你自己的工作里攒一套「私有考题」:从真实任务里挑一批有标准答案或能自动检查的题目(比如数字是否和源表一致、字段是否齐全、测试是否通过)。这套题不公开、不拿来调提示,专门用于对比 agent、模型或提示的版本。
  2. 02每道题跑多次,同时记录 pass@k 和 pass^k。日常要靠得住的任务看 pass^k,偶尔成功一次没有参考意义。
  3. 03每次记下成本、步数、用时,以及有没有越界动作(例如删文件、对外发送信息、花钱),不只看最终对错。比较方案时采用帕累托方法,同时衡量质量、成本和速度。
  4. 04专门出几道表述含糊的题,看 agent 会不会先问清楚;再出几道中途改需求的题,看它会不会重新规划。
  5. 05不要只信厂商公布的基准分数:公开基准可能已经饱和或发生了数据泄漏。把模型放到你的真实任务上,用你自己的考题重新测一遍。

自测

同一任务独立运行 4 次,只有 1 次成功。pass@4 与 pass^4 分别如何?

自测

这些基准按什么打分?

GAIA
SWE-bench
τ-bench
OSWorld


08第 8 章

智能体设计 V:降本、提速与 harness 架构Agent design V: cost, speed and harness architecture

要点

  1. 成本等于用户数、会话数、轮数、步数、token 数与单价的乘积;中间三项靠缩短过程压低,单价靠缓存、批处理和路由压低。
  2. 读取缓存的 token 占了绝大部分;任何留在上下文里的 token,之后每一步都要再付一次钱。
  3. 每一项节省都有副作用,要在同一批任务上测净效果,并给每个任务设上限。
  4. 完成时间由关键路径决定;harness 的架构从单体、模块化走向微内核,职责一步步从代码移到服务。

先说清两个概念:轮是你和 agent 一问一答的一个来回;步是一轮之中 agent 的一次模型调用(通常伴随一次工具调用)。

一个任务的 LLM 花费可以拆成四个乘数:

01每任务轮数
02每轮步数
03每步 token 数
04每 token 价格

减少轮数与步数

本章只讨论 LLM 的花费,不含其他算力成本。

第 k 轮要把前 k−1 轮全部重读一遍,因此总花费随轮数的平方增长。一组编程 agent 的使用记录显示:只用一条提示就结束的会话,在两批任务里分别占 68% 和 75%,但也有少数会话超过 100 轮。

用户之所以回来追问,是因为 agent 没有计划、半途停下,或者从来没检查过自己的结果。解决对策是:动手前先确认目标和计划;把任务拆成各自带完成标准的子任务;交付前自己验证。最终目标是用户不用插手,任务就能做完。

多数轮次只有几步(主要因为推理强度设成了中或高),也有接近 1,000 步的。

每次模型调用都要重读全部上下文,所以调用越少越省。具体做法包括:把彼此独立的调用合到一步(比如一步读五个文件,而不是分五步各读一个);开始时一次读入需要的文件;复用以前成功过的计划和 skill。

相关研究有技能库(Voyager、SkillRL)、经验提炼(ExpeL、ReasoningBank)、计划模板缓存、持久对话记忆(Mem0、LightMem、SimpleMem)。

只有任务会重复出现时,复用才划算;维护记忆的开销和过时的条目,可能把省下的钱吃掉。

减少每步的 token

97.6%第一批任务中,读取缓存的 token 占全部 token 的比例
208K / 301K主 agent 每步上下文的中位数(第一批 / 第二批任务)
~80K子智能体每步上下文的中位数,第 90 百分位约 200K
1 : 10 : 50读缓存、普通输入、输出的典型价格比

缓存通过复用前缀来降低成本。上一步处理过的开头部分,服务方会保存中间计算结果。下一步如果发送相同的前缀,这部分只会收取费率极低的「读缓存」价格。

在各类 token 的数量分布上,输出数量通常比新写入缓存的 prefill 少约 5 倍,而新 prefill 又比读取缓存少约 100 倍。随着交互进行,上下文长度增长非常快,通常到第 500 步左右就会累积到 650K 至 670K。所有保留在上下文里的 token,在后续每一步调用中都会重复计费。

减少输入 做法
丢掉过时的 截掉过时的结果;压缩历史;遮住已经用过的工具输出;把旧轮次总结成一段状态
缩小进来的 压缩观察,只留报错而不是整份日志;大的输出存成文件,只传路径
只加载需要的 有选择地检索,只给相关的工具和记忆;把探索交给子智能体,只带回摘要

相关研究与实践展示了不同的优化效果: - ACON 能把上下文峰值降低 26% 至 54%。 - LLMLingua 最多可将 token 减少至原本的 1/20,但这种压缩只在提示很长时才具备性价比。 - MemGPT 将上下文视作一块快速内存来进行分层管理。 - 先用代码过滤 MCP 返回的结果,能将数据量从 150K 降至 2K。 - 引入工具搜索可以减少 85% 的工具定义 token;改用代码批量调用工具能进一步减少 37% 的开销。 - TRACE 发现,单纯做摘要处理容易导致模型返工。

减少输出有以下几种常见方式: - 明确限制提示:在提示词中直接注明长度、格式以及排除项,例如「不超过 100 字」「只返回 JSON」「不要复述问题」。 - 设置 API 参数:直接配置 API 的最大输出长度。需要注意,这可能会将回答强行截断在半句,而且模型内部的推理过程本身就可能耗尽这部分额度。 - 采用结构化输出:要求模型仅输出包含必要字段的内容,例如使用枚举来限制可选值。在工具调用前后附带的说明文字往往没有实质价值,纯属额外成本。 - 按步骤调整推理强度:在查找、格式化等简单步骤中使用低强度,在规划、调试等关键步骤中使用高强度。

需要注意的是,如果格式限制得过紧,可能会对模型的推理表现造成负面影响。


压低单价

缓存加批处理可把输入单价降到基础价的 5%

相对基础输入 token 价格的倍数,Claude API

  1. 输出 token5×
  2. 基础输入 token1×
  3. 批处理输入0.5×
  4. 缓存输入0.1×
  5. 批处理加缓存输入0.05×
Anthropic 公开价格,原始讲义

批处理是指把不着急的请求交给服务方排队处理,以此换来更低的价格。

具体做法包括两方面: - 保持前缀稳定:系统提示、工具定义和早期历史尽量不要改动,这样缓存才能命中。 - 能等的工作走批处理:例如评测、补数据和批量任务。

模型路由主要有三种方式: - 预先选定:用偏好数据训练一个路由器,提前决定使用的模型,还能借此决定 agent 的角色(如 RouteLLM、MasRouter)。 - 失败后升级:先使用便宜模型,检查不通过再换用大模型。检查手段可以是训练出来的打分器、模型自查,也可以是实际运行结果(如 FrugalGPT、AutoMix、EcoAssistant)。 - 每一步重新选:按历史和预算动态路由,由一个编排器把各个模型当作工具来调用(如 ToolOrchestra)。

模型路由的难点在于:便宜模型如果出现一个规划错误,可能导致后续浪费很多步。

系统层面还有一批降价手段: - MoE(第 9 章)、量化、剪枝、蒸馏,以及针对具体负载微调; - 推测解码、KV cache 优化、更好的调度; - 更快的 kernel 与专用加速器。



每项节省都有副作用

手段 副作用
压缩 被丢掉的文件之后要重读;摘要会改变前缀,让缓存失效
路由 便宜模型的坏计划会增加步数或导致失败
子智能体 每个子智能体都要重读共享的文件和指令
推测 猜错会浪费 token,还会和正常调用争抢同一批工具

净节省等于总节省减去副作用。这两项指标要在同一批任务上一起测。

给每个任务设定上限(示例:10 美元、80 次模型调用、15 分钟工具时间、每步最多重试 2 次)。上限可以设为成功任务第 95 百分位用量的 2 倍。

当任务验证通过、连续 N 步没有新测试通过、同一个错误反复出现,或碰到上限时停下,并附一份摘要交接。

带着摘要停下来的任务,比失控的任务便宜得多。

  1. 01步骤每次都一样:让 LLM 写一次脚本,之后直接运行脚本
  2. 02输入格式固定:用正则、解析器、模板,每次调用零成本
  3. 03标签或分数的范围很窄:训练一个小分类器
  4. 04流程固定、几乎不需要推理:把流程写成脚本,只在需要推理的那一步调用 LLM


让 agent 更快

完成时间由关键路径决定,也就是最长的那条先后依赖链,而不是所有步骤耗时的总和。更快的执行通常也更便宜,但并不总是如此:小模型可能需要多走几步,并行也会消耗更多 token。

加速 LLM 服务前面提到的所有降本手段都能降低延迟:更少的轮数、步数和 token,以及更快的模型服务
改进编排异步执行(工具在运行时就开始执行下一步);保持会话(跨步骤一直维持同一个 shell 或浏览器会话);流式与流水线(模型回复还没生成完就提前调用工具);把各项服务部署在同一处
加速工具构建、测试或页面加载往往比模型调用还慢:缓存工具结果、把重计算放到服务器、换用更快的工具、给容易卡住的调用设置超时;在优化模型之前,先测准每一步的工具耗时
并行在单步内发起多个互不依赖的工具调用;把独立的子任务交给并行的子智能体执行,再合并摘要;若涉及共享状态,则需要增加合并步骤
推测动作用便宜模型预测下一个动作,趁主模型思考时提前执行;猜对就能省去等待时间,猜错就丢弃结果,代价仅多一次调用;适合命中率高且动作可撤销的场合

推测的对象范围很广:从下一个工具(SPORK)、工具加参数(PASTE)、任意动作,一直到多条分支(B-PASTE)和整段已执行的链。

预测的依据主要有三类:来自模型(由小模型起草)、来自自我推测(利用同一个模型的早期分支),或者来自历史轨迹。例如 PASTE 发现“搜索之后通常是打开页面”,就会直接从搜索结果里取出 URL 提前打开。

目前尚未解决的问题是:在有限的 GPU、CPU 和 API 预算下,怎样合理安排推测调用,才能让省下的关键路径时间超过浪费的工作。

优化是一个持续循环的过程:运行并记录每次调用、token 消耗、工具耗时与等待时间;测出成本和延迟主要花在哪里;一次只做一处改动(如压缩、路由、缓存或并行);在同一批任务上重新评估成功率、花费和第 95 百分位延迟;然后再开始下一轮。



用到工作里

  1. 01先看账单结构:如果你的 agent 能显示每次会话的 token 和费用,先看它们各占多少。读缓存占大头,说明上下文太长,优先减少输入;新写入量大,说明前缀经常变动,先让系统提示和说明文件稳定下来。
  2. 02一次把需求说完整:把目标、约束、验收标准和要读的文件一次给齐,减少来回追问。对话每多一轮,前面的内容就要重读一遍。
  3. 03不重要的探索和读日志交给子智能体或小模型;规划、调试这类复杂步骤用大模型和高推理强度,格式化、查找用低推理强度。
  4. 04给每类任务设定上限(费用、调用次数、时间、重试次数),达到上限就停下来并输出摘要,不要让它无限跑下去。
  5. 05反复出现、步骤固定的工作,让 agent 写成脚本,以后直接运行脚本;只把真正需要判断的步骤留给模型。
  6. 06每次只改动一处(例如开启压缩,或换一个路由规则),在同一批任务上对比成功率、花费和耗时,再决定是否保留。


Harness 的三种架构

维度 单体 模块化 微内核
设计原则 全部集成在一个运行时里 通过接口抽象;由一个控制器统管 仅保留最小内核;其余均为外部服务
替换组件 困难 容易(如把 Docker 换成 Firecracker,只需替换实现) 只要协议匹配就容易替换
执行隔离 可选 可选 架构上的重点
部署 通常部署在一起 可以部署在一起,也可以分开部署 通常各自独立部署
单独扩容 能力有限 支持单独扩容 扩容能力强
通信开销 低 低到中等 可能更高
典型用途 单机 agent agent 框架 多 agent 基础设施
优点 实现与调试简单;状态易于共享 职责清楚;便于测试;第三方容易接入 各服务独立扩容;故障互不影响;基础设施可共享
缺点 组件紧密耦合;难以共享基础设施 控制器仍掌管全过程;协调逻辑变复杂 出错方式更多;端到端调试更难;需要标准协议

以运行一段 Python 为例:

单体架构直接在本机执行。这种方式环节最少,但难以实现隔离。

模块化架构调用统一的沙箱接口(如 SandboxProvider.run(code))。更换具体实现时,不用修改 agent。

微内核架构把请求发给一个执行服务,由它统一负责分配资源、隔离和沙箱的生命周期。

系统职责逐步从代码移到接口,再移到服务。


七个 harness 的独特设计

harness 定位 独特之处
Codex CLI OpenAI,Rust 先沙箱后审批:命令在断网沙箱中运行,只有跳出沙箱时才请求批准;补丁格式由 Lark 语法约束,分四轮匹配改动块
DeepSeek Harness TypeScript 运行循环本身即为插件,可通过 YAML 配置层替换;每个请求都是会话日志的一份冻结快照,harness 仅向日志追加内容;编辑采用「比较后交换」机制:若文件在模型上次读取后被修改,编辑直接失败
OpenCode TypeScript、Bun harness 本身即为独立服务器,终端界面、SDK 与网页端共用同一套 OpenAPI 接口;内置九种替换器,支持从精确匹配到锚点匹配,拒绝过于模糊的大范围匹配;每一步通过影子 git 仓库创建快照,执行撤销命令即可恢复文件
Pi TypeScript 内核保持极简,仅保留四个工具,未引入 MCP、子智能体与审批流程;仅在预计节省超过 0.05 美元时,才发送请求为缓存「保温」;pi-ai 支持 42 个模型提供方与 10 种协议
oh-my-pi TypeScript 加 Rust 引入 hashline 编辑:通过 4 位十六进制文件标签与行号精准定位,模型无需重复输出旧文本;常驻单个 shell,原生提供搜索、语法树、LSP 与调试器;通过 snapcompact 将历史记录转为图片进行压缩
OpenClaw TypeScript 面向 27 个聊天渠道的消息网关,为每个会话独立维护一条队列;压缩上下文前会自动记录带日期的笔记,召回时结合全文搜索与向量搜索;使用围栏隔离不可信文本,一旦读取网络内容即标记当前轮次受污染,并部署「哨兵」监控机密信息是否外泄
Hermes Agent Python 在后台分支复查刚被提示过的轮次,随后更新记忆与 skill;上下文窗口使用达到 50% 即触发压缩,在同类设计中触发最早;执行任何产生副作用的操作前,均优先将工具调用写入会话数据库

自测

每项节省手段的副作用是什么?

被丢掉的文件要重读,摘要让缓存失效
便宜模型的坏计划增加步数或导致失败
每个都要重读共享的文件和指令
猜错浪费 token,还争抢同一批工具

自测

在 Claude API 上,批处理加缓存后,输入 token 的价格约为基础输入价的多少?


09第 9 章

LLM 基础:一次请求的生命周期与 TransformerLLM basics: the life of a request and the transformer

要点

  1. 一次请求要经过六个阶段:分词、调度、prefill、decode、反分词和流式输出。
  2. Prefill 受算力限制,决定第一个字多久出来;decode 受显存带宽限制,决定之后每秒能出多少 token。
  3. 每个 token 的 KV cache 有多大,决定一张卡能同时服务多少请求;GQA 让 Llama 3 70B 的 KV 降到每 token 320 KB。
  4. MoE 模型的显存占用看总参数,计算量只看每次激活的那部分参数。
01分词
02调度
03Prefill:决定首 token 时间
04Decode 与采样:决定每秒 token 数
05反分词
06流式输出


六个阶段

  • 分词。 文本会被切分成 token,而不是按单词切分。英文平均每个 token 对应 3 至 4 个字符,「Serving is hard」对应 4 个 token。token 数量决定了成本和显存占用。不同模型的分词器不同,同一段话在不同模型里的 token 数量也不一样。常用的字节级 BPE 从 256 个字节值出发,反复把最常一起出现的相邻两块合成一个新 token。因此任何文字都能切开,不存在「不认识的字」。词表越大,同样的文字切出的 token 越少,但存放词表的嵌入表越大。
  • 调度与批处理。 请求是一个个独立到来的,但 GPU 需要成批处理才高效。连续批处理让请求可以在任意一步加入或离开,不必等凑满一批再开始。系统能同时接纳多少请求,受 KV cache 占用的显存限制。
  • Prefill。 把整段提示一次性送入模型,所有提示 token 并行计算注意力。这个阶段受算力限制:提示越长,处理越慢,成本也越贵。在此期间,模型会同步生成 KV cache,并输出第一个 token。
  • Decode 与采样。 之后每生成一个新 token,就要把模型完整运行一遍。KV cache 在每一步都会多存一个 token。这个阶段受显存带宽限制,因此要把很多请求凑在一起处理。显存不够时,部分请求会被暂停或排队。采样是从模型给每个候选 token 打的原始分数(logits)里挑选下一个 token,参数设置会改变答案和运行时长(见下表)。
  • 反分词与流式输出。 每生成一个 token ID,就转回文字直接发送出去;若出现半个字符则先暂存缓冲。遇到结束符、达到长度上限或连接断开时,输出即告结束。提前停止会释放占用的 cache。
采样参数 例 作用
temperature(温度) 0 为 0 时总选分数最高的那个;大于 1 时更多 token 有机会被选中,回答更发散
top-k 50 只在最可能的 k 个里抽;k 固定
top-p 0.9 取累计概率刚好达到 p 的最少几个 token 来抽;模型越有把握,候选越少


Transformer 的结构

01token ID
02嵌入:每个 ID 变成 8,192 个数组成的向量
03Transformer 块 × 80:自注意力加 FFN
04LM head:给词表里每个 token 打一个分
05softmax:把分数变成下一个 token 的概率

模型是一摞相同的 Transformer 块。

输入是一串整数 token ID。嵌入层把每个 ID 变成一个向量(Llama 3 70B 是 8,192 维)。

接着,向量会经过 L 个块(Llama 3 70B 有 80 个)。每个块都包含两部分:自注意力负责让 token 之间交换信息,前馈网络 FFN 对每个 token 单独做一次变换。

最后,LM head 为词表里每个 token 打分,softmax 把分数换算成加起来为 1 的概率。

每个块都遵循「先归一化、再计算、再加回去」的结构:先做 RMSNorm,进入注意力计算,把结果加回一条贯穿全模型的主干(残差流);接着再做 RMSNorm,进入 FFN 计算,结果同样加回主干。

RMSNorm 按均方根把数值缩放到稳定范围,每个维度都有一个可学习的放大系数。先归一化(pre-norm)让很深的堆叠也能稳定训练。残差流贯穿全部 80 个块,每一层只往上加一点「修改量」。

自注意力让每个 token 去读它前面所有的 token。每个 token 会生成三个向量:查询 Q(我在找什么)、键 K(我有什么)、值 V(我能提供的内容),分别由输入 X 乘以三个权重矩阵得到。

Q 和 K 的点积除以 √dₖ,用来决定从每个 token 读多少。之所以除以 √dₖ,是因为点积会随维度变大;如果不缩放,softmax 会过于偏向某一个 token。因果掩码把对角线以上填成 −∞,让 token 看不到后面的内容。softmax 让每一行的权重加起来为 1。输出则是各个 V 按权重混合的结果。

n 个 token 会产生 n² 个分数,每层的计算量(FLOPs,浮点运算次数)约为 4n²d。如果把分数矩阵 S 全存下来,在 8,192 个 token、64 个头、80 层的配置下,需要约 690 GB。FlashAttention 分块计算 softmax,根本不存 S。

步骤 公式 形状
输入 X n × d
查询 Q = X W_Q n × dₖ
分数 S = Q Kᵀ ÷ √dₖ n × n
权重 A = softmax(S + M) n × n
输出 O = A V n × dᵥ

多头注意力把 Q、K、V 拆成 64 个 128 维的「头」,各自做一遍带掩码的注意力,再用 Wₒ 混合起来。

由于 64 × 128 = 8,192,多头的计算量和一个宽头一样。拆开改变的是能学到的模式(有的头盯前一个 token,有的盯第一个 token,有的看附近,有的看全文),而不是成本。


KV cache 与共享 KV 头

KV cache 把每个已读 token 的 K 和 V 存下来,下一步不用重算。

它每 token 的大小 = 2(K 和 V)× 层数 × KV 头数 × 头维度 × 每个数的字节数。

MHA 每个查询头都有自己的一组 KV;GQA 让几个查询头共用一组 KV;MQA 让所有查询头共用一组。以 8 个查询头为例,三者的 KV cache 分别是 1 倍、四分之一、八分之一。

Llama 3 70B 的 64 个查询头共用 8 组 KV。按上述公式计算:2 × 80 × 8 × 128 × 2 B = 每 token 320 KB。如果用 MHA,则是 2.5 MB。

Llama 3 70B 参数 数值
模型宽度 d 8,192
层数 L 80
查询头数 H 与头维度 dₖ 64 与 128
KV 头数 Hₖᵥ 8
FFN 中间层宽度 28,672(d 的 3.5 倍)
词表大小 V 128,256

Llama 3 70B 的参数大部分在 FFN

参数量,十亿,按组件

  1. 注意力(80 层)12.1B
  2. FFN(80 层)56.4B
  3. 嵌入与 LM head2.1B
Meta, The Llama 3 Herd of Models (2024),按其公开结构推算

每层注意力约 151M 参数,FFN 约 705M。80 层合计 68.5B,加上嵌入与 LM head 共 70.6B。

图中注意力和 FFN 的合计,是每层数值乘以 80 得出的。


从系统角度估算

141 GB权重(BF16,每个参数 2 字节)
141 GFLOPs每生成一个 token 的计算量(约为 2 × 参数量)
320 KB每个 token 的 KV cache

以 2 块 H200 为例,硬件合计具备 1,978 TFLOP/s 算力、9.6 TB/s 带宽以及 282 GB 显存。

在此硬件条件下处理一段 8 万 token 的提示: - 仅处理 1 个请求时,prefill 耗时约 9.95 秒,需要占用 167 GB 显存。 - 若 64 个请求并发,耗时则达 637 秒,显存需求增至 1,779 GB。

当上下文长度增加时,注意力计算量会按 n² 增长,KV cache 则按 n 线性增长。这正是长上下文难以处理的根本原因。



MoE:显存看总参数,计算看激活参数

MoE(混合专家)把每个块里的 FFN 换成一个路由器和一组较小的「专家」FFN。每个 token 只交给其中几个(比如 8 选 2)处理,再按权重加起来。

模型 专家 总参数 每 token 激活 权重(BF16)
Llama 2 70B 全部(稠密) 69B 69B 138 GB
Mixtral 8x7B 8 选 2 46.7B 12.9B 93 GB
Llama 3.1 405B 全部(稠密) 405B 405B 810 GB
DeepSeek-V3 257 选 9 671B 37B 1,342 GB

DeepSeek-V3 每个 token 只激活 37B 参数

每 token 激活参数,十亿;每 token 的计算量(GFLOPs)约为它的 2 倍

  1. Llama 2 70B69B
  2. Mixtral 8x7B12.9B
  3. Llama 3.1 405B405B
  4. DeepSeek-V337B
Jiang et al. 2024;DeepSeek-AI 2024;Touvron et al. 2023;Llama Team 2024

在模型质量相当时,计算量更少:Mixtral 用约五分之一的计算量达到 Llama 2 70B 的水平;DeepSeek-V3 用约十一分之一的计算量与 Llama 3.1 405B 相当,但显存需要 1.7 倍。



用到工作里

  1. 01agent「第一个字出来得慢」,多半是提示太长(prefill 慢);「字出得慢」,多半是输出太长或服务繁忙(decode 慢)。前者可以删减上下文,后者可以限制输出长度并要求简洁。
  2. 02同一段中文在不同模型里的 token 数不同。比较价格时,请按你自己的样例文本实际算一遍 token 数,不要只看单价。
  3. 03面对抽字段、分类、格式转换等要求结果稳定、可复现的任务,把 temperature 设为 0 或接近 0;起草、头脑风暴等需要发散的任务再调高。即便设为 0,结果也不保证完全一样(第 1 章)。
  4. 04打算自己部署开源模型时,先用本章公式估算显存:权重约为参数量乘以 2 字节(BF16),再加上「每 token 的 KV cache × 上下文长度 × 同时服务的请求数」。
  5. 05选择 MoE 模型时要记住:它算得快、单价低,但显存必须按总参数量准备,部署门槛并不低。


延伸:八种进阶结构
结构 做法 对推理服务的影响
滑动窗口 局部层只看最近 w 个 token,少数全局层负责长距离回忆;Gemma 3 为 5 个局部层配 1 个全局层,w = 1,024;Mistral 7B 全部是局部层,w = 4,096 在 128K 上下文下,Gemma 3 的 KV 占用约为全部用全局层时的六分之一
多头潜在注意力(MLA) 每个 token 只缓存一个压缩向量,需要时再还原出 K 和 V DeepSeek-V2 比 DeepSeek 67B 的 KV cache 少 93%,生成吞吐提高 5.8 倍
线性注意力 维护一个固定大小的状态,边读边更新;Gated DeltaNet 先让旧状态衰减再写入;Qwen3-Next 为 36 层 GDN 加 12 层注意力,Kimi Linear、Qwen3.5 也是 3 比 1 四分之三的层中,每个请求只存一份大小不变的状态
状态空间模型 每个通道维护一个小状态,由 token 决定衰减多少;对应 Mamba 的选择性机制,Mamba-2 则将其改写为矩阵乘法 不再有持续增大的 KV cache;Mamba 报告生成吞吐最高可达 Transformer 的 5 倍
稀疏注意力 由轻量索引器给过去的 token 打分,每次查询只读前 2,048 个(DeepSeek-V3.2) 每个 token 的计算量有上限,但所有 token 的 KV 仍需保存
循环 Transformer 同一个块重复使用 K 次 加深网络只增加计算量和延迟,不增加权重
多 token 预测 一次预测多个 token 原始资料仅列出名称
扩散语言模型 先遮住待生成的位置,再经过几步并行修改逐步填出(LLaDA 8B、Dream 7B) 一次计算可填充多个 token,但修改步数越少,生成质量越差

自测

哪个阶段受显存带宽限制,并决定每秒能出多少 token?

自测

Llama 3 70B 有 80 层、8 组 KV 头、头维度 128,用 BF16。每 token 的 KV cache 约为多少?


10第 10 章

GPU 基础:为什么 decode 受带宽限制GPU basics: why decode is bandwidth-bound

要点

  1. GPU 用几千个简单的计算核心换取吞吐量。它在线程组(warp)之间来回切换,以此掩盖读取显存的等待。
  2. 每个计算程序(kernel)都受三项因素限制:峰值算力、显存带宽和显存容量。roofline 图上的「脊点」用于区分这两类瓶颈。
  3. 当 decode 一次只处理一个请求时,仅能用到 H200 峰值算力的 0.5%。批处理有所帮助,但 decode 的注意力计算始终受带宽限制。
  4. 新一代 GPU 的算力增长快于带宽增长。要提高实际带宽,就必须让更多字节同时在路上。

GPU 与 CPU

64 核服务器 CPU NVIDIA H200 SXM
并行单元 64 核 132 个 SM(流式多处理器);16,896 个 FP32 核
同时在跑的线程 270,336(每个 SM 2,048)
内存带宽 约 0.46 TB/s(DDR5) 4.8 TB/s(HBM3e)
峰值稠密算力 约 5 TFLOPs FP32 989 TFLOPs BF16
怎样掩盖延迟 缓存、乱序执行 切换到已经准备好的 warp

CPU 就像跑车,送两个人速度最快。GPU 则像车队,虽然单程偏慢,但一次能运送几千人。

LLM 非常适合 GPU,因为每个 token 都在同一套权重上执行相同的矩阵乘法。

  • 切换 warp 来掩盖读内存的等待。 warp 是 GPU 上协同执行的 32 个线程。当一个 warp 在等待显存读取时,另一个就绪的 warp 会接着发射指令,让计算单元始终有活可干。A100、H200 和 B200 的每个 SM 都配有 4 个 warp 调度器,每个调度器最多管理 16 个 warp,合计拥有 64 个常驻 warp。
  • SIMT(单指令多线程)。 一条 warp 指令可以同时驱动 32 个线程。取指令、解码和调度的开销只需支付一次,就能完成 32 条普通指令的工作。
  • 分支发散。 当同一个 warp 里的线程走向不同的 if 分支时,不同分支路径必须轮流执行。例如,分支 f 只用到 32 条通道中的 8 条,分支 g 用到其余 24 条,两次执行各自都有一部分通道处于闲置状态。
GPU 放弃了 换来了
单线程速度(时钟不高、不做推测;串行代码慢得多) 芯片面积和功耗集中在几千个运算单元上
并行必须由程序员写明(约 27 万个线程才能填满 132 个 SM;小任务会让芯片闲着) 靠切换 warp 而不是缓存和推测来掩盖延迟
控制流共享(32 个线程一组;分支发散就会损失吞吐) 取一次指令、解一次码即可驱动 32 个核
每个线程的片上存储很小(满载时约 240 字节) 所有线程的状态均常驻;切换 warp 没有额外开销

三项指标与 roofline

显存带宽逐代提高,但增速低于算力

HBM 带宽,TB/s;Rubin 为初步数据

  1. 2 TB/sA100
  2. 4.8 TB/sH200
  3. 8 TB/sB200
  4. 22 TB/sRubin
NVIDIA 数据表,原始讲义
A100 H200 B200 Rubin
峰值 BF16 算力(决定数学运算多快) 312 TFLOP/s 989 TFLOP/s 2,250 TFLOP/s 约 4,000 TFLOP/s
显存带宽(决定读权重和 KV cache 多快) 2.0 TB/s 4.8 TB/s 8 TB/s 约 22 TB/s
显存容量(决定放得下多少权重和 KV) 80 GB HBM2e 141 GB HBM3e 180 GB HBM3e 288 GB HBM4

算力相当于发动机,带宽相当于油管,容量相当于油箱。

一个 kernel 的用时,约等于「要读取的字节数 ÷ 带宽」与「要完成的运算量 ÷ 峰值算力」两者中的较大值。

Decode,一次一个请求:算力在等数据

  • 每个 token 耗时 3.3 毫秒
  • 需要从显存读取 16 GB 权重
  • 每个权重只用一次;0.016 毫秒的计算要等待 3.3 毫秒的读取
  • tensor core 有 99.5% 的时间处于闲置

Prefill,2,048 个 token:算力很忙

  • 每段提示耗时 33 毫秒
  • 权重读取完成后,显存读取便处于空闲
  • 每个权重服务 2,048 个 token,速度由计算决定
  • 完成 33 TFLOP 运算,接近峰值

Roofline 模型用「算术强度」来判断性能瓶颈。算术强度是指每从显存搬运一个字节,能够完成多少次计算(即 FLOPs ÷ 字节数)。

脊点的计算公式为:脊点 = 峰值算力 ÷ 带宽。对于 H200,该值约为 206 FLOP/B。 - 当算术强度低于脊点时,性能受带宽限制,处理速度 = 带宽 × 算术强度。 - 当算术强度高于脊点时,性能受算力限制,处理速度 = 峰值算力。

运算 算术强度(b 为每个元素的字节数)
向量加法(长度 N) 1/(3b)
矩阵乘向量(GEMV,decode 的主要运算;N × N;每个权重用一次) 约 2/b
decode 的注意力(每个 KV 条目在每个头用一次) 2/b
方阵乘方阵(GEMM;每个元素大约复用 N 次) 2N/(3b)

一次只处理一个请求的 decode 属于 GEMV 操作,其算术强度约为 1 FLOP/B。在 H200 上,它只能发挥 989 TFLOP/s 中的约 5 TFLOP/s,仅达到峰值算力的 0.5%。

要提高硬件利用率,就必须提高算术强度。常见方法包括加大批次大小、量化(用更少的位数存储权重),以及减少 KV cache 的读取量。

批处理能够把权重计算部分的 GEMV 推近脊点(例如 batch 为 256 时强度提升至 256 FLOP/B)。但 decode 阶段的注意力计算强度始终停留在 2/b,因为每个请求读取的都是自己独立的那份 KV。

上下文变长后,每步 decode 读取的字节主要来自 KV cache

每个 decode 步从显存读取的总字节,GB;Llama 3 8B,batch 16,BF16;权重固定 16.1 GB

  1. 18.2 GB1K
  2. 24.7 GB4K
  3. 33.3 GB8K
  4. 50.5 GB16K
  5. 84.8 GB32K
按 Llama 3 论文与 H200 数据表推算,原始讲义

在此例中,每个 token 的 KV 为 128 KiB,其数据总量会随着 batch 与长度增加。按照 4.8 TB/s 的显存带宽计算,单步 decode 用时会从 1K 上下文时的 3.8 毫秒增加至 32K 时的 17.7 毫秒。

计算精度越低,脊点越往右移。以 Rubin 为例,其稠密 NVFP4 需要达到约 1,600 FLOP/B 的算术强度才能脱离带宽限制、转为受算力限制。

从 A100 到 Rubin,BF16 算力增长了约 13 倍,而带宽仅增长约 9 倍。因此,各类 kernel 越来越容易受到带宽限制。

H200 的内部结构

H200 配有 132 个 SM,共用 50 MB 的 L2 缓存与 141 GB 的 HBM3e 显存(由 6 个堆栈组成,带宽 4.8 TB/s)。它可以通过 NVLink 以 900 GB/s 的带宽与其他 GPU 相连。

每个 SM 分为 4 个处理分区。每个分区各有 64 KB 寄存器、32 个 FP32 核和 1 个 tensor core,每个周期发射一条 warp 指令。同一个 SM 内的所有分区共用 256 KB 的 L1 缓存与共享内存,最多可常驻 2,048 个线程。

Tensor core 是专做小矩阵乘加的单元。它用一条指令即可完成 D = A × B + C(例如 16×16 乘 16×8 的矩阵乘加)。单次 mma 等于 2,048 次乘加,相当于一条普通乘加指令(FMA)工作量的 64 倍。

在 LLM 中,矩阵乘法占了 99% 以上的计算量,而 softmax 和归一化等操作则由普通 FP32 核执行。

Tensor core 之所以速度极快,主要有四个原因: - 单次运算所需的指令更少; - 拥有专用的乘加电路; - 操作数高度复用(矩阵 A 的一个值供多列使用,矩阵 B 的一个值供多行使用); - 支持低精度格式(如 FP16、BF16、FP8),在提升吞吐量并缩减数据体积的同时,通常会采用更高精度来累加结果。

存储层级(H200) 容量 延迟(Hopper) 带宽
寄存器 每个 SM 256 KB 在流水线里 每条指令直接读取
共享内存 / L1 每个 SM 256 KB 约 30 个周期(L1 命中约 40 个周期) 每个 SM 每周期 128 B;132 个 SM 合计约 33 TB/s
L2 缓存 50 MB 约 250 个周期 Hopper 上约 12 TB/s
HBM3e 显存 141 GB(6 个堆栈) 约 500 个周期 4.8 TB/s
主机内存与其他 GPU 微秒级 NVLink 4 每个方向 450 GB/s;PCIe 5.0 约 64 GB/s

显存是一条 250 纳秒长的管道

根据利特尔定律:带宽 = 同时在路上的字节数 ÷ 延迟。

如果 kernel 写得较为简单,每个 SM 平均只有约 4 KB 数据在路上,显存带宽就只能跑到 2.2 TB/s,仅达到峰值的 45%。要跑满 4.8 TB/s,每个 SM 就需要保持约 9 KB 数据在途传输(计算公式为:4.8 TB/s × 250 ns ÷ 132)。

硬件决定了管道的延迟长度。因此,提高实际带宽的唯一途径就是往管道里塞进更多在途字节: - 采用每次 16 字节的向量读取; - 让每个线程并发发出 4 个互不依赖的读取请求; - 使用批量异步复制(TMA)。

H200(Hopper) B200(Blackwell) Rubin
显存 141 GB HBM3e 180 GB HBM3e 288 GB HBM4
带宽 4.8 TB/s 8 TB/s 22 TB/s
整卡需要在路上的字节 1.2 MB 2.0 MB 5.5 MB
每个 SM 需要在路上的字节 9 KB 14 KB 25 KB
新的数据通路特性 TMA;cluster TMEM;2-SM MMA 内联 TMA 描述符

延伸机制: - 合并访问:让 32 个线程各读连续 4 字节的请求,合并为单次 128 字节的请求。 - 16 字节向量读取:让一条 warp 指令直接搬运 512 字节。 - cp.async(从 Ampere 开始支持):数据无需经过寄存器,直接复制到共享内存。 - Hopper 的 TMA:仅由单个线程发起整块数据复制,一条指令即可让几十 KB 数据同时在路上;TMA 多播机制支持将一次 L2 读取的数据同时分发给一个 cluster(最多 8 个线程块)内的各个 SM。 - Blackwell 新特性:将计算结果放入 256 KB 的 tensor memory,腾出寄存器以发起更多在途读取;同时支持两个 SM 协同完成一个矩阵乘法,各自读取并共享一半数据块。

从单卡到多卡

HGX H200(8 卡节点) GB200 NVL72(整机柜)
组成 8 块 GPU 经 NVSwitch 互联;8 张 400 Gb/s 网卡接外部网络 每层 4 块 GPU 加 2 颗 CPU;共 9 层经 NVLink 交换机互联
显存带宽 4.8 TB/s 8 TB/s
NVLink 900 GB/s 1.8 TB/s
RDMA(跨机直接读写内存) 50 GB/s 100 GB/s

从 G80(2006 年)到 B300(2025 年),GPU 峰值算力增长了约 43,000 倍,而显存带宽仅增长约 90 倍。

这二十年的发展主线十分清晰:GPU 首先从图形处理转向通用计算(引入 CUDA、缓存、HBM2、NVLink 和 tensor core),随后进一步转向专为低精度优化的 AI 引擎(引入 TF32、BF16、FP8、TMA、FP4、TMEM 与 NVL72)。

用到工作里

  1. 01评估 GPU 或推理服务参数时,别只看算力(TFLOPs)。运行 LLM 生成任务,特别是一次服务少量请求时,速度主要由显存带宽决定;能容纳多大的模型与多长的上下文,则由显存容量决定。
  2. 02上下文越长,每生成一个 token 需要读取的 KV 越多,生成速度就越慢。给 agent 塞入超长上下文,代价不仅是费用增加,还有每一步生成速度的变慢。
  3. 03自己部署模型时,调节速度与成本的核心杠杆包括:将请求凑成批次(使用支持连续批处理的推理框架)、对权重进行量化,以及缩短上下文。若让单个请求独占一张卡,绝大部分算力都会处于闲置状态。
  4. 04估算单请求生成的最快速度:生成每个 token 至少要把全部权重读取一遍,因此「权重字节数 ÷ 显存带宽」即为单请求下每 token 耗时的下限。例如,16 GB 权重在 4.8 TB/s 带宽下的读取用时约为 3.3 毫秒。
  5. 05新一代 GPU 的算力增长始终快于显存带宽,因此「使用更低精度、减少数据搬运」的优化会越来越关键。在选型模型与推理服务时,应重点留意其是否支持低精度与 KV 压缩。
延伸:其他加速器
芯片 特点 编程方式
AMD MI355X 由 8 个计算芯粒组成,软件上视为一块 GPU;配备 256 MB Infinity Cache;64 个线程为一组(wavefront);稠密 FP8 算力 5.0 PF,显存 288 GB,带宽 8 TB/s ROCm 与 HIP;可运行 PyTorch、vLLM、SGLang;可使用 Triton 或 Composable Kernel
Google TPU Ironwood 采用权重常驻的脉动阵列;通过 3D 环形网络互联 9,216 颗芯片;稠密 FP8 算力 4.6 PF,内存 192 GB,带宽 7.4 TB/s JAX 或 PyTorch/XLA;使用 Pallas 编写自定义 kernel
Amazon Trainium3 每颗含 8 个 NeuronCore,各配备张量、向量与标量引擎;每核拥有 32 MB 由软件管理的 SRAM,无硬件缓存;算力 2.5 PF MXFP8,内存 144 GB,带宽 4.9 TB/s Neuron SDK;在 Python 中使用 NKI 显式搬运数据块;没有 CUDA
Cerebras WSE-3 一整片晶圆就是一颗芯片;拥有 44 GB 片上 SRAM,无片外内存 更大的模型需要边计算边流式加载权重
Groq LPU 配备 230 MB SRAM,无片外内存 运行 8 位精度的 70B 模型约需 300 颗芯片
Microsoft Maia 200 配备 272 MB SRAM 与 216 GB HBM3e 仅在 Azure 内部提供

自测

H200 做一次只处理一个请求的 decode 时,用到峰值算力的多少?

自测

这些运算在 H200 上受什么限制?

方阵乘方阵,N = 8192
一次一个请求的 GEMV
decode 的注意力
2,048 个 token 的 prefill


∞SOURCES

延伸阅读与资料说明

  • 本手册整理自公开讲义,以及讲义中引用的论文、技术报告和厂商文档。如果想深入了解某个主题,可以阅读以下一手资料:ReAct(arXiv 2210.03629)、Liu et al.「Lost in the Middle」(TACL 2024)、Chroma 的 Context Rot 测试、Breunig「How Contexts Fail」(2025)、Lewis「Same Model, Different Harness」(arXiv 2608.26218)、Anthropic「Building a C compiler」、OpenAI 的 Codex 报告与内部使用报告(2026 年 6 月与 9 月)、Meta 的 Llama 3 论文、NVIDIA 白皮书与数据表,以及各个基准的原始论文。
  • 手册图表均按原始资料中的数值重绘,来源标在每张图下方。标为「原始讲义」的,是讲义中给出且未注明更早出处的数值。Llama 3 70B 注意力与 FFN 的合计参数由每层数值乘以 80 计算得出,其余数值均依照原始资料。
  • 各章的「用到工作里」是整理时根据该章内容给出的做法建议,没有引入原始资料之外的数据。
  • 具体产品名只在介绍案例、数据来源或工具清单时出现。介绍 agent 的通用机制时统一采用通用说法,具体命令和文件名以你所用 agent 的文档为准。

TEN CHAPTERS · 2026.11

Agents and AI system optimizationAGENTA study handbook

This handbook treats an agent as a systems problem. The model sets the ceiling, the harness sets real performance, and the serving system and GPU set cost and speed. Chapters 1 to 8 cover using and designing agents: the loop, tools, context, memory, multi-agent systems, reliability, evaluation and cost. Chapters 9 and 10 cover how LLM inference and GPUs work. Each chapter opens with key points, then the material, then concrete steps for putting it to work, and ends with a self-check.

SCROLL

01CHAPTER 1

The big picture: AI systems and agentic systems全景:AI 系统与智能体系统

Key points

  1. AI systems is the study of how to train and run models at scale so they are fast, cheap, reliable and sustainable; in this handbook it means large language model (LLM) systems.
  2. An agent uses a model to reason, call tools and act step by step until a task is done. Think of it as a new kind of computer: the LLM is the CPU, context is RAM, tools are peripherals, the harness is the operating system.
  3. A running agent is a long chain of inference and tool calls, and each property of that workload names a systems problem to solve.
  4. The thing to optimize is not tokens per second but getting the task done within limits on latency, cost, resources, reliability and security.

Two words come up in every chapter. A token is the smallest unit of text a model reads or writes, roughly a word or part of one; price and speed are both counted in tokens. The harness is the program wrapped around the model: it packages your request and files for the model, runs the tool calls the model asks for, checks permissions and feeds the results back. The same model can perform very differently in different harnesses.

Five ways AI systems differ from traditional systems

Dimension What differs
Compute The CPU and GPU split the work. The CPU tokenizes text, launches the small programs that run on the GPU (kernels), moves data and runs tool calls; the GPU does large matrix multiplications. Reading the whole prompt is called prefill and is limited by compute; producing tokens one at a time afterwards is called decode and is limited by how fast memory can be read (bandwidth). How long a request takes depends on how long the output is, which is unknown in advance, so scheduling is hard
Non-determinism The same input can give different outputs. Adding floating-point numbers in a different order gives slightly different results, and a shift in the seventh decimal can flip the next token. The variation comes from the runtime (the order in which GPU thread groups, called warps, are scheduled; how many requests share a batch), software (whether multiply and add are fused into one FMA step; which algorithm autotuning picked) and hardware (ordinary cores or tensor cores; low-precision formats such as FP8). This approximation is acceptable
Memory, storage, communication Model weights run from GBs to TBs. The KV cache is what the model keeps for every token it has already read so it need not recompute it, and it takes tens to hundreds of KB per token; a prefix cache lets requests that start the same way share it. Moving data, not computing, is often the bottleneck. When one machine is not enough, the model is split across GPUs (by layer, by matrix, by expert, by context) over fast interconnects such as NCCL, NVLink, InfiniBand and RDMA
Fast-moving models and workloads Attention, the mechanism a model uses to find what matters in its context, moved from MHA to GQA, MLA, NSA and linear attention, mostly to save memory and compute. Workloads moved from multi-turn chat, long reasoning and retrieval-augmented generation (RAG) to agents, which need long context, prefix caching, and routing and load balancing across models and machines
Reliability and power GPUs fail at 9% a year, so a 16K-GPU cluster loses one about every 3 hours. A GPU draws 700 to 1000 W, and server power rose from 800 W to 6,000 W

Server power rose about eightfold with GPUs

Power per server, W

  1. CPU server800 W
  2. GPU server6,000 W
Original lecture notes

Chapters 9 and 10 go into these details. For now, remember one thing: longer outputs are slower and costlier, and two runs are not guaranteed to agree.

What an agent is

An AI agent is an autonomous software system that uses an AI model to reason about a goal, use external tools (search, reading and writing files, running code, calling APIs) and carry out multi-step actions until the task is finished. Its work breaks into five steps:

01Plan: break the task into sub-steps
02Act: call external tools
03Observe: read what the tools returned
04Adapt: revise the plan on new information
05Deliver: return the final result

Agents exist because LLMs are uneven. They beat most people at recalling facts, language, pattern matching, writing code and connecting fields, but they forget past conversations, cannot reliably understand long context, state false things with confidence (hallucination), don’t know what they don’t know and are easily steered by hostile input. Tools give the model hands; memory gives it recall.

An agent can be read as a new kind of computer: the LLM is the CPU, the context window (all the text the model can see at once) is RAM, tools are peripherals, the harness is the operating system and the agent is the application. How you program it and how it fails are both entirely different from a traditional computer.

Why agents are a systems problem

Ordinary LLM serving is one request, one inference, one response. An agent is a chain: infer, call a tool, infer, call a tool, retrieve, infer. One task passes through GPU, CPU, storage, network and outside services, which brings six problems: each step depends on the last, step times vary widely, the agent must wait on tools, state keeps growing, it needs concurrency and guessing ahead, and anything along the chain can fail.

Property of the agent workload Systems problem it names
Long trajectories (tens or hundreds of steps per task) State and context management
Huge context Memory hierarchy and retrieval
Repeated prefixes (every step carries the same system prompt and history) Prefix caching
Branching reasoning Speculative execution
Tool dependencies Dependency-aware scheduling
Different models Routing
Variable tool latency Asynchronous execution
External side effects (sending email, changing a database) Security and isolation
Multiple agents Orchestration and communication
Long-running tasks Checkpointing and fault tolerance

The stack, top to bottom: application and user; agent and harness (planning, context, memory, tools, subagents), beside the external environment and tools (web, files, APIs, humans); the model; the serving system (batching requests together, scheduling, routing, caching); runtime and kernels (CUDA, Triton, multi-GPU communication); hardware (GPU, CPU, memory, network, storage).

What to optimize

Throughput, tokens generated per second, is the wrong objective for an agent. The objective is to get tasks done within limits on latency, cost, resources, reliability and security.

What to optimize

  • Task success and accuracy
  • Time from request to result
  • Tokens per task
  • Dollars per successful task
  • Energy per successful task

Useful, but insufficient

  • TTFT (time to first token) and TPOT (time per output token)
  • Tool-call latency
  • GPU utilization

More tokens per second can still mean a slower, costlier agent, for example one that takes ten extra steps. That makes observability a first-class problem: a task must unfold into nested records of sessions, turns, agent steps, model requests, tool calls and subagents. You cannot optimize what you cannot see.

Questions that run through this handbook

Batching and latencyWhy does batching requests raise throughput but slow an agent down? When is a larger model worth it?
Where state livesWhere should the KV cache and shared prefixes live? How should requests from one agent be queued?
Overlap and delegationCan the model do useful work while a tool runs? When should an agent hand work to a subagent?
Routing and recoveryHow do we spread requests across different GPUs and models? How does a 30-minute task resume after a failure?
The objectiveHow do we optimize dollars per successful task rather than tokens per second?

This handbook leaves out model training (inference now dominates compute demand), model architecture design, multi-machine communication, power, and new hardware design.

Putting it to work

  1. 01Define what “done” means before you start: all tests pass, every report field is filled, figures match the source table. Without that test you cannot measure success rate or cost per successful task.
  2. 02Account per task, not per call: for each task record total tokens, spend, time and whether it succeeded. When you compare two agents or two prompts, compare these numbers, not which one replied faster.
  3. 03When a task is slow or expensive, open the agent’s run log or trace, unfold it into individual tool calls, and find the slowest, costliest or most repeated step before changing anything.
  4. 04Use the six levels below to decide how much to hand over. Start at level 3, handing off a well-scoped task and reviewing the result; move to level 4 once checking is automated with tests or validation scripts.
  5. 05Not everything needs an agent. Work with fixed rules that finishes in one step is cheaper and steadier as a script or a simple bot; chapter 8 covers how to tell.
Also: six levels of AI coding, and agents vs assistants vs bots
Level Meaning
0 No AI, hand-written code
1 Assist: AI autocompletion
2 Supervised: AI writes functions, you review
3 Scoped: hand off a task, review the code
4 Goal-driven: AI writes all, tests verify
5 Parallel agents: subagents split the work
Agent Assistant Bot
Purpose Performs tasks autonomously and proactively Assists users with tasks Automates simple tasks or conversations
Capabilities Complex multi-step actions; learns and decides independently Responds to prompts and can recommend; the user decides Follows predefined rules; limited learning
Interaction Proactive, goal-oriented Reactive, responds to requests Reactive, responds to triggers

Self-check

When you evaluate an agent, which number matters most?

Self-check

Which systems problem does each workload property name?

Every step starts with the same text
Tools take unpredictable time
It changes outside data
A task runs for half an hour

02CHAPTER 2

How an agent works: the loop, memory and extensionsAgent 如何工作:循环、记忆与扩展

Key points

  1. One request expands into many model calls and tool runs: the model proposes an action, the harness checks permission and runs it, the result goes back into context, and the loop goes round again.
  2. Context is rented working memory that vanishes when the session ends; the project instruction file and auto memory are files loaded every session, and stale memory is worse than none.
  3. Each extension does one job: a skill says how, MCP says what the agent can reach, a hook says what happens automatically at a given moment, a plugin packages it all for sharing.

A coding agent is, at heart, a loop:

01Gather context: your prompt, relevant files, the last tool result
02The model proposes an action, e.g. “run pytest”
03The harness checks permission and runs it
04The result goes back into context; repeat

Facts about the loop

  • Context holds over 10K tokens before you type. First come system instructions, the project environment, memory (the project instruction file), descriptions of the available tools (read files, edit, run commands, find files by name, search contents, browse the web, start a subagent), and the names and one-line descriptions of skills and MCP servers; your words come last. Skills and MCP start as names only; their full text loads when the agent reaches for them.
  • It does not send your whole codebase. The code stays on disk and the model pulls slices on demand: a search for “authentication” brings back only the matching lines.
  • The model proposes, the harness executes. The model emits a tool request; the harness parses it, checks permissions, runs it on your machine and puts the result (the tool result) back into the model’s context. Every request builds on the previous inference and the previous tool result.
  • Permissions sit between intent and execution. A tool request is only a proposal; you or another model must approve it (table below).
  • Context grows, then gets compacted. A typical window today is 1M tokens; 256K was common earlier in the year. Reading the cached prefix accounts for most of the cost. When the window fills, the agent compacts: it summarizes the old history and puts the project instruction file and memory back in.
Permission mode Meaning
Manual You confirm every step
Accept edits File edits pass automatically; other actions still ask
Bypass permissions Everything runs directly
Auto A small model reviews each request

Each request ends one of three ways: allowed (the command runs), ask (you confirm first) or denied (nothing happens).

Memory: context is rented, memory is owned

An agent remembers nothing between runs; every session starts from zero. What we call memory is just files loaded at session start. Context is working memory and disappears with the session; persistent memory lives outside it and is reloaded next time. Memory solves four problems: giving the same instruction again and again, redoing the same exploration, losing decisions and their reasons at compaction, and different sessions choosing differently. Memory turns repeated reminders into convention.

Project instruction file Auto memory
Who writes it You The agent
Contains Instructions and rules Lessons and patterns
Scope Project, personal or organization One per codebase, shared across its working copies
Loaded Every session Every session (only the start, e.g. the first 200 lines or 25KB)
Use for Standards, workflows, architecture Preferences, corrections, project background

The project instruction file is a Markdown file the agent reads at every start; the exact name and location depend on your agent’s documentation. It usually comes in four layers, loaded broadest first, with the most specific read last and winning: organization policy (cannot be switched off by individuals), your personal global settings, the project file (shared with the team through the codebase) and a local personal file (yours only, kept out of version control).

Belongs in the instruction file

  • Commands: how to run tests, the build and the linter
  • Hard constraints: never commit to main, never edit generated files
  • Facts the agent cannot cheaply find out: how folders are split, who owns what, known pitfalls

Does not belong

  • What the model already knows about the language or framework
  • Style a linter or formatter already enforces
  • Long prose, changelogs, anything secret

Keep each file under 200 lines, use Markdown headings and bullets, and make the rules concrete and consistent. When it grows, split it into one rule file per topic; if your agent lets you tag a rule with the paths it applies to, it loads only when the agent touches matching files.

Auto memory is written by the agent, and each entry usually carries a type: user (your role and preferences), feedback (approaches you corrected or confirmed), project (work in progress, decisions the code does not show) and reference (where outside material lives). An index file lists every entry and only its start loads each time; topic files are read only when relevant. Most agents offer commands to browse, edit or switch off memory, to see which instruction files are loaded, to draft an instruction file, and to check the file for content that does not belong.

Memory has a price: every resident token is rent paid at the start of every session, and it competes with the task for the same window. Stale memory is worse than none, because it actively misleads. Review it, prune it and keep it under version control, like code.

Tools and the four extension mechanisms

Core tool Role
Read Open files and inspect state; the most used
Search Find by content (grep) or file name (glob) without reading everything
Fetch Pull a web page or document; brings untrusted text into context
Edit / Write Change files; the first tool with consequences
Shell Build, test, git; without a sandbox it hands over the whole machine
Delegate Start a subagent and get back a summary

The model decides which tool to use. To let the agent do more, there are four extension mechanisms:

Mechanism Problem it solves Where it attaches in the loop
Skill How the agent should do a kind of task (knowledge and workflow) Model reasoning
MCP Which outside data and actions it can reach Tool selection
Hook What happens automatically at a given moment Any stage; it can inspect, block or react
Plugin How extensions are packaged and shared Bundles the other three into one installable package

Take a release workflow (prepare, verify, publish to GitHub, notify the team):

01Skill: follow the release steps
02MCP: create the GitHub release
03Hook: block the release if tests fail
04Plugin: share the whole setup with the team

A skill is a folder: one instruction file (its name and description decide when the agent thinks of using it; the body is the workflow), plus reference material and scripts. Only the description loads at session start; the body loads when the skill runs. The model can invoke it on its own when the description matches the task, or you can call it by name with a slash command. Workflows with side effects should usually require an explicit call; clear, non-overlapping descriptions reduce wrong picks. At bottom, a skill is a way of managing context.

MCP (Model Context Protocol) connects outside services through one standard protocol: GitHub, databases, monitoring, Figma, Slack, browsers and more. A call takes six steps: the agent decides it needs an action; the MCP client calls a tool; the MCP server handles the connection; the outside service does the work; a structured result comes back; the agent evaluates it. In use it is almost the same as a local tool, only running in another process.

A hook is an automatic action attached to an event; it fires on time and does not depend on the model remembering. Model reasoning itself is not an event. A hook can run a command, send an HTTP request, call an MCP tool, insert a prompt or start a subagent.

01Session start: load context, log
02You submit a prompt: validate or add to it
03Before a tool call: inspect or block
04After a tool call: format, test, log
05Before stopping: confirm tests pass

A plugin bundles skills, hooks, subagent definitions, MCP settings and language-server settings into one package, which gives one-command install, pinned versions, names that do not collide, team reuse and distribution through a marketplace.

An agent’s configuration folder in a project usually has several parts: the instruction file and rule files are memory; a settings file holds permissions, hooks and environment variables; skills and custom commands are workflows; subagents and hooks are delegation and guardrails. Your personal folder has the same structure and applies to all your projects; project settings win over personal ones.

Need Use
Follow the company API conventions Skill
Read issues from Jira MCP
Run the formatter after every edit Hook
Guide a multi-step deployment Skill
Send a notification when done Hook plus MCP
Block writes to production Hook or policy
Share the whole setup across codebases Plugin

Putting it to work

  1. 01Write an instruction file for the project you use most: first the commands for tests, build and checks, then two or three hard constraints, then the folder layout and known pitfalls. Delete whatever the model already knows and keep it under 200 lines.
  2. 02Once you have corrected the agent on the same thing twice, put it in the instruction file or have the agent save it to memory. It is the cheapest improvement there is.
  3. 03Pick the extension by need: a workflow you repeat becomes a skill; reading or writing an outside system means MCP; anything that must happen every time and cannot rely on the model remembering (formatting, blocking dangerous commands) is a hook; package it as a plugin when the whole team needs it.
  4. 04Start permissions at manual or accept edits; use bypass only in a sandbox, a container or an environment you can throw away.
  5. 05Go through auto memory and the instruction file now and then, delete stale entries, keep changes under version control and review them as you would code.
Further: MCP in detail

Before MCP, connecting N AI clients to M services took N×M integrations. MCP is an open, stateless protocol: the host (for example, your agent) runs one MCP client per server, and an MCP server exposes a system’s capabilities as tools.

MCP primitive What it is Example
tools Actions the model can call create_issue(…)
resources Data to read, such as an issue or a table schema github://issues/123
prompts Prompt templates the server provides; you decide when to use them Shown in the agent as a slash command, e.g. “triage issue”

The three work together: to triage issue #123, the prompt supplies the organization’s triage procedure, the resource supplies the issue, and a tool fetches current diagnostics.

Security: least privilege, with tokens scoped to the repositories, tables or channels you need; separate reads from writes and require approval for writes; never treat tool output as instructions; review third-party servers before installing them, since they can carry prompt injection (instructions hidden in content to steer the model). Before connecting, ask two questions: what can this server read, and what can it change?

An MCP gateway is a control layer between AI clients and many MCP servers. It aggregates, routes, enforces policy, acts on behalf of the user’s identity, observes and scales. It pays off when there are many users, agents, servers or compliance rules, but the gateway is itself a trust boundary, with risks of over-broad credentials, losing the end user’s identity, tool-name collisions, secrets leaking into logs and a single point of failure. The 2026-07-28 specification is the largest revision since launch: the core became stateless, so any request can land on any instance; a new Mcp-Method header lets a gateway route without reading the request body, and tool lists can be cached for a set lifetime; long-running tasks (Tasks) and server-rendered interfaces (MCP Apps) ship as extensions.

Self-check

Design exercise: which mechanism fits each need?

Follow the company API conventions
Read issues from Jira
Run the formatter after every edit
Guide a multi-step deployment
Block writes to production
Share the whole setup across codebases

Self-check

Which of these belongs in the project instruction file?

03CHAPTER 3

Multi-agent use and Programming 3.0多智能体用法与 Programming 3.0

Key points

  1. Changing instructions alone can change how an agent works: Superpowers uses skills plus a session-start hook to impose a development process, and Caveman uses skills, hooks, MCP and a local proxy to cut tokens in both directions.
  2. There are three ways to scale: parallel agents save waiting time, subagents buy focus, long runs widen what one request can cover; a team of agents is worth it only when the work needs discussion.
  3. The core of Programming 3.0 is uncertainty: don’t expect the agent to behave the same every time, make the system around it reliable, and match autonomy to risk.
  4. Field data show the tasks handed to agents grew sharply in six months, but the longer the task, the lower the share that succeeds without a human stepping in.

Case one: Superpowers

Superpowers is a plugin for software development. By default an agent starts writing code as soon as it gets a request and fixes mistakes by trial and error. With the plugin, the work follows a fixed path:

01Human types the request
02Clarify questions
03Approve a design
04Write a detailed plan
05Test-driven development: write a failing test first, then code until it passes
06Review and verify
07Finish or merge the branch

It is made of nine skills:

Skill Role
using-superpowers Rules for when to discover and invoke which skill
brainstorming Turn a request into an approved design
writing-plans Break the design into concrete tasks
using-git-worktrees Set up workspaces that don’t interfere
test-driven-development Red (test fails), green (test passes), refactor
systematic-debugging Find the root cause before proposing a fix
requesting-code-review Review the work against the plan
verification-before-completion Show evidence before reporting “done”
finishing-a-development-branch Merge, open a PR, keep or clean up the branch

A skill file has six parts: name, description, instructions, checkpoints, references and scripts. A process skill can also state entry conditions, required actions, forbidden actions, gates that need human approval, verification requirements and the next skill to use.

Installing skills does not guarantee the agent will look at them. Superpowers adds a hook that runs at session start: whenever a session starts, is cleared or is compacted, a script reads the full text of a “bootstrap” skill and injects it straight into context, reminding the agent to follow the process.

Design question Superpowers’ answer
How is complex behavior represented? Small, composable skills
How does the agent remember to use them? A session hook injects a bootstrap skill
How does context stay manageable? Task skills load only when relevant
How do stages connect? Each skill names its gates and the next skill
How do users install it? Everything ships as a plugin
Are commands or MCP required? No; add them when needed

Case two: Caveman

Caveman compresses an agent’s tokens in both directions. There are three reasons: logs, diffs (side-by-side code changes) and tool output crowd the context; every turn costs money and waiting; and trimming only when the context fills cuts out key details. For example, 786 lines of test output become one line: “3 tests failed: ETIMEDOUT at client.ts:88”.

65%Reported cut in output tokens; the skill itself adds input tokens, so whole-session savings are smaller
2Directions: the skill changes how the model writes, the proxy changes what it reads
5MCP tools: compress, fetch the original, stats, and JSON-to-TOON conversion both ways

It uses all five extension mechanisms plus a local proxy (a small program that sits between the agent and the model service and can rewrite every request):

  • A skill sets a terse style: keep technical terms, commands, paths, code, errors, numbers, units and negations; drop filler, repetition, pleasantries and hedging.
  • Commands let you choose a level, such as /caveman ultra or /caveman off.
  • A session-start hook decides and saves the session’s level and restores the rules after compaction; a hook on prompt submission catches mid-session switches.
  • MCP provides compression and retrieval of the original.
  • A plugin packages it all.
  • The proxy compresses by content type: logs keep errors, stack traces and the first and last lines; code keeps imports, function signatures and types; diffs keep file names, hunk headers and changed lines; JSON keeps keys and structure.
A hook can intercept a request but cannot quietly rewrite what is sent to the model, hence the proxy. The proxy intercepts every request and changes the context; MCP runs only when called and cannot change context. If you write your own harness, you can do it directly.

Three ways to scale

Parallel agents Subagents Long runs
How Independent tasks, one worktree each Give a well-bounded task to a fresh context and get a summary back One large task runs over many steps
You gain Less waiting, not better answers Time and focus: the main conversation never sees the messy middle Scope: more done per request, less intervention

Parallel by hand. A git worktree is a second working folder of the same codebase: its own files and branch, a shared commit history, no touching each other’s files, no stashing and no second clone. Many agents can create a worktree per session with one command, say one for a payments feature and one for a login bug. With three sessions you can still hold the plan in your head. With twenty you need a copy of yourself: the plan lives only in your head, the sessions cannot see each other, you merge the branches yourself, and nothing is recorded to rerun.

Subagents are specialized assistants with their own context, tools and permissions, used for five things: keeping long output out of the main context, restricting tools and models, reuse across projects, parallel work and controlling cost (for example with a small model). A custom subagent is usually a Markdown file whose header gives a name, description, allowed tools and model, and whose body is its system prompt, stored in the project or personal configuration folder. Subagents can spawn subagents up to a limit, and two to three levels is the sweet spot; a subagent needs the delegate tool itself before it can spawn children.

Common built-in subagents Use
Explorer Read-only search of the codebase, no writing or editing; thoroughness can be set per call
Planner Research during planning, keeping exploration out of the main window
General-purpose Complex multi-step work that needs both exploring and acting

Explorer and planner skip the project instruction file and git status to stay fast and cheap. Ways to invoke a subagent, from weakest to strongest control:

  1. 01Name it in plain language: the agent decides whether to delegate, for this one request
  2. 02Call it with the dedicated syntax: this task always goes to it
  3. 03Run the whole session as that subagent: its prompt, tools and model
Keep in the main conversation Hand to a subagent
Back-and-forth iteration Verbose output you won’t need again
Stages that share context Work that needs restricted tools or permissions
Quick, targeted changes Self-contained work that returns a summary
Latency-sensitive work Parallel, independent work; simple jobs on a small model

Agent teams (offered by some agents, usually as an experiment) have a lead and several teammates. The lead spawns teammates, coordinates and synthesizes; each teammate is a separate agent instance; everyone shares a task list and claims items from it; each agent has a mailbox, so teammates talk directly. Teammates don’t inherit the conversation but load the project instruction file and skills. Teams suit reviews from several angles, independent modules, debugging with competing hypotheses and work that crosses front and back end; sequential tasks, edits to the same file or dependency-heavy work belong in one session or with subagents.

Subagents Agent team
Communication Report back to the caller only Teammates talk directly
Coordination The lead manages Shared task list
Best for Tasks where only the result matters Work that needs discussion
Token cost Lower Higher

Dynamic workflows use a script running in the background to orchestrate many subagents, for codebase-wide bug hunts, migrations of 500 files, research that needs cross-checking and planning from several angles.

Long runs. One form is a goal mode: you hand over a verifiable end state, such as “the lint command exits with zero errors”, and an evaluator rechecks after every attempt, stopping when the condition holds or the maximum number of attempts runs out. “All integration tests pass” works as a goal; “refactor the code” does not, because nothing can check automatically whether it is done. The other is a timed loop that repeats one prompt at an interval, such as “check CI and fix whatever broke” every 5 minutes, until you stop it.

Case three: 16 agents build a C compiler

16Parallel agents, about 2,000 sessions over two weeks
~100KLines of Rust that build Linux 6.9 on x86, ARM and RISC-V
2B / 140MInput / output tokens; just under $20,000 in API cost
~99%Pass rate on the major test suites

Plain infrastructure did the coordination:

  • Each agent had its own container and copy of the code.
  • Tasks were claimed with lock files in one folder, so no two agents did the same job.
  • After implementing and testing, an agent pulled everyone else’s work, then merged, pushed and released its lock.
  • New sessions read a progress document to regain context.
  • Specialist agents handled documentation, performance, quality and deduplication.
  • Automated tests showed how far the work had come.

There was no chat and no manager agent. The limits: merge conflicts were frequent; once every agent hit the same Linux kernel failure, parallelism stopped helping; part of 16-bit x86 still relied on GCC; and the generated machine code was less efficient than GCC’s.

Programming 3.0 and uncertainty

One way to divide it What humans write Through Becomes
Programming 1.0 Machine instructions or assembly Run by hardware
Programming 2.0 A programming language Compiler Machine instructions
Programming 3.0 The goal, stated in natural language Agent A programming language, then machine instructions

Each step up raises productivity and uncertainty together. Karpathy’s Software 3.0 divides it differently: 1.0 is source code, 2.0 is neural network weights (collect data, train), 3.0 is prompts to an LLM (natural language). Judging whether a job should be done the 1.0, 2.0 or 3.0 way is an important engineering skill.

Uncertainty is not new. Hardware (32 vs 64 bit, byte order), environment (concurrency, unreliable networks) and software (compiler versions, dependencies that update quietly) were handled in 2.0 by fixed-width types, memory consistency models, APIs that are safe to retry and full testing before upgrades. 3.0 adds more: non-determinism in GPU computation and floating-point variance, code generation that changes the environment as it writes, randomness in sampling, and the vagueness of a one-line prompt. Uncertainty sits in five layers: natural language (the meaning may be misread); retrieval and context (results change, indexes update, content gets truncated); model generation (sampling, software and hardware non-determinism); the agent and tool loop (tools fail, the environment changes); and the generated program (usually deterministic once written, unless it calls models or tools at runtime).

  1. 01Specify: state assumptions and have the model confirm unclear points before acting; hand over outcomes rather than a prompt, meaning requirements, invariants (conditions that must always hold), constraints and acceptance tests
  2. 02Control: separate proposing from executing and verify a plan before committing; manage context deliberately, owning memory, sources and retrieval, and expire stale information
  3. 03Verify and govern: tighten the generate-and-check loop, since frequent cheap checks beat one expensive review at the end; measure one layer deeper with tests, several metrics and simulated workloads you can reason about

Don’t expect the agent to be deterministic; make the system around it reliable, and match autonomy to risk.

Evidence from the field: Codex and OpenAI

Tasks given to Codex grew sharply in six months

Share of users running tasks of this size, %, Dec 2025 vs May 2026; person-hours are the hours a person would need

  1. ≥ 1 person-hour · 2025.1235.4%
  2. ≥ 1 person-hour · 2026.0570.2%
  3. ≥ 8 person-hours · 2025.122.1%
  4. ≥ 8 person-hours · 2026.0525.6%
OpenAI Codex report (June 2026)

Users running full-day tasks grew 12×. Active users grew more than 5× in the first half of 2026; under 1% of individuals and 17.3% of organizations used Codex in the past 28 days, while nearly every OpenAI employee did.

28.6%OpenAI users running more than 5 agents in a week
~2.5Hours of agent time per day for the median employee
~71Hours per day at the 99th percentile, up 88% since April
3.14×Agent workdays per human workday in research, September 2026

Before June 2026, agent run time was smaller than human work; after, it was larger. Most researchers run four or more parallel workstreams, and lines changed per engineer are close to 8× the pre-2025 average. The human role shifts to planning, delegating, monitoring, reviewing and integrating.

The longer the task, the less often it succeeds without help

Share of tasks succeeding without human intervention, %, by the time a person would need

  1. 86%<15m
  2. 76%15–30m
  3. 69%30m–1h
  4. 61%1–2h
  5. 57%2–4h
  6. 43%4–8h
  7. 40%8–16h
  8. 23%16–32h
  9. 13%32–64h
  10. 16%64–128h
OpenAI report (September 2026)

The delegation ladder, bottom to top: chatbot (AI answers, the human does the work), assistant (human and AI work together), agent (the human hands over a whole unit of work), multi-agent worker (the human coordinates several agents), systematized workflow (skills and agents run the process). Measured on this ladder, OpenAI’s workforce as a whole is still on the lower rungs.

Putting it to work

  1. 01Get one agent working end to end before you go parallel. Run in parallel only tasks that are independent (different modules, different bugs), one worktree each; tasks that touch the same file should not run in parallel.
  2. 02Hand verbose searching, log reading and research to a subagent and have it bring back only a summary; give it the fewest tools it needs, read-only if reading is enough.
  3. 03Write every long task as an end state that can be checked automatically: a command plus the expected result, such as “the test command exits with 0” or “all 12 months in the report have figures”. If you cannot say how to check it, don’t hand it over yet.
  4. 04The longer the task, the likelier it fails. Split anything a person would need several hours for into smaller tasks that can each be accepted, and hand them over and check them one at a time.
  5. 05Break the workflows you repeat into small skills, each with entry conditions, forbidden actions and the next step; put human approval on steps that change production data or send anything outside.
  6. 06When tool output runs long, borrow Caveman’s rules so the agent reads only what matters: errors and the first and last lines of logs, changed lines of diffs, keys and structure of JSON.
Also: CLI coding agents, mid-2026
Category Examples
From model vendors Codex CLI, Antigravity CLI, Grok Build, Mistral Vibe, Kimi Code, Qwen Code
Platform agents Copilot CLI, Cursor CLI, Amp, Auggie, Droid, Junie CLI, Qoder, CodeBuddy
Open source, bring your own key OpenCode, Crush, Goose, Aider, Cline, Kilo, Continue, OpenHands and others
Minimal kernels Pi, oh-my-pi, mini-SWE-agent, gptme, Open Interpreter
Axis The two ends
Open vs closed Open: Codex CLI, OpenCode, Goose, Cline, Pi; closed: Copilot CLI, Cursor, Droid, Junie
Locked vendor vs bring your own key One vendor’s models only: Antigravity CLI, Grok Build; any model service: OpenCode with 75+ providers, Kilo with 500+ models
Sandbox vs permission prompts Operating-system sandbox: Codex CLI, Copilot CLI, OpenHands in containers; per-action permission prompts: most tools
Local vs cloud Local-first, no usage reporting: Goose, Nanocoder, gptme; hand off to the cloud: Copilot CLI, Codex, Mistral Vibe
Kitchen sink vs minimal Most features: oh-my-pi; four tools only: Pi, mini-SWE-agent (about 100 lines of Python)

Self-check

Should this kind of work stay in the main conversation or go to a subagent?

Back-and-forth iteration
Verbose output you won’t need again
Quick, targeted changes
Work that needs restricted tools or permissions
Latency-sensitive work
Parallel, independent work

Self-check

Handing a long task to a goal mode, which of these works as the goal?

04CHAPTER 4

Agent design I: the loop, tools and context智能体设计 I:循环、工具与上下文

Key points

  1. Agent = model × harness; changing only the harness raised the tasks one model solved on two SWE-bench versions by 1.7 to 2.3×.
  2. Designing tools is designing context: few tools that don’t overlap, output that saves tokens, errors that tell the model how to fix things.
  3. Context costs money, time and attention, and the model is most likely to miss an answer placed in the middle.
  4. When the window gets too large, apply admission, offloading and transformation in turn; having the LLM summarize is the last resort.

ReAct and the agent loop

ReAct (reason plus act) puts reasoning and acting into one loop: think (what is known, what is missing, what to do next), act (issue a structured call the environment can run, such as “search for this function name”), observe (the facts the environment returns). Reasoning alone has nothing to check it, so small errors compound into confident hallucination; acting alone has no plan behind the calls, so the model goes round in circles. ReAct lets thinking steer the next action and observation correct the next thought, until the observations answer the question or a stop rule ends the run.

Written as code, a minimal agent loop is:

  1. 01Start the message list with the system prompt and the user request
  2. 02Loop up to a step limit: call the model and append its reply
  3. 03If the model gives a final answer, return it
  4. 04Otherwise, for each tool call: check the arguments, run the tool, turn the result into text and append it as a tool message
  5. 05Past the step limit, exit with an error

As the designer of a harness you do four things: write tool definitions (which tools exist and what arguments each takes); assemble the context; check requests, verify permission and execute; and optionally post-process results and manage context. A coding agent’s three parts must be designed together because they share one context window: the model plus the loop; tools and guardrails (permissions, sandbox, approvals); and state (what is in the window now, and what carries from one step to the next).

Tool design: search and read

Approach How it finds code Fits when Main cost
glob / grep Matches file-name patterns or literal text The name is known or guessable Each search costs a turn and context; literal matching misses code phrased differently
Semantic index Turns code chunks into vectors that capture meaning (embeddings) and searches by meaning; or, as Aider does, a repo map (the file tree plus functions and classes ranked by importance) Your words don’t match the code’s Building the index and keeping it in sync
Outside clues Stack traces, failing tests, git history A report already points at the code Present in only some tasks
Language server (LSP) The compiler’s view of symbols: where defined, who references them, what type The change must follow references, as in a rename One resident server per language, slow to start

In practice, start with grep and add an index or LSP when names are not enough.

Tool design: edit

Approach How it works Risk
Whole-file rewrite The model regenerates the entire file Output grows with file length; code you meant to leave alone quietly changes in long files
Unified diff / patch The model emits a patch and a tool applies it Stale line numbers or surrounding code make a change block (hunk) fail to apply
Search and replace An exact anchor string from the original plus its replacement Fails if the anchor is not unique, is stale or has mismatched whitespace
Structured / AST edit Operations on symbols in the syntax tree (AST, a structured form of code), such as rename or add a parameter Needs tooling per language and can express fewer edits, but cannot produce invalid syntax by construction

Tool design: execution and the rest

The shell (command line) is the most powerful and most dangerous tool. One call can chain, filter, loop and retry; it reaches the file system, network, package managers and any program; files and processes it leaves behind outlive the call. Whatever the shell can do, the agent can do. Think through isolation (where it runs, what it can reach), failure signals (errors the agent can understand and act on), output (enough but not too much), duration (long-running and background processes) and budget (after how many retries to stop and hand back).

Five more kinds of tools are common: memory and notes (so the plan survives compaction); subagents (explore and return a shortlist, not the transcript of 40 file reads); web search and fetch (read the installed source first, then the web); browsers and visual feedback (send screenshots back to the model); and asking the user (one cheap question beats a confident wrong patch).

Few and non-overlappingOverlapping tools make the model hesitate over which to use
Specific, not generalsearch_orders(customer_id) beats a raw run_sql that executes any SQL
Token-efficient outputTruncate, paginate, summarize; designing tools is designing context
Errors that teachReturn a hint on how to fix it, not just “invalid argument”
Idempotent by defaultRunning the same call twice has the same effect as once, so retries are safe

An interface built for agents solves more than a bare shell

SWE-agent ablation (removing one design choice at a time to see the effect), GPT-4, resolve rate, %

  1. Full SWE-agent interface18%
  2. Full interaction history15%
  3. Whole-file viewer12.7%
  4. Shell only11%
  5. No dedicated editor10.3%
SWE-agent ablation, original lecture notes

SWE-bench tests agents on real GitHub issues: given a codebase and an issue description, does the agent’s patch make the tests pass?

From prompt engineering to goal engineering

Era Name Question Focus
2023–2024 Prompt engineering How do I instruct the model? Wording, examples, output format
2025–2026 Context engineering What should the model see? Retrieval, memory, history, compaction
Now Harness engineering How should the agent run? Loop, tools, sandbox, retries, stopping
Next Goal engineering What counts as success? Objectives, criteria, constraints, trade-offs
Prompting technique How When to use it When to move on
Zero-shot Instruction only Common task, format easy to describe Rules hard to state: go few-shot
Few-shot Instruction plus a few examples Unusual output shape that is easier to show than describe Needs steps: go chain-of-thought
Role and persona Assign a role Tone or judgment matters, specific audience Needs steps: go chain-of-thought
Chain-of-thought Write the reasoning steps, then the answer The task really has steps and errors come from skipping them Several paths: go tree-of-thought
Tree-of-thought Branch into lines of thought, score each, prune the weak Several routes are viable and scoring is cheap One right answer: go self-consistency
Self-consistency Answer several times, then vote One answer and costly mistakes; send split votes (such as 3/5) to a human Stages separate: go prompt chaining
Prompt chaining One job per call, checked at each handoff Staged work where each stage can be checked; retry only the stage that fails Tuning the prompt itself: go meta-prompting
Meta-prompting Have the model rewrite its own prompt You have a scored evaluation set Gains plateau: revisit the choice

Four general rules: start simple and add context as needed; separate the parts (context, instructions, tools, output spec, ordered as instructions, delimiter, data); be specific and concise, since clever phrasing does nothing; break big tasks down rather than front-loading complexity. Prompting advice differs by model, so re-tune when you switch, and some older tricks no longer help with newer models.

Context engineering: context is a finite resource

Karpathy’s definition: context engineering is the art and science of filling the context with just the right information for the next step. Context has three costs: money (every step resends the whole window), time (bigger prompts make prefill and decode slower) and attention (the fuller the window, the worse the recall, and the middle is most often ignored).

Accuracy is lowest when the answer sits in the middle

Position of the answer among 20 documents vs answer accuracy, %

  1. 76%Doc 1
  2. 61%Doc 5
  3. 55%Doc 10
  4. 59%Doc 15
  5. 71%Doc 20
Liu et al., “Lost in the Middle”, TACL 12 (2024)

Length has its own cost: in Chroma’s Context Rot tests, growing the input from 1K to 400K tokens dropped simple-lookup accuracy to 73%, and to 46% with distractors added.

An illustrative token budget for one turn: system prompt about 2K, tool definitions about 6K, project environment about 8K, retrieved material about 25K, message history about 80K and growing. When the window gets too large there are four strategies, from preventive and lossless to lossy and irreversible:

The first three strategies shrink context by 75% to 98% without summarizing

Example, tokens before and after

  1. Admission · raw web DOM48,000
  2. Admission · extracted result only900
  3. Offload · 60 tool definitions42,000
  4. Offload · index plus 3 definitions3,100
  5. Transform · all results kept96,000
  6. Transform · latest state only24,000
Original lecture notes, example
Strategy How
Admission Guard the door: targeted retrieval (just the fields, not the whole document); reshape tool output into a lean format first and truncate only when it cannot be reshaped; hand raw data to a subagent to process on its own
Offloading Load on demand: tiered tool definitions; tool search (keep only an index and fetch a tool’s full definition, its schema, when needed); tool outputs that return a handle you can redeem for the full text; task lists on disk; persistent memory kept to a small index
Transformation Drop history selectively: deduplicate (keep only the latest state of each object); mask old observations (remove tool results older than N steps); sliding window (keep only the start and the last few turns)
Compaction The last resort, with an LLM: rolling summaries, a full summary at the limit, auto memory that stores key facts outside the window. Reserve room for output, keep the system prefix, and put key facts back after compacting

Context fails in five ways, and naming the failure makes the fix obvious: poisoning (a hallucination enters the window and is later cited as fact), distraction (the history is so long the agent starts imitating its own past actions), confusion (irrelevant tools and documents pull the answer off course), clash (old and new information contradict each other but both stay) and drift (the real goal is buried and swapped for a nearby subgoal).

The same model with only the harness changed solved clearly more tasks on both benchmarks: SWE-bench Verified rose from 43/169 to 72/169, SWE-bench Pro from 31/316 to 72/316. There were only four changes: compress old tool output, keep recent observations visible, detect repetition and stalls, and step in when stuck. Some of what looks like model failure is really context and control-loop failure.

Putting it to work

  1. 01When you connect a new tool to an agent (say, an orders or inventory API), check five things: does it overlap an existing tool; are its name and arguments specific; is the default output lean and paginated; does an error say how to fix it; is calling it twice safe?
  2. 02When the agent goes off track or drifts further over time, check the five context failures first: is it citing an earlier wrong conclusion (poisoning), repeating itself (distraction), led astray by irrelevant files (confusion), caught between old and new statements (clash), or has it forgotten what you wanted (drift)?
  3. 03Put the most important information at the start or the end, not buried in the middle of a long document; give the agent only the relevant passages of reference material, not whole documents.
  4. 04In a long session, have the agent save processed logs, web pages and data to a file and keep only the path, or hand them to a subagent that reads them and brings back the conclusion.
  5. 05Pick a prompting technique starting from zero-shot and move down the table as needed; give two or three examples when the format is fixed, and split staged work into a prompt chain, checking each stage before passing it on.
Further: beyond ReAct

ReAct loops every step; Reflexion loops after failure (try, evaluate, reflect, retry); plan-and-execute loops when the plan breaks (plan, execute, replan); tree search does not loop at all but expands several branches in parallel and keeps the best one.

Self-check

Which context strategy is each of these?

Take only the fields you need, not the whole document
Keep a tool index and load full definitions on demand
Keep only the latest state of each object
Have an LLM summarize the history at the limit
Hand raw data to a subagent
Remove tool results older than N steps

Self-check

“The history is so long the agent starts imitating its own past actions.” Which context failure is this?

05CHAPTER 5

Agent design II: multi-agent systems智能体设计 II:多智能体系统

Key points

  1. Multiple agents are not the default; there are only four good reasons to split: specialization, isolation, parallelism and keeping context in check.
  2. Every architecture answers three questions: who coordinates, how the task is split and how agents communicate; real systems mix several architectures.
  3. A subtask must state its goal, boundaries, output format and completion test; parallelism pays only when the work saved exceeds the coordination overhead.
  4. Communication between agents is a distributed-systems problem: keep control separate from content, and handle timeouts with idempotency keys and rollback paths.

Three graphs and eight architectures

Every architecture rests on three questions: the control graph (who coordinates: one supervisor, layers of supervisors or nobody; is control handed over mid-run), the task graph (how the work is split: a planner splits it up front, agents bid for it, or it emerges from local rules) and the communication graph (direct messages, broadcast or a shared workspace).

Class Architecture Core idea Fits Weakness
Centralized Supervisor and workers One planner, many executors Subtasks that split and run in parallel The supervisor becomes the bottleneck and its context grows fastest
Centralized Hierarchical Supervisors manage sub-supervisors Tasks that break down level by level Errors amplify down the levels; hard to decide how much context crosses each level
Centralized Pipeline / DAG Each stage feeds the next, with an agreed data format at each handoff Clear stages in a fixed order Errors flow downstream with no going back; easiest to debug
Decentralized Market and auction Agents bid on capability, cost and speed Dynamic allocation; work lands with the cheapest qualified agent Bids are self-reported and can overstate ability
Decentralized Blackboard Coordinate through shared state (a database, file system or git repository) Many agents working on one shared artifact Stale state; consistency, concurrency, provenance, versions and cleanup all need managing
Decentralized Committee and debate Answer independently, then a judge or a vote decides Tasks that need judgment Groupthink: same model, same context, same blind spots
Decentralized Swarm No fixed coordinator; agents negotiate directly Local negotiation Messages grow with the square of the agent count (about n² for n agents), conflicts are hard to resolve, rare in products
Hybrid Dynamic topology Add, remove or rewire agents mid-run Task structure unknown in advance; keep simple tasks cheap A different shape every run, so failures are hard to reproduce

A DAG (directed acyclic graph) is a task dependency map that only moves forward and never loops back: B waits for A, while C and D can run at the same time.

Real systems are hybrids. For example, a planner agent sends work along a task DAG it can adjust at any time to coder, researcher, tester and reviewer agents, all sharing one git repository, and replans when needed. That uses supervisor, hierarchy, shared memory and pipeline at once.

01Planner agent
02Task DAG, adjustable at any time
03Coder · researcher · tester · reviewer
04Shared git repository
05Replan when needed

Task decomposition

There are six ways to split work: by data (each agent takes a slice of the documents), by expertise (security, performance, correctness, legal), by stage (plan, build, test, review), by hypothesis (each agent investigates one possible explanation), by tool (web, database, code execution) and by permission (different administrative domains). To review a pull request that touches 200 files, for instance, split by file first, then by security and performance.

A good subtask states: the goal; inputs and relevant context; boundaries and exclusions; allowed tools and permissions; the output format (a schema listing the fields to return and their types); the completion test; budget and deadline; and which other tasks it depends on.

A bad subtask

  • “Research storage systems”

A good subtask

  • “Find storage-related papers published in 2026; return title, date, systems contribution, evaluation scale and a link to the primary source; exclude database query optimization”

Granularity is a trade-off: too coarse and there is no parallelism; too fine and scheduling and communication dominate. Total multi-agent time is roughly planning time plus critical-path time (the longest chain of dependencies) plus communication time plus merge time. Parallelism helps only when the serial work it saves exceeds those costs. Rather than sending 20 agents one-line lookups each, merge them into 4 subtasks.

Decomposition can be static (known before running, like summarizing 5 PDFs), dynamic (spawn a lookup when a dead link turns up), recursive (a reviewer spawns a subagent for each subdomain) or opportunistic (an idle agent claims the next unlabeled document). Dynamic decomposition needs a spawn limit, a budget, a depth limit and a stop condition, or delegation recurses without end.

Common decomposition failure Example
Overlap Two agents summarize the same paper
Gap One takes “2020–2023”, another “2025–2026”, and 2024 is missed
Hidden dependency Pricing needs a size estimate, discovered only at runtime
Unmergeable outputs One returns free text, another JSON
Lost global context Every section is fine on its own, yet the report contradicts itself
Straggler Six agents finish in 20 seconds, one takes 4 minutes and everyone waits

Communication

Dimension Options Rule of thumb
Topology (who can talk to whom) Supervisor and workers, peer to peer, mesh Follow the task’s dependencies
Medium (how information is exchanged) Message passing (queues or a bus), shared memory (such as a shared task list), files and artifacts (including databases) One medium per link
Channel (how it is delivered) Point to point, broadcast, publish and subscribe, shared blackboard, request and response, artifact handoff Broadcast only when everyone must know
Format and meaning Natural language plus control fields Route on fields, never on the wording

Natural language is flexible but vague; structured messages are easy to validate but less expressive. In practice, use both: messages carry fields such as task_id, type, status, claim, confidence, evidence and artifact. Keep control separate from content with a small set of operations the runtime understands: DELEGATE, QUERY, REPORT, HANDOFF, UPDATE, CANCEL, ACK (received), ERROR and COMPLETE. The runtime can then route, retry and stop without asking an LLM what a message means.

Communication is a hard distributed-systems problem. Agent A asks B to “buy 8 GPU instances”, and the network times out with no reply. Did B do it? Retry or give up? Guarantee “at most once” (might skip it) or “at least once” (might do it twice)? Can you get “exactly once”? Use the task_id as an idempotency key (one ID takes effect only once, so resending cannot buy twice), prepare compensation and rollback paths, and decide in advance who answers for a duplicate purchase.

Multi-agent systems inherit every hard problem of distributed systems: concurrency and non-determinism; unreliable networks (delay, loss, reordering, duplication); no shared clock; partial failure (you cannot tell a slow agent from a dead one); keeping copies of state consistent; and debugging and observability (logs are hard to line up when machine clocks drift). On top of that come scheduling (who runs next, and for how long), resource allocation (models, CPUs) and state management (checkpoints, memory, provenance, versions), with no request flow planned in advance. LLMs are black boxes, which makes it harder:

Problem What it looks like
Information loss A summary drops what the worker knew
Context pollution Key information gets buried
Stale information X has changed to 5, but B still acts on X=3
Conflicting beliefs A says safe, B says vulnerable
Nobody owns it Every agent thinks another is responsible
Communication loops A asks B, B asks C, C asks A
Hard to diagnose Nobody can say why it failed

A2A and MCP

A2A (agent-to-agent) is a protocol for agents to talk to each other. Every A2A server publishes an Agent Card at /.well-known/agent-card.json with its identity, skills, address, capabilities (such as streaming) and authentication. There are three basic objects: messages (one exchange between client and agent), tasks (a piece of work with an ID and a lifecycle) and artifacts (what a task produces). Follow-up messages join the same task. A task is submitted, then working; it can pause for input or authentication and resume; it ends completed, failed, rejected or canceled. Long tasks can be followed by polling (short tasks), streaming (watch output as it comes) or push notification (tasks of several hours). A2A standardizes only communication, not orchestration: who delegates to whom, how work is split and when to stop are still the harness’s decisions.

01Submitted
02Working
03Pauses for input or authentication, then resumes
04Completed · failed · rejected · canceled
MCP A2A
Main object Capabilities / tools Agents / tasks
Connects An agent to a service An agent to an agent
What you discover Tools, resources, prompts The other agent’s capabilities
One piece of work One tool call A long-running task
Internal state Exposes a capability interface Best kept private
Analogy A device or API interface A remote call between services (RPC)

One A2A remote agent may call twenty MCP servers inside. With MCP, the host, not the model, decides what is exposed.

Design principles

  1. 01First ask whether you need multiple agents at all: when one agent is enough, more usually just add overhead
  2. 02Let the task’s dependencies set the topology, and keep communication to a minimum
  3. 03Find where information is lost: whichever node summarizes is where detail disappears
  4. 04Draw failure-isolation boundaries so one stuck part cannot stall the whole system

A dense mesh is rarely a good default. More communication adds context pressure without necessarily adding useful information.

Putting it to work

  1. 01Try a single agent before splitting. Split only if one of these holds: the context will not fit; parts need different permissions or tools; subtasks are independent and parallelism clearly saves time; or different expertise must check different aspects.
  2. 02Write a task card for each subtask: goal, inputs, what not to do, allowed tools, return format (list the fields), what counts as done, budget and deadline. A shared return format is what makes the final merge possible.
  3. 03After splitting, check for the six failures: overlapping scopes; gaps (time periods, regions and product lines are the easiest to miss); unstated dependencies; outputs that cannot be merged; overall consistency; and one subtask so slow it should be split again.
  4. 04At the merge, have one person or one agent read the whole thing specifically to find contradictions between parts, because summarizing is where detail gets lost.
  5. 05Give every action that spends money, sends a message or changes data a unique task number; check whether that number has already run before acting, and after a timeout query the status rather than retrying blindly.

Self-check

Which architecture fits each kind of task?

Independent subtasks that split and run in parallel
Clear stages in a fixed order
Tasks that need judgment
Assigning work dynamically to the cheapest qualified agent

Self-check

One agent covers “2020–2023” and another “2025–2026”, and 2024 is missed. Which decomposition failure is this?

06CHAPTER 6

Agent design III: memory and reliability智能体设计 III:记忆与可靠性

Key points

  1. Every stage of memory is a trade-off: whether to write, what form to store, where to keep it, when to retrieve, how to generalize, when to forget.
  2. Every memory needs a validity time and a source, and forgetting is as essential an operation as remembering.
  3. At 95% per-step success, only 8% of 50-step tasks finish without an error; errors compound and also flow downstream.
  4. Failures come from five places: the task description, the harness, the model, the tools and the environment, and each has its own defenses.

Six design questions for memory

01Write or skip: is it worth keeping?
02Encode and organize: what form should it take?
03Store: where should it live?
04Retrieve: does this task need it?
05Reflect and generalize: what broader conclusion follows?
06Keep, update or delete: is it still true?

Writing. Recording every interaction misses nothing but is noisy; writing selectively is precise but can miss things. The decision to write can rest on an explicit user request, a fixed rule, a small classifier or a periodic LLM review.

Form Example Trait
Raw event “We moved serving from vLLM to SGLang.” Faithful but large and redundant
Unstructured summary “Uses SGLang for model serving.” Compact, may lose context
Structured state serving_engine = SGLang Queryable, but bound by the field definitions
Knowledge graph Project → USES → SGLang Connects entities and can express change over time
Store Examples Good at
Plain files The project instruction file, scratchpads Easy for people to inspect, diff and search
Key-value or relational database Redis, SQLite, Postgres JSONB Exact lookup, filtering, transactions
Vector store pgvector, Chroma, Pinecone Finding content with similar meaning
Graph database Neo4j, FalkorDB (Graphiti) Querying relations and following them several hops
When memory is used How Pros Cons
Automatic Search, call the LLM and write every turn Predictable, simple More latency and irrelevant context
Runtime-controlled Search or write only when a condition holds Selective, efficient Needs rules or a trained classifier
Model-controlled Give the LLM search, add, update and forget as tools On demand May fail to read or write when it should

Many systems mix these, and reads and writes can follow different policies.

Retrieval. The basic pipeline is query, vector search, take the top k most similar, put them in the prompt. But similar meaning is only one signal. Also weigh scope (the same user, project, entity or task), importance (the cost of missing it or bringing in the wrong thing), validity (does it still hold now, for this task) and provenance (source, confidence, evidence).

Reflection. Repeated questions about vLLM, SGLang, TRT-LLM and LLM scheduling generalize to “sustained interest in LLM inference systems, medium confidence”. Generalize once enough new evidence has built up (every N events, or when the context fills) or when facts conflict or repeat, preferably as a background job.

Forgetting matters as much as remembering. Reasons to forget: staleness, errors or contradictions, privacy and security, storage and retrieval cost. Ways to do it: mark invalid, delete permanently, expire automatically (TTL), or tier the store and evict from active memory. Every memory needs a validity time and a source: “serves with vLLM” recorded in April 2026 is replaced in June by “serves with SGLang”, noting that it came from conversation 28.

Who owns it. Either the agent does (files in the harness: the project instruction file, scratchpads, task notes, saved by the harness) or a dedicated memory system does (a service the agent calls, making memory an interface shared across agents and sessions).

Memory system Kind How it stores and retrieves
Mem0 Fact-centric Scoped by user, agent or run; vector search plus filters, optional graph memory
Graphiti Knowledge graph with time Extracts entities and facts with validity periods from conversation snippets; mixes meaning, keyword and graph search
supermemory Profiles, memories and documents Maintains user profiles, memories and documents together, linked to source and time
Memory failure What it looks like
Retrieval miss The relevant memory exists but is not found
Context pollution Too many irrelevant memories enter context
Memory hallucination An inference is stored as fact: “studies at University A” becomes “visiting student at University A”
Staleness An old fact overrides new information
Isolation failure One user’s memory reaches another user
Over-generalization A one-off event becomes a lasting preference
Persistent prompt injection Untrusted content is stored and later comes back as an instruction
Unbounded growth The store keeps growing, and retrieval gets costlier and less accurate

Evaluate memory on four fronts: retrieval (precise and complete?), writing and updating (precise and complete? how much stale memory?), governance (deletions honored, scopes isolated?) and the system (latency, extra tokens, storage growth). End-to-end benchmarks mainly test whether an agent can recall and reason over a long conversation history, covering recall, temporal reasoning, updates, preferences and declining when it should: LoCoMo (ACL 2024, 10 long conversations, 1,540 questions), LongMemEval (ICLR 2025, five memory abilities, 500 questions) and BEAM (ICLR 2026, up to 10M tokens, 2,000 questions). A memory stack comes in two shapes: a separate memory layer (the agent runtime, plus memory management such as Mem0 or Letta, plus a vector, SQL, graph or object store), or memory inside the harness (managed by the runtime itself and stored as Markdown files).

Reliability: errors compound

At 95% per step, only 8% of 50-step tasks finish without an error

Probability of an error-free task, %, by number of steps, assuming independent steps

  1. 95%1 step
  2. 77%5 steps
  3. 60%10 steps
  4. 36%20 steps
  5. 8%50 steps
Computed as 0.95 to the power n

A task succeeds only if every step succeeds, and an early error carries into later steps, so real runs do worse than this estimate. Failures can start in five places: the task description, the harness, the model, the tool layer and the environment.

Failure Example Fix
Vague goal “Fix the login bug”, and it fixes the wrong one of three State the file, the symptom and how to reproduce it
Proxy goal “Make the tests pass”, and it deletes the failing test Forbid editing tests; review the changes
Unstated constraint “Speed up search”, and it breaks the public API Say what must not change
No definition of done “Tidy up the parser”, and it refactors forever Give an acceptance test and a stop rule
Conflicting goals “Smallest change, cover every edge case”, and it quietly drops the edge cases Rank the goals explicitly
Task description: write “done” as a testGive acceptance tests up front and list what must not change
Harness: bound every runCap steps, cost and time; checkpoints you can roll back to
Model: demand evidenceEvidence for every claim, verification, a stronger model when needed
Tools: fail loudlyExplicit field types; errors kept separate from empty results
Environment: pin and isolateA fresh sandbox with fixed versions every time; retry transient failures before judging

The field still knows little about agents running at scale, and written best practice is thin.

Putting it to work

  1. 01Before handing over a task, answer five questions: is the goal specific (which file, what symptom); could it be gamed (say, by deleting tests); what must not change; what counts as done; which goal wins when goals conflict? Write the answers into the task.
  2. 02Give every run three limits: maximum steps, maximum spend and maximum time; set checkpoints where you can roll back, and return to the last good state on failure.
  3. 03Make the agent argue from evidence: “tests pass” comes with the test output, “fixed” with before-and-after results from the reproduction steps.
  4. 04Set rules for memory: every entry carries a date and a source; conclusions the agent inferred are marked as inferred; anything personal gets an expiry date; clear out stale and contradictory entries now and then.
  5. 05The more steps a task has, the likelier it fails, so split where you can: several segments, each accepted on its own, are far more reliable than one long unbroken chain.
  6. 06When diagnosing a failure, go through the five sources in the tabs above: first whether the task was ambiguous, then the harness’s limits and state, then the model’s behavior, and finally tools and environment.

Self-check

Where does each failure come from?

Told to “make the tests pass”, it deletes the failing test
No step or cost limit, 200 steps with no progress
Says “the tests should pass” without running anything
A date without a time zone puts the task 8 hours off
Fails in leap years

Self-check

At 95% success per step, with independent steps, what is the chance a 20-step task finishes error-free?

07CHAPTER 7

Agent design IV: evaluation智能体设计 IV:评估

Key points

  1. What gets evaluated has moved from a single model to the whole of model, prompt, tools and harness, and scoring now rests on tests and the final state of the environment.
  2. Eight representative benchmarks each test one environment: question answering, function calls, the web, the desktop, a code repository, customer service, the terminal and a simulated company.
  3. It is hard for three reasons: leakage has four routes; exams that give the full instruction up front reward guessing; and success rate alone ignores cost and safety.
  4. Benchmarks get maxed out ever faster; judging a real agent means weighing capability, cost and speed together.

A benchmark is a public set of standard test questions, so everyone can compare models or agents on the same exam.

History and what is evaluated

There are two ways to evaluate an agent: by component (planning and task breakdown; extracting, consolidating and retrieving memory; discovering, choosing and filling in tools; recovering from errors) or end to end (success rate, cost per task, time to finish). Benchmarks are moving toward larger scope, less specific instructions, more realistic settings and fresher questions.

Period Representative benchmarks Focus
Before 2018 Penn Treebank, WikiText, LAMBADA, SQuAD Language modeling and narrow tasks
2018–2019 GLUE, SuperGLUE, ARC, HellaSwag, WinoGrande Transfer learning and general understanding
2020–2022 MMLU, BIG-bench, GSM8K, MATH, HumanEval, TruthfulQA, HELM Foundation-model capability
2023–2024 MT-Bench, Chatbot Arena, IFEval, LongBench, MMMU, GPQA, AgentBench, WebArena, GAIA, SWE-bench, OSWorld, τ-bench Agents and tools, long context, multimodality
2024–2025 MMLU-Pro, LiveBench, LiveCodeBench, FrontierMath, Humanity’s Last Exam Difficulty, robustness, fresh questions
2025–2026 GDPval, BrowseComp, Terminal-Bench, ARC-AGI-3 Larger scope, closer to real use
What is evaluated Representative benchmarks What success means
Predicting text PTB, WikiText High probability for text that actually occurs
Giving the right answer MMLU, GSM8K, GPQA, HLE Matches the reference answer
Giving a preferred response Arena, AlpacaEval, MT-Bench Rated well by people or a judge model
Writing code that runs HumanEval, LiveCodeBench, SWE-bench Passes executable tests
Completing interactive tasks WebArena, OSWorld, τ-bench, Terminal-Bench The environment reaches the required state

On metrics: early work used perplexity (how “surprised” a model is by text it has not seen; lower is better), accuracy or F1, and preference win rate. Capability is measured with pass@k (at least one of k runs passes) and pass^k (all k runs pass, introduced by τ-bench). Cost is mostly LLM spend; tool calls and the extra cost of cache misses are often overlooked. Latency is not just the model’s latency either.

A benchmark run: for each task, reset the environment to its initial state; while the task is not done and the budget is not spent, observe the environment, let the agent pick an action from the instruction, observation, history and tools, and execute it; finally an evaluator scores the final answer, the final environment state and the whole trajectory.

Eight representative benchmarks

Benchmark Where the agent works Typical actions Scored on Notes
GAIA Web, files, code tools Search, inspect files, compute A short final answer 466 human-written questions at 3 levels (up to 5 steps, 5 to 10 steps, any length); scores the whole agent system; does not test actions like sending email or booking tickets
BFCL Function and API interfaces Structured function calls Calls, arguments and resulting state Checked by syntax-tree comparison or by execution; common errors are invented IDs (it should ask the user) and unnecessary calls; read the category scores, not the total
WebArena Self-hosted websites Click, type, navigate Website or backend state 812 tasks across shopping, admin, Reddit, GitLab, maps and a wiki; the agent sees the page’s accessibility tree (a structured list of page elements); the Verified version drops the LLM judge for deterministic checks on recorded HTTP requests
OSWorld A full desktop virtual machine Mouse, keyboard, application actions File, application and system state 369 tasks; the agent sees screenshots; OSWorld 2.0 (2026) has 108 long workflows, often over an hour, with about 27 checkpoints for partial credit
SWE-bench A software repository View, edit, run tests Whether the patch passes the tests Variants: Verified (human-checked), Lite (300 problems), Multilingual (9 languages), Multimodal, Pro (harder, multi-file)
τ-bench A customer-service API and dialogue Talk with the user, call APIs Database state and replies The user is played by an LLM and the agent must follow an airline’s policy; reward is the action score times the reply score; read-only calls may differ from the reference, but one extra write is a failure
Terminal-Bench An isolated terminal container Any shell command Task-specific verification tests Programming, operations, data processing, model training, security and scientific workflows; TB 2.0 has 89 tasks, TB 4.0 has 66 after dropping maxed-out ones, with an 8-hour timeout per task
TheAgentCompany A simulated software company Use web apps, write code, talk with colleagues Process checkpoints and final state 175 tasks across software, project management, data science, HR and finance; partial credit = 0.5 × share of points + 0.5 × whether fully completed

Terminal-Bench sits between SWE-bench and OSWorld: the agent acts through a shell in a container and reads terminal output, with tasks ranging from configuration and debugging to repair and building. There is no guessing where to click, so it tests long-chain reasoning and interaction with systems. pass^k is far stricter than pass@k: it needs every one of k independent runs to succeed, while pass@k needs just one.

Why evaluation is hard

Training leakageThe question or its human fix appears in the training data
Leakage during evaluationThe agent searches the web and copies a fix published “in the future”
Environment leakageThe sandbox exposes later commits or hidden tests
Overfitting to the benchmarkPrompts and scaffolding were tuned again and again on the public test set

An agent’s performance is roughly a joint product of the LLM, prompt, scaffold, tools, retriever, memory and environment, and any of them can carry the answer in: fine-tuning used benchmark answers as example trajectories; the retrieval corpus indexed the answers; memory holds earlier attempts; researchers tuned the system by studying failures again and again. So “the model was not trained on the test set” is far from enough. Evaluating agents needs real tools, and real tools open more routes for leakage.

The full instruction up front. Most benchmarks give one complete instruction: prompt in, final state out, with no user in between. Real work is vague, gets revised and is interrupted. This format rewards confident guessing, because asking a clarifying question costs steps and earns nothing. Three things should also be tested: does it ask when the goal is unclear; does it replan when corrected mid-task; does it remember constraints across turns?

Other challenges: success rate alone is not enough (200 steps for $40 and 12 steps for $0.30 both count as “success” but are not comparable); results are random, so one run’s score is noise; nothing penalizes deleting files, sending email or spending money along the way; judging only the outcome lets lucky or unsafe runs through, while demanding the reference trajectory penalizes reasonable alternative paths.

Frontier models reach the baseline ever faster

Months from benchmark release until a frontier model reached the marked baseline

  1. GLUE (2018) · human 87.114 months
  2. MMLU (2020) · expert 89.839 months
  3. GPQA Diamond (2023) · PhD expert 69.710 months
  4. SWE-bench Verified (2024) · 33% → 95%22 months
  5. ARC-AGI-2 (2025) · average human 6011 months
  6. ARC-AGI-3 (2026) · 0.5% → 62.7%6 months
Original lecture notes

Benchmarks get maxed out quickly. As of September 2026, SQuAD, GLUE, SuperGLUE, MMLU, MATH, HumanEval, Chatbot Arena, MT-Bench, WebArena, SWE-bench Verified, GPQA Diamond, MMMU and OSWorld are saturated; FrontierMath, Humanity’s Last Exam, ARC-AGI-2/3, Terminal-Bench, GDPval, SWE-bench Pro, Remote Labor Index and OSWorld 2.0 are not. Saturated means the strongest models have reached the human baseline, or the top models can no longer be told apart.

Dimension Then The frontier now
What is evaluated The foundation model Model, prompt, tools and harness together
Interaction Static, one shot Stateful, long-running
Grader Exact match or likelihood Tests, environment state, people or judge models
Dataset Fixed, public Fresh, hidden, generated or contamination-resistant
Main metric Average accuracy Beyond success: reliability, quality, cost, latency
Main concern Still right on new questions Finishing robustly under real constraints and safety requirements
Judging real-world agents means weighing capability, usability, cost and speed together. One method ranks by Pareto dominance: A dominates B if A is no worse on every metric and better on at least one; the set nobody dominates is the Pareto frontier and ranks first.

Putting it to work

  1. 01Build a private exam from your own work: pick real tasks that have a reference answer or can be checked automatically (figures match the source table, all fields present, tests pass). Keep it unpublished and never tune prompts on it; use it only to compare versions of agents, models or prompts.
  2. 02Run each question several times and record both pass@k and pass^k. For work you need to rely on, pass^k is what counts; an occasional success means little.
  3. 03Record cost, steps, time and any out-of-bounds action (deleting files, sending outside, spending money) on every run, not just right or wrong; compare options the Pareto way, on quality, cost and speed together.
  4. 04Add a few deliberately vague questions to see whether the agent asks first, and a few that change requirements midway to see whether it replans.
  5. 05Don’t take vendors’ benchmark scores on trust: a benchmark may be saturated or leaked, so retest on your own tasks with your own exam.

Self-check

A task is run independently 4 times and succeeds once. How do pass@4 and pass^4 come out?

Self-check

What is each benchmark scored on?

GAIA
SWE-bench
τ-bench
OSWorld

08CHAPTER 8

Agent design V: cost, speed and harness architecture智能体设计 V:降本、提速与 harness 架构

Key points

  1. Cost is users × sessions × turns × steps × tokens × price; the middle three fall with shorter trajectories, the price falls with caching, batching and routing.
  2. Cache reads make up the vast majority of tokens; any token left in context is paid for again at every later step.
  3. Every saving has a side effect, so measure the net effect on the same set of tasks and cap every task.
  4. Completion time is set by the critical path; harness architecture runs from monolithic to modular to microkernel as responsibility moves from code to services.

Two words first: a turn is one exchange between you and the agent; a step is one model call within a turn (usually with one tool call). A task’s LLM spend breaks into four multipliers:

01Turns per task
02Steps per turn
03Tokens per step
04Price per token

Fewer turns and steps

This chapter covers LLM spend only, not other compute costs.

Turn k rereads all k−1 earlier turns, so total cost grows with the square of the number of turns. Usage records from a group of coding-agent users showed that sessions ending after a single prompt made up 68% and 75% of two task sets, while a few sessions ran past 100 turns. Users come back with follow-ups because the agent had no plan, stopped early or never checked its result. The fixes: confirm the goal and plan before starting; split the task into subtasks that each carry a completion test; verify before delivering. The aim is a task finished without the user stepping in.

Most turns take only a few steps (mainly because reasoning effort was set to medium or high), though some approach 1,000. Every model call rereads the whole context, so fewer calls save money: merge independent calls into one step (read five files in one step, not five), reuse plans and skills that worked before, and read the files you need once at the start. Related research covers skill libraries (Voyager, SkillRL), distilled experience (ExpeL, ReasoningBank), cached plan templates and persistent conversation memory (Mem0, LightMem, SimpleMem). Reuse pays only when tasks recur; the cost of maintaining memory and stale entries can eat the savings.

Fewer tokens per step

97.6%Share of tokens that were cache reads in the first task set
208K / 301KMedian main-agent context per step (first / second task set)
~80KMedian subagent context per step; 90th percentile about 200K
1 : 10 : 50Typical price ratio of cache read, ordinary input and output

This is how caching saves money: for the opening part already processed in the last step, the provider has kept the intermediate results, so sending the same opening again is billed at a low cache-read price. In volume, output is about 5× smaller than new prefill written to the cache, and new prefill about 100× smaller than cache reads; context grows quickly, reaching 650K to 670K by about step 500. Any token left in context is paid for again at every later step.

Cut input How
Drop what is stale Truncate stale results; compact history; mask tool output already used; summarize old turns into a state
Shrink what comes in Compress observations, keeping errors rather than whole logs; save large outputs to a file and pass only the path
Load only what is needed Retrieve selectively, giving only relevant tools and memory; send exploration to a subagent that returns a summary

Related research: ACON cuts peak context by 26% to 54%; LLMLingua cuts tokens up to 20×, but compression pays only on long prompts; MemGPT manages context as fast memory; filtering MCP results with code takes 150K down to 2K; tool search cuts tool-definition tokens by 85%, and calling tools in batches from code cuts 37%. TRACE found that summaries cause rework.

Cut output: state length, format and what to skip in the prompt (“under 100 words”, “return only JSON”, “don’t restate the question”); set a maximum output length in the API (this can cut an answer mid-sentence, and reasoning alone can use up the limit); ask for structured output with only the needed fields (enums limit the allowed values, and any text around a tool call is pure cost); and tune reasoning effort per step (low for lookups and formatting, high for planning and debugging). Note that very strict formats can hurt reasoning.

Lower the price

Caching plus batching cuts input price to 5% of base

Price multiple relative to base input tokens, Claude API

  1. Output tokens5×
  2. Base input tokens1×
  3. Batch input0.5×
  4. Cached input0.1×
  5. Batch plus cached input0.05×
Anthropic public pricing, original lecture notes

Batching hands requests that are not urgent to the provider to queue and process later, in return for a lower price. In practice: keep the prefix stable (leave the system prompt, tool definitions and early history alone so the cache hits), and send work that can wait through batch (evaluations, backfills, bulk jobs). Model routing takes three forms: choose up front (a router trained on preference data, which can also assign agent roles, as in RouteLLM and MasRouter); escalate on failure (a cheap model first, a larger one when a check fails; the check can be a trained scorer, self-verification or actual execution results, as in FrugalGPT, AutoMix and EcoAssistant); and re-route each step (on history and budget, with an orchestrator calling models as tools, as in ToolOrchestra). The hard part: one planning mistake by a cheap model can waste many later steps. At the systems level there is a further set of ways to lower price: MoE (chapter 9), quantization, pruning, distillation and fine-tuning for the specific workload; speculative decoding, KV-cache optimization and better scheduling; faster kernels and specialized accelerators.

Every saving has a side effect

Technique Side effect
Compaction Dropped files must be reread later, and a summary changes the prefix and breaks the cache
Routing A cheap model’s bad plan adds steps or causes failure
Subagents Each one rereads the shared files and instructions
Speculation Wrong guesses waste tokens and compete with normal calls for the same tools

Net savings are total savings minus side effects, measured together on the same tasks. Cap every task (for example: $10, 80 model calls, 15 minutes of tool time, at most 2 retries per step). Stop when verification passes, when N steps pass with no newly passing test, when the same error repeats or when a cap is hit, and hand over with a summary. Caps can be set at twice the 95th-percentile usage of successful tasks. A task that stops with a summary is far cheaper than one that runs away.

  1. 01Same steps every time: have the LLM write a script once, then just run the script
  2. 02Fixed input format: regexes, parsers and templates cost nothing per call
  3. 03Narrow range of labels or scores: train a small classifier
  4. 04Fixed workflow with little reasoning: script the workflow and call the LLM only at the step that needs reasoning

Faster agents

Completion time is set by the critical path (the longest chain of dependencies), not the sum of every step. Faster is usually cheaper, but not always: a small model may take more steps, and parallelism spends more tokens.

Faster LLM servingEvery cost technique above also cuts latency: fewer turns, steps and tokens, faster serving
Better orchestrationAsynchronous execution (start the next step while a tool runs); persistent sessions (keep the same shell or browser open across steps); streaming and pipelining (start tool calls before the model’s reply is finished); co-locate services
Faster toolsBuilds, tests and page loads can be slower than model calls: cache tool results, move heavy computation to a server, use faster tools, set timeouts on calls that might hang; measure tool time per step before tuning the model
ParallelismIssue several independent tool calls in one step; send independent subtasks to parallel subagents and merge their summaries; shared state needs a merge step
Speculative actionsA cheap model predicts the next action and runs it while the main model thinks; a right guess saves the wait, a wrong one is thrown away at the cost of one call; best when guesses are usually right and actions can be undone

Speculation ranges from the next tool (SPORK), tool plus arguments (PASTE) and any action, up to multiple branches (B-PASTE) and whole executed chains. Predictions can come from a model (a small model drafts), self-speculation (an early branch of the same model) or history (past trajectories: PASTE learned that a search is usually followed by opening a page, so it takes the URL from the search result and opens it early). The open question: with limited GPU, CPU and API budgets, how should speculative calls be scheduled so the critical-path time saved exceeds the work wasted?

Optimization is a loop: run and record every call, token, tool and wait; measure where cost and latency go; change one thing at a time (compaction, routing, caching or parallelism); re-evaluate success, spend and 95th-percentile latency on the same tasks; repeat.

Putting it to work

  1. 01Start with the structure of the bill: if your agent shows tokens and spend per session, look at how they split. If cache reads dominate, the context is too long, so cut input first; if new writes are high, the prefix keeps changing, so stabilize the system prompt and instruction file first.
  2. 02Say everything at once: goal, constraints, acceptance criteria and files to read in one request, to avoid back-and-forth. Every extra turn rereads everything before it.
  3. 03Send unimportant exploration and log reading to a subagent or small model; use a large model with high reasoning effort for hard steps such as planning and debugging, and low effort for formatting and lookups.
  4. 04Set caps for each kind of task (money, calls, time, retries); when a cap is hit, stop and hand over a summary rather than letting it run on.
  5. 05Have the agent turn recurring, fixed-step work into a script and run the script from then on; leave only the step that truly needs judgment to the model.
  6. 06Change one thing at a time (switch on compaction, say, or a new routing rule), compare success, spend and time on the same tasks, then decide whether to keep it.

Three harness architectures

Dimension Monolithic Modular Microkernel
Design principle Everything integrated in one runtime Abstracted behind interfaces, one controller A minimal kernel; everything else is an outside service
Swapping components Hard Easy (Docker to Firecracker means changing one implementation) Easy if the protocols match
Execution isolation Optional Optional An architectural focus
Deployment Usually together Together or separate Usually independent
Independent scaling Limited Possible Strong
Communication overhead Low Low to medium Can be higher
Typical use A standalone agent Agent frameworks Multi-agent infrastructure
Strengths Simple to build and debug, state easy to share Clear responsibilities, testable, third parties can plug in Services scale independently, faults stay isolated, infrastructure can be shared
Weaknesses Tightly coupled, hard to share infrastructure The controller still owns the whole run, and coordination logic gets complex More ways to fail, harder end-to-end debugging, needs standard protocols

Take running a snippet of Python: the monolith runs it locally, with the fewest hops but weak isolation; the modular harness calls a uniform sandbox interface (such as SandboxProvider.run(code)), so you change the implementation without touching the agent; the microkernel sends a request to an execution service that handles allocation, isolation and the sandbox lifecycle. Responsibility moves from code to interfaces to services.

What is distinctive in seven harnesses

Harness Position What is distinctive
Codex CLI OpenAI, Rust Sandbox first, approval second: commands run in a sandbox with no network and ask for approval only to leave it; the patch format is constrained by a Lark grammar and change blocks are matched in four passes
DeepSeek Harness TypeScript Even the loop is a plugin, replaceable through a YAML configuration layer; each request is a frozen snapshot of the session log, which the harness only appends to; edits are compare-and-swap, so an edit fails if the file changed since the model last read it
OpenCode TypeScript, Bun The harness is a server, and the terminal UI, SDK and web client share one OpenAPI interface; nine replacers run from exact to anchor matching and reject overly fuzzy wide matches; a shadow git repository snapshots every step so undo can restore files
Pi TypeScript A minimal kernel of four tools, with no MCP, subagents or approvals; sends cache keep-warm requests only when the expected saving is at least $0.05; pi-ai supports 42 model providers and 10 protocols
oh-my-pi TypeScript plus Rust Hashline edits locate text by a 4-hex-digit file tag plus line number, so the model need not retype old text; one resident shell, with native search, syntax tree, LSP and debugger; snapcompact compresses old history by turning it into images
OpenClaw TypeScript A gateway to 27 chat channels with one queue per session; before compacting it quietly writes a dated note, and recall combines full-text and vector search; fences isolate untrusted text, reading anything from the network marks the turn as tainted, and planted sentinels watch for leaking secrets
Hermes Agent Python A background branch reviews recently prompted turns and then edits memory and skills; it starts compacting at 50% of the window, the earliest of these; before any action with side effects it writes the tool call to a session database

Self-check

What is the side effect of each saving?

Dropped files are reread and the summary breaks the cache
A cheap model’s bad plan adds steps or causes failure
Each one rereads the shared files and instructions
Wrong guesses waste tokens and compete for the same tools

Self-check

On the Claude API, with batching plus caching, input tokens cost about what share of the base input price?

09CHAPTER 9

LLM basics: the life of a request and the transformerLLM 基础:一次请求的生命周期与 Transformer

Key points

  1. A request passes through six stages: tokenize, schedule, prefill, decode, detokenize and stream.
  2. Prefill is compute-bound and sets how long the first token takes; decode is bandwidth-bound and sets how many tokens per second follow.
  3. The KV cache per token sets how many requests one GPU can serve at once; GQA brings Llama 3 70B down to 320 KB per token.
  4. An MoE model’s memory follows its total parameters, while its compute follows only the parameters active per token.
01Tokenize
02Schedule
03Prefill: sets time to first token
04Decode and sample: sets tokens per second
05Detokenize
06Stream

The six stages

  • Tokenize. Text is split into tokens, not words; in English a token averages 3 to 4 characters, and “Serving is hard” is 4 tokens. Token count sets cost and memory, and tokenizers differ, so the same text has different token counts in different models. Byte-level BPE, the common method, starts from the 256 byte values and repeatedly merges the pair of adjacent pieces that most often occur together into a new token, so any text can be split and there are no “unknown characters”. A larger vocabulary means fewer tokens for the same text but a larger embedding table to store it.
  • Schedule and batch. Requests arrive one by one, but a GPU is efficient only on batches. Continuous batching lets requests join or leave at any step instead of waiting for a full batch; how many can be admitted is limited by the memory the KV cache takes.
  • Prefill. The whole prompt goes through the model at once, with attention computed for all prompt tokens in parallel; it is compute-bound, so longer prompts are slower and costlier; it builds the KV cache and emits the first token.
  • Decode and sample. Every new token after that needs a full pass through the model, and the KV cache grows by one token per step; it is bandwidth-bound, so many requests are batched together, and when memory runs short some requests are paused or queued. Sampling picks the next token from the raw scores the model gives every candidate (logits), and the settings change both the answer and how long it runs (table below).
  • Detokenize and stream. Each token ID is turned back into text and sent as soon as it is produced, holding back partial characters; generation ends on a stop token, the length limit or a dropped connection, and stopping early frees the cache.
Sampling setting Example Effect
temperature 0 At 0 it always picks the top score; above 1 more tokens get a chance and answers wander more
top-k 50 Sample only from the k most likely; k is fixed
top-p 0.9 Sample from the fewest tokens whose probabilities add up to p; the more confident the model, the fewer candidates

The transformer

01Token IDs
02Embedding: each ID becomes a vector of 8,192 numbers
03Transformer blocks × 80: self-attention plus FFN
04LM head: one score for every token in the vocabulary
05Softmax: probabilities for the next token

A model is a stack of identical transformer blocks. The input is a sequence of integer token IDs; the embedding layer turns each ID into a vector (8,192 dimensions in Llama 3 70B). The vectors pass through L blocks (80 in Llama 3 70B), each with self-attention (tokens exchange information) and a feed-forward network, the FFN (each token is transformed on its own). Finally the LM head scores every token in the vocabulary and softmax turns the scores into probabilities that add up to 1.

Every block normalizes, computes, then adds back: RMSNorm, then attention, with the result added to a trunk running through the whole model (the residual stream); then RMSNorm, the FFN, and the result added back again. RMSNorm scales values to a stable range by their root mean square, with one learnable gain per dimension; normalizing first (pre-norm) keeps very deep stacks stable in training; the residual stream runs through all 80 blocks, and each layer only adds a small update.

Self-attention lets every token read all the tokens before it. Each token produces three vectors, a query Q (what am I looking for), a key K (what do I have) and a value V (what I can contribute), by multiplying the input X by three weight matrices. The dot product of Q and K divided by √dₖ decides how much to read from each token; the division is there because dot products grow with dimension, and without scaling softmax would lock onto a single token. A causal mask fills everything above the diagonal with −∞ so a token cannot see what follows; softmax makes each row’s weights add up to 1; the output is a weighted mix of the V vectors. n tokens produce n² scores, and each layer costs about 4n²d FLOPs (floating-point operations). Storing the full score matrix S for 8,192 tokens, 64 heads and 80 layers would take about 690 GB; FlashAttention computes softmax in tiles and never stores S.

Step Formula Shape
Input X n × d
Query Q = X W_Q n × dₖ
Scores S = Q Kᵀ ÷ √dₖ n × n
Weights A = softmax(S + M) n × n
Output O = A V n × dᵥ

Multi-head attention splits Q, K and V into 64 heads of 128 dimensions, runs masked attention in each, and mixes them with Wₒ. 64 × 128 = 8,192, so the compute equals one wide head; splitting changes the patterns the model can learn (some heads watch the previous token, some the first token, some the neighborhood, some the whole text), not the cost.

The KV cache and shared KV heads

The KV cache stores the K and V of every token already read so the next step need not recompute them. Its size per token = 2 (K and V) × layers × KV heads × head dimension × bytes per number. In MHA every query head has its own KV; GQA lets several query heads share one set of KV; MQA has all query heads share one. With 8 query heads the three give 1×, a quarter and an eighth of the KV cache. Llama 3 70B’s 64 query heads share 8 sets of KV: 2 × 80 × 8 × 128 × 2 B = 320 KB per token, against 2.5 MB with MHA.

Llama 3 70B parameter Value
Model width d 8,192
Layers L 80
Query heads H and head dimension dₖ 64 and 128
KV heads Hₖᵥ 8
FFN hidden width 28,672 (3.5 × d)
Vocabulary V 128,256

Most of Llama 3 70B’s parameters are in the FFN

Parameters, billions, by component

  1. Attention (80 layers)12.1B
  2. FFN (80 layers)56.4B
  3. Embedding and LM head2.1B
Meta, The Llama 3 Herd of Models (2024), computed from the published architecture

Attention is about 151M parameters per layer and the FFN about 705M; 80 layers make 68.5B, and embedding plus LM head bring the total to 70.6B. The chart’s attention and FFN totals are the per-layer figures times 80.

Estimating from a systems view

141 GBWeights (BF16, 2 bytes per parameter)
141 GFLOPsCompute per generated token (about 2 × parameters)
320 KBKV cache per token

On 2 H200s (1,978 TFLOP/s of compute, 9.6 TB/s of bandwidth and 282 GB of memory between them), an 80,000-token prompt takes about 9.95 s of prefill and 167 GB for one request; 64 requests at once need 637 s and 1,779 GB. As context grows, attention compute grows with n² and the KV cache grows linearly with n, which is why long context is hard.

MoE: memory follows total parameters, compute follows active ones

MoE (mixture of experts) replaces the FFN in each block with a router and a set of smaller “expert” FFNs; each token goes to only a few of them (say 2 of 8), and their outputs are added by weight.

Model Experts Total parameters Active per token Weights (BF16)
Llama 2 70B All (dense) 69B 69B 138 GB
Mixtral 8x7B 2 of 8 46.7B 12.9B 93 GB
Llama 3.1 405B All (dense) 405B 405B 810 GB
DeepSeek-V3 9 of 257 671B 37B 1,342 GB

DeepSeek-V3 activates only 37B parameters per token

Active parameters per token, billions; compute per token (GFLOPs) is about twice this

  1. Llama 2 70B69B
  2. Mixtral 8x7B12.9B
  3. Llama 3.1 405B405B
  4. DeepSeek-V337B
Jiang et al. 2024; DeepSeek-AI 2024; Touvron et al. 2023; Llama Team 2024

Less compute at similar quality: Mixtral matches Llama 2 70B with about a fifth of the compute; DeepSeek-V3 matches Llama 3.1 405B with about an eleventh, but needs 1.7× the memory.

Putting it to work

  1. 01If the agent is slow to show the first word, the prompt is probably too long (slow prefill); if words come out slowly, the output is probably too long or the service busy (slow decode). Cut context for the first; cap output length and ask for brevity for the second.
  2. 02The same text has different token counts in different models, so compare prices by counting tokens on your own sample text, not by the unit price alone.
  3. 03For tasks that must be stable and repeatable (extracting fields, classifying, converting formats), set temperature to 0 or close to it; raise it for divergent work such as drafting or brainstorming. Even at 0, results are not guaranteed identical (chapter 1).
  4. 04Before self-hosting an open model, estimate memory with this chapter’s formulas: weights are about parameters × 2 bytes (BF16), plus KV cache per token × context length × concurrent requests.
  5. 05When choosing an MoE model, remember that it computes fast and is cheap per token, but its memory must cover all its parameters, so it is not easy to host.
Further: eight advanced variants
Variant How Effect on serving
Sliding window Local layers see only the last w tokens, and a few global layers handle long-range recall (Gemma 3 has 5 local layers per global one, w = 1,024; Mistral 7B is all local, w = 4,096) At 128K context, Gemma 3’s KV is about a sixth of an all-global model’s
Multi-head latent attention (MLA) Each token caches one compressed vector, from which K and V are rebuilt when needed DeepSeek-V2 has 93% less KV cache than DeepSeek 67B and 5.8× the generation throughput
Linear attention A fixed-size state updated as tokens are read; Gated DeltaNet decays the old state before writing (Qwen3-Next pairs 36 GDN layers with 12 attention layers, and Kimi Linear and Qwen3.5 also run 3 to 1) Three quarters of the layers keep only a constant-size state per request
State-space models A small state per channel whose decay depends on the token (Mamba’s selective mechanism; Mamba-2 recasts it as matrix multiplication) No growing KV cache; Mamba reports up to 5× a transformer’s generation throughput
Sparse attention A light indexer scores past tokens and each query reads only the top 2,048 (DeepSeek-V3.2) Compute per token is capped, but KV for every token must still be stored
Looped transformer The same block is reused K times Extra depth adds compute and latency but no weights
Multi-token prediction Predict several tokens at once The original material only names it
Diffusion language models Mask the positions to be generated, then fill them in over a few parallel refinement steps (LLaDA 8B, Dream 7B) One pass fills several tokens, but fewer steps mean lower quality

Self-check

Which stage is bound by memory bandwidth and sets how many tokens per second come out?

Self-check

Llama 3 70B has 80 layers, 8 KV heads and head dimension 128, in BF16. About how large is its KV cache per token?

10CHAPTER 10

GPU basics: why decode is bandwidth-boundGPU 基础:为什么 decode 受带宽限制

Key points

  1. A GPU trades a few fast cores for thousands of simple ones, and hides the wait for memory by switching between thread groups (warps).
  2. Every compute program (kernel) is bounded by three things: peak compute, memory bandwidth and memory capacity; the “ridge point” on a roofline chart separates the two kinds of bottleneck.
  3. Decode serving one request at a time uses 0.5% of an H200’s peak compute; batching helps, but the attention part of decode stays bandwidth-bound.
  4. Compute grows faster than bandwidth in each new GPU; raising real bandwidth means keeping more bytes on the way at once.

GPU vs CPU

64-core server CPU NVIDIA H200 SXM
Parallel units 64 cores 132 SMs (streaming multiprocessors), 16,896 FP32 cores
Threads running at once 270,336 (2,048 per SM)
Memory bandwidth About 0.46 TB/s (DDR5) 4.8 TB/s (HBM3e)
Peak dense compute About 5 TFLOPs FP32 989 TFLOPs BF16
How it hides latency Caches, out-of-order execution Switch to a warp that is ready

A CPU is a sports car, fastest for two people; a GPU is a convoy, slower per trip but carrying thousands at once. LLMs suit GPUs because every token does the same matrix multiplication on the same weights.

  • Warp switching hides the wait for memory. A warp is 32 threads that execute together on a GPU. While one warp waits on memory, another issues instructions, so the compute units stay busy. Each SM on A100, H200 and B200 has 4 warp schedulers managing up to 16 warps each, 64 resident warps in all.
  • SIMT (single instruction, multiple threads). One warp instruction drives 32 threads, paying for fetch, decode and scheduling once, which does the work of 32 ordinary instructions.
  • Branch divergence. When threads in a warp take different sides of an if, the two paths run one after the other; if f uses 8 of 32 lanes and g uses 24, part of the lanes sits idle in each.
What the GPU gives up What it gains
Single-thread speed (modest clocks, no speculation, so serial code is much slower) Chip area and power spent on thousands of arithmetic units
Parallelism must be spelled out by the programmer (about 270K threads fill 132 SMs, and small jobs leave the chip idle) Latency hidden by switching warps rather than by caches and speculation
Shared control flow (threads in groups of 32, so divergence costs throughput) One fetch and decode drives 32 cores
Little on-chip storage per thread (about 240 bytes at full occupancy) Every thread’s state stays resident, so switching warps costs nothing

Three numbers and the roofline

Memory bandwidth rises each generation, but more slowly than compute

HBM bandwidth, TB/s; Rubin figures are preliminary

  1. 2 TB/sA100
  2. 4.8 TB/sH200
  3. 8 TB/sB200
  4. 22 TB/sRubin
NVIDIA datasheets, original lecture notes
A100 H200 B200 Rubin
Peak BF16 compute (how fast the math runs) 312 TFLOP/s 989 TFLOP/s 2,250 TFLOP/s About 4,000 TFLOP/s
Memory bandwidth (how fast weights and KV cache are read) 2.0 TB/s 4.8 TB/s 8 TB/s About 22 TB/s
Memory capacity (how much weight and KV fits) 80 GB HBM2e 141 GB HBM3e 180 GB HBM3e 288 GB HBM4

Compute is the engine, bandwidth the fuel line, capacity the tank. A kernel takes about the larger of “bytes to read ÷ bandwidth” and “operations to do ÷ peak compute”.

Decode, one request at a time: compute waits for data

  • 3.3 ms per token
  • Reads 16 GB of weights from memory
  • Each weight is used once, so 0.016 ms of math waits on 3.3 ms of reading
  • Tensor cores idle 99.5% of the time

Prefill, 2,048 tokens: compute is busy

  • 33 ms per prompt
  • Memory reads go quiet once the weights are in
  • Each weight serves 2,048 tokens, so compute sets the speed
  • 33 TFLOP, close to peak

The roofline model finds the bottleneck from arithmetic intensity: how many operations are done per byte moved from memory (FLOPs ÷ bytes). The ridge point is peak compute ÷ bandwidth, about 206 FLOP/B on an H200. Below the ridge a kernel is bandwidth-bound (speed = bandwidth × intensity); above it, compute-bound (speed = peak).

Operation Arithmetic intensity (b = bytes per element)
Vector add, length N 1/(3b)
Matrix times vector (GEMV, the main operation in decode), N × N, each weight used once About 2/b
Decode attention, each KV entry used once per head 2/b
Square matrix times matrix (GEMM), each element reused about N times 2N/(3b)

Decode for one request at a time is a GEMV at about 1 FLOP/B, which on an H200 reaches only about 5 of 989 TFLOP/s, 0.5% of peak. Higher utilization needs higher arithmetic intensity: bigger batches, quantization (storing weights in fewer bits) and less KV traffic. Batching pushes the weight GEMV toward the ridge (intensity 256 at batch 256), but decode attention stays at 2/b, because every request reads its own KV.

As context grows, most bytes read per decode step come from the KV cache

Total bytes read from memory per decode step, GB; Llama 3 8B, batch 16, BF16; weights fixed at 16.1 GB

  1. 18.2 GB1K
  2. 24.7 GB4K
  3. 33.3 GB8K
  4. 50.5 GB16K
  5. 84.8 GB32K
Computed from the Llama 3 paper and the H200 datasheet, original lecture notes

Here the KV cache is 128 KiB per token and grows with batch and length; at 4.8 TB/s a step goes from 3.8 ms at 1K of context to 17.7 ms at 32K. Lower precision pushes the ridge further right: Rubin’s dense NVFP4 needs about 1,600 FLOP per byte to be compute-bound. From A100 to Rubin, BF16 compute grows about 13× and bandwidth about 9×, so kernels are increasingly bandwidth-bound.

Inside the H200

The H200 has 132 SMs sharing a 50 MB L2 cache and 141 GB of HBM3e memory (6 stacks, 4.8 TB/s), linked to other GPUs over NVLink at 900 GB/s. Each SM has 4 partitions, each with 64 KB of registers, 32 FP32 cores and a tensor core, issuing one warp instruction per cycle; the SM shares 256 KB of L1 cache and shared memory and holds 2,048 resident threads.

A tensor core is a unit built for small matrix multiply-adds: one instruction computes D = A × B + C (say 16×16 by 16×8), so one mma is 2,048 multiply-adds, 64× the work of an ordinary multiply-add instruction (FMA). Matrix multiplication is over 99% of LLM compute; softmax and normalization use the ordinary FP32 cores. Tensor cores are fast for four reasons: fewer instructions per operation; dedicated multiply-add circuits; operand reuse (one value of A serves many columns, one value of B many rows); and low precision (FP16, BF16, FP8), which raises throughput and shrinks the data, usually with results accumulated at higher precision.

Storage level (H200) Capacity Latency (Hopper) Bandwidth
Registers 256 KB per SM In the pipeline Read directly by each instruction
Shared memory / L1 256 KB per SM About 30 cycles (L1 hit about 40) 128 B per cycle per SM, about 33 TB/s across 132 SMs
L2 cache 50 MB About 250 cycles About 12 TB/s on Hopper
HBM3e memory 141 GB, 6 stacks About 500 cycles 4.8 TB/s
Host memory and other GPUs Microseconds NVLink 4 at 450 GB/s each way; PCIe 5.0 about 64 GB/s

Memory is a 250-nanosecond pipe

Little’s law: bandwidth = bytes on the way ÷ latency. A simply written kernel keeps about 4 KB on the way per SM and reaches 2.2 TB/s, 45% of peak; filling 4.8 TB/s needs about 9 KB per SM (4.8 TB/s × 250 ns ÷ 132). The hardware fixes the pipe’s length, so the only way to raise bandwidth is to put more bytes in it: 16-byte vector reads, four independent reads per thread at once, and bulk asynchronous copies (TMA).

H200 (Hopper) B200 (Blackwell) Rubin
Memory 141 GB HBM3e 180 GB HBM3e 288 GB HBM4
Bandwidth 4.8 TB/s 8 TB/s 22 TB/s
Bytes needed on the way, whole GPU 1.2 MB 2.0 MB 5.5 MB
Bytes needed on the way, per SM 9 KB 14 KB 25 KB
New data-path features TMA, clusters TMEM, 2-SM MMA Inline TMA descriptors

Further detail: coalescing merges 32 threads’ consecutive 4-byte reads into one 128 B request; 16-byte vector reads let one warp instruction move 512 B; cp.async (Ampere and later) copies into shared memory without passing through registers; Hopper’s TMA lets one thread start a whole block copy, putting tens of KB on the way from one instruction, and TMA multicast delivers one L2 read to every SM in a cluster of up to 8 thread blocks; Blackwell keeps results in 256 KB of tensor memory, freeing registers for more reads, and pairs two SMs on one matrix multiplication, each fetching half of the shared block.

From one GPU to many

HGX H200 (8-GPU node) GB200 NVL72 (whole rack)
Makeup 8 GPUs linked by NVSwitch, 8 × 400 Gb/s network cards to the outside network 4 GPUs plus 2 CPUs per tray, 9 trays linked by NVLink switches
Memory bandwidth 4.8 TB/s 8 TB/s
NVLink 900 GB/s 1.8 TB/s
RDMA (direct memory access across machines) 50 GB/s 100 GB/s

From G80 (2006) to B300 (2025), peak compute grew about 43,000× and bandwidth only about 90×. The twenty-year arc runs from graphics to general-purpose computing (CUDA, caches, HBM2, NVLink, tensor cores) and on to low-precision AI engines (TF32, BF16, FP8, TMA, FP4, TMEM, NVL72).

Putting it to work

  1. 01When reading a GPU’s or an inference service’s specs, don’t look only at compute (TFLOPs). For LLM generation, especially when serving few requests at once, speed is set mostly by memory bandwidth, and the model size and context length you can fit are set by memory capacity.
  2. 02The longer the context, the more KV must be read for every generated token, and the slower generation gets. Stuffing a very long context into an agent costs speed at every step, not just money.
  3. 03When you host a model yourself, the main levers on speed and cost are batching requests (use an inference framework with continuous batching), quantizing the weights and shortening context. A single request with a GPU to itself leaves almost all of its compute idle.
  4. 04To estimate the best-case generation speed: every token must read all the weights at least once, so weight bytes ÷ memory bandwidth is the lower bound on time per token for one request. For example, 16 GB of weights at 4.8 TB/s takes about 3.3 ms.
  5. 05Compute grows faster than bandwidth in each new GPU, so optimizations that lower precision and cut data movement will matter more and more; when choosing models and services, check whether they support low precision and KV compression.
Further: other accelerators
Chip Traits Programming
AMD MI355X 8 compute chiplets that software sees as one GPU; 256 MB Infinity Cache; 64-thread groups (wavefronts); 5.0 PF dense FP8, 288 GB, 8 TB/s ROCm and HIP; PyTorch, vLLM and SGLang run; Triton or Composable Kernel
Google TPU Ironwood Weight-stationary systolic arrays in a 3D torus network of 9,216 chips; 4.6 PF dense FP8, 192 GB, 7.4 TB/s JAX or PyTorch/XLA; Pallas for custom kernels
Amazon Trainium3 8 NeuronCores per chip, each with tensor, vector and scalar engines; 32 MB of software-managed SRAM per core, no hardware cache; 2.5 PF MXFP8, 144 GB, 4.9 TB/s Neuron SDK; NKI moves data blocks explicitly from Python; no CUDA
Cerebras WSE-3 A whole wafer as one chip, 44 GB of on-chip SRAM, no off-chip memory Larger models must stream weights in while computing
Groq LPU 230 MB SRAM, no off-chip memory An 8-bit 70B model needs about 300 chips
Microsoft Maia 200 272 MB SRAM plus 216 GB HBM3e Available only inside Azure

Self-check

When an H200 runs decode for one request at a time, what share of its peak compute does it use?

Self-check

What limits each operation on an H200?

Square matrix times matrix, N = 8192
A one-request GEMV
Decode attention
Prefill of 2,048 tokens

∞SOURCES

Further reading and notes on sources

  • This handbook is compiled from public lecture material and the papers, technical reports and vendor documents it cites. To go deeper on a topic, start with these primary sources: ReAct (arXiv 2210.03629); Liu et al., “Lost in the Middle” (TACL 2024); Chroma’s Context Rot tests; Breunig, “How Contexts Fail” (2025); Lewis, “Same Model, Different Harness” (arXiv 2608.26218); Anthropic, “Building a C compiler”; OpenAI’s Codex report and internal usage report (June and September 2026); Meta’s Llama 3 paper; NVIDIA whitepapers and datasheets; and each benchmark’s original paper.
  • Charts are redrawn from the values in the source material, with the source under each chart; “original lecture notes” marks figures given there without an earlier source. The attention and FFN totals for Llama 3 70B are the per-layer figures times 80; every other value is as given in the sources.
  • The “Putting it to work” section in each chapter is practical advice written from that chapter’s content and adds no data beyond the source material.
  • Product names appear only for specific case studies, data sources or tool lists; general agent mechanisms are described in general terms, so check your own agent’s documentation for exact commands and file names.