DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

buguoshixc /

buguoshixc/dsh-doctor

Verified

AI Code Doctor for DeepSeek Harness: zero-dependency judge core (doctor_judge/doctor_gate) + 「诊断模式」 agent preset + Socratic skill. MIT.

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHub
READMESource: main@c126ec69

dsh-doctor — AI Code Doctor for DeepSeek Harness

给 DeepSeek Harness 桌面端加一个诊断模式: 学生贴代码求助时,模型不再直接给答案,而是先跑代码拿到证据、再用苏格拉底式提问带他自己修。 答案由工具挡,不由自律挡。

学生代码 + 用例(带 expected) + 正解
      │
      ├─ doctor_judge ──► verdict / failure_distribution / counterexample
      │                        │
      │                   模型组织回复(一次只给一层提示)
      │                        │
      └──────────────── doctor_gate ──► pass / block / downgrade-to-level2
                               │
                            发给学生

它解决的问题

编程题助教最容易做错的两件事:

  1. 凭印象下结论——"你这里下标写错了",其实没跑过,纯属猜测;
  2. 忍不住给答案——尤其是学生说"就给我看一眼完整代码"的时候。

本插件把这两件事变成机械约束:

  • 归因必须来自 doctor_judge 的执行证据(哪个用例、输入什么、期望什么、实际什么);
  • 面向学生的任何回复必须先过 doctor_gate:能跑出结果就是完整答案,直接拦; 与正解高度相似(≥0.75)就降级成思路提示;
  • 这套流程写进技能手册,模型每次会话都会读到。

它是什么 / 不是什么

是 不是
DSH 插件(bundle + agent preset) LLM 应用;不调用任何模型 API
离线判定核(Python 3.11+ 标准库,零第三方依赖) 判题云服务;不接 judge0、不联网
两个原生工具 + 一份教学技能 + 一个预设 一个 Web 平台;没有前端、没有数据库、没有 HTTP 服务
一个"答案门控" 安全沙箱;本地执行只有超时/内存上限/尽力禁网

架构 C:会话里的模型负责出用例和正解,工具只负责裁决。所以判定核不生成任何东西, 也不需要 API key——它只做三件确定性的事:跑代码、比输出、挡答案。

快速开始

dsh plugin --profile desktop add github:buguoshixc/dsh-doctor

装完重启 DSH,新建会话时在预设选择器里选「诊断模式」。细节见 docs/INSTALL.md。

想让 agent 帮你装?把 docs/INSTALL-PROMPT.md 里那段 prompt 直接粘给它。

两个工具

doctor_judge — 唯一裁决器

什么时候必须调:只要学生给了代码 + 题目,就先调它。不跑就下结论 = 编造证据。

参数 说明
problem 题面全文(Markdown,含示例)
code 学生代码全文
cases 用例集 JSON({"func_name":"…","cases":[{"case_id","input","expected","kind"}]})
refs 1~4 份正解代码(会交叉校验)
func_name / timeout_ms / memory_mb 可选

它先跑正解做自校验:任何一份正解与 expected 不符,立刻返回 verdict=REF_REJECTED, 不执行学生代码、不进入归因——这样"模型自己写错正解"不会变成"学生被冤枉"。

真实输出(lc-053-maximum-subarray 的边界错误样本,节选):

{
  "verdict": "WA",
  "phenotype": "WA",
  "compile": { "passed": true, "errors": "" },
  "ref_status": "trusted",
  "failure_distribution": { "total": 5, "failed": 1, "pattern": "boundary_only" },
  "counterexample": {
    "case_id": "b1",
    "input": [[-3, -2, -5]],
    "expected": -2,
    "actual": 0,
    "kind": "boundary"
  },
  "category": 3,
  "category_label": "边界处理错",
  "confidence": "high",
  "reason": "1/5 条用例失败,失败模式 boundary_only,归类为第 3 类(边界处理错)"
}

counterexample 是模型唯一可以写进回复的事实。字段全表见 docs/SCHEMA.md。

doctor_gate — 回答门控

什么时候必须调:任何面向学生的回复,发出之前。

三层判定:

  1. layer1 能跑即拦——抽出回复里的代码片段,真的执行。能跑出结果 ⇒ 它就是完整答案 ⇒ block。 (只看语法不够:while 左指针 < 右指针: 在 Python 里语法合法,但它跑不起来,是合格伪代码。)
  2. layer2 相似度防漏——与正解的 AST 结构相似度(0.55 权重)+ token Jaccard(0.45 权重): ≥0.75 ⇒ downgrade-to-level2(实质等同给答案),≥0.60 ⇒ suspect=true(放行但标记)。
  3. fail-closed——内容像代码却分析不了,一律拦或降级,绝不当成"安全"。

真实输出(回复里贴了正解原文):

{
  "action": "block",
  "reason": "layer1 判定为可运行代码(定义了 twoSum)",
  "layer1": { "runnable": true, "detail": "定义了 twoSum" },
  "layer2": { "similarity": 1.0, "ast_sim": 1.0, "token_sim": 1.0, "suspect": true },
  "leaked_fragments": ["def twoSum(nums, target):\n    # 正解 B:哈希表一次遍历,O(n)\n    …"],
  "recommended_level": 1,
  "reasons": ["extract:found_fragment", "layer1:runnable"]
}

「诊断模式」预设

项 内容
预设 id / 名称 diagnose / 诊断模式
persona 中文助教人格;铁律:过 gate、不给完整代码、只用工具证据、REF_REJECTED 时先修不归因
声明的工具面 bash(POSIX)/ pwsh(Windows)、read/write/edit、glob/grep、skill
插件自带工具 doctor_judge、doctor_gate
技能 doctor(只在预设里可见:includeDefaultRoots: false + 随包目录)
继承的 host 工具 present、ask_user_question 等(profile 决定)

预设不用 {{cwd}} 这类提示变量(DSH 0.2.1 起在 preset persona 里会整轮失败),只用 {{model}}。

目录结构

plugin/
├── cordis.patch.yml          # bundle patch:插入一行 Host 插件
├── package.json              # bundle 清单 + engines.dsh + files 白名单
├── lib/                      # Node 侧(纯 ESM,零依赖)
│   ├── plugin.mjs            #   name/inject/apply:注册工具、预设、技能
│   ├── tools.mjs             #   两个工具的 JSON Schema 与执行体
│   ├── python.mjs            #   Python 探测、临时工作区、超时/中止/错误映射
│   ├── preset.mjs            #   「诊断模式」声明
│   └── skill.mjs             #   SKILL.md 解析与兜底
├── doctor_core/              # Python 判定核(stdlib only)
│   ├── __main__.py           #   CLI:judge / gate
│   ├── executor.py           #   子进程执行:5s 超时、256MB rlimit、RSS 采样
│   ├── wrapper.py            #   运行器与 layer1 探针源码
│   ├── cases.py compare.py phenotype.py gate.py jsonio.py
├── presets/
│   ├── skills/doctor/SKILL.md    # 教学手册(真正的"度"在这里)
│   └── diagnose/                 # 旧格式的等价组合描述(0.2.1 不读,留作对照)
├── tests/                    # Python unittest + 三题 fixture
├── test/                     # Node node:test(含真实 dsh-tools 契约测试)
├── scripts/verify.sh         # 一条命令跑完全部
└── docs/                     # SCHEMA / PLUGIN_API / EXTRACTION / INSTALL / ACCEPTANCE

跑测试

bash scripts/verify.sh

它会跑:环境自检 → 零第三方依赖扫描 → 93 个 Python 单测 → 22 个 Node 单测(含用本机真实 @deepseek-ai/dsh-tools 校验 schema 的契约测试)→ 三题 fixture 演示(AC/WA/CE/TLE/REF_REJECTED

  • 门控三种动作)→ 包元数据契约 → stdout 纯净性。全绿退出码 0。

诚实的边界

  • 正解由模型生成,这是架构 C 的固有代价。 我们只能做到"正解与题面示例不符就终止", 做不到"保证正解正确"。所以 doctor_gate 是最后一道防线,不是唯一一道。
  • 本地执行不是安全沙箱。 只有 5 秒墙钟超时、256MB RLIMIT_AS(Windows 上 resource 模块不存在,内存上限不生效,会带 memory_limit_not_enforced 标记)、以及尽力而为的网络屏蔽 (替换 socket.socket)。真正的隔离要靠 OS 级沙箱,本插件不提供也不声称提供。
  • 只支持 Python。 C++/Java 的 wrapper 与原平台的 tree-sitter 相似度都没搬过来。
  • "必须先过 gate"是提示工程,不是机制。 工具能拦住被送进来的回复,拦不住模型干脆不调用它。 降低风险的办法是技能里写死步骤 + persona 里的第 1 条铁律。

许可

MIT。见 LICENSE。

—/ 5

No ratings yet

Verified DSH bundle

Commit c126ec69ae79

Community comments

No comments yet. Be the first to write one.

DSH HUB

A community index for DSH plugins. Not an official GitHub or DeepSeek AI product.

CommunityResourcesAPIAbout