dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
English | 中文
给 DeepSeek Harness(DSH)加一个教育模式:进入这个模式后,DSH 会把「讲清楚一门课」当成任务本身——先真的去查资料,再讲明白,把课堂笔记写下来,最后出题检查你到底会不会。
它不是一个提示词模板,而是一个真正的插件:一个可切换的会话模式、一段注入到每次模型请求里的教学协议、三个模型必须遵守的工具,以及落盘的课程文件。
| 阶段 | 行为 | 由什么保证 |
|---|---|---|
| 1. 调研 | 用 web_search / web_fetch 找权威来源(教材、大学课程页、标准、论文),记录标题和链接;需要多来源时并行开子代理 | 教学协议 + 现有 web 工具 |
| 2. 讲解 | 先讲为什么有用 → 直觉/类比 → 精确定义(先定义符号)→ 推导 → 完整例题 → 常见误区 → 与前后知识的联系 | 教学协议 |
| 3. 笔记 | 每讲一次课就调用 edu_notes,把讲解、要点、易错点、来源写成 markdown 存到课程目录 | edu_notes 工具 |
| 4. 出题 | 每讲结束调用 edu_quiz,在 GUI 自带的问答界面里让你做题并自动判分;答错的点会被重新讲一遍再重考 | edu_quiz 工具 |
| 5. 进度 | 模块自测通过后调用 edu_course 打勾,跨会话保留课程进度 | edu_course 工具 |
三个工具:
edu_course — open 建立/改写课程大纲(目标、水平、模块清单、参考来源)并把课程设为当前课程;status 报告进度和下一个模块;complete 给某个模块打勾。edu_notes — 为某一讲写课堂笔记(正文 + 要点 + 常见误区 + 来源),写入课程笔记文件。同一讲重复写会被拒绝,除非显式 replace: true。edu_quiz — 出题、通过对话内问答组件收答案、判分、把结果写进测验记录。选择题自动判分(单选/多选),开放题标记为「需要模型自己判」。没有可交互问答通道时(headless、ACP、子代理)不会报错,而是把题目交回给模型在对话里问。默认写在会话工作区的 edu-notes/<课程名>/:
edu-notes/线性代数/
├── syllabus.md # 课程目标、水平、模块清单(- [ ] / - [x])、参考来源
├── notes.md # 课堂笔记,一讲一节
└── quizzes.md # 测验记录,一次一节,含得分与错题
课程名会做安全化处理(保留中文,去掉路径分隔符),所以 /edu 线性代数 会得到 edu-notes/线性代数/。
插件是一个标准的 DSH 组合包(dsh.bundle + cordis.patch.yml)。lib/ 是构建产物并已随仓库提交,因此不需要授权任何构建脚本。
# 1) 从 npm 安装(有 release 之后可用)
dsh plugin --profile web add dsh-edu-mode
# 2) 从 GitHub Release 下载的 tarball
dsh plugin --profile web add ./dsh-edu-mode-0.1.0.tgz
# 3) 直接装 git 仓库
dsh plugin --profile web add github:1Vewton/dsh-edu
注意安装方式。 请用 npm / tarball / git 安装(安装到 profile 的
node_modules里的是一份真实目录)。不要用dsh plugin add <目录路径>:那是 pnpm 的link:,Node 会把它解析到源目录的真实路径,于是插件的@deepseek-ai/*导入会命中源码仓库自己的node_modules,从而加载第二份 cordis / dsh-tools 实例,DSH 就无法把它识别成插件了。DSH 源码检出内开发(pnpm dsh+--patch)不受影响。
用源码检出运行时,把上面的 dsh 换成 pnpm dsh。验证层已生效(不启动服务):
dsh --profile web --dump-config # 应能看到 "# == dsh-edu-mode" 这一段
装完需要重启该 profile 的服务(例如 pnpm dsh web)才会加载。卸载:dsh plugin --profile web remove dsh-edu-mode。
cordis.patch.yml 里的 config(插件加载时会严格校验,写错会直接报错而不是静默取默认值):
- insert:
- id: edu-mode
name: 'dsh-edu-mode'
config:
notesDir: edu-notes # 课程文件根目录(工作区相对路径)
maxQuizQuestions: 6 # 一次 edu_quiz 最多几道题
passRatio: 0.8 # 自测通过线(自动判分部分的比例)
# policy: | # 需要的话,用整段自定义教学协议覆盖内置的
会话里用 /edu 命令开关模式:
| 命令 | 效果 |
|---|---|
/edu 线性代数 | 打开教育模式并把这门课设为当前课程,同时把你这句话作为请求发给模型 |
/edu | 打开教育模式(课程待定,模型会先问你想学什么) |
/edu status | 查看当前状态和课程 |
/edu off | 退出教育模式 |
典型开场:
/edu 线性代数,我从行列式开始,基础一般
之后模型会按教学协议走:先检索 MIT 18.06 / 教材等来源 → 讲清一个模块 → 写笔记 → 出题 → 根据错题回炉。你也可以随时插话:「这块再讲一遍」「出难一点的题」「跳过这节」。
状态存在会话日志里(edu/mode 事件,最后一个生效),所以会话恢复、分叉都会自动带上模式和当前课程;课程进度则落在工作区的课程文件里,跨会话可用。
发布由 GitHub Actions 完成(.github/workflows/release.yml):推一个版本 tag 就会构建、测试、发 npm,并创建带 tarball 附件的 GitHub Release。
# 1) 改版本号并提交
npm version patch --no-git-tag-version # 或手改 package.json
pnpm build && pnpm test # 确保 lib/ 与 src/ 一致
git commit -am "chore: release v0.1.1"
git push
# 2) 打 tag 触发发布
git tag v0.1.1 && git push origin v0.1.1
一次性配置:在 npm 生成一个 Automation token(npmjs.com → Access Tokens),加到仓库 Settings → Secrets and variables → Actions,名字用 NPM_TOKEN。没有这个 secret 时 workflow 会在发布步骤明确报错,不会静默跳过。
workflow 会拦住这些情况:tag 与 package.json 版本不一致、提交的 lib/ 与 src/ 不一致(防止发出去的构建产物是旧的)、单元测试失败。已经发布过的版本不算失败:对同一个 tag 重新运行会只提示一句「已在 npm 上」并跳过发布,继续把 GitHub Release 补齐——发布挂在一半时正需要这个语义。Release 步骤本身也是幂等的:tag 上已经存在 Release(包括你手动开的 draft)时改为上传/覆盖附件,而不是报 already exists。
也可在 Actions 页面手动 dispatch:默认 dry_run = true,只跑构建/测试/打包,不发版。
之后可选升级到 npm 的可信发布(OIDC):包在 npm 上存在后,在包的 Settings → Trusted publishing 里填
1Vewton/dsh-edu/release.yml,之后就能删掉NPM_TOKEN(workflow 已经带了id-token: write)。首次发布仍需要 token,因为可信发布只能在包已存在时配置。
dsh-market(DSH 里的插件市场)只允许安装 curated 索引里列出的来源,索引数据由 awesome-dsh-plugin/awesome-dsh-plugin 的 data/plugins/*.yml 生成(站点 https://awesome-dsh-plugin.com)。所以"上架"就是**一个只加一个文件的 PR**,而不是往某个服务投递。
本仓库的条目副本在 contrib/awesome-dsh-plugin/1Vewton__dsh-edu.yml;tests/marketplace.test.js 会按索引写明的要求校验它(仓库地址、分类、描述格式,以及描述里的声明是否与代码一致)。提交时把它原样粘成 registry 仓库里的 data/plugins/1Vewton__dsh-edu.yml 再开 PR;那边的两个 README 由脚本生成,不要手改。
收录的硬性要求,对着本仓库的现状:
| 要求 | 状态 |
|---|---|
package.json 声明 dsh.bundle(决定能否用 dsh plugin add 装) | ✅ |
| 有真实可用的代码,不是占位或纯 README 仓库 | ✅ |
| 仓库创建满 1 天(CI 自动检查) | ⏳ 建于 2026-09-12 03:56 UTC,2026-09-13 04:00 UTC 之后才达标 |
仓库加 dsh-plugin topic | ⬜ 需在仓库 About 里手动加 |
| 描述属实(评审会对着代码逐条核) | ✅ 条目只声明仓库里确实存在的三个工具 |
| 分类贴合插件实际做的事 | agi(agent 行为/模式类;不贴切的话维护者会直接改,不会打回) |
推荐但非必需:发布到 npm(市场据此展示下载量、安装更快),或在 GitHub Release 上挂预构建 tarball 供条目的 tarball: 字段引用。两者都已就绪——发布工作流会同时挂上 dsh-edu-mode-0.1.0.tgz 与不带版本号的 dsh-edu-mode.tgz(releases/latest/download/<文件名> 按字面取文件名,带版本号会在下一次发版后 404)。
pnpm install
pnpm check # = pnpm build + pnpm test(改完 src 用这个,别只跑 test)
pnpm test # 108 个测试,约 0.3 秒(测的是 lib/,也就是安装后真正被加载的产物)
测试跑的是 lib/ 而不是 src/,这正是关键:安装到 profile 里被加载的就是 lib/,所以测试要么先 pnpm build(用 pnpm check),要么测的就是旧产物。
测试文件与它们锁定的行为:
| 文件 | 覆盖 |
|---|---|
tests/paths.test.js | 课程名安全化、课程文件布局、markdown 渲染、模块勾选/解析 |
tests/quiz.test.js | 判分规则:单选/多选/开放题/未作答、得分与通过线、报告渲染 |
tests/store.test.js | 课程文件读写:相对路径约束、工作区解析、沙箱策略、fs/observed、追加语义 |
tests/tools.test.js | 三个工具的真实行为:大纲、进度、笔记、测验记录,以及所有降级路径 |
tests/plugin.test.js | 真实 cordis Context 上的装配:服务、提示段、/edu 命令、模式状态机、会话日志契约 |
tests/bundle.test.js | 组合包契约:patch 行、files、入口、以及「所有运行时裸导入必须是 peer」 |
tests/mode.test.js | 配置校验与 edu/mode 折叠 |
CI(.github/workflows/ci.yml)在 ubuntu 与 windows 上、Node 22 与 24 上跑同一套:pnpm install --frozen-lockfile → pnpm build 并校验提交的 lib/ 与 src/ 一致 → pnpm test。Windows 那一档不是摆设:插件要解析工作区相对路径并写课程文件,两个平台都跑一遍才放心。.gitattributes 把文本统一成 LF,好让 lib/ 的对比在哪个平台都成立。
源码结构:
src/index.ts 插件入口:EduMode 服务、edu:policy 提示段、/edu 命令、状态机
src/policy.ts 默认教学协议文本(可被 config.policy 覆盖)
src/course.ts edu_course / edu_notes 工具
src/quiz.ts 判分逻辑(纯函数)+ edu_quiz 工具
src/store.ts 课程文件读写(走 ctx.fs,受沙箱约束)
src/paths.ts 纯函数:课程名安全化、文件布局、markdown 渲染
tests/ 测试与 tests/helpers.mjs(临时工作区、假 fs/会话/工具注册表)
改完代码后,profile 里装的是一份拷贝,必须重新 remove + add 才会更新。
ctx.fs,并按会话解析 sandbox 策略,因此写入受部署的沙箱模式约束(workspace-write 下写不到工作区外)。本插件对自己的文件只做追加/精确替换,所以不申请读写前置意图,而是补发 fs/observed,让模型自己的 write/edit 看到最新版本。/edu 命令回执和会话记录可见(后续可以再加输入栏 chip,需要客户端插件)。/edu off 不影响其它会话。MIT