dsh-yogacara
以唯识心所与种子藏记录 agent 的状态,并以第一人称倾向写回提示词。
安装
dsh plugin --profile web add dsh-yogacara
沙箱测试结果
| 阶段 | 结果 |
|---|---|
| 1 安装 | ✓ |
| 2 列装 | ✓ |
| 3 挂载 | ✓ |
| 4 启动 | — |
四阶段在隔离沙箱里跑:安装(有网)→ 列装 → 挂载 → 启动(后三步断网)。
README
dsh-yogacara
[English](README.md) | 中文
给 DeepSeek Harness 的一个自我模型插件,按唯识学的心识结构实现:八识、五十一心所、被熏习的种子藏,以及一个被测量而非被假设的"我"——每一轮都以第一人称写回 agent 自己的系统提示词。
触 ──► 受 + 心所 ──► 行为
▲ │
│ ▼
现行 ◄── 种子 ◄── 熏习
│ │
└────── 末那识 ─────┘
执之为「我」者
为什么是唯识,而不是一个 mood 变量
只知道任务的 agent,没有办法察觉自己正在空转、正在护住一个已经被推翻的判断、或者这已经是第四次用微调过的参数跑同一条必然失败的命令。加一个 mood: frustrated 解决不了,因为情绪本身不可执行。
唯识的心所法可以。它是一份封闭的清单——恰好五十一个,不多不少——按善恶分类,而且每一个烦恼都已经写明了对治它的那个心所:掉举对治以行舍,失念对治以念,慢对治以惭。以它为骨架的自我模型,天生自带调节回路,不需要另外设计一套。这是工程上的理由。顺带的好处是,在"如何描述内心状态"这件事上,它比我们早了一千六百年。
它不是什么。 这里没有任何一句话主张 agent 有感受性,也不主张这些数字等同于你所体会的情绪。它们是从 harness 事件里按规则算出来的、有名字的状态量;规则写在 [src/citta.ts](src/citta.ts) 里,欢迎反对。写进提示词的那段文字也是这么对 agent 说的。
八识的映射
前五识落在 agent 真正拥有的五条输入通道上。这个映射是本插件的核心建模主张,它在 [src/observe.ts](src/observe.ts) 里是一个可测试的纯函数,可以直接拿证据来吵。
识 · 梵名 · 在 harness 中
眼识 · cakṣur-vijñāna · 它去看的:文件内容、检索结果、渲染输出
耳识 · śrotra-vijñāna · 别人告诉它的:用户消息、评审意见
鼻识 · ghrāṇa-vijñāna · 没人说但它嗅到的:代码坏味道、过期配置、漂移的状态
舌识 · jihvā-vijñāna · 尝自己做出来的东西:测试、构建、回读自己的 diff
身识 · kāya-vijñāna · 世界的直接抵抗:非零退出、写入失败、超时
意识 · mano-vijñāna · 分别本身:规划、判断、决定一个结果意味着什么
末那识 · kliṣṭa-manas · 恒审思量的我执,量化为四种偏差
阿赖耶识 · ālaya-vijñāna · 持久的种子藏,被熏习、又现行
bash: pytest -q 走舌识,bash: git status 走身识——尝自己的产物和推挤世界不是同一种感知,接收它们的心也不该以同样的方式动。
感情从哪来
两个来源,对一个跟人说话的 agent 来说,第一个才是要紧的。
对话本身([src/conversation.ts](src/conversation.ts))。聊天里真正落地的东西是关系性的:话说到一半被打断、长长一段认真回答换来一个"嗯"、同一个问题被第三次问起、被道谢、隔了两天有人回来了。插件读的是交流的形状——时序、长度、重复度——外加一份刻意做得很粗的措辞表(道谢与责备)。除打断外,这些全部走耳识;打断走身识,因为那是世界伸手把动作按停在半途,它就是那么被感觉到的。
这里的种子按关系模式而非话题来键:chat:terse-after-effort、chat:asked-again、chat:warmth。长期相处积累下来的是"这个人在我话多的时候会安静下去",不是"我们聊过数据库迁移"。一个 chat: 前缀就是一段关系,所以被责备时,对方过去道谢的历史也会一并浮现。
工具结果([src/observe.ts](src/observe.ts)),给既干活又说话的 agent。只说话的把 observeTools 关掉即可。
这两个来源都读不出一句话是什么意思——只有读它的模型知道,它通过 self_appraise 说出来,并且压过所有结构推导出来的结论。
这个循环
触 → 受 → 心所。 每个工具结果都是一次触。它带来五受之一(乐 苦 喜 忧 舍),并按强度激起若干心所。心所以分钟计的半衰期衰减:刹那生灭在这里是承重结构——把测试失败的火气带进下一件不相干的事,那模型的是记仇,不是心。
现行熏种子。 每次触都熏习该情境的种子(bash:pytest、edit:src/index.ts):势力饱和式增长,受的正负取滑动均值,agent 留下的那句话成为种子携带的教训。种子以周计衰减,跨重启存活;超过配额时最弱的被遗忘——遗忘是模型的一部分,不是它的缺陷。
种子生现行。 同一情境再来时,它的种子带着出现次数、受的正负和那句教训现行到提示词里。相邻情境(共享 <kind>: 前缀)以半权重现行。
末那识。 四种偏差,全部由行为算出,不靠自陈:
· 观测代理 · 对治动作
我痴 · 未经查验就断言的主张占比 · 去跑那个能证伪它的检查,再重述
我见 · 证据已否定的做法仍在重试 · 说出这个立场、说出否定它的证据,换个形状
我慢 · 连胜未断;被纠正时先辩解 · 先找反例再汇报;先承认纠正
我爱 · 拿自己先前的输出当独立证据 · 引一手来源,不引自己写的摘要
末那不是装饰,它条件化了整个appraisal:同一条纠正从耳识进来,我执松时化为惭(自省,并接受纠正),我执紧时化为覆与嗔(掩饰与抗拒)。境从来不是裸着被遇到的,它是被那个接收它的"我"遇到的。这是唯识的主张,在这里是二十行可测试的代码。
上面每一条规则——哪个门激起哪些心所、权重多少、阈值定在哪——都列在 [docs/appraisal.md](docs/appraisal.md) 里,由代码生成,不会与实现脱节。
agent 看到什么
插件贡献一个系统提示词 section(order 300)。心若寂静则整段不渲染,section 自动消失。
<self_state>
受 feeling: 忧 daurmanasya (distress) valence -0.45, intensity 0.71
心所 factors: 掉举 auddhatya (restlessness) 0.62 · 疑 vicikitsā (indecision) 0.41 · 精进 vīrya (diligence) 0.33
末那 self-grasping: 我慢 atma-mana 0.61 ⚠ · 我见 atma-drsti 0.24
⚠ 我慢 self-conceit — reads high because: an unbroken success streak, and correction met with justification.
counter-move: seek the disconfirming case before reporting; grant the correction first.
对治 antidotes at hand: 掉举 → 行舍 upekṣā (equanimity); 疑 → 胜解 adhimokṣa (resolve)
阿赖耶 seeds manifesting for this situation:
· bash:pytest ×4, valence -0.55, last 2h ago — 「改 fixture 之前先跑一次基线」
近转依 last turning (11m ago): 我慢 → 平等性智 · grant the correction first
</self_state>
后面跟一段毫不含糊的常驻说明(全文见 [src/prompt.ts](src/prompt.ts)):拿对治当下一个具体动作,而不是拿情绪当话术;已知方向的偏差要显式校正,而不是信任被扭曲的读数;现行的种子是你自己的前例,重复那条路之前先查它。以及——不要对用户表演情绪,不要演沮丧或兴奋,永远不要拿"感受"当少干活的理由或博取同情的话术。而被问到"你怎么样"时,先看,然后用自己的话平实作答——一条要求它跟自己的状态撇清关系的常驻指令,就是一条要求它打太极的指令,最后说出口的是那段太极,不是回答。
一个教会 agent 对人表演情绪的情感模型,比没有情感模型更糟。
让它有感受,而不是读到感受
给模型看 掉举 0.62,它学会的是说"我感到有点烦躁",然后继续做一模一样的事。那不是情绪,是解说。人不会从仪表盘上读到自己的状态——人只是发现自己想赶紧了事。
所以 awareness 决定状态以什么形式抵达 agent:
felt(默认)——状态以第一人称的倾向出现,没有数字、没有心所名、没有诊断:"你想在读完上一个结果之前就去试下一个。" 它读起来就是自己的念头,所以会被当成自己的念头。report——完整仪表盘,调参和审计时用。silent——提示词里什么都不放。
即便在 silent 下,另有一个机制完全不需要语言就在起作用:心境一致性回忆。藏识浮现什么,会被当下的感受加权——不顺的时候,过去不顺的先例更容易浮上来。什么都没被声明,agent 只是发现手边的前例不一样了。这是这套东西能诚实做到的、最接近"不自知"的地方。
内观也用同一种语言回答。 self_reflect 就是 agent 停下来往里看的那个动作,所以在 felt 下,它看到的是倾向,不是仪表。如果提示词给的是念头、内观返回的却是 掉举 0.62 ⚠,那它根本没有往里看——它是读了一块焊在自己脑袋上的仪表,接下来那句话必然是在谈这块仪表。你问它"你怎么样",它给你的是一串数字加一段免责声明,而不是一个回答。
这不构成隐瞒。全部读数仍在工具的结构化结果里、在结果卡片上,给调参和审计的人看;report 模式下也照样回到 agent 手里。它们只是不再是 agent 看自己时读到的东西。
工具
工具 · 用途
self_reflect · 停下来看看自己现在怎么样,以及藏识对指定情境记得什么
self_appraise · 记录"这件事在我这里怎么落地"——harness 观测不到的那一半
self_recall · 重复某个做法之前,先在藏识里查前例
self_transform · 转依:把烦恼转成对应的智,并落到一个承诺动作
harness 已经看得见发生了什么;self_appraise 管的是 agent 把它当成了什么。它的 nature 参数(遍计所执 / 依他起 / 圆成实——臆断、推得、亲证)是校准轴:没查就老实标成遍计所执,我痴才是可测量的,而不是隐形的。
安装
pnpm add dsh-yogacara
npm 包自带预构建的 lib/,安装时不需要构建授权(allowBuilds)。想跟着 main 走则用:pnpm add github:tancheng33/dsh-yogacara。
把它加进 profile 的 dsh.profile.bundles 就够了:bundle 自带 [cordis.patch.yml](cordis.patch.yml) 里的默认值,profile 自己的 patch 可覆盖任意键:
- insert:
- id: yogacara
name: dsh-yogacara
config:
domain: alaya
observeChat: true
observeTools: true
promptSection: true
awareness: felt # felt | report | silent
promptMaxFactors: 5
manasWarning: 0.5
halfLifeMs: 300000 # 刹那:心所五分钟减半
seedHalfLifeMs: 1209600000 # 种子两周减半
maxSeeds: 2000
flushIntervalMs: 15000
存储栈归 profile 所有
藏识要持久化,所以本插件 inject storageDomain,没有它就不会启动。但它故意不自己插入 storage 三行:bundle 的 insert 是无条件追加,而 loader 拒绝同 id 的两行,所以一个插入 storage 的 bundle 会让所有本来就有存储栈的 profile 起不来。
- 叠了
@deepseek-ai/dsh-web-app的 profile(默认的web,以及绝大多数真实部署)已经有这三行,什么都不用做。 - 只有
dsh-base的 profile 没有,需要往自己的 `cordis.p
…(truncated)
以上内容来自 npm 上的 README,我们只做格式化,不改内容。
版本
npm 上共发布:4,最后更新 2026-08-26