dsh-code-taste
Learns a user's coding conventions from instructions and corrections, stores them as confidence-scored rules in editable Markdown, and injects them as reference data into every session. Rules that decay out of range or contradict a newer rule stay visible for review instead of being applied.
Install
dsh plugin --profile web add dsh-code-taste
Sandbox test results
| Stage | Result |
|---|---|
| 1 install | ✓ |
| 2 list | ✓ |
| 3 mount | ✓ |
| 4 boot | — |
Four stages run in an isolated sandbox: install (network on) → list → mount → boot (last three with no network).
README
dsh-code-taste
[English](README.md) | 中文
一个 DeepSeek Harness 插件:让鲸鱼持续学习你的代码品味、审美风格和各种习惯,并在每个会话里照着写。
它是什么
新开一个会话,它什么都不记得——你要重新说一遍 const 别用 let、圆角 8px、commit 怎么排、回复用中文。这个插件专门听这些时刻:把你说的话变成带置信度的规则,存成一份你能手改的 markdown,然后在每个会话开始时把已经确认的那些放到模型面前。
所有东西都是你本机上的纯文本文件,不联网、不埋点。
信号
它从什么里学,以及现在还看不到什么:
信号 · 长什么样 · 状态
显式指令 · 记住:以后都用 const · 已支持 — 0.85–0.90 直接写入
禁令 · 永远不要用 moment.js · 已支持 — 0.88
纠正 · 不要用 any,改成 unknown · 已支持 — 0.60 进待确认
正向反馈 · 对,就这样 · 已支持 — 给当前最强那条 +0.10
接受 · 你看了改动,直接继续往下做 · P1 — 用“后续没有编辑”推断
拒绝 · 你拒绝了工具调用,或把改动撤回 · P1 — 监听工具决策和工作区 diff
编辑 · 你把 AI 刚写的东西重写了 · P1 — 对比 AI 写入的内容与之后的文件
选择 · 你从它给的几个方案里挑了一个 · P1 — 对提问的回答,或你反复选的做法
前四条今天就能用。后四条(接受/拒绝/编辑/选择)才是最诚实的信号——你留下什么、扔掉什么、重写什么——也是下一个版本的重点:它们要盯工作区和工具管线,而不只是聊天内容,所以分开做、分开验证。见 [docs/ROADMAP.md](docs/ROADMAP.md)。
安装
环境要求
- DeepSeek Harness
0.2.x(在0.2.1-rc.2上验证) - Node.js
22.19+或24+(就是 DSH 自己跑的那个版本)
没有其它依赖:这个 bundle 零依赖,也不需要构建。
从 GitHub 安装
dsh plugin --profile desktop add github:BaxterL/dsh-code-taste
从本地目录安装
git clone https://github.com/BaxterL/dsh-code-taste dsh plugin --profile desktop add ./dsh-code-taste
本地目录是链接进去的,不是拷贝,所以改完源码重启一次就生效。
让 DeepSeek 帮你装
把下面这段直接粘给一个 DeepSeek Harness 会话,它会替你做:
把 https://github.com/BaxterL/dsh-code-taste 这个 bundle 装进我当前的 DSH profile。 1. 用 plugin_manager 的 install_bundle,target 填 `github:BaxterL/dsh-code-taste`; 或者执行 `dsh plugin --profile <profile> add github:BaxterL/dsh-code-taste`。 2. 不要动其它任何插件、bundle、配置或工作区文件。 3. 不要自己重启。告诉我是否需要重启、会影响什么。 4. 装完把 row id、解析到的版本号,以及验证步骤告诉我。
正常情况下它会回答:row id 是 taste、版本号是多少、以及 restart-required。如果它说 applied,说明已经加载;否则重启后再跑一次 taste list。
必须重启
bundle 的行是在宿主启动时插入的,新装 bundle 没有热重载。装完重启 DSH。
验证
新开一个会话,向模型要规则:
taste list
空工作区会回答 No taste rules yet for this workspace.——说明工具已经挂上,只是还没学到东西。第一条规则被捕获后,<工作区>/.dsh/taste/ 目录会出现。
更新
dsh plugin --profile desktop add github:BaxterL/dsh-code-taste # 重装最新
然后重启。本地目录安装的,git pull 就够。
卸载
在 设置 → 插件 里移除,或者:
dsh plugin --profile desktop remove dsh-code-taste
然后重启。你的 TASTE.md 不会被删——想彻底清空,自己删掉 .dsh/taste/ 和 ~/.dsh/taste/。
使用
说话就行
你说 · 会发生什么
记住:以后都用 const · 立刻写入,置信度 0.85–0.90,直接生效
永远不要用 moment.js · 立刻写入为 guardrail,0.88
不要用 any,改成 unknown · 进待处理队列,taste learn 复核后才写入
对,就这样 · 给当前注入的最强那条 +0.10
问句、一次性指令(“这次”“先这样”)、任何含密钥的内容,在进库之前就被丢掉了。
复核它学到的东西
纠正不会直接污染提示词,先等你确认:
taste review taste approve id:r_8f2a1c
同一条被看到第二次时,也会自己转正。
手改规则文件
<工作区>/.dsh/taste/TASTE.md
## code-style - [r_8f2a1c] 统一用 const,除非需要重新赋值 @0.85 src:explicit ev:2 ## avoid - [r_9x8y7z6] 不引入 moment.js @0.72 src:correction ev:3 [pending] [glob:src/ui/**]
格式是 - [id] 正文 @置信度 src:来源 ev:次数 [pending|archived] [pinned] [glob:路径]。
不符合格式的行一律当注释,所以你可以随便加说明。
查看依据
taste why id:r_8f2a1c
打印这条规则的证据:什么时候抓到的、触发了哪个信号、原话是什么(截到 200 字,永远不存上下文代码)。
导出给别的工具
taste export format:agents # .dsh/taste/export/AGENTS.taste.md taste export format:claude # .dsh/taste/export/CLAUDE.taste.md
导出的片段只列生效规则、不带置信度,可以直接贴进 AGENTS.md 或 CLAUDE.md。
配置
默认是 regex 模式,一次模型调用都没有。要切换,在你自己 profile 的
cordis.patch.yml 里覆盖这一行:
- id: taste
name: dsh-code-taste
config:
mode: hybrid
model:
format: openai
baseURL: https://dashscope.aliyuncs.com/compatible-mode/v1
model: qwen-plus
apiKeyEnv: DASHSCOPE_API_KEY
两种模式
mode · 模型调用 · 行为
regex(默认) · 无 · 显式指令和禁令立即写入;纠正等你 taste learn
hybrid · 每批一次 · 用一个小模型把一批信号蒸馏成规则,有节流和上限
模型线路
format: openai 走任何 /chat/completions 接口:
线路 · baseURL · 模型示例
通义千问 / DashScope · https://dashscope.aliyuncs.com/compatible-mode/v1 · qwen-plus
Ollama(本地) · http://127.0.0.1:11434/v1 · qwen2.5-coder:7b
llama.cpp(本地) · http://127.0.0.1:8080/v1 · -m 加载的那个
LM Studio(本地) · http://127.0.0.1:1234/v1 · 加载的模型 id
vLLM(本地) · http://127.0.0.1:8000/v1 · 服务的模型 id
format: anthropic 走 Messages API:
format: anthropic
baseURL: https://api.anthropic.com
model: claude-sonnet-4-5
apiKeyEnv: ANTHROPIC_API_KEY
本地接口一般不需要 key:apiKey 和 apiKeyEnv 都留空即可。apiKeyEnv 填环境变量名,
apiKey 是直接写死的兜底值。不要把 key 提交进仓库——taste config 只会显示
env:NAME 或 (inline key set)。
token 预算
配置项 · 默认 · 含义
mode · regex · 完全不调用模型
extract.minPending · 3 · 攒够这么多信号才调一次
extract.throttleMinutes · 10 · 每个会话每个窗口最多一次
extract.maxInputChars · 4000 · 输入约 1000 token
model.maxOutputTokens · 256 · 输出硬上限
extract.maxRulesPerRun · 3 · 单次最多接受的规则数
injectBudgetChars · 3000 · 每轮注入约 750 token(最小 400)
regex 模式下唯一持续的开销就是注入那一段:默认约 750 token,其中大部分是固定的引导语。
嫌多可以把 injectBudgetChars 调小。
taste config 会打印当前模式、预算、线路和警告,不会打印 key。
工具
插件只暴露一个工具:taste。
action · 参数 · 作用
list · — · 列出全部规则:作用域、分类、置信度、是否在注入
learn · — · 取走本会话累积的纠正,交给模型蒸馏
add · text、category?、scope?、confidence?、glob? · 新增一条,或强化一条近似规则
review · — · 列出待确认候选(这些不会被注入)
approve · id · 把候选转正
forget · id、scope? · 从项目/全局里删掉一条
why · id · 打印这条规则的证据
profile · — · 一段话的品味画像 + 最强的几条规则
export · format(agents \ · claude) · 在 .dsh/taste/export/ 下生成片段
参数说明
text— 一句祈使句,≤ 200 字。写成一个月后还看得懂的样子:“统一用 const,除非需要重新赋值”,而不是“这里改一下”。category—code-style(默认)、design、stack、workflow、project-detail、communication、avoid。只用于分组和在提示词里加标签,不改变行为。scope—project(默认)只在这个工作区生效,global全局生效。同名规则项目覆盖全局。confidence—0.1–0.95。不填就按来源定:模型自己加的是0.55,显式指令是0.85–0.90。低于0.55的进pending,不会注入。glob— 把规则限定到匹配的路径,比如src/ui/**。目前只存储并展示,路径匹配在 P2 做。id— 内容寻址(r_+ 归一化
…(truncated)
Rendered from the README published on npm. Formatted only, not edited.
Versions
Published on npm::5,最后更新 2026-10-31