- 人工智能
- AI 应用
- 交互助手
- AI Agent
【免费下载链接】ironclaw
IronClaw is an Agent OS focused on privacy, security and extensibility
IronClaw 将"持久化记忆"拆分为"provider-neutral 契约"与"可插拔提供方"两层:memory-native(扩展 idironclaw.memory)是随二进制默认捆绑、基于文件系统实现的[memory]提供方,负责记忆文档的读写、搜索、树形浏览、结构化用户档案,以及检索前(retrieve-before)/记录后(record-after)的完整生命周期。本文以 crates/extensions/packages/memory-native/CLAUDE.md 为骨架,结合该包的源码、manifest.toml、prompt 资产与测试套件,讲清它"拥有什么、如何实现、受哪些约束"。
一、包的定位:契约在ironclaw_memory,实现在ironclaw_memory_native
memory-native是一个完整的 self-contained 包,目录本身即"crate + manifest + prompts + schemas"四位一体(CLAUDE.md "Start Here" 一节)。它与mem0包是同一[memory]提供方表面的两个候选实现——每次部署恰好激活一个(README.md),默认就是本包。
# crates/extensions/packages/memory-native/manifest.toml id = "ironclaw.memory" name = "Reborn Memory" trust = "first_party_requested" [runtime] kind = "first_party" service = "native_memory_provider" [memory] lifecycle = ["read_long_term", "read_short_term", "record_interaction", "profile_read"] guidance_doc = "prompts/memory-guidance.md"关键分层事实:
- 契约归属:
MemoryServicetrait、DTO、scope/path/context 值类型、prompt-safety 词汇表、审计/事件契约都定义在 crates/domains/ironclaw_memory,本包只实现并 re-export(lib.rs)。 - 依赖集非常克制(Cargo.toml):只依赖
ironclaw_memory、ironclaw_filesystem、ironclaw_safety、ironclaw_host_api四个 crate;不依赖 mem0、任何 HTTP client、ironclaw_extension_host/ironclaw_extension_manager或任何 kernel/product crate。 - 链接方式:包 crate 只被二进制链接,唯一例外是
ironclaw_host_runtime持有普通依赖(其捆绑式内存包构建器见 crates/kernel/ironclaw_host_runtime/src/memory_native_extension.rs),这是契约文档中明确记录的 pending port inversion,而非迁移。
二、本包拥有的功能面(What This Crate Owns)
1. 文档仓储与后端插件契约
MemoryDocumentRepository有两个实现:
FilesystemMemoryDocumentRepository:生产部署目标,单层叠加在RootFilesystem之上;InMemoryMemoryDocumentRepository:仅测试支撑,绝不用于部署(CLAUDE.md "Guardrails")。
后端层MemoryBackend/RepositoryMemoryBackend/MemoryBackendCapabilities(backend.rs)封装"仓储 + 索引器 + 能力声明"。能力声明是强制执行输入:声明不支持的搜索/文件行为会在后端产生任何副作用之前 fail-closed。原生后端默认声明(见 service.rs 的build_native_backend):
file_documents = true, metadata = true, versioning = true, prompt_write_safety = true, full_text_search = true, delete = true, transactions = true注意:不声明vector_search——本包没有 embedding-provider 端口,向量检索只能针对预先提供的 embeddings 激活,否则在后端 fail-closed 消息中直接拒绝(这正是"无向量、纯 FTS"的设计取舍,mem0 后端则相反)。
2./memory虚拟路径语法与 scope
MemoryDocumentPath:以(tenant_id, user_id, agent_id, project_id, relative_path)定位一条记忆文档;MemoryDocumentScope(path.rs):拒绝空字符串作为提供的 id,因此"未指定 agent/project"的存储哨兵必须用空字符串,而_none只是虚拟路径哨兵、永远不得落库。
唯一性约束:UNIQUE (tenant_id, user_id, agent_id, project_id, path)。每一条读/列/搜索/写/版本/分块操作都按完整四元组过滤,绝不从路径前缀推断 project scope(CLAUDE.md "Guardrails")。
3. 分块、内容哈希与索引器
ChunkConfig、chunk_document、content_sha256(chunking.rs)负责把文档切成块并做内容寻址;ChunkingMemoryDocumentIndexer(indexer.rs)把块写入索引。写入提交语义:一旦持久化成功即视为已提交,之后派生索引/embedding 刷新失败不得让写入报告失败(否则会把"持久化已成功"误报为失败)。
4. 混合搜索:FTS + 向量经 RRF 融合
MemorySearchRequest/MemorySearchResult/FusionStrategy(search.rs)实现了混合搜索骨架:全文检索与向量检索各自产生候选集,再通过 RRF(Reciprocal Rank Fusion)融合排序。由于原生后端vector_search=false,实际运行时走纯 FTS 路径——MemorySearchRequest::new(&query).with_limit(...).with_pre_fusion_limit(limit.max(20)).with_vector(false)(service.rs 的search方法)。
5. 文件系统适配器与显著事件 sink
MemoryBackendFilesystemAdapter/MemoryDocumentFilesystem(filesystem.rs):把记忆文档映射到虚拟文件系统;- 显著事件 sink(events.rs):记忆写入/检索的关键节点产生审计事件。
6. 提示写入安全引擎(PromptWriteSafetyPolicy)
词汇表(operation、source、severity、reason code、事件 payload/sink、policy trait、protected-path registry)在ironclaw_memory,强制执行引擎在本包(safety.rs):
DefaultPromptWriteSafetyPolicy=PromptProtectedPathRegistry+ironclaw_safety::Sanitizer;check_write先做 protected-path 分类,再跑 sanitizer,把Severity映射到契约的PromptSafetySeverity桶(Low/Medium/High/Critical)。
三、模型面记忆指引(guidance_doc):提供方自带的"什么该记"
prompts/memory-guidance.md是[memory].guidance_doc声明的模型面指引(service.rs 通过MEMORY_GUIDANCE/MEMORY_GUIDANCE_DOC_REF常量 +MEMORY_ASSETS资产表捆绑),要点:
- 保存时机:用户给出持久偏好、事实、决定或纠正时,主动用
ironclaw.memory.write保存(targetmemory、append: true、一行自包含简洁事实),不要等被要求; - 措辞纪律:写成关于用户的陈述句("User prefers concise responses"),绝不写成给自己的指令("Always respond concisely")——因为保存的文本会在每个后续回合作为上下文被重新读取,祈使句会变成一条覆盖用户当前请求的常驻指令;
- 不保存清单:任务进度、会话结果、已完成工作日志、临时 TODO、PR 号/issue 号/commit SHA 等短期工件;一两周内会过时的事实不进持久记忆;绝不保存 secrets、凭据、token;
- 去重更新:写入前先 search/read,更新已有条目而非追加近似重复;显式"忘记"用
append: false重写文档(追加式纠错会让原始条目仍然留在原地,记忆块会同时携带两者)。
这一指引属于提供方自有资产,因为它点名本提供方的工具、描述本提供方的召回行为;host 只把绑定提供方声明的指引拼进 system prompt,自己不写任何一句。mem0 故意不提供 guidance(无追加)。
四、五个模型工具面:read / write / search / tree / profile_set
manifest.toml的[[tools]]数组声明了 5 个工具,input/output schema 由schemas/memory/*.v1.json资产内联提供(单一事实源),prompt 文档在prompts/memory-native/:
| 工具 id | 行为 | effects | 默认权限 | origin gate(loop_run) |
|---|---|---|---|---|
ironclaw.memory.read | 读当前 scope 的持久记忆文档 | read_filesystem | allow | ungated |
ironclaw.memory.write | 写/追加/补丁记忆文档 | read_filesystem+write_filesystem | allow | gated_unless_granted |
ironclaw.memory.search | 仅搜索内部持久记忆 | read_filesystem | allow | ungated |
ironclaw.memory.tree | 以紧凑树列出记忆文档 | read_filesystem | allow | ungated |
ironclaw.memory.profile_set | 记录 timezone/locale/location 结构化档案 | read_filesystem+write_filesystem | allow | ungated |
安全要点(manifest 注释明确):origin_gate_matrix缺失不等于"无门禁"——S4 授权折叠对任何带 origin 戳的调用 fail-closed 到Forbidden。Product/Automation 对全部五个工具都是forbidden(deny-by-default);write 保持gated_unless_granted(可写任意路径);read-like 工具通过UNGATED_LOOP_RUN_CAPABILITIESallowlist 放行。
write 的路径别名与解析
resolve_target_path(service.rs)定义了 4 个约定别名 + 任意相对路径:
| target | 解析结果 |
|---|---|
memory | MEMORY.md(常驻记忆文档) |
heartbeat | HEARTBEAT.md |
bootstrap | BOOTSTRAP.md(清空语义) |
daily_log | daily/YYYY-MM-DD.md(按调用方 timezone 解析,缺省 UTC) |
| 其他 | 原样作为相对路径 |
profile_set 与档案路径
profile_set/profile_read使用独立于 agent/project 的档案路径:profile_scope_and_path把 scope 钉在(tenant_id, user_id, agent=None, project=None),文档路径固定为context/profile.json——这是"关于人类用户本人的私有本地事实",与builtin.trace_commons.profile_set无关。写入用 compare-and-write(CAS)+ 至多MAX_MEMORY_PATCH_RETRIES = 8次重试,并校验 timezone/locale/location 字段必须为字符串。
五、生命周期钩子与双通道召回
manifest 声明了完整生命周期:read_long_term、read_short_term、record_interaction、profile_read(未声明的钩子永远不会被调用)。NativeMemoryService是纯内部实现,模型只能通过工具触达,生命周期钩子由 host 驱动(service.rs 的MemoryServiceimpl)。
常驻 MEMORY.md 前缀(read_long_term 的 always-on curated prefix)
本提供方在自己的长程通道头部、全文命中之前无条件投放常驻MEMORY.md(#7185),与本次查询无关:
- 理由:全文搜索只有在当前消息与存储事实共享词汇时才有效——新开一个无关话题的会话,已保存的偏好就不可见了;而 write 指引让模型维护的正是这份常驻文档;
- 上限
MAX_CURATED_SNIPPETS = 4,防止常驻文档吃光调用方的max_snippets配额、饿死其后的搜索命中; - 分块
CURATED_CHUNK_RAW_BYTES = 400字节/块:host 对模型可见 snippet 有 512 字节上限并跑 prompt denylist,分块保证每个模型可见字节都经过与搜索命中相同的检查,携带 denylisted 秘密的行只丢自己、不连累整份文档; - 截断标记
" (truncated)"与行内分隔符"; "都是明文单词——方括号等符号会被 host 的 safe-summary 规则拒绝; - 缺失是正常态(用户从未保存过任何东西),此时优雅降级为空前缀,而非让通道失败;后端故障同样降级并打
debug!——记忆是最佳努力上下文,绝不让一次 turn 随它一起倒下。
长/短程双通道
read_long_term:常驻前缀 + 全文命中;从候选集中剔除threads/子树(与短程通道保持不相交)和MEMORY_PATH本身(避免重复占槽);read_short_term:只检索活动线程的threads/<thread_id>/子树;thread_id来自可信 host 运行上下文,绝不来自模型;无活动线程则降级为空;- 两个通道共享
ranked_in_scope_results:先超量抓取(max_snippets * 8,下限 64)再做 scope+通道过滤,最后才截断——否则全局 top-N 的普通长程命中会饿死线程限定的短程通道。
record_interaction:每轮转录写入threads/
record_interaction把完整 turn 历史以 Markdown 转录(每条消息## {role} ({name}))写入每轮独立文件threads/<thread_id>/<turn_run_id>.md(append: false覆盖写):
- 幂等性:调度器重跑已
Completed的 run 会覆盖同一文件,而不是把对话复制进无限增长的共享log.md; - 这是唯一合法的
threads/写入口:公共write对任何threads/前缀目标直接拒绝(保留命名空间审计 L1——散落写入会成为"检索黑洞"),只有可信的记录器经write_reserved_document绕过该守卫,且该 helper 自身也防御性拒绝非threads/路径。
六、版本控制、补丁与并发安全
- Patch 语义:
old_string/new_string都非空(保留 Origin 的"空 new_string 不得删除匹配文本"约束),支持replace_all;基于 CAS(expected hash)+ 至多 8 次重试的 read-compare-write 循环; - append 语义:每条追加条目以恰好一个换行符终止——后端 append 是字节精确的,若不加换行,两条受引导的正确保存("likes tea" 与 "lives in Berlin")会拼成一行
likes tealives in Berlin被当成一个事实; - 并发安全测试:
tests/用#[tokio::test(flavor = "multi_thread", worker_threads = 2)]跑针对replace_document_chunks_if_current的真实抢占竞态测试(Cargo.toml 注释:单线程下tokio::join!协作式轮询会隐藏真实竞态,因此显式依赖rt-multi-thread)。
七、路径安全与输入卫生
reject_local_or_traversal_path拒绝三类输入(service.rs):
- 含
\反斜杠的路径; - 形如文件系统绝对路径 /
~/开头 / 盘符(C:\、C:/)的路径; - 含
..遍历片段的路径(按/分段检查)。
八、守卫与边界(Guardrails / Do Not Move In Here)
从 CLAUDE.md 提炼的可执行约束:
- 依赖纪律:只依赖上述四个 crate;
ironclaw_extension_contracts仅在某个表面真正需要时才允许加入; - scope 纪律:后端是 host 解析 scope 之后的插件,不得推断更宽的 tenant/user/agent/project 权限,不得绕过 mount/scope 文件系统检查;
- 语义搜索、分块、embeddings、版本控制必须留在 memory 自有的 repository/indexer 抽象之后;通用 mount/catalog 逻辑留在
ironclaw_filesystem; - 不迁移入本包:中性
MemoryService词汇表(留在ironclaw_memory)、通用文件系统语义、直接 provider HTTP、原始 secret 处理、loop prompt 策略; - 输出纪律:错误、事件、快照、日志、文档中不得出现 secrets、raw host 路径、后端错误细节、未脱敏的用户内容。
九、验证体系:契约测试套件
验证分三层(CLAUDE.md "Validation"):
- 快速本地检查:
cargo test -p ironclaw_memory_native——tests/下五个契约文件:- memory_service_contract.rs(共享
MemoryService一致性套件) - memory_backend_contract.rs
- memory_filesystem_contract.rs
- repo_filesystem_contract.rs
- repo_in_memory_contract.rs 这些测试瞄准内存后端,覆盖版本控制、chunk 替换、metadata 级联、混合搜索融合等记忆文档语义(后端特定的 libSQL/Postgres 行为覆盖属于
ironclaw_filesystem的后端契约测试);
- memory_service_contract.rs(共享
- 边界检查:依赖/API 变更后跑
cargo test -p ironclaw_architecture_tests; - 跨提供方一致性:同一共享套件也跑在 mem0 包上——契约变动时必须让两个提供方都保持通过。
测试基建注意点:test-supportfeature 默认关闭,避免契约测试 harness 中的.expect/.unwrap/assert!*进入生产构建并触发 scripts/check_no_panics.py 扫描;本 crate 的集成测试通过自依赖ironclaw_memory_native = { path = ".", features = ["test-support"] }启用(Cargo.toml)。
十、调度运维:每十轮一次的记忆整理(scheduled_ops)
manifest 中声明了提供方自有的循环维护(#7664):
[[memory.scheduled_ops]] trigger = "after_turn" interval_turns = 10 pass = { prompt = "prompts/memory_curation.md", tools = ["ironclaw.memory.read", "ironclaw.memory.search", "ironclaw.memory.write"], max_model_calls = 10 }- 归属原则:整理工作属于提供方——prompt 描述本提供方的文档形状、挑选本提供方的工具,因此随 manifest 声明而非放在 product/loop 层;host 只负责时钟、调用信封与授权;
- 预算:
max_model_calls = 10是本轮自身预算(低于 host 上限);#7770 的实测显示真实模型会多花调用(一次失误的 read、一次多余的 write),需要余量来完成报告; - 工具选择限制:pass 的 tools 只能从同一 manifest 声明的
[[tools]]中挑选,且每次调用仍要过常规能力授权。
整理 prompt(prompts/memory_curation.md)与 guidance 资产一起由MEMORY_ASSETS表承载,host 通过泛型解析(不按包名硬编码匹配),manifest 引用与资产文本由native_bundle_declares_guidance_that_resolves_to_the_bundled_asset测试保证不漂移。
结语
memory-native是"契约中立、实现可插拔"架构的完整样本:ironclaw_memory定义词汇表与行为契约,本包以文件系统为底座、以严格依赖集和 fail-closed 能力声明为边界,提供常驻记忆前缀、长/短程双通道召回、每轮转录、结构化档案与提示写入安全,并通过共享一致性套件与 mem0 提供方保持可互换。若需替换后端,可参照../mem0包实现同一MemoryService契约,二者在 compose 时经[memory]绑定切换,五个模型工具的输入/输出 schema 完全不变。
- 人工智能
- AI 应用
- 交互助手
- AI Agent
【免费下载链接】ironclaw
IronClaw is an Agent OS focused on privacy, security and extensibility
相关推荐
IronClaw 内存契约解析:provider 无关的 MemoryService 抽象与 /memory 路径文法
IronClaw 内存契约解析:provider 无关的 MemoryService 抽象与 /memory 路径文法 IronClaw 将"内存"抽象为一个
人工智能AI 应用交互助手AI AgentIronClaw 记忆契约层深度解析:provider-neutral 的 MemoryService 接口、`/memory` 路径语法与 Prompt 写安全边界
IronClaw 记忆契约层深度解析:provider neutral 的 MemoryService 接口、 /memory 路径语法与 Prompt 写安全
人工智能AI 应用交互助手AI AgentIronClaw 内存服务契约深度解析:provider-neutral 的 MemoryService 接缝与路径/安全词汇表
IronClaw 内存服务契约深度解析:provider neutral 的 MemoryService 接缝与路径/安全词汇表 本文围绕 IronClaw 中
人工智能AI 应用交互助手AI Agent
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考