内存和负载生命周期
ZeroClaw 在一次回合中会携带多种“记住的”信息。它们并不都具有相同的所有者、持久性、隐私边界或审查风险。
当更改涉及 memory、history、session persistence、tool results、files、media attachments、summaries、context trimming 或 prompt assembly 时,请使用此页面。最重要的问题不是“代理是否记得这一点?”,而是“哪个 surface 拥有这些数据,以及它会存活多久?”
谁拥有什么
| Surface | 所有者 | 持久性 | 审阅者应检查什么 |
|---|---|---|---|
| 长期记忆 | zeroclaw-memory 在 Arc<dyn Memory> 后面 | 后端特定:SQLite/Postgres/Lucid/Qdrant/共享存储,或每个代理的 Markdown 文件 | 存储和回忆必须保持 agent 作用域。工具结果、日志行或会话行并不构成长期记忆,除非发生了 memory write。 |
| 关系记忆 | knowledge 工具和知识图谱 | 启用时的 Graph 后端 | 捕获是显式的。启用图并不会自动摄取会话、文件或频道数据。 |
| 会话历史 | zeroclaw-infra 会话后端、ACP 存储和实时 RPC/会话映射 | Chat/ACP 历史可以持久化;实时 RPC 句柄是进程本地的 | 历史记录用于保留对话连续性。它不是用户偏好、配置或文件的权威存储。 |
| 当前提示上下文 | Agent 循环提示词组装 | 临时 provider 请求 | 已调用的记忆、硬件 RAG、当前输入、系统提示、技能和工具结果可能会发送给提供方。这并不意味着它们会持久保存。 |
| 历史修剪 | agent::history 和 agent::history_trim | 对请求/会话历史结构的有损更改 | 裁剪必须可见,保留 tool-call/tool-result 配对,并避免假装旧上下文仍然可用。 |
| 工具结果负载 | ToolResult、ToolResultMessage 和工具分发器 | 当前轮次以及记录该轮次的任何持久会话历史 | 限制大小和来源。大型输出应有意地截断或汇总;图像路径提升必须仅适用于生成工具,而不是路径列表工具。 |
| 文件和工作区 | 每个代理的工作区安全策略 | 文件会根据文件系统而不是内存持久保存 | 文件内容并不因为工具读取了它们就算作内存。除非策略明确允许更多,否则写入应保留在代理工作区中。 |
| 媒体附件 | 频道/网关媒体管线和 MediaAttachment | 默认情况下为入站负载;持久性取决于接收路径 | 原始字节应保持有界并经过路径验证。应有意存储摘要或引用,而不是在不知不觉中将媒体复制到内存中。 |
| 日志和观察器事件 | zeroclaw-log, ObserverEvent, 运行时跟踪 | 可选运行时跟踪和实时观察器 | 日志是证据和诊断信息,不是事实来源内存。在记录日志之前,应清理或限制用户/工具负载。 |
| 成本和用量记录 | 成本跟踪器和提供商使用事件 | 启用时的成本账本 | 使用记录描述模型调用。它们不应包含提示正文、工具输出或记忆内容。 |
此表补充了 运行时状态和持久化。该页面说明状态存放在哪里;本页面说明面向用户的载荷如何在内存、历史记录、工具、文件、媒体和提供方请求之间流转。
长期记忆
代理从内存工厂接收其内存句柄。共享后端和 Markdown 存储具有不同的具体布局,但审查规则相同:内存访问必须始终绑定到代理身份以及 Runtime internals 中描述的已配置对等方允许列表。
信息变成持久记忆通常有两种方式:
- 该代理调用诸如
memory_store之类的内存工具; - 运行时代码会显式存储一条内存条目,例如已配置的对话自动保存路径。
默认不要将提示上下文、工具输出、文件或日志视为持久记忆。若某个 PR 要使这些表面中的任意一个变为持久化,必须注明记忆类别、会话范围、代理范围、保留行为以及操作员可见的控制。
提示上下文和回忆
在回合开始时,运行时可以回忆相关记忆,并将一个有界的 [Memory context] 块注入到用户可见的提示上下文中。相关入口点并不都应用相同的过滤器。通道/交互循环会在该回合没有安全的会话作用域或不是用户发起时,过滤生成的自动保存噪声、过期的 <tool_result> 块以及 Conversation 条目。通用记忆加载会过滤自动保存噪声和相关性,但其本身并不强制执行通道循环的 Conversation 排除。
因此,provider 请求可以包含回调的 memory,而不会将当前轮次变成新的 memory。通过提出以下问题来审查 prompt 组装更改:
- 查询了哪个内存后端和代理作用域;
- 当允许会话条目时,该查询是否为会话范围内的;
- 是否仍然过滤自动保存噪声、过期的工具结果块和低相关性条目;
- 用户或操作员是否可以看到何时移除了较旧的上下文。
会话历史和修剪
会话历史是对一次对话的连续记录。它可以包括聊天消息、助手工具调用和工具结果。它与长期记忆不是一回事。
历史管理负责裁剪机制。此页面只定义生命周期边界:裁剪是对提供方可见/会话可见上下文的一种有损更改,而不是内存删除,并且它必须是可见的,而不是悄无声息地假装旧上下文仍然可用。
工具调用配对比节省字节更重要。历史更改绝不能让提供方请求中留下没有匹配 tool_result 的悬空 tool_use,反之亦然。
工具结果
工具返回一个小型结构化结果:success、output 和 error。调度器会将这些结果转换为提供方消息,以供下一次模型调用使用,而流式客户端可以在该轮交互期间接收相关联的 ToolCall 和 ToolResult 事件。
工具结果载荷很容易过度保留。审阅者应检查:
- 最大结果大小,包括
max_tool_result_chars; - 截断是否会保留结构化信封和图像标记;
- 搜索/列表工具是否会避免将偶然出现的图像路径转换为媒体负载;
- 收据、日志和观察者事件是否携带有界、已清理的证据,而不是原始敏感输出;
- 结果是否只存在于当前轮次/会话历史中,还是也被有意写入了记忆。
如果一个 PR 说某个工具结果是“记住的”,则要求它说明这是否指提供方可见的历史、持久化会话历史、内存后端行、文件工件、回执,还是日志事件。
文件和媒体
文件内容和媒体字节是负载,不是记忆。Filesystem 的所有者是 Filesystem components 和 Runtime internals 中所描述的 per-agent 工作区策略。文件读取可以将内容放入工具结果或提示中;文件写入可以创建持久的文件系统状态;二者都不会自动创建 memory 行。
传入通道消息可以携带带有文件名、字节和可选 MIME 类型的 MediaAttachment 值。MediaKind 由 MIME 类型或文件扩展名推导得出。底层附件加载器会原样读取调用方提供的路径,因此,接受不可信路径的调用方必须在加载之前验证或约束这些路径。
对于文件和媒体,审阅者应查找:
- 在读写之前执行 workspace policy enforcement;
- 当路径来自用户、HTTP 请求、channel payload 或工具参数时进行路径验证;
- 有界字节处理以及对缺失或不可读文件的明确失败行为;
- 当大型/二进制负载进入提示时,提供明确的摘要或引用;
- 不要将附件或文件内容静默复制到长期记忆中。
日志与可观测性
Observer 事件和运行时日志有助于解释发生了什么。它们不应变成隐藏的有效载荷存储。Memory recall 事件携带经过清理/截断的查询摘要和计数。Memory store 事件携带有界的类别和后端标识符。
工具调用可观测性需要额外谨慎,因为各个接收端并不共享同一种载荷契约。当前带类型的工具调用观察器事件可以携带完整参数以及经过凭据清理的完整结果输出,而 OTel 会将这些值转发到 span 属性中。除非代码实际对其进行了边界限制或摘要处理,否则不要将这一路径描述为“摘要”。新的遥测应优先使用受限标识符、计数、持续时间、成功标志以及对操作员有用的摘要。只有在该功能明确要求且已记录隐私边界时,才将原始内容放入日志或观察器事件中。
审阅者清单
对于内存、payload、历史、文件或媒体更改,在审阅者签字确认前,请先回答以下问题:
- 数据的规范所有者是什么?
- 它是仅限当前轮次、会话持久、文件系统持久、内存持久,还是日志持久?
- 哪个 agent、session、channel 或 workspace 作用域会限制访问?
- 调用方可以将内存回忆范围扩大到超出已配置的允许列表吗?
- 自主作业能看到聊天发起的对话记忆吗?
- 什么限制工具输出、文件字节、媒体字节和提示大小?
- 截断或裁剪会让损失变得可见,而不是静默发生吗?
- 提供者可见的负载是否与持久内存写入分离?
- 日志和 observer events 是否经过清理并且有界?
- 如果 PR 更改了生成或派生的 payload,是否会更新源 owner,而不是手动编辑生成的输出?
源指针
规范文档:
关键代码入口点:
- 内存 trait 和条目形状:
crates/zeroclaw-api/src/memory_traits.rs - 内存工厂和 agent 作用域:
crates/zeroclaw-memory/src/lib.rs、crates/zeroclaw-memory/src/agent_scoped.rs和crates/zeroclaw-memory/src/agent_scoped_markdown.rs - Memory tool 注册表和示例:
crates/zeroclaw-tools/src/lib.rs(MEMORY_TOOL_NAMES)、crates/zeroclaw-tools/src/memory_store.rs和crates/zeroclaw-tools/src/memory_recall.rs - Prompt 回忆和注入:
crates/zeroclaw-runtime/src/agent/memory_inject.rs(回忆策略以及[Memory context]渲染器),由引擎侧注入到crates/zeroclaw-runtime/src/agent/turn/mod.rs;逐轮 memory 句柄通过crates/zeroclaw-runtime/src/agent/loop_.rs传递 - 历史裁剪和工具结果载荷整形:
crates/zeroclaw-runtime/src/agent/history.rs、crates/zeroclaw-runtime/src/agent/history_trim.rs和crates/zeroclaw-runtime/src/agent/turn/results_collect.rs - 工具和提供者消息形状:
crates/zeroclaw-api/src/tool.rs和crates/zeroclaw-api/src/model_provider.rs - 频道附件:
crates/zeroclaw-api/src/channel.rs和crates/zeroclaw-api/src/media.rs