Agent 实现方法论
From Scratch
学习地图
练习
术语表
← 返回首页
本章教程
本章练习
第 16 章测验
第 16 章测验
对应章节:断线恢复与后台运行 v03
共 8 题,答对率 ≥ 80% 即通过。请完成全部题目后点击「提交」。
Q1
第 16 章给事件加 seq(会话内单调递增序号),核心动机是什么?
让事件流里的每条事件都有一个可寻址的位置:客户端断线后能精确说出「我从第几条断的」,服务端据此只补发增量,而不是全量重放
让事件更容易被 JSON 序列化
给事件加上加密密钥
让 mock 模型能区分不同会话
Q2
seq 的语义有三条规则:会话内单调递增、跨会话独立、跨多轮运行连续。其中「单调」比「连续」更重要,为什么?
因为单调递增实现起来更简单
因为运行可能被取消/失败而留下序号空洞(如 1、2、3、7、8),客户端必须只依赖「seq 越大越新」,不能假设每跳只差 1
因为连续递增会让序号很快耗尽
因为跨会话需要共用一个计数器
Q3
产品代码里 seq 是谁盖的?为什么不在 loop 内部写死一个计数器?
存储层每次 append 时盖的;loop 盖会双重编号
主循环在 emit 时盖的,分配器作为参数注入(按会话持有、跨运行共享);loop 保持无状态,不注入分配器就没有 seq(CLI 即如此)
客户端收到事件后自己编号
SSE 帧格式自动带序号
Q4
getSince(sessionId, since) 的语义是什么?
返回该会话所有事件,按时间倒序
只返回 seq > since 的事件,按序排列;不含 since 本身,未知会话或 since 超过终点返回空数组
返回 seq >= since 的事件,含 since 本身
返回该会话最后一条事件
Q5
GET /events 的 since 参数缺省或非法时,服务端怎么处理?
直接返回 400 错误
视为 0,即全量回放——与 ch15 行为一致,老客户端无需改动
视为当前会话的 lastSeq,只收新事件
随机挑一个序号
Q6
POST /chat 的响应新增了 lastSeq 字段,它的用途是什么?
让客户端知道这一轮对话花了多少 token
让客户端从「本次提交前事件流的终点」开始订阅,从而只收这一轮运行产生的新事件
服务端心跳
用于前端渲染时间戳
Q7
「断开连接后 Agent 继续跑(后台运行)」在存储层的本质是什么?
服务器为每个客户端单独开一个 Agent 副本
append 不要求有任何订阅者:事件照常落库、照常编号,连接只是读取进度的窗口
断线后 Agent 暂停,等客户端重连再继续
需要 WebSocket 才能实现
Q8
为什么协议允许事件重复投递,而把「幂等」的责任放在客户端?
因为服务端无法保证顺序
网络层会重试、SSE 可能重推、客户端可能把 since 传错(多记漏一条、少记重一条)——服务端只保证单调、有序、可寻址,不保证恰好一次;客户端必须按 seq 去重、对 done/tool_result 做状态守卫
因为 seq 不够用
因为 mock 模型会重复返回结果
提交