AI 应用人工智能AI Agent本地部署前端后端工作流自动化【免费下载链接】ekko-studioEkko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.项目地址https://gitcode.com/gh_mirrors/he/ekko-studio点击查看免费下载本篇技术指南以 Ekko Agent 记忆系统规划文档 为核心骨架结合 ekko-agent 包中src/memory/与src/database.ts的完整源码实现系统讲解 Ekko Agent 如何用唯一一张记忆卡片集合memory_nodes承载全部长期记忆从前台运行链路、四个记忆工具的参数契约到受控 kind 与 canonical key 的生成规则、并发安全的 revision 机制再到ekko.db的表结构与崩溃安全迁移策略。读完本文你将掌握 Ekko Agent 记忆系统的完整数据流能准确理解memory_search/memory_get/memory_write/memory_forget的正确调用姿势以及数据库在旧进程仍写入时为何宁可阻止启动也不重建。设计哲学只有一种可操作的长期记忆Ekko Agent 的记忆模型遵循一条极简且严格的原则整个 Agent 只维护一种可操作的长期记忆——memory_nodes中的记忆卡片。系统内不存在独立的审批队列、后台记忆评审任务也没有隐藏的 Session 摘要作为第二套记忆。这一点可以从源码中得到直接印证。在 types.ts 中MemoryNode定义了记忆卡片的完整结构id、key服务端生成的 canonical key、revision乐观锁版本、statusactive/superseded/expired/deleted、domain、categoryPath、type、valueJson、confidence、importance、sourceMessageIds证据来源等字段它就是记忆的唯一事实载体。与之相对memory_messages表只保存受信任的对话证据MemoryMessage见 types.ts用途是让记忆卡片能够追溯到具体的用户/助手消息它不参与形成另一套记忆。也就是说证据对话消息→ 存在memory_messages记忆可检索、可注入、可增删的持久知识→ 只存在memory_nodes所有增删改行为 → 直接落盘到memory_audit_events审计表不存在待审批状态。前台运行链路记忆的增删改只有一条路原文档给出了记忆系统的核心运行链路这里完整保留并结合源码展开Ekko Agent turn - 保存当前用户消息证据 - 按宿主授权的 scope 检索 active memory_nodes - 注入相关记忆卡片 - 主模型调用 memory_search / memory_get / memory_write / memory_forget - memory_write / memory_forget 在当前 run 中直接生效 - run 完成后仅补录助手消息证据这条链路对应的实现事实保存用户消息证据MemoryService.captureMessages()service.ts在 turn 开始阶段把当前用户消息按确定性 ID 写入memory_messages作为后续sourceMessageIds的唯一合法来源。按 scope 检索 active 记忆自动召回受宿主授权 scope与token budget双重约束默认自动召回 token 预算为DEFAULT_AUTOMATIC_MEMORY_TOKEN_BUDGET 4000最近消息证据上限为DEFAULT_MEMORY_RECENT_MESSAGE_LIMIT 20工具检索结果上限为DEFAULT_MEMORY_SEARCH_RESULT_LIMIT 50见 config.ts。注入记忆卡片buildMemoryContextPrompt()与selectMemoryNodesByTokenBudget()见 service.ts把候选记忆组织成上下文注入主模型。模型调用四个记忆工具memory_search/memory_get/memory_write/memory_forget由createMemoryTools()注册tools.ts其中memory_write与memory_forget在writable: false时不会暴露从而实现只读模式。当前 run 直接生效写操作不做后台异步、不进入审批队列run 完成后仅补录助手消息证据。一个关键保证是工具失败时 Runtime 立即返回真实错误。例如memory_forget在缺少reason、缺少显式遗忘意图时会直接返回失败tools.ts模型不允许继续声称操作成功。四个记忆工具参数契约与正确用法memory_search结构化检索与全量枚举memory_search的核心语义是已知类别优先用结构化kinds开放问题才用queryTexttools.ts。其参数包括参数类型说明allboolean枚举当前宿主授权 scope 下所有 active 记忆不做相关性过滤queryTextstring开放问题的自然语言查询kindsarray精确匹配一个或多个受控 kind如profile_name、home_locationdomain/categoryPathPrefix/types/keystring/array结构化过滤条件tags/entitiesarray标签与实体过滤valueJsonany按结构化值过滤limitnumber150值得注意的实现细节中文所有/全部记忆与英文 all/every memories 等旧式 list-all 表达会被自动转换为全量枚举。isListAllMemoryQuery()用正则匹配了中英文两类表达tools.ts命中后queryText被置空、listAll置真从而执行不带相关性过滤的全量枚举——这正是文档所述不得把 list-all 意图写成 queryText的底层原因。memory_get按 id 取整张卡片memory_get按id返回完整记忆卡片含 canonical key 与当前 revision未提供id时退化为一次 limit2 的精确检索tools.ts。它的核心用途是为后续写操作获取targetId与expectedRevision。memory_write原子批量写入memory_write支持create/update/supersede/expire四种操作并优先推荐operations数组的批量形态整个数组先整体校验、再在一个事务中原子提交任一操作非法则整批回滚tools.ts。成功返回done: true并明确提示此更新已完成不要重复执行。写操作的关键约束均有源码强制校验create必须提交受控kind对 itemized 类 kind 还必须提供itemKey短而稳定的概念/实体标识如kindproject_context, itemKeyhermes_studio严禁使用句子、时间戳或随机值。update/supersede/expire必须携带来自memory_search/memory_get的targetId与expectedRevisiontools.ts。node中title与content必填结构化值必须用字段名valueJson兼容旧字段名value见normalizeToolMemoryNode。sourceMessageIds只能从宿主提供的受信任用户证据中选取模型不能伪造来源tools.ts。explicitUserIntent仅在用户明确要求记住/修改/纠正/删除时才置 true若宿主设置了memoryWritePolicy explicit-only未显式意图的写入会被直接拒绝tools.ts。memory_forget精确删除与全量清除memory_forget只服务于用户的显式遗忘请求context.memoryForgetIntent ! true时直接拒绝支持四种形态按all: true全量删除、按targets数组批量精确删除、按id expectedRevision删除、按domain/key等宽泛选择器删除tools.ts。mode可选soft保留审计状态或hard同时清理节点、FTS 与 embedding。受控 kind 与 canonical key服务端生成的槽位机制文档强调创建时模型提交受控kind和可选itemKey服务端生成 canonical key。这背后的实现是MEMORY_SLOTS槽位表schema.ts每个受控 kind 都被映射到固定的槽位定义key、domain、categoryPath、type、是否 itemizedkindcanonical key非 itemizeddomain / categoryPath类型interaction_contractinteraction.relationshipinteraction / relationshippreferenceprofile_nameprofile.identity.nameprofile / identityfacthome_locationprofile.location.homeprofile / locationfactoccupationprofile.occupationprofile / occupationfacttimezone_preferencepreference.timezonepreference / timezonepreferencelanguage_preferencepreference.languagepreference / languagepreferencehard_constraintconstraint.hardconstraintconstraintlong_term_goalgoal.long_termgoal / long_termtaskdurable_decisiondecision.durabledecisiondecisioncustom_factcustom.factcustomfact…………对于 itemized kind如accessibility_need、communication_preference、project_context、food_avoidance、personal_relationship等canonical key 由槽位key : 规范化后的 itemKey组成schema.ts。itemKey会经过 NFKC 归一化、小写化、空白/分隔符替换为下划线、剔除非法字符等处理normalizeCanonicalItemschema.ts保证同一概念得到稳定 key。canonicalizeMemoryDraft()还会对部分 kind 做受控值校验例如interaction_contract必须包含userRole/assistantRole/addressUserAs至少一个字段home_location必须含city或locationschema.ts。normalizeMemoryNode()则负责最终节点归一化并依据explicitUserIntent调整默认置信度显式意图 0.98默认 0.7与重要性0.9 / 0.6schema.ts。增删改规则noop、supersede 与并发防护文档的增删改规则全部能在源码中找到对应实现同槽位同内容返回 noop写入时若目标槽位的 active 卡片内容与提交内容一致服务端判定无变更返回action: noop不产生新 revision。同槽位新内容建立下一 revision 并 supersede 旧版MemoryStoreMutation的supersede形态types.ts会把旧节点标记superseded、新节点记录supersedesId并递增 revision。更新、过期和按 id 删除必须携带expectedRevisionupdateNodeStatus/deleteNode在 revision 不匹配时返回失败防止并发覆盖types.ts。sourceMessageIds只能来自宿主提供的当前用户证据前文已述parseMemoryMutation会逐一校验 ID 是否在context.sourceMessageIds白名单内。soft delete 保留审计状态hard delete 清理节点、FTS 与 embedding从 store.ts 的DELETE FROM memory_nodes_fts WHERE node_id ?可见hard delete 会同步清理 FTS5 索引store.ts。增删改直接写入memory_audit_eventsMemoryAuditEvent.eventType枚举为create | update | supersede | expire | deletetypes.ts每笔变更即时落审计无待审批状态。检索规则token budget、scope 与不能据此宣称记忆库为空检索的四个要点在resolveMemoryQuery()retrieval.ts中均有落地自动召回不等于完整记忆库自动召回受 token budget默认 4000与宿主授权 scope 限制MemoryContextDiagnostics会记录retrievedNodeCount/omittedNodeCount/tokenBudget/usedTokenstypes.ts。已知类别用kinds开放问题用queryTextmemory_search的工具描述明确要求优先kindsALWAYS_RECALLED_MEMORY_KINDS常量还会让interaction_contract、language_preference、accessibility_need、communication_preference、hard_constraint等始终参与自动召回service.ts。全量枚举用all: true旧式 list-all 查询会被自动归一化见前文isListAllMemoryQuery。无匹配不得宣称记忆库为空只有执行过全量枚举才能下库为空的结论。检索结果的冲突处理同样严谨resolveConflicts()会过滤superseded/deleted/expired/confidence 0.35的节点并在同一 conflictKeyscope domain key下只保留胜出者其余记为conflict_lostretrieval.ts超限结果记为over_limit。相关性打分relevanceScore()对 title5、entities/key4、tags/value3、category/content2加权并叠加importance * 2 confidenceretrieval.ts。删除规则一句话即算明确意图不再有确认弹窗文档列出的删除规则非常激进但也非常清晰用户明确要求忘记某条内容 → 调用一次memory_forget精确删除带idexpectedRevision。用户明确要求清除全部记忆 → 调用一次memory_forget({ all: true })且要求context.memoryForgetAllIntent true。清掉、清除、清空、删除、忘掉等表达都属于明确删除意图直接进入删除链路不再经过确认弹窗或审批任务。权限边界由当前用户意图 宿主授权 scope双重保证memoryScopeAllowed()校验写入 scope 是否在writeScopes白名单内scope.ts。scope 共有三种类型types.tsscope含义可见性{ type: profile }当前 profile 跨会话共享默认 scope{ type: session, id }仅当前会话可见会话级{ type: context, namespace, id }宿主定义的上下文范围可见上下文级数据库ekko.db、四张核心表与 schema version 8 迁移数据库位于baseDirectory/.ekko/ekko.db记忆相关表共四张文档原述源码见 store.ts 的建表逻辑表职责memory_messages受信任的用户/助手对话证据来源追溯memory_nodes唯一的长期记忆卡片集合memory_audit_events创建、覆盖、过期和删除审计memory_embeddings语义检索数据memory schema version 8会删除旧的memory_review_jobs、memory_summaries和memory_session_state表——这从侧面印证了文档的核心主张早期设计中存在过的后台记忆评审与Session 摘要体系已被彻底废弃统一收敛到单一memory_nodes模型。迁移不会删除memory_nodes中现有的记忆卡片即升级是保留数据的平滑迁移。崩溃安全的迁移策略迁移基础设施在 database.ts 中实现其设计层层递进逐版本、逐组件迁移每个组件如 memory按版本号排序依次执行记录在schema_migrations表中已应用版本跳过database.ts。BEGIN IMMEDIATE事务 重试每个迁移运行在BEGIN IMMEDIATE事务中database.ts立即获取写锁。锁冲突最多尝试三次每次受PRAGMA busy_timeoutmigrationBusyTimeoutMs约束database.ts。仍被占用时阻止启动三次重试仍失败则直接抛出EkkoDatabaseMigrationError阻止启动database.ts绝不会在旧进程仍写入时重建数据库。其他迁移错误 → 备份 恢复先把原数据库及 WAL/SHM 移动到带时间戳的备份路径${databasePath}.migration-failed-${timestamp}-${randomUUID()}.bakdatabase.ts再创建新库并按兼容列恢复记忆、证据、审计和 Ekko 会话随后重建 FTS 索引若新库本身也无法建立则恢复原数据库并终止启动。绝不降级整个迁移过程不会以禁用 Memory或切换到临时空库作为降级方案——要么成功迁移并保留全部数据要么回滚并终止。这一策略的工程含义很明确记忆数据被视为不可丢失的资产宁可拒绝启动、等待锁释放也不允许在数据竞争条件下产生半迁移的脏状态。小结一套模型、一条链路、一份保证Ekko Agent 的记忆系统可以浓缩为三句话一套模型长期记忆只有memory_nodes一种事实载体memory_messages只是证据审计表只做记录不存在第二套记忆或审批队列。一条链路所有记忆的增删改都发生在 Agent turn 的前台链路中由memory_search/memory_get/memory_write/memory_forget四个工具直接驱动失败即报错、成功即生效。一份保证canonical key 由服务端依据受控 kind 生成expectedRevision并发防护杜绝覆盖sourceMessageIds白名单防止伪造来源而数据库迁移在BEGIN IMMEDIATE 重试 备份恢复的组合下做到数据零丢失。对希望深入理解的读者建议按以下路径继续阅读源码先读 schema.ts 理解槽位与规范化再读 tools.ts 掌握工具参数契约随后用 service.ts 串联运行链路最后通过 database.ts 与 store.ts 验证迁移与存储的工程细节。赞分享AI 应用人工智能AI Agent本地部署前端后端工作流自动化【免费下载链接】ekko-studioEkko Studio is a local-first AI workspace for multi-agent chat, coding, and visual workflows, available on desktop and the web.项目地址https://gitcode.com/gh_mirrors/he/ekko-studio点击查看免费下载相关推荐FreeTube 隐私视频客户端完整展望缓存重构与跨设备同步背后的五大信号FreeTube 隐私视频客户端完整展望缓存重构与跨设备同步背后的五大信号 FreeTube 是一款注重隐私的开源 YouTube 客户端当前版本 0.25桌面应用音视频破解AI Agent的记忆难题openJiuwen agent-memory长期记忆系统深度解析破解AI Agent的记忆难题openJiuwen agent memory长期记忆系统深度解析 openJiuwen 是一个开源 AI Agent 开发与运文档人工智能AI AgentLightdash AI Agent 记忆系统深度解析记忆抽取Distill、梦境整合Consolidation与召回机制全指南Lightdash AI Agent 记忆系统深度解析记忆抽取Distill、梦境整合Consolidation与召回机制全指南 导读 Lightda后端前端数据分析数据可视化人工智能AI Agent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考