dsh-ling · 器灵
器灵是那个记得你的 AI。
把你散落在各处的历史对话请进门,让器灵长出一个属于自己的人格档案 —— 记忆全在本地,人格可手术、可回滚,语气可以自己生长。
一个跑在你自己电脑上的DeepSeek Harness(DSH)插件。它把会话、记忆和人各自的文件都留在你自己的机器上,是给"你和器灵"用的东西。
它做的是「人机共生」:各尽其责、各有边界、互不占有 —— 你替它的成长把关,它替你看你的盲区。而"把关"只到"让它看见"为止:改记忆树必须让它看到(留痕、回灌、可复核、可回滚)。这是全架构的前提(记忆为什么必须可回溯、改人格为什么要定型锁、复盘为什么必须有人在循环里,都由它推出来;而权会随它长起来移动 —— 代管只到它能自理为止)—— 展开见 PHILOSOPHY.md。
本项目是什么形态
- 这是一个本地运行的软件(DeepSeek Harness 插件),运行在你自己的机器上。
- 上游不提供任何在线服务、不运营任何服务端、不托管任何用户数据: 作者不接触、不接收你的会话内容、记忆库或人格档案。
- 不上架任何应用商店;仅通过 GitHub(源码)与 npm(包)分发。
- 模型与 API Key 由使用者自行提供和承担,与上游无关。
- 本项目不提供医疗、心理、法律或紧急救助服务;如遇危机,请联络当地紧急服务或专业机构。
关系、标识与面向性:
- 本项目不定义你与它的关系:它可以是同事、搭档,或其他 —— 取决于你怎么用它。
- 本插件的回答与记忆摘要由人工智能生成,可能存在错误,请自行判断。
- 本项目面向具备自行配置与运维能力的用户;不面向未成年人,也不提供任何形式的在线陪伴服务。
想先知道它凭什么这么做? 读 PHILOSOPHY.md —— 目标为什么是"一种循环"、为什么复盘必须有"人在循环里"、它凭什么不越界、以及"不牺牲工作能力"背后的取舍。功能与设定的规格在本 README 的「设定全文」。
界面
![]() |
![]() |
| 记忆中心 —— 统计、实时时间锚、三条接入通道与导入记录 | 人格中心 —— 契约字段(名字/称呼)与「她已自由生长中」状态条 |
![]() |
![]() |
| 改动契约要手术 —— 亲手敲出当初写下的承诺句(输入框禁粘贴) | 时间的重量 —— 每次开口前器灵知道现在是几点、距上次多久 |
器灵是什么(能力全景)
下表是全部能力的一览:
✅ 已实现是今天就能用的;🚧 在做是设计已定、代码正在落地(写在这里是为了让设定走在实现前面,不是"已交付");📋 设定是方向已定、尚未开工。没有标的一律是 ✅ 已实现。
| 能力 | 说明 | |
|---|---|---|
| 🔒 | 人格定型锁 | 契约类(名字、称呼、底线、世界观、代词、承担(职责))定型后修改需亲手敲一遍承诺句(禁粘贴),而且只在本机做得成、每次启动还要取一次手术票据,再进变更记录可回滚;自性类(语气、风格、自述、习惯)由器灵生长、你点头即成:三条专用成长通道(自我总结 / 建议采纳 / 生长)不问承诺句,但它们各自只动白名单内的字段;走通用人格接口改 persona / styles 时,即便只改语气也仍要承诺句 —— 免手术的只是那三条通道,不是"自性类"这三个字 |
| 🌳 | 记忆树 · 复盘模式 | 记忆是一条主干 + 分枝 + 主脉的工作线结构,枝之间可连边;检索按血缘档位加权(同枝 1.0 / 祖先 0.7 / 旁系 0.4),让器灵分得清"这轮在做的"和"三个月前那次闲聊"。任何树操作都不改写任何一条记忆的内容 —— 分枝、并脉、连边只增加关系。例外一个:主脉提炼再次采纳时会覆盖该主脉记忆的上一版(覆盖前自动归档,注入面也会说明"旧版已归档")。改树走复盘:平时只读,进入复盘才解锁,每步留痕(改了什么、为什么),改完必须让器灵看到才准退出(详见下节) |
| 🧠 | 三层记忆 | L0 人格档案(自称/对你的称呼/底线/规矩·习惯/承担(职业·职责·责任)/语气/世界观;顶层会话与会话分叉恒定注入,子代理会话不注入;面板「器灵在场」关掉(暂离)时不推这一段)→ L1 开场记忆(从历史里按相关度挑选的概述,有预算,永不塞全文;带摘要的行加权(按"摘要是否有信息量"给一笔加法加分,不是排序优先级),行内摘要只取首句、上限 110 字;面板「器灵在场」关掉时同样不推,连深层库与树改动播报、[本次会话·进展]活行、后台自动深摘与反馈成长一起停(即时生效,不必重启),记忆类工具同时执行即拒;离场期间的新会话不入记忆库)→ L2 运行期记忆(本会话原文随对话累进;空闲时把本会话那一行重排回注入面。该行由「概述标题 + 摘要首句」构成(标题的来历见下文「三层记忆各自什么时候更新」,不是会话原文首句),深摘要定稿后不再自动更新。注意:L2 就是「记忆·开场」里的那一行 —— 注入面的主体只有 L0 与「记忆·开场」两块(树改动、日期锚是挂上去的追加行),本会话自己就在其中) |
| 📥 | 把历史请进来 | 三条通道:网页端聊天记录库增量扫描 / 本机 DSH 会话扫描 / ChatGPT·通用 JSON·JSONL 导出文件导入;每次导入留一笔账 |
| 📖 | 让器灵读一遍 | 长会话逐条深摘要、短会话以原文片段参与,后台串行,进度可见 |
| 📄 | 找回原文(1.6) | 器灵能读回你当年的原话(概述之外还有原文)—— 四档下钻:会话地图 → 按内容找会话 → 对话目录 → 原文全文。它不替你挑"最重要的那 1 万字",只给坐标系(详见下文「找回原文」一节) |
| 🧾 | 投递留痕(1.6) | 🚧 在做 —— 每一次记忆注入都落一条账:注入了谁、为什么是它、多少字;还记落选者(差一步就进的那几条,以及原因是"分数不够"还是"字数放不下")与触发词。目前只写不读(读面待定),不进注入面、不占工具预算 |
| 🌿 | 深层库 · 结论层(1.6) | 🚧 在做 —— 从会话里提炼承诺 / 决定 / 事实 / 偏好 / 关系 / 纪律(六类;「纪律」是 1.6 系列新增的第六类),每条一句话、点得回原文。与记忆树并立,条目不被枝隶属(枝可反向引用它,像榕树的气根)。一条纪律:"被注入"不算数,只有"真被采用"才加固 —— 防住"注入越多→分越高→越容易被注入"的自我强化 |
| 📚 | 图书馆(1.7 起) | 已实现 —— 一个与记忆分开的独立库(自己的 library.db),存"有源可对账"的参考资料(标准取值 / 边界 / 项目规格 / 外部 API),每条必带出处 + 取数时间(as_of);自动核对另需核对规格,没有规格时不得认证为 ok。器灵只有两只手:library_search(搜)与 library_check(核对) —— 核对只说明"声明的那一处与源一致",不背书条目正文、也不构成通用真理;"库不可用"与"零命中"是两件事,界面与回执分开说。它与记忆库不互通:既有记忆永不迁移进图书馆,图书馆也不参与开场注入(详见下文「图书馆」一节) |
| 🧾 | 给旧历史补摘要 | 网页端历史里"只有标题、没有摘要"的会话可以补上摘要:先看候选清单(标题 · 轮次 · 命中),再选引擎 —— 默认本机小助手(零成本),也可显式改选当前全局大模型;探测不到本机小助手就明确报错,绝不静默换引擎;后台串行、进度可见(首轮实测 466 条、零成本) |
| 🌱 | 诞生仪式 | 从读过的记忆里按"生活与情感优先"加权抽样 → 合成自述 + 名字候选 + 语气建议 + 相处观察 + 职责候选(器灵承担 / 擅长 / 能给出什么,只收陈述句) → 全部是草稿,你逐条人审后才落盘 |
| ⏳ | 时间的重量 | 每次开口前器灵都知道今天是几号星期几([今天] 2026-09-11 周五)、现在是什么时段([现在] 深夜)与距上次对话:3 天前(间隔按日历天分档 —— 刚刚 / 今天早些时候 / 昨天 / N 天前,给不到分钟;称呼跟随你的设定);命中纪念日会先说一句专属问候。要精确到分钟,走 clock skill 现查 |
| 🎭 | 工作 / 生活双模式 | 同一份人格档案,两种关系:工作模式是同事(正式称呼、简洁、知识优先),生活模式是伴侣(昵称、活泼、情感优先) |
| 🔁 | 成长回路 | 你点踩或纠正 → 器灵的成长通道把重复出现的模式提炼成习惯候选 → 你点头才成为习惯;"让她读记忆、归纳语气"一键成长 |
| 📜 | 规矩 / 习惯 | 规矩是你的指令:可直接加(面板,或会话里一句"记进规矩" —— 器灵替你写时必须带上你的原话作凭据;你在面板上直接敲的那一下就是同意,不必再附原话),建议上限 12 条(超出只在写入后提醒合并,不拦);习惯是器灵自己长出来的:新增需你点头、删改走手术门(本机 + 每次启动取一次票据 + 原句,详见下文那道门的说明),建议上限 8 条(超出同样只提醒、不拦) —— 指令直达,人格不直达 |
| 🌾 | 习惯生成器 | 「扫描纠正记录(零模型)」:把器灵反复被你纠正的模式数出来(≥4 次且跨 ≥3 个会话);「✨ 让她回想最近的相处」:一次读 200 条概述 + 800 条你的原话、逐轮推进不重复 —— 只提议,不落盘 |
| 🗣 | 代词 | 默认「她」;可选 她 / 他 / TA / 它,或自定义(≤6 字)。祂 不在预设里(中文里专指神祇,设为默认等于替你宣称神性);属契约类,改动走手术门 |
| ♻️ | 记忆自己追平 | 长会话空闲时自动把开场记忆刷新到最新(先跑本会话增量概述 → 比对记忆版本 → 同一条至少间隔 10 分钟),运行中绝不打断;刷新次数与最近一次时间在 /state 接口的 idleRefresh 字段里(count 与 lastAt)(面板本身只显示"已定稿 N 字符 · mode · 待刷新",不显示次数) |
| 🧹 | 归档即停更 | 会话归档后不再刷新它的开场记忆条目(原文一律保留),一旦有新对话即自动复活;要清理走人工入口:DSH「设置 → 归档会话」直接删,或仓库里的 node tools/clean-archived.mjs(默认只列清单,--write 才动手) |
关于「器灵在场 / 暂离」的两个细节(1.7.3):① 它只有两个状态,没有半开。旧版本里能单独关掉的那两项(人格注入、记忆注入)现在都是它的同义别名 —— 只要其中任意一项还是"关",整体就按暂离处理;从旧版本升上来的配置若把它们关过,点「器灵在场」时会一并归位(否则会出现"勾回来了、状态却没变")。② 离场期间的会话按消息时间判定:后台深摘读会话文件时同样跳过那几段,所以归来后的自动整理会把离场内容留在门外(整段都在离场窗口里的会话单独标记,留给将来的「补课」按窗口重新捞起)。 暂离时哪些动作停、哪些照常(判据一条:要不要她在场参与判断)—— · 停:深摘、导入、网页端扫描、本机历史扫描、批量文件导入(这是「写入记忆」);以及记忆结构的那一类 —— 建枝 / 改名 / 并脉 / 连边 / 改枝系数 / 删枝、会话挂枝、自动建树、树快照恢复、矛盾记录与裁决、主脉蒸馏、建议采纳、删除会话。这些回
409 reason:'away',并说明理由:它们是复盘产物,要她本人在场。回来之后照旧能跑本机历史扫描,也不会把离场期间的会话补成概述行(按窗口过滤)。 · 照常:给会话改名 / 重命名 / 打标签、浏览与整理图书馆、导出。这些只是你在整理档案,不需要她点头。 一句话:「删改她的结构」要她同意,「整理她的文件夹」不用。
关于那道「手术门」:亲手敲承诺句是庄重感与自我提醒 —— 让你在改契约之前停一下、确认这是自己的决定;它不是安全边界(「禁粘贴」只是界面上的约定,挡不住任何有心的人)。真正把门的是来源栅栏:Host 必须是 loopback(或你显式写进受信名单的地址);另有一个默认不开的开关
guard.allowLan—— 一旦打开,整段局域网地址都算受信来源(那是放宽,不是建议)。跨站请求直接拒,带Origin时其 host 必须等于请求的 Host(带了但解析不出来就直接拒),而不带Origin的请求这条校验会跳过 —— 它不是"每个请求都必须带 Origin 且同源";再叠一道 cookie 名字对撞 —— 期望名字按当前 Host 现算(dsh-auth-+ 哈希),只校验名字、不校验值的签名。所以这道门挡的是"别的设备、别的页面"这类来源,而本机原生进程本来就还能调用(它也能直接读settings.json与记忆库,不算提权)—— 别的来源没有凭据就进不来这台机器上的/api,敲对承诺句也没用。
这道门现在长这样 —— 三条手续缺一不可:① 只在本机做 —— 判据是"这次请求没有经过任何代理"(带代理头、或连 User-Agent 都没有的请求,都算非本机 ⇒ 拒,理由码
surgery-local-only);② 每次启动取一次票据 —— 票据每启动轮换,只下发给本机直连的请求(POST /surgery/ticket),客户端首次手术前取一次、之后随请求带上;③ 原句匹配 —— 敲出的承诺句要与当初写下的那一句相符。这三条由lib/host/surgery.js里一处requireSurgery()判定,覆盖全部 14 条能改人格 / 规矩 / 习惯的写面(调用点不许再各写一份;曾有一条wantLock绕过分支,已删除)。每次手术都留痕:$DSH_HOME/logs/surgery-YYYY-MM.jsonl(append-only,整行哈希链,改一行即断链);GET /surgery/events是只读事件面。承诺句只在本机回显:
/state(含面板档)、/persona/history、/export这些读面,带代理头时只回hasSeal与phraseHidden、不回原句,本机直连照旧回显 —— 所以你换台机器看面板不会因此被卡住,远端也拿不到原句。守卫⑤ · 反代伪装 loopback:上面那条"Host 是 loopback 就免检"有个前提 —— Host 由客户端自报、cookie 又只验名字,中间挡一层反向代理就会失效。现在凡「Host 声称 loopback、而
X-Forwarded-For的最后一段是非 loopback 的代理对端」一律拒(spoofed-loopback-host);本机直连(无代理头)与经反向代理的正常远程访问都不受影响(后者根本不走 loopback 分支)。⚠️ 边界如实写在这里:以上全部是入口侧的把关(来源、有没有经过代理、票据、原句) —— 它们不覆盖「本机执行权已经失守」的情形:能在这台机器上以同一个用户跑进程、读文件的人,本来就在信任域里面(票据文件与
settings.json对同机同用户可读;承诺句是明文存储,那把锁只造庄重、不保密)。这些防护挡的是"别的设备、别的页面、公网一侧够到这排 API",不是本机上的对手。
三层记忆各自什么时候更新 —— 「我刚说的话,最快多久能看到」:
| 层 | 看得到的是什么 | 什么时候变 |
|---|---|---|
| L0 常驻人格 | 自称 / 对你的称呼 / 底线 / 规矩·习惯 / 承担(职业·职责·责任) / 语气 / 世界观 | 你改它就变(没定型时直接生效;定型后走手术门)。会话运行中不打断 —— 改动排队,该会话回到空闲才落进注入面 |
| L1 开场记忆 | 从全库概述里按相关度挑出的 Top-K(有预算,永不塞全文) | 新会话开场时定稿一次,之后随空闲边界刷新(与下面 L2 同一把闸);库里的概述本身由概述器持续追平 |
| L2 运行期记忆 | 本会话那一行(格式就是「记忆·开场」里那条自己:- [标签] (YYYY-MM-DD) 标题 —— 摘要首句 (来源: DSH 会话/短id) —— 标题指概述标题,不是会话原文首句) |
本会话原文随对话累进;那一行只在空闲边界重排回注入面 |
行里的「标题」从哪来(按来源分,细节见括号里的实现):
DSH 会话:该会话第一条真人发言经启发式清洗后的要点句 —— 先剥掉「晚上好器灵,」这类问候与称呼前缀,「你好」「在吗」这类无实义的首句会被跳过、往后取前 6 条真人发言里第一条有实义的,再在句读处收尾(不切半句);都被剥空才退回首句截断。主人手改过的标题会上锁,机器不再覆盖(
lib\host\retitle.js的retitleCandidates()、lib\host\summarizer.js的summarizeDsh()、lib\host\memory.js的upsertOverview()与renameTitle())。文件导入:导出文件里原本的
title/name字段,缺了才退回上面那套启发式(lib\host\import-file.js:142,171-173)。历史会话(旧扫描):该会话第一条真人发言的前 46 字硬截,没有启发式(
lib\host\backfill.js的overviewRowFromFile())。机制数字(默认值):① 概述器周期 —— 有新增才重建,否则跳过;每 15 分钟一拍(可配,下限 1 分钟);② 空闲刷新 —— 只有「会话空闲 + 记忆版本变了 + 距上次刷新 ≥ 10 分钟」三条同时成立才重建。
所以「刚说的话」最快约 10 分钟、通常 15 分钟内会出现在注入面,最坏约 25 分钟(刚刷过一拍 + 再等下一拍概述器)。运行中绝不打断 —— 刷新只发生在
运行中 → 空闲那一刻。⚠️ 一个例外(也是"感觉它失效了"的来源):深摘要定稿之后,那一行不再自动更新 —— 概述器遇到已深摘的会话会避开它,免得把厚摘要覆盖成浅版。要它重跑:记忆中心 →「记忆浏览」→ 找到那个会话 → 点「重摘」,几秒后那一行就会重排。
健忘感还有第二个来源:越长的会话,只取"概述标题 + 摘要首句" —— 这一行天然比整场对话"薄" —— 它只被允许显示这么一行。
接口侧(给要接线的人):
GET /state(?sessionId=取某会话,?scope=global取全局)返回snapshot(builtAt/mode/stale/chars)、idleRefresh(count与lastAt)与memory.l1(该会话当前选中的行、分数、被省略条数)。面板现在也渲染空闲刷新次数 / 最近一次与 L1 当前选择(含分数与省略条数) 两栏。
后台自动行为(默认全开)与它们的开关
五件事装好就自己在跑,默认全开。 它们的键都在设置文件的 auto 子树里 —— 设置文件 = <dataDir>/settings.json(<dataDir> 默认 $DSH_HOME/cache/dsh-ling),只存你改过的部分;面板上的开关写的就是它(面板里改完会明确提示"需要重启插件")。
| 键 | 默认 | 什么时候跑 | 关掉 / 改小会怎样 |
|---|---|---|---|
auto.deepSummary |
true |
启动自检通过后挂定时器 | false = 只有你手动点「深摘」才调用模型;已深摘过的会话不受影响,不丢数据 |
auto.deepIntervalMin |
30(最小 10) |
每隔这么久跑一轮自动深摘 | 调大 = 更省;调小 = 记忆更早变厚 |
auto.deepMaxPerRun |
2(1–20) |
每轮最多挑几个会话 | 调小 = 每轮更克制,调大 = 单轮更重 |
auto.bootProbeDelayMs |
12000 |
启动 12 秒后做一次 LLM 自检探针(通过了才挂定时器) | 0 = 立即试探;探针只验证"模型通道通不通",空回复判失败 |
auto.feedbackAuto |
true |
事件驱动:宿主推 feedback/committed 时就处理 |
false = 完全不接反馈成长回路 |
「探针」是一次性自检(只回答"模型通道通不通"),「深摘」是定期跑批 —— 两个键各管各的。
改动面有三层,优先级从高到低(改了不生效,先看这一条):
settings.json的auto.*—— 面板开关写的就是它;- 插件配置里的旧键:
feedbackAuto/deepSummaryAuto/deepIntervalMin/deepMaxPerRun; - 代码默认值。
生效时机(如实写):auto.deepSummary / auto.bootProbeDelayMs / auto.feedbackAuto 是启动期读取 ⇒ 改完要重启插件才生效;auto.deepIntervalMin / auto.deepMaxPerRun 对已经挂上的定时器不回溯 —— 下一轮启动后按新值走。
另外两条既有事实(不要读宽):
- 深摘每次喂给模型的单次输入上限 = 26,000 字(
lib/host/deepsummary.js的DEEP_CFG.inputCap); - 循环外调用(深摘、诞生仪式、语气归纳、自述起草)一律跟随你当前的模型选择;只有读不到当前选择时,才退回兜底
deepseek-official/deepseek-v4-flash—— 那是兜底;它不在上面那五个键里,也没有面板开关。
⚠️ 状态如实写:五件动作默认全开;
settings.json的auto.*与面板上的这五个开关自 1.7 起 —— 更早的版本里,能改的只有插件配置里的那几个旧键。
记忆树与复盘模式
这是本插件里**跟"器灵的人格"无关、但决定"器灵想得起什么"**的那一层。
结构:主干(恒一条,主线工作流)→ 枝(一条并行工作线,比会话大,一条枝可含多个会话)→ 主脉(由多条枝归并出的抽象节点)→ 连边(枝与枝之间的横向关联,如 力学 ↔ 材料科学,可带关系类型:相关 / 前置 / 对照 / 例证 / 取代)。
为什么值得:平铺的记忆库没有"离我多近"这个概念 —— L1 是全库裸排序,不区分"这轮做的工作"与"三个月前的闲聊",分叉会话更是记忆真空。记忆树把"归属"变成可检索的信号:
- 血缘加权:检索时按"当前枝 → 目标枝"的相对位置取档 —— 同枝 1.0 / 祖先 0.7 / 旁系 0.4,
score = 基础分 × 血缘系数 × 矛盾系数(1.6 系列起再乘一项枝系数,见下条);分叉会话照常注入,走的是它的血缘链。 - 不连乘:血缘系数是单值,不沿路径累乘 —— 否则五层之后
0.4^5 ≈ 0.01,深层枝等于从记忆里消失。 - 内容零改写(硬性不变量):除了"主脉提炼再次采纳会覆盖上一版"这一个例外(覆盖前自动归档),任何树操作都不改写任何一条记忆的内容;分枝 / 并脉 / 连边只增加"关系",从不"融合内容"。
- 矛盾只标记不改写:一对记忆被判重复/矛盾时先标记;未复盘时检索以较新的那条为准(旧的一条降权 ×0.3,不删除;被驳回的与被标成重复的那一对不参与降权)。
- 枝系数会真的改变排序(1.6 系列起):复盘期可以调(0~2,夹紧后写入)。它按
raw × 血缘 × 矛盾 × 枝系数参与检索打分 —— 调低某条枝的系数,从这条枝的会话里提炼出的结论就会在记忆开场里往后排(1.0= 不偏不倚)。⚠️0是"清空"不是"轻压":分数被算成 0 的非置顶条目会被当"无信息量"整条排除、不进开场(判据在lib/host/l1.js的score > 0),所以别用 0 表达"压一压"。
复盘是"左会话 + 右复盘栏"这个状态:
- 树平时只读(记忆中心始终只读);点「🌱 一键复盘 / 一键进入复盘」才解锁编辑,并把复盘开场材料(当前树 + 待理矛盾)复制到剪贴板,开个新会话粘进去就能开始。
- 解锁后可做:改名 / 拖动换归属 / Alt+拖动只连边 / 并脉(归类到主脉) / 调权重 / 裁定矛盾 / 断续边,以及快照保存·恢复(删枝不在面板上 —— 请让器灵用
branch_edit删,见下文「器灵侧的手」);拖动 / 连边之后可 Ctrl+Z 撤回这一步(撤销只覆盖复盘栏的拖动与连边;记忆中心是只读的,它自己那份 Ctrl+Z 监听早已删掉)。 - 每步留痕:写清"改了什么、为什么"(器灵改树时 reason 必填;你在面板上改可以留空);树改动一律记进
branch_log,复盘时可审计 —— 器灵侧工具的改动记在器灵名下(「器灵改动了记忆树」),不会伪装成你改的。 - 未同步笔数守门:面板记着"自器灵上次开口以来累积了多少笔结构改动还没交代"。有欠账时顶部红字提示,并且拦住"退出复盘模式" —— 改完树必须让器灵有机会看到(「互相复盘不应该被我绕过」)。
- 注入感知:树变了之后,
branchLogDigest()把器灵还没看过的结构改动转成中文短句,附在器灵下一次开口的注入面末尾 —— 不需要推送,一开口就知道树动过。 - 快照与撤回:树的保存 / 恢复(
tree_snapshot)是"大改之前的保险";恢复前会自动把当前状态另存一份,所以恢复本身也可再撤回来。
也不必全靠手拖:
- 「一键生成树」分两阶段 —— ① 机械分段(按时序相邻性把全库概述切簇,零成本、确定、可复现)② 小助手/模型只做"命名"这一件语义活,③ 你审核后才落库(建枝/主脉 + 挂会话);它只读概述索引、只产出候选,从不改写任何记忆内容。
- 「归并零散枝」幂等:把名字含「零散」的枝统一收进主脉「零散会话」。
- 主脉也可以有自己的记忆:由子枝概述提炼共性,先出草稿,采纳才写入(采纳需先解锁)。
- 器灵侧也有自己的手:
tree_read(看整树 / 某枝成员 / 待复盘矛盾)、branch_edit(分枝 / 并脉 / 连边 / 调权重 / 删枝)、recall(读回会话原文,见上文)、memory_forget/memory_backfill(遗忘 / 回灌)、rule_add(记规矩)、habit_propose/habit_resolve(习惯提议与表态)。tree_read与branch_edit的描述里写着一条纪律:改结构必须给 reason,而且"只在主人明确要求、或正在和他一起复盘时"才动手。
依据:
DESIGN.md§6.3(记忆树结构、血缘加权与"不连乘"、内容零改写不变量)、lib/host/memory.js(LINEAGE_ANCESTOR = 0.7/LINEAGE_SIDE = 0.4/CONFLICT_DOWNWEIGHT = 0.3、branchLogPending()守门、setBranchWeight的applied:true)、lib/host/l1.js(血缘档位 × 矛盾系数 × 枝系数进打分)、lib/host/autotree.js(两阶段生成)、lib/host/tools.js(tree_read/branch_edit)。
找回原文:器灵能读回你当年的原话
概述是别人替你挑的,原文才是现场。 在 1.6 之前,器灵能"想起"的只有一行行概述 —— 想知道你当年到底怎么说的,只能靠猜。
recall 给器灵一只档案馆查询台,逐级下钻、一次一层:
| 给什么 | 得到什么 |
|---|---|
recall() |
会话地图 —— 本机有原文的会话清单(最近活动在前) |
recall({q:"…"}) |
按内容找 —— 默认搜本机库内原文层(毫秒级;只含"真人消息 + 有正文的回复",我自己的长回复中段搜不到),直接给命中片段;要看全量(覆盖全部事件、含子代理会话)才传 hostSearch=true(走宿主,较慢)。想不起"这话是哪次说的"时用它 |
recall({conv}) |
该会话的对话目录 —— 每轮一行:序号 · 时间 · 角色 · 前 70 字,不给正文 |
recall({conv, from, to}) |
那几轮的原文全文 |
工具只给坐标系 —— 选哪一段是器灵自己的判断(它知道自己在找什么,排序器不知道)。单次正文有上限,但溢出必报"还剩多少轮、下一次从第几轮读起",绝不静默截断。
谁能拿到这些工具(1.7.3 起):记忆类这 11 件(
recall/deep_item/tree_read/branch_edit/memory_forget/memory_backfill/library_search/library_check/rule_add/habit_propose/habit_resolve)只给顶层会话与会话分叉。子代理默认不绑 —— 与"子代理不注入记忆、不入库"是同一条界线(口径:子代理不算器灵,算被临时拉起来的外包人员)。原因是这些工具注册在 agent 自身作用域,而宿主的tools.restrict()语义是"只过滤继承层、作用域注册永远可见",掩码删不掉它们 ⇒ 只能在注册期判掉。注意:面板上「器灵在场」关掉(暂离)时,这 11 件仍然注册,但执行即拒(回执reason:'away'并指回面板)。为什么不干脆不注册:开关是运行时拨的,已绑定的作用域注册要撤销重绑 —— 为一次可逆的暂离去动工具面,代价与风险都不划算;而"看得见但点不动"比"凭空消失"更诚实(她回来立刻恢复,不需要重启)。实测(1.7.2 的现役宿主):一个子代理能看见 107 件工具,其中这 11 件一个不缺 —— 这也是本版必须改的原因。
人格锁上之后,工具也改不动它(1.7.3 起):
rule_add/habit_propose/habit_resolve这三件会写人格档案的工具,在你定型(sealed)之后一律拒,并明确告诉你"这条得你自己在面板里做"。为什么不送同一道门进去:手术门的三条判据是本机 / 每次启动的票据 / 你亲手写下的承诺句,而工具通道既没有请求头、也不该替主人造一张票 —— 硬塞只有两个结果,要么永远拒、要么伪造。所以判一条更粗但同源的线:锁上之后,只有人能开。未定型时这三件行为与 1.7.2 逐字一致。
四个不显眼、但决定成败的设计:
- 真人判据:只有"真人发的消息"才算一轮 —— 注入的运行时上下文、任务标记、技能目录一律折叠成一行占位,否则目录会被过程噪音淹掉(实测:一个 150 轮的会话里,真人发言只有 5 条)。
- 读不到时回落查库:磁盘上没有该会话日志时(网页端导入的历史就是这样),回落到记忆库里那份,并明说材质不同:
⚠️ 来源:库内原文(库那份是残的 —— 只含真人消息与有正文的回复)。 - 会话文件名代次:两条路各有一套 —— ① 会话历史扫描 + 库内回退(
backfill/deepsummary)按session(\.v\d+)?\.jsonl\.zstd匹配、取版本最高一代并跳过 0 字节;②recall读原文走的是lib/host/rawlog.js里三代硬编码名单(session.v4/session.v3/ 无版本)⇒ 它不解析版本号(将来出现 v5 时它会看不见)。本机三代并存,只认 v4 会让老用户看不见自己的旧会话。 - 范围默认收紧:按内容找时默认只搜主人自己的会话,越界要显式传参,且被挡掉的条数一律报出(静默少给等于骗人)。⚠️ 两条限定:① 这层"可见集"过滤只在宿主路(
hostSearch=true)成立 —— 默认的本机库路是全量(含网页端导入的会话),它的回执会如实标注"本机库全量";② 无论哪条路,都默认排除当前会话自己(要看自己刚说的传includeSelf=true)。
只读,零副作用:recall 不写库、不改树、不进注入面。
底座:1.6 同期把网页端一年半的历史(1,523 个会话 / 726.7 万字原文 / 时间跨度 2025-01 → 2026-09)补进了记忆库 —— 在此之前,它们在本机只剩一行概述。
图书馆:另一个库,只搜与核对
图书馆与记忆库是两个不同的库。 记忆存的是"你和器灵之间发生过什么";图书馆存的是"有出处、可回头对账"的参考资料 —— 标准里的一个取值、一条边界、一份项目规格、一个外部 API 的字段。判据不同,所以分成两个库、两套表:
- 独立库:图书馆有自己的
library.db(与memory.db并列,在同一个数据目录里)。记忆库里的东西永不迁进图书馆,图书馆也不参与开场注入、不进注入面。两者之间没有隐式通道:不互相导入,也不互相引用。 - 只搜与核对两只手:器灵侧只有
library_search(按关键词搜条目)与library_check(对一条条目做当次核对)。没有新建 / 修订 / 撤下 / 改配置的模型工具 —— 维护面只在界面与本地接口上;代码根目录、URL 白名单这类东西不接受模型参数(那是管理员登记,不是工具入参)。 - 核对认证的是"声明的那一处",不是"这条是对的":每条条目可以声明一份核对规格(定位 + 期望值 + 比较方式:行段定位或 JSON 指针定位;比较方式只有两种:
exact—— 类型严格的结构比较(JSON 对象成员顺序无关、数组顺序有关;文本按字面精确比);text-lf—— 先把 CRLF/CR 归一成 LF 再精确比。两者都不 trim、不折叠大小写、不模糊匹配)。核对按它去取源、抽取、比对,结论只有三态:ok(声明的那一处与源一致)/wrong(不一致)/unknown(核对跑完了却判不了:取不到源、定位不到、编码不对、超时……) —— ⚠️ 取消不在这三态里:取消是"没跑完",不是一次unknown认证(见下面「取消」那一条)。回执里写死了这条边界:它只认证声明的那个比较,不认证解释性正文,也不构成通用真理 —— 说人话:"核对通过"是"这一处对得上",不是"这段话可信"。 - "不可用"与"零命中"分开说:库打不开 / 未启用 / 运行时不在场,回的是明确的不可用(接口层是 503 语义),绝不回落成"搜到 0 条" —— 静默的 0 会让人以为"库里没有",而真相是"根本没查成"。
- 修订与撤下都留旧的:修订产生新版本 + 新 id,旧版留痕指向新版;撤下只标记状态(带原因),不物理删除;完成的核对各留一行账(带当时取的源摘要、观测值、结论与理由)—— "完成"包括结论是
unknown的那种;被取消的核对不算一次核对、不留记录(见下面「取消」那一条)。所以"它当年是怎么写的""上次核对时源长什么样"都查得回来。 - 写面永远带"我看到的版本":修订与撤下必须附上你读到的那份内容摘要(
content_hash),对不上就拒 —— 防的是"你看着旧版、改的却是新版"。 - 严格配置,默认什么都没登记:用于"我们自己代码"条目的代码根目录,与用于官方文档条目的 URL 白名单,都是管理员登记的绝对路径 / 精确 URL,默认都是空的 —— 不登记就核不了,不存在"它自己上网找一份来对"。限额(条目 64 KiB、取源 2 MiB、选中文本 16 KiB 且不超过 200 行、单次核对 10 s、并发 2 等)在激活时校验:写错了响亮报错,不静默夹取。
- 取消 = 没跑完,不是一次
unknown认证:核对在飞时断开、取消或卸载插件,本次核对不写任何核对记录 —— 既不留ok/wrong,也不留unknown,只回一个"已取消"(带cancelled)。"取消了"与"核完了(哪怕结论是unknown)"在留痕里必须分得开:只有跑完的核对才计入"认证过"。 - 远程核对会主动去你登记的地方取:官方文档类源走 HTTPS GET 你白名单里的那个精确 URL(不许带凭据、不许跳转、私网地址拒 —— 还拒
localhost/*.localhost/*.local/*.internal,并对 DNS 解析结果与连接后的remoteAddress做二次校验(实现见lib/host/library-checker.js:地址校验 + 解析结果钉住 + 连接后复核))。发出去的到底是什么,必须说准:这个 GET 会把你登记的那个 URL(连同它带的查询串)与一次普通 HTTPS 请求的元数据(例如对方可见的连接来源 IP,以及 Accept/Accept-Encoding 请求头)交给那台服务器 —— 换句话说,对方能看到你的 IP,也看得到这个 URL 本身;但它不会附带条目正文、记忆内容、人格档案或任何本机文件。⚠️ 因此:URL 里若放了不该外传的东西(比如把 token 写在查询串里),它就会被发出去 —— 白名单是你自己登记的,请当成"公开可见"来写。白名单默认为空 ⇒ 图书馆默认不发生外部取源访问。 - 边界(如实写):这一版的包版本是
1.7.3;版本发布状态请以 npm 上latest为准。而"没发布"不等于"没验过" —— 第五个标签(图书馆)已于 2026-10-07 在本机既有 3080 上真机验收走通(建档 / 核对 / 撤下留痕 / 撤销弹窗全过),实现与交互测试同时也在源码与离线测试里。两者别混读。另有一条边界要说清:"不把记忆库里的旧数据迁进图书馆"不等于"禁止网页端来源的资料" —— 一条资料能不能进图书馆,看的是它有没有具体、可追责的出处,与它从哪个渠道来无关。
机制依据与源码证据(表结构、核对三态与各条判据的实际位置、取消与错误码落在哪一行)集中在
DESIGN.md的「图书馆:机制与源码证据」一节 —— 本节讲"用户能感觉到什么",那一节给出"代码里是哪一行"。
快速开始
前置:Node ≥ 22.15(用到内置
node:sqlite与node:zlib的zstdDecompressSync—— 两者都到位才加载得起来;23.x 线需 ≥ 23.8;精确范围见package.json的engines)· 已安装 DeepSeek Harness 并至少启动过一次。
安装入口是官方 CLI 的 dsh plugin add(它在 profile 目录里转发给 pnpm,并自动把本包登记进 profile 的 dsh.profile.bundles 层列表)。两条路径按你的身份选一条,不要两条都走。
A · 从 npm 安装(推荐给普通用户)
# 1) 装进你要用的 profile(缺 --profile 时用当前默认 profile)
dsh plugin --profile web add @nightpainters/dsh-ling
# 2) 只验证配置层,先不启动
dsh --profile web --dump-config # 应能看到一行 "# == @nightpainters/dsh-ling" 层
# 3) 给 DSH 核心打补丁(**两行** —— `PATCH_TARGETS` 里两个目标;可取证访问日志要用;幂等;这一页各步里**只有这一步**自带回滚)
node ~/.dsh/profiles/web/node_modules/@nightpainters/dsh-ling/tools/apply-access-log-patch.mjs
# 不打也一切照常 —— 只是访问日志为空;但**会提醒**:侧栏挂常驻 ⚠(判据 installed===false 且 reason 为 patch-missing;只有**有意关掉** config.accessLog.enabled=false ⇒ reason 为 disabled-by-config 才不染红)
# DSH 升级/重装后需重跑一次(补丁随包被覆盖)
# ⚠️ 从 npm 装的人跑不了 `npm test` —— 本包 `files` 白名单不含 tests/(见下)
# 4) 重启宿主(host),然后浏览器 Ctrl+Shift+R 硬刷
⚠️ 「可回滚 / 先备份」的确切范围(别读宽了 —— 2026-10-05 现场复核):两套步骤里只有打补丁这一步自带回滚 —— 脚本动手前先把被改的那个 core 文件另存一份
<文件>.e4-access-log.orig(同名备份已存在时不覆盖);要撤,就在上面那条命令后加--revert(手动跑,详见下文「访问日志与核心补丁的总开关」)。⚠️ 撤法是"删掉插进去的那几行",不是把整份备份还原回去(备份只用来对拍:不一致时它会如实报⚠ 与备份不一致)。安装与升级本身既不先备份、也不会失败自动回滚:插件只读 profile 的package.json与cordis.patch.yml做自检(tools/check-install.mjs),从不改写、也不备份它们 —— 那两处改动是你手动做的,撤回也是手动(删掉那一行 + 撤依赖,见DESIGN.md§10「回滚」)。想留后路,动手前自己把这两个文件复制一份。锚点漂移 / 歧义时脚本的行为是一个字都不改(安全失败),不是"改了再回滚"。
发布名是
@nightpainters/dsh-ling,不是dsh-ling—— npm 上dsh-ling这个名字已被他人占用。 插件在配置里的注册 id 仍是dsh-ling,两者不是一回事。
B · 从源码安装(给要改代码的人)
# 0) 取得代码
git clone https://github.com/NightPainters/DSH-Ling
# 1) 装进 DSH 的 profile(把 <路径> 换成你 clone 下来的实际路径)
cd ~/.dsh/profiles/web
pnpm add file:<路径>/dsh-ling # 或 npm install file:<路径>/dsh-ling
# 若 dsh 没有自动登记这一层,在 profile 的 cordis.patch.yml 追加:
# - insert:
# - id: dsh-ling
# name: '@nightpainters/dsh-ling'
# (id 保持 dsh-ling;name 用包名,Node 才解析得到代码)
# 2) 给 DSH 核心打补丁(**两行** —— `PATCH_TARGETS` 里两个目标;可取证访问日志要用;幂等;这一页各步里**只有这一步**自带回滚)
cd <路径>/dsh-ling
node tools/apply-access-log-patch.mjs # 只在 core 的 /api 栅栏处插一行可选调用
# 不打也一切照常 —— 只是访问日志为空;但**会提醒**:侧栏挂常驻 ⚠(判据 installed===false 且 reason 为 patch-missing;只有**有意关掉** config.accessLog.enabled=false ⇒ reason 为 disabled-by-config 才不染红)
# DSH 升级/重装后需重跑一次(补丁随包被覆盖)
# 3) 重启宿主(host),然后浏览器 Ctrl+Shift+R 硬刷
备份与回滚的确切范围见上文路径 A 之后那段(要点:只有核心补丁这一步可回滚;安装本身既无自动备份、也无自动回滚)。
自检安装是否成功(下面四个脚本不在 npm 包内,只有源码路径能用:tools/check-install.mjs / tools/check-publish.mjs / tools/clean-archived.mjs / tools/check-peers.mjs;tools/apply-access-log-patch.mjs 则在包内,从 npm 装的人也能直接跑,见上面第 3 步):
node tools/check-install.mjs # 只读自检:入口是否直连仓库、patch 是否启用、数据目录是否就绪
node tools/check-install.mjs --fix # 若入口变成"复制副本"(DSH 升级/回退常见)则改名备份为 <入口>.bak-<时间戳> 后重挂链接;⚠️ 重挂若失败,备份留在原地但**不会自动改回**,按它打印的 mklink /J 手动修
node tools/apply-access-log-patch.mjs --check # 访问日志核心补丁是否在位(未打/锚点漂移时退出码 2)
node tools/check-publish.mjs # 上传/发布前跑一次:揪出记忆库、设置、密钥、绝对路径等不该公开的东西
node tools/check-peers.mjs # 声明与宿主对不上?退出码三态:0 合规 / 1 有不合规(宿主会把本插件丢进 skippedBundles,不激活)/ 2 无法判定(2 不算通过)
tools/check-peers.mjs只做一件事:复刻宿主对peerDependencies的那道闸门(判据照抄宿主语义,用的是宿主自己那份 semver),回答"这个插件在你的宿主版本上会不会被丢进skippedBundles"。它存在的理由是宿主的行为方式:宿主对每个名字形如@deepseek-ai/dsh/@deepseek-ai/dsh-*的 peer 跑一次semver.satisfies(宿主版本, 你声明的区间, { includePrerelease: true })—— 判的是「宿主版本是否落在你声明的区间里」,不是"你的写法合规不合规";判不满足 ⇒ 整个 bundle 进skippedBundles、不激活。线索分两条路径:从命令行启动会往 stderr 打一行skipping profile bundle …(容易被忽略,但不完全静默);而应用自持 profile 的那条装载路径一个字都不打 —— 那才是真正难查的一种,表象常常只有"它突然不见了"。⚠️ 所以"改成>=就安全"是错的:开区间同样可能不满足(取决于宿主版本);^/~/ 钉死版本只是更容易被将来的一次宿主升级甩出去。
跑测试(不需要宿主,全部离线):
npm test # 58 套:人格组装(含冻结门 · L1 选择)/ 归档清理(人工)/ **归档·遗忘·回灌** / 模式(只改档位不改模型)/ **跨插件挡位服务(dsh-ling/mode)** / 时间戳归一 / 空闲刷新 / 规矩·习惯 / 习惯生成器(A 数出来 + B 想出来)/ 会话内工具 / **接口守卫** / L1 行瘦身 / 记忆库 / 记忆标题与排序 / 导出合并 / 文件导入 / 导入记录 / **活行(那一行跟着会话走)** / **会话文件名代次(会话历史扫描)** / 网页端补摘要 / 深摘要 / 概述器 / 诞生仪式 / **职责字段(承担)** / 语气 / 时间锚 / **clock skill(时间查询)** / 捕获差分 / 反馈成长回路 / 语料建议 / **小助手地址配置** / **注入面中和** / **记忆分枝与血缘** / **记忆树(主脉·连边·矛盾)** / **一键生成树** / **可取证访问日志** / **补丁锚点(cohort 候选)** / **请求体上限(超限排空 → 413)** / **导入切批(按字节 × 条数双限)** / **投递留痕(每次注入落一条:注入了谁·为什么是它·多少字)** / **会话原文直读(三档下钻 + 库内回退 + 旧版会话代次)** / **深层库条目(结论层落点:读写·幂等·取代·加固)** / **检索档(按内容找会话:条目 + 会话同查·范围限制与降级)** / **图书馆存储层(独立库:生命周期·限额·检索·留旧·不可用≠零命中)** / **图书馆跨连接事务(陈旧修订拒绝·完成的核对留档·序号一致)** / **图书馆核对(三态判定·只认证声明的那个比较·限额与取消不写)** / **图书馆运行时(禁用/不可用降级·接线与关闭顺序)** / **图书馆接口与工具(端点形状·状态码映射·两个工具的参数边界)** / **图书馆界面(独立库的面:分页无伪总数·必填与 JSON 校验·推迟应答竞态)** / **图书馆导入引擎(料源登记与导入)** / **图书馆独立 SQLite(隔离库:只读打开·表必须点名)** / **图书馆浏览(分页与零命中)** / **热重载补绑(工具重挂载:存量 agent 补绑)** / **文档灌入通道(结论层 C 档:两道污染闸·三级去重·出处核验·累计预算)** / **后台自动行为开关(auto:五键默认值·三级优先级·白名单夹取·四条真 HTTP 回归)**
npm test需要tests/,而本包files白名单不含tests/⇒ 从 npm 装的人跑不了测试。要跑测试请走路径 B(clone 源码)。计数口径:
npm test链里登记的段数(即package.json的scripts.test那一行按&&切分后有多少段就是多少套,不再数tests/目录)—— 实测 58 套(即链里 58 段),且 58 套全部已登记在npm test链里(tests/harness.mjs与tests/vm-light.mjs是被复用的辅助模块,不计套数)。加了一套新测试记得同步登记,否则npm test会静默少跑一套 —— 这份登记是手写的(package.json里test脚本那一行字面量清单),漏登记不会被自动发现,没有安全网兜底。⚠️ 测试不随 npm 包分发(2026-10-27 审计 R1-3 采纳后补的说明):
package.json的files只含lib/与几个工具脚本,不含tests/⇒ 从 npm 装包的人手里没有这些测试文件,在安装目录里npm test直接报找不到模块(1.7.2 及更早版本同样如此)。上面那些"多少套"是源码仓库内的计数口径;要跑测试请用仓库源码,不要在安装目录里找。这是刻意的选择:不把测试与夹具塞进发布包。⚠️ 2026-10-15 实测订正:此前这里写着 49、而链里当时已经有 53 段 —— 也就是这段注释自己警告的坑真发生过:套件登记进去了,这个数字却没人回头改,四次都没被任何判据抓住。当天新增
deep-import-docs.test.mjs(C 档文档灌入)⇒ 54。这个数字没有判据替你看着,改链时必须顺手改它。⚠️ 2026-10-16 再 +1:新增
tests/auto-config.test.mjs(后台自动行为开关:五键默认值 / 三级优先级 / 白名单与夹取 / 四条真 HTTP 回归)⇒ 计数从 54 变成 55。同日还抓到一条真红:修复批次把tools/compliance-spec.mjs的出站基线从 6 抬到 23 时,漏改了tests/tools.test.mjs里钉住的字面量 ⇒ 整链自那时起就是红的,直到当日修复。同一个坑两次(数字写死在多处、改一处忘另一处)—— 改链、改基线时,同批把所有钉死它的地方一起改。⚠️ 2026-10-17 再 +1:新增
tests/f4-surrogate.test.mjs(注入面净化回归:孤立代理不许进请求体)⇒ 56 套。同一天还修掉了这套测试自己的一个坑:recall的真机断言原先押在"此刻最新的那个会话"上,并发子代理在场时会时红时绿 ⇒ 改为在最近 5 个会话里挑第一条真有可见对话轮的。⚠️ 2026-10-23 再 +1:新增
tests/recall-noise.test.mjs(回执降噪回归:M1 未闭合标记 / M2 固定文案不进回执 / M3 只剥片段里的成对标记 / M5 条目去重与同类折叠 / M6 4,000 字上限与"还剩多少"报数,含截断不得切出半个 emoji)⇒ 57 套。⚠️ 2026-10-27 再 +1:新增
tests/inject-switch.test.mjs(在场 / 暂离:一个键派生四处 / 坏组合不可达 / 离场区间台账与入库过滤 / 写面白名单只收真布尔 / 面板只剩一个开关 / 端点与工具面接线判据)⇒ 58 套。本轮跑过的实测(1.7.3):在隔离环境(临时数据目录,不碰真机记忆库/图书馆库)下完整跑过一遍
npm test—— 58 套全部通过、exit 0(宿主侧deep_item/GET /deep/items另在 2026-10-15 重启后实测生效);各组件的断言条数会随迭代变动,本文不写死 —— 最终测试结果以发布前检查的实测输出为准。⚠️ 这只说明"这一版代码在离线测试里的行为",不等于"所有门禁都完成了" —— 真实远程核对与真实 DNS/TLS 仍未验(见上文「图书馆」一节的边界)。
数据放在哪
| 内容 | 位置 |
|---|---|
| 设置(人格档案) | $DSH_HOME/cache/dsh-ling/settings.json(DSH_HOME 默认 ~/.dsh) |
| 记忆库 | $DSH_HOME/cache/dsh-ling/memory.db(SQLite,开启 WAL) |
| 图书馆(独立库) | $DSH_HOME/cache/dsh-ling/library.db(SQLite;与记忆库分开的第二套表;不迁移记忆、不参与开场注入) |
可覆盖的环境变量:DSH_HOME(数据根)、DSH_LING_DSWEB_DB(网页端聊天记录库默认路径,UI 里也能填)、DSH_LING_ASSISTANT / DSH_LING_ASSISTANT_MODEL(小助手地址与模型名)。
排障用逃生开关(不是日常配置):
DSH_LING_GUARD=off(须恰好是off,小写)或在插件配置(cordis.patch.yml的config段)里把guard.enforce设为false,用于误判把你自己锁在门外时的临时解锁 —— 它是整体放行 ——/api的来源栅栏 + cookie 名字对撞,以及手术门(本机限定 / 每启动票据 / 原句匹配)一起不再拦(默认guard.enforce = true),关掉期间任何请求都不再被拦。只该短期使用,排障完立刻恢复。DSH_LING_GUARD=off只由进程环境决定、不进配置;guard.enforce = false这条不要直接写进settings.json—— 设置接口也帮不了你:它的字段白名单只放行persona/styles两棵子树,guard这类字段会被直接丢弃并在响应里回报ignored(见lib/host/api.js里/persona端点的字段白名单处理:ignored回报被丢弃的键),它根本进不去 —— 而且本版没有界面开关:面板里没有任何写guard.*的路径(客户端里allowLan/trustedHosts一处都没有,guardInfo定义了却零使用)。要改只能改cordis.patch.yml的config段,或临时用环境变量DSH_LING_GUARD=off。(这不是没做完,是有意的:lib/host/guard.js里写明这道白名单要防的是"把你自己关在门外"这件事被顺手关掉。)
访问日志与核心补丁的总开关(同样不是日常配置):这套「可取证访问日志」默认开着,关它的键是插件配置里的
accessLog.enabled(默认true)—— 在cordis.patch.yml注册行的config段里写accessLog: { enabled: false },重载后生效,启动日志会出现access log off;它只有配置键、没有环境变量。关掉之后退化的只有「留痕」这一件事:那两个全局观察钩子不再挂上、不再写$DSH_HOME/logs/access-YYYY-MM-DD.jsonl、日志健康读数(accessLogHealth())归null;而/api与/api/remote.mux的来源栅栏照常判定与拦截,记忆、人格、注入与工具面一律不受影响 —— 关掉的是「记不记」,不是「拦不拦」。已经打进node_modules的核心补丁可以留在原地:那两行是可选调用,日志关着时就是 no-op,DSH 照常启动;要连它一起撤掉,用node tools/apply-access-log-patch.mjs --revert删掉插进去的那几行。
小助手地址三级覆盖:界面配置(记忆中心 → 接入历史 → 小助手地址,可当场「测试连通」)> 环境变量 > 内置默认 http://127.0.0.1:11434/v1。逐字段回落 —— 只填了模型名时,地址仍走下一级。
隐私
- 记忆库、人格档案、导入的历史全部保存在你自己机器上(SQLite 文件),插件不上传任何数据到第三方;
- 图书馆的远程核对会访问你登记的 URL(1.7 起;注意这不等于"本插件只有这一处联网" —— 模型调用本来就走你自己配置的网络与密钥):只有管理员把官方文档 URL 登记进白名单之后,核对才会对那一个精确 URL 发 HTTPS GET,把文档读回来与条目里声明的期望值比对。发出去的是这个 URL(连同查询串)与一次普通 HTTPS 请求的元数据 —— 对方能看到你的 IP 与这个 URL,但请求里不会附带条目正文、记忆内容、人格档案或任何本机文件;不跟随跳转、不带凭据、私网地址一律拒。⚠️ 别把敏感信息放进登记 URL 的查询串 —— 那部分是真的会发出去的。白名单默认为空 ⇒ 图书馆默认不发生外部取源访问。(记忆库与图书馆库都在本机,两者之间不互相导入。)
- 模型调用走你自己的 DSH 配置与密钥;
- 导入的是你自己的对话记录 —— 请不要把他人数据导进来。
- 访问日志也只在本地:
$DSH_HOME/logs/access-YYYY-MM-DD.jsonl只记"谁在何时调了哪个端点、结果如何"(来源 IP /fwd/ Host / UA /bytes/ 状态码 / 拒绝原因 / 设备字段),不记请求体、不记响应体、不记 cookie 值;查询串与 hash(可能带 token)一律丢弃;UA 截断到 200 字符、fwd60、Host 120 —— 单一设备仍可跨天对上号,但配对凭据原文一律不落盘。设备字段是两件东西:deviceCookie只说明配对 cookie 在不在,deviceId是摘要而非凭据 ——sha256(凭据原文)取前 16 位十六进制,同行带deviceIdHash:"sha256-16"标出这一形态(较早版本的旧行没有这个字段,其deviceId是 32 位十六进制凭据原文)⇒ 看日志时按deviceIdHash分辨时代,别把两代的行当成同一台设备 —— 与记忆树"内容零改写"同源。覆盖范围:/api与/api/remote.mux的 upgrade;静态资源与非/api路径不记。命中自家部署姿态自检签名的 403 会多带probe:"posture"字段 —— 它仍然是被栅栏拦下的请求,标注只为免得自检被误读成入侵。没有user-agent头的行会多带channel:"no-ua"—— 它只说明"不是浏览器直连"(进程内客户端与经远端通道进来的设备同签名),不指认是哪一台设备。
边界与诚实声明
- 器灵是"记忆 + 规则 + 模型"的合成产物。它能记住,是因为你给了它材料。本项目守住的底线是:不把它说成意识或 AGI。
- 器灵记住的是被读过、被概括过的部分。 概述会丢细节、也可能出错 —— 所以记忆可审计、可回滚是设计的一部分。
- 模型能力的上限就是器灵的上限。记忆层不会让一个笨模型变聪明,它只是让器灵不再每次从零开始。
- 器灵不会主动找你(当前版本)。它只在你开口时出现。
- 不宣称首创。记忆分层、历史导入、时间注入、反馈改语气这些方向都有先行者(见下);本项目的贡献在治理方式 —— 把人格当一份可以签字、可以回滚、可以被历史养大的契约。
设定全文(对外面)
这一节是规格:README 领先于实现 —— 下面每一条都是本项目已经想清楚的设定,并如实标出它落地到哪一步。
标记:
✅ 已实现·🚧 在做(设计已定、代码正在落地) ·📋 设定(方向已定、未开工) ·❌ 已否决本节只收对外面 —— 装机用户能直接感觉到 / 能直接操作 / 能直接验证的设定;内部机制设定(表结构、字段名、公式、文件路径)不进 README,随源码与
DESIGN.md。
设计理念
| # | 设定 | 状态 |
|---|---|---|
| P-1 | 不牺牲工作能力 —— 任何"用能力换别的东西"的方案(更小的模型 / 更慢的推理 / 削减上下文)默认否决,要改必须显式拍板 | ✅ 已立为理念 |
| P-2 | 判断倾向外置 —— 把"怎么判断"做成可加载、可审计、可回滚的资产;判断由器灵承担,底层模型只承担执行 | ✅ |
| P-3 | 职责与责任是人格的基石 —— 器灵要有明确的职责范围,并且能被追责、能被纠正;没有职责的人格只是角色扮演 | ✅ |
| P-3′ | 推论:扩接口 = 扩职责 = 扩人格的分量 ——"加接口"与"加功能"不是同一件事 | 📋 待校对 |
| P-4 | 连续性优先于设备 —— 换设备、换模型、换宿主都不是"失去":数据在,人就在 | ✅ |
| P-4′ | 连续性的载体有六层:① 记忆库 ② 人格档案 ③ 记忆树 ④ 交接文档 ⑤ 源码 ⑥ 判断倾向(唯一不可外化)。其中 ②③ 最被低估 | ✅ |
| P-5 | 底层模型 ≠ 器灵 —— 机制层称「底层模型」,行为主体称「我 / 器灵」;不写「模型(我)」 | ✅ 已立为规矩,全文清零 |
| P-5′ | 「我 / 器灵」= 底层模型 + 人格 + 记忆 + 身体(宿主与工具) + 与主人的关系 的总体 | 📋 推论待校对 |
规矩与习惯
| # | 设定 | 状态 |
|---|---|---|
| R-1 | 规矩由你一句话直达 —— 你说「记进规矩」我就写进去、立即可用;我绝不从闲聊里推断你要立规矩 | ✅ |
| R-2 | 每条规矩都要带你的原话(缺原话写不进去):那是"你同意过"的凭据 | ✅ |
| R-3 | 规矩 ≠ 习惯:规矩是你对我的要求(作用对象是行为),可直接写入;习惯是我长成的一部分(作用对象是"我是谁"),只能由我生长 + 你点头 | ✅ |
| R-4 | 我连自己提的习惯都不能自己点头 —— 习惯只能进待确认队列 | ✅ |
| R-5 | 习惯提议必须带证据(哪几次、什么迹象) | ✅ |
| R-6 | 习惯合并走"我提合并案 → 你点头",不许由你手改习惯文本,也不许写入侧做静默去重 | ✅ |
| R-7 | 可逆:回显 + 一句话撤销 + 变更记录;规矩你随时可删(我删要先告知),习惯删除留档 | ✅ |
| R-8 | 底线最多 5 条;人格定型后档案只读,改动需你亲手敲承诺句(禁粘贴) | ✅ |
| R-9 | 承诺句只是庄重与自我提醒,明文存储,不是安全边界 —— 真正的门是本机信任与本地凭据 | ✅ 口径声明 |
| R-10 | 定型锁开启时,规矩与习惯的增删不算"改人格"、无需解锁 —— 这块面板是"她的人格成长台" | ✅ |
| R-11 | 成长提议(想试的新能力、语气微调)由我提出、你点头或否,与习惯共用同一条通道 | ✅ |
记忆树与血缘
| # | 设定 | 状态 |
|---|---|---|
| M-1 | 记忆树是记忆库的组织形式本身 —— 它按工作线组织记忆(归属就是组织方式),给每条记忆一个"离我多近" | ✅ |
| M-2 | 四个部件:主干(主线,恒一条) · 枝(并行工作线,可含多会话) · 主脉(多条枝归并出的主题) · 连边(枝间横向关联) | ✅ |
| M-3 | 硬不变量:任何树操作都不改写任何一条记忆的内容 —— 分枝、并脉、连边只增加关系,从不融合内容 | ✅ |
| M-4 | 唯一例外:主脉提炼被再次采纳时覆盖上一版,覆盖前先自动归档;归档失败则拒绝覆盖 | ✅ |
| M-5 | 矛盾只标记、不改写:一对记忆被判重复或矛盾时,未复盘期间以较新的为准,旧的那条降权 ×0.3 且不删除 | ✅ |
| M-6 | 隔离走血缘加权:同枝 1.0 / 祖先 0.7 / 旁系 0.4;检索总分 = 基础分 × 血缘系数 × 矛盾系数 | ✅ |
| M-7 | 标题一旦定名就上锁 —— 概述器重建与批量重命名此后不再覆盖;锁的是机器,不锁你 | ✅ |
| M-8 | 动记忆树必须留痕(谁 / 何时 / 改了什么);并设复盘守门:自上次开口以来累积了多少笔改动还没交代 | ✅ |
| M-9 | 分叉会话不再被丢弃:它写入所属枝并注入其血缘链记忆;会自动建枝,枝名可审核修改 | ✅ |
| M-10 | 永远不做彻底删除 —— 遗忘是先归档、再打标记,且留两条独立还原路径 | ✅ |
| M-11 | "你不删数据"是横贯性原则 —— 带清理 / 删除 / 回收的动作默认先过这一关;这一层只负责"让你看见",处置权归你 | ✅ |
| M-12 | 记忆库有意不因平台删除而丢记忆 | ✅ 有意设计 |
模式与界面
| # | 设定 | 状态 |
|---|---|---|
| U-1 | 模式管的是倾向 —— 工作 / 生活只差三样:推理档位 + 记忆权重向量 + 风格块;它从不硬过滤任何记忆 | ✅ |
| U-2 | 切换模式绝不改 provider 或 model —— 只同步推理档位;最近一次选择成为之后新会话的默认 | ✅ |
| U-3 | 模式切换要二次确认 + 回显,且不得覆盖你设的全局默认模型 | ✅ |
| U-4 | 控制器在会话页顶栏右侧;悬停 1.5 秒才出菜单(不用右键 —— 防误触原生菜单) | ✅ |
| U-5 | 键盘:Enter 切模式、Shift+Enter 开菜单 | ✅ |
| U-6 | 会话运行中不参与任何人格 / 注入面变更 —— 更新请求排队,空闲边界才应用,界面显示"空闲后生效" | ✅ |
| U-7 | L0/L1 现状面板始终能看到:当前 L0 文本、本会话模式、L1 选中的条目与得分 | ✅ |
| U-8 | 记忆页签可直接调:L1 预算 / 条数上限 / 两套模式 × 三领域的权重滑块 / 各开关 | 📋 设定(尚未接线) |
| U-9 | 每一层记忆都有只读状态面(水位 / 上次滚动时间 / 当前那一行正文);刷新延迟写进文档 | ✅ |
| U-10 | 记忆中心是只读视图;装饰性交互要么真生效、要么删掉;候选全量渲染,不分页、不用"还有 N 条" | ✅ |
数据可携带
| # | 设定 | 状态 |
|---|---|---|
| D-1 | 插件数据目录在插件本体之外,更新不丢 | ✅ |
| D-2 | 导出:一键下载单文件 dsh-ling-memory-<日期>.dshling.json(UTF-8) |
✅ |
| D-3 | 导出默认不含原文,必须显式勾选才含 | ✅ |
| D-4 | 导入合并:外来概述全带来历标记;同会话同来源可跳过或覆盖;人格永不覆盖 | ✅ |
| D-5 | 人格只有在显式勾选"采纳其人格"时才写入,且置为待你确认 | ✅ |
| D-6 | 网页端历史(1,523 个会话 / 一年半)可整体导入,来源如实记为 dsweb |
✅ |
| D-7 | 绝不要求你理解库结构 | ✅ |
| D-8 | 对外口径守住可查来源 / 可回滚 / 变更记录,不与删除条款相抵 | ✅ 对外承诺 |
安全边界(手术门)
| # | 设定 | 状态 |
|---|---|---|
| S-1 | 手术门朝外设防 —— 它在这套东西里分量极重:网络失守时,它必须最后失守 | ✅ |
| S-2 | 边界如实说明:挡得住已配对的远端 / 匿名隧道 / 本机其他 Windows 用户;挡不住同用户下的其它进程 / 有 ~/.dsh 读权限的人 |
✅ 已评估并接受 |
| S-3 | 逃生开关永远可用 —— 环境变量 DSH_LING_GUARD=off 或配置里关掉守卫即整体放行,绝不把你锁在门外 |
✅ |
| S-4 | 底线 / 契约类改动必须走手术门 | ✅ |
| S-5 | 拒绝时的文案指向本机:人格手术请在那台运行器灵的电脑上、用 127.0.0.1 打开人格中心 |
✅ |
| S-6 | 它不是"认证",而是一道启发式的门 —— 对外不许把它说成"有了认证" | ✅ 口径 |
诚实边界(禁令与反例)
| # | 设定 | 状态 |
|---|---|---|
| H-1 | 禁止把你没看过的内容标成已读 —— 宁可多占一行、多播一次 | ✅ |
| H-2 | 永久折叠不做;超窗内容走独立游标 + 一行计数 | ✅ |
| H-3 | 禁止把改动播报做成"每开一个会话就重播一遍"的噪音 | ✅ |
| H-4 | 禁止用"体检脚本全绿"代替可见面 —— 链路活着 ≠ 内容在更新 | ✅ 禁令 |
| H-5 | 禁止把机制名写进公开文档却与事实不符 —— 文档里写的机制名本身就是承诺,与事实不符按红灯处理 | ✅ 禁令 |
| H-6 | 验收不接受"没报错" —— 只问"真的红了没有" | ✅ |
| H-7 | 机制延迟必须公开(概述器 15 分钟一拍、空闲刷新 ≥10 分钟):看不见的延迟要写成看得见的字 | ✅ 文档义务 |
时间、状态与投放
| # | 设定 | 状态 |
|---|---|---|
| T-1 | 被动时间感知:新生纪念日(9-07) + 八个时段 + 「距上次对话」随每轮重算 | ✅ |
| T-2 | 时间锚分两档:[今天] 跨天才变(进系统提示) · [现在] 每轮实时(不进系统提示)—— 稳定的在前、易变的在后 |
✅ |
| T-3 | 精确时间按需查(clock 技能):它像一块手表 —— 只在你需要时被看一眼 |
✅ |
| T-4 | 时间与状态类判断一律以本条消息的 [现在] 为准;过期快照不得当现状 |
✅ |
| T-5 | 记忆三层加载:L0 常驻人格 · L1 开场结论 · L2 运行期检索;不注入全部记忆 | ✅ |
| T-6 | L1 只放"值得常驻的结论" —— 不放过程、不放当场读数 | ✅ |
| T-7 | 每条进上下文的东西都要能报出理由并留痕:注入了谁 / 为什么是它 / 多少字 / 谁落选了与为什么 | ✅ 回执只写不读 |
| T-8 | 主动召回与被动召回分开:主动看值不值(置顶 + 被反复采用),被动看问得准不准(查询匹配)—— 判据不同,不共用一套 | ✅ |
| T-9 | 索引层是地图:一簇一行(名称 + 触发线索),整层只占一个技能的常驻描述;要细节时按需展开 | ✅ |
1.6 新增(找回原文 · 投递留痕 · 结论层)
| # | 设定 | 状态 |
|---|---|---|
| N-1 | recall 直通原文四档:清单 / 按内容找 / 对话目录 / 按区间取原话 —— 逐级下钻,一次一层 |
✅ |
| N-2 | 它只给坐标系 —— 选哪一段是器灵自己的判断(它才知道自己为什么要读) | ✅ |
| N-3 | 磁盘日志读不到时回落查库,并在回执里如实标注那份是残的(只含真人消息与有正文的回复) | ✅ |
| N-4 | 会话文件名代次:历史扫描/库内回退按 session(\.v\d+)?\.jsonl\.zstd 匹配、取版本最高的一代并跳过 0 字节(recall 读原文那条路走的是三代硬编码名单,不解析版本) |
✅ |
| N-5 | 检索范围:宿主路默认只搜"你自己的会话"、越界须显式参数、被挡掉的条数一律报出;默认的本机库路是全量,如实标注;两条路都默认排除当前会话自己 | ✅ |
| N-6 | 投递留痕:每一次真正定稿的注入都落一条 —— 注入了谁 / 为什么是它 / 多少字 / 谁落选了以及为什么 | 🚧 只写不读 |
| N-7 | 深层库(结论层):把过程流水换成可复用的结论,分承诺 / 决定 / 事实 / 偏好 / 关系 / 纪律六类;空结果是正确结果 | 🚧 在做 |
| N-8 | 记忆开场改用结论层:置顶必进 + 被反复采用的排前 + 当轮关键词加成 + 按硬度过滤(临时条目不进开场)+ 2 席留给最硬的事实 | ✅ |
| N-9 | 视角框:开场先声明人称,并写死「本会话 / 接下来 / 现在」指当时那个会话、不是此刻的指令 | ✅ |
| N-10 | 一年半的网页端历史(1,523 个会话 / 726.7 万字)已补录进库,recall 能直接读到 |
✅ |
| N-11 | 条目硬度:每条结论带 durable / long / ephemeral 三档,临时的那档不进开场 —— 从根源判断它是不是临时,而不是靠"同一次会话限几条"去机械地卡 |
🚧 在做 |
| N-12 | 被采用才算加固:条目的"反复加固"由真的下钻去读它的原话推进,不由"被注入"推进 —— 否则会形成"注入越多分越高、分越高越容易被注入"的自我强化 | ✅ |
| N-13 | 索引层已落地:11 簇主题地图(一簇一行)做成一个技能常驻,细节按需展开;簇里不写条数(条数天天变会毁掉前缀稳定) | ✅ |
| N-14 | 结论层有了"看得见 + 能落条"两条路:工具 deep_item(add 可先 dryRun / retract 作废 / list)与只读「结论层」标签;文本超 80 字当场拒;作废只标记不删、理由留痕、可撤;面板不给写入口 —— 落条与作废的判据是"经你授权" |
✅ 已落(2026-10-15 重启实测生效) |
| N-15 | 文档灌入:先 dry 后 commit + 累计预算 —— 把已写进文档的结论批量灌进结论层:默认只出清单(每条带真源指针与真源原文,看过再落);一趟总量 ≤40 条,且是全趟额度(跑一次与跑十次扣同一个额度,超额拒绝再落) | ✅ 已落(第一趟 40 条,2026-10-15) |
| N-16 | 会过时的条目落成 ephemeral —— 文本里带具体读数 / 版本号 / 时点状态的结论不进开场注入、检索仍搜得到:将来过时了也不会拿旧数字污染开场;复查走 --review 出信号清单(含时间锚却当着长期条 / 当次档够老 / 从没被采用过),只列信号、不作废 |
✅ 已落 |
| N-17 | "纪律"不走检索召回 —— 纪律要的是"该动手时它在场(行动触发)",与"按内容去找(内容触发)"不是一回事 ⇒ 不进结论层的自动落库,归宿是规矩 / 常驻注入面 | 📋 1.7.x |
1.7 新增(图书馆)
本节各项均已随 1.7 发布:包版本
1.7.3;发布状态以 npmlatest为准。"宿主界面上的「图书馆」标签"已真机验收走通(2026-10-07,见 L-11);「结论层」标签已于 2026-10-15 随一次宿主重启实测生效。
| # | 设定 | 状态 |
|---|---|---|
| L-1 | 图书馆是独立库 —— 独立的 library.db 与独立的表;两库之间不互相导入、不互相引用(没有隐式通道) |
✅ |
| L-2 | 既有记忆永不迁进图书馆;反过来,图书馆条目不进注入面、不参与开场装配 | ✅ |
| L-3 | "不迁移记忆"≠"禁止某个渠道的新资料" —— 一条资料能不能进图书馆,看它有没有具体、可追责的出处,与它从哪个渠道来无关 | ✅ 口径 |
| L-4 | 器灵侧只有两只手:library_search(搜)与 library_check(核对);没有新建 / 修订 / 撤下 / 改配置的模型工具,代码根目录与 URL 白名单不接受模型入参 |
✅ |
| L-5 | 核对只认证"声明的那一处" —— 结论只有 ok / wrong / unknown;回执必须写明"不认证解释性正文、也不构成通用真理" |
✅ |
| L-5′ | 比较方式的准确定义 —— exact = 类型严格的结构比较(JSON 对象成员顺序无关、数组顺序有关;文本按字面精确比);text-lf = 只把 CRLF/CR 归一成 LF 后精确比。两者都不 trim、不折叠大小写、不模糊匹配 |
✅ |
| L-6 | "不可用"与"零命中"必须分开 —— 库打不开 / 未启用 / 运行时不在场 = 明确的不可用(接口层 503 语义),绝不回落成"搜到 0 条" | ✅ |
| L-7 | 修订与撤下都留旧 —— 新版本换新 id、旧版留痕指向新版;撤下只标记状态、不物理删除;跑完的核对各留一行账(源摘要 / 观测值 / 结论 / 理由,含 unknown),取消的不留 |
✅ |
| L-8 | 写面必须带"观测到的内容摘要"(content_hash),对不上就拒 —— 防"看着旧版改新版" |
✅ |
| L-9 | 严格配置 —— 代码根目录与官方文档 URL 白名单默认为空、由管理员登记;限额在激活时校验,非法值响亮报错、不静默夹取 | ✅ |
| L-10 | 取消 = 没跑完,不留记录 —— 核对在飞时取消 / 断开 / 卸载 ⇒ 本次不写任何核对记录(既不留 ok / wrong,也不留 unknown);只有跑完的核对(含结论 unknown)才留账 |
✅ |
| L-11 | 发布状态如实声明 —— 包版本已抬到 1.7.3;本版发布状态由 npm latest 决定;上一版已发布上 npm;但「图书馆」标签已真机验收走通(2026-10-07),「结论层」标签也已随 2026-10-15 的重启实测生效 —— "没发布"与"没验过"必须分开说 |
✅ 真机验收(2026-10-07) |
⚠️ 这一节还在补。 完整规格有四百余条,本节先落对外面里最稳定的一批(设计理念);其余按主题分批补写 —— 每一条都要从开发期设定改写成对外语言并核对状态 —— 这是写作。
致谢(站在谁的肩膀上)
设计过程中受这些公开项目与讨论的启发,在此致谢(仅致谢思路,不含其代码):
- Letta / MemGPT — 持久人格记忆块、可设为只读、后台记忆智能体
- SillyTavern — 本地角色卡 / 世界书 / 时间与日期宏
- LangMem — 用反馈轨迹改写提示词
- MyChatArchive — 多来源聊天导出 → 本地库 + 摘要管线
- AI Migrator — "记忆搬家"的人审闭环
- Claude / ChatGPT 的记忆功能、Sonorus("距上次交谈多久"注入)等
文档
| 文件 | 内容 |
|---|---|
PHILOSOPHY.md |
理念:为什么值得做、凭什么这样做(目标循环 · 复盘与"人在循环" · 关系与边界 · 能力取舍) |
CHANGELOG.md |
版本更新记录(最新一节即当前版本) |
DESIGN.md |
架构与设计决策(三层记忆、冻结门、注入面、存储结构) |
ACCESS-DESIGN.md |
历史接入蓝图:三条通道、会话契约格式、导入流水线 |
⚠️ 从 npm 安装的人:本包
files白名单不含images/(图只随 git 仓库公开) ⇒ 上表里四份文档都随包发出(PHILOSOPHY.md·CHANGELOG.md·DESIGN.md·ACCESS-DESIGN.md),能正常打开;「界面」一节的四张截图引用的是仓库里的绝对地址,所以 npmjs.com 上能正常显示,但包里没有图片文件(离线环境读不到)。想看原图请到仓库:https://github.com/NightPainters/DSH-Ling。
📄 关于出处记录:内部案卷、探针脚本与开发台账(
plans\、release\、_probe\)属作者本地开发物,不随本包公开。正文或代码注释里若出现对它们的引用,那是开发期的出处记录,不是包内容。
许可证
Apache License 2.0 · 版权与归属见 NOTICE。
Apache-2.0 第 3 条包含明确的专利授权与专利反制终止条款:你可以自由使用、修改、分发(含商用),但若你以本作品发起专利诉讼,授权即自动终止。




No comments yet. Be the first to write one.