🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI
广告☁️ 云服务器特惠阿里云首购 8 折 · 腾讯云合作特惠
DeepSeek Harness Hub
← 返回列表

Yiipu/dsh-agentmemory

DeepSeek Harnessspec-screened扫描:低风险在 GitHub 查看 ↗
⚠ 装前注意

一个 DSHDeepSeek Harness的 Cordis 插件,让每个 dsh 会话都拥有 agentmemory…

基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/4 · 已提供中文文档

一个 DSH(DeepSeek Harness)Cordis 插件,将会话活动桥接到 agentmemory——一个本地、自托管的记忆守护进程。

综合分
31.3
GitHub 分
31.3
用户评分
—
★ Stars
4
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add Yiipu/dsh-agentmemory
未发布到 npm registry,仅可从源码安装,改用 GitHub 源安装
信任档位:已验证本站已于 3 天前真实安装成功(L4 · 真实安装)
是什么
dsh 原生插件 · chat
装得上吗
本站已真实安装成功(L4 · 真实安装,非静态推断)
安全吗
本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
还在维护吗
活跃:最近一次提交在 21 天前

档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →

🟢实装验证通过· 2026/9/23
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/20(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包dsh-agentmemory(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=20 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

未发布到 npm registry,仅可从源码安装

验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/20 20:43:32

依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-tools@deepseek-ai/schemastery
用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动

README

由 DeepSeek 最新模型翻译生成
dsh-agentmemory

一个 DSH(DeepSeek Harness)的 Cordis 插件,让每个 dsh 会话都拥有 agentmemory —— 一个本地自托管、带 REST API 的记忆守护进程 —— 中的持久、可搜索记忆。

⚠️ 已废弃。 本插件不再维护。agentmemory 0.9.29+ 自带官方 dsh 连接器,请迁移:

agentmemory connect dsh --with-hooks

官方连接器提供自动捕获(hook 经第一方 dsh-hooks-claude-code 桥接)与 MCP 记忆工具;本插件的 agent/pre-step 上下文注入无官方等价物。已写入的记忆与观察留在 daemon 中(按 project/agentId 组织),迁移后仍可查询——但官方连接器写入的 project/agentId 可能与本插件不同(本插件用 git toplevel 项目名、dsh agentId)。过渡期内每个 profile 二选一:daemon 去重无法合并两路捕获,同时开启会产生重复行。

dsh 会话是短暂的:会话一结束,agent 学到的一切——做过的工具调用、恢复过的错误、定下的决策——都随之消失。agentmemory 用跨会话、跨 harness 的持久化解决这一点(它已在服务 Claude Code、OpenCode、Hermes 等)。本插件就是 dsh 侧的那一环:把每个会话的活动写入 daemon 成为观察记录,在恰当的时机把记忆读回模型,并向 agent 暴露显式的记忆工具。

一个插件,三个面:

| 面            | 做什么                                                                                                                   |
| ------------ | --------------------------------------------------------------------------------------------------------------------- |
| 写(观察桥)   | 把每个 DSH 会话事件映射为 agentmemory 标准 hookType,让 daemon 的压缩管线、搜索索引、viewer 都能读到真实内容——见映射注册表 |
| 读(上下文注入) | 经 agent/pre-step waterfall 追加 sourced user/message:每会话一次的项目 recall 窗口、可选的逐消息语义 recall、压缩前的补注入                     |
| Agent 工具 | memory_recall / memory_remember,注册为模型工具,用于显式精确召回与主动写入                                                             |

agentmemory 是硬依赖。 插件在加载时、注册任何能力(工具、监听器)之前就先检查 /agentmemory/livez。如果守护进程不可达或未报告 status: ok,插件会加载失败并抛出明确错误——绝不静默降级。

所有配置都放在插件 cordis.yml 行的 config 字段里。没有浏览器 UI,也没有持久化的配置文件。

安装(静态组合)

先把 agentmemory daemon 跑起来——插件的加载硬门要求它在线。daemon 默认 REST 端口为 3111;安装方式见 agentmemory 快速上手(npx -y @agentmemory/agentmemory@latest)。已在 agentmemory 0.9.29 上验证;要求 ≥ 0.9.29:

- 更早的 0.9.x 会在 /agentmemory/remember 上丢弃 agentId,agent 作用域的 recall 会因此漏掉所有已保存的记忆。
- 更早的 0.9.x 的 observe 去重会把不带 tool_input 的行(本插件的 approval → notification 行)折叠到同一把 key、5 分钟窗口内静默丢弃第二次审批。

然后从 GitHub 把包装进 profile:

dsh plugin --profile web add github:Yiipu/dsh-agentmemory

(本地 dev 检出也可用:dsh plugin --profile web add /path/to/checkout。)

把 cordis-row.example.yml 里的行挂进 host 组合 cordis.yml(或 ${DSH_HOME:-$HOME/.dsh}/.agent-presets// 下的每会话 preset 组合)。最小行就是 {name}——Cordis 按插件的 Config schema 校验并填默认值(scoped 包名以 @ 开头时需加引号,因为 @ 是 YAML 保留标量起始):

- insert:
- id: agentmemory-bridge
name: "dsh-agentmemory"
config:
baseUrl: http://localhost:3111
enabled: true

需要 Node >= 20、一个 shell 能力接缝(capability seam,标准 bash/pwsh 执行器),以及与 package.json 中 peerDependencies 范围匹配的 dsh harness(已验证版本:dsh-tools 0.1.1-rc.2 与 0.1.2-rc.1)。行可接受的全部键见配置键。校验命令见验证。

DSH 事件 → agentmemory 映射注册表

这张表是桥接向 daemon 发送内容的权威注册表。每条观察都使用 agentmemory 的标准 hookType:daemon 的 mem::observe 只对 prompt_submit / post_tool_use / post_tool_failure 提取可搜索字段(prompt、tool_name、tool_input、tool_output);其他 hookType 的数据留在 raw.raw,永远进不了搜索与压缩读取的合成 narrative。因此本插件不使用任何自定义 hookType——每条记录都落在 daemon 本就认识的桶里。

| DSH 事件               | agentmemory 调用                                                                                                       | hookType            | data 字段                                                                                                                                                                             | dedup 判别                                                   |
| -------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
| session/created    | POST /agentmemory/session/start(enableSessionStartEnd 开启时);否则在 injectContext 开启时直接 POST /agentmemory/context | —                   | sessionId、project、cwd、agentId;响应中的 context 被缓存用于注入                                                                                                                          | —                                                          |
| user/message       | observe                                                                                                            | prompt_submit     | prompt=content、source(另含原始 content)                                                                                                                                             | tool_input=content(同 prompt 自然合并)                        |
| assistant/message  | observe                                                                                                            | post_tool_use     | tool_name='assistant_message'、tool_output=content、provider、model(另含原始 content)                                                                                              | tool_input='#'+seq(唯一;内容不进 input)                        |
| tool/call          | 不发观察行(见下)                                                                                                        | —                   | —                                                                                                                                                                                     | —                                                          |
| tool/result(ok)    | observe                                                                                                            | post_tool_use     | 来自 callMeta stash 的 tool_name/tool_input/tool_output(tool_name 兜底取事件的 name;tool_input 兜底为 'result#'+callId),另含 callId、原始 content、isError: false、errorName: '' | tool_input=args                                          |
| tool/result(err)   | observe                                                                                                            | post_tool_failure | 同上,但 isError: true、errorName 有值                                                                                                                                                   | tool_input=args                                          |
| turn/end           | observe                                                                                                            | post_tool_use     | tool_name='turn_end'、tool_output=reason(如 completed)                                                                                                                            | tool_input='turn#'+seq(唯一)                               |
| approval/asked     | observe                                                                                                            | notification      | notification_type='permission_prompt' + tool_name、request_id、call_id、reason                                                                                                 | 无 tool_input:dedup 哈希覆盖整个 data,其中唯一的 request id 区分不同审批 |
| compaction/start   | POST /agentmemory/context 刷新 + 补注入标记(injectContext + injectContextOnCompaction 开启时)                            | —                   | —                                                                                                                                                                                     | —                                                          |
| compaction/summary | POST /agentmemory/remember(compactionBridge 开启时)                                                                 | —                   | content='[dsh compaction] '+summary、type='fact'、concepts=['compaction']、project、agentId                                                                                     | —                                                          |
| session/flush      | 缓冲观察落库                                                                                                               | —                   | —                                                                                                                                                                                     | —                                                          |
| session/disposed   | 最终 flush;POST /agentmemory/session/end(enableSessionStartEnd 开启时)                                                | —                   | —                                                                                                                                                                                     | —                                                          |

未列出的事件(boundaries、chunks、todo/write、request/\*)是纯日志噪音,不产生任何输出。

为什么 tool/call 不发观察行

tool/result 行已经携带 name + args(经 callMeta,在 call 事件经过时 stash)加上输出,合成一条标准 post_tool_use。单独的 call 行要么落在 daemon 提取的字段范围之外(见表格上方的说明),要么与结果行撞 dedup key(相同 tool_name + args)导致结果行的输出被静默丢弃。所以 call 被记录,但只作为结果行的元数据。

为什么 turn/end 借壳 post_tool_use

纯粹为了让 turn 的 reason 进 tool_output、从而进可搜索的合成 narrative(自定义 hookType 会让它不可见——同上)。assistant/message 对其内容做同样的事。

为什么 approval/asked 映射为 notification

notification 正是 Claude Code 的 Notification hook 与 OpenCode 的 permission 事件产生的 hookType,dsh 的审批提示因此落入 daemon 本就认识的同一个类型化、可渲染桶。daemon 设计上不对 notification 做内容索引,所以这里的字段无需为提取而摆放。

为什么 compaction/summary 走 /remember

蒸馏出的摘要是免费的、daemon 侧的记忆——把它持久化为 durable fact,意味着它在产生它的那次历史压缩之后依然存活,而不是随被压缩的 transcript 一起消亡。上限 6000 字符,compactionBridge: false 可关闭。

去重安全设计(Dedup-safe)

agentmemory 的 mem::observe 对 sha256(sessionId, tool_name||hookType, tool_input[0..500]) 做 5 分钟 TTL 去重,命中即整条丢弃。桥接用每会话单调 seq 与自然内容/callId 做 tool_input 判别,保证同类多条都落库,同时保留「相同 prompt / 相同 (tool,args) 结果」的自然合并。tool_input 缺失时 daemon 改为哈希整个 data 对象。

记忆注入(读侧)

桥接走 DSH 原生的 agent/pre-step 注入通道(与 harness 内置的 dsh-time-context 插件同一范式),把 sourced user/message append 到进入 step 的消息批次尾部。两条路线都做事件级去重,不在每个 tool step 重复注入。前端把每次注入渲染为独立的「上下文注入」块(ContextMessageNode)。

路线 1 —— 项目 recall(form: 'recall',默认开)

每会话把 agentmemory 的 /context 项目级跨会话窗口(「这个项目之前干过啥」,排除当前会话)注入一次。session/created → /session/start 从响应缓存 context;enableSessionStartEnd 关闭(或 cwd 为空)时改为直接 POST /agentmemory/context 取窗口。agent/pre-step 的首个有缓存的 step append 一次(injectedContext 去重);每条 user/message 仍异步刷新缓存。

路线 2 —— 语义 recall(form: 'semantic',默认关)

每条 user/message 用原文(查询截断到 2000 字符)做一次 /smart-search(BM25+向量+图),把召回记忆的标题组装成一条注入消息(semanticSeq 逐消息去重)。精确召回(/search)仍留给 agent 显式调用 memory_recall 工具。

压缩前补注入(injectContextOnCompaction,默认开)

compaction/start 触发一次 /context 刷新,并在下一个 agent/pre-step 把最新项目窗口再注入一次,避免项目背景随历史压缩丢失。

模型工具

| 工具                | 参数                                                             | 说明                                                                                             |
| ----------------- | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| memory_recall   | query (必填), limit? (默认 8,钳制到 1–50), project?, agentId? | 按调用会话自动定位 project,跨会话召回。按 project 过滤,可选按 agentId(不传 = 项目的所有 agent,包含历史无 agent 的记录)           |
| memory_remember | content (必填), type?, concepts? (最多 20 个), ttlDays?     | 主动固化记忆;type ∈ pattern/preference/architecture/bug/workflow/fact。写入行带插件 agentId(见配置键) |

工具用 defineTool 定义、经 ctx.tools.register 注册,守护进程传输走 host shell seam(inject: ['tools', 'shell']);二者随插件 Fiber 生命周期自动清理。execute 失败返回 {ok:false,error} 而非抛错。

配置键

所有键都放在行的 config 下;省略的键会自动填默认值——无需把默认值手抄进行里。Cordis 原生校验:非法值(例如 curlTimeoutMs: -5)会让插件加载失败并给出明确错误。

| 键                           | 默认值                     | 范围       | 用途                                                 |
| --------------------------- | ----------------------- | -------- | -------------------------------------------------- |
| baseUrl                   | http://localhost:3111 | —        | daemon 基地址                                         |
| secret                    | ''                    | —        | Bearer token——明文或环境变量引用(见下)                        |
| enabled                   | true                  | —        | 生命周期桥总开关;false = 不再产生观察、session 行与注入数据源(模型工具仍可用) |
| enableTools               | true                  | —        | 注册 memory_recall / memory_remember             |
| enableSessionStartEnd     | true                  | —        | 镜像 session/start 与 session/end 行               |
| compactionBridge          | true                  | —        | 经 /remember 持久化压缩摘要                              |
| agentId                   | 'dsh'                 | —        | 写入行的身份标识;解析顺序:env AGENT_ID → 该值                  |
| curlTimeoutMs             | 4000                  | 1–60000  | 单次 curl 超时                                         |
| observeBatchLimit         | 20                    | 1–200    | 缓冲观察达到该数量时落库                                       |
| maxContentChars           | 4000                  | 1–100000 | 单条观察内容上限                                           |
| maxArgsChars              | 2000                  | 1–50000  | 工具调用参数上限                                           |
| injectContext             | true                  | —        | 项目 recall 开关(路线 1)                                 |
| injectContextMaxChars     | 6000                  | 1–200000 | 注入项目窗口文本上限                                         |
| injectContextOnCompaction | true                  | —        | 压缩前补注入 /context                                  |
| injectSemantic            | false                 | —        | 语义 recall 开关(路线 2)                                 |
| injectSemanticMaxResults  | 8                     | 1–50     | smart-search 结果并入语义块的上限                            |
| injectSemanticMaxChars    | 3000                  | 1–100000 | 渲染后语义 recall 文本上限                                  |

secret:明文或环境变量引用

secret 支持两种形式——明文或环境变量引用(后者有三种变体)。注意明文 secret 会原样留在 cordis.yml 里——若该文件会被共享或纳入版本管理,请优先用环境变量引用:

| 形式                                              | 行为                            |
| ----------------------------------------------- | ----------------------------- |
| secret: "xxx"                                 | 明文,原样用作 Bearer token          |
| secret: '${AGENTMEMORY_SECRET}'               | 读环境变量;未定义 → 加载失败并报错           |
| secret: '${AGENTMEMORY_SECRET:default}'       | 读环境变量;未定义 → 用 default       |
| secret: '${AGENTMEMORY_SECRET:?goes nowhere}' | 读环境变量;未定义 → 报错 goes nowhere |

环境变量经 shell 能力接缝在 apply() 开始时解析(沙箱无直接 env 访问)。

模型体验

模型看到什么。 桥接不改动已接收的输入;其影响是追加式的——每个去重边界附加一条 sourced user/message(见记忆注入),加上 enableTools 为 true 时的两个模型工具。

Token 影响。 有条件。注入只在去重边界贡献额外输入 token——项目 recall 每会话一次、开启语义 recall 时每条用户消息一次、每次压缩一次,而非每个 tool step。上限由 injectContextMaxChars / injectSemanticMaxChars 控制。enableTools 为 true 时工具 schema 增加少量固定 token 成本。工具响应正常回到模型的上下文窗口。

KV cache 影响。 追加式、前缀稳定。注入消息 append 到 step 消息批次的尾部,因此之前的前缀保留且可复用;再注入只改变后缀。去重条件(injectedContext、injectedSemanticKey、compactionInject)防止同一块在同一边界重复追加,所以桥接自身的活动不会使稳定前缀失效。

传输与失败语义

- 沙箱无 fetch/require/timers;出网走 shell 能力接缝,每次调用一个 curl,JSON body 走 stdin(--data-binary @-)。
- 缓冲:观察按会话缓冲,达到 observeBatchLimit(20)条、session/flush 或 session/disposed 时逐条落库;多个并发会话各自持有独立缓冲。
- 绝不 veto 生命周期:生命周期监听器有错误防护(观察发送失败在 flush 循环内被捕获);工具调用尊重 AbortSignal。
- 基础设施失败(curl 非零退出)重排队列、下一个 checkpoint 重试。daemon 返回的 HTTP 错误响应目前不会为观察行检查——这类行会被静默丢弃;一次性调用(压缩 / context / session 行)则记录后丢弃。
- flush 竞态:flush 在途时新事件经 dirty 标志被在途循环补发,不丢。

日志。 所有运行时错误都以 [agentmemory] 前缀写入 dsh 宿主进程的 stdout/stderr——如 daemon unreachable at …(加载门)、secret env … is unset(secret 解析)、observe failed, re-queuing tail(发送失败)、session/start failed / context refresh failed(一次性调用)。加载横幅([agentmemory] bridge active: …)确认 apply() 成功。

验证

node scripts/boot-check.mjs   # 模块 + Config schema + daemon livez + peer deps(7 项)
node test/smoke.mjs           # 端到端(需 daemon 在 :3111)

冒烟测试覆盖上表注册表的大部分内容:schema 校验、livez 硬门、工具注册、secret 三种 env 引用、观察落库(title/type/narrative 形状)、approval → notification 行、turn/end reason 可在 narrative 搜索、无幽灵 tool/call 行、compaction → /remember 桥接、以及 agent/pre-step 注入形状。未覆盖:tool/result 错误路径(post_tool_failure)与压缩前补注入。

本地开发——peer 依赖链接、冒烟 fixture 清理、ESM 缓存——见 DEVELOPMENT.md。

已知边界

- 工具侧与桥接侧的 project 解析不一致:观察桥按 AGENTMEMORY_PROJECT_NAME 环境变量 → git toplevel → cwd basename 解析 project,而 memory_recall / memory_remember 默认只取会话 cwd basename。当会话 cwd 位于 git 仓库子目录时,观察落在 toplevel 项目名下、工具却查 cwd basename——此时请显式传 project。
- 无只读模式:enabled: false 同时切断观察桥与注入数据源(只有模型工具保持可用)。只注入上下文、不写观察目前做不到。
- 记忆默认跨会话共享(观察记录打的是插件 agentId,不是 DSH session id);需要隔离某个 agent 时,设置 agentId 或让 memory_recall 按它过滤。
- Agent 隔离为可选:写入记录都带插件 agentId(见配置键);早于 agentId 标记功能的插件版本写入的记录 agentId 为 undefined,不传过滤时仍可召回。
- 环境变量(AGENT_ID、AGENTMEMORY_PROJECT_NAME)经 shell seam 从 dsh 宿主进程环境读取——在启动 dsh 的地方设置,而不是写在 cordis.yml 里。
- 未改动任何 @deepseek-ai 包;未改动随 dsh 发布的 preset 安装目录。

许可证

MIT——见 LICENSE。

上游仓库有新提交时邮件通知你(每天最多一封,无更新不打扰),随时一键退订。

💬 加入社群

插件用法、部署报错、新插件第一时间同步——群里问,比一个人翻文档快。

DPharness QQ 群二维码,QQ 扫码进群
QQ 扫码进群
DPharness 飞书群二维码,飞书扫码进群
飞书扫码进群