dsh-math-tex:在落盘前修好 KaTeX 红字公式

前言

在 DeepSeek Harness(DSH)里做数学推导时,界面用 KaTeX 渲染 Markdown 里的公式。一旦模型输出的定界符、宏或结构不符合解析器预期,KaTeX 不会报错退出,而是把原始源码用错误色 #cc0000 直接画在屏幕上。整篇回答可能因此「一片血红」,会话记录里也会留下同样不可读的文本;前端 bundle 在 app.asar 里,KaTeX 选项为空,事后无法通过配置改 errorColor 或 maxExpand。

dsh-math-tex 是维护者 EnhydraLutristus 发布的 host 侧 DSH 插件(分类:联网工具),在文本写入持久化与推向前端之前,用与客户端同版本的 KaTeX 校验并修复会渲染成红色的数学区域,同时用 system prompt 规则减少模型犯错的概率。下面介绍它的定位、两道防线、安装与配置,以及使用时的边界。

这是什么

  • 名称:dsh-math-tex(npm 包名 dsh-math-tex,当前资料中版本 1.2.11)
  • 仓库:EnhydraLutristus/dsh-math-tex
  • 定位:纯 host 插件,没有客户端部分;渲染器改不了,修复发生在流式输出仍由 host 掌控的 llm/stream waterfall 上。
  • 解决的问题:让 DSH 数学回答保持可读——流式 chunk 经守卫改写后,会同时进入持久化消息体、实时前端帧和上下文压缩,屏幕与会话出口一致。

插件在 package.json 中声明与 @deepseek-ai/dsh ^0.2.0-rc.2 等 peer 依赖兼容;运行环境要求 Node ^22.19 || >=24。许可证为 MIT。

两道防线

事前:system prompt 规则

通过 systemPrompt.section 注入排版规则(行间公式单独成段、$$ 内只有公式、标题不粘公式等),让模型少产出会破坏 KaTeX 的结构。

配置项 promptRules 控制注入范围:

值 行为
auto(默认) 只给已经出现过数学的会话注入
full 每个会话都注入完整九条
minimal 只留防红字的两条
off 不注入

兜底:llm/stream 守卫

每一次流式模型调用外层的 waterfall 会:

  1. 按区域切分数学(认 $…$ / $$…$$,以及 \(…\) / \[…\] 四种定界符);
  2. 用客户端同版本 KaTeX 渲染每个区域;
  3. 若产物里出现错误色(不能仅靠「是否抛异常」判断,例如 \htmlClass{red}{x} 严格调用可成功却仍显示红字),则按固定顺序尝试修复后再放行。

修复顺序(不猜数学、不删公式内容):

  1. 重新排版——公式本身无误、框架错了时,改成规范的 $$\n…\n$$ 等形态;
  2. 定点施救——仅在有确定语义时处理:去掉未知命令前的反斜杠,或对重复下标重新分组;改完必须重新渲染且严格通过、无红色才接受;
  3. 降级——修不了的块级区域包成代码围栏,行内去掉定界符保留源码,避免读者看到红字。

不含 $ 和 \ 的文本逐字节直通,不改写非数学正文。

安装与启用

在插件源码目录执行官方安装脚本(复制到 profile 并注册 bundle):

node tools/install.mjs              # 复制到 profile 并注册 bundle
node tools/install.mjs --dry-run    # 只说会改什么
node tools/install.mjs --uninstall  # 从 bundle 列表移除

装完后必须开新会话:bundle 栈在会话的 runner 进程启动时读取,当前会话不会重新加载。

手工挂载:将本包放入 <profile>/node_modules/,并把包名加入 profile package.json 的 dsh.profile.bundles。

社区目录页(与 DeepSeek / 幻方无官方从属):skillhub.cn 上的 dsh-math-tex。

配置

在 profile 的 cordis.patch.yml 里按 id 设置,例如:

- id: dsh-math-tex
  name: dsh-math-tex
  config:
    repair: auto
    logFile: C:/tmp/math-tex.log
选项 默认 说明
enabled true false 时两道防线都不挂载
promptRules auto 见上文
repair auto auto 改写 / check-only 只记日志不改写 / off 完全放行
tailBuffer 15 最少扣住字符数,避免完成记号被逐字泄漏
maxHold 600 单个未闭合区域最多等待字符数,超限原样放行且不再修该块
logFile '' 诊断日志路径;空则只走 host logger
katexPath '' 指定 KaTeX 路径,默认按 profile 解析
macros {} 传给渲染器的宏,与客户端一致

未知配置键会报错而非静默忽略。enabled 为 false 或 repair 为 off 时与未装插件行为一致;maxHold 超限时的放行策略与「宁可不管,不可卡住」的设计一致。

典型用法与诊断

确认插件已挂上

host 日志中可出现类似行(最后一行表示真实回合经守卫处理):

oracle: katex 0.16.47
prompt section "math-output-format" registered (auto)
llm/stream hooked model=deepseek-flash mode=auto
prompt rules now apply to session session-8c6a99cc-…
guarded stream: 214 text delta(s) in, 231 out

in 应远大于 1(自测假流为 1)。

本地检查一份文本如何被判定与修复

node tools/inspect-fixture.mjs                    # 默认检查 test/fixtures/real-broken.txt
node tools/inspect-fixture.mjs path/to/text.md    # 任意 Markdown/文本

会打印区域数量、标红原因、修复动作,以及修复后是否仍有会渲染成红色的区域。

排查真实会话

node tools/find-red-session.mjs                   # 扫本机会话,列出仍会渲染成红色的回答
node tools/strip-sentinel.mjs --list
node tools/strip-sentinel.mjs --id <前缀> --yes
node tools/inspect-session.mjs <session.jsonl>
node tools/probe-region.mjs 'd\alpha=0'

注意:持久化记录里存的是模型原文;守卫改的是对外流式出口。记录里仍有「坏公式」不代表当前界面仍红,要以同一次流的出口为准。

在插件目录跑回归:

npm test

适用场景与注意

适合谁:经常在 DSH 里让模型写推导、证明或含 LaTeX 的技术说明,且遇到过 KaTeX 红字污染整段回答的开发者。

设计边界(README 明确写出):

  • 不能改前端 KaTeX bundle,只能 host 侧拦截;
  • 等待与持有均有上界,避免流式卡住;
  • 数学内容不会被删掉,最坏是源码形态展示。

安全与权限:插件以当前 DSH 进程权限运行,会 hook llm/stream 并可能写 logFile;安装前请阅读仓库源码与 MIT 许可证,仅在信任的 profile 中启用。

DSH 生态强调「一切皆插件」;社区目录是独立站点,本文不将其描述为官方应用商店。

结尾

dsh-math-tex 用 prompt 规则加 KaTeX 真渲染判定,在落盘前拦住并修复会显示为红色的公式区域,让流式数学回答在界面和出口上保持可读。需要细节、测试说明与设计文档时,见仓库 README 与 docs/、STATUS.md。

  • 目录页:https://www.skillhub.cn/plugins/EnhydraLutristus/dsh-math-tex
  • GitHub:https://github.com/EnhydraLutristus/dsh-math-tex
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜