一、总览:一条原则统领三层缓存
缓存能力分散在三个层次,但它们全部服从同一条地基原则——会话事件日志(append-only)是唯一权威,所有缓存都只是从日志派生出来的”快捷方式”,可以过时、可以丢失、但永远不会给出错误的值。理解了这一条,三层缓存的失效策略、写回时机、fail-soft 行为就都是它的自然推论。
1 | flowchart TB |
三层各自解决不同的成本问题,作用域和生命周期完全不同:
缓存能力分散在三个层次,但它们全部服从同一条地基原则——会话事件日志(append-only)是唯一权威,所有缓存都只是从日志派生出来的”快捷方式”,可以过时、可以丢失、但永远不会给出错误的值。理解了这一条,三层缓存的失效策略、写回时机、fail-soft 行为就都是它的自然推论。
1 | flowchart TB |
三层各自解决不同的成本问题,作用域和生命周期完全不同:
抛开一切框架和术语,一个 agent 能干活,靠的只是一个循环:拿到用户的输入,把它和历史一起交给模型,模型要么直接答复、要么要求调用某个工具;如果要求调用工具,就执行它、把结果塞回历史、再问一次模型;直到模型不再要求工具为止。这个循环用五十行代码就能跑通第一个版本,先把它跑通,再来谈设计。
真正的设计难度不在这个循环本身,而在它周围的四件事:状态存在哪里、消息历史怎么来、提示词怎么拼、工具怎么被看见和执行。下面这张图是一个成熟形态的完整往返,你会发现循环还是那个循环,只是每一步都从”直接做”变成了”向某个部件要”。
1 | sequenceDiagram |
图里有一条贯穿的主线值得先记住:主循环自己不保存任何状态,它只是反复地”读日志、问模型、写日志”。之所以要把它设计成这样,是因为 agent 有一个和普通后端服务完全不同的要求——它必须能被完整重放。用户刷新页面要看到全过程、程序崩溃后要能接着跑、上下文满了要能压缩后重试、出了问题要能复盘模型当时到底看到了什么。只要主循环里藏了一点只存在于内存的状态,这四件事就全都做不到。