HongzhongL/dsh-grayprint
GrayPrint — dsh web plugin for live reasoning-style fingerprints. Scores paragraph openers against grayscale/current references and independently tracks Let me ↔ We need. 94.2% holdout.
安装Install
dsh plugin --profile web add github:HongzhongL/dsh-grayprint
把 HongzhongL/dsh-grayprint 加入你的 DSH 配置(web profile)即可启用。
READMEREADME
GrayPrint · dsh 思考文字双指纹面板
中文 | English
DeepSeek Harness(dsh)网页端插件,默认从会话页右下角打开两条彼此独立的实时指纹:① 当前思考文字更像灰度样本还是当前版样本;② 段落开头更偏 Let me 逐步试探,还是 We need 规划执行。两条读数都只描述文字形态,不直接证明模型版本或能力。
| 极点 | 写法 | 证据来源 |
|---|---|---|
| 🟢 灰度指纹 | 第一人称叙述:I'm planning out… I'll set up… I've got… |
opncd.ai 分享的 dsv4 灰度 opencode 会话 41 个 / 1749 个 raw reasoning block / 7870 个内部段落 |
| 🔵 当前版指纹 | 集体人称速记:We need answer likely… Let's inspect…,不成句 |
本机 DSH 导出的当前版 standard preset 会话 41 个 / 3021 个 raw reasoning block / 53994 个内部段落 |
为什么是这两极
起因是检验 NoLetMe 的判据在这批语料上是否成立。结论是极性相反:let me 的总命中并不能稳定区分两极,因此不参与灰度得分;只有每个内部段落的段首 Let me / We need 会进入另一条独立的组织方式指纹。GrayPrint v0.4 将所有判据统一到同一个口径:先取 reasoning block,按 Markdown 空行拆出实际段落,再只检查每段开头。
对照组的一次重大修正
v0.1 的对照组是错的。 当时的"当前极"取自 anchored-standard preset —— 而那个 preset 的设计目的本就是把模型锚回 minimal 的电报体轨迹,等于把结论写进前提。用 169 个真实会话分层复测后发现:同一个当前模型,只换 preset,得分从 10% 跳到 86%,8 个当前版会话被误判成「灰度指纹」(其中一个还是本插件的开发会话自己)。
改用 standard preset 作对照,并把每个 reasoning block 拆成内部段落后,真实分离度是这样:
| 判别轴(每个内部段落归一) | 灰度 | 当前版 standard | 单轴准确率 | 权重 |
|---|---|---|---|---|
段首第一人称(I'm / I'll / I've / I) |
22.15% | 3.76% | 93.9% | 49% |
段首 I'm / I'll |
14.94% | 1.28% | 96.3% | 51% |
段首 we / let's(仅保留计数) |
0.0% | 1.13% | 54.9%(≈随机) | — |
段首 We / Let's / Need(仅保留计数) |
0.0% | 1.35% | 54.9%(≈随机) | — |
| 各会话内部段落中位长均值(只展示) | 342 字 | 198 字 | 95.1% | — |
两条计分轴都只看段首,每个内部段落最多贡献 1 次;不会把同一段正文里的重复词累计进去。we / let's 弱轴接近随机,已移除其进度、灰度方向评分和权重,只保留按段落开头统计的数量;更宽泛的 We / Let's / Need 段首计数与段落长度也只展示、不计分。Let me 只在独立组织指纹里按段首计数。
段落口径
reasoning block 是传输容器,不是统计段落。插件先把其中的 CRLF 统一为 LF,再按一个或多个空行拆分非空 Markdown 段落并去掉首尾空白。raw reasoning block 数量仍会在详情里单独显示;两条灰度轴、Let me ↔ We need 指纹、风格信号守卫和样本门槛都按内部段落的开头计算。运行时不再统计或展示正文任意位置的词频;“原始统计”只保留段首计数及非词频元数据。
判别式
两条段首比例轴加权(第一人称轴线性,低频的 I'm / I'll 段首轴用 log10(x+0.01) 拉开低值区,再在两极值间夹逼到 [0,1])。详情里的“相对轴位置”表示当前比例在当前版参考与灰度参考之间的归一化位置,不是段首命中率或模型概率;实际命中率另列在“当前会话”。权重运行时重新归一。得分 ≥55% 判「灰度指纹」,≤25% 判「当前版指纹」,其间为「两者之间」。
非对称证据门:判「灰度指纹」额外要求 ≥48 个内部段落。灰度是"意外主张",而小样本下段首比率极不稳;不足 48 段时报「样本偏少 · 倾向灰度」。普通样本少于 5 个内部段落时直接拒判。
段首写法倾向(独立指标,v0.4)
第二条进度与灰度得分完全独立,只统计每个 reasoning block 内部段落的开头:
Let me…/Now, let me…→ 试探型一侧We need…/Now, we need…→ 规划型一侧
进度为 We need 开头数 ÷(Let me 开头数 + We need 开头数)。两类合计少于 3 个内部段落时显示“指纹信号不足”,不会硬塞一个 50%。面板里的 Let me 开头、We need 开头 和 Let me 开头比例 都是段首口径;raw block 数单独展示。
验证
留出验证 94.2%(200 次 70/30 随机划分,阈值在训练折内重选;每次先拆 reasoning block 内部段落,再只提取段首特征)。这才是诚实的数字 —— v0.1 宣称的 96.3% 是在同一批数据上自证的。
发货代码在全部语料上的实测:
| 语料 | n | 灰度 | 两者之间 | 当前版 | 守卫拒判 |
|---|---|---|---|---|---|
| 灰度 opencode(41 会话 / 1749 raw block / 7870 段落) | 41 | 38 | 1 | 1 | 1 |
| 当前版 standard(41 会话 / 3021 raw block / 53994 段落) | 41 | 1 | 4 | 29 | 7 |
| 当前版其他 preset(标定外 49 个) | 49 | 0 | 2 | 41 | 6 |
上方数字来自同一份备份语料快照;raw block 和内部段落是两种不同计数口径,不能混作同一个样本数。
得分分位:灰度 中位 96%(p25 79%);当前版 standard 中位 5%(p75 14%);当前版其他 preset 中位 0%。
灰度侧的 Pybm06QA 得分最低(13%,当前版指纹);6AWmBTvh 虽然得分很高,但只有 47 个内部段落,因此按非对称证据门显示“样本偏少 · 倾向灰度”。当前版 standard 中有 1 个会话落入灰度档,说明这仍是文字风格相似度,不是模型身份判定。
六道守卫(拒绝给假读数)
- 中文思考 — 中文占比 >15% 时拒判并标注。
- 其他非英文 — 拉丁字母占全部字母 <40% 时拒判,避免日语、韩语、俄语等被自动判成当前版。
- 英文风格信号不足 — 即使是拉丁字母语言,
I'm / I'll / we / let's等信号过少也拒判,避免法语、西语等落到当前版低分区。 - 样本太少 — 内部思考段落 <5 拒判。
- 非对称证据门 — 判「灰度指纹」需 ≥48 个内部段落,否则降级为「样本偏少 · 倾向灰度」。
- 没有思考文字 — 只有可见回复时报告异常,不从回复文本编造轨迹。
诚实边界
- 两极样本来自不同渲染通道:灰度侧是 opencode 分享页的叙述体呈现,当前侧是 DSH 原生
reasoning块。部分差异可能来自通道而非模型版本 —— 这一点至今没有被排除。 要排除它,需要"当前模型跑在 opencode 上"的样本,而那批仓库是灰度期存档,没有。 - 灰度侧只有正例(社区精选后发布,幸存者偏差),两侧都没有任务评分或 rubric。
- preset 的影响大于版本的影响:同一模型换 preset,得分可以从 10% 到 86%。所以一个「灰度指纹」读数不能推断模型版本。
- 因此本面板测的是推理的叙述人称形态,不是能力、后端、路由或 checkpoint 判定。
安装
前置条件:dsh CLI ≥ 0.1.0-rc.7,并已建好目标 profile。
方式一 · 从 GitHub 直装(推荐) —— 不需要任何构建授权。本插件的 lib/ 是手写的、已随仓库提交,没有 prepare 脚本,所以 pnpm 没有需要你 allowBuilds 批准的东西:
dsh plugin --profile web add github:HongzhongL/dsh-grayprint
想钉死版本就加 commit:github:HongzhongL/dsh-grayprint#<sha>。
方式二 · 本地 tgz(自行 npm pack,或使用已有 Release 提供的包):
dsh plugin --profile web add ./dsh-grayprint-<version>.tgz
方式三 · 本地 clone:
git clone https://github.com/HongzhongL/dsh-grayprint.git
dsh plugin --profile web add ./dsh-grayprint
装好后重启 dsh web 宿主,再刷新页面。卸载:dsh plugin --profile web remove dsh-grayprint。
使用
面板初始位于右下角,展开态和折叠胶囊都可拖动;两种形态共享一个位置锚点,并在展开时自动向窗口内避让以保证完整可见。短按吸顶标题栏收回,长按或拖动不会误触;开合带缓动动画。默认只显示灰度样本指纹与独立的 Let me ↔ We need 段首写法倾向,两条计分判据和段首原始统计收在可展开详情中。界面跟随 dsh 的中英文语言设置,开合与位置状态记在 localStorage,并常驻提示“只比较文字风格,不代表实际模型版本”。
数据口径与隐私
- 只统计当前浏览器会话快照里的推理块(
kind === 'reasoning');可见回复文本仅用于"没有思考文字"的异常诊断,不参与任何风格统计。 - 推理块先按 Markdown 空行拆成内部段落;所有判据、组织指纹、风格守卫和样本门槛只看每段开头。运行时不保留全文词频,raw block 数、段落长度与段首计数分别展示。
- 每个推理块的段落计数缓存在
WeakMap;命中缓存时同时校验当前文本,宿主即使原地更新同一个块对象也会重新统计,避免流式结束后沿用旧分母和旧段首计数。 - 数据不离开你的浏览器。
架构
lib/index.js # Node(宿主)半边 —— 空操作,满足 Loader
lib/client.js # 浏览器包(手写闭包工厂,无构建步骤)
# 计数引擎 / 判别式 / 守卫 / 实时会话源 / store / 面板
evidence/profile.json # 标定档:两极参照值、单轴判别力、验证结果、preset 敏感性
test.mjs # 零依赖回归:计数、语言守卫、双指纹、订阅销毁
浏览器包是 window.__ModuleLoader__.load({id, factory}) 闭包工厂产物,externals 走注入的 require(此插件只用 react),通过官方 shell.overlay 插槽挂载,并接入官方 locale 服务。会话订阅、统计 store 和自注入样式都挂在插件生命周期上,热重载/卸载时主动清理。不改动、不补丁任何既有 UI。
为什么没有构建步骤:lib/client.js 直接手写成符合 dsh 客户端契约的闭包工厂产物,不经 tsdown。代价是没有 TypeScript 类型检查,收益是 git 直装即可用、用户无需授予任何安装期代码执行权限。
致谢
判据的起点来自 NoLetMe(Yuer6327)与 xiaobright/modeltest 的轨迹调研;灰度语料来自 YunhaoFu/dsv4ga-news-gather 收录的 opncd.ai 分享链接。本插件的结论与它们不一致,理由见上文。
ruvnet/ruflo
amruthpillai/reactive-resume
volcengine/OpenViking
Molunerfinn/PicGo
titanwings/colleague-skill
nocobase/nocobase