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 对应 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、花费、耗时和是否做成。比较两个 agent 或两种提示时,看的是这几个数,而不是谁回得快。
  3. 03遇到慢或贵的任务,打开 agent 的运行日志或追踪记录,把它展开成一步步的工具调用,先找最慢、最贵、重复最多的那一步,再动手优化。
  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)
用途 规范、工作流程、架构 偏好、纠正、项目背景

项目说明文件是 agent 每次启动都会读的一份 Markdown 文件,具体文件名和位置看你所用 agent 的文档。它通常分四层,按范围从大到小加载,越具体的越晚读取、越优先:组织策略(不能被个人关掉)、个人全局设置、项目文件(随代码库一起共享给团队)、本地个人文件(只给自己,不进版本库)。

应写进项目说明文件

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

不该写进去

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

每个文件控制在 200 行以内,用 Markdown 标题和列表,规则写具体,不要自相矛盾。太长时按主题拆成多个规则文件;如果你的 agent 支持给规则标注适用路径,就只在它碰到匹配文件时才加载。

自动记忆由 agent 自己写,通常每条标注一种类型:user(你的角色与偏好)、feedback(你纠正过或确认过的做法)、project(进行中的工作、代码里看不出来的决定)、reference(项目之外的资料在哪里)。一个索引文件列出所有条目,每次只加载开头一部分;具体主题的文件只在相关时读取。多数 agent 都提供几类命令:浏览、编辑或关闭记忆;查看当前加载了哪些说明文件;自动生成说明文件初稿;检查说明文件里有没有不该放的内容。

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

工具与四种扩展机制

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

用哪个工具由模型决定。想让 agent 做更多事,有四种扩展机制:

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

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

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

Skill 是一个文件夹:一份说明文件(名称和简介决定 agent 何时想到用它,正文写流程),加上参考资料和脚本。会话开始时只加载简介,真正执行时才加载正文。它可以由模型自己调用(简介和任务对得上时),也可以由你用一条斜杠命令点名调用。会产生副作用的流程,最好要求点名调用;各个 skill 的简介写清楚、彼此不重叠,能减少用错。本质上 skill 是在管理上下文。

MCP(Model Context Protocol,模型上下文协议)用统一的协议连接外部服务:GitHub、数据库、监控、Figma、Slack、浏览器等。一次调用分六步:agent 判断需要一个动作;MCP 客户端调用工具;MCP 服务器处理连接;外部服务执行操作;结构化结果返回;agent 评估结果。它用起来和本地工具几乎一样,只是运行在另一个进程里。

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 网关是 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 拿到需求就开始写代码,靠反复试错修正;装上它之后,流程变成:

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 格式互转

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

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

三种扩展方式

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

手动并行。 git worktree 是同一个代码库的多个工作目录:每个有独立的文件和分支,共享提交历史,彼此不碰文件,不用暂存改动,也不用再克隆一份。很多 agent 都支持一条命令为每个会话建一个 worktree,例如一个做支付功能、一个修登录 bug。开三个会话时,人还能记住整体计划;开到二十个,就需要一个「自己的分身」:计划只在人脑里,会话彼此看不见,分支要人来合并,过程没有记录、没法重跑。

子智能体 是有独立上下文、工具和权限的专门助手,用途有五:保护主上下文不被冗长内容塞满;限制可用的工具和模型;在多个项目间复用;并行;控制成本(例如用小模型)。自定义子智能体通常是一个 Markdown 文件,开头写名称、简介、可用工具和模型,正文就是它的系统提示,放在项目或个人的配置目录里。子智能体可以再派生子智能体,但层数有上限,2 至 3 层最合适;子智能体自己要有「委派」工具才能再派生。

常见的内置子智能体 用途
探索型 只读搜索代码库,不能写和改,每次调用可设定查得多彻底
计划型 在计划阶段做调研,让探索过程留在主窗口之外
通用型 既要探索又要动手的复杂多步任务

探索型和计划型为了快和省,会跳过项目说明文件和 git 状态。调用方式按控制力从弱到强:

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

Agent 团队(部分 agent 提供,通常是实验功能)由一个负责人和多个队友组成:负责人派出队友、协调并汇总;每个队友是一个独立的 agent 实例;大家共享一张任务列表,自己认领;每个 agent 有一个邮箱,队友之间可以直接通信。队友不继承对话历史,但会自动加载项目说明文件和 skill。适合多角度审查、彼此独立的模块、几种假设同时排查的调试、前后端跨层开发;有先后顺序的任务、改同一个文件、依赖很重的工作,应改用单个会话或子智能体。

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

动态工作流 是在后台用脚本编排大量子智能体,适合全库排查 bug、500 个文件的迁移、需要交叉核对的调研、多角度做计划。

长时运行。 一种做法是「目标模式」:交出一个可验证的终态,比如「代码检查命令以零错误退出」,评估器在每次尝试后复查,满足条件或用完最大尝试次数时停止。「所有集成测试通过」可以当目标,「重构代码」不行,因为没法自动判断完成没有。另一种是「定时循环」:每隔一段时间重复同一条提示,例如每 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 都卡在同一个 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 是给 LLM 的提示(自然语言)。判断一件事该用 1.0、2.0 还是 3.0 的方式做,是一项重要的工程能力。

不确定性并不新鲜:硬件(32 位与 64 位、字节顺序)、环境(并发、不可靠的网络)、软件(编译器版本、依赖悄悄升级)早就存在,2.0 时代的应对是固定宽度的数据类型、内存一致性模型、可以安全重试的接口、升级前做全面测试。3.0 又多了几种:GPU 计算本身的非确定性与浮点差异、生成代码时直接改动环境、采样的随机性,以及一句话提示本身的含糊。不确定性分布在五层:自然语言(意思可能理解偏);检索与上下文(检索结果变了、索引更新了、内容被截断);模型生成(采样、软硬件的非确定性);agent 与工具循环(工具失败、环境变化);生成的程序(生成后通常是确定的,除非它运行时还会调用模型或工具)。

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

不要指望 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 年上半年活跃用户增长 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 月)

委派阶梯从低到高是:聊天机器人(AI 回答,人干活)、助手(人和 AI 一起做)、agent(人把一整块工作交出去)、多 agent 协作者(人协调多个 agent)、系统化工作流(由 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. 窗口太大时依次用准入、卸载、变换三种手段,让 LLM 做摘要压缩是最后一招。

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 能做的 agent 都能做。设计时要想清楚:隔离(在哪里运行、能碰到什么);失败信号(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 的基准:给出代码库和问题描述,看它的补丁能否让测试通过。

从提示工程到目标工程

时期 名称 问题 关注
2023–2024 提示工程 怎样指示模型 措辞、示例、输出格式
2025–2026 上下文工程 模型应该看到什么 检索、记忆、历史、压缩
现在 harness 工程 agent 应该怎样运行 循环、工具、沙箱、重试、停止
下一步 目标工程 什么算成功 目标、标准、约束、取舍
提示技巧 做法 何时用 何时换下一种
零样本 只给指令 任务常见,格式能用文字说清 规则说不清时,用少样本
少样本 指令加几个示例 输出形状特殊,规则不如示范好懂 需要步骤时,用思维链
角色与人设 给一个角色 语气或判断标准重要,受众特定 需要步骤时,用思维链
思维链 先写推理步骤,最后给答案 任务确实有步骤,错误来自跳步 有多条路径时,用思维树
思维树 分出几条思路、各自打分、剪掉差的 多条路线都可行,打分便宜 只有一个正确答案时,用自洽
自洽 同一问题多次回答后投票 有唯一答案且答错代价高;票数不够(如 3/5)时转人工 能分阶段时,用提示链
提示链 每次调用只做一件事,交接前检查 工作分阶段且每段可检查;哪段不合格只重试哪段 在调提示本身时,用元提示
元提示 让模型改写自己的提示 有一套评测题能打分 收益停滞时,回头重审选择

四条通用原则:从简单开始,按需加上下文;分区写(上下文、指令、工具、输出要求分开,按「指令、分隔符、数据」排列);具体而简洁,花哨措辞没有用;大任务拆小,不要一开始就堆复杂度。提示的写法因模型而异,换模型就要重新调;有些老技巧对新模型已经没用。

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

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 增至 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、偏好胜率。能力用 pass@k(跑 k 次至少一次通过)和 pass^k(跑 k 次全部通过,由 τ-bench 提出)。成本主要是 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 次独立运行全部成功,后者一次成功就算。

评估为何困难

训练泄漏题目或它的人工修复出现在训练数据里
评估时泄漏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读缓存、普通输入、输出的典型价格比

缓存是这样省钱的:上一步已经处理过的开头部分,服务方存下了中间结果,下一步再发同样的开头时只收很低的「读缓存」价。数量上,输出约比新写入缓存的 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 里设最大输出长度(可能把答案截在半句,而且推理本身就可能把额度用光);要求只含必要字段的结构化输出(用枚举限定可选值,工具调用周围的说明文字都是纯成本);按步骤调整推理强度(查找、格式化用低,规划、调试用高)。注意,格式卡得太死可能损害推理。

压低单价

缓存加批处理可把输入单价降到基础价的 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 次);在验证通过、连续 N 步没有新测试通过、同一个错误反复出现或碰到上限时停下,并附一份摘要交接。上限可以设为成功任务第 95 百分位用量的 2 倍。带着摘要停下来的任务,比失控的任务便宜得多。

  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 是约 1 FLOP/B 的 GEMV,在 H200 上只能用到 989 TFLOP/s 中的约 5,也就是峰值的 0.5%。要提高利用率,就得提高算术强度:批次更大、量化(用更少的位数存权重)、减少 KV 的读取量。批处理能把权重那部分的 GEMV 推近脊点(batch 256 时强度为 256),但 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 算,一步从 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 与其他 GPU 以 900 GB/s 相连。每个 SM 分成 4 个分区,各有 64 KB 寄存器、32 个 FP32 核和一个 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 核。它快的原因有四:每次运算需要的指令更少;有专用的乘加电路;操作数复用(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 字节一次的向量读取;每个线程同时发出四个互不依赖的读取;用批量异步复制(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 B 请求;16 字节向量读取让一条 warp 指令搬 512 B;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),峰值算力增长约 43,000 倍,带宽只增长约 90 倍。二十年的主线是:从图形处理转向通用计算(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;用 NKI 在 Python 里显式搬运数据块;没有 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.