helibeiqi/dsh-memory-projection ↗★ 0

@helibeiqi/dsh-memory-projection

DeepSeek Harness 可热插拔的记忆投影框架,运行时动态切换 Agent 认知模式,严格遵循 Model-Visible 不变量 适合研究上下文切片策略的开发者,投影不丢弃原始日志,需 Cordis 运行时。

Package
@helibeiqi/dsh-memory-projection
Compatibility
Unverified
Version
0.2.0
License
MIT
Last updated
Aug 28, 2026

Install

This plugin has no verified bundle, or compatibility checks failed. Read the repository notes first. Read the full README ↗

dsh-memory-projection

DeepSeek Harness 可热插拔的「记忆投影」框架 —— 在运行时动态切换 Agent 的认知模式(模型可见上下文的切片方式),而非对历史做有损压缩。

CI License: MIT


项目介绍:关于「记忆投影」的定位

很多上下文管理方案做的是 context-compression(上下文压缩):把历史对话塞进一个摘要,用摘要替换原始记录,从而「缩小」喂给模型的 token 数。这种做法的代价是不可逆地丢弃了原始日志——一旦压缩,模型就再也看不到被压缩掉的真实事件。

本插件做的是 memory-projection(记忆投影),二者有本质区别:

维度Context CompressionMemory Projection(本插件)
对原始日志压缩 / 覆盖 / 丢弃只读、永不直接修改
历史的可恢复性不可恢复(摘要即真值)始终可从 append-only 日志精确重建
模型看到的内容一段「总结」原始事件的某个切片 / 重排(真实事件)
运行时行为通常静态热插拔、可切换、可回归默认
与 DSH 不变量关系容易破坏 Model-Visible ⇔ Logged由 invariant guard 强制守住该不变量

核心心智模型:

append-only 会话事件日志是唯一的真相源(single source of truth)。 投影(projection)只是这个日志的一个纯函数视图——同一个日志,配合不同策略,得到不同的「模型可见切片」。模型当下看到什么,永远可以追溯回某几条原始事件(sourceSeqs)。

因此本插件不是一个「压缩器」,而是一个调度框架 + 内置策略集:它让你在运行时按场景切换 Agent 关注历史的哪一部分,而历史本身一分不少地留在日志里。


核心特性

  • 🔌 可热插拔的调度框架:ctx.memoryProjection 提供 registerStrategy / setActiveStrategy / getActiveStrategy / listStrategies,运行时动态切换 Agent 认知模式,下一次投影即生效。
  • 🧩 内置三种纯函数策略 + 默认 passthrough(等价于原生推导):
    • precision-window —— 保留最近 N 轮 + 关键事件(聚焦执行)。
    • associative-divergence —— 从全史召回与当前上下文语义相关的事件,前置拼接(创造联想)。
    • critical-focus —— 只保留错误 / 边界 / 未解决事件(调试 / 复盘)。
  • 🛡️ 运行时不变式守卫(invariant guard):对激活策略做「双跑可复现性 + 日志溯源(provenance)」校验。凡违反 Model-Visible ⇔ Logged 不变量的投影,自动回退到默认投影,绝不让 Agent 循环中断。可开关。
  • ♻️ 零残留热插拔:所有副作用(service、事件监听、第三方注册)均通过 Cordis 原生生命周期(fiber 作用域)注册,卸载时 LIFO 自动回滚。不手写事件总线、不手写服务管理器、不手写 cleanup。
  • 📐 Cordis 原生合规:仅使用 definePlugin / ctx.plugin(Service) / ctx.on(...) 等官方扩展点,不修改内核。
  • 🧪 严格工程:TypeScript strict + ESM、Vitest 测试、ESLint + Prettier、tsup 打包,npm publish 就绪,一键 GitHub CI。

快速开始

安装

npm install dsh-memory-projection

运行依赖为 @deepseek-ai/cordis@^4(即 DSH 运行时所用的 Cordis 内核,已发布于公共 npm,可直接 npm install)。 @deepseek/harness 以 可选 peerDependency 声明——本插件只依赖 Cordis 契约,不强制依赖 Harness 内核。

在你的 DSH / Cordis 应用中加载

import { Context } from '@deepseek-ai/cordis';
import { dshMemoryProjection } from 'dsh-memory-projection';

const root = new Context();
root.plugin(dshMemoryProjection);

const svc = root.memoryProjection;

// 切换策略(下一次投影即生效)
svc.setActiveStrategy('precision-window', { windowSize: 6 });

// 投影:输入 append-only 事件日志,输出模型可见消息
const messages = svc.project(sessionEvents);

接入原生推导(拦截 session/derive-messages)

插件在加载时注册了一个 waterfall 事件监听 session/derive-messages:

  • 监听存在时 → 用当前激活策略替换原生推导(veto next)。
  • 监听移除时(插件卸载)→ 原生 next() 原样执行,默认投影完全恢复。

在 DSH 侧,只需把原生 Session.deriveMessages() 作为 next 续体传入该 waterfall 即可;本插件不要求修改内核。


内置策略详解

所有策略都是纯函数:相同输入(日志 + 选项)→ 相同输出,只读日志、无 I/O、无时钟读取、不修改入参。

passthrough(默认)

恒等投影,等价于 DSH 原生推导。即「不投影」,把完整日志逐事件映射为模型可见消息。作为守卫回退的安全兜底。

precision-window

选项(均可选):
  windowSize      number  保留最近 N 个会话轮次(以 user 消息为轮次边界),默认 6
  keepSystemEvents boolean 轮次外仍保留 system/boundary 事件,默认 true
  keepErrors      boolean 轮次外仍保留 error 事件,默认 true

适用:高频工具调用 Agent、聚焦执行场景。模型只需「最近上下文 + 持久系统约束」,丢弃窗口外的冗余工具步骤。

associative-divergence

选项(均可选):
  threshold       number  历史事件的语义相似度下限,默认 0.08
  topK            number   最多召回的历史事件数(0 = 不限),默认 0
  keepRecentRound boolean 始终保留最近一轮(当前线程),默认 true

从全史中,按「当前上下文(最新 user prompt / recentContent)」的局部词重叠余弦相似度,召回语义相关事件并前置拼接。不强制截断——最近上下文始终保留,相关历史是「追加」而非「替换」。

相似度用确定性、零依赖的局部词重叠余弦作为「语义相关」的代理,保证策略仍是纯函数。 生产环境可通过 registerStrategy 注册基于 embedding 的策略实现真正的语义召回。

适用:创造联想、跨会话回溯——模型拿到相关先验上下文,同时不丢失当前线程。

critical-focus

选项(均可选):
  keepErrors      boolean 保留 error/failure 事件,默认 true
  keepBoundary    boolean 保留 boundary(约束)事件,默认 true
  keepUnresolved  boolean 保留 unresolved 事件,默认 true
  keepLastUser    boolean 保留最后一条 user 消息作为上下文锚点,默认 true

只保留 error / boundary / unresolved 事件,丢弃所有「顺利执行」的步骤。适用:调试、质量审查、风险复盘——模型只看「什么出错了 + 约束是什么」。


自定义策略开发指南

一个策略 = 一个满足 ProjectionStrategy 契约的纯函数对象:

import type { ProjectionStrategy, ProjectedMessage, SessionEvent } from 'dsh-memory-projection';

const myStrategy: ProjectionStrategy = {
  name: 'my-strategy',
  project(events: readonly SessionEvent[], options?: Record): ProjectedMessage[] {
    // 1) 只读 events + options,不读外部状态 / 不读时钟 / 不修改入参
    // 2) 每条产出的消息必须带 sourceSeqs(溯源到日志中的真实事件)
    const out: ProjectedMessage[] = [];
    for (const e of events) {
      if (/* 你关心的条件 */ e.data.role === 'user') {
        out.push({
          role: 'user',
          content: e.data.content ?? '',
          sourceSeqs: [e.seq], // 溯源:必须落在 events 的 seq 集合内
        });
      }
    }
    return out;
  },
};

注册并启用:

const svc = root.memoryProjection;
svc.registerStrategy('my-strategy', myStrategy);
svc.setActiveStrategy('my-strategy', {/* 运行时选项 */});

不变式要求(由 guard 强制):

  1. 可复现性:同一日志跑两次必须 deepEqual 一致。读外部状态 / 随机 / 时钟 → 守卫判定为「非纯函数」并回退。
  2. 日志溯源:每条输出消息的 sourceSeqs 必须是日志中真实存在的 seq。凭空捏造内容 → 守卫回退。

若你想关闭守卫(例如你信任自己的策略且需要跑非确定性逻辑),可:

svc.setGuardEnabled(false);

架构设计

1. 与 DSH 不变式的关系(Model-Visible ⇔ Logged)

DSH 的核心不变量是:模型可见的内容,必须能从已落库(logged)的会话日志中重建。本插件把这条不变量变成可机检的工程约束:

  • 日志(SessionEvent[])是唯一的真相源,投影只读它。
  • 每条投影消息携带 sourceSeqs,显式声明「我来自哪几条原始事件」。
  • invariant-guard.ts 在每次投影后做两层校验:
    • 可复现性:纯函数双跑一致。
    • 溯源:sourceSeqs ⊆ 日志.seq。
  • 任一校验失败 → 回退到 passthrough(默认投影),并告警。Agent 循环永不因投影失败而中断。

这把「不变量」从一句哲学宣言,落地为每次投影都会跑的自动化测试。

2. 可逆副作用原则(零残留热插拔)

插件不手写事件总线、不手写服务管理器、不手写 cleanup 函数。所有副作用都委托给 Cordis 原生生命周期:

副作用实现方式卸载时如何回滚
ctx.memoryProjection 服务继承 Service 基类,super(ctx, 'memoryProjection')Cordis 自动从所属 fiber 移除该服务
session/derive-messages 监听ctx.on('session/derive-messages', handler)返回的 fiber 作用域处置器自动注销
第三方策略注册ctx.plugin(...) / ctx.on(...)同样随 fiber 作用域 LIFO 回滚

加载流程(apply(ctx) → ctx.plugin(MemoryProjectionService))→ 注册 4 个内置策略 + 1 个 waterfall 监听;卸载(ctx.dispose())→ 服务、监听、第三方注册全部自动撤销,原生推导恢复如初。不留下任何全局状态或孤儿监听。

3. 为什么把 session/derive-messages 建模为 waterfall

DSH 原生的「消息推导」是一个方法(Session.deriveMessages()),并不存在字面意义上的 session/derive-messages 事件。本插件把它建模为 Cordis 的 waterfall 接缝:

  • 插件监听在该接缝上,包裹原生 next(即原生推导)。监听存在时,返回策略结果(veto 原生 next)。
  • 监听消失(卸载)时,next() 原样执行 → 默认投影完全恢复。

这是对「官方扩展点」的正确使用方式:既实现了「拦截推导」的诉求,又保证卸载可逆、零残留。

目录结构

dsh-memory-projection/
├── src/
│   ├── index.ts                      # definePlugin 包装 + 公共导出
│   ├── types.ts                      # 类型 + 纯辅助(classifyEvent/isKeyEvent/eventToMessage/deepEqual)+ 模块增强
│   ├── core/
│   │   ├── projection-service.ts     # MemoryProjectionService(ctx.memoryProjection)
│   │   └── invariant-guard.ts       # checkInvariant(可复现 + 溯源)
│   └── strategies/
│       ├── precision-window.ts
│       ├── associative-divergence.ts
│       └── critical-focus.ts
├── tests/                            # Vitest 单测(策略正确性 + 纯函数性 + 生命周期零残留)
├── examples/
│   └── basic-usage.ts                # 可运行最小示例
├── .github/workflows/ci.yml          # 推送自动 类型检查→单测→构建
├── package.json
├── tsconfig.json
├── tsup.config.ts
├── vitest.config.ts
├── .eslintrc.json
├── .prettierrc.json
├── .gitignore
├── README.md
└── LICENSE

验证清单(自测通过项)

本仓库已覆盖以下 7 项自检:

  1. Cordis 原生合规:仅使用 definePlugin / Service / ctx.on / 模块增强,未修改内核。
  2. 不变式守卫:checkInvariant 对非确定性 / 无溯源的策略自动回退。
  3. 零残留热插拔:load → setActiveStrategy → dispose 后,session/derive-messages 恢复原生推导。
  4. 纯函数性:内置策略满足确定性、不可变性、同源同输出(测试覆盖)。
  5. 策略可扩展:registerStrategy 注册自定义策略并即时生效;未知策略名安全忽略。
  6. 工程就绪:tsc --noEmit / vitest run / tsup 全绿;ESLint + Prettier 配齐。
  7. 发布就绪:files 字段、exports 映射、MIT LICENSE、CI 工作流齐备,npm publish 可直接发。

许可证

本项目基于 MIT 许可证 开源。