DSH 后台对话反思插件,在每轮结束后静默复盘用户消息,把反复出现的纠错或工作流沉淀为本地技能文件供后续会话直接调用。
- 语言
- TypeScript
- 分支
- main
安装
$ dsh plugin --profile web add github:LoserFox/distill在终端中运行以上命令,通过 dsh CLI 安装此插件。可在右上角切换 Profile。 第一次用 dsh?看这篇新手教程
对话式安装
帮我安装 DeepSeek Harness 插件 LoserFox/distill:先查看仓库 https://github.com/LoserFox/distill 确认安全性,然后执行安装命令并验证插件加载成功。
把这段指令粘贴给 DSH Web GUI 里的助手,由它代你完成安装与验证。
一句话定位
distill 是 DSH 的"学习回路"插件:在每轮对话结束后静默分析新增的人类用户消息,把反复出现的纠错、风格偏好或工作流沉淀为可命名的技能条目,写入本地 .agents/skills 目录供后续会话直接加载——用户不需要主动教,下一次会话就能"记得"。
核心能力
- 监听回合结束事件,按人类消息数阈值异步触发后台反思
- 派生子代理对最近新增的人类消息做结构化复盘,输出 skip / create / update 三类决策
- 把复盘结果写入带 frontmatter 的本地
SKILL.md技能文件,宿主技能文件系统可直接发现 - 支持全量替换此前蒸馏的技能(仅限带
distilled-by: dsh-distill标记的文件),但永不改动用户手写、内置或运行时注册的技能 - 派发前发出仅运行期的
distill/review-requestCordis 通知,方便外部观察者做审计而不会污染会话日志 - 可独立配置反思使用的 provider/model 与子代理提供方,避免抢用主对话资源
技术实现
- 语言: TypeScript(ESM 模块,
"type": "module") - 关键依赖:
@deepseek-ai/cordis:插件宿主与事件总线@deepseek-ai/dsh-agent/@deepseek-ai/dsh-subagent:复盘子代理派发@deepseek-ai/dsh-skill:isSkillName校验技能名 kebab-case
- 架构模式: Cordis 插件(
inject: ['subagents']),通过cordis.patch.yml将自身行挂入 profile 组合层;监听agent/turn-stopping事件触发后台 fork 子代理,使用结构化输出契约(assertObjectJsonSchema)捕获复盘结果;通过本地文件系统(node:fs/promises)落盘技能文件 - 入口文件:
src/index.ts(编译产物为lib/index.js,通过package.json#main暴露)
适用场景
用户与 DSH 长期协作时,常常需要反复纠正模型的输出风格、格式或工作流顺序,每次都得从头说一遍很烦。distill 会在用户不知不觉中把这些"教训"沉淀成可命名的技能,下次开会话时主 agent 就能直接命中——特别适合希望 agent 越用越顺手、能记住自己偏好的重度用户。如果你的工作流很标准化、每天都在重复同类任务,这个插件也能把整套流程打包成一个可调用的技能条目。
前置依赖与兼容性
| 依赖 | 最低版本 | 说明 |
|---|---|---|
| @deepseek-ai/dsh-agent | ^0.1.0-rc.6 | 宿主必需,提供 Agent/Session 等类型 |
| @deepseek-ai/dsh-subagent | ^0.0.1-rc.1 | 复盘子代理派发能力 |
| @deepseek-ai/dsh-skill | ^0.0.1-rc.1 | 技能名校验(kebab-case) |
| @deepseek-ai/dsh-tools | ^0.0.1-rc.1 | 结构化输出契约校验 |
| 宿主插件 subagent-spawn-in-process | base bundle 默认 | 提供名为 spawn 的子代理提供方 |
| 宿主插件 tool-skill | base bundle 默认 | 复盘子代理用以查看技能内容 |
| Node.js | 未声明 | package.json 未声明 engines 字段 |
| 平台 | 跨平台 | 源码仅使用 node:fs / node:os / node:path 内置模块,无 os/cpu 限制 |
安装方式
dsh plugin --profile web add github:LoserFox/distill
配置项
| 配置 | 类型 | 说明 | 默认值 |
|---|---|---|---|
| enabled | 布尔 | 总开关,关闭后插件完全不再触发监听 | true |
| minUserMessages | 整数 | 触发一次复盘所需新增人类用户消息数 | 3 |
| provider | 字符串 | 复盘子代理使用的 provider(必须与 model 同时配置) | 未设置 |
| model | 字符串 | 复盘子代理使用的模型(必须与 provider 同时配置) | 未设置 |
| maxTokens | 整数 | 复盘子代理单次输出 token 上限 | 2048 |
| timeoutMs | 整数 | 单次复盘端到端超时(毫秒) | 30000 |
| targetRoot | project / user | 技能写入位置:项目级写入 git 根目录 .agents/skills;用户级写入 ~/.agents/skills | project |
| agentsHome | 字符串 | 用户级目标时覆盖根目录,优先于 DSH_AGENTS_HOME 环境变量 | 未设置 |
| providerName | 字符串 | 复盘子代理使用的子代理提供方注册名 | spawn |
| allowUpdate | 布尔 | 是否允许全量替换此前蒸馏的技能;关闭后只允许 create | true |
常见问题
Q: 装上之后主对话会变慢或被打扰吗?
A: 不会。distill 完全在后台运行,只在回合结束事件触发后才异步派发复盘子代理,主对话不会被注入任何新工具或提示词。
Q: 复盘生成的技能会覆盖我手写的技能吗?
A: 不会。复盘只能新建技能,或全量替换带 distilled-by: dsh-distill frontmatter 标记的技能(即它自己之前生成的)。你手写、内置或运行时注册的技能永远不会被改写。
Q: 复盘生成的文件存放在哪里?
A: 默认写入当前项目 git 根目录下的 .agents/skills/<技能名>/SKILL.md;若配置 targetRoot: "user",则写入 ~/.agents/skills/ 下,可通过 agentsHome 配置项或 DSH_AGENTS_HOME 环境变量覆盖根目录。
Q: 为什么装了但从来没看到复盘发生?
A: 两个最常见原因:新增的人类用户消息没攒够 minUserMessages 条(默认 3 条);或者既没配置显式 provider/model,主 agent 自身也没指定 provider/model,此时本轮会被跳过并打印 warning 日志。
Q: 复盘子代理需要哪些宿主插件才能工作?
A: 需要宿主的 base bundle 默认挂载 subagent-spawn-in-process(提供名为 spawn 的子代理提供方)和 tool-skill(复盘子代理用 skill 工具查看现有技能内容)。缺 tool-skill 时复盘仍会运行,但子代理看不到技能目录。
Q: 怎么彻底关掉这个插件?
A: 在 profile 配置里把 distill.enabled 设为 false 即可静默关闭,也可以 dsh plugin --profile web remove distill 卸载。注意安装/卸载后必须重启目标 profile 的 DSH 进程——组合层变更不参与 HMR 热更新。
Q: 它会占用多少额外 token?
A: 每次复盘最多消耗 maxTokens 个输出 token(默认 2048),且只在消息累积到阈值后才触发;超时会被截止为 timeoutMs(默认 30 秒),日常对话几乎感觉不到开销。
上手难度
入门 — 安装即生效,主对话无需任何额外配置;只需要知道它会在后台默默生成技能,并在某天你想复盘"我之前学到了什么"时去翻 .agents/skills 目录。
已知问题与限制
- update 动作会重写整个 SKILL.md 文件,不支持局部补丁;提示词建议把支持文件意图并入正文或直接跳过
- 仅 0.1.0+ 版本蒸馏出的技能带
distilled-by标记,更早蒸馏的技能会被视为用户所有、永不被更新,除非用户手动重新创建或打上标记 - 检查点只保存在内存中(
WeakMap<Session, number>),进程重启或会话恢复后从Session.firstLiveSeq重新计数,上一个进程未达阈值的消息不会跨进程结转 - 旧版本曾往会话日志写入
session/distill-review-request事件;这类历史日志需要为事件信封补ignorable: true或用宿主修复工具处理后才能重新加载 - 当项目级目标找不到
.git祖先时会回退到会话 cwd,可能写入意料之外的位置 - 同一会话同时只允许一次复盘进行中,期间到达的回合会被跳过,等本次结算后下次复盘再统一评估
安装(DSH profile bundle)
# 从本仓库 checkout 安装到 profile(web / headless 等),bundle 声明自动加入组合层
dsh plugin --profile web add <目录|git-url>
# 验证
dsh --profile web --dump-config | grep distill
- 插入行 id:
distill(cordis.patch.yml);不注册任何面向模型的工具或技能——它只挂接agent/turn-stopping并运行后台反省。 - 宿主前提:dsh 组合必须挂载
subagent-spawn-in-process(注册反省子代理使用的spawn子代理提供方)与tool-skill(子代理可调用的skill查看器)——两者在 base bundle 中默认存在。 - 卸载:
dsh plugin --profile web remove distill。 - 安装后需重启目标 profile 的 DSH 进程(组合层变更不参与 HMR 热更新)。
概述
自动对话反思与技能蒸馏。
需要 ctx.subagents(inject: ['subagents'])以及已注册的子代理提供方——subagent-spawn-in-process 插件注册了默认的 spawn 提供方——并且部署中包含面向模型的 skill 工具(tool-skill),反省子代理才能查看技能。反省提示词改编自 Nous Research 的 hermes-agent _SKILL_REVIEW_PROMPT(MIT 许可,Copyright (c) 2025 Nous Research),针对本界面做了改写;完整署名见源文件头。
行为
每个回合完成(agent/turn-stopping 触发)时,插件会收集自上次蒸馏检查点以来新增的人类 user/message 事件;数量达到 minUserMessages 后,派发一个后台反省子代理(Hermes Agent 后台反省的形态:受限工具集的全新子代理,在回合之后运行,从不与用户任务争抢)。子代理的提示词携带 Hermes 策展课程、消息窗口帧和可更新技能列表;其工具集白名单只保留 skill 查看器,最终答案通过结构化输出契约捕获。派发前会发出非持久化的 Cordis distill/review-request 通知,携带精确的路由、提示词、工具白名单和 token 上限;该通知不会写入会话日志。
反省子代理提议以下之一:
{"action": "skip"}— 无值得保存的内容;本轮结束。{"action": "create", "skill": {"name", "description", "whenToUse?", "content"}}— 一个新技能,写成带 frontmatter 的SKILL.md包,本地技能提供方会像发现手写技能一样发现它。{"action": "update", "skill": {...}}— 对某个先前蒸馏出的技能的完整替换。
每个提议都会经过校验(通过 isSkillName 校验 kebab-case 名称,描述和内容非空)。目标文件已存在时 create 被跳过。只有目标文件存在且带有插件 distilled-by: dsh-distill frontmatter 所有权标记时 update 才会被应用;缺失或非蒸馏所有的目标会跳过并记录警告,因此用户手写、内置和运行时注册的技能永远不会被重写。蒸馏出的文件都带该标记,且只有带标记的技能会出现在子代理的可更新列表中。无论结果如何,检查点都会推进到最后一条已反思消息,因此每轮只覆盖新消息。
反思目标优先使用显式配置的 provider/model 对(两者需同时配置),否则使用已结束 agent 自身的 agent.options 路由。两者都不存在时本轮跳过并记录警告。子代理运行在 providerName 指定的子代理提供方上;提供方缺失、或运行失败、被取消、无捕获结果时只记录警告,绝不会使循环崩溃。
配置
| 字段 | 默认值 | 含义 |
|---|---|---|
enabled | true | 总开关。 |
minUserMessages | 3 | 触发一次反省所需的新增人类用户消息数。 |
provider / model | 未设置 | 显式辅助路由;必须同时提供。默认使用 agent 自身路由。 |
maxTokens | 2048 | 反省子代理输出 token 上限。 |
timeoutMs | 30000 | 反省的端到端截止时间。 |
targetRoot | project | project 写入 <git-root>/.agents/skills;user 写入 ~/.agents/skills。 |
providerName | spawn | 反省子代理使用的子代理提供方注册名。 |
allowUpdate | true | 是否允许反省更新先前蒸馏出的技能;false 时只提供 create。 |
模型体验
主对话不注册任何工具或提示,插件从不改变其表面。唯一的模型可见效果是间接的:后台运行一个带 skill 工具的反省子代理(它看到与主 agent 相同的目录,可在提议前查看任意技能内容),写入或更新的技能会在后续轮次出现在 dsh-tool-skill 目录中。反省派发通过仅运行期的 distill/review-request 通知暴露给观察者,不写入会话日志,也不进入对话循环;需要跨进程审计的部署应由监听方自行持久化该通知。
已知限制与后续工作
- 仅整文件更新 — update 会重写整个
SKILL.md;不支持局部补丁或支持文件(references//templates//scripts/)写入。提示词把支持文件意图并入正文或跳过。 - 所有权标记按来源选择 — 本变更之前蒸馏出的技能没有
distilled-by标记,会被当作用户所有(永不更新),除非用户重新创建或手动标记。 - 检查点仅限当前进程 — 检查点保存在内存中;恢复或 fork 的会话从
Session.firstLiveSeq开始,只处理本进程新增的消息。上一个进程中尚未达到阈值的消息不会结转。 - 既有受损日志需单独修复 — 本版本不再写入
session/distill-review-request,但已经含有该未知事件的日志仍需为事件信封补上ignorable: true或使用宿主提供的修复工具后才能重新加载。 - 项目目标需要 git 根 — 没有
.git祖先时,项目目标回退到会话 cwd。 - 每个会话一次进行中的反省 — 反省进行期间到达的已结束回合会被跳过;下一次结算会重新评估。
- 反省子代理依赖部署的工具 — 子代理的
skill工具和目录来自同一部署中的tool-skill;没有它的部署仍会运行反省,但子代理在提议前无法查看技能。
查看使用指南 →
该插件的安装步骤、关键要点、FAQ 与兼容性说明(基于已收录字段派生)。
收录徽章
[](https://deepseek-plugin.org/plugins/LoserFox/distill)把这段 markdown 粘贴到你的 GitHub README,链接回本插件详情页。徽章只声明已被本站收录,不代表安全认证。