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

概率决策器 xia-sc/dsh-decision

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

让智能体用校准概率回答选项、打分与定位问题

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

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

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

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · tool
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L5 · 运行时冒烟等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 7 天前
档位由哪些信号合成

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

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

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

读写/删除本地文件读取剪贴板或密钥环境变量发起外部网络请求
查看扫描证据(共 24 处,展示前 21 条)
  • 写入本地文件
    index.js:99
    await mkdir(DATA_DIR, { recursive: true })
  • 读取本地文件
    index.js:112
    raw = await readFile(from, 'utf8')
  • 读取本地文件
    index.js:118
    await readFile(to, 'utf8')
  • 写入本地文件
    index.js:124
    await mkdir(dirname(backupBase), { recursive: true })
  • 读取本地文件
    index.js:128
    await readFile(backupBase)
  • 写入本地文件
    index.js:133
    await writeFile(backup, raw, { encoding: 'utf8', mode: 0o600 })
  • 写入本地文件
    index.js:135
    await writeFile(to, raw, { encoding: 'utf8', mode: 0o600 })
  • 删除本地文件
    index.js:137
    await rm(from, { force: true })
  • 读取本地文件
    index.js:153
    const value = JSON.parse(await readFile(SETTINGS_PATH, 'utf8'))
  • 写入本地文件
    index.js:178
    await mkdir(dirname(path), { recursive: true })
  • 写入本地文件
    index.js:181
    await writeFile(tmp, `${JSON.stringify(value, null, 2)}\n`, { encoding: 'utf8', mode: 0o600 })
  • 删除本地文件
    index.js:184
    await rm(tmp, { force: true }).catch(() => {})
  • 读取密钥环境变量
    index.js:207
    const envKey = typeof process.env.DECISION_API_KEY === 'string' ? process.env.DECISION_API_KEY.trim() : ''
  • 发起网络请求
    index.js:297
    response = await fetch(joinUrl(baseUrl, options.path), {
  • 读取本地文件
    index.js:531
    bytes = await readFile(entry)
  • 读取本地文件
    index.js:974
    const raw = await readFile(RESULTS_PATH, 'utf8')
  • 发起网络请求
    client.js:449
    fetch('/dsh-decision/client-report', {
  • 发起网络请求
    client.js:623
    const res = await fetch(url, {
  • 发起网络请求
    client.js:699
    const res = await fetch(url, {
  • 发起网络请求
    client.js:799
    const res = await fetch('/dsh-decision/config', {
  • 发起网络请求
    client.js:1080
    const res = await fetch(`/dsh-decision/result?callId=${encodeURIComponent(callId)}`, {
扫描于 2026/11/2(1 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

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

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

Decision 3.0 多模态决策模型,用于 DeepSeek Harness:带校准概率的智能体工具(choice/noul/score/box)、一个设置页,以及一张概率条卡片。

README

由 DeepSeek 最新模型翻译生成
@xia-sc/dsh-decision 把 Decision 3.0(vLLM Semantic Router 的 System One 决策 API)接进 DeepSeek Harness:让智能体对一段文本 / 图片 / 视频问带选项的问题,拿回的是校准概率,而不是生成文本;同时在 Web UI 里给出可视化的概率条和设置页。 决策模型不生成文字。它一次前向就回答「哪个选项 / 是或否 / 几分 / 在图里哪里」,并给出每个答案的概率与置信度。 目录 - 1. 它做什么 - 2. 安装与配置 - 2.1 给 Agent 的安装与验证步骤 - 3. 工作原理 - 4. 什么时候触发 - 5. 如何实现 - 6. 工具参数与返回 - 7. 服务端限制 - 7.1 性能实测 - 8. 排查 - 9. 已知边界 - 10. 兼容性 - 10.1 运行环境 - 10.2 依赖的 Harness 扩展点 - 10.3 Decision API 依赖 - 10.4 版本矩阵 - 10.5 发布与安装形态 - 10.6 已知不兼容 / 限制 1. 它做什么 | 能力 | 入口 | 形态 | | 多类型决策(choice / noul / score / box) | 智能体工具 decision_ask | 一次请求问多个问题,返回概率、置信度、框选坐标 |
展开完整文档(README 剩余 1 节)
@xia-sc/dsh-decision

把 Decision 3.0(vLLM Semantic Router 的 System One 决策 API)接进 DeepSeek Harness:让智能体对一段文本 / 图片 / 视频问带选项的问题,拿回的是校准概率,而不是生成文本;同时在 Web UI 里给出可视化的概率条和设置页。

决策模型不生成文字。它一次前向就回答「哪个选项 / 是或否 / 几分 / 在图里哪里」,并给出每个答案的概率与置信度。

目录

- 1. 它做什么
- 2. 安装与配置
- 2.1 给 Agent 的安装与验证步骤
- 3. 工作原理
- 4. 什么时候触发
- 5. 如何实现
- 6. 工具参数与返回
- 7. 服务端限制
- 7.1 性能实测
- 8. 排查
- 9. 已知边界
- 10. 兼容性
- 10.1 运行环境
- 10.2 依赖的 Harness 扩展点
- 10.3 Decision API 依赖
- 10.4 版本矩阵
- 10.5 发布与安装形态
- 10.6 已知不兼容 / 限制

1. 它做什么

| 能力 | 入口 | 形态 |
| 多类型决策(choice / noul / score / box) | 智能体工具 decision_ask | 一次请求问多个问题,返回概率、置信度、框选坐标 |
| 服务洞察(模型表 / 配额 / 状态) | 智能体工具 decision_info | models · usage · status |
| 概率可视化 | 对话内卡片 | 长在 decision_ask 的工具调用行里,画概率条 |
| Key / 默认模型 / 用量管理 | Settings → 决策模型 | 同源路由读写,Key 不下发浏览器 |

典型用法:分类路由、二选一判定、0–10 档打分、图片目标定位、给候选答案打分后由外层挑选。

2. 安装与配置

从 npm 安装(已发布:https://www.npmjs.com/package/@xia-sc/dsh-decision) plugin_manager action=install_bundle target=@xia-sc/dsh-decision

或者从本地目录安装(开发:link 到本目录,改代码即时生效) plugin_manager action=install_bundle target=<本目录绝对路径>

Host 端零 npm 依赖、无需构建;安装后整页刷新(Ctrl+R)即可看到设置页与卡片。

| 项目 | 位置 | 默认值 |
| API Key | DSH 凭据 DECISION_API_KEY(设置页写入),或环境变量 DECISION_API_KEY | 无(未配置时工具返回可读错误) |
| 默认模型 | $DSH_HOME/.dsh-decision.json 的 model | vllm-sr/d3-flash |
| 服务地址 | $DSH_HOME/.dsh-decision.json 的 baseUrl | https://decision.vllm-sr.ai |
| 卡片结果缓存 | $DSH_HOME/.dsh-decision-results.json | 200 条 / 1 小时,自动清理 |

2.1 给 Agent 的安装与验证步骤

写给执行安装的智能体:从 npm 安装,然后逐项验证。不要跳过验证,也不要把 API Key 写进任何文件。

第 1 步 — 从 npm 安装

plugin_manager(action: "install_bundle", target: "@xia-sc/dsh-decision")

成功标志:application: "applied",且返回的 bundle 是 @xia-sc/dsh-decision。

- restart-required:告诉用户重启 Harness 后继续。
- failed:读 error.code 后停止,不要重复安装。

第 2 步 — 确认工具已注册

cordis_inspect_query(platform: "host", provider: "Tool", method: "listTools")

成功标志:结果里出现 decision_ask 与 decision_info。

第 3 步 — 确认 UI 半区已加载

text
cordis_inspect_query(platform: "client", provider: "Slots", method: "listSubTree",
input: { "root": "settings.section" })

成功标志:occupants 里含 id: "dsh-decision"(active: true);再查 root: "tool.call.toolview",occupants 里含 key: "decision_ask"。
缺失 → 让用户整页重载(Ctrl+R)后再查。

第 4 步 — 确认同源路由 text GET http://127.0.0.1:<PORT>/dsh-decision/status

成功标志:200,JSON 含 models、keyConfigured。
404/405 → 路由未注册:把该 row enabled: false 再 true 重试;403 → 用回环地址,不要带跨站 Origin。

第 5 步 — 配置 API Key(向用户索取) text POST http://127.0.0.1:<PORT>/dsh-decision/config content-type: application/json

{ "apiKey": "sk-vsr-..." }

成功标志:200 且 keyConfigured: true、keyPrefix 为掩码。400 key rejected 表示 key 无效或已吊销;报告里只写掩码前缀。

第 6 步 — 冒烟 jsonc { "state": "ping", "questions": { "ok": { "type": "noul", "instructions": "Is this a test?" } } }

成功标志:decision_ask 返回 answers.ok.noul(0–1)与 usage.input_tokens;decision_info(action: "models") 返回 7 个模型。

回滚 text
plugin_manager(action: "remove_bundle", target: "@xia-sc/dsh-decision")

验收清单

- [ ] application: applied,bundle 为 @xia-sc/dsh-decision
- [ ] Tool.listTools 含 decision_ask / decision_info
- [ ] settings.section 有 dsh-decision,tool.call.toolview 有 decision_ask
- [ ] GET /dsh-decision/status 返回 200 且含 models
- [ ] keyConfigured: true,冒烟返回概率

3. 工作原理

3.1 两个半区

插件是一个 bundle,包含 Host 与 Client 两半,通过 同源 HTTP 路由(而不是 typert Remote)通信: text ┌──────────────────────────── Host 进程 ────────────────────────────┐ │ index.js │ │ ├─ ctx.tools.register(decision_ask) ── Agent 工具(模型可见) │ │ ├─ ctx.tools.register(decision_info) │ │ ├─ ctx.inject(['webServer']) → 5 条路由 │ │ │ GET /dsh-decision/status 设置页数据(快,20s 缓存) │ │ │ GET /dsh-decision/usage 配额用量(慢,独立请求) │ │ │ POST /dsh-decision/config 保存 Key / 默认模型 │ │ │ GET /dsh-decision/result?callId 卡片取结构化结果 │ │ │ POST /dsh-decision/client-report 客户端异常上报(仅异常) │ │ ├─ 密钥:ctx.credentials(REF) → env → 文件 │ │ └─ 缓存:内存 Map + $DSH_HOME/.dsh-decision-results.json │ │ │ fetch /v1/systemone(带 X-API-Key) │ └──────────────────────────┼────────────────────────────────────────┘ ▼ https://decision.vllm-sr.ai ▲ ┌──────────────────────────┼────────────── 浏览器渲染进程 ──────────┐ │ client.js │ │ │ ├─ settings.section ←──┴─ GET /status · /usage · POST /config │ │ └─ tool.call.toolview ←─── GET /result?callId │ └───────────────────────────────────────────────────────────────────┘ 为什么用同源路由:Client 插件能直接用相对 fetch('/dsh-decision/...') 打到同一个 webServer(桌面壳与 Web 形态都会转发到宿主 HTTP),不需要给 typert 编译 schema、也不需要额外的 RPC 通道;同时浏览器永远拿不到 API Key。

3.2 一次 decision_ask 的完整链路

1. 模型决定调用:工具描述里写清了题型与限制,Agent 据此决定何时调用(插件不注入 system prompt)。
2. Host 校验与准备(execute):
- 解析 Key(env → 凭据 → 文件),无 Key 直接返回可读错误;
- 校验 state 长度、题数、每题 type/criteria 形状;
- 读取本地图片/视频(png/jpeg/webp、mp4/webm/mov/mkv)→ base64 data URL,超限即拒绝;
- box 题要求恰好 1 张图,否则本地报错(不浪费一次网络请求)。
3. 请求服务端:POST /v1/systemone,timeoutMs = 60s,透传服务端错误码(model_not_allowed、request_too_long 等)。
4. 返回与记录:工具结果 { model, answers, usage, requestId };
- output.render 把结果渲染成分题 markdown 文本,写进会话日志(这是权威副本);
- 同时按 exec.callId 写入结果缓存(内存 + 落盘),供卡片使用。
5. 卡片渲染:Chat 渲染到该工具调用时挂载卡片,用 callId 取回结构化结果画条(见 3.3)。

3.3 卡片的数据从哪来

卡片不解析工具文本,而是按 callId 向 Host 要结构化结果:

- 工具执行成功时 rememberResult(exec.callId, value),并立即落盘(不再依赖防抖窗口);
- 卡片挂载后 GET /dsh-decision/result?callId=…。注意卡片可能在工具尚未执行完时挂载,这时 Host 还没有这份结果:因此卡片在 phase 变为 result 时重新请求,并在 miss 后 1.5 秒重试一次;
- Host 侧缓存 miss 时会重新读取磁盘(另一个进程或重载前写入的条目也能命中);
- 结果按 200 条 / 1 小时保留,并持久化到 $DSH_HOME/.dsh-decision-results.json,重启后历史卡片仍能回放;
- 仍取不到(过期 / 被淘汰)时显示「详细结果不可用 · call xxxx」,工具文本仍在会话里,所以不会丢信息;GET /dsh-decision/status 的 diagnostics.recentResultLookups 会记录每次查询是否命中。

3.4 设置页如何读写配置

读(三个来源,先快后慢,永远不会因为慢请求白屏):

1. 浏览器 localStorage 里上次的快照(dsh-decision.status.v1 / dsh-decision.usage.v1)—— 进页面立即渲染,不转圈;
2. GET /status —— Key 掩码前缀、默认模型、模型表、诊断信息(Host 端 20 秒复用,热时 3–80 ms);
3. GET /usage —— 今日请求/tokens 与每个模型的配额条(上游较慢,单独请求,到达后补进页面;Host 端同样 20 秒复用)。

后台请求返回后会替换屏幕上的缓存并回写 localStorage;请求失败时保留已有数据,只在下面补一行错误提示(不会把页面清空)。前端两个请求都带 15 秒超时。

写:

- 填写 Key → POST /config:Host 先用 /api/keys/self 验证该 Key,成功才 credentials.set;失败返回 400 与原因。
- 选择模型 → 同一个 POST /config:校验它在 /api/info 的模型列表里,然后原子写入 $DSH_HOME/.dsh-decision.json。
- 保存成功后 Host 使缓存失效并返回最新 status + usage,页面直接应用,不再多打一轮请求。

为什么拆成 /status 与 /usage:/api/info 冷启动要 4–5 秒、配额接口约 0.8–2.5 秒,而模型表/Key 状态是页面的主体。拆开后主体先出来,配额随后补齐;再叠加两级缓存(Host 20 秒 + 浏览器上次快照),重复进入设置页基本是瞬时的。

3.5 密钥与配置的解析顺序 text DECISION_API_KEY 环境变量 → DSH 凭据 DECISION_API_KEY(ctx.credentials.resolve,返回 { value, source }) → $DSH_HOME/.dsh-decision.json 的 apiKey(无 credentials 服务时的兜底写入位置)

默认模型每次调用时读取(readSettings 有进程内缓存,写入后失效),所以改完设置立刻生效,不需要重启。

4. 什么时候触发

| 触发点 | 时机 / 条件 | 行为 | 失败退路 |
| decision_ask | 模型主动调用;工具描述说明"需要概率而非生成文本时使用" | 发一次 /v1/systemone,多题合并为一个请求 | 返回可读错误(无 Key / 超限 / 服务端错误码) |
| decision_info | 模型需要模型表、配额或服务状态时 | models 走 /api/info(缓存 10 分钟,无 Key 也可) | 返回错误文本 |
| 卡片挂载 | Chat 渲染该 decision_ask 调用时(打开会话、滚到该行、展开) | fetch /result?callId 一次 | 显示「详细结果不可用 · call xxxx」 |
| 设置页加载 | 打开 Settings → 决策模型 | 先用 localStorage 快照立即渲染,再 GET /status(Host 20s 缓存) | 保留旧数据 + 一行错误提示 |
| 设置页用量 | /status 到达后立刻发起 | GET /usage(上游慢,独立请求,12s 超时) | 保留旧用量;失败不阻塞页面 |
| 保存配置 | 点击「保存并验证」/「刷新」 | POST /config;「刷新」= 两个 GET 加 ?refresh=1 | 页面显示失败原因,不改动现有配置 |
| 结果落盘 | 每次工具成功返回后 800ms 防抖 | 原子写 ~/.dsh/.dsh-decision-results.json | 写失败只影响回放,不影响调用 |
| 客户端上报 | 仅异常:取数失败或卡片渲染崩溃 | POST /client-report | 无影响(fire-and-forget) |

注意:插件不改变模型的调度策略,也不会自动替 Agent 决策;是否调用 decision_ask 完全由模型根据工具描述与任务判断。

5. 如何实现

5.1 文件与职责

| 文件 | 职责 |
| index.js | Host:两个工具 + 五条同源路由 + Key/模型存储 + 媒体编码 + 结果缓存 |
| client.js | Client:settings.section 设置页 + tool.call.toolview 决策卡片 + 错误边界 |
| cordis.patch.yml | 插入 bundle 行(不写任何密钥) |
| locale/{zh,en}.json | Plugins 页显示的标题与描述 |
| icon.svg | 插件图标(决策分叉 + 概率条) |
| package.json | dsh.bundle.patch + dsh.client(platform: web) |

5.2 Host 端关键函数(index.js)

| 函数 | 作用 |
| apply(ctx) | 注册工具;ctx.inject(['webServer']) 等服务就绪后注册路由(冷启动竞态修复点) |
| registerTools(ctx) | ctx.tools.register 两个 ToolDefinition(parameters / output.schema / execute / render) |
| buildQuestions(raw) | 按题型校验 criteria,统计 box 题数量 |
| annotateConfidence(answers) | 按阈值给每题标 lowConfidence,并决定整次结果是否带 hint: "low-confidence"(模型与卡片共用) |
| buildMedia(list, kind) | 本地文件 → data: URL,按扩展名定 MIME、按大小上限拒绝 |
| apiRequest(ctx, opts) | 统一 fetch:超时 35s、X-API-Key、错误归一化(code/status/retryAfter) |
| resolveApiKey / saveApiKey | 三级解析与写入(见 3.5) |
| readSettings / writeSettings | $DSH_HOME/.dsh-decision.json 原子读写(0600) |
| rememberResult / recallResult | 结果缓存与持久化(防抖写、TTL 1h、上限 200) |
| buildStatus(ctx, {refresh}) | 设置页主体:Key 状态、模型表、limits、诊断信息;Host 端 20 秒复用 |
| buildUsage(ctx, {refresh}) | 配额与用量(独立慢请求,USAGE_TIMEOUT_MS = 4s),20 秒复用 |
| invalidateStatus / invalidateUsage | 保存配置后让两个缓存立即失效 |
| fetchInfo | /api/info,10 分钟缓存,失败时回退到上一份快照 |
| registerRoutes(ctx, webServer) | 五条路由与 ctx.effect 释放 |
| guardRequest(req) | 回环 Host + 拒绝 cross-site + Origin 与 Host 同源 |

工具注册形如: js
ctx.tools.register({
name: 'decision_ask',
description: 'Ask the Decision 3.0 multimodal decision models for calibrated probabilities: …',
parameters: { type: 'object', required: ['state', 'questions'], properties: { /* … / } },
output: {
schema: { / model / answers / usage / requestId / },
render: (_args, value) => [{ type: 'text', text: formatAnswers(value) }],
},
timeoutMs: 60_000,
isConcurrencySafe: () => true,
async execute(args, exec) { / 校验 → 媒体 → POST → 缓存 → 返回 / }, })

5.3 Client 端关键结构(client.js)

- 以 window.__ModuleLoader__.load({ id: '@xia-sc/dsh-decision', factory(require) }) 注册;inject: ['slots', 'locale']。
- 设置页:ctx.slots.inject('settings.section', () => ctx.slots.register({ name, id: 'dsh-decision', order: 60, label }, Component))。
- 卡片:ctx.slots.register({ name: 'tool.call.toolview', key: 'decision_ask' }, Wrapper),Wrapper 用 CardBoundary(错误边界)包住卡片。渲染失败时显示原因并上报,而不是整行空白。
- 卡片组件:callId → /result → 按 answer.type 渲染:
- choice:每个选项一行横向条(选中项用品牌色),右侧百分比;
- noul:单条「是」概率;
- score:每档概率条 + 期望值 + legend;
- box:四边百分比 + 置信度,confidence < 0.5 用告警色标注。
- 样式:只用 --dsw-alias- token(bg-layer-、border-l1、label-primary/secondary、brand-primary、state-warn/error-primary),类名统一 dsd- 前缀; 作为组件内 React 元素渲染,卸载即移除。
- 文案:ctx.locale.register('dsh-decision', { zh, en }) + 本地字典兜底。

5.4 路由与安全

- 全部 kind: 'exact',前缀 /dsh-decision/,Cache-Control: no-store。
- guardRequest:要求 Host 解析为回环地址(127.0.0.0/8、localhost、::1);拒绝 Sec-Fetch-Site: cross-site;有 Origin 时必须与 Host 同源。失败返回 403。
- 方法限定:status / usage / result 只允许 GET,config / client-report 只允许 POST,否则 405。
- 请求体上限 64 KB;响应从不包含 Key 原文,只有 sk-vsr-AbCd…xYz 这类掩码前缀。
- Key 校验放在写入之前,验证失败不落库。

5.5 可观测性

- GET /dsh-decision/status 的 diagnostics.recentRequests:最近到达的请求(方法 / URL / Host / Origin / Sec-Fetch-Site),用来区分「客户端没请求到」和「请求被拒」。
- diagnostics.clientReports:卡片取数失败或渲染崩溃时的客户端上报(正常渲染不上报,零噪音)。

6. 工具参数与返回 jsonc // decision_ask 参数 { "model": "vllm-sr/d3-flash", // 可选,省略用默认模型 "state": "要判断的文本,或写成文本的 JSON",
"images": ["C:\\path\\to\\photo.png"], // 可选,≤4 张;本地路径(png/jpeg/webp)或 data: URL
"videos": ["C:\\path\\to\\clip.mp4"], // 可选,≤1 个
"questions": {
"route": { "type": "choice", "instructions": "哪个团队处理?", "criteria": { "returns": "退换货", "billing": "账单", "technical": "技术" } },
"receipt": { "type": "noul", "instructions": "客户有收据吗?" },
"urgency": { "type": "score", "instructions": "多紧急?", "criteria": ["常规", "尽快", "今天"] },
"where": { "type": "box", "instructions": "火箭在哪里?" }
}
}

| 题型 | criteria | 答案字段 |
| choice | 选项对象(≥2 项,值为描述或 null) | choice + probabilities + confidence |
| noul | 可选 {"false": "...", "true": "..."} | noul(是概率) |
| score | 有序档位数组(2–10 项) | score(期望档位)+ probabilities + legend + confidence |
| box | 无(靠 instructions 描述目标) | box{top,left,bottom,right} + confidence |

返回给模型的结构化结果:{ model, answers, usage, requestId };同时渲染成分题 markdown 文本(概率降序、confidence、legend、错误题原样展示)。

低置信标注(阈值由 Host 统一计算,模型与卡片共用同一套判断):

| 题型 | 判定为低置信 |
| choice | 最高概率 < 0.6,或 confidence < 0.5 |
| score | confidence < 0.5 |
| noul | noul 落在 0.4–0.6 之间 |
| box | confidence < 0.5 |

命中时:

- 该题返回 lowConfidence: true(照常带 probabilities / confidence);
- 整次结果额外带 hint: "low-confidence";
- 文本渲染在该题标题后加一行 ⚠ low confidence,并在末尾加 hint: low-confidence — …;
- 对话卡片给对应题标「低置信」;
- decision_ask 的工具描述要求模型此时不要把 argmax 当作结论:说明证据不足,或用更清晰的措辞 / 更多选项 / 更强模型(d3-turbo、d3-ultra)重试。

decision_info 的 action:models(模型与 limits)、usage(今日配额与 p50/p90 延迟)、status(模型实时状态)。

7. 服务端限制

state ≤ 32000 字符 · ≤ 64 题 · ≤ 4 图(每图 ≤ 8 MB)· ≤ 1 视频(≤ 32 MB)· 请求估算 token ≤ 131072 · 单请求 30 秒超时。

超过时服务端返回 400 与具体错误码(如 request_too_long、box_needs_image、too_many_questions);部分题型限制随模型不同(d3-turbo 支持 16 图、131072 字符 state)。

7.1 性能实测(2026-10-27,本机直连服务端)

每次先跑 1 次不计入预热,随后顺序执行;文本题 5 次、box 题 3 次。

| 场景 | 模型 | 平均 | 中位 | p90 | 最大 | 输入 tokens |
| 短文本 / 1 题 | d3-edge | 298 ms | 299 | 302 | 307 | 102 |
| 短文本 / 1 题 | d3-ultra | 306 ms | 304 | 311 | 321 | 119 |
| 短文本 / 1 题 | d3-nano | 331 ms | 303 | 306 | 462 | 102 |
| 短文本 / 1 题 | d3-turbo | 336 ms | 336 | 352 | 360 | 102 |
| 短文本 / 1 题 | d3-lite | 375 ms | 298 | 317 | 679 | 102 |
| 短文本 / 1 题 | d3-mini | 380 ms | 312 | 318 | 667 | 102 |
| 短文本 / 1 题 | d3-flash | 385 ms | 319 | 326 | 670 | 102 |
| 长文本 / 3 题(约 1200 字符) | d3-flash | 320 ms | 321 | 321 | 356 | 588 |
| 图片 box(1 张) | d3-flash | 1664 ms | 1558 | 1558 | 1946 | 20769 |
| 图片 box(1 张) | d3-turbo | 377 ms | 380 | 380 | 383 | 442 |

结论:

- 文本决策的延迟与模型大小基本无关:7 个模型都在 ~300 ms 量级(平均 298–385 ms),差异小于尾部抖动(p90 到 ~680 ms),主要由网络与排队决定。选型应按准确率(官方 Jev Decision Index)而不是按速度。
- 图像定位差异巨大:d3-flash 没有原生 box 输出,用 65 个 noul 子问题做 grid scoring(约 2 万输入 tokens、1.5–1.9 s);d3-turbo 有原生 box 输出(442 tokens、~0.38 s)。box 题优先 d3-turbo / d3-ultra,又快又省 token 配额。
- 工具默认 timeoutMs = 60s 对上述场景都很宽裕;真正需要预留时间的是"多题 + 大图/多图"。

复测(脚本在 .bench/,不参与打包,只读凭据、不打印): powershell

所有文本模型的短文本延迟

$env:N = '5'
node .bench/latency.mjs vllm-sr/d3-flash vllm-sr/d3-mini vllm-sr/d3-turbo vllm-sr/d3-ultra

长文本 3 题 + 图片 box(flash 对比 turbo);需要 .bench/test.png

node .bench/probe2.mjs

.bench/test.png 可用 Pillow 重新生成:640×480 米白底,左侧红圆(80,90–300,310)、右侧蓝方块(380,150–570,340)。

8. 排查

| 现象 | 先看 |
| 设置页「请求失败:HTTP 404/405」 | 路由没注册(ctx.inject(['webServer']) 竞态),重载插件;GET /dsh-decision/status 直接验证 |
| 设置页用量显示「用量查询超时」 | 上游配额接口慢;其它数据不受影响,点「刷新」重试 |
| 设置页首屏仍是旧数据 | 正常:先显示 localStorage 快照,几十毫秒后会被新数据替换(底部有「正在刷新…」提示) |
| 设置页显示未配置 Key | diagnostics 与 ~/.dsh/.credentials.yaml 的 refs.DECISION_API_KEY |
| 工具报 No Decision API key configured | 同上;或环境变量未生效 |
| 卡片显示「详细结果不可用 · call xxxx」 | 该 callId 的结果已过期/被淘汰(1 小时、200 条),工具文本仍在会话日志里 |
| 卡片渲染异常 | 卡片会显示「决策卡片渲染失败:…」,并出现在 diagnostics.clientReports |
| 调用返回 403 model_not_allowed | 模型 id 不在 /api/info 列表(如 vllm-sr/d3 是 d3-turbo 别名) |
| 调用返回 429 | 每分钟额度或并发限制;看响应 Retry-After |

9. 已知边界

- 卡片数据依赖 Host 的结果缓存(200 条 / 1 小时,已持久化);超出后回放失败,但工具文本永不丢失。
- 设置页的即时感依赖浏览器 localStorage 快照(status / usage 各一份,24 小时过期)与 Host 端 20 秒缓存;换浏览器、清缓存或很久没打开时,首次进入仍会走一次网络(模型表 4–5 秒、配额 1–3 秒)。
- 服务端可能记录请求与响应(见官方 Logging 章节),不要发送敏感数据。
- 视频只作为普通题的输入(noul / choice / score),不产生轨迹(track);box 只有 d3-turbo / d3-ultra / d3-flash 支持。
- 插件不导出 Config:参数在设置页与 $DSH_HOME/.dsh-decision.json 管理,不引入 schemastery 依赖。
- 卡片渲染在工具调用行内(不在助手正文里),历史会话需要滚到对应调用处。

10. 兼容性

10.1 运行环境

| 项 | 支持范围 | 说明 |
| DeepSeek Harness | 0.2.x(实测 0.2.1-rc.3) | 依赖的扩展点见 10.2;更早版本未验证 |
| Harness 形态 | Web GUI(dsh web 或桌面应用的渲染进程) | Host 工具与 /dsh-decision/ 路由在 Host 进程;设置页与卡片需要 Client slots |
| TUI / headless / ACP | 部分支持 | 工具、路由、密钥/模型存储可用;设置页与卡片不渲染(没有 slots),Key 用环境变量或 $DSH_HOME 文件配置 |
| Node.js | ≥ 18(宿主运行时,实测 Node 26) | 用全局 fetch、AbortController、performance.now,无原生依赖 |
| 操作系统 | Windows(实测)/ macOS / Linux | 无平台特定代码;路径走 node:path,媒体按扩展名转 data: URL |
| 浏览器 | Chromium / Firefox 现代版 | 只用 fetch、CSS 变量(--dsw-alias-)、localStorage |
| npm(发布) | ≥ 9 | 发布走 .github/workflows/publish.yml,见 10.5 |

10.2 依赖的 Harness 扩展点

| 扩展点 | 用途 | 缺失时的行为 |
| ctx.tools.register | 注册 decision_ask / decision_info | 插件不激活(inject: ['tools']) |
| ctx.inject(['webServer']) + webServer.register | 五条同源路由 | 工具可用,设置页/卡片报 404 |
| ctx.credentials | Key 存 DECISION_API_KEY | 回退到环境变量或 $DSH_HOME/.dsh-decision.json |
| ctx.slots(settings.section、tool.call.toolview) | 设置页与卡片 | 只影响 UI,不影响工具 |
| window.__ModuleLoader__ | Client bundle 注册 | 同上 |
| --dsw-alias- 主题 token | 样式跟随主题 | 回退为基础样式,不崩 |

10.3 Decision API 依赖

| 能力 | 端点 / 字段 | 必需 |
| 决策请求 | POST /v1/systemone(/v1/decisions 同义) | 是 |
| 模型表与上限 | GET /api/info | 是(模型下拉、limits) |
| 配额与用量 | GET /api/keys/self、/api/keys/self/usage | 否(失败只影响用量区) |
| 服务状态 | GET /api/status | 否(decision_info action=status) |
| 鉴权 | X-API-Key 或 Authorization: Bearer | 是 |
| 题型 | choice / noul / score | 全部模型 |
| 题型 | box | 仅 d3-turbo / d3-ultra / d3-flash(其余返回 box_unsupported) |
| 媒体 | 图片(PNG/JPEG/WebP)、视频(MP4/WebM/MOV/MKV) | 可选 |

10.4 版本矩阵

| 插件版本 | Harness 版本 | npm | 说明 |
| 0.1.x | 0.2.x(rc 系列) | @xia-sc/dsh-decision | 当前版本:五条路由、双层缓存、卡片错误边界 |
| < 0.1.0 | — | — | 不存在(早期仅在本地以 @local/dsh-decision 链接安装) |

升级约定:插件小版本只加能力,不改 decision_ask 的参数形状;answers 字段跟随上游 API。

10.5 发布与安装形态

| 形态 | 命令 | 适用 |
| 本地目录(开发) | plugin_manager install_bundle target=<绝对路径> | 改代码即时生效(link) |
| npm 包 | plugin_manager install_bundle target=@xia-sc/dsh-decision | 分发、多机安装 |
| 发布 | push v* tag → GitHub Actions | 见 .github/workflows/publish.yml |

发布到 npm:0.1.0 已由本地发布(2026-10-27),之后的版本交给 .github/workflows/publish.yml。workflow 有两条凭据路径,任选其一:

- A. NPM_TOKEN secret:npmjs.com 建 token(granular:scope @xia-sc、Read and write、勾选 Bypass 2FA;或 classic Automation token),加到仓库 Settings → Secrets and variables → Actions → NPM_TOKEN。
- B. Trusted Publishing(OIDC,无 token,带 provenance):包已存在后,在 npm 包页面 Settings → Trusted publishing 添加 GitHub:repository xia-sc/dsh-decision、workflow file publish.yml。workflow 已带 id-token: write 且会升级到 npm ≥ 11.5。

发版流程: bash
npm version patch # 0.1.0 → 0.1.1,自动 commit 并打 v0.1.1 tag
git push origin main --tags # 触发 workflow:preflight → 校验 tag 与版本一致 → 发布

workflow 的行为:

- tag 与 package.json 版本不一致 → 直接失败(不发布);
- 该版本已存在于 npm → 输出 notice 并跳过发布(所以给已发布版本补 tag 不会产生失败记录);
- 没有任何凭据(既无 NPM_TOKEN 也未配 Trusted Publishing)→ 发布步骤失败,日志会写明认证错误。

scripts/preflight.mjs 会在发布前检查:必需文件齐全、包名是 @xia-sc/dsh-decision、private 未开启、publishConfig.access = "public"、client.js 的 module id 与包名一致、无 API Key / 本机路径、两个 JS 文件语法正确。

10.6 已知不兼容 / 限制

- TUI / headless / ACP:没有 Client slots,设置页与卡片不出现;decision_ask、decision_info 与路由照常可用。
- 桌面端(Electron):改 Client bundle 后必须整页重载(Ctrl+R)或重启应用;只重载 Host 不会刷新前端。
- Harness < 0.2.0:ctx.inject 的用法与 slot 名称可能不同,未验证。
- 插件不注册任何 slash command、不改 agent preset,也不注入 system prompt。
预览分享卡片长什么样 ↓xia-sc/dsh-decision
分享 · DeepSeek Harness Hub
xia-sc/dsh-decision

让智能体用校准概率回答选项、打分与定位问题

这是你的仓库?认领条目

回到顶部