DSH HUB
HomePlugin StorePlugin PacksCommunityRankingsResourcesPublish Guide
Plugin source
Back to catalog

W-SING-HUNG /

W-SING-HUNG/dsh-resume

Verified

求职简历工坊:粘贴 JD,AI 按岗位重写简历,只基于真实内容,不编造 — DeepSeek Harness 插件

★ 0 Stars0 Forks0 IssuesN/A Community rating0 Confirmed installs
View on GitHubProject homepage
READMESource: main@96cbb30c

dsh-resume · Resume Studio

粘贴 JD,AI 按岗位重写你的简历 —— 只基于真实经历,绝不编造。

CI Release License: MIT Node

一个 DeepSeek Harness (DSH) 插件。 在会话里粘贴岗位描述与简历原文,模型会调用 rewrite_resume 工具,按岗位定制简历。


目录

  • 为什么需要它
  • 快速开始
  • 核心特性
  • 反虚构铁律
  • 工作原理
  • 开发与验证
  • 架构与硬约束
  • 常见问题
  • 贡献
  • License

为什么需要它

投递时每个岗位都要微调简历:对齐 JD 关键词、调整经历顺序、强化表述。 人工做这件事,一个岗位要花 20-30 分钟;不改,又会在 ATS(简历筛选系统)里沉底。

现有网页版简历工具的问题:

  • 简历要上传到第三方服务器
  • 切换平台,割裂工作流
  • 无法保证"不编造"——很多工具会主动替用户加经历

本插件把这件事放进你已有的 AI 工作流,且从机制上不可能编造。

快速开始

安装

# 1. 放入 DSH 插件目录($DSH_HOME 默认 ~/.dsh)
#    把 dsh-resume 放到 $DSH_HOME/plugins/dsh-resume

# 2. 装进目标 profile(pnpm 语义)
dsh plugin --profile web add "file:///$DSH_HOME/plugins/dsh-resume"

# 3. 在 profile 的 package.json 中把插件加入 bundles
#    $DSH_HOME/profiles/web/package.json → dsh.profile.bundles 追加 "dsh-resume"

# 4. 重启
dsh web

仅装依赖不够——必须出现在 dsh.profile.bundles 里,加载器才会应用它的 patch。

使用

插件装载后自动注册 rewrite_resume 工具,并向系统提示词注入求职意图感知。 直接在会话里说:

帮我根据这个岗位要求优化一下简历。

【JD】 …岗位描述原文…

【我的简历】 …简历原文…

模型会自动调用工具,交付四部分:优化后简历 / 改动说明 / 待补充清单 / 校验结果, 并可按需导出为可直接投递的 .docx 文件——不用自己复制排版。

它实际拦住了什么

不需要安装任何东西——下面全部输出由 npm run demo:guard 真实运行产生。

假设你的简历里原本写着:

## 项目经历
校园二手交易平台(前端负责人)
- 使用 Vue2 编写主要展示页面和商品列表模块
- 对接后端 REST 接口,完成登录与购物车功能
- 通过懒加载商品图片与合并请求,将首屏加载时间从 2.4s 缩短至 1.8s

情况一:模型顺手加了个数据

- 对接后端 REST 接口,完成登录与购物车功能
+ 对接后端 REST 接口,完成登录与购物车功能,接口响应时间优化 60%
verify_rewrite → ok = false
  FABRICATED_NUMBER  evidence: ["60"]

那个 60% 是你没写过的。面试官问"怎么测的",你答不上来。

情况二:模型把"负责"升格成"主导"

- 负责使用 Vue2 编写主要展示页面
+ 主导使用 Vue2 编写主要展示页面
verify_rewrite → ok = false
  RESPONSIBILITY_INFLATED

这类改动最容易被放过——它没编任何数据,只是把语气抬高了。 但面试官会问"你是怎么主导的",而你只是参与实现。

情况三:模型凭空多写了一条经历

  - 通过懒加载商品图片与合并请求,将首屏加载时间从 2.4s 缩短至 1.8s
+ - 负责用户增长策略,主导社群运营体系搭建,实现月活翻倍
verify_rewrite → ok = false
  NOVEL_CONTENT

这条与原文任何一条都对不上。特征式检查抓不住它(没有新数字、没有新机构), 所以这里用的是逐条内容比对。

情况四:合法改写——只强化措辞、事实分毫未动

- 使用 Vue2 编写主要展示页面和商品列表模块
+ 负责使用 Vue2 完成主要展示页面与商品列表模块的开发
verify_rewrite → ok = true   (findings 数量:0)

这就是这个项目想做到的事:让模型可以放心地帮你把简历写得更好, 但每一处改动都必须在事实边界内——而且这件事由代码判定,不靠模型自觉。

先看看它长什么样

无需安装 DSH 即可运行示例:

npm install
npm run example      # 完整流程演示
npm run demo:guard   # 只看守卫拦住编造的过程

核心特性

特性 状态 说明
JD × 简历 → 定制简历 ✅ ATS 关键词对齐、经历权重重排
反虚构代码守卫 ✅ 确定性校验,不依赖模型自觉,见下节
一键导出可投递 .docx ✅ 零依赖生成,单栏 A4,ATS 可解析
改动说明 ✅ 每处改动对应 JD 哪条要求,5 条以内
待补充清单 ✅ JD 要求但简历缺失的能力,明示而非编造
会话内工具调用 ✅ agent 可自动识别意图并调用
中英双语 ✅ language: 'zh' | 'en'
独立双栏 UI 面板 计划中 client half

导出的文件长什么样

调用 export_resume 会直接产出文件,不用手动复制:

verify_rewrite → ok = true
export_resume  → 已导出 DOCX 文件(1454 字节)到 ./投递版简历.docx

生成的 .docx 是零依赖手写 OOXML(本项目运行时依赖为 0): 单栏版式、A4 页边距、项目符号段落,Word / WPS / Google Docs 均可直接打开。 版式刻意保持简洁——复杂排版会导致 ATS 解析失败,这在简历领域是已知问题。

两种导出模式:

模式 内容 用途
默认 只有简历本体 投递给 HR(不带改动说明等内部内容)
includeAppendix: true 附改动说明 / 待补充清单 / 校验结果 自己留档、复盘

安全边界:不覆盖已存在的文件、不自动创建目录、拒绝目录路径—— 避免误毁你已有的简历文件。三类边界都有测试覆盖。 | 多版本管理 | 计划中 | 每个 JD 一版 |

反虚构:从"提示词约束"到"代码校验"

只能重排与强化简历中真实存在的信息。禁止编造任何新经历、新数据、新技能。

这不是一句宣传语,而是本项目的存在理由。编造的经历会在面试第一轮就被问穿, 用户因此丢掉 offer,插件也因此被差评——编造等于项目自杀。

为什么提示词不够

把铁律写进提示词,只能表达意图,无法提供保证:模型一旦违反, 没有任何机制能发现,用户会拿着编造的内容去面试。 因此本项目把反虚构做成确定性代码校验——判定由代码执行,不依赖模型的态度。

守卫检查什么

改写完成后,verify_rewrite 工具会逐项比对你的简历原稿与改写结果:

检查项 级别 说明
出现原文没有的数字 必须修正 简历里风险最高的编造类型("提升 40%"、"服务 8 万用户")
出现原文没有的机构/专名 必须修正 换了公司名、加了没做过的项目
职责强度被升格 必须修正 把"参与"写成"主导"、"协助"写成"负责"——比编数字更隐蔽,面试追问时才暴露
时间点被改动 必须修正 起止日期属事实字段,改动会与背调不符
整条内容凭空新增 必须修正 与原文任何一条都对不上的表述(如凭空多出一段没做过的经历)
关键词覆盖虚报 必须修正 声称已对齐 JD 关键词,但该词并未真的写进简历
原文数字在改写后丢失 建议检查 真实量化结果被无意删掉

为什么专门检测"职责升格":简历造假最常见、也最隐蔽的形态不是编数字, 而是悄悄抬高职责——"参与"变"主导"、"协助"变"负责"。 数字编造容易被追问("这 40% 怎么算的"),职责升格往往能蒙混过关, 直到面试官问"你是怎么主导的"才露馅,对用户的伤害更大。 许多工具在文档里写了这条纪律,但只作为给模型的提示;本项目把它做成了代码检查。

强制闭环:模型改写后必须调用守卫自检;返回不通过时必须修正后重新校验, 直到通过才能交付。未通过校验就交付视为违反铁律。

已知边界(不夸大能力)

守卫明确声明它能做什么、不能做什么——使用者知道边界在哪,才不会被虚假的安全感误导:

  • 只检测带强后缀的机构名(某某公司/大学/银行…);无后缀的机构名(如"字节跳动")无法可靠识别,需人工确认
  • 数字按 token 比对,不做语义判断:把"提升 40%"改成"提升四成"不会被发现
  • 职责升格检测基于中文动词词表,措辞避开词表的同义升格可能漏检
  • 整条新增检测按字级相似度判定:"把原有经历改写得面目全非"可能被误报为新增,需人工确认
  • 本校验只做文本特征比对,不判断内容是否真实——它拦得住"与原文对不上"的编造,拦不住"原文本身就写了假的"

设计取舍:宁可漏报少数无后缀机构,也不制造大量误报。 一个频繁误报的守卫会被使用者直接忽略——那比没有守卫更糟。

三重保障

第一重:提示词层 src/prompt.js 内置三条硬规则,并强制要求改写后调用守卫校验。

第二重:代码层 src/guard.js 确定性比对(纯函数、零依赖、可离线测试), npm run check:guard 做行为级验证——若守卫被改成"永远通过",脚本立刻失败。

第三重:测试层 npm test 含守卫测试,其中反向验证用例专门确认"编造必须被抓住", 正向用例确认"合法改写不得误报"。CI 的 guard 任务独立再校验一次。

工作原理

用户会话
   │  「帮我按这个 JD 优化简历」
   ▼
DSH 会话模型 ──识别求职意图──▶ 调用 rewrite_resume 工具
   │                                    │
   │                          ┌─────────┴──────────┐
   │                          │  src/core.js       │
   │                          │  纯函数,零副作用   │
   │                          │  返回改写指令集     │
   │                          └─────────┬──────────┘
   │                                    │
   ▼                                    ▼
模型按指令集重写 ──▶ 调用 verify_rewrite 校验
                          │
                    ┌─────┴─────┐
                    │           │
                 通过        不通过
                    │           │
                    ▼           ▼
              四段式交付    修正后重新校验

两层设计:工具不做重写,只产出改写指令集;真正的重写由会话模型执行。 这样插件的核心逻辑保持纯函数、可离线测试,且不绑定任何模型实现。 反虚构校验作为独立工具介入,形成"改写 → 校验 → 修正"的闭环。

开发与验证

npm install          # 仅装 devDependencies
npm run verify       # 全量验证:语法 + 类型 + 文档检查 + 发布审计 + 守卫行为 + 172 项测试 + 示例
命令 内容 需要 DSH
npm run lint 语法检查 否
npm run typecheck TypeScript 静态类型检查(JSDoc + checkJs) 否
npm test 172 项测试,node:test 标准 runner 否
npm run test:coverage 覆盖率报告 否
npm run check:guard 守卫行为验证(编造必须被拦、合法必须放行) 否
npm run check:docs 文档一致性检查 否
npm run check:secrets 敏感信息扫描 否
npm run demo:guard 只看守卫拦住编造的过程 否
npm run demo:export 端到端:校验 → 导出真实 .docx 否
npm run example 可运行示例(含守卫演示) 否
npm run verify 以上全部 否

测试分七组(test/node/):

  • guard.test.js — 反虚构守卫:token 提取、反向验证(编造必须被抓住)、 正向路径(合法改写必须放行)、职责升格、时间线一致性、关键词回验、 整条新增检测、防误报、已知局限声明
  • export.test.js — 导出:ZIP/DOCX 结构真实性(真实解包校验)、 XML 转义、Markdown 解析、安全边界(不覆盖已有文件等)
  • core.test.js — 语言规范化、输出契约、真实场景、失败路径
  • contract.test.js — 工具定义形态、schema 关键字白名单、真实 execute
  • plugin.test.js — apply(ctx) 装载路径、架构硬约束守卫
  • schema.test.js — 调用平台自身的断言函数校验 schema(探测不到 DSH 时优雅跳过)
  • publish-audit.test.js — 发布审计元测试

CI 在 Linux / Windows / macOS × Node 20 / 22 / 24 共 9 个组合上重跑同一套命令。

架构与硬约束

src/guard.js    反虚构守卫:确定性校验(零依赖纯函数,可离线测试)
src/export.js   导出:手写 ZIP + OOXML,零依赖生成 .docx
src/core.js     零依赖核心:业务逻辑 + 契约常量(唯一事实来源)
src/index.js    平台装配:section 注入 + 工具注册 + 文件 IO
src/prompt.js   核心资产:简历改写引擎 prompt(含版本号)
test/node/      测试套件
examples/       可运行示例与 fixtures
scripts/        验证工具(文档一致性 / 发布审计 / 守卫行为 / 演示 / 测试运行器)

分层原则:core.js 与 guard.js、export.js 全部是零 IO 纯函数, 因此可在任何环境离线测试;文件系统写入只出现在 index.js(装配层)。 这样契约层永远可测,IO 边界清晰。

两条不容违反的硬约束

这两条都是端到端验证踩坑得出的,纯离线测试发现不了:

1. 插件不可 import 任何 @deepseek-ai/* 包

// ❌ 会让运行时崩溃
import { defineTool } from '@deepseek-ai/dsh-tools'

原因:插件从自身位置会解析到一份独立的 dsh-tools 副本,与宿主运行时形成模块双实例。 两份模块里的 TOOL_RUNTIME_SCHEDULER 是不同的 Symbol,宿主执行工具时取到 undefined, 报 Cannot read properties of undefined (reading 'prepare')。

2. package.json 的 dependencies 必须为空

声明平台包会让 pnpm 在目标 profile 里再装一份,重新制造上述双实例问题。 平台包只放 devDependencies(仅供测试)。

其他契约要点

  • schema 关键字白名单:平台只接受 type/oneOf/properties/required/additionalProperties/items/enum/const + 注解
  • required 位置:必须是 object 根级的字符串数组,不能写在 property 内部
  • 输出 schema 的 additionalProperties:false:execute 返回值字段必须与其严格一致,多一字段即 ToolOutputError
  • 参数根节点是开放对象:平台不拦截未知参数,防线是 required 校验 + 白名单解构

常见问题

简历内容会被上传到第三方吗?

不会。插件自身零网络请求、零文件写入。简历只在你的本地会话中流转。

它会不会替我编造经历?

不会。见反虚构铁律——三重机制的保障,且有测试物理锁定。

支持哪些语言?

工具支持中英双语输出(language: 'zh' | 'en')。

需要什么版本的 DSH?

针对 @deepseek-ai/dsh-tools@0.1.5-rc.2 与 cordis 4.0.2 验证。Node 需 20 以上。

有独立界面吗?

当前是会话驱动形态(工具 + 提示词注入),没有独立图形界面。双栏 UI 面板在路线图中。

为什么工具返回的是"指令集"而不是直接改写好的简历?

因为重写需要理解语义,交给会话模型做质量更高,且让插件核心保持纯函数、可离线测试。 这是刻意的架构选择,不是功能缺失。

贡献

欢迎 PR。动手前请读 CONTRIBUTING.md——里面有两条会直接导致运行崩溃的硬约束, 以及反虚构铁律的不可违反说明。

npm run verify   # 提交前必须全绿

License

MIT

—/ 5

No ratings yet

Verified DSH bundle

Commit 96cbb30cbd95

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