07 Workspace / Memory / State
学习目标:能区分会话上下文、任务状态、长期记忆、工作区文件和中间产物。 重点度:需要会(8 分) 前置要求:Ch5 Agent Runtime、Ch6 工作流编排
概述#
Agent 执行复杂任务时,不能只依赖上下文窗口——窗口有限、易失忆、重启就丢。
本章解决"Agent 的状态放在哪"的问题。注意与 Ch3 Context 工程的边界:
| Ch3 Context 工程 | Ch7 Workspace/Memory/State |
|---|---|
| 决定什么进上下文窗口 | 决定状态放在外部哪里 |
| 实时 token 预算管理 | 持久化、跨会话、跨任务 |
| 模型推理时管理 | 模型推理外管理 |
三种状态:会话状态 / 任务状态 / 工作区状态#
1. 会话状态(Session State)#
一个用户会话的上下文:
text
session_id: abc123
user_id: user_456
messages: [...] ← 完整对话历史
current_agent_step: 7
budget_used: 50K token
created_at: ...
last_active: ...特征:
- 临时性强(会话结束可能就归档)
- 实时变化(每步都在更新)
- 大小受限(上下文窗口限制)
存储:Redis(实时读写) + DB(持久化)
2. 任务状态(Task State)#
一个长任务的执行进度:
text
task_id: task_789
session_id: abc123
plan: ["读 README", "分析 src", "生成报告"]
completed_steps: ["读 README", "分析 src"]
current_step: "生成报告"
status: "in_progress"
checkpoint: {...}
artifacts: ["report_draft.md"]特征:
- 跨会话持久(任务可能跑几小时/几天)
- 结构化(步骤/状态/产出)
- 可恢复(checkpoint)
存储:DB + Workspace 文件
3. 工作区状态(Workspace State)#
Agent 操作的文件、目录、产出物:
text
/workspace/task_789/
├── task.md ← 任务说明
├── plan.md ← 当前计划
├── progress.md ← 进度日志
├── scratch/ ← 临时草稿
│ ├── notes.md
│ └── temp_data.json
├── output/ ← 交付物
│ └── report.md
└── .state/ ← 内部状态
├── checkpoint.json
└── messages.json特征:
- 文件形式(不是 DB 记录)
- 可读可写(用户也能看)
- 跨任务共享(同一 workspace 多任务)
存储:本地文件系统 / 对象存储
Scratchpad(草稿区)#
用途#
Agent 的"草稿纸"——记中间想法、临时计算、过渡产物:
text
Scratchpad 内容示例:
- "用户要求分析 repo, 我先列出关键文件"
- "package.json 显示依赖 React 18, 这意味着..."
- "测试覆盖率 30%, 低于行业平均"
- "下一步: 看 src/auth 目录"关键设计#
- 不进上下文:scratchpad 放文件,不塞 messages,省 token
- 按需读:Agent 需要时再 read_file("scratch/notes.md") 读进来
- 可丢弃:任务完成后可清空
- 可审计:debug 时能看 Agent 当时怎么想的
短期记忆 / 长期记忆 / Skill Memory#
1. 短期记忆(Short-term Memory)#
= 当前会话的上下文。
- 范围:单次会话
- 存储:上下文窗口 + Redis
- 失效:会话结束归档
2. 长期记忆(Long-term Memory)#
跨会话记住用户偏好、历史任务、学到的经验:
text
长期记忆示例:
- 用户偏好: 喜欢简洁代码, 不喜欢注释过多
- 历史任务: 上周帮用户做过 repo 分析, 用了 React 模板
- 学到经验: 这个用户的项目都用 TypeScript实现方式:
| 方式 | 优势 | 劣势 |
|---|---|---|
| 向量库 RAG | 灵活、语义检索 | 召回不一定准 |
| KV 存储 | 精确、快 | 不灵活 |
| 结构化 DB | 可查询 | schema 死 |
| 文件 | 可读、简单 | 不易检索 |
实战策略:混合存储——结构化偏好存 DB,自由文本记忆存向量库。
3. Skill Memory(技能记忆)#
Agent 学到的"如何做某类任务":
text
Skill Memory 示例:
- "代码 review 任务": 应该先看测试覆盖率, 再看安全风险
- "部署任务": 应该先 dry-run, 再正式部署
- "数据处理": 应该先 sample 100 行看 schema实现:Skill 本身(见 Ch8)+ 执行经验记录。
⚠️ 注意:长期记忆写入要谨慎。记忆写错的后果比没记忆更严重——Agent 会基于错误记忆做错误决策。要有记忆审核/修正机制。
Checkpoint / Resume#
Checkpoint 内容#
python
checkpoint = {
"task_id": "task_789",
"step": 7,
"messages": [...], # 或压缩后的
"plan_state": "in_progress",
"completed_steps": [...],
"workspace_snapshot": "...", # 关键文件版本
"budget_used": {...},
"timestamp": "..."
}Resume 流程#
text
1. 加载最近 checkpoint
2. 恢复 messages 历史(或 summary)
3. 恢复 workspace 状态
4. 恢复 budget 状态
5. 通知 Agent: "你之前做到第 7 步, 现在继续"
6. Agent 从当前状态继续Checkpoint 存储策略#
| 策略 | 说明 |
|---|---|
| 全量 | 每次存完整状态,恢复简单但存储大 |
| 增量 | 存 diff,存储小但恢复复杂 |
| 滚动 | 保留最近 N 个 checkpoint,旧的归档 |
| 关键节点 | 只在关键步骤后存,节省存储 |
Workspace 设计实战#
目录结构推荐#
text
/workspace/
├── users/{user_id}/ ← 用户隔离
│ ├── sessions/{session_id}/ ← 会话级
│ │ ├── messages.json
│ │ └── scratch/
│ └── tasks/{task_id}/ ← 任务级
│ ├── task.md
│ ├── plan.md
│ ├── progress.md
│ ├── output/
│ ├── .state/checkpoint.json
│ └── logs/
└── shared/ ← 跨任务共享
├── templates/
└── skills/关键工程点#
- 隔离:用户间数据严格隔离(多租户)
- 配额:每用户 workspace 容量上限
- 清理:过期任务自动归档/清理
- 备份:关键 workspace 文件要备份
- 权限:workspace 文件有 ACL,Agent 不能越权读
文件 vs DB 的取舍#
| 内容 | 推荐存储 |
|---|---|
| 用户对话历史 | DB(结构化查询) |
| 任务进度状态 | DB |
| 中间草稿、笔记 | 文件(灵活、可读) |
| 交付物(报告/代码) | 文件(用户能直接看) |
| 长期记忆 | DB + 向量库 |
| Checkpoint | DB(结构化)+ 文件(workspace 快照) |
与 Ch3 Context 工程的协作#
text
[Agent 推理时]
上下文窗口 (Ch3 管理)
├── system prompt
├── 最近 N 轮对话
├── 当前工具结果
└── 从 workspace 临时读入的文件
[Agent 推理外]
Workspace 文件 (Ch7 管理)
├── 完整对话历史 (超出窗口的归档)
├── 任务状态
├── 长期记忆
└── 交付物
→ 上下文窗口是"工作内存", workspace 是"硬盘"
→ Context 工程 = 内存管理; Workspace = 持久化阶段产出#
完成本章后应该能:
- 区分会话状态 / 任务状态 / 工作区状态
- 设计 Workspace 目录结构(用户/会话/任务隔离)
- 实现 Scratchpad(不进上下文的工作笔记)
- 实现短期/长期/Skill 三类记忆
- 实现 Checkpoint / Resume(含增量存储策略)
- 处理多租户隔离、配额、清理、备份
- 协调 Ch3 Context 工程(窗口内)与 Ch7 Workspace(窗口外)
下一章 Ch8 进入 Skills / Plugins / Agent Extension——Agent 能力不能全写死,怎么通过 Skill/Plugin/MCP Server 扩展。