dsh-decision-engine

中文文档
1.2.1发布于 2026/11/03MITES Module零依赖

dsh-decision-engine: DeepSeek Harness的一个便宜的判断层——一个小的决策模型在主模型行动之前回答结构化的问题,因此调用可以被允许、升级、重新路由到更便宜的模型,或者跳过。所有八个决策点(也是)

中文使用文档
文档目录19 节
  1. 安装 / Install
  2. 数据文件 / Data files
  3. 决策历史 / The Decisions tab
  4. 匿名使用统计 / Anonymous usage stats
  5. 配置页 / The config page
  6. Provider:接哪个决策服务 / Which decision service
  7. 端点路径由服务商决定,不由模型决定
  8. 密钥保存位置 / Where keys are stored
  9. 模型默认「自动」
  10. 决策点 / Decision points
  11. 三态 / Three modes
  12. 省 token 的设计 / Token-saving design
  13. 超时与降级(fail-open)/ Timeout and fail-open degradation
  14. 统计与对比 / Statistics
  15. token 估算 / Token estimation
  16. 阈值 / Thresholds
  17. 开发 / Development
  18. 想深挖为什么这样设计 / Why it works this way
  19. License

dsh-decision-engine

website

给 DeepSeek Harness 的决策层:在主模型动手之前,把「当前状态 + 一组结构化问题」发给一个 便宜的决策小模型,拿回概率化的答案,据此决定放行、询问、拦截,或改道(换模型)、跳过(省掉一次 昂贵调用)。例如工具授权问四个问题:风险、可逆性、任务相关性、注入嫌疑。 默认只记录、不拦截(shadow),任何异常一律 fail-open 放行。

A judgement layer for DeepSeek Harness: before the main model acts, it sends "current state + a set of structured questions" to a cheap decision model, gets probability-bearing answers back, and decides to allow, ask, block — or reroute (switch model) and skip (drop an expensive call). Tool authorization, for example, asks four questions: risk, reversibility, task relevance, injection suspicion. Defaults to shadow (record only) and fails open on any error.

接任意决策服务:请求形状只有一个——{ model, state, questions, think_mode } 发过去, 拿回 answers。哪些服务商提供这个端点、走哪条路径、用谁的 key,都由 provider 决定, 与各决策点的解析逻辑无关。因此内置多个预设,也可填任意 custom base URL (自建 llama.cpp / vLLM、企业网关、第三方中转)。

Works with any decision endpoint: there is exactly one request shape — { model, state, questions, think_mode } in, answers out. Which service provides it, which path it sits on, and whose key it uses are the provider's business and never touch the per-point parsing logic, so you can pick a built-in preset or fill in any custom base URL (self-hosted llama.cpp / vLLM, corporate gateways, relays).

安装 / Install

dsh plugin add dsh-decision-engine

或手动装进 profile:add it to a profile manually:

cd ~/.dsh/profiles/desktop
pnpm add dsh-decision-engine

然后在 profile 的 package.json → dsh.profile.bundles 里加入 "dsh-decision-engine", 重启 DSH。Then add "dsh-decision-engine" to package.json → dsh.profile.bundles and restart DSH.

本地开发 / local development:git clone 后复制进 profile 的 node_modules,或用 pnpm link(详见 docs/local-dev-link.md)。

配置改完即生效,不需要重启:每次调用前都会检查配置文件 mtime。 Config changes take effect without restarting DSH.

数据文件 / Data files

数据目录是 $DSH_HOME/dsh-decision-engine/(DSH_HOME 未设置时为 ~/.dsh, Windows 上形如 C:\Users\<name>\.dsh\)。解析顺序与宿主一致:显式路径 → $DSH_HOME → 系统家目录。All paths below live under $DSH_HOME/dsh-decision-engine/.

文件作用
config.yml配置(可从 config.example.yml 拷贝;实际以配置页写入为准)
telemetry.jsonl决策流水账,给人读 / tail 排查
stats.jsonl按 provider × model 的 token 与耗时,供「统计与对比」页读取
decisions.jsonl决策明细(含会话归属与决策内容),供「决策历史」标签页读取;到 8 MB 轮转
analytics.json匿名统计的本地状态(安装 id + 上次上报日期),可随时删除以重置身份
~/.dsh/.credentials.yaml 的 refs: 段API key 的默认存放处(见下)

配置里可能有明文 key,因此 config.yml 权限保持 600。

决策历史 / The Decisions tab

开启后,会话的标签栏会在「对话」「轨迹」之后多出一个 决策历史 标签页, 按时间顺序列出当前会话里经本插件做出的每一次决策,共八列: 时间 / 决策点 / provider / model / 裁决 / 耗时 / 内容(有内容 / 仅元数据)/ 标记(缓存命中、已降级)。点任意一行展开,能看到这次决策的完整现场—— 发给决策模型的 state 与 questions,以及它回来的 answers 和本地算出的 scores。

列表滚动时表头(时间 / 决策点 / …)保持冻结,记录多了也看得到列名。 每一列表头都可点排序(再点切换升降序;默认按时间升序)。

With the feature on, each session gains a Decisions tab right after Chat and Trajectory. It lists every decision this plugin made in that session in time order, in eight columns: time / decision point / provider / model / verdict / latency / content (has content, metadata only) / flags (cache hit, degraded). Expanding a row reveals the full context sent to the decision model, the questions, its answers, and the locally computed scores.

默认开启,可在配置页关掉(decisionsTabEnabled):

Default on; turn it off on the config page (decisionsTabEnabled):

# 唯一的开关:开 = 记录明细(含决策内容);关 = 不写任何明细文件,标签页也消失
decisionsTabEnabled: true

# 以下是高级档位,配置页上没有开关,需要时手改 config.yml:
decisionsMaxContentChars: 4000   # 单条内容上限
decisionsMaxBytes: 8388608       # 明细文件体积上限(到顶轮转,只留一代)

隐私边界 / Privacy:明细只写本机 decisions.jsonl,不发网络请求, 也不进匿名统计。开关开着时一定记录决策内容(现场与回答),只有当 内容大到超出上限、连裁剪后的问题与回答都装不下时,该条才退化成「仅元数据」。 所以想不保留内容,唯一的办法是关掉整个开关——关掉后完全不写这个文件, 不采集、不落盘、不占磁盘,没有「只存元数据」的中间档。写盘前会做一层 密钥兜底替换(sk-…、Bearer …、JSON 里的 apiKey/token 字段),单条 内容超 4000 字符时按「工具参数 → 对话摘要 → 整个 state」依次裁剪。

The detail file never leaves the machine and is never part of anonymous telemetry. With the switch on the decision content is always recorded — a row only degrades to "metadata only" when its content is too large to fit even after trimming. So the only way to keep content off disk is to turn the whole feature off, which writes nothing at all: nothing collected, nothing stored, no disk footprint. Secrets matching common key shapes are masked before the line hits disk, and oversized content is trimmed in a fixed order.

为什么单独一个文件:telemetry.jsonl 是给人 tail 的结论流水账, 平均每行几百字节,而且被历史回填消费;把会话正文与完整现场塞进去会让它 膨胀十几倍,同时破坏「好读」和「回填口径」两件事。所以明细另立 decisions.jsonl,各管一件事。

有一个已知取舍:思维链翻译这个决策点在使用免费通道(google / bing) 时拿不到会话 id,因此那些记录「不可归属」,不会出现在任何会话的决策 历史里。为它编造一个会话 id 会让用户看到不属于自己会话的记录,比缺失 更糟。

匿名使用统计 / Anonymous usage stats

默认 daily 档:每天上报一次(首次运行那次算「安装」,之后算「今天在用」), 附带当日决策数。install 只在首次运行报一次;off 是真的一个请求都不发。

telemetryLevel: daily     # off | install | daily
telemetryEndpoint: ""     # 留空用内置端点

为什么默认是 daily 而不是更保守的 install:只报首次的话,装机之后再也没有 心跳,日活/周活会恒为 0,统计本身就没有意义了。这条上报不改任何决策、不给会话 加延迟(apply() 里 void 掉),隐私边界见下。不想参与就设 off。

上报内容只有八个字段:插件标识(本插件的 npm 包名,服务端按它分插件统计)、 匿名安装 id(首次运行随机生成的 UUIDv4,与任何账号无关)、插件版本、平台、架构、 宿主版本、当日决策数、事件类型。

绝不上报:API key、prompt / 工具参数、文件路径、provider 地址、会话内容、用户名; 服务端也不记录 IP。想看/重置身份就删掉 analytics.json——下次运行会生成新 id。

配置页 / The config page

插件 → 已安装 → dsh-decision-engine → 点进该插件,上方出现 Decision Engine 卡片 (内置 enabled: false,不会擅自介入):

  • 服务提供方:system one / bamboonode / 硅基流动 / Silicon Flow / custom, 下一行显示当前生效端点
  • 两个开关:启用守卫、真正拦截
  • 思考模式:never(默认)/ auto / always
  • 模型下拉(来自当前 provider 的 /v1/models,含「自动(服务端默认)」)
  • API Key 输入框;选 custom 时展开 Base URL(必填)、端点风格、附加请求头、密钥变量名
  • 测试端点 按钮:回显 provider、实际 POST 的完整地址、HTTP 码、请求 id 与响应体
  • 决策模型参与点:每个决策点一行,关闭 / 观察 / 生效 三态
  • 统计与对比 tab:命中率、token / 耗时 / 节省量、裁决分账(见下)

改完即保存,没有「保存」按钮:开关 / 下拉点一下即落盘;文本框停顿约 0.7 秒或失焦落盘; API Key 只在失焦或回车时落盘(半截 key 不会进凭据文件)。底部状态行实时显示 待保存… / 保存中… / 已保存 / 未保存:原因,失败可重试。 选 custom 但 Base URL 为空或不合法时,配置改动整体延后并给出原因,地址补全后自动落盘。

There is no Save button: controls persist on click, text fields after ~0.7s or on blur, the API key only on blur/Enter. The status line reports pending / saving / saved / unsaved-with-reason.

界面语言跟随宿主 / UI language follows the host:配置页与统计页会自动使用宿主 (DSH 设置 → 语言)当前的语言:中文宿主显示中文,英文宿主显示英文,切换语言时面板 即时跟随,无需重开。宿主未提供语言时按浏览器语言判断。文案由插件自带的词表提供, 因此与插件信息页里的标题/描述独立。工具授权审批卡的标题同样跟随宿主语言:插件按 宿主的 PreToolDecision.displayReason 契约成对给出中英两种文案,reason 保持中文 原文,只用于审批审计与遥测。

The config and stats panels use the host language (DSH settings → Language): a Chinese host gets Chinese, an English host gets English, and the panel follows a live switch without reopening. When the host exposes no language, the browser language decides. Translations live in the plugin's own dictionary, independent of the manifest title. A tool-authorization approval card's title follows the host language too: the plugin supplies the host's paired PreToolDecision.displayReason, while reason stays the Chinese original for the approval audit trail and telemetry.

Provider:接哪个决策服务 / Which decision service

请求形状对所有 provider 完全一致:

POST <base>/decisions   或 / or   POST <base>/systemone
authorization: Bearer <key>
content-type: application/json

{ "model": "...", "state": {...}, "questions": {...}, "think_mode": "never" }

响应只需含 answers(model / usage 可选)。所以 provider 只决定三件事: 往哪发、用谁的 key、默认哪个模型。

provider默认地址端点密钥变量名默认模型
system onehttps://api.typesafe.ai/v1/v1/systemoneTYPESAFE_API_KEY服务端默认(jev-latest)
bamboonodehttps://api.bamboonode.dev/v1/v1/decisionsBAMBOO_API_KEY服务端默认(startlux-decision-27b-autothink)
siliconflow(国内站)https://api.siliconflow.cn/v1/v1/systemoneSILICONFLOW_API_KEYKev-4B(可改 SemIf)
siliconflow-intl(国际站)https://api.siliconflow.com/v1/v1/systemoneSILICONFLOW_INTL_API_KEYKev-4B(可改 SemIf)
custom用户填写(必填)按 端点风格 拼customApiKeyEnv(缺省 DECISION_ENGINE_CUSTOM_KEY)customModel

硅基流动接入文档:国内站 · 国际站。 两个站点是两套账号、key 互不通用,所以各占一格;选它们只需粘一个 key, 地址、路径、默认模型都已预置。

每个 provider 有自己的密钥变量名并各自保存 key,互不覆盖:五套凭据可以同时配好, 切换 provider 不会把 A 的 key 发给 B。模型字段同样按 provider 分开存 (model / systemoneModel / siliconflowModel / siliconflowIntlModel / customModel), 切 provider 不会把 A 的模型名发给 B。

custom 的 Base URL 必须是 http:// 或 https:// 地址(不带 scheme、其它协议、含空格或 查询串都会被拒),端点风格 取 auto(默认)/ decisions / systemone, 附加请求头 格式 名称: 值(分号分隔;authorization / content-type / host 由插件固定)。 结尾斜杠会先去掉,因此 .../v1/ 与 .../v1 等价;拼接幂等,不会产生 /v1/v1/decisions。

端点路径由服务商决定,不由模型决定

端点风格 只是首选路径:先打首选,收到 404(= 路径不存在)时自动改用另一条再试一次, 试通的那条按 base URL 记住,下次直接命中、不再多一次往返。两条都 404 时,遥测与 测试端点 会列出试过的两个地址并提示改端点风格。只有 404 触发换路径——400(模型/内容不合法)、 401(key 不对)、5xx 与路径无关。配置页会显示「已验证可用:…」。

The endpoint style is only a preference: on 404 the plugin retries the other path once and remembers the one that works (keyed by base URL). Only 404 triggers a switch — 400 / 401 / 5xx have nothing to do with the path.

密钥保存位置 / Where keys are stored

keyStorage写到哪里适合
credentials(默认)~/.dsh/.credentials.yaml 的 refs: 段与其他服务统一托管,插件目录不留明文
config插件配置目录下的 config.yml配置自包含、可随目录整体备份;注意是明文

写 credentials 时只改 refs: 段,records: 与注释逐字保留;权限固定 600; 清空即删除该键;写入失败整体报错,不会出现「配置说存了、实际没存」。 已有 key 不会随存储位置切换被悄悄搬家,需要时重新粘贴一次。

密钥优先级:该 provider 的显式 key 字段 > 所选存储位置里的对应键 > 环境变量。 Key precedence: explicit key field > the matching key at the chosen storage location > environment variables.

模型默认「自动」

留空即不发送 model 字段,由服务端用它当前的默认决策模型——服务商将来改名也不会 400。 注意 config.yml 里 model: 必须写出来但留空:整行删掉会让键缺失并回落到内置模型名。 两个 SiliconFlow 端点把 model 列为必填,所以它们的「留空」= 预设默认 Kev-4B; 模型名大小写不敏感。模型下拉只列该 provider 真正能服务的模型(服务商的 /v1/models 会列出大量 chat 模型,打到决策端点必然 400)。

Blank = auto: the field is not sent and the server picks its default decision model. In config.yml the model: key must be present but empty — deleting the whole line falls back to a built-in name.

决策点 / Decision points

八个决策点全部已实装,由你决定让决策模型进入哪些环节。原则:只在「替代更贵的调用」 或「阻止更大的开销」处介入,绝不为了「多一道检查」而介入。

All eight decision points are implemented. The plugin intervenes only where a call replaces something more expensive or prevents a bigger expense — never just to add a check.

#决策点挂载位置触发闸(为什么不是每次都问)生效方式省 token
1工具授权 authorizetools/pre-execute只读工具 / auto 预设 / 排除名单直接放行ask / deny替代 auto-review 的满上下文审查
2模型路由 routeagent/request每轮仅前 N 步 + 路由未变不问 + 新用户输入不问替换 provider / model机械步骤下沉到便宜模型
3子任务分派 delegateagent/pre-step仅每轮第一步且带新用户输入注入一条提示少开一个 subagent = 省一整个上下文
4上下文压缩 compactagent/pre-step → ctx.compaction仅实测 token 达触发线 ×70%先跑确定性裁剪,让摘要被跳过省掉一次摘要调用
5轮次延续 turnStopagent/turn-stopping同一轮最多续一次agent.steer()避免空转一整轮
6检索必要性 retrievaltools/pre-execute仅检索类工具;其余工具零开销deny省搜索与结果 token
7技能选择 skillPicktools/pre-execute仅 skill 工具且候选 ≥2deny + 指路省误加载的技能正文
8思维链翻译 cotTranslate包住 translator.translate()本地预筛 + 同文本缓存跳过并返回原文按条省翻译调用

三态 / Three modes

模式行为
关闭 off连请求都不发,既省 token 也省一次往返
观察 observe照常判断并记录「本该怎样」,不改变任何行为
生效 enforce按判断执行该点的处置

新接入的决策点默认 off,升级不改变行为;建议先跑 观察,确认与人工判断一致后再切 生效。 New points default to off; run observe first, switch to enforce once verdicts match human review.

热路径上的点(route / delegate / cotTranslate,配置页标「热路径」角标)每次约 1.9k token,且每步都触发,因此都带明确的触发闸,不能无条件调用。 本插件不设每小时 token 预算:命中缓存后几乎为零,而「超限即停止判断」会让守卫在最需要 它的时候失效。

省 token 的设计 / Token-saving design

  • 精确缓存(唯一默认开启的层):完整 state + 问题集一致即复用,命中即不发请求。
  • 同类复用软缓存默认关闭:其键刻意丢弃参数内容,命中意味着不同参数共享同一裁决; 只有调用方显式声明 softCacheable: true 才启用,工具授权永久禁用该层(安全裁决 要么绑定完整调用上下文,要么不缓存)。
  • 只读工具直接放行:read / read_image / grep / glob / todo_write / web_search / web_fetch 等不发请求。
  • state 截断:args 走头尾摘要,recent 只带最近 4 条、每条 240 字符 (recentMessages / recentMessageChars / maxStateChars)。
  • thinkMode 默认 never:主要省延迟(约 1.9s vs 7.2s)。always 每次约多等 5s, 适合排查误判时临时用。非法值会被归一成 never。
  • 失败冷却:连续 3 次失败进入 60s 冷却,冷却期内直接放行、0ms 返回。

超时与降级(fail-open)/ Timeout and fail-open degradation

每次请求带硬超时(默认 timeoutMs: 8000,最小 1000);超时不是错误,而是降级放行。 没有配置 key 时根本不发请求,直接 no-key 降级,零延迟。上层 AbortSignal 被中止时 立即返回 caller-aborted。设计原则:任何不确定都退回原生行为,守卫自身故障绝不卡住工具调用。

Every request has a hard timeout (default 8000ms) and a timeout is a fail-open degradation, not an error. With no key, no request is sent at all.

所有降级放行主流程,并在 telemetry.jsonl 记一条 action=degraded:

情形detail
插件未启用(enabled: false)不判断,直接放行
没有 API keyno-key
命中失败冷却cooldown
端点 4xx / 5xxhttp-404 / http-500 …(附 endpoint、body、provider)
网络不可达 / 超时network-error / timeout(附 timeoutMs)
响应非 JSON / 非对象 / 缺 answersinvalid-json / invalid-response / missing-answers
答案形状不符(类型错、缺字段、choice 非法、概率越界)answer-shape-mismatch
provider 不可用(如 custom 的 base URL 非法)invalid-base-url(附原因)
鉴权被拒(401/403)auth-failed(附该 provider 的密钥变量名)
守卫内部抛异常捕获后放行,仅 logger.warn

降级不止写进日志:它显示在所属那一轮消息的尾部(与宿主自带的 token 统计同一位置), 一轮里同一类错误只出一行;错误永不进入模型可见上下文。若宿主没有该扩展位或读不到当前轮次, 则宁可只进日志,也不会把错误挂到别的消息下面。

Degradations also surface at the tail of the message they belong to (one line per error kind per turn), and never enter the model's visible context.

统计与对比 / Statistics

设置页第二个 tab 回答两个问题:钱花在哪,以及不开这个插件本该花多少。

  • 时间范围:当日 / 本周(周一起)/ 本月 / 本年 / 自定义(精确到分钟)。区间一律 左闭右开 [start, end),界面上会写出预设解析成的真实边界。
  • 维度:按 provider × model 独立统计,每组给 input / output token 总量、 总耗时与平均耗时(均耗时只按真实请求算,缓存命中那次耗时为 0)、命中缓存次数。
  • 横向对比表统计全部模式(回答「钱花在哪」);节省量对比表(基线 → 实际) 只统计 observe 模式的记录——节省量是反事实数字,只有两条路径跑在同一批工作上 才成立;生效模式下主模型路径根本没发生,只能事后估算。界面据此标注「(观察)」, 并在区间内没有观察样本时明确写「没有可比对的数据」而不是显示「省了 0」。
  • 基线 = 不启用本插件的缓存与上下文截断时同样的工作本应消耗的 token 与时间; 只有这两类优化计入,think_mode(用户自己的配置)刻意不算。无可归因优化时节省量是 0。
  • 裁决统计:allow(照常进行)/ ask(升级到人工确认)/ reject(拦下不执行), 外加一格 未裁决(降级时插件什么都没改变)。映射按 (决策点, 裁决词) 定义在 lib/outcomes.js——同一个词在不同点上含义可能相反 (retrieval.skip 是拦截,cotTranslate.skip 只是没翻译一句)。未登记的裁决会显式提示条数。
  • 按决策点分账:同一 provider/model 上哪个点在花钱。
  • 写入是异步的,不占决策路径;写盘失败只记警告。

每条统计记录含 provider / model / point / mode / action / cached / inputTokens / outputTokens / durationMs 与对应的 base* 基线值;实现见 lib/stats.js 与 lib/stats-store.js。 Each stats record carries provider, model, point, mode, action, cached, token and duration values plus their base* baseline counterparts.

token 估算 / Token estimation

API 不返回 usage 时(自建 llama.cpp / vLLM 通常不返回)用内置零依赖估算器兜底: tokens ≈ 90 + 中日韩字符数 + 其它字符数 / 3(真实请求标定,平均相对误差约 6%)。 真实返回值始终优先。本插件的硬约束是零运行时依赖,因此不引第三方 tokenizer。

阈值 / Thresholds

每个决策点的阈值都可用真实端点的成对样本(「该判 A」与「该判 B」)校准,全部可在 config.yml 覆盖;键名、默认值与「调高 / 调开会怎样」逐项写在 config.example.yml 里,那里是唯一的权威清单。

Every threshold is overridable in config.yml and calibrated against paired samples on a real endpoint. config.example.yml is the single authoritative list of keys, defaults, and what raising or lowering each one does.

开发 / Development

pnpm test             # 单元测试:纯函数、适配器接线、providers、配置往返、设置界面渲染、缓存回归、统计与裁决分账
pnpm verify:wiring    # 接线检查:用真实 schemastery 加载插件,确认每个监听器注册、每个新点默认 off
pnpm verify:endpoint  # 逐个决策点打真实端点,校验题型与答案形状(需网络与该 provider 的 key)
pnpm verify           # test + verify:wiring

verify:endpoint 不能省:题型写错会在运行时 400 并静默降级,光看日志几乎发现不了 「这个点其实一直没生效」。It cannot be skipped: a wrong question type 400s at runtime and degrades silently, so logs alone won't reveal that a point never worked.

verify:wiring 需要 profile 的依赖可解析;仓库里没有 node_modules 时先 ln -s ~/.dsh/profiles/desktop/node_modules node_modules。

想深挖为什么这样设计 / Why it works this way

本文只讲「现在的行为」。每个取舍背后的推理与实测证据另有去处: This file documents current behavior only; the reasoning and measurements behind each trade-off live elsewhere.

  • DECISIONS.md — 设计决策日志(为什么节省量只统计观察模式、为什么软缓存 对授权永久禁用、为什么去掉 token 预算…)
  • docs/lessons/ — 踩过的坑(端点路径与模型名的关系、model 字段哪些 服务商必填、本地开发的链接方式)
  • config.example.yml — 全部配置键与阈值的权威清单
  • 项目站 — 带英文版的介绍页

License

MIT

版本与发布记录

dsh-decision-engine 共发布 17 个版本,首次发布于 2026/10/25;过去 12 个月发布了 17 个版本。

版本发布日期距今
1.2.1latest2026/11/03今天
1.2.02026/11/03今天
1.1.02026/11/021 天前
1.0.02026/11/021 天前
0.9.12026/11/012 天前
0.9.02026/10/286 天前

关于 dsh-decision-engine 的常见问题

dsh-decision-engine 是什么?

dsh-decision-engine: DeepSeek Harness的一个便宜的判断层——一个小的决策模型在主模型行动之前回答结构化的问题,因此调用可以被允许、升级、重新路由到更便宜的模型,或者跳过。所有八个决策点(也是)

如何安装 dsh-decision-engine?

在项目目录运行 npm install dsh-decision-engine,或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖:@deepseek-ai/cordis(*)、@deepseek-ai/schemastery(*)。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖,Yarn 需要手动安装。

dsh-decision-engine 支持 TypeScript 吗?

该包的 package.json 没有声明类型入口。需要类型提示时,可以在 npm 上查找社区维护的 @types/dsh-decision-engine 是否存在。

dsh-decision-engine 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

dsh-decision-engine 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20.3.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

dsh-decision-engine 可以商用吗?

dsh-decision-engine 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

dsh-decision-engine 还在维护吗?

最新版本 1.2.1 发布于 2026/11/03(今天);至今共发布 17 个版本,其中过去 12 个月发布了 17 个;首次发布于 2026/10/25。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。