ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

agentmemory 架构深度解析:基于 iii 引擎的编码代理持久化内存服务

agentmemory 架构深度解析:基于 iii 引擎的编码代理持久化内存服务 agentmemory 架构深度解析基于 iii 引擎的编码代理持久化内存服务【免费下载链接】agentmemory#1 Persistent memory for AI coding agents based on real-world benchmarks项目地址: https://gitcode.com/GitHub_Trending/age/agentmemoryagentmemory 是一个面向 AI 编码代理coding agents的本地持久化内存服务器它捕获代理工作过程中的观测observations建立混合检索索引再通过 REST 与 MCP 两种面surface把记忆回放给代理。它不自己发明一套运行时而是完整构建在 iii 引擎之上一切能力都以函数 触发器的形式存在。读完本文你将掌握 agentmemory 的整体架构骨架、iii 原语的工作方式、三流混合检索的实现原理、端口布局规则以及记忆从捕获到遗忘的完整生命周期。agentmemory 是什么一个本地内存服务器从架构定位看agentmemory 是一个常驻本地的内存服务器memory server运行链路由三部分组成iii 引擎iii-engine——提供进程内状态KV、队列、发布订阅、定时任务、HTTP 服务器与可观测性等运行时原语agentmemory worker——由引擎拉起的一个 Node 进程node dist/index.mjs它向引擎注册全部内存函数对外接口——REST API默认:3111锚定端口与 MCP 工具面供 Claude Code、Cursor、Gemini CLI 等编码代理接入。worker 启动时会把~/.agentmemory/.env折叠进进程环境仅当对应键未设置时保证真实环境变量优先然后读取配置并完成全部函数注册见 src/index.ts 与 src/config.ts。启动日志会打印引擎地址、provider、embedding 维度、REST 端点与 streams 地址便于确认各组件就绪状态。iii 原语函数、触发器与 worker 状态agentmemory 架构上最重要的一条原则是它没有独立的插件系统。所有能力都建立在 iii 引擎的三个原语之上函数functionsworker 通过sdk.registerFunction(mem::xxx, handler)注册的具名能力例如mem::observe、mem::remember、mem::search、mem::consolidate触发器triggersHTTP 触发器api::*把 REST 请求路由到函数内部调用则通过sdk.trigger({ function_id: mem::xxx, payload })触发另一个函数worker 状态worker 启动时用registerWorker(engineUrl, {...})连接引擎声明自己的 worker 身份与遥测元数据project_name: agentmemory、language: node、framework: iii-sdk此后所有 KV 读写都经由引擎状态层完成。新增一项能力就等于新增一个函数 一个触发器而不需要任何注册中心之外的设施。例如注册mem::observe后REST 侧由registerApiTriggers暴露/agentmemory/observe二者共用同一个 handler。函数注册清单见 src/index.ts。引擎侧的 worker 拓扑iii-config.yamlagentmemory 的引擎配置由仓库根目录的 iii-config.yaml 描述它定义了引擎内部的一组 worker 拓扑worker 名称职责iii-httpHTTP 服务默认监听127.0.0.1:3111配置了 CORS 白名单默认放行 localhost:3111 / localhost:3113与 180s 默认超时iii-stateKV 状态适配器file_based存储落盘到./data/state_store.dbiii-queue内置队列适配器iii-pubsub本地发布订阅iii-cron基于 KV 的定时任务iii-stream实时流默认监听:3112file_based落盘./data/stream_storeiii-observability可观测性采集采样率0.1避免高负载下日志订阅积压形成正反馈指标与日志默认开启iii-exec执行器监听src/**/*.ts变更执行node dist/index.mjs拉起 worker这里有两个值得注意的工程细节其一iii-observability的sampling_ratio: 0.1是为了防止日志订阅 lag 告警重新进入同一条日志流形成放大循环代码注释记录了某个用户在几天内写出 137GB 日志的真实事故其二iii-exec的 watch 配置是开发态模型运行时 config 会被 CLI 复制到数据目录并改写file_path确保状态库落在用户指定的数据目录而非仓库内。检索模型BM25 向量 图的三流混合召回Recall 是 agentmemory 架构的核心。它采用的是混合检索BM25 关键词检索 向量相似度检索 基于关联概念的图扩展三者融合后再做会话级去重与排序。其实现位于 src/state/hybrid-search.ts核心入口tripleStreamSearch依次执行BM25 流对查询做词法检索取limit * 2条候选BM25 索引在启动时重建或从持久化快照恢复见 src/state/search-index.ts向量流若配置了 embedding provider 且向量索引非空先对查询生成 embedding再做向量近邻检索失败时优雅降级为纯 BM25图流从查询中抽取实体extractEntitiesFromQuery经GraphRetrieval.searchByEntities检索关联概念再取 Top-5 向量结果通过expandFromChunks做图扩展形成第二条图证据路径图检索是 best-effort失败不影响前两流。三流结果按RRFReciprocal Rank Fusion融合每条结果记录其在各流中的排名加权得分w * 1/(RRF_K rank)RRF_K 60再用各流实际产生结果的权重之和做归一化避免某条流静默时产生惩罚结果同时命中多条流的会获得AGREEMENT_BONUS0.05加成——这正体现了图扩展存在的价值即使关键词或向量命中的不是同一篇文档只要它们在图谱上相邻也能互相增强。融合之后还有两道后处理diversifyBySession限制同一会话最多贡献 3 条结果防止单一会话刷屏enrichResults回查 KV 补齐观测的完整内容。若开启RERANK_ENABLEDtrue还会对 Top-20 结果做一次重排src/state/reranker.ts。零 API Key 设计默认安装不需要任何 API key向量 embedding 在本地运行on-device见 src/providers/embedding/local.tsBM25 本身无需外部依赖。此时 boot 日志会明确提示Provider: noop (noop) Embedding provider: local ... Ready. Triple-stream (BM25VectorGraph) search active.LLM provider 只用于两项可选增强更丰富的摘要LLM compression与上下文自动注入context injection二者都默认关闭需显式开启见 src/config.ts 的AGENTMEMORY_AUTO_COMPRESS/AGENTMEMORY_INJECT_CONTEXT。因此记忆检索的核心链路在零成本、零密钥的前提下即可工作。检索权重配置混合检索的三流权重可在~/.agentmemory/.env中调节解析逻辑见 src/config.ts 与 src/index.ts环境变量默认值说明BM25_WEIGHT0.4BM25 流权重非法值回退 0.4上限 1VECTOR_WEIGHT0.6向量流权重非法值回退 0.6上限 1AGENTMEMORY_GRAPH_WEIGHT0.3图流权重RERANK_ENABLEDfalse是否开启 LLM 重排EMBEDDING_PROVIDER自动检测显式指定 embedding provider未设置时按 GEMINI → OPENAI → VOYAGE → COHERE → OPENROUTER 的键顺序自动推断存储模型与记忆生命周期数据模型记忆memories由以下字段构成内容content、概念concepts、关联文件files、重要度strength/importance与时间戳createdAt/updatedAt。它们被组织进会话sessions可选地与 git 提交commits关联。KV 的 scope 划分定义在 src/state/schema.tsmem:sessions—— 会话元数据project、cwd、observationCount、firstPrompt 等mem:obs:sessionId—— 按会话组织的观测mem:memories—— 长期记忆含isLatest、version、parentId、supersedes等版本字段mem:summaries、mem:relations、mem:graph:nodes、mem:graph:edges—— 摘要、关联、知识图谱其他高级 scopemem:lessons、mem:insights、mem:slots、mem:retention等。生命周期capture → compress → consolidate → forget记忆库不会无限增长而是由一套捕获、压缩、整合、遗忘的生命周期维持越用越有用的状态1. Capture捕获mem::observesrc/functions/observe.ts接收来自各类 hook 的载荷pre_tool_use/post_tool_use/post_tool_failure/prompt_submit校验sessionId、hookType、timestamp后先做去重DedupMap 对 sessionId toolName toolInput 计算哈希再做隐私清洗stripPrivateData随后按会话级 keyed-mutex 串行写入 KV 并推送到实时流stream::set/stream::send供 viewer 与订阅方消费。每条观测受MAX_OBS_PER_SESSION默认 500上限约束。2. Compress压缩默认走zero-LLM 合成压缩路径buildSyntheticCompression无需 API key 即可把原始观测提炼成可检索的标题、叙述与概念并同步写入 BM25 与向量索引只有显式开启AGENTMEMORY_AUTO_COMPRESStrue时才改为调用 LLM 生成摘要代价是 token 消耗与工具调用频率成正比启动时会打出醒目告警。3. Consolidate整合mem::consolidatesrc/functions/consolidate.ts把同一项目内达到阈值默认 10 条观测的会话聚合成长期记忆由 LLM 按系统提示输出 XML 结构type/title/content/concepts/files/strength随后写入mem:memories。此外还有更完整的mem::consolidate-pipeline与每小时/每日定时器CONSOLIDATION_INTERVAL_MS默认 7200000ms即 2 小时驱动自动整合。4. Forget遗忘mem::forgetsrc/functions/remember.ts支持按 memoryId、按 observationIds 或整会话删除删除会同步移除 BM25/向量索引条目、图片引用计数与访问日志并记录审计mem::audit。自动遗忘由mem::auto-forgetsrc/functions/auto-forget.ts每小时执行AUTO_FORGET_INTERVAL_MS默认 3600000ms处理三类对象TTL 过期记忆remember时设置ttlDays的记忆到期后自动删除矛盾记忆同一 concept 桶内 Jaccard 相似度超过 0.9 的成对记忆删除较旧的一条并保留审计记录低价值观测超过 180 天且 importance ≤ 2 的观测被回收。dryRun参数支持只预览不执行方便评估影响面。另外mem::remember还内置了记忆版本化与取代机制src/functions/remember.ts保存新记忆时用 BM25 索引召回候选与新内容做 Jaccard 相似度比较相似度 0.7 则新记忆取代旧记忆旧版本保留在 KV 中供 viewer 查看版本链但移出检索索引相似度 0.4~0.7 的命中会以similarTo提示返回供调用方决定是否整合。不同 project 的记忆不会被跨项目取代。端口布局以 REST 为锚点的四端口组agentmemory 的端口分配遵循一个固定公式REST 是锚点服务端口公式默认值REST APIN3111Streams实时流N 13112Viewer网页查看器N 23113iii engine内部总线N 4602349134--instance N会把整组端口右移N * 100--instance 1得到 3211 / 3212 / 3213 / 49234--instance 0保持规范的四件套。--instance取值范围 0~50实现见 src/cli.ts。此外--port N可单独覆盖 REST 端口streams/viewer/engine 依然自动派生避免二次碰撞。端口解析的完整优先级见 src/config.ts 与 src/cli.tsRESTAGENTMEMORY_URL中的端口 III_REST_PORT 默认 3111StreamsIII_STREAM_PORTIII_STREAMS_PORT旧名兼容REST 1EngineIII_ENGINE_PORTIII_ENGINE_URL中的端口 REST 46023ViewerAGENTMEMORY_VIEWER_URL 运行时通过/agentmemory/livez探测到的实际端口 REST 2。/agentmemory/livez是一个关键的探活端点CLI 的status、doctor与 viewer 地址发现都依赖它返回的viewerPort字段。iii-config.yaml中iii-http的 CORS 白名单默认放行 3111 与 3113 两个来源正是为了 REST 与 viewer 之间的跨端口协作。Viewer实时观测记忆构建过程agentmemory 自带一个实时网页查看器默认地址http://localhost:3113由startViewerServer在 REST2 端口启动见 src/viewer/server.ts。它订阅mem-live实时流viewer group随着会话运行观测与压缩结果会实时流入页面因此特别适合演示向他人展示记忆正在被构建的过程验证捕获是否生效跑一轮 hook 后立刻在页面上看到新增的 raw/compressed 观测。Viewer 还承担了版本链查看superseded 记忆的历史版本与 REST 代理的职责。安全方面它内置了多重防护Host 头白名单防 DNS rebinding 攻击、Origin 白名单VIEWER_ALLOWED_ORIGINS、绑定地址默认 127.0.0.1AGENTMEMORY_VIEWER_HOST可改以及可选的AGENTMEMORY_SECRET鉴权。延伸阅读围绕本文涉及的架构模块仓库内还有更深入的配套文档agentmemory-mcp-tools 技能参考 与 agentmemory-rest-api 技能参考两种对外访问面的完整工具/端点清单agentmemory-hooks 技能参考hook 如何自动捕获观测、何时写入mem::observeagentmemory-config 技能参考端口与全部 feature flag 的权威说明iii 引擎配置文件 与 CLI 入口引擎 worker 拓扑与端口派生的实现依据。理解这套架构后无论是排查为什么搜索返回为空可沿 BM25 索引重建 → 向量维度校验 → 三流权重顺序排查还是规划新增一种记忆能力新函数 触发器而非新建插件系统都有了清晰的着手点。【免费下载链接】agentmemory#1 Persistent memory for AI coding agents based on real-world benchmarks项目地址: https://gitcode.com/GitHub_Trending/age/agentmemory创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进