先试一试 · 入门探针
入门探针|OpenHands 团队实测了 1,500 个真实 session 的 token 构成:平均每个 session 消耗 77,922 tokens。其中占比最大的成分是?
本讲地图
点击卡片下钻详解增长账单:上下文为什么会失控
循环的代价是复利:第 1 次调用 6K token,第 5 次累计 80K;1,500 个真实 session 实测平均 77,922 tokens,工具结果独占 37%。注意力平方增长、KV 缓存线性显存与中间遗忘三个约束,共同决定长程任务必须管理。
入门5 分钟#contextL3 p.3-5 ↗
Lost in the Middle:位置与长度双重衰减
相关信息放在中间利用率明显偏低,性能呈 U 形;Context Rot 用 18 个模型×8 种长度×11 个位置约 19.4 万次调用复证:把 haystack 打乱,全体模型升分。位置效应是 todo.md 贴末端这类工程对策的直接动机。
入门8 分钟#contextL3 ↗
RAG 还是长上下文
资源充足时长上下文平均优于 RAG,但贵得多;Self-Route 先按 RAG 试探、模型自省不足再升级长上下文,效果损失很小、成本大幅下降。两条车道按任务画像分工,外部记忆还附带跨会话复用与可审计性。
进阶7 分钟#ragL3 ↗
缓存经济账:前缀复用的价差
缓存读价格普遍只有全价输入的十分之一量级:Kimi K3 缓存读 $0.30 vs 输入 $3.00,DeepSeek 一档压到约三十分之一。设计纪律是稳定前缀+追加状态:换模型、改 effort、增删工具、时间戳扰动都会整段作废。
进阶9 分钟#cachingL3 p.38-44 ↗
上下文压缩:留下什么,扔掉什么
24K 行 CI 日志压成 GOAL/CAUSE/VERIFIED/EVIDENCE/NEXT 五行检查点;KEEP/ENCODE/尾部保留/EXTERNALIZE/DISCARD 五分法与 Trigger→Select→Replace→Recover 四步,再加对反复压缩漂移的防御:压缩是设计问题,不是摘要问题。
进阶8 分钟#compactionL3 p.46-50 ↗
长上下文怎么评:四代基准
从大海捞针到 RULER、HELMET、NoLiMa:合成召回近乎饱和(Gemini 1.5 10M 内 >99%),可配置长度下 17 个模型近半数 32K 失效,深层语言理解 11/13 模型跌破基线一半。合成任务不预测下游,是这代评测的新共识。
进阶8 分钟#evalL3 p.51 ↗
架构速览:让窗口变大的五条路
Softmax→Linear→DeltaNet→Gated DeltaNet→KDA 五步演化梯子,回答「状态怎么写、怎么忘」;混合架构以 3:1~5:1 的局部:全局配比落地(个别更密),配 NoPE/插值/YaRN 与渐进长度的训练配方,百万窗口才真正可用。
前沿9 分钟#architectureL3 p.15-25 ↗p.28-35 ↗
外部记忆:MemGPT 到 Mem0
MemGPT 把上下文当内存、外部存储当磁盘,模型自主换页;Mem0 把长期记忆当数据库,LLM 显式决策 ADD/UPDATE/DELETE/NOOP 四操作。LongMemEval 提醒:商业助手在持续记忆上仍有约 30% 落差——远没到「解决了」。
进阶8 分钟#memoryL4 p.17-20 ↗
SKILL.md:写进文件的程序性记忆
技能是一组文件:YAML 元数据+正文+脚本,按渐进披露三层按需加载,整套索引常驻约 3K tokens。SkillsBench 实测 87 任务平均 33.9%→50.5%,但 13 个任务反被拖累,聚焦 1-3 个短技能增益更大。
入门8 分钟#skillsL4 p.8-15 ↗
技能库:从 Voyager 到自动归纳
从 Voyager 的代码技能库(独特物品 3.3 倍、科技树 15.3 倍)到 AWM/ASI/ReasoningBank 的自动归纳:judge 筛选、模板入库、失败复盘。技能要随用随修:淘汰不用的,防对一类有益、伤另一类。
进阶8 分钟#skillsL4 p.22-36 ↗p.38-43 ↗
伴读笔记
导语
你可能有过这种体验:开工那天桌面干干净净,三天后堆满打印稿、咖啡杯和缠成一团的数据线。桌面没有变小,可用的空地却越来越小,找任何东西都要翻一阵。Agent 的上下文窗口就是这张桌子。
第 1 讲说过,Agent 约等于大模型 + 工具 + 循环。任务跑得久,循环每转一圈都往桌上添点东西。
第 2 讲回答两个很现实的问题:桌子不够用了怎么办,这是 2a 的上下文管理;能不能把桌上的经验收进柜子、下次直接拿出来用,这是 2b 的技能与记忆。
本笔记对齐官方两份讲义:2a「Context Management for Long-Context Agents」(54 页)与 2b「Skills and Memory」(46 页)。页码随文以 slides L3 p.X/ L4 p.X 标注,L3/L4 即课程资料库中第 2 讲的两份讲义。
事实与数字只出自这两份讲义与本讲指定 readings。把它当成课前预习、课后消化用的地图,不是课程实录。
上下文是工作记忆:桌子会满,注意力会散
三个事实决定了长程任务必须做上下文管理。
第一,注意力的计算量随长度平方增长。标准自注意力:
其中 QK^T 是 n×n 的矩阵。输入长度翻倍,预填充(prefill)的计算量约翻四倍。
第二,推理时每个 token 都要留一份底稿,也就是 KV 缓存,字节数大约是:
L 是层数,h_kv 是 KV 头数,b 是每个元素的精度位数。缓存的目的是让解码不必重算历史,代价是显存占用随对话线性上涨。
第三,也是最伤人的:模型看得见,不等于用得上。Lost in the Middle 的实验显示,相关信息放在上下文开头或结尾时准确率高,放在中间时明显下滑,性能曲线呈 U 形。桌子越大,堆在中间被无视的东西就越多。
先看账单有多凶。课程的第一组数字:一个任务的第 1 次调用约 6K token,到第 5 次调用累计已 80K。历史线性累积,注意力的计算量却随长度平方增长,见 slides L3 p.3。
OpenHands 团队对 1,500 个真实 session 的实测更具体:平均 77,922 tokens,工具结果独占 37%,见 slides L3 p.4。完整构成解剖见增长账单篇。
换句话说,上下文的大头是工具回的,不是人说的。后面压缩与证据外置,优先下刀的地方也在这。
再看位置效应的机理与边界。StreamingLLM 发现开头少数 token 会承接超高注意力,也就是 attention sink,成为全序列的锚;靠保留开头加滑动窗口,就能把流式推理拉到 4M token、注意力计算快 22.2 倍(arXiv:2309.17453)。
Chroma 的 Context Rot 拿 18 个模型复证:退化同时来自长度与位置,把 haystack 打乱后全体模型升分,网格细节见 Lost in the Middle 篇。中间遗忘因此是当前注意力机制的普遍性质,不是哪个模型的怪癖。
课程在 slides L3 p.5 给了一张总地图。Capacity 一侧管架构、位置编码、训练,让窗口能更大;Efficiency 一侧管 attention 计算、KV 内存、缓存、压缩,让每一步更便宜。
前者主要是模型厂商的事,后者是 Agent 工程师每天要做的决策。这篇笔记两条线都会走,落点始终在后者。
管理三条路:清桌面、进柜子、上台账
工程上的解法大致三条,而且互补。
压缩:上下文逼近预算时,把旧对话总结成一份「状态笔记」,记当前目标、关键决策、未完成的待办,然后以笔记为新起点继续。
压缩是有损的。丢什么留什么是设计问题,任务目标与待办优先于闲聊细节。
外部记忆与检索(RAG):把完整历史放进外部存储,向量库、笔记、文件系统都行,每轮按需取回相关片段,桌面上只放正在用的。
MemGPT 用函数调用在上下文与外部存储间自主换页,完整隐喻见记忆的四个操作一节。
结构化管理:不指望模型每轮从头重读历史,而是让它自己维护显式状态文件,记待办清单、关键值、决策日志。相当于给秘书一个台账本:好秘书不靠脑子记事,靠本子。
三条路用伪代码串起来大概是:
while 任务未完成:
if 上下文超过预算:
state = 总结(目标, 决策, 待办, 最近 k 轮)
上下文 = [系统提示, 技能目录, state]
行动() # 需要旧细节时检索外部记忆
让 Agent 自己维护结构化状态文件,记目标、当前步骤、待办、已知事实,把状态文件当唯一真源、上下文只当缓存;压缩与检索都围绕这份台账展开,出错时一眼能看出它记错了什么。
RAG 还是长上下文
三条路里的进柜子 RAG,与把桌子做大的长上下文,常被当成二选一。实证的答案更细。
资源充足时,长上下文平均效果优于 RAG,但贵得多。Self-Route 先按 RAG 试探作答,模型自省检索是否足够、不足才升级长上下文,效果损失很小、成本大幅下降(arXiv:2407.16833)。
窗口本身的能力边界也在被推远,10M 级召回的数字见四代基准一节。
但窗口大与用得好之间有真实落差,RULER 与 NoLiMa 的失效数字也见四代基准一节。
工程结论:两条车道按任务画像分工,小任务走检索,大任务走长窗,边界任务让模型自己选。外部记忆还额外带来跨会话复用与可审计性,这是任何窗口都给不了的。
长上下文的经济账:KV 缓存与前缀缓存
既然已经有百万 token 级的模型,为什么不把全部历史直接塞进去?U 形衰减是一个原因,经济账是另一个。
主流推理平台普遍提供提示词缓存(Prompt Caching):本轮请求与上一轮共享相同前缀时,命中部分按大幅折扣计价,写入时收取小额溢价。
这对 Agent 设计的影响有三条。
- 前缀要稳定。系统提示、技能目录这类不变的内容放前面,易变的会话状态放后面。
- 压缩会毁缓存。清空历史意味着前缀变化、下一轮全价重算,压缩频率不只是技术决策,也是成本决策。
- 长上下文不豁免管理。窗口变大只是推迟桌子满掉的时间,注意力衰减与费用仍随长度增长。
桌子再大,也得收拾。
压得太勤丢信息又费钱,压得太懒预算先爆。
把账算细一点。一次请求的生命周期分两阶段:预填充决定首 token 延迟(TTFT),解码决定后续每个 token 的间隔(TPOT),见 slides L3 p.9。
缓存命中的本质,是把预填充的中间结果 KV 状态存下来复用,延迟与费用同时受益。Agent 既是缓存的最佳客户也是最大杀手:工具调用让相邻请求共享越来越长的前缀,Prompt Cache 论文(MLSys 2024,arXiv:2311.04934)与 slides L3 p.38-39 都有梳理;但任何前缀扰动都让整段作废。
服务端也在做工程。vLLM 的 PagedAttention 把 KV 缓存像虚拟内存一样分页管理,近零浪费,见 slides L3 p.41;SGLang 的 RadixAttention 把历史请求的前缀组织成基数树,新请求沿树 match/split/evict,再配缓存感知路由把同类任务调到同一副本,见 slides L3 p.42-43。
价差有多悬殊,见 slides L3 p.40,单位是美元 / 1M tokens:
| 模型 | 缓存读 | 输入 | 输出 |
|---|---|---|---|
| DeepSeek V4 Flash | 0.007-0.014 | 0.22-0.44 | 0.66-1.32 |
| Kimi K3 | 0.30 | 3.00 | 15.00 |
| Claude Opus 5 | 0.50 | 5.00 | 25.00 |
价目截至 2026-09 讲课当周,厂商调价频繁,以官方定价页为准;其余模型与全表见缓存经济账篇。
对请求组装,设计纪律是稳定前缀 + 追加状态,见 slides L3 p.44。系统提示、工具目录、技能索引这类不变的内容放最前;易变的会话状态、时间戳、随机数永远以追加的方式放末尾。
两家定价可对照着记:Anthropic 提示词缓存写入收 1.25 倍、命中读只要 0.1 倍(最低 512-4096 token、4 个断点、TTL 内命中即刷新);OpenAI 的自动缓存同样是 1.25x/0.1x(最低 1024、默认 30 分钟)。
对照 Claude Code 的缓存失效清单更直观:中途换模型、改 reasoning effort、增删一个 MCP 工具、compact 重写历史,任何一个动作都意味着下一轮全量重算。
Manus 团队甚至把 KV 缓存命中率列为生产 Agent 最重要的单一指标,并把 todo.md 计划持续重写到上下文末端:既贴着生成点,也占了 U 形曲线的高注意力位。
最贵的 token 不是新增的,是重算的。100k 会话里动一次前缀,等于把 100k 从一折打回全价,请求组装代码里每一个看起来无害的字段顺序,都是钱。
压缩与检查点:留下什么,扔掉什么
先看 slides L3 p.46 的一个案例。编码 agent 排查 CI 超时,工具读回 24,000 行日志,上下文瞬间见底:直接摘要会丢证据指针,全量保留则下一步就没预算。课程的解法是把它压成一份结构化检查点:
GOAL: 修复 CI 超时(方案已验证:--workers=1)
CAUSE: 测试并发抢端口,日志报 "address already in use"
VERIFIED: --workers=1 本地跑通
EVIDENCE: 3 个失败构建的日志工件路径 + 定位命令
NEXT: 开 PR 提交修复
五行,每一行都有分工。
- 目标与根因:行为保真的锚。
- 验证过的事实:防止重复试错。
- 证据路径:把 24K 行日志外置成可回源文件。
- 下一步行动:让压缩后的上下文立即可用。
课程在 slides L3 p.48 把它一般化为五分法:
- KEEP EXACT 锚点。目标、约束、关键决策的原文,一个字不改。
- ENCODE。中段过程性内容编码成检查点。
- KEEP EXACT 近期尾部。最近若干轮原样保留,报错与最新观测往往就在尾部。
- EXTERNALIZE。大块证据移入外部存储,上下文里只留路径与索引。
- DISCARD。与目标无关的内容直接扔。
落成流程是四步,slides L3 p.49:Trigger 定何时触发,常见 token 阈值或输出余量;Select 定保护什么、压什么;Replace 定用什么形态替换;Recover 定怎么回源。
好的压缩状态要过三条性质检验,见 slides L3 p.47:行为保真,即后续决策不变样;有界,即大小可控;可恢复,即能回到原始证据。
还有一个隐蔽的坑:反复压缩的漂移,见 slides L3 p.50。第 k+1 次压缩的输入,往往是第 k 次压缩的输出加上新内容,误差逐轮滚雪球;公式与 CUDA 版本号一路磨损的例子见上下文压缩篇。
漂移的根源是摘要成为下一次摘要的输入。锚点内容永远从原文复制;检查点定期用原始历史重写一遍,别让第 N 手转述冒充事实。
长上下文怎么评:四代基准
第一代是大海捞针,needle in a haystack:在长 haystack 里藏一根针看召回。Gemini 1.5 在 10M 内召回 >99%,这一代已近饱和(arXiv:2403.05530)。
第一、二代之间有一条复证线:Lost in the Middle 的 U 形与 Context Rot 的网格证明,退化不只来自找得到找不到,还来自放在哪、有多长,细节见 Lost in the Middle 篇。
第二代是 RULER:把有效长度参数化,17 个模型近半数在 32K 处失效(arXiv:2404.06654)。
第三代是 HELMET:用 7 类任务测 59 个模型,结论是合成任务成绩不预测下游(arXiv:2410.02694)。
第四代是 NoLiMa:要求不做显式字符串匹配的推理关联,11/13 模型在 32K 跌破基线 50%,GPT-4o 从 99.3 掉到 69.7(arXiv:2502.05167)。
课程自己的取向是「基于延续的评测」,见 slides L3 p.51:让模型在真实长会话上继续做事,比拼行为保真。
给工程师的启示:别拿厂商的大海捞针图当采购依据,拿你自己任务的最长会话做延续测试。
长上下文架构速览:让窗口变大的五条路
这一节抬头看模型侧:窗口是怎么变大的。公式记不住没关系,记住各家模型在权衡什么就行,选型与提示设计都用得上。
演化梯子:状态怎么写、怎么忘。
标准 Softmax 注意力保留全部历史 KV,精确但平方增长;滑动窗口把 压到 ,但局部层够不到远处,见 slides L3 p.18。
真正的演化主线,是把注意力改写成固定大小的状态加循环更新,五步走完,见 slides L3 p.19-23:
每步修上一步的什么,公式与配比见架构速览篇。
这五步回答的都是同一个问题:有限状态里,什么该留、什么该忘、怎么忘。
混合架构:3:1 到 5:1 的分工。
纯线性状态会丢长程细节,纯 Softmax 又太贵,主流做法是混合:多数层用线性注意力或 Mamba 类 SSM 压状态,少数层保留全局注意力收长程依赖,局部: 全局大约 3:1~5:1(个别更密,如 Kimi K3 约 2.9:1),见 slides L3 p.15-16:
| 模型 | 局部层机制 | 全局层机制 | 局部: 全局 |
|---|---|---|---|
| Qwen3.8-Flash-Next | Gated DeltaNet | QSA | 36:12 |
| Kimi K3 | KDA | dense Gated MLA | 69:24 |
| Nemotron 3 Ultra | Mamba-2 | GQA | 48:12 |
全表与逐模型配比见架构速览篇,表内 QSA、Gated MLA 等缩写以 slides L3 p.15-25 为准。DeepSeek-V4-Pro 则用 128-token 窗口的交错分支做类似分工。对使用者的含义:别假设窗口等于均匀注意力,长程信息最好在提示里复述或外置,别赌那少数全局层替你记住。
顺带两个省显存的旁支。稀疏注意力分固定模式与内容相关 TopK 两族,后者一旦选择器漏选 key 就丢信息,见 slides L3 p.24;GQA 共享 KV 头,MLA 缓存潜在向量按头重建,见 slides L3 p.25。
位置编码:从绝对坐标到不编码。
早期用绝对正弦位置。RoPE 的关键性质是注意力分数只依赖相对位移。NoPE 干脆不加位置编码,顺序信息由因果掩码的动态推断补上,Kimi K3 就是 NoPE + 循环 KDA,见 slides L3 p.28-32。
外推从位置插值 到 YaRN 的频率选择性插值加温度修正,见 slides L3 p.32-33。插值就是把位置除以 压回训练范围。
扩展路径各家不同:Qwen 从 262K 原生配 partial RoPE + YaRN 推到 1M,GLM-5.3 原生 1M、NoPE 无需重缩放,DeepSeek V4 走 4K→16K→64K→1M 的渐进,见 slides L3 p.33。
训练配方:窗口大不等于用得好。
让长窗口真正可用靠数据:先做 4-8K 的短预训练,再在 32-128K 上继续训练,最后做可到 1M 的长适应,见 slides L3 p.34-35。
长上下文数据四类里最有信号的是「答案依赖远距证据」的构造。Kimi K3 用清洗文档与视频,把跨全上下文的证据排列成子任务;GLM 系用仓库 /issues/PR/diff 加 agent 轨迹,从 32K 渐进到 200K。
共同配方是连贯长源、答案依赖远距证据、渐进长度。这也解释了为什么合成大海捞针满分不等于真实任务好用 —— 上一节的四代基准正是证据。
技能与记忆:把情节沉淀为程序
认知心理学把记忆分几层,恰好能对上 Agent 的工程组件:工作记忆 = 上下文,情节记忆 = 会话日志与总结,语义记忆 = 沉淀出的用户偏好与事实条目,程序性记忆 = 怎么做的知识,也就是技能。
技能就是沉淀好的程序性记忆。以 Anthropic 的 Agent Skills 为例,一个技能是一个文件夹:SKILL.md 的 frontmatter 写 name、description 与 when_to_use,正文写操作指引,旁边可以挂脚本与参考文件。
加载分三层渐进披露:启动时只把所有技能的名称与描述放进系统提示,每个只占几十个 token;判断相关才读入正文,真正需要时再打开挂载的文件。像公司的 SOP 手册:目录常备案头,正文放柜子里,用到哪本取哪本。
记忆的另一半问题是读写策略:什么时候写、写什么、怎么读。写的时机常见的是会话结束或反思触发,写的内容要在蒸馏后的事实与原始日志之间选。
Generative Agents 给了个经典打分,按相似度、新近度与重要性的加权和检索:
还有一个常被忽略的点:遗忘是特性不是缺陷。只增不减的记忆库迟早把检索质量拖垮,记忆也需要垃圾回收。
三个更新位置与三类经验
2b 的开场是两个购物任务:把 Sony 耳机加进心愿单,查无线键盘的价格区间。开头几步的搜索流程一模一样,只有收尾动作不同:怎么搜是可复用的,买什么才是每次新的,见 slides L4 p.2。
由此带出三个问题:
- Representation:经验怎么表示。
- Induction:怎么归纳。
- Lifecycle:怎么维护。
三问不会一次答完:表示这一节先落地,归纳与生命周期两条线索由后面的技能库一节收口。
表示先看更新发生在哪,slides L4 p.3 给了三个位置。
- 窗口内。保真最高,但贵、噪,随压缩消失。
- 外部工件。文件、技能库、记忆库,可检查、可编辑、可检索、可移植,工程上的主战场。
- 权重。SFT 进参数,最持久也最贵。
经验本身分三类,见 slides L4 p.4:Episode 是这次会话发生的具体轨迹,Fact 是可复用的世界知识,Skill 是可复用的行动模式。
课程还给了 memory 与 skill 的分界,见 slides L4 p.5:memory 来自自身交互,偏向知道什么;skill 是如何行动的可复用知识。
来源上既可以人写,也可以 agent 自学,见 slides L4 p.6。后面技能库一节会看到,自学路线已经跑通。
记忆的四个操作:从 MemGPT 到 Mem0
外部记忆系统一脉相承。更早的 Reflexion 用语言反馈修正下一次尝试,经典的 White Plains 战役问题,反馈「答案应给出所属 campaign」之后第二次就答对了;轨迹检索一族 ExpeL、Synapse、Agent S、ICAL 把相似历史轨迹嵌入检索作 few-shot,见 slides L4 p.19-20。
MemGPT 把上下文当内存、外部存储当磁盘,模型用函数调用自主换页(slides L4 p.17;arXiv:2310.08560)。Mem0 把粒度细化到事实条目,LLM 对记忆做四个操作:ADD/UPDATE/DELETE/NOOP,见 slides L4 p.18。检索出的旧记忆与新信息冲突时,做的是显式决策,不是无脑追加。
效果有数:LOCOMO 基准上,Mem0 相对 OpenAI 的记忆方案准确率高 26%,相对全上下文方案 p95 延迟降 91%、token 省 90% 以上(arXiv:2504.19413);同代的 Zep 用时序知识图谱,LongMemEval 上最高 +18.5%、延迟 -90%(arXiv:2501.13956)。
LongMemEval 本身值得记住:五能力考察下,商业助手在持续记忆上仍有约 30% 的落差(arXiv:2410.10813)。记忆系统远没到「解决了」的程度。
SKILL.md:写进文件的程序性记忆
最朴素的起点是一个真实痛点:同一份 spec,每个 PR 都要重复粘贴进提示,见 slides L4 p.8。解法是把怎么做从提示词搬进文件。
技能就是一组文件:SKILL.md 的 YAML 元数据(name/description/when_to_use)加操作正文,旁边挂 scripts/references/assets,见 slides L4 p.9。
加载走渐进披露三层,slides L4 p.9-10:元数据常驻 <available_skills> 索引,触发相关才载入正文(课程讲义示例 agent Hermes 的实现是 skill_view 工具),用到才读捆绑文件。
slides L4 p.11 有成本实测:一个技能的索引项只要几十 token,整套索引在 Hermes 例子中约 3K。SKILL.md 正文按需载入;脚本执行只把输出回灌,代码本身不进上下文;references 再按需。
值不值得?SkillsBench 用 87 个真实任务 ×8 域 ×18 配置给出目前最系统的答案,见 slides L4 p.12-13:平均 33.9%→50.5%,条件与 13 个反例见 SKILL.md 篇。
拖累的机理不复杂:技能描述挤占注意力,与模型默认策略打架。
slides L4 p.14 把来源分三类:官方捆绑、人写安装、agent 自建。OpenHands 的建议很具体:刚完成一个想复用的工作流,就立刻创建技能,再测几次。
维护也可以成环:slides L4 p.15 里,OpenHands 在自家仓库用模型裁判统计人类对技能的采纳率,归纳复发原因并修订。技能库像代码一样有 review 与迭代。
顺带一提生态。Claude Code 的技能规范给同样精神定了硬约束:description 与 when_to_use 合计 1536 字符,SKILL.md 少于 500 行,上下文压缩时每技能保留 5K、全部技能合计 25K tokens。
Agent Skills 已有开放标准(agentskills.io),数十家客户端支持。写技能正在变成一门有 lint 的手艺。
文本技能还是代码技能
文本技能是自然语言写的 workflow,如 AWM 归纳出的带 {变量} 模板,胜在灵活、可读、易改;代码技能是可执行函数,胜在可执行、可测试、可组合,见 slides L4 p.29。
差距有多硬?ASI 的实验:无记忆基线要 50 步的任务,装上代码技能 4 步完成,见 slides L4 p.32;WebArena 五站的达成率与步数全面单调改善,逐组数字见技能库篇(slides L4 p.33)。
机理不神秘:一次函数调用替代多步模型推理,把确定性流程从每次现场推理变成一次写好、反复执行。
但代码技能硬编码了环境假设:sort_listings 在多数站点好用,到 Target 却因打开侧栏而脆断,见 slides L4 p.34。
对策如 PolySkill,一个接口、多个站点实现,见 slides L4 p.35;归纳侧 ASI 用 judge 双问把关:终态正确吗、技能真的用上了吗,SkillWeaver 则让候选技能先过练习场、由 reward model 打分才准入,见 slides L4 p.30-31。
选型直觉:环境稳定、流程确定,选代码技能;环境多变,选带变量的文本模板,或一个接口多实现。
技能库:从 Voyager 到自动归纳
程序归纳的谱系从 Voyager 说起:GPT-4 生成代码技能、环境反馈验证、存入可检索可组合的技能库。Minecraft 里独特物品 3.3 倍、科技树解锁快 15.3 倍,技能还能迁移到新世界(arXiv:2305.16291)。
后续 DreamCoder/Stitch/LAPS/LILO 把程序归纳加压缩做成主线,在线归纳的累计成功率一路爬升,见 slides L4 p.22-24。生命周期统一为 LEARN/USE/MAINTAIN,slides L4 p.25:学是归纳入库,用是检索执行,养是修订淘汰。
自动归纳还有两条线:一个走文本模板,一个从失败里攒策略(代码线的 ASI 上一节已见)。
AWM 用 judge 先验证轨迹成功,再 few-shot 归纳出带 {变量} 的 workflow 模板入库,后续任务检索复用,越用越准呈复利(slides L4 p.26-28;arXiv:2409.07429)。
ReasoningBank 从成败轨迹归纳策略级记忆,多数轨迹是失败;失败对策略记忆帮助大,对轨迹 /workflow 记忆帮助小 —— 记教训,别记流水账。附录案例即一次死路:搜索返回 5,578 条结果、每页 12 条,翻到步数上限也没把答案发出去(slides L4 p.38-39;arXiv:2509.25140)。
它还有两条反直觉:裁判不必完美,准确度在宽区间内都有效(slides L4 p.40);检索不是越多越好,过度检索反而掉分(slides L4 p.41)。
治理工具也在跟上。TroVE 淘汰使用次数低于 ½・log₁₀(n) 的函数;「Not All Skills Help」提醒技能会厚此薄彼,对一类任务有益可能伤另一类,见 slides L4 p.42;SAGE/AgeMem 干脆训练一个技能归纳器,用成功复用当奖励,成功率 55.4%→60.7%,见 slides L4 p.43。
最后一课是所有权,见 slides L4 p.45:哪些记忆决策给人、哪些给 agent。人有判断力与责任,agent 有规模与一致性,各有各的份额。
主题导读
导读分两组:第 1-6 篇是围绕两个主题的自选深读;第 7-11 篇是官方 2b 指定的六篇 readings 里还没收录的五篇(MemGPT 已在第 5 篇),补作短导读。
主题一:上下文管理
-
Lost in the Middle: How Language Models Use Long Contexts(Liu et al., 2023) 问题:上下文窗口变大了,模型真的用得好位置信息吗?做法:在多文档问答与键值检索任务中,把含答案的文档放到上下文不同位置做受控实验。结论:性能呈 U 形,开头结尾好、中间差;局限是实验设置偏合成,且只诊断问题不给解法。它把窗口大不等于用得好从直觉变成定量事实,所有上下文管理的工作都从这里出发。 https://arxiv.org/abs/2307.03172
-
LLMLingua: Compressing Prompts for Accelerated Inference of Large Language Models(Jiang et al., 2023) 问题:提示词里的 few-shot 示例与长指令冗余而昂贵。做法:用小语言模型给 token 打困惑度分,在预算内丢弃低信息 token,粗到细两级压缩。结论:最高 20 倍压缩、多项任务损失很小;局限是压缩比对任务与格式敏感,对代码这类精确格式要求高的内容要保守。它确立了提示词是可压缩对象的视角,Agent 的历史压缩可直接借鉴。 https://arxiv.org/abs/2310.05736
-
Effective Context Engineering for AI Agents(Anthropic 工程博客,2025) 问题:一线实验室如何系统性地做「上下文工程」。做法:把上下文窗口当作稀缺资源,类比 RAM,梳理了压缩、结构化笔记、即时检索与子代理隔离等机制。结论:核心原则是用最小的高信号 token 集合达成目标;局限是工程经验之谈,没有受控实验。值得读:Claude Code 的自动压缩、CLAUDE.md、子代理等机制在这里有第一手阐述。 https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
主题二:技能与记忆
-
Voyager: An Open-Ended Embodied Agent with Large Language Models(Wang et al., 2023) 问题:不微调模型,Agent 能否在开放世界持续学习。做法:GPT-4 生成「代码即技能」,环境反馈验证后存入可检索、可组合的技能库,配自动课程驱动探索。结论:在 Minecraft 中比基线多拿 3.3 倍独特物品、科技树解锁快 15.3 倍;局限是依赖稳定的代码接口与环境反馈,跨游戏 / 跨环境迁移难(同款游戏内新世界可迁移)。它是可执行、可验证、可检索复用三件事合一的技能范本。 https://arxiv.org/abs/2305.16291
-
MemGPT: Towards LLMs as Operating Systems(Packer et al., 2023) 问题:上下文有限而任务数据无限。做法:借操作系统的分层内存思想,让模型通过函数调用在主上下文与外部存储间换页,并自我编辑记忆。结论:在超长文档问答与多会话对话上明显优于直接塞上下文的基线;局限是依赖模型的指令遵循能力,自我编辑写错了就一路错下去。上下文即内存,是 Agent 记忆领域最有影响力的思想实验。 https://arxiv.org/abs/2310.08560
-
Equipping Agents for the Real World with Agent Skills(Anthropic 工程博客,2025) 问题:如何把专长打包给 Agent,且不撑爆系统提示。做法:技能 = 文件夹 + SKILL.md,内含 name/description、指引正文与可选脚本,三层渐进披露按需加载。结论:与 MCP 互补,MCP 连接外部工具,Skills 沉淀工作流知识;局限是描述写得好坏直接决定技能会不会被启用。值得读,SKILL.md 已是事实标准,配套示例库开源,读完即可上手写自己的技能。 https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
官方指定读物(2b readings)
-
OpenHands: How to Create Effective Agent Skills(Michelini & Neubig,2026) 问题:技能文件到底怎么写才有效?要点:从「同一 spec 每个 PR 重复粘贴」的痛点出发,给出 SKILL.md 写法与渐进披露的实证建议 —— 刚完成想复用的工作流就立刻创建、聚焦少数短技能、测几次再收。适合当操作手册读,与 SkillsBench 的结论互为印证。 https://openhands.dev/blog/20260227-creating-effective-agent-skills
-
SkillsBench(arXiv:2602.12670) 问题:加技能到底有多大用?要点:87 个真实任务、8 个领域、18 种配置的系统评测,平均增益显著但 13 个任务反被拖累,结论与边界条件见 SKILL.md 篇。技能的收益是有条件的,这份基准把条件量了出来。 https://arxiv.org/abs/2602.12670
-
Agent Workflow Memory(AWM,arXiv:2409.07429,ICML 2025,Zora Wang) 问题:工作流经验怎么自动沉淀?要点:judge 先验证轨迹成功,再 few-shot 归纳出带 {变量} 的 workflow 模板入库,后续任务检索复用 —— 归纳出的 workflow 越用越多,呈复利。文本技能自动化的代表作。 https://arxiv.org/abs/2409.07429
-
Agent Skill Induction(ASI,arXiv:2504.06821,COLM 2025) 问题:技能能不能让 agent 自己写?要点:从成功轨迹归纳可执行代码技能,judge 双问把关:终态正确吗、用了技能吗;WebArena 上代码技能单调领先无记忆与文本技能(数字见技能库篇),一次调用替掉多步推理,代价是跨站脆断要留适配层。 https://arxiv.org/abs/2504.06821
-
ReasoningBank(arXiv:2509.25140,ICLR 2026) 问题:失败经验值钱吗?要点:从失败轨迹归纳策略级记忆,按任务相似度检索(附录案例即一次 5,578 条搜索结果的死路翻页);失败对策略记忆帮助大,对轨迹与 workflow 帮助小,记教训比记流水账有用,且过度检索反而掉分。 https://arxiv.org/abs/2509.25140
完整资料库见本讲资料区。
实践视角
站主的 SecondPal 是本地优先的桌面 Agent,PalWave 是它的移动终端,这个形态同时考到本讲的两个主题。
观察一:失败模式常见的是记错,不是记不住。桌面 Agent 连续工作四十分钟,一次压缩把某个关键文件名弄丢了,之后每一步都自信地走在错误路径上。
解法是先让 Agent 自己写结构化状态文件,记目标、当前步骤、待办、已知事实,再做压缩。状态文件是唯一真源,上下文只是缓存。这与 Anthropic 工程博客说的结构化笔记不谋而合。
观察二:本地优先往往意味着小模型、紧预算,技能恰好是省 token 的手段。把怎么做沉淀进 SKILL.md 文件而非系统提示,系统提示保持极简。
再把系统提示与技能目录放在前缀最稳定的位置,缓存命中率上升,同样任务的成本肉眼可见地下降。
观察三:最有用的跨会话记忆,往往是少数几个 Agent 自己维护、自己修剪的本地 Markdown 文件,自动膨胀的向量库反而不顶用。本地优先还附带一个意外好处:记忆就是用户可以直接打开编辑的明文,出了问题一眼能看出它记错了什么。
至于移动端,屏幕小、交互短,PalWave 的定位更像对讲机:把任务委托给桌面端执行,记忆留在桌面,手机不背这个包袱。
本讲要点
- 上下文是 Agent 的工作记忆:注意力的平方级计算、KV 缓存的线性显存与中间遗忘共同决定,长程任务必须管理,不能只靠加长窗口。
- 压缩、检索、结构化是互补的三条路;最稳的打法是让 Agent 自己维护显式状态文件,把上下文当缓存而非真源。检索与长上下文按任务画像分工(Self-Route:先按 RAG 试探、不足再升级),外部记忆另附跨会话复用与可审计性。
- 技能与记忆把情节经验沉淀为程序性与语义性知识:SKILL.md 的渐进披露是技能的工程形态,而记忆需要写入策略、检索打分与主动遗忘。
- 缓存是上下文管理的经济维度:稳定前缀 + 追加状态是请求组装的铁律;换模型、改 effort、增删工具、系统提示里放时间戳,都会把缓存整段作废。
- 压缩按五分法与四步流程做:KEEP/ENCODE/ 尾部保留 / EXTERNALIZE/DISCARD、Trigger→Select→Replace→Recover,加防漂移的回源重验。
- 窗口变大有五条路,Softmax→Linear→DeltaNet→Gated DeltaNet→KDA,与 3:1~5:1 的混合配比,但合成评测近饱和、深层理解仍会崩,别拿大海捞针图当真实能力。
- 经验按 Episode/Fact/Skill 分类、按窗口 / 外部工件 / 权重落位:SKILL.md 渐进披露、代码技能一次调用替多步推理、Mem0 四操作显式管理记忆 —— 技能贵精不贵多,记忆要能写也要能忘。
延伸阅读
- Lost in the Middle:https://arxiv.org/abs/2307.03172
- LLMLingua:https://arxiv.org/abs/2310.05736
- StreamingLLM(attention sink 与流式 KV 保留):https://arxiv.org/abs/2309.17453
- Effective Context Engineering for AI Agents:https://www.anthropic.com/engineering/effective-context-engineering-for-ai-agents
- Voyager:https://arxiv.org/abs/2305.16291
- MemGPT:https://arxiv.org/abs/2310.08560
- Generative Agents(记忆流、反思与检索打分):https://arxiv.org/abs/2304.03442
- Mem0(生产级长期记忆系统):https://arxiv.org/abs/2504.19413
- Equipping Agents for the Real World with Agent Skills:https://www.anthropic.com/engineering/equipping-agents-for-the-real-world-with-agent-skills
- Agent Skills 规范与示例库:https://github.com/anthropics/skills
- Context Rot(Chroma,位置与长度双重退化):https://trychroma.com/research/context-rot
- Self-Route(RAG 与长上下文的成本路由):https://arxiv.org/abs/2407.16833
- Gemini 1.5(10M 窗口的召回实验):https://arxiv.org/abs/2403.05530
- RULER(可配置长度的长上下文基准):https://arxiv.org/abs/2404.06654
- HELMET(合成任务不预测下游):https://arxiv.org/abs/2410.02694
- NoLiMa(无显式匹配的深层关联):https://arxiv.org/abs/2502.05167
- Zep(时序知识图谱记忆):https://arxiv.org/abs/2501.13956
- LongMemEval(持续记忆五能力基准):https://arxiv.org/abs/2410.10813
- Agent Workflow Memory(AWM,workflow 自动归纳):https://arxiv.org/abs/2409.07429
- Agent Skill Induction(ASI,代码技能自动归纳):https://arxiv.org/abs/2504.06821
- ReasoningBank(失败归纳策略记忆):https://arxiv.org/abs/2509.25140
- SkillsBench(技能有效性基准):https://arxiv.org/abs/2602.12670
- Agent Skills 开放标准:https://agentskills.io
- Manus 上下文工程实践(「KV 缓存命中率是生产 Agent 最重要单一指标」,manus.im 博客)
概念回顾
翻卡自测 · 「再看看」的卡进入复习队列别只读一遍——先看正面的问题,心里作答,再翻面对照。主动提取比重复阅读记得牢。
模型一次能看见的 token 预算——桌面会满、注意力会散,长程任务必须管理。
推理时为历史 token 保留的「底稿」,显存与费用随对话线性增长。
把旧对话总结成状态笔记再继续——有损,丢什么留什么是设计问题。
完整历史放外部存储,每轮按需取回相关片段,桌面只放「正在用的」。
上下文中间位置的信息利用率明显偏低、性能呈 U 形——窗口更长不解决它。
请求相同前缀按大幅折扣计价——「系统提示放前、易变状态放后」的经济依据。
沉淀「怎么做」的文件夹(SKILL.md + 脚本),按渐进披露三层按需加载。
认知心理学「怎么做」一类知识,恰好对应 Agent 的技能;与会话日志(情节)、事实偏好(语义)相区分。
把上下文当内存、外部存储当磁盘,模型用函数调用自主换页——后续记忆系统的思想原点。
技能文件夹的入口:YAML 元数据(name/description/when_to_use)+ 操作正文 + 可选脚本与参考文件。
技能加载的三层纪律:元数据常驻提示、触发才载正文、用到才读捆绑文件——常驻成本每技能几十 token。
Mem0 把长期记忆当可编辑数据库:LLM 决策 ADD/UPDATE/DELETE/NOOP 四操作,又准又省。
多数层用线性注意力压状态、少数层保留全局 Softmax,局部:全局约 3:1~5:1——长窗口的主流落地形态。
87 个真实任务×8 域的技能基准:平均 33.9%→50.5%,但 13 个任务反被技能拖累——技能贵精不贵多。
官方指定读物
本讲资料库
查看全部 45 条 →- Agent Skill Induction(自适应技能归纳) ↗论文2504.06821前沿官方指定
官方指定读物。与 AWM 相同的 judge→induce→admit 归纳环,但产出物从文本模板换成可执行函数,由模型在沙箱里自己写、自己测、再入库。WebArena 五站点成绩从 41.3 提升到 59.5,注入技能后可达 80.2,完成任务所需步数从 24.5 降到 15.0。代码技能更强但门槛更高,是本讲技能库板块的关键对照。
为什么读
证明「让 agent 自己写技能代码」能闭环,且收益巨大。
Zora Wang 等(UC San Diego) · COLM 2025 · 2025
- Agent Workflow Memory ↗论文2409.07429前沿官方指定
官方指定读物。让 agent 从成功轨迹中归纳文本型 workflow 技能:先判断哪些步骤值得记住,再用 few-shot 提示把轨迹抽象成带 {变量} 占位符的动作模板,存入技能库供后续任务检索复用。在 WebArena 与真实网站任务上,跨任务的「技能复利」持续抬升成功率。与 ASI 同一团队的两条路线之一:这条走文本。
为什么读
技能库思想「归纳一次、处处复用」的最清晰示范。
Zora Wang 等(UC San Diego / Ohio State) · ICLR 2025 · 2024
- MemGPT: Towards LLMs as Operating Systems ↗论文2310.08560进阶官方指定
官方指定读物。把 LLM 当操作系统:主上下文是内存,外部存储是磁盘,用函数调用做「换页」,靠自编辑内存的指令让模型自己管理内存层级,中断机制负责协调。这是上下文窗口不够用时的经典解法,后来演化为商业产品 Letta。本讲记忆管理板块的谱系源头。
为什么读
「上下文即内存」的隐喻从这篇开始,后续记忆系统几乎都在回应它。
Charles Packer 等(UC Berkeley) · 2023
- OpenHands: How to Create Effective Agent Skills ↗博客入门官方指定
官方指定读物。OpenHands 团队的技能创建一手指南:什么时候该建技能——在模型刚刚完成一个值得复用的工作流时立刻动手,趁记忆新鲜把它固化;怎么写 SKILL.md,让 description 负责触发、正文写给模型看;以及如何在真实使用中迭代打磨。读完就能动手把重复工作流沉淀成自己的第一个技能。
为什么读
技能创建的实践帖很多,来自一线 agent 团队的手把手复盘最可信。
Simone Michelini、Graham Neubig(OpenHands) · 2026
- ReasoningBank: 从失败轨迹归纳策略记忆 ↗论文2509.25140前沿官方指定
官方指定读物。把失败也当资产:从轨迹(含失败尝试)中归纳「策略记忆」,按任务特征检索注入,让 agent 越用越强。工程结论很有分寸——LLM 裁判的归纳准确度只要落在宽区间内效果就稳定,检索条数过多反而掉分。融合了记忆管理与技能归纳两条线索,是本讲技能板块的收官读物。
为什么读
「失败轨迹也要入库」的记忆设计直觉,来自这篇的消融实验。
Siru Ouyang、Jun Yan、I-Hung Hsu 等 · ICLR 2026 · 2025
- SkillsBench: 能力、局限且经实证的 Agent Skills 评测 ↗论文2602.12670进阶官方指定
官方指定读物。87 个真实软件工程任务 × 8 个领域 × 18 种模型-harness 配置,系统量化技能的价值:带上策展技能后平均成功率从 33.9% 升至 50.5%。更细的结论是——只加载 1-3 个聚焦技能、SKILL.md 更短时增益更大;另有 13 个任务反被技能拖累。技能不是越多越好,这是第一份大规模实证。
为什么读
给「要不要建技能库、建多大」提供了目前最硬的量化证据。
Simone Michelini 等(OpenHands / CMU) · 2026
自测19 题 · 约 32 分钟即时反馈 · 答错的题自动进入复习队列先自己作答,再看解析——检索练习的效果来自「先提取、后对照」。数字键 1-4 可快选,Enter 提交。
「Lost in the Middle」指的是?
窗口已到百万 token,为什么长程任务仍必须做上下文管理?(多选)
下列哪项不属于上下文管理的「三条路」?
「把全部历史直接塞进百万 token 窗口,就不需要压缩与检索了。」
把认知心理学的记忆分层按「从当下到沉淀」排序:
编码 Agent 连跑 40 分钟后开始自信地引用一个不存在的文件名——修复的第一步是什么,为什么不是先改压缩算法?
缓存保卫战|一个 100k token 级的编码 agent 会话正在享受前缀缓存折扣。下列哪些操作会把已有缓存整段作废、下一轮全价重算?
压缩分拣|编码 agent 排查 CI 超时,工具读回 24K 行日志,上下文即将见底。按「留下什么、扔掉什么」的五分法,压缩后最应保留的组合是?
位置效应工程化|Manus 团队把 todo.md 任务计划持续重写到上下文的最末端,而不是放在开头后任其沉到中间。这么做的依据是?
技能不是越多越好|SkillsBench 在 87 个真实任务上评测 Agent Skills:平均成功率 33.9%→50.5%,但其中 13 个任务反而被技能拖累。最合理的解读是?
文本还是代码|ASI(Agent Skill Induction)在 WebArena 五站的 checkpoints 达成率:无记忆 41.3% → 文本技能 59.5% → 代码技能 80.2%,平均步数 24.5→20.6→15.0。最合理的解释是?
经验分型配对|L4 把 agent 的经验分成三类。把类型与实例配对:
开放设计|为一个平均 20 轮、上下文频繁逼近预算的编码 agent 设计一套 compaction 策略:须覆盖 Trigger(何时触发)、Select(保护什么、压什么)、Replace(用什么形态替换)、Recover(怎么回源)四要素,并给出应对「反复压缩导致约束漂移」的机制。
在 Agent 的请求组装中,想尽量利用提示词缓存并降低长上下文成本,哪种做法符合笔记中的建议?
编码 Agent 读入 24,000 行 CI 日志后上下文接近预算。按照讲义中的结构化检查点方案,哪种做法最符合要求?
某项网站操作流程环境稳定、步骤确定,团队希望把「怎么做」沉淀为可执行、可测试并减少重复推理的程序性记忆。按照笔记,最合适的技能设计是?
某 Agent 每轮都重排工具定义,并把当前时间戳放在系统提示之前;同时为了节省 token,每轮都执行 compact。依据笔记,哪种调整最有利于提示词缓存和成本控制?
编码 Agent 一次读取了 24,000 行 CI 日志。哪种检查点方案同时符合笔记中的压缩五分法、可恢复性和防漂移要求?
Agent 两次执行购物任务:搜索、比价和加购流程相同,但一次买跑鞋、一次买礼物。依据笔记,应怎样表示这些经验?
题目与解析 AI 辅助生成 · 人工审校。答错的题会按间隔重复节奏在复习页重现。
AI 生成 · 仅供参考,与课程方无关。选中正文里的任何一段也能直接问我(解释一下 / 举个例子)。
英文文字稿(YouTube 自动字幕机转,未校对)
Okay. Uh hello everyone. Can you hear me in the back? All good. Okay. So, uh well, welcome back everyone. Am I uh echoing? All good. Okay. So, um, today I’d like to talk about context management for long context agents. And
I at first thought about titling this as like context management for long context LLMs because most of the stuff I’m going to be talking about today is kind of more general LLM stuff, but long context is super super important for when we’re working on agents and it’s not
necessarily covered uh, very well in all of the LLM prerequisite classes. So, I’m going to cover it in a fair amount of detail today. I’m also going to try to go through kind of the long context architectures that are used in many of the kind of state-of-the-art open uh
models so you can kind of see the best practices that everybody is using in order to handle a very long context. So first I’d like to talk a little bit about um how long an agent context can grow. So basically the input is quadratic uh
from the uh or the number of token accesses that you do is quadratic uh based on the linear history growth. So um if each call uh you make for an agent takes about you know five tokens and let’s say you start out with a an initial system prompt of one token uh
you’ll get six tokens in the first call 11 16 uh 21 and 26. you know, this will increase and increase and increase. Um, and so by the time you have gotten to the end, you will, if you do things completely naively, you will have had to process ADK tokens uh for these five
calls. And you know, this can continue for a very long time. I I don’t know the longest anybody has used a single coding agent session or something like that, but I’ve certainly done them for like multiple days uh where I’ve been working with it for almost the entire day. So
you could imagine this could get uh very very large. Um the actual computational complexity of this is uh is actually even larger than this. Um well no sorry. So yeah the the computational complexity is is quadratic here.
So why do agent prompts get so long uh so quickly? I did a little bit of data analysis on uh the composition of prompts that I used in um uh 1,500 sessions from our uh coding agent openhands. And each each session was relatively short.
These are not like the long multi-day sessions that you do. This is more like solving a single task. But uh each one used about 78,000 tokens on average. Um 23% of this was a system prompt in all of the tool descriptions. Uh this is relatively large for a coding agent. I
think our system prompt is somewhere on the order of like 15,000 to 18,000 tokens because we’re very opinionated. Uh the open ants agent is very opinionated about how people uh do work. Um these tend to vary from like 8,000 to uh 8,000 to 20,000 tokens depending on
you know how many tools you uh you pull in and stuff like this. Um separately from this uh 9% were user messages. So this is the user either saying the initial task or following up with uh additional information after that. 9% were reasoning traces um and you know
where the model is thinking through things. 2% were model replies. Sorry, this isn’t showing on the slide, but 2% were um the model replying directly to the user. So, it’s spending about um five times as many tokens freezing as it is spending communicating uh with text
to the user. And 20% were tool calls. Uh so, you know, uh you know, writing code, uh reading code, that sort of thing. And 37% were tool results. So, this is uh you know, getting the result of, you know, reading a file or something like this.
So you know each step can uh will consist of all of these and that tends to add up uh very quickly. So when you’re handling this very long context uh there’s two big challenges here. Uh the first one is capacity and so whether your model is able to handle
this large amount of uh evidence in the first place and this is a challenge uh because as I’ll talk about in a little bit training models to handle very long context is hard um and so in order to manage this you need uh things like architecture
position encoding training data uh and uh you also need to be able to evaluate whether you’re doing a good job of this. And then the second thing is efficiency uh and whether the system can afford to serve it. And there’s a bunch of techniques to do that as well. And I I
think some people might be taking this for granted if you’re just using, you know, cloud code or codeex or something like this, but they’re doing some pretty monumental feats of engineering to take a, you know, multi- trillion parameter model and serve it within seconds uh to
uh over and over and over again for mil I don’t know codeex has 25 million users. So you can imagine uh 25 million daily users hitting it every few seconds for this huge model. Uh if you want to you can calculate in your head how many flops per uh per second that might be.
It’s a lot of flops. Cool. Um so any questions or things? Probably pretty straightforward I guess. Okay. So uh let’s go into inference. And so in order to make this happen uh the you basically need to be able to um calculate uh prefill and decoding. So uh
calculate your inputs and your outputs at each step. And this uh you know I’m sure everybody has done in your previous classes uh for generating from uh you know a language model. some things you may or may not have thought about in your previous classes. If you took how
many people took like uh language model systems or deep learning systems or something like that actually more than I thought. So if you took the systems course you you probably handled this. Um but other things you need to think about are how do you schedule uh multiple
concurrent queries? Um and also how do you save the results in the KV cache uh so you can reuse them and not have to reuse them over and over again. uh not have to calculate over and over again. So going into a bit more detail here, um we have a few phrase uh phases in
inference. The first one is called prefill. Um you could also call it encoding. Um but I think pre prefill is kind of the like preferred term of art nowadays. And so you take in all of your input tokens uh that you don’t need to generate and uh you generate the key and
value pairs uh from each of them. And then uh when you’re decoding you basically uh take the prompt uh and key value pairs um generate an output and append uh the key value pair that you get from the output. So um you do this kind of incrementally whereas this can
be done in a batched sequence. And so uh when we think about this as a serving system, there’s a bunch of ways we quantify how good a serving system is. Uh the first one is time to first token. So this is how long you need to start um you need to wait between when
you start uh entering a query and when you start seeing the first output. And so like I’m sure everybody you know who uses chat GPT or something like that uh you put in a long output you notice it takes longer to start getting a response than if you
put in sorry put in a long input you see it takes longer to start getting a response than if you put in a short input and that’s like your TTFT is higher. Uh then uh your time per output token is the uh time like the amount of time it takes uh between generating each
token. And if you go to a website like open router um t typically uh here this will be your time per output token there I am pretty sure they’re not counting prefill here and it’s just like the time between uh
each of the tokens that might be a little bit small with the black background but you can see that um for GLM 5.2 to uh you have like 63, 48, uh 24, uh that sort of thing. And you know, some providers are drastically better than others. Like this provider,
not to pick on Mistl, but they’re getting, you know, three three tokens per second and then these other ones like Parasel and Coreweave are getting, you know, hundreds of tokens per second. So um so basically uh you know this makes a huge difference in your
experience using um uh using agents. Uh one other interesting thing is um there’s different ways people can use agents. And so in some cases you might really hear about this. So like let’s say you’re working together um with a an agent on a interactive task in your
favorite coding CLI. you may really really care about, you know, TTFT and Tapot. Um, if you’re running an agent in the background to do some background tasks that run overnight, you might not care at all. Um, and there’s trade-offs between them, between like throughput
and cost and how fast uh you can get the the tokens. And like I you know also um serve coding agents uh with my company and when I talk to providers they’ll often often ask which do you care about more so we can optimize the system uh for the one you care about more and so
um there’s uh there’s ways you can do that and I’ll I’ll talk about those too. Cool. Um yeah so sorry just to finish the slide. So throughput is um the completed tokens or requests divided by the wall clock time. So this is kind of seen
usually on a more holistic level over the whole system. And then uh the cost is you know how much it costs. So as a refresher um I I hopefully everybody should know this already. Um but you have uh the uh query key and value calculation in uh
typical attention and this is uh so you have this here and then you take the softmax um divide it by this. You might have some sort of uh you know positional uh bias and then you calculate your output and typical full attention uh looks uh like this. you mask all the
previous tokens and and or you consider all the current tokens and you mask all the um the future tokens. Um so this is of course very expensive because it’s quadratic in the sequence length. Uh and so a lot of the stuff I’m going to be talking about today is about
how to fix that. Um so this is on the efficiency side and then on the effectiveness side just because you have a model or just because you have a serving system that can take in you know a million tokens doesn’t necessarily mean that you can use that a
million tokens effectively and um this is a very like old school example of this I guess this is a needle in the haststack evaluation how many people have seen this figure for maybe some but not not that many. Okay, so to explain what this looks like,
basically what this is saying is um it’s a very weird evaluation. Basically, they um they took a whole bunch of Paul Graham essays uh by the like famous entrepreneur and head of Y Combinator Paul Graham and they stuck in uh something about like the best place in
San Francisco to eat a sandwich is something or other and then they ask a question where’s the best place in San Francisco to eat a sandwich and then the language model has to answer that correctly. um and they made the context longer and longer and longer and then
they evaluate uh models with the longer context and eventually the weaker models start getting worse at these very very long contexts and there’s a bunch of examples of things like this. Um ruler and helmet are kind of the the common benchmarks that people use here. Um but
basically uh the long the summary is that if you have very long context your models might start getting worse at processing them. So has anybody noticed this when you’ve used a coding agent for a long time like are there common
or used any agent for a long time are there common like failure cases that you see? What what kind of things what kind of things have bothered you? Anybody? >> Yeah.
>> Forget the previous context. >> Yeah. Forgets the previous context. Did that cause any like problems for you? with me telling it not to do something in the middle of the conversation and then it goes and does it. Um there there was a really bad example uh where I
think actually Daniel talked about it here where the person had said do not delete this and then it went and deleted it anyway because it had forgotten the context. So yeah, this can be a really big problem in agentic settings because you know the user is giving these
incremental instructions. So so I’m going to be talking about several different things. I’m going to be talking about architecture. I’m going to be talking about training inference and compaction. So going first into architecture. Um this is both about
efficiency and accuracy. And so as I mentioned standard attention is global. So it makes pairwise comparisons across uh all of the tokens here. And um the problem with this is uh like this is quadratic obviously. And does anyone know the like standard
length of the of models nowadays of these uh of like state-of-the-art language models? >> 256 to a million. >> 256 to a million. Yeah. And I I’d say most people are aiming for a million now because they don’t want to be the, you
know, the model that has 256 when everyone else has a million. So very quick math in your head, how many pairwise comparisons is that? >> 10 12 >> 10 10^ the 12 or in English. >> A trillion. Yeah, that’s a trillion.
That’s a trillion comparisons every time. uh like when you’re uh generating a sequence of a million long and each comparison uh requires you to multiply large vectors by each other over and over and over again. So you’re starting to get up into the you know 10 to the
I guess it’d probably be 10 to the 20ish uh which is a lot that that’s a lot of compute um for a single sequence. So um there there’s ways that people solve this and basically almost all of them fall into the category of taking this quadratic computation and putting
some sort of constant limit on the number of comparisons that are made uh at each time step. And that brings your uh n squared down to owl where I I wrote w for window but it doesn’t necessarily need to be a window. It just needs to be the cap on the number of comparisons
that you’re making. Um so there’s the idea of local models and global models. And so local models are are basically models where this cap on computation happens within a local window. And then global models you have a cap on you might or might not have a
cap on computation but that cap on computation is not localized. So you can pass information uh throughout the entire sequence. And the I’d say almost all of the models uh that exist nowadays or are widely popular nowadays are some variety of hybrid model where they have
many local computations and then one global computation then many local computations one global computation and specifically I’m going to talk about six uh models that we have here. So uh the most recent Quen model uh has uh local computation of uh gated delta net.
I’ll explain all of these uh or most of these in a bit. And then um sparse retrieval uh for the global computation and the ratio is 3:1. Uh GLM 5.3 is uh also a variety of delta um and sparse attention uh with 3:1. Um
uh Kim K3 is uh a variety of Delta and um this is a dense uh dense attention 3:1. Uh Neimotron is Mamba uh which is uh kind of like recurrent style model and uh dense attention 4:1. um to uh window uh sliding window
attention uh dense attention 5 to one and deepseek’s a little bit different. It kind of has uh window windowed attention but then some uh sparsity uh sparse stuff with interle branches. So um basically the the standard way of doing things is hybrid model uh with
some sort of local thing and uh either sparse or dense uh global attention. So I’m I’m going to be talking about this. I’m not going to go into like a ton of details for all of them, but uh it should be enough that you could be able to look them up later.
So the first one is uh sliding window attention. And this is maybe the the simplest conceptually. And what you do is you take chunks or uh you take chunks of the output and basically you’re able to attend to your current chunk and um all of the previous chunks and uh
or not all of the previous chunks, a fixed number of previous chunks. So if this is your current chunk, um it might be a chunk of like 512 tokens or something like this. You would have an additional 512 and 512 tokens in the previous chunks and you would attend to
those. Um so pretty simple, no changes to attention, but you have something like this. But the nice thing about this is on the first layer you’re passing information from the previous one or two chunks, but on the next layer the uh previous chunks also have information
from their previous chunks. And so you kind of get this gradually expanding window. Um so uh this uh this is pretty widely used. Um but the more popular way of doing things nowadays is using some variety of
linear attention. And so the way uh linear attention works is basically we take our uh standard attention and standard attention has this um softmax operation included in it. And this is the reason why it’s hard to compute because you’re taking the
exponent and um and dividing. And because you do this there’s you basically have no choice but to expand all of the uh key and query computations uh like key query multiplication computations in and be uh quadratic uh quadratic
complexity. What linear attention does is you basically start from this uh kind of standard attention formulation but you take you remove the softmax and the normalization here or I mean the normalization doesn’t really matter but
you remove the softmax and you get just the key query multiplication and [clears throat] this is definitely less expressive because basically what you’re doing is you’re moving from something that
takes in a bunch of uh like numbers. Anyway, like pretend pretend that this bottom one adds up to one, but you’re going from a thing that takes a bunch of real numbers and normalizes them into probability like numbers that are between zero and one and add to one. Um,
so this nonlinearity allows you to focus on like only some of the previous uh like tokens. And this is kind of the good point of attention. That’s the selling point of attention that allows you to focus on the relevant previous context. And you’re basically taking
away that ability, right? You’re you’re removing the relative comparisons and just getting um the the dotproduct between the queries and keys. But it allows you to do something really uh nice which is that you can use uh the associative
uh you can use associivity and basically rearrange so that um you can convert the sum of all the key and value uh multiplications before into a single uh state matrix. And so this state matrix is essentially a function that map it’s a linear
function that maps from a query to a value. So attention is also a linear value. So if I go back to this here you’re basically calculating you’re taking the query you’re calculating the attention over all the keys you’re multiplying it by the values and you’re
getting a value here. Um and this state matrix is also that. But the nice part about it is this state matrix can be decomposed. So you can update it. You can keep this state matrix around and update it in constant time every time you get a new value. So this essentially
becomes like a recurrent neural network. So it it allows you to update the state matrix um in linear time without having uh without requiring the quadratic computation. So this basically solves your quadratic
problem and it solves it so much that um O of N squ becomes O of N. There’s no like there’s no even W term in this because uh each time you’re uh you’re updating based entirely on the previous state. Um but there’s there’s caveats here. So um is this clear though
uh so far? Okay, cool. Um, so the big caveat is exactly the caveat I mentioned before. Like this is just a less expressive function. Um, and it doesn’t allow you to make like relative comparisons between the
previous tokens, that sort of thing. So there’s a bunch of uh workarounds around this to try to make a more expressive function that nonetheless is useful in um in kind of uh doing attention-like calculations. And so um most of these are
if you dig deep into the math in them, they’re basically trying to become better predictors of the final value that you would get from attention. Um and you you can dig into the papers to see how that works, but I’m going to explain them mostly uh mechanistically
here. And so um the first thing is Delta. And the idea behind deltaNet is um you can predict what you can essentially predict what value you would want to be getting from the uh from the calculation of uh KT um and S. And so you know KT here is uh
the key at time step t and you are comparing it with the matrix at time step t uh t minus one and uh you’re calculating this v hat t and on the other hand you um so basically this this is the prediction that you would get of kt But on the other hand,
you know what the uh output VT should be uh based on um what the query times uh or based on uh what the Hang on one second. [laughter] I don’t want to I don’t want to get this wrong. So you calculate KT with respect to the
matrix. And you can view this matrix as a way of uh calculating the uh the way of calculating the mapping from a query to a value. And you can also get the the actual value and subtract out uh what the value you get when multiplying it from the previous uh together with the
previous matrix is. And this is essentially the error uh that you get here. And then you want to reduce the error. And so in order to reduce this error, what you do is you um essentially add in this uh this term which is KT uh times the error term. And after you do
this, if you multiply in KT to the new matrix, you will no longer have any error. But you don’t want to make an update that is too big. So you add this beta term. This is essentially a learning, it’s similar to a learning rate. And this learning rate will make
the updates uh smaller. And so uh if you if you do this, this allows you to basically nudge the matrix in the direction of uh the in the direction that will cause a query that looks like the current key to output the value that you want essentially. So it’s it’s
reducing the error uh reducing the error in the prediction of the value that you want. So um as I said this is going to be a little bit high level. Um the the papers are are pretty good uh descriptions of Um so after this um this basically what
this is doing is this is pushing you in the direction of the uh of making the the matrix a better predictor of the uh the value. But one problem with this is you can build up lots and lots of context uh from the previous uh spots and linear attention doesn’t have any
mechanism to prevent very far away cont uh context from having a bad influence on your next predictions. And so if you have like a very weird key far back in the future, it might have a very big influence on you in the f uh in the future. And so the way they fix this is
basically they have a decay term to make uh to make the matrix decay a little bit at every time step. And by decaying the matrix a little bit at every time step, they’re basically discounting the the far in the past
context. And so you multiply um the matrix by alpha t and then you add this uh st tilda into uh into your calculation here and update the matrix. And so the stronger you make this decay basically the the more quickly uh it will forget the previous context. And so
you can make this more local or or less local. And so this is uh gated delta is used in the Quen models. So it’s one of the more uh the more popular methods now. Um but both uh GLM and uh KI which are kind of two of the state-of-the-art models use a
slightly more expressive version of this uh where they basically have a per element uh decay term. So each element can decay at a different speed. And uh because each element decays at a different speed, you can have some uh portions of the context that uh you know
carry over very long time periods, some portions of the context that carry over very short time periods. Cool. So hopefully this was more or less uh more or less legible. Um any any questions here? Long long story short, it’s basically a
way to turn uh into um it’s a way to turn the idea of attention to something that you can calculate um in context. Mamba is uh something that’s very similar um but it’s a little bit more mathematically involved um uh and I I
decided to skip over it. uh I covered it more in the uh language model uh description course but similar idea but just a bit more complex uh in the math. So the next thing I’d like to talk about is sparse attention. And so sparse attention is uh basically looking up a
not attending to everything in the previous context but only attending to some things in the previous context. And essentially you limit the number of things that you look up in the previous context. There’s a few ways you can do it. Um originally in there was a sparse
attention paper by OpenAI uh quite a while ago like 5 years ago or something like this. Um and basically uh what they did was they had sparse attention every you know uh 512 tokens or something like this. And what this does is it means that you still have a fixed it’s still
quadratic in the sequence length but it’s 512 times less than if you attended to every token and that’s like good enough uh that you can manage to calculate it over the context that you’re interested in. Another option is to do um content
dependent sparse attention. And basically what this does is you have a very cheap way of calculating attention. Like for example, you can down project the attention vectors to be very very small and then you do attention over these very very small uh attention
vectors. You pick the top k ones and then you do full attention over the top k. So uh that’s uh another way that you can do this and this is what’s used in deepseek. Yeah. >> How do we define the metric for which we
do the top similarity compared in this in the shrine space we just do like coine distance. >> Yeah. I I think it’s typically not cosine but it’s just product but yeah >> I I I think although maybe maybe they’re normalizing beforehand. They actually
don’t know that detail. Any other questions? So basically um these th this is a very very cheap way to achieve global attention because you can just uh write a kernel that will do this for you. Um this over here will uh
require you to have two passes, but you know it’s potentially uh more accurate. So um I I’ve seen both of these used pretty widely. So a final um a final thing is KV compression. How many people saw this in a language modeling course?
Maybe some people. Okay. Um so I will uh I’ll explain this. So basically um this is standard multi head attention. And so in standard multi-head attention, you have a bunch of heads and each one has values and keys and all of these are a certain dimension. So they’re like
dimension, let’s say they’re dimension D and you have uh you have like a certain number of heads. Let’s say that’s H. Um so the two main ways that people solve uh or help uh this problem of having very uh large and expensive KV caches is uh
grouped query attention. And grouped query attention basically uh just uses a smaller number than h um you usually h divided by some uh power of two uh number of uh keys and values. And because it’s the KV cache, it’s not the KVQ cache. Um
if you reduce the number of uh keys and values that are used, you reduce the amount of memory that you need to hold the KV cache. This is really important because if it gets very large then um it limits the number you can fit on one GPU and so this can usually be reduced by
like four or by eight or something like that. Um multiquery attention is just like grouped query attention with a single one. So you can kind of almost skip over that. You already know what it means. Um multi head latent attention the the um
is essentially down projecting uh the size of the keys and values. So it’s not reducing the number of heads, it’s making each head smaller. And so this is similar to what I talked about with the top K attention. Um and of course you can combine both of these together as
well. You could have group query attention with um you know smaller uh keys of values. Um so the these are the method the architectural methods that people use to handle very long contexts and with these um you can handle up to a million uh
tokens. So like this is uh you know this makes the efficiency possible. The next thing is uh training long context models. And this is actually uh pretty hard. And the reason why is because um if we want something to handle 128k tokens or even more, there’s
actually not that much data on the internet that is 128k coherent tokens. Um it’s actually a lot of a lot of data. it’s more than most Wikipedia articles, you know, um you’re starting to get in the in the order of like having a book uh that you need to have and there’s not
that many books on the internet. So, typically what you do is you start out with like short pre-training. Um you do more continued training with longer documents and then you do long adaptation. Um I wrote packed sequences here. Um,
but packed sequences are are useful can be useful for efficiency, but they’re not super useful for learning long contexts because um every time you like let’s say you pack 10 documents into a sequence, you’re not learning to attend across the documents and in fact you
probably should not be. So um you really need coherent uh long sets of data to do adaptation to very long contexts. Um so I’m going to talk about a few things that we do here. Um the first thing I’m going to talk about is uh handling positional encodings. Um so
absolute positional encodings uh I I hope everybody has seen in their language modeling class. Um but basically uh each individual entry in the uh each individual word embedding uh gets a position vector and that position vector
is typically calculated by uh some sort of function like using signs and cosiness and other stuff like this. So hopefully you know most people have seen this. So I’ll I’ll kind of skip over that. Also maybe most people have seen rope. Are people generally familiar with
rope? Okay, I see a fair number of people. I see actually less people uh than I would have expected, but um uh maybe people are just uh not interested in raising your hand. Um [laughter] but uh but basically um rope rope is pretty elegant mathematically in my opinion. Uh
basically the problem they were trying to solve is they wanted to have a positional embedding. um where the positional uh or positional encoding where the positional encoding is entirely determined by the relative distance uh
between two tokens. And the reason why they wanted to do this is they didn’t they didn’t want the absolute position to have an effect on uh they didn’t want the absolute position to have an effect on whether
two tokens would attend to each other. And so this is this has been quite effective and a lot of uh a lot of models use rope. Um the the math I’m not going to go through here because it’s kind of not the main point, but they do some
interesting stuff with rotations and imaginary numbers and stuff like this. Um but there’s also this like super counterintuitive uh nope. which is uh don’t don’t use positional encodings at all. Um and if you took
your uh class on transformers uh you might have heard this scary stuff which is like you need positional encodings for transformers because otherwise something in position one in position five will have exactly the same representation. So if you have like this
this is a cat but this is not a cat it will attend to both of the cats the same amount or something like this. Um theoretically when the transformers were originally created um this might have been true but now actually it’s it’s not true anymore based on the transformers
we use now. Um anybody have an idea why this is the case? I’ve kind of given a hint in the slide but you might also need to know a little bit of the history of transformers uh which is uh before we were using encoder decoder models uh where the encoders
encoded all of the input and then the decoders uh generated the output any idea >> because we’re doing causal masking exactly so um to elaborate on that a little bit if I go back to our transformer equation
Um, we have the keys um, and the queries. And if we look at the queries, even if you have cat at position two and cat at position five, the cat at position two is only attending to the previous token where the cat at position five is attending to the previous four
tokens. Um, and so both of them are like actually different. um starting at least in the first layer of attention. And so you can tell like even if they are exactly the same word, the embeddings starting in the first layer of attention will will not be different. And there’s
kind of uh this counterintuitive paper that demonstrates that you don’t need uh positional encodings at all. And this is especially true um this is in auto reggressive uh transformers. In non-auto reggressive transformers where you’re attending all the tokens are attending
to each other. You still do need positional encodings. Um this is especially true when we start talking about like gated delta because gated delta has like the decay term and uh other things like this which causes each uh token to be different. So once
we start having those sort of local biases, we actually don’t need positional uh encodings anymore. and if you uh if you look um we uh the first two here have rope uh or at least partial rope. The second two
have nope uh no positional attend encodings. Um the the fourth one uh relies entirely on implicit order and mamba and some of them in uh and inkling has relative positional encodings. So you can see that it’s kind of like half split between having relative positional
encodings and not at all. But like let’s say we did have positional encodings. Uh one thing you need to worry about for long context is uh position interpolation or position extension. And what this means is if you have a pre-training range, um, you need to
essentially extend your model so that it’s able to handle longer sequences. And so the the promise of rope was that rope relied only on the relative position uh between the different tokens in the output. But that that’s fine as long as the relative
position is only um well okay there there’s two reasons why this is not fine. So number one if you’re training on sequences of length L and then you extend to sequences uh of length SL then it’s never seen two tokens attend to
each other over a distance of more than L. So the tokens that are more than L away from each other are going to have problems attending to each other and you’re not going to be able to uh manage that very well. Um the other problem is that actually relative positional
encodings are only one part of the story and like actually the auto reggressive mask has an effect in all these other things. So you can’t just take rope and expect it to work uh really well on longer sequences. And so the typical way you fix this is
there’s a parameter in rope that basically uh let me see if I have it in my slide. So I I don’t I don’t really have it in my slide, but there’s basically a um a parameter in rope theta that uh tells
you how much you rotate at each time step. and you divide this theta by the uh multiplier by which you extended the sequence. And so basically you’re stretching the rope position so that the rope uh position at position zero would um or the rope position at position like
five would be 5s uh would be equivalent to the position 5s in your uh extended context. And there’s also um a more sophisticated way of doing this called yarn uh which basically is uh similar in spirit uh to like the delta uh the ki
delta attention um which basically said that we want some of them to be very long distance and some of them to not be very long distance. In yarn essentially you have some of them be uh extended more and some of them be
extended less and so you don’t um you don’t necessarily interpolate all of them at the same frequency. So um yeah in the interest of time I’m not going to go into like a lot of detail about this but basically these are um uh these are the various methods
that you can use here. So, um, I’d like to talk a little bit now, um, taking a step back from the detailed modeling stuff and going into the data that you can use to train this. So, um, as I mentioned before, packed examples,
you can just pack a whole bunch of stuff in there, um, a whole bunch of documents in into your context length. And this will work at training models to be able to process things near the end of your context window. But what it won’t work for is the kind of global coherence. And
um so there’s a number of different ways that people do this. One way is just to find um very long documents uh like books or something like this. There aren’t a lot of these uh but there are books. There are code bases and code bases tend to be coherent. So you can
just download a big codebase and that will definitely have more tokens. Um multi-document corpora of some kind. So, you know, like uh you can get a whole bunch of documents that are on the same topic and then at least you’ll have topical coherence between them. Um I’ve
also seen people train on patents because patents have like there’s lots of public data for them and you can kind of link link them together. A big source nowadays is agent trajectories because you know agents can make very very long trajectories if you
just interact with them for a little while. So that’s another one. And then you can also create synthetic tasks and a lot of the evaluations are synthetic tasks. So you can do that as well. Um and I I have some examples of how the models do this. Um a lot of the model
training companies don’t like to share these details with you because this is like if they release their um well so number one the closed models like anthropic open AAI you know those places uh uh Gemini they will not release even their architectural details the open
model companies have to release their architectural details otherwise you can’t run their model so what do they keep secret they keep their data mixes and their their training strategy secret so um this there’s a lot less detailed stuff that we can say. Um, but there’s
uh all of them explain all of the ones in here explain a little bit about their data mixtures and they are things like uh cleaned up sampled documents and video um documents, repository files, issue, PRs, uh long document QA, scientific papers and technical reports.
And then uh they also create a bunch of synthetic tasks. And typically they have a scaling strategy of like 8 64 256 1 million uh that that sort of stuff as well. Oh yes. Um [clears throat] one other
logistical detail that you might need to deal with um or might not need to deal with depending on the size of the model you’re training. like for example for your project if you want to start dealing with um uh larger models is context parallelism and basically what
this means is there’s a bunch of uh ways to do parallelism when training models I wrote context parallelism up here what are two other ways uh that you can parallelize models during model training or serving >> yes
>> data parallelism >> yeah you you said a more specific example of the second one but data parallelism and I would say model parallelism in general and model parallelism can have lots of varieties. It can have uh expert parallelism where
you have different experts on different machines uh tensor more generally tensor parallelism where you split um uh the uh the parameters and you can also have pipeline parallelism where you have different layers on different uh different devices. But context
parallelism starts becoming import more important for agents because when you train agents you want to train them on very long contexts. And so uh the way this works is you will compute like one part of the context uh the keys and values. So you send it to the next
device calculate the keys and values for the next for that part send it to the next device uh and etc etc. So um this is uh very useful. It’s really important if you start getting above like 32k 32k context or so. Um, but it’s also a pain because
you have the you have all the modeling people saying I want my I want my KI delta attention and then you have all the info people saying but wait I need to implement a context parallel kernel for KI delta attention and make sure it actually
works and you can back prop through it and all of these other things. So um I I personally had an experience where I was trying to train uh Quen uh for uh like a smaller quen model like 135 uh 35b and uh I I wanted to go do use context parallelism on it and it’s like there’s
no kernel for gated delta net anywhere on the internet and so um you need to uh you need to either go in and implement that kernel or decide to do something else. So um th those two can conflict some of the times. So be be aware I guess
um the the good news is for like standard attention and sliding window attention and stuff like that all of those will have uh kernels more easily implemented. The hard parts are where you’re like not doing a standard attention operation.
Okay. So the next part I’d like to talk about is prompt and KV caching. This is uh very important even if you’re not the person who’s implementing the language model, but also if you’re just a person who’s um like running agents uh yourself, but I’m
going to talk about uh the the technical details of how it’s implemented. So, you know, at least you you have a good uh idea about how that works. So um when we I I simplified this a little bit but when we’re generating an agent call we have an input uh we have an output uh
so this could be like the the messages and tool calls and then we have the tool result and so so as we calculate the input we do prefill and as we calculate the output uh we do uh basically decoding Right? And so during prefill and decoding, we have to
calculate the KV cache. This is all done in a batch. Uh this is done every time we generate a token. But after we have that, we have the uh key and value uh for each of the positions up until the end of the output. And so what we can do is we can throw that in a cache and then
we don’t need to calculate it anymore. The tool result is new uh because you know we don’t calculate over the tool result. So this becomes a new input and we generate an output and we get another tool result. And so in step two we need to calculate the KV cache over the new
input and we uh during prefill and the output but we can reuse the cache and then we do that over and over and over again. And so as you imagine um as you can imagine I just showed steps 1 2 3 but by the time we get to step 50 if we haven’t done anything tricky with our
output this is going to be 50 times larger than the new input in the in the output right so that’s pretty significant savings if we can cache this properly and here are some examples from actual papers uh that you know examine this and
basically What we can see is this is like the the token length on uh different GPUs and this is the amount of uh of compute that you need with caching and no caching. And so the upper one of the same color is uh or the lower one with the same color is caching and the
the upper one is no caching. So uh basically as the sequence gets longer the non-cashed one becomes quadratic and the cache one is is mostly linear. This also shows up in how much you pay to run an agent. And so I I pulled all of these numbers from uh the official
pricing. And basically you can see here that if you go through all of these uh all of these numbers including the commercial ones typically cashed tokens are onetenth of the price of uncashed tokens. And so what this means is you need to be very aware of uh whether your
tokens are being cached or not. Uh because if they’re not being cached uh you’re going to be paying a lot of money to be running your agents. Um, so does anyone have an idea of what a good uh cash hit rate is if you’re running an agent? Yeah.
>> 80 to 90%. >> Um, yeah. So I I heard 80 to 90% I heard like more than 95%. I my my impression is 90 to 95 is everything is fine. Like I’m I’m good with 90 to 95. If it’s less than that, you might be fine, but you might be might be losing out somewhere.
Um so, uh yeah, so basically you can you can cache most of your tokens. Um one other interesting thing is the output also tends to be five times more than the input. So um this is uh there’s a 50x difference between output and cached input which just reflects the amount of
uh uh the amount of cost uh savings that you can get from serving it. So why why is caching um so much cheaper is maybe kind of obvious. You just need to look up um you need to look up the outputs. uh you just need to look these up instead of like actually uh
performing the calculation over them. Uh especially the feed forward network calculation is pretty expensive in transformers and so being able to skip that is is uh particularly a win. Um but how do we actually manage that? So um the first thing is uh how do you hold
it in memory? And there’s two like most popular open-source uh two most popular open-source LLM serving libraries VLM and SGLANG and both of them are based on an innovation around the how you manage KV caching. Um so VLM’s main technical in innovation
and like of course they have a lot more stuff in there now. They’re like general purpose serving libraries, but like the main technical innovation that led to VLM was something called page detention. And basically the way it works is you have physical GPU memory blocks and you
rear you arrange them like kind of memory blocks or or disk blocks on uh like more typical uh like CPUbased machines. And so you might have uh block zero uh block one block two that you actually need to calculate and they put that you know in like block one and then
block seven and then block three or sorry uh block seven block one block three and then you have an index to each one of these uh as you’re generating. And the reason why they wanted to do this is they want to be able to generate in parallel many sequences in parallel
and when you finish generating um you can like evict that from your memory and so you can uh evict whole blocks at once and this makes the calculation more more efficient. So um this is uh one technical trick that they used to make this uh you know make parallel serving
work. the technical innovation that kind of led to SG lang in particular uh was something called RAIX attention and this is specifically focused around uh like re reusing already cached uh out uh inputs. And so what they do is they form
a a tree basically uh it’s a radics tree and they use this to look up prefixes that have been used already. And so this uh when it first came out this was specifically focused around uh chat bots like chatgpt uh because you know you can have
somebody start a conversation and then continue the conversation and so you’ll be caching some portion of the already done conversation. But for uh now it’s like much much more important for agents because agent conversations are much longer and much more frequent. So we
need this uh looking up more frequently. Um so another uh another thing that you need to think about um which is handled in uh newer versions of sglang for instance is let’s say you’re doing multi-achine serving. So you’re serving on um you know different machines uh you
know maybe you have a data center with like 64 nodes or 128 nodes or something like this. um every time a request comes in, you want to route it to the machine that has your KV cache that has the best KV cache for you um to be accessing and so that you actually have cache aware
routing uh route it to the appropriate place and then have the worker with the best uh KV cache match uh process set. I love getting all my uh my serving statistics from Open Router um because they have so much data and uh they cover all of the things I want to talk about,
but I believe they even have a ranking of providers by cash hit rate. [laughter] I’m sorry mist the data the data doesn’t lie but um you can see uh mistrol has the worst cache hit rate and then um you have other one other ones like Alibaba
cloud or dicard or silicon flow that have higher cash hit rates um this is not entirely reflective of the provider being bad or something like that it could be just the workloads that they’re running but there’s a number of things that like actually factor into
into this cache hit rate and um one of them one of them is how good is the cash routing. The other one is how fast is the cash eviction. Um so the providers will not hold your cash for you forever. Um they will uh you know evict your cash after a certain amount of time. Does
anyone know how long this is for like popular providers? Have you ever taken a look at that >> yet? Close to an hour. >> Close to an hour. I I think the long like I’m not I’m not like super up to
date on this, but I know anthropic used to be five minutes. And so it’s basically if you have a an active conversation going on with them and you don’t pause your conversation, you’ll stay in the cache. Otherwise, if you like stop the conversation, you get
evicted from the cache. I think you at least have an option to go up to an hour now. Um but I don’t know if you um but like it costs a little bit more if you go up to an hour or something. Um but yeah, ba basically they don’t want to keep this around because there this is a
huge amount of memory uh that they’re keeping in memory and so they want to use it if it’s working and and evict it if it’s not working. So um that that’s another policy that could change your cash hit rate. The bad news for us as users is the pricing doesn’t change no
matter how good the provider is at routing or um or cash eviction. So you uh you might be paying just because they evict you uh evict you too quickly which seems a little bit unfair. >> Um yeah >> do they use like cash layering where you
can store it on device in memory that’s like adjusted to device and then on this >> yeah so the that’s a great question. So the question was, do they use a cache layering where you have like a fast cache that’s stored in the device and then uh a slower cache that’s stored on
disk or something like that? I actually don’t know the answer to that question. That’d be a great uh like a great follow-up for us to do. Um the open source libraries also are probably not as sophisticated as the closed libraries because um if you look at all the people
on open router their job is to be really good at serving and so you know they’re some of them might be using open source libraries but they’ll be building stuff on top of them and that’s kind of their you know competitive differentiation. So um like I I think
the internal solutions that inference providers are likely to be you know a bit better than the ones that are available in open source too with respect to that. >> They usually offload to CPU from GPU. >> Yeah. Because your GPU memory is so
precious. So yeah. Yeah. >> Cool. Um so uh yeah. Oh, sorry. I skipped a important part. So, what does this mean? If you’re just designing a harness and you’re not deploying models or or anything like this, it means you need to be super super careful to not
break your cache unintentionally. So, remember that your cache only works if the entire prefix is exactly the same. And so there’s a bunch of things that we’ve thought about uh doing but we decided are a very bad idea because we don’t want to break the
cache. So one thing that’s completely forbidden you should not do is don’t change the system message every time you uh you take a step because that means like no caching essentially. uh you don’t have a single message that you’re able to cache. So one thing one very
logical thing that you might think of is okay I want to append the current time and date to the system message uh so that the agent knows what time it is. Do not do this because the time and date changes every step and so that will break your cache. So if you do need to
append it, append it to the final user message uh or the final uh tool call result that you get. um and uh like changing your um changing your tools uh dynamically in the middle of the conversation. You can do this. That’s okay. Um another thing is a very logical
thing that you might think of doing is routing to a different model every time you uh every time you take a step. So it’s like this step looks like a really good model for you know a really power a really good step for a really powerful model. um like uh like I want to do this
step on Fable and then I want to do the ne next three steps on um on a cheaper model to save money. But the thing is you’re still paying you’re still paying the you know 10x cost for Fable the next time you use uh Fable. So you really need to be very uh
frugal in the amount of switching you’re going to be doing if you want to be doing switching to save cost for instance. Cool. Um, so the final thing I’d like to talk about is context compaction. Um, how
many people know know about this? Use this in your everyday coding agent use. How many people are really excited when it says compacting context? That’s nobody good. So um the the basic idea behind context compaction is uh that you have uh before
and uh this is you know all your observations and actions that you might have had. Um then after what you tend to do is you tend to take your previous context and you crush it down into just the essence of the previous context. Um, and so the reason why people are
like not excited about using this, uh, perhaps obviously is if you do a bad job at this, your agent forgets things. It starts doing something completely different and, uh, maybe deletes your file system. um we can view compaction as essentially
trying to come up with a previous representation where your future action sequence um you take your history, you compact that, you get a working state and you want your future action sequence to be the same or you know similar or possibly better um if uh after
compaction than it was before. Um at the same time you also have a constraint which your state needs to be bounded. So it needs to be small enough that you’re happy to continue work. Um so if we look at what survives uh
compaction um there’s different ways of doing this. I’m going to cover the different ways that people do this, but a common strategy is to take some anchors and these can be the very first um like the very first things the user said when they started the session for
instance. Um, so, uh, one of the answers to the things that I heard agents forget when I asked the question, what do agents forget was sometimes they forget the things at the very beginning of the session? And that actually might be a design bug in
the agent harness that you’re using. Um, because uh, some good agent harnesses uh, like kind of intentionally avoid deleting the stuff at the very beginning of the session because they think it’s more important. Um, but it could also be, you know, impossible to avoid
depending on the situation. Um, also you want the stuff in the middle that’s encoded and put back into the context. And then the recent tail is often kept around. So often people will keep around the the most recent actions. Separately from this, I don’t see this a
whole lot, but um, you can also add the evidence to an evidence store. Actually, no, sorry. I I’ll correct this. Um, the evidence is typically added to an evidence store. Um, and at the very least, if you’re using a CLI coding agent, usually your full history is
saved on disk somewhere. And so, if you know where on disk, your coding agent has saved all of this history. Even if you lose stuff through compaction, you can tell the coding agent to go back and read the history, and it can, you know, uh, read the history for you and find
the the previous results. Um but there there are also uh possibly more structured ways of doing this and so then um you know other things can be discarded. Um so there’s a few ways to decide uh compaction policy. Um the first one is
the trigger and there’s essentially two ways of doing this. Um one is a token threshold. So you limit uh the token threshold. Uh so you can say I’m I’m only going to use up to 200k tokens. Once I go over 200k tokens, I’m I’m going to compact the context.
Another thing is um like when you get forced to do that by the provider. Um so that’s kind of like a hard limit on the number of tokens you can have. Um finally, you can also have a manual request. And so uh a lot of uh kind of coding agent toolkits for instance have
a slashcompact uh like command that you can use to compact the context. Um then based on that uh you’ll select you might protect the beginning and keep the recent tail and compact the older region. Um replace it with a summary. Um
that summary can be a structured summary. So sometimes uh they require a tool call uh that says this and this and this and this must be in the compaction summary. Sometimes it’s just free text. Um there’s also uh I think this is only open AI uh
possibly. But basically they um they compact into something encrypted uh that you cannot read. So you can’t see how they’re compacting because they don’t want you to steal their uh their precious compaction algorithm. Uh so uh so
there’s that. Um and then uh yeah, you can you can keep on on working on that. one of the risks here is uh sometimes you can compact over and over and over again and the first time it works uh but as you walk through more um you uh you
end up losing more and more. So again this is one of the reasons why people don’t like compaction because it can cause the agent to go off the rails. Um so uh ba basically the way we evaluate this is typically in a holistic state. So you can vary the compaction
algorithm and evaluate it against whatever benchmarks you’re evaluating against. I would like to warn you uh about this. I have a a kind of like story from when we were first developing open hands which is um we actually I think made one of the first like
production grade uh compaction algorithms. We called it compression then um and we evaluated it against bbench which is a very common you know benchmark for for coding agents and we worked pretty hard on it like as a research project for about a month or
something like that and we were like we found this great compaction strategy. It doesn’t reduce our score at all. it’s saving us a lot of tokens. And then we actually tried it in our um we tried it in our our system and it made these really silly mistakes like um sending a
pull request every time it compacted. So it forgot that it had sent a pull request to GitHub. And so uh you know we would get five pull requests for the same functionality because it had forgotten. Um or you know it would forget
user instructions that were sent in the middle of the conversation because we had only evaluated on single turn conversations that had a single user message and we were compacting away the multiple user messages. So it’s not just good enough to benchmark uh unless you
have really really robust benchmarks that represent every use case. You kind of need to test them in the wild as Cool. Um so we’re we’re getting close to time. Uh but yeah, basically uh what I covered today is uh you know agent loops grow very quickly. Uh we have a lot of
inference challenges in doing so. uh we can handle uh efficiency problems through architectures and um and caching and uh compaction is kind of the way we handle this uh once we expand beyond the level that we can handle. So um that’s all I have. Uh if there is any questions
happy to happy to cover them and next time we’re going to be talking about skills and memory. So this is like even longer context over your entire uh your entire time. Um, are there any questions before we all uh all leave or >> Yeah, great question. Um, the question
was, do we consider sub agents as a way to manage context? And yes, but we’re going to talk about sub aents later, so I didn’t cover them this time. Yeah.
本讲伴读笔记以 CMU 11-768 AI Agents (Fall 2026) 课程大纲为参考框架独立撰写。原课程由 Daniel Fried 与 Graham Neubig 讲授,原始课件与视频见cmu-agents.com; 音频镜像与文字稿仅作大陆可达性便利,版权归课程方所有。本文观点与文字为作者原创。