尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Obsidian Copilot 用户记忆系统设计解析:Recent Conversations 与 Saved Memories 双轨记忆架构

Obsidian Copilot 用户记忆系统设计解析:Recent Conversations 与 Saved Memories 双轨记忆架构 AI 应用大模型AI Agent交互助手RAG【免费下载链接】obsidian-copilotRun agents in Obsidian - OpenCode, Codex, Claude Code etc.项目地址https://gitcode.com/gh_mirrors/ob/obsidian-copilot点击查看免费下载导读Obsidian Copilot 在仓库 src/memory/memory-design.md 中明确了其用户记忆系统的完整设计以近期对话Recent Conversations与保存记忆Saved Memories两条独立轨道分别承载自动化上下文提取与用户显式长期记忆存储。本文以该设计文档为核心结合 UserMemoryManager.ts 的实现与测试逐步拆解两条记忆轨道的触发时机、写入流程、文件格式、滚动保留策略、配置项与三种聊天模式下的行为差异帮助你理解这套双轨记忆架构的每个环节并能在实际使用中准确配置与排障。记忆系统总览双轨架构与核心流程Obsidian Copilot 的记忆系统由两个互补的记忆类型构成设计文档src/memory/memory-design.md将它们定义如下Recent Conversations近期对话对聊天历史进行自动后台处理为后续对话提供上下文Saved Memories保存记忆用户显式发起存储请求保存重要信息供长期使用。两套机制共享同一个记忆文件夹、同一套配置开关与同一个记忆读取接口但在写入触发、更新策略与保留策略上完全独立。设计文档给出了三条完整流程近期对话写入流程Chat Conversation Ends→addRecentConversation()被调用 → 检查enableRecentConversations开关 → 通过 LLM 提取标题与摘要 → 生成 Markdown 会话小节 → 加载现有文件 → 追加新小节 → 应用滚动缓冲区策略仅保留最近maxRecentConversations条→ 写入Recent Conversations.md保存记忆写入流程用户显式要求记住 →updateMemoryTool被调用 → 检查enableSavedMemory开关 → 确保记忆文件夹存在 → 加载现有记忆 → LLM 生成合并去重后的条目列表 → 覆盖写入Saved Memories.md记忆读取流程每次 LLM 请求 →getUserMemoryPrompt()被调用 → 同时加载近期对话与保存记忆 → 合并两个记忆区块 → 作为系统提示词前缀返回给 LLM。这三条流程共同决定了记忆系统自动写、显式写、统一读的整体行为。核心实现位于 src/memory/UserMemoryManager.ts 的UserMemoryManager类它负责加载记忆文件、生成对话小节、维护滚动缓冲区、解析 LLM 返回的 JSON并将记忆内容格式化为系统提示词的一部分。Recent Conversations自动化上下文记忆触发时机与后台执行近期对话记忆的入口是addRecentConversation(messages, chatModel)方法。从 UserMemoryManager.ts 的源码可以看到它的三个关键特征触发点每次聊天对话结束时被调用。在 src/components/Chat.tsx 与 src/main.ts 中均以plugin.userMemoryManager.addRecentConversation(chatUIState.getMessages(), chatModel)的形式在会话收尾时触发开关守卫方法首先检查settings.enableRecentConversations关闭时仅记录警告日志Recent history referencing is disabled, skipping analysis并直接返回对应测试 src/memory/UserMemoryManager.test.tsFire-and-forget真正的内存更新逻辑通过this.updateMemory(messages, chatModel).catch(...)在后台异步执行不阻塞当前操作任何后台失败仅记录错误日志。滚动缓冲区与并发保护updateMemoryUserMemoryManager.ts内部实现了两个核心保障竞态保护类字段isUpdatingMemory作为互斥标志若上一次更新仍在进行新请求会被直接跳过并记录Memory update already in progress, skipping.防止多条会话同时写入导致文件损坏写入前守卫无可用聊天模型或无消息时分别记录错误并提前返回。会话小节的追加与滚动保留在addToRecentConversationsFileUserMemoryManager.ts中完成文件不存在时直接创建文件存在时先读取现有内容通过parseExistingConversations按##标题切分出历史会话数组追加新会话后若总数超过settings.maxRecentConversations则从数组头部截断splice(0, conversations.length - maxConversations)即保留最近的 N 条、丢弃最旧的。最终所有小节trim()后以空行分隔写入避免多余空行。文件格式与内容构成近期对话文件Recent Conversations.md中的每个会话小节格式如下由createConversationSection在 UserMemoryManager.ts 生成## 会话标题LLM 提取2-8 个词 **Time:** 2026-09-26 03:21 **Summary:** LLM 生成的 2-3 句摘要包含关键细节与结论其中标题由 LLM 根据对话提取捕获主要用户意图限制 2-8 个词时间戳为本地时间YYYY-MM-DD HH:MM格式见getTimestampUserMemoryManager.ts摘要为 2-3 句包含关键细节用户提到的事实、实体与结论且与对话使用同一种语言。标题与摘要的 LLM 提取实现标题和摘要通过一次 LLM 调用完成extractTitleAndSummaryUserMemoryManager.ts系统提示词要求模型以严格 JSON 返回{title: ..., summary: ...}并明确规则使用与对话相同的语言人类提示词将消息拼接为conversation_text.../conversation_text传入响应先经过extractJsonFromResponseUserMemoryManager.ts做多策略 JSON 提取优先匹配json代码块包裹的 JSON无代码块时匹配{...}对象模式两者皆失败时退回原始内容解析失败时降级为Untitled Conversation/Summary generation failed不会中断主流程。设计文档特别强调这一鲁棒 JSON 解析能力是因为 Gemini 等模型常把 JSON 包在代码块中返回多策略提取可显著提高兼容性。Saved Memories显式长期记忆存储触发时机与工具注册保存记忆由用户显式请求触发。当用户在对话中表达记住这个别忘记等意图时updateMemoryTool被调用。该工具的注册与配置在 src/tools/builtinTools.ts 中完成工具 ID 为updateMemory显示名Update Memory归类memory支持memoryCopilot 命令元数据声明工具使用原则仅用于个人事实、偏好或用户明确要求存储的内容不要用于一般信息并给出示例语句Im studying Japanese and Im preparing for JLPT N3工具标记为isAlwaysEnabled: true但实际可用性仍受enableSavedMemory设置与各模式的工具启用列表约束。工具底层实现位于 src/tools/memoryTools.tscreateUpdateMemoryTool(app)以 Zod schema 定义参数statement最小长度 1调用ChatModelManager.getInstance().getChatModel()获取当前聊天模型执行memoryManager.updateSavedMemory(statement, chatModel)并根据结果返回成功/失败消息成功时附带实际写入的文件路径。LLM 驱动的合并去重写入updateSavedMemoryUserMemoryManager.ts是一个读-改-写流程核心逻辑在updateSavedMemoryFileUserMemoryManager.ts读取现有Saved Memories.md内容文件不存在则为空字符串将系统提示词与人类提示词组装后调用 LLM系统提示词要求模型维护用户的长期个人记忆列表规则包括仅保留稳定、长期有效的事实或偏好通过合并去除重复与近似重复新陈述与旧内容冲突时保留最新真相并删除过时条目优先使用简短、具体、无歧义的措辞保持输入记忆的语言仅输出以 bullet point 呈现的记忆内容人类提示词将现有记忆放入current_memories、新陈述放入new_statementLLM 返回去重、合并、冲突消解后的完整新列表若响应为空或调用失败返回带描述性错误信息的结果如Empty content returned from LLM、LLM call failed while updating saved memories: ...文件存在则vault.modify覆盖不存在则vault.create创建。关键设计点是整文件覆盖而非追加由于 LLM 基于完整旧列表生成新列表直接覆盖可天然实现去重、合并与冲突消解因此 Saved Memories 的保留策略是无上限直到用户手动删除。文件格式与内容构成保存记忆文件Saved Memories.md采用由 LLM 维护的 bullet-point 列表每条代表一条规范化陈述- 用户长期偏好示例Im studying Japanese and Im preparing for JLPT N3 - 重要的个人事实或决定内容特征包括原始用户指定信息、个人事实/偏好/重要决定/上下文、经 LLM 归一化的去重合并列表、冲突时保留最新真相并移除过时条目、保留源语句语言。记忆读取系统提示词注入getUserMemoryPrompt 的组装逻辑getUserMemoryPrompt()UserMemoryManager.ts是记忆读取的统一入口先调用loadMemory()UserMemoryManager.ts从两个文件中加载内容到类字段文件缺失时优雅降级为空字符串并记录日志不抛错若enableRecentConversations开启且近期对话内容非空拼入recent_conversations.../recent_conversations区块附注当前时间The current time is ${this.getTimestamp()}.并提示模型仅在相关内容时使用若enableSavedMemory开启且保存记忆内容非空拼入saved_memories.../saved_memories区块提示模型这些是用户明确要求记住的重要记忆用于提供更个性化、更贴合上下文的回答任一块区存在则返回拼接结果否则返回null。系统提示词集成记忆内容并非直接附加在用户消息中而是作为系统提示词前缀注入。在 src/system-prompts/systemPromptBuilder.ts 中getSystemPromptWithMemory(userMemoryManager, userPrompt)先调用getUserMemoryPrompt()获取记忆区块非空时以\n${systemPrompt}的形式将记忆前缀置于基础系统提示词之前。该函数被 src/LLMProviders/chainRunner/CopilotPlusChainRunner.ts 与 src/core/ChatManager.ts 等核心调用链使用保证各聊天模式统一获得记忆上下文。记忆文件夹的解析与目录管理记忆文件位于配置的记忆文件夹中。路径解析由 src/settings/copilotFolder.ts 负责deriveMemoryFolder(settings)将可配置的copilotFolder根目录与固定子目录名memory拼接COPILOT_SUBFOLDER.memory得到如copilot/memory的路径getEffectiveMemoryFolder()读取实时全局设置返回当前有效路径。ensureMemoryFolderExistsUserMemoryManager.ts调用ensureFolderExists递归创建目录。loadMemory的注释UserMemoryManager.ts还揭示了一个重要的实现细节读取时只解析一次记忆文件夹避免 Copilot 根目录在操作中途变更导致近期对话文件与保存记忆文件来自不同根目录的错配updateSavedMemory则在模型调用前捕获文件夹路径保证读-改-写写入的正是本次读取的那个文件。配置项详解与默认值记忆系统由四个设置项控制默认值定义于 src/constants.ts字段声明与校验位于 src/settings/model.ts配置项类型默认值作用说明enableRecentConversationsbooleantrue近期对话记忆总开关关闭后addRecentConversation直接跳过读取时也不注入近期对话区块enableSavedMemorybooleantrue保存记忆总开关关闭后updateSavedMemory返回Saved memory is disabled, skipping savememoryFolderNamestringcopilot/memory记忆文件存放文件夹默认值DEFAULT_MEMORY_FOLDER为${COPILOT_FOLDER_ROOT}/memory写入前递归创建maxRecentConversationsnumber30近期对话保留条数支持范围 10-50超过时滚动淘汰最旧条目其中maxRecentConversations的默认值30在 src/memory/UserMemoryManager.test.ts 等测试中被反复验证sanitizeSettingssrc/settings/model.ts会为缺失或类型错误的配置项回填默认值保证记忆模块在异常配置下仍可用。错误处理与鲁棒性保障设计文档将错误处理列为记忆系统的关键能力代码中均有对应实现全面错误日志loadMemory、updateMemory、updateSavedMemoryFile、extractTitleAndSummary等路径均以logError/logWarn记录上下文参见 UserMemoryManager.ts 多处 catch 分支AI 处理失败降级标题/摘要 JSON 解析失败降级为固定占位文案保存记忆 LLM 调用失败或返回空内容时向调用方返回带描述的错误信息而非写入脏数据文件缺失优雅处理两个记忆文件不存在时均以空内容继续流程并记录... file not found, skipping ...日志用户通知updateSavedMemory的调用方 memoryTools.ts 根据结果返回success与message其中成功消息包含实际写入路径与内容失败消息透传错误描述多策略 JSON 提取支持代码块包裹 JSON、内联 JSON 与原文回退三种解析路径竞态保护isUpdatingMemory标志确保同时只允许一次近期对话更新。三种聊天模式下的记忆行为设计文档明确记忆能力随聊天模式分级其差异可总结为下表功能Agent 模式Plus 模式基础聊天记忆读取✅ 动态✅ 动态✅ 动态记忆保存✅ XML 工具✅ 意图分析❌ 无工具决策AI 推理预分析不适用记忆上下文系统提示词系统提示词系统提示词用户控制AI 驱动意图驱动仅手动Agent 模式自主 Agent记忆读取通过系统提示词获得近期对话与保存记忆的完整访问记忆保存可直接通过 XML 工具调用updateMemoryTool调用格式为use_toolnameupdateMemoryTool/namememoryContent.../memoryContent/use_tool行为特征AI 根据用户请求自主决定何时保存记忆可逐步推理某信息是否值得记住保存时向用户展示通知访问控制受工具启用设置autonomousAgentEnabledToolIds约束——该列表默认包含updateMemory见 src/constants.ts从 Agent 工具决策状态机src/LLMProviders/chainRunner/utils/AgentReasoningState.ts可以看出updateMemory被识别为可执行的工具调用。Plus 模式传统工具调用记忆读取同样通过系统提示词获得完整记忆上下文记忆保存通过memory命令触发Plus 模式下 CopilotPlusChainRunner.ts 会检测工具调用列表中是否包含updateMemory命中时创建工具实例执行保存行为特征由 Brevilabs API 意图分析在 LLM 响应生成前预先确定要执行的工具记忆保存是预定动作而非 AI 实时推理与 Agent 模式使用同一套通知机制。基础聊天模式仅 LLM记忆读取仍可通过系统提示词引用已有记忆作为上下文记忆保存无任何记忆工具可用对话过程中无法新建记忆只能由用户手动在聊天之外添加。使用建议与实战要点基于上述设计与源码分析在实际使用 Obsidian Copilot 记忆功能时可以参考以下几点合理设置保留条数maxRecentConversations支持 10-50 条滚动窗口默认 30 适合大多数场景若你的对话主题跨度大、需要更长周期的上下文回溯可调高至上限若在意记忆文件体积与提示词 token 开销可调低善用显式记住而非依赖自动摘要近期对话摘要主要服务短期上下文而长期重要的个人事实、偏好与决策应通过记住这个之类的显式指令写入 Saved Memories后者无保留上限且经 LLM 去重合并长期可靠性更高留意记忆文件位置记忆文件默认位于记忆文件夹如copilot/memory下的Recent Conversations.md与Saved Memories.md均为普通 Markdown 文件可直接在 Obsidian 中查看、编辑或手动维护移动或更换 Copilot 根目录时记忆文件夹会随新根目录重新推导关闭开关即完全禁用关闭enableRecentConversations或enableSavedMemory后对应的写入与读取区块都会按代码中的守卫逻辑跳过不会残留记忆内容进入系统提示词基础聊天模式记忆只读如果你需要在基础聊天模式下保存新记忆需切换到 Agent 或 Plus 模式或直接在记忆文件中手动编辑。延伸阅读设计文档全文src/memory/memory-design.md核心实现src/memory/UserMemoryManager.ts单元测试覆盖开关守卫、滚动缓冲、JSON 解析、合并写入等场景src/memory/UserMemoryManager.test.ts记忆工具定义与注册src/tools/memoryTools.ts、src/tools/builtinTools.ts记忆文件夹推导src/settings/copilotFolder.ts系统提示词集成src/system-prompts/systemPromptBuilder.ts默认配置值src/constants.ts赞分享AI 应用大模型AI Agent交互助手RAG【免费下载链接】obsidian-copilotRun agents in Obsidian - OpenCode, Codex, Claude Code etc.项目地址https://gitcode.com/gh_mirrors/ob/obsidian-copilot点击查看免费下载相关推荐agno中的智能体记忆系统短期与长期记忆的设计与实现agno中的智能体记忆系统短期与长期记忆的设计与实现 在多智能体系统Multi Agent System, MAS中记忆系统是实现智能体持续学习和个性化人工智能大模型AI AgentAgent 框架多智能体工具调用RAGAgent 工作流Agent 记忆gin-vue-admin 的 AI 记忆层aiDoc/memory 双轨记忆体系设计与落地指南gin vue admin 的 AI 记忆层aiDoc/memory 双轨记忆体系设计与落地指南 导读 gin vue admin 仓库中维护着一套面向 AI后端前端认证鉴权低代码任务调度gin-vue-admin 项目 AI 记忆层设计long-term 与 business 双轨记忆体系实践指南gin vue admin 项目 AI 记忆层设计long term 与 business 双轨记忆体系实践指南 gin vue admin 仓库在 aiDo后端前端认证鉴权低代码任务调度上一篇npm-security-best-practices自动化配置default.sh脚本详解与使用指南下一篇深度解析宝玉翻译优化工作流构建专业级AI翻译引擎的实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表