🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

划词翻译 Gty2408/dsh-word-translate

DeepSeek Harness
Gty240834 天前有提交已提供中文文档扫描:含敏感能力

右键选中英文,离线词典与AI翻译随取随用

30/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/1 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add Gty2408/dsh-word-translate
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:需留意
是什么
dsh 原生插件 · ui
装得上吗
实装验证未通过(unknown),装前请到仓库确认最近更新与 issue
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 34 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
⚠︎ 实装验证未通过(unknown · 2026/10/1) ——可能是验证环境差异,装前建议到 GitHub 仓库确认最近更新与 issue。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

读写/删除本地文件写入剪贴板(不计风险)发起外部网络请求
查看扫描证据(共 4 处,展示前 4 条)
  • 发起网络请求
    lib/client.js:852
    const response = await fetch(path, {
  • 写入剪贴板
    lib/client.js:1175
    navigator.clipboard?.writeText(text).catch(() => {});
  • 写入剪贴板
    lib/client.js:1687
    clipboard.writeText(text).then(done, fallback);
  • 读取本地文件
    lib/dictionary.js:74
    const text = await readFile(DICT_PATH, 'utf8');
扫描于 2026/11/3(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 右键划词翻译
  • 离线词典查询
  • AI翻译与朗读

在 DSH Web UI 里右键选中的英文,即可使用内置离线词典(词性、音标、柯林斯星级、考试标签和词频排名)、结合上下文的 AI 翻译和语音朗读。译文会存进可搜索、可拖动的历史面板,同时充当持久缓存。

README

由 DeepSeek 最新模型翻译生成
dsh-word-translate 在 DSH Web 界面里选中英文单词、短语或整段文字,鼠标右键弹出菜单: | 菜单项 | 行为 | 花 token | | 复制 | 把选中文字放进剪贴板 | 不花 | | 记录 | 弹出翻译记录浮层(查看 / 搜索 / 删除) | 不花 | | 词典 | 查内置离线词典:中文释义、词性、音标、柯林斯星级、考试标签、词频排名 | 不花 | | AI 翻译 | 把选中文字连同它所在的句子发给当前会话的模型,结合上下文翻译;支持整段 | 花 | | 朗读 | 用浏览器自带的 SpeechSynthesis API 朗读英文原文 | 不花 | AI 翻译的结果会自动存进「翻译记录」。记录以浮层卡片弹出: - 可以拖动:抓住顶栏拖到任意位置,不会被挡住的会话内容遮住 - 关闭方式:点遮罩、点 ✕、或按 Esc,回到会话——全程不离开当前会话 - 每条卡片:查的词(大字)、译文、带高亮的原句 「复制」是必需的,不是锦上添花。 菜单为了替换系统右键菜单会调用 preventDefault(),这同时拿掉了系统的"复制"——所以在加上这个按钮之前, 选中英文后根本没法复制。剪贴板 API 不可用时回退到 execCommand。
展开完整文档(README 剩余 1 节)
dsh-word-translate

在 DSH Web 界面里选中英文单词、短语或整段文字,鼠标右键弹出菜单:

| 菜单项 | 行为 | 花 token |
| 复制 | 把选中文字放进剪贴板 | 不花 |
| 记录 | 弹出翻译记录浮层(查看 / 搜索 / 删除) | 不花 |
| 词典 | 查内置离线词典:中文释义、词性、音标、柯林斯星级、考试标签、词频排名 | 不花 |
| AI 翻译 | 把选中文字连同它所在的句子发给当前会话的模型,结合上下文翻译;支持整段 | 花 |
| 朗读 | 用浏览器自带的 SpeechSynthesis API 朗读英文原文 | 不花 |

AI 翻译的结果会自动存进「翻译记录」。记录以浮层卡片弹出:

- 可以拖动:抓住顶栏拖到任意位置,不会被挡住的会话内容遮住
- 关闭方式:点遮罩、点 ✕、或按 Esc,回到会话——全程不离开当前会话
- 每条卡片:查的词(大字)、译文、带高亮的原句

「复制」是必需的,不是锦上添花。 菜单为了替换系统右键菜单会调用
preventDefault(),这同时拿掉了系统的"复制"——所以在加上这个按钮之前,
选中英文后根本没法复制。剪贴板 API 不可用时回退到 execCommand。

记录卡片为什么这样排版

初版把上下文拆成 before 和 after 两行显示,结果把查的词本身漏掉了:

菜单为了替换系统右键菜单会调用 0,这同时把系统的"复制"也拿掉了 ← 读者看不出查的是哪个词

现在合成一句,查的词在中间高亮,读起来就是完整句子:

菜单为了替换系统右键菜单会调用 preventDefault,这同时把系统的"复制"也拿掉了

字号也整体调大(查的词 17px、译文 15px、上下文 14px),并去掉了卡片底部那行时间 / token / 模型——那些是调试信息,不是学习时要看的东西。

两个按钮的设计意图

「词典」不花 token,因为它是本地数据。 查词是高频动作,如果每次都调用模型,成本会随着阅读量线性增长——而"这个词什么意思"大部分时候并不需要模型。

「AI 翻译」才用模型,因为上下文需要理解。 bank 在 river bank 里是河岸、在 balance at the bank 里是银行——这不是查表能解决的,必须读懂句子。

两者互补:先用词典(免费、秒回),词典没收录或需要看语境时再用 AI 翻译。

词典:为什么值得内置

数据来自 ECDICT(MIT,77 万词条),构建时裁到 26,974 词 / 3.05 MB。
保留的判据用的是 ECDICT 自带的评级,不是我自己编的:

| 字段 | 作用 |
| translation | 中文释义(最多 4 个义项) |
| phonetic / pos | 音标、词性 |
| collins | 柯林斯星级(1–5) |
| oxford | 是否 Oxford 3000 |
| tag | 考试标签:中考/高考/四级/六级/考研/托福/雅思/GRE |
| bnc / frq | BNC / COCA 词频排名(数字越小越常用) |

最后三行才是关键。 一个词的释义机器也能翻,但"这是四级词、柯林斯 5 星、词频排第 406"回答的是另一个问题:这个词值不值得记。学习时间有限,应该优先学高频词——这些字段让插件能直接告诉你该不该学。

查 banks 会自动跳到 bank:词典里存了 27,241 个屈折形式的映射(banks→bank、running→run、better→good),因为词根条目才有完整的释义和评级。

上游数据来源与协议声明见 data/NOTICE.md。

翻译记录:既是历史,也是缓存

每一条成功的 AI 翻译都会存进宿主端的持久化存储 (ctx.storage → dsh-storage-json,落在 $DSH_HOME/storages/word_translate.json),而不是浏览器 localStorage。理由是:

- 数据活过浏览器 profile,是可读的 JSON 文件,能备份能看
- 换浏览器/清缓存不会丢
- 写入是原子替换(先写临时文件再 rename),带版本号

同一条内容(原文 + 前后文一起做 key)如果没被删过,再次翻译会直接调出来,不再调用模型——这就是持久缓存。上下文参与 key 是必须的:同一个词在不同句子里是不同答案。

记录可以在面板里搜索、单条删除、一键清空。

选区可以是整段

选一整段(多句话)时,整段都会被翻译。这一条曾经是坏的,值得记下来:

原来的系统提示词通篇把选区称作 "selected term"(词/术语),模型就照字面理解,只翻译了第一句。实测 227 个字符的三句话选区,只返回了 14 个字符——第一小句的译文。
模型不是"偷懒",是提示词就是这么要求的。

修法是两处:提示词改称 "selection" 并明确"必须整段翻译、长度绝不是缩短的理由",用户消息里再按句数提醒一次(The selection is N sentences long)。

同时加了一道兜底:如果所有尝试都只译出开头(译文长度不足原文的 15%),就报错让用户重试,而不是把第一句当成整段译文显示出来——那比报错更误导。

修复后实测同一段:8/8 完整(122–130 字符),之前是 14 字符。

为什么是"前后各一段"

同一个词在不同上下文里是完全不同的词。插件把选区所在段落的前一个和后一个同级段落一并送出,所以:

- grassy bank → 河岸
- check his account balance at the bank → 银行
- mount the React root 里的 mount → 挂载

两个已修复的模型行为陷阱

这两条都是实测发现的,不是推断出来的;写在这里是因为它们直接决定了代码的形状。

1. 模型有时把答案写在"推理块"里

deepseek-v4.1-flash 是推理模型。它有时完全不在正文块里回答,把答案写进推理就结束了:

reasoning: 'The term "mount" in React context means 挂载.' finish: stop ← 没有任何 text 块

按协议只读 text-delta 的话,这里会看到一个「空答案」,于是一次成功的调用被误报成失败。

2. 模型有时吐出被截断的正文

同一个请求的另一次尝试会给出:

text: '挂' ← 被截断的正文 reasoning: '…"mount" = 挂载.' ← 模型自己知道完整答案

模型知道正确答案,只是没写全。 实测同一请求在 挂 与 挂载 之间随机摆动(8 次里 4:4)。
长句上更明显:7 个单词的英文短语曾被答成 一键(2 个字)就停了。

处理分两层:

第一层:对账(reconcileAnswer)——正文与推理之间取更完整的那个:

| 正文 | 推理里点名的结论 | 结果 |
| 空 | 挂载 | 用 挂载 |
| 挂(单字) | 挂载 | 用 挂载 |
| …绑定到选择器(长句截断) | …绑定到选择器钩子 | 用完整的那个 |
| 配置(完整) | 推理里只是提到过 配置文件 | 保留 配置 |

最后一行是关键:只有正文是某个被明确标记为结论的答案(Final: / Answer: / 最终: / = X)的前缀时才会替换。推理里顺带提到的更长词组不算——那会引入新错误而不是修复。

第二层:判为残句就重试(最多 4 次)。三种信号之一成立即认为正文不完整:

| 信号 | 例子 | 为什么能看出来 |
| 单字 | 挂 | 一个汉字几乎不可能是完整译文 |
| 末尾是不能收句的虚词 | 一键重启按钮被 | 被 不能结束句子 |
| 末尾是必须带动词的副词 | 一键重启按钮被故意 | 故意 后面必须还有动词 |
| 明显过短 | 一键(源文 7 个单词) | 多词短语不可能只用 2 个字承载 |

重试取最长的一次作为兜底;如果每次都是残句,就返回最长的那个残句(好过报错),但完全没产出正文时仍然报错,不会拿一段乱码充数。

修复后实测:mount / bank / volume 各 3/3 稳定;7 个单词的长短语从 4/10 完整提升到 10/10 完整。

一个我查错过、值得记下来的点。 我一度以为长句被截断是「读 chunk 的代码丢了尾巴」,于是加了个临时调试路由把原始 chunk 序列打出来。结果证明读取没问题:模型只是有时少写一个句末虚词(…选择器钩子 vs …选择器钩子中)——那是风格差异,不是截断。
先拿证据再改代码,这一步省掉的话我会去修一个不存在的问题。

架构

插件是标准的 DSH 双半 bundle:

- 宿主半(lib/index.js)注册三条 loopback-only 路由:

| 路由 | 作用 |
| /dictionary | 查内置词典,不调用模型 |
| /translate | 用 ctx.llm.stream() 发起侧信道模型调用——和会话标题生成走同一条辅助调用路径,不写入会话日志,不产生对话轮次 |
| /history | 翻译记录的增 / 删 / 查 |

- 浏览器半(lib/client.js)注册两个 shell.overlay 条目:右键菜单,和记录浮层。
记录入口就在右键菜单里,没有额外的工具栏按钮。

记录界面绝对不能放进 main 插槽。 会话(连同输入框)就渲染在 main 的 conversation key 下面,注册自己的 main key 并选中它,会把整个会话卸载掉;而「会话」是 activePanelId === null 时的默认值、不是侧边栏的一行,所以点了之后没有任何入口能回去——表现就是输入框失效、只能重启。

我第一版正是这么做的(main + sidebar.panellist),踩了这个坑。
现在记录是 shell.overlay 上的浮层,浮在框架之上、不参与 main 的 key 分发,所以打开和关闭都不可能影响会话。

第二个「输入框失效」的坑:window.confirm

修好 main 之后,清空记录又出现了同样的症状——输入框打不了字,只能重启。
单条删除一直正常,唯一的差别是清空用了 window.confirm。

根因:window.confirm 是同步阻塞的原生对话框,会卡住渲染进程的主线程。
DSH 的编辑器是 contenteditable,对话框期间浏览器丢失 selection / 焦点状态,回来之后编辑器再也拿不回焦点——表现就是打不了字。

这不是猜测:整个 DSH 自带 UI 里 window.confirm 出现 0 次(我在打包产物里 grep 过)。DSH 有正规的 Modal 组件(plugin-manager、workspace 都在用)。
是我用了一个整个项目都刻意回避的 API。

修法:改成两步按钮,完全不用对话框——第一次点击按钮变成红色的「确认清空 N 条」,第二次点击才真的清空,4 秒后自动解除。清空记录本来也不值得为它弹一个模态框。

tools/client-eval.test.mjs 现在会扫描源码禁止 window.confirm / alert / prompt(tools/guard-selftest.mjs 反过来验证这条护栏真的会触发,而不是空转)。

教训:在这个项目里,「别的框架能用」不等于「这里能用」。window.confirm 在普通网页里完全正常,但在 Electron + contenteditable 编辑器里会毁掉输入焦点。
判断依据应该是项目自己的既有做法,而不是通用经验。

一个静默的数据丢失 bug(值得记)

dsh-storage-json 的 KV 后端每个 unit 只允许一个活句柄,第二次 open 会直接抛 unit '...' is already open。

我第一版 openHistory() 只 open、不 close。后果非常隐蔽:

1. 第一次激活拿到句柄,然后永远持有;
2. 之后每次激活(包括热重载产生的)open 都失败;
3. 失败被 catch 住并降级到内存存储——UI 完全正常,翻译也正常返回;
4. 但新记录再也不会写进磁盘,而界面上看不出任何异常。

只有把 unit 的 close() 注册成 ctx.effect 的 disposer 才正确:fiber 卸载时释放句柄,下一次激活才能重新打开。tools/history-reopen.test.mjs 用「单句柄」规则的桩把这个生命周期钉住了——它会先卸载再重开,正是热重载做的事。

教训:catch 之后静默降级,会把"持久化失效"变成"看起来一切正常"。
所以记录界面会显示一条 durable: false 的警告,而不是假装写成功了。

模型选择

翻译使用的模型按优先级解析:

1. 当前会话自己的模型选择(modelSelection 投影的 pending / lastUsed);
2. 该会话最后一次真实请求头里的 provider/model;
3. 部署默认模型。

会话冷启动或已销毁时逐级回退,不会让一次翻译失败。

上下文采集

这是本插件改过的第二个严重缺陷。 原来的实现只取选区的上一个和下一个兄弟块,完全不看选区在自己那段里的位置——于是选区所在句子的其余部分一个字都没被送出去。

实测(选中 false,它在 重启后如果 durable 还是 false,告诉我,我再查。 里):

| | 送出去的上下文 | 结果 |
| 旧 | before = 上一个 列表(两条 被空格拼成一行)after = 下一段关于素材的话 | 模型答 假(当形容词翻了) |
| 新 | before = 重启后如果 durable 还是after = ,告诉我,我再查。 | 模型答 false(认出是代码值) |

现在的优先级,最相关的排第一:

| 优先级 | 内容 | 说明 |
| 1 | 选区所在的句子 | 从块文本里定位选区,再向前/向后切到最近的句末标点 |
| 2 | 同块剩余文字 | 仅当句子太短(不足 12 字)不足以消歧时 |
| 3 | 邻居块(限长 400 字) | 仅当块内什么都取不到时的兜底 |

句末标点同时认半角和全角(.!?。!?;;),因为周围是中文、选中的是英文,句子边界两种都可能出现。

输入框(编辑器、)走同一条句子切分逻辑,只是文本源是 selectionStart/selectionEnd 切片。两侧都限长 2000 字符。

为什么原来会那么写:插件最初的目标是"查英文单词",对孤立的单词来说前后各一段确实够用。但当用户选中句子里的词(false、durable),同一句话才是真正的上下文——而它恰好是被丢掉的那部分。

菜单显示

| 情况 | 菜单显示 |
| 选区 ≤ 40 字 | 顶部回显"选中 <文字>" |
| 选区 > 40 字 | 不回显(长文本来就在菜单后面看得见,回显会把操作挤出屏幕) |
| 菜单顺序 | 复制 / 记录 / 词典 / AI 翻译 / 朗读,下面是音量(和语音) |
| 点「复制」 | 按钮变成 已复制,不额外占一行 |
| 点「词典」 | 音标 + 词性 + 评级徽章(牛津3000/柯林斯星级/考试标签)+ 释义 + 词频 |
| 词典没收录 | 内置词典没有收录这个词。可以用「AI 翻译」。 |
| 翻译成功 | 译文 + 本次翻译使用 N token(输入 x / 输出 y) |
| 命中内存缓存 | 译文 + 缓存 |
| 命中历史记录 | 译文 + 来自记录(重启后仍生效) |
| 点「记录」 | 菜单关闭,记录浮层弹出 |
| 正在朗读 | 按钮变成 停止朗读,再按一次即停止 |

朗读不会清掉查词结果

内容状态和播放状态必须分开。 初版把两者挤在同一个 result 里,所以点「朗读」会用 {status:"spoken"} 覆盖掉词典条目或译文——刚查完想听发音,结果内容没了。

现在拆成两个状态:

| 状态 | 管什么 |
| result | 卡片内容:词典条目 / 译文 / 错误 |
| speaking | 是否正在播放,只驱动按钮文案 |

所以「查词典 → 朗读」是叠加的,词典条目始终留在卡片上。切换新选区时会
stopSpeaking() 并复位,避免残留"停止朗读"。

菜单不显示模型名——用的就是当前会话的模型,不需要重复告知。

长译文不会溢出屏幕

菜单原本只有 max-width、没有 max-height,所以一段长译文会一直往下长、跑出屏幕底部,后面的内容再也看不到。修法是三层配合:

1. 卡片限高:max-height: calc(100vh - 16px),永远不会超出视口。
2. 译文可滚动:只有译文区允许被压缩(flex: 1、overflow-y: auto),按钮和音量条保持原尺寸不被挤掉。
3. 按真实尺寸定位:useLayoutEffect 量出卡片的实际宽高再决定位置,而不是用写死的估算值——长译文和短词的实际高度差很多,估算必然出错。
量完在绘制前修正位置,所以看不到跳动。

朗读设置

菜单里有音量滑块和语音选择,两项都记在 localStorage,下次打开还在。

关于"音量拉满还是太轻": SpeechSynthesisUtterance.volume 的上限就是 1.0(W3C 规范硬限制),插件无法超过它。所以滑块只能调小,不能把系统音量之上的响度提上去。真正影响响度的是语音本身——Windows 上不同语音的响度差别很大——所以菜单提供了语音下拉框。如果仍然偏轻,请调系统音量(或换一个语音)。

语音 下拉框只在浏览器报告多于一个英语语音时出现;只有一个时显示它没有意义。

缓存与重试

分两层,都是按 (选中文字, 前文, 后文) 做 key——上下文参与 key 是必须的,同一个词在不同句子里是不同答案。

| 层 | 位置 | 寿命 | 命中时 |
| 内存缓存 | 插件 fiber 内 | 10 分钟 / 200 条,fiber 销毁即清 | 缓存 |
| 历史记录 | $DSH_HOME/storages/word_translate.json | 永久(直到你删除) | 来自记录 |

先查内存(免费),未命中再查历史(要读盘但不用调模型),都没有才调用模型。

- 重试:一次失败会再试一次。模型对「想多久」并不稳定,同一次请求可能第一次推理完就结束、第二次正常作答,重试把这种抖动变成成功。
- 失败不缓存,稍后重试仍有机会成功。
- token 统计:重试时会把各次尝试的用量相加,所以报告的是这次翻译的真实花费,而不只是成功那一次的花费。
- 删除记录会同时清掉内存缓存。否则删掉后重新翻译会命中内存、记录不再重建,面板上看起来「删了就永远找不回来」。

安装

从本地目录:

dsh plugin --profile desktop add <本目录路径>

发布到 npm 后也可以按包名安装:

dsh plugin --profile desktop add dsh-word-translate

本插件零运行时依赖,所以安装不需要 allowBuilds 构建授权——比需要编译的插件省事。

改宿主半代码需要重启 DSH。 本 profile 的 HMR 默认 root: [](不监听任何模块根目录),所以 lib/index.js 只在启动时读一次;用插件管理器禁用再启用不会重新加载它,会继续跑缓存里的旧模块。浏览器半不受影响,由 client-modules 的 HMR 通道热发布。

上架到插件市场

DSH 没有「一键上传」。上架是两步,完整步骤见 submission/README.md:

1. 代码推到 GitHub 仓库
2. 往 awesome-dsh-plugin 提一个 PR,加一个 YAML 文件(data/plugins/<owner>__<repo>.yml)

合并后市场自动收录,通常一天内生效。不要往 dsh-market 仓库提插件条目。

投稿内容已准备好:submission/awesome-dsh-plugin.yml (把 OWNER/REPO 换成真实地址即可)。

node tools/check-listing.mjs # 逐条核对收录要求(31 项)

配置

无。插件不注册任何设置命名空间,也不需要凭据——它复用当前会话已有的模型通道,词典是内置数据,翻译记录用宿主自带的存储栈。

测试

node tools/host-logic.test.mjs # 翻译逻辑、对账、重试(16 项)
node tools/dictionary.test.mjs # 词典查询、词形还原(19 项)
node tools/routes.test.mjs # 三条路由 + 历史存储语义(38 项)
node tools/history-reopen.test.mjs # 持久化句柄生命周期(7 项)
node tools/client-eval.test.mjs # 客户端模块求值 + 槽位注册 + 禁用阻塞对话框(21 项)
node tools/context-capture.test.mjs # 上下文句子优先 + 菜单顺序 + 记录卡片 + 朗读不覆盖内容(35 项)
node tools/guard-selftest.mjs # 验证上面的禁用对话框护栏真的会触发(6 项)
node tools/check-listing.mjs # 核对插件市场的收录要求(31 项)

其中几项是回归护栏,专门钉住踩过的坑:

- client-eval.test.mjs 断言没有注册 main 或 sidebar.panellist ——因为注册它们会把会话卸载掉(见「架构」)。
- history-reopen.test.mjs 断言 unit 在 fiber 卸载时被释放 ——否则后续激活会静默降级到内存,记录不再落盘。
- context-capture.test.mjs 断言菜单按钮顺序是 复制/词典/AI翻译/记录/朗读 ——顺序是需求,不是细节(复制必须在最前,因为它替代了系统菜单里的复制)。

边界与已知限制

- 三条路由都只接受 loopback 来源,非本机 origin 一律 403。历史路由也在此列,因为它暴露的是你的阅读记录。
- 单次翻译超时 45 秒;输出上限 8192 token(推理与译文共用该预算)。
- 词典是离线快照:只收录 26,974 个常用词,冷僻词、专有名词、新词查不到——此时用「AI 翻译」。数据更新需重新运行 tools/build-dict.mjs。
- 朗读依赖浏览器的语音合成;没有任何已安装语音时,Chromium 可能静默失败,此时菜单会显示错误而不是假装成功。
- 音量上限 1.0 是规范限制,插件无法让朗读比系统音量更响;见上文「朗读设置」。
- 上下文只在块内和邻居块之间取,不跨容器边界(例如表格单元格之间互不作为上下文)。
句子切分是标点驱动的启发式,遇到没有标点的长句会退化为整块。
- 推理对账(reconcileAnswer)是针对 deepseek-v4.1-flash 实测行为写的启发式:它只在「正文为空」或「正文是单字且推理给出了更长的同前缀答案」时介入。换用其他模型时这段逻辑不会造成伤害(大多数模型本来就把答案放在正文块),但也不再必要。
预览分享卡片长什么样 ↓Gty2408/dsh-word-translate
分享 · DeepSeek Harness Hub
Gty2408/dsh-word-translate

右键选中英文,离线词典与AI翻译随取随用

这是你的仓库?认领条目

回到顶部