
Working Memory【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenVikingSession Title简短独特的 5-10 词标题信息密集Current State当前工作状态、待完成任务、下一步Task Goals用户目标、关键设计决策、解释性上下文Key Facts Decisions重要结论、技术选择及理由、用户偏好与约束Files Context重要文件 / 函数 / 模块及路径Errors Corrections遇到的错误及修复、用户纠正、失败方案Open Issues未解决问题、阻塞项、后续风险模板在 [session.py](https://link.gitcode.com/i/a654d680b56087e9f23a2e21dc0456c6) 中由 WM_SEVEN_SECTIONS 常量定义服务端解析与合并均围绕该常量遍历。段与段的「数据性格」不同决定了 Guard 策略不同 - **锚定型**Session Title会话身份标识不应随意变更 - **易变型**Current State、Task Goals每轮反映当前状态LLM 可自由 UPDATE - **累积型**Key Facts Decisions重要结论不断积累丢失代价高 - **引用型**Files Context文件路径一旦提及不应消失 - **只增型**Errors Corrections错误记录只增不删 - **跟踪型**Open Issues未解决项不应被静默丢弃。 从源码看预算约束还落在 prompt 指引层面每段上限约 2000 tokens、总 WM 上限约 12000 tokens服务端定义 _WM_SECTION_BULLET_THRESHOLD 25、_WM_SECTION_TOKEN_THRESHOLD 1500[session.py](https://link.gitcode.com/i/a654d680b56087e9f23a2e21dc0456c6#L4737-L4738)当单段超过 25 个 bullet 或 1500 tokens 时触发 consolidation 提醒。 --- ## 四、增量更新协议tool_call JSON Schema WM 更新通过 **tool_callfunction calling JSON schema** 实现LLM 调用 update_working_memory 工具以结构化 JSON 提交对 7 个段的逐段操作。JSON schema 的强约束保证漏段、多段、格式错误在 schema 层直接拦截。 ### 4.1 tool schema 定义 python WM_SEVEN_SECTIONS [ Session Title, Current State, Task Goals, Key Facts Decisions, Files Context, Errors Corrections, Open Issues, ] WM_UPDATE_TOOL { type: function, function: { name: update_working_memory, parameters: { type: object, required: [sections], additionalProperties: False, properties: { sections: { type: object, required: list(WM_SEVEN_SECTIONS), # 7 段全部必填 additionalProperties: False, properties: {name: _WM_SECTION_OP_SCHEMA for name in WM_SEVEN_SECTIONS}, } }, }, }, }每段的操作_WM_SECTION_OP_SCHEMA用oneOf约束为三种形状之一{op: KEEP}— 原样保留{op: UPDATE, content: ...}— 全段替换{op: APPEND, items: [..., ...]}— 追加条目实现细节上op字段使用type: string, enum: [KEEP]形式以兼容更多 JSON Schema 版本additionalProperties: falserequired把 LLM 输出严格钉在 schema 里。7 段全部必填的设计强制 LLM 对每个段落都显式表态避免「某段被遗忘而隐式丢失」。4.2 段级合并服务端_merge_wm_sections(old_wm, ops)按WM_SEVEN_SECTIONS常量遍历 7 段执行合并KEEP→ 原样复制旧内容UPDATE→ 用 LLM 提供的 content 替换先经过该段的 guard 校验APPEND→ 旧内容 LLM 提供的 items渲染为- item漏段 / 未知 op→ 兜底 KEEP。配套的_parse_wm_sections()按##标题切分 Markdown 为{header: body}字典。关键实现位于 session.py 的_parse_wm_sections()约 L4715与_merge_wm_sections()约 L5367。五、服务端 Guards信息保留的系统级兜底Guards 是服务端在合并 LLM 提交的操作时按段执行的语义校验函数即使 LLM 说 UPDATE服务端也根据段的特性决定是否接受。7 个段的保护策略如下段数据特点Guard规则Session Title锚定型_wm_enforce_title_stabilityUPDATE 与旧 title 的 meaningful-word overlap 1 → 回退 KEEPCurrent State易变型无LLM 可自由 UPDATETask Goals易变型无LLM 可自由 UPDATEKey Facts Decisions累积型_wm_enforce_key_facts_consolidation双阈值验证bullet count ≥ 旧值 15% 且 lexical anchor coverage ≥ 70%被拒时提取新 items 做 APPENDFiles Context引用型_wm_enforce_files_no_regressionUPDATE 丢失旧路径 → KEEP APPEND 新路径Errors Corrections只增型_wm_enforce_append_onlyUPDATE 降级为 APPEND去重后只追加新条目Open Issues跟踪型_wm_enforce_open_issues_resolvedsilently drop 的 item → 加[restored]标签恢复从源码看这些 guard 的工程实现相当细致session.pyErrors 的 append-only 降级_wm_enforce_append_only()将 UPDATE 的 content 解析为 bullet items过滤掉旧内容中已存在的条目后把「真正新增的条目」以 APPEND 形式重新发射既不让 LLM 重写的内容丢失也绝不丢弃旧 body 的任何内容若没有新增条目则整体回退为 KEEP。Key Facts 的受控合并_wm_enforce_key_facts_consolidation()采用双层验证。第一层拒绝明显缩水的 UPDATEbullet 数 旧值 15%第二层要求至少 70% 的lexical anchor覆盖——_extract_lexical_anchors()会从文本中提取日期如2024-03-15、数字短语如3 months、$200、决策标记词because / decided / chose / agreed / resolved以及专有名词大写 token作为事实锚点session.py。被拒的 UPDATE 会通过_salvage_new_items_from_rejected_update()抢救出真正的新条目做 APPEND当前轮次的事实不会静默丢失。Key Facts 的反膨胀anti-bloat机制当 Key Facts 已超限bullet 25 或 token 1500时 APPEND 被节流——1~2 倍阈值区间只接受去重后的新条目且上限 5 条_WM_OVERSIZED_APPEND_CAP 5超过 2 倍阈值紧急状态则拒绝一切普通新增仅插入一条幂等的[⚠ CONSOLIDATION REQUIRED: ...]哨兵且哨兵已存在时后续轮次不再追加任何内容形成硬停止session.py。Files 的路径回归检测_WM_PATH_LIKE_RE用宽松的 path-like 正则识别旧 Files Context 中出现过的文件路径覆盖py/ts/tsx/js/jsx/md/yaml/yml/json/sh/ps1/cmd/bat/toml/ini/cfg/rs/go扩展名及a/b/c型路径UPDATE 一旦丢失旧路径即回退 KEEP 并追加新路径。Title 的停用词机制_WM_TITLE_STOPWORDS过滤the/a/an/and/session/working/memory等无信息量词汇后再计算新旧 title 的重叠度判断是否「换了个身份」。另外更新 prompt 中还会注入动态的section size warnings_build_wm_section_reminders()扫描当前 overview统计每段 bullet 数与 token 估算超过阈值时生成section_size_warningsXML 块明确告知 LLM 哪些段必须用 UPDATE 做合并压缩、并给出目标≤ 25 bullets、≤ 1500 tokens从而把「何时必须压缩」的信号从服务端传到模型session.py。这些 guard 均有配套单元测试集中在 tests/unit/session/test_wm_v2_guards.py共 107 用例覆盖 5 个 guard growth 通用 schema另有test_working_memory_growth.py、test_working_memory_v2.py等测试文件补充验证。六、滑动窗口与 pending_tokensSessionMeta维护pending_tokens: int与keep_recent_count: int两个字段持久化到.meta.json。其核心语义session.pypending_tokens是落在最近保留窗口之外、将在下次 commit 被归档的消息的累计 estimated_tokenskeep_recent_count是插件最近一次通过 commit API body 传入的值被记住后后续add_message调用可在进程重启后依然一致地维护pending_tokens。运行机制add_message时新消息进入保留窗口尾部窗口头部被挤出的消息 token 累加到pending_tokenscommit时pending_tokens归零GET /sessions/{id}直接读 metaO(1) 获得 pending_tokens。服务端有防御性 clamppending_tokens与keep_recent_count在加载与写入时都执行max(0, ...)session.py。CommitRequest.keep_recent_count在 router 层还有ge0, le10_000的数值约束见 routers/sessions.py 的CommitRequest定义。此外从源码看commit 之后服务端还会通过_rebuild_pending_tokens()依据当前消息列表重算pending_tokenssession.py保证跨重启、跨异常路径下的账目一致。关键实现位置session.py的SessionMeta/add_message()、routers/sessions.py的CommitRequest。七、保留最近消息keep_recent_countcommit 归档时并不全量清空消息而是保留最近 N 条以维持上下文连贯参数keep_recent_count由插件在 commit API body 中传入afterTurn 路径默认 10compact 路径硬编码 0OV 存储模型保证tool_use/tool_result配对完整性ToolPart 自包含因此归档与保留都不会拆散一次工具调用与其结果。该值会被持久化到SessionMeta.keep_recent_count确保跨进程重启后滑动窗口的边界仍与插件侧预期一致。关键实现session.py的commit_async(keep_recent_count)、routers/sessions.py的CommitRequest以及插件侧的context-engine.ts、client.ts。八、核心流程8.1 afterTurn 流程每轮对话后自动归档插件端逻辑不变commit 的耗时工作在服务端完成[插件] afterTurn ├── extractNewTurnMessages → 提取新消息 ├── addSessionMessage → 逐条 POST /sessions/{id}/messages │ 服务端: append msg 滑动窗口更新 pending_tokens save meta ├── GET /sessions/{id} → 返回 pending_tokensO(1) └── pending_tokens tokenBudget * commitTokenThresholdRatio? │ YES → commitSession(waitfalse, keepRecentCountcfg.commitKeepRecentCount) │ [服务端 commit_async] │ ├── Phase 1同步不阻塞返回 │ ├── split_idx total - keep_recent_count │ ├── 归档 messages[:split_idx] → archive_NNN/ │ ├── 保留 messages[split_idx:] │ └── pending_tokens 0, 更新 meta │ └── Phase 2asyncio.create_task 后台执行包在 request_wait_tracker.register_request / wait_for_request / cleanup 包络内确保所有下游 enqueue 都被等待 ├── 读旧 WM: _get_latest_completed_archive_overview() ├── 有旧 WM? │ YES → ov_wm_v2_update prompt tool_call │ → guards 检查每段决策 │ → _merge_wm_sections 段级合并 │ NO → ov_wm_v2 prompt 全量创建 ├── 写入 archive_NNN/.overview.md .abstract.md .meta.json ├── 提取 long-term memorySessionCompressorV3需 archive_uri 才能写 memory_diff.json ├── 等待 embedding / semantic 队列排空wait_for_request └── 写入 .done最后写标志该 archive 全部状态终结Phase 2 的关键细节均有源码对应格式检测读取旧 overview 后先检查是否包含 WM 7 段 headerany(f## {s} in overview for s in WM_SEVEN_SECTIONS)。若是 legacy 格式走创建路径而非 tool_call 更新保证平滑升级。Section reminders更新路径中_build_wm_section_reminders()从旧 WM 提取每段当前状态摘要与尺寸告警注入到 update prompt 的wm_section_reminders变量。完整回退链tool_call 缺失 →_fallback_generate_wm_creation()重跑传入旧 WM 作为上下文JSON parse 失败 → 正则 recovery_wm_recover_ops_from_raw()针对 VLM 后端包装非 JSON 参数、未转义字符、弯引号、截断 JSON 等场景做逐段恢复→ 段级 guard 兜底 KEEPVLM 不可用 → 占位 summary。Phase 2 队列等待register_requestwait_for_request(timeout_PHASE2_QUEUE_WAIT_TIMEOUT_SECONDS1800s)是必需的——否则下游compressor/memory_updater通过register_*_root注册的 embedding / semantic 队列无人 await会让tracker.complete()与.done在向量化 / 语义入库之前就触发导致调用方看到 commit 完成但 memory 不可检索。Phase 2 主循环对应 session.py 的_run_memory_extraction()。8.2 compact 流程主动上下文压缩[插件] compact └── commitSession(waittrue, keepRecentCount0) ├── Phase 1: 全部消息 → archive, messages.clear() ├── Phase 2: 读旧 WM → 创建/更新 → 写入 └── 返回 → getSessionContext → 回读最新 WM与 afterTurn 的差异在于waittrue同步等待完成keepRecentCount0表示 Phase 1 全量归档并清空 live messages实现彻底压缩。8.3 assemble 流程上下文组装assemble 将上下文组织为 instruction / archive / session 三分区┌──────────── System Prompt ────────────────────┐ │ systemPromptAddition语义示意非逐字 │ │ 1. [Session History Summary] 是压缩摘要 │ │ 2. Active messages 是最新未压缩上下文 │ │ 3. 二者冲突时优先 active messages │ │ 4. 缺细节时询问用户不要猜 │ │ 原始 system prompt │ └────────────────────────────────────────────────┘ ┌──── Layer 1: Archive Memory (≤8K tokens) ─────┐ │ [user] [Session History Summary] │ │ # Working Memory │ │ ## Session Title │ │ ## Current State │ │ ## Task Goals │ │ ## Key Facts Decisions │ │ ## Files Context │ │ ## Errors Corrections │ │ ## Open Issues │ └────────────────────────────────────────────────┘ ┌──── Layer 2: Session Context ─────────────────┐ │ server 侧合并后的 ctx.messages: │ │ - 未完成 archive 的 pending messages │ │ - 当前 live session messages │ └────────────────────────────────────────────────┘ ┌──── Layer 3: Reserved (≥20K tokens) ──────────┐ │ LLM 回复空间 │ └────────────────────────────────────────────────┘【免费下载链接】OpenVikingSelf-evolving Context Database for AI Agents. Unify Agent Memory, Knowledge RAG and Skills.项目地址: https://gitcode.com/GitHub_Trending/op/OpenViking创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考