letta-code — 本课题摘录
读了哪几篇: 01-stateful-turn(有状态回合与批准环路)。
其余五篇本轮没读。
这一家把本课题"状态放在哪"这一问推到了另一头:不在循环里,也不在进程里,在服务端。
它对本课题回答了什么
决定四(架构):状态在服务端,每次只发增量
| 维度 | 常见做法 | 这一家 |
|---|---|---|
| 谁存历史 | 客户端进程内存 | 服务端会话 |
| 每次请求发什么 | 全量历史 | 只发本轮新增的那一条 |
| 进程被杀之后 | 历史丢失,只能靠本地文件重放 | 服务端仍持有,重开即接上 |
| 未决的工具调用 | 丢失 | 服务端仍停在"需要批准" |
(依据:Agent 库 · Letta Code · 一次回合是怎么跑的:后端抽象与 approval 环路 —— conversation 的消息历史、系统提示、未决工具调用全部由服务端持有,CLI 每次只发本轮新增的 message 或 approval 而非全量历史;进程被 kill 后服务端仍停在 requires_approval)
本课题读到这里,"状态在哪"已经有四种答案:
- 循环自己拿着(最朴素);
- 上一层拿着,循环无状态(kimi-code、pi);
- 写进消息里,决策函数纯读(agentscope);
- 服务端拿着,客户端只是调试器(letta-code)。
第四种是唯一能做到"换一台机器接着跑"的。
它自己的直觉句很好:把会话当成一台停在断点上的虚拟机。客户端不是虚拟机本身,而是调试器——attach 上去、看寄存器、执行一条外部指令、再把结果写回去让它继续跑。调试器崩了,虚拟机还停在原来那个断点上。
"需要批准"就是那个断点。
决定三:工具在客户端跑,结果当成一条新消息发回去
一个回合的形状:
用户敲回车
→ 组请求体(只发增量)→ 开流
→ 看这次为什么停:
正常结束 → 回合结束
需要批准 → 分三堆:自动放行 / 自动拒 / 问用户
出错 → 重试或报错
→ 本地执行工具
↺ 把工具结果当成一条新消息再发一次
注意这条回边的性质:它不是"循环再转一圈",而是"再发起一次完整的请求"。 一个用户回合被拆成 N 次服务端往返。
对本课题的意义:"循环"这个词在这里名不副实。 真正在转的是"客户端和服务端之间的往返",循环体在服务端。 这跟 qwen-code 的"