dsh-web-search-pro-plus

DSH PLUGIN记忆与知识

仓库 AlbertZJ/dsh-web-search-pro-plus

记忆与知识 L4 · 沙盒安装通过 安全审查:低风险 可信度:银 可安装插件
安装这个插件

dsh-web-search-pro-plus 是 AlbertZJ 维护的 记忆与知识 类 DSH 可安装插件, 仓库为 AlbertZJ/dsh-web-search-pro-plus,许可证 MIT。 下面按「装什么、怎么装、验没验过、跑起来要注意什么」逐项列出。

一句话选型结论

按资料字段整理

dsh-web-search-pro-plus 是记忆与知识类的 DSH 可安装插件,验证等级 L4 · 沙盒安装通过,安全审查为低风险,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类记忆与知识 收录类型可安装插件 验证等级L4 · 沙盒安装通过 安全审查低风险
验证等级 L4 L4 · 沙盒安装通过
GitHub 星标 0 复刻 0 · 未关闭 issue 0
最近更新 2026-10-27 创建于 2026-10-27
README 84.7 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:AlbertZJ/dsh-web-search-pro-plus
  1. 1
    确认版本与运行环境

    仓库没有标注兼容版本与 Node.js 要求,先确认你的 DSH 版本能装,再继续。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本未标注版本不匹配时安装会报错
Node.js 要求未标注来自仓库 package.json 的 engines 字段
前置依赖无需要同时安装的同级依赖
npm 包名未发布到 npm可用 npm view 查看包信息

能做什么

记忆与知识
字段来自项目仓库与公开索引,中文说明由本站标注

适用场景

联网搜索

上游标签

deepseek-harnessdshdsh-pluginpluginsearchtypescriptweb-searchwindows

验证等级与安全审查

L4 · 沙盒安装通过
自动化流程结论,不是人工审核
验证等级L4 · 沙盒安装通过安装命令在隔离沙盒内真实执行成功,无依赖错误
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度银综合仓库活跃度与验证结果

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L4:在沙盒里真实装过,依赖能装上,不是纸面声明。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。

先想清楚的地方

  • 没有声明 Node.js 版本要求,版本不匹配可能装不上。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在记忆与知识场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-web-search-pro-plus当前 L4 · 沙盒安装通过 低风险 0 未标注 有
ruflo L3 · 安装规范通过 低风险 7.4 万 未标注 无
OpenViking L3 · 安装规范通过 低风险 3.9 万 未标注 无
WeKnora L4 · 沙盒安装通过 低风险 3.3 万 未标注 有
distilly L4 · 沙盒安装通过 低风险 2.5 万 未标注 有
EverOS L4 · 沙盒安装通过 低风险 1.3 万 未标注 有

仓库档案

记忆与知识
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方AlbertZJ仓库 dsh-web-search-pro-plus · 默认分支 main
分类记忆与知识knowledge
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言未标注仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue0 / 0 / 0收录时的数值,非实时
创建 / 更新2026-10-27 · 2026-10-27最后推送 2026-10-27
本站收录2026-10-30首次进入本站目录的时间

README 全文

84.7 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-web-search-pro-plus

增强型、可持久化的扩展网页搜索插件 for DeepSeek Harness(DSH)。

一个 DSH bundle 插件,把多引擎网页搜索、持久化缓存、抓取与证据管线打包成模型可调用的能力。常驻上下文只有 web_index / web_call 两个工具(原 11 个 web_* 工具已并入 20 个动作,见工具面)。路由控制面借鉴 Agent-Reach 的后端探测、顺序选择和失败冷却思路,核心逻辑为本项目原生 TypeScript 实现。

本项目是 anweat/dsh-web-search-pro 的派生版本:搜索核心与上游一致,针对 dsh-v0.2.1-rc.2 调整 peer 范围,并修复了在 Windows 上运行测试的路径与清理问题。浏览器相关能力在本宿主版本上不可用(原因见下)。上游版权与归属见 NOTICE。

兼容与发布通道

插件发布通道 DSH 基线 兼容承诺
0.2.1-r1(本仓库) 只支持 dsh-v0.2.1-rc.2 这一条线(peer >=0.2.1-rc.2 <0.2.2-0) 派生版本;774 项单元测试(745 pass / 29 skip / 0 fail)、94 项 bench 测试、pnpm run test:peers 两种解析模式检查、类型检查、构建与客户端 bundle 检查均通过。浏览器能力不可用

支持范围:DSH >=0.2.1-rc.2 <0.2.2-0。这是唯一验证过的宿主基线;更早的 0.2.0 线与 0.2.1 的前序预发布都会被拒绝。

浏览器能力不可用:上游配套的 @anweat/dsh-browser 0.2.0 自身 peer 范围是 >=0.2.0-rc.2 <0.2.1-0,在 0.2.1-rc.2 宿主上无法安装,本派生也不 fork 它。因此:

  • 不要在本 profile 里安装或升级 @anweat/dsh-browser;
  • read.snapshot、read.fetch mode=playwright、浏览器平台与 OpenCLI 平台会返回 CAPABILITY_UNAVAILABLE;
  • read.fetch mode=auto 只走 HTTP/CLI 后端,不尝试浏览器渲染;
  • 其余搜索、抓取(HTTP)、证据管线、缓存、历史功能照常工作。

peer 范围的写法:

  • 宿主的组装期校验用的是 semver.satisfies(host, range, { includePrerelease: true });真正决定装机成败的是 npm/pnpm 的默认 semver:预发布版本只有在某个比较符自带同号(同 major.minor.patch)预发布时才被判为满足。>=0.2.1-rc.2 自带 0.2.1 的预发布,是承重的,必须保留;把下界写成别的版本线会过宿主校验、却让 dsh plugin add 报 ERESOLVE。
  • 上界是 <0.2.2-0 而不是 <0.2.2:后者放行 0.2.2-alpha.1 这类预发布。收口后,若 0.2.2 真出现破坏,会在组装期直接报 is incompatible with dsh 0.2.2 并点名。
  • 范围只表示「测过哪些」,不等于承诺不破坏。pnpm run test:peers(已并入 pnpm verify)用两种解析模式逐个断言受管 peer:0.2.1-rc.2 必须通过,0.1.7-rc.2、0.2.0-rc.2、0.2.1-rc.1、0.2.2-alpha.1 必须被拒绝;并自带 --selftest 已知行为自校验。

安装

本仓库尚未发布到 npm,直接从 GitHub 或本地目录安装:

# GitHub(推荐):
dsh plugin --profile web add github:AlbertZJ/dsh-web-search-pro-plus
# 或本地目录(先在仓库内 pnpm install && pnpm build):
dsh plugin --profile web add ../dsh-web-search-pro-plus
# 重启(web profile 关闭了 HMR):
dsh --profile web

> 本插件必须是 profile 的直接依赖:DSH 只激活直接依赖的 bundle layer。标准 profile 可能设置 autoInstallPeers: false,不要依赖 peer 自动补齐。
> 若你的 harness 是本地源码 checkout,版本号可能有出入——用 dsh plugin --profile web add ./,并在 profile 的 pnpm-workspace.yaml 里对齐依赖后重装。
> 安装/更新带客户端面板的插件版本后需要完整停止并重启 Web profile,仅刷新网页不会重新扫描 client.js。

从上游版本迁移

本包名是 dsh-web-search-pro-plus,与上游 dsh-web-search-pro 并存,不是原地升级。迁移时先移除上游包,再安装本包;web-search-pro: 配置段与已存储数据(历史、页面、规则、证据、账本)保持兼容:

dsh plugin --profile web remove dsh-web-search-pro
dsh plugin --profile web add github:AlbertZJ/dsh-web-search-pro-plus
dsh --profile web

> 不要安装 @anweat/dsh-browser:它的 peer 范围不包含 0.2.1-rc.2,会让安装失败;即使装上了,本插件也不会驱动它。浏览器相关动作会返回上面的 CAPABILITY_UNAVAILABLE。

> 破坏性变更(工具面):旧的 web_search_pro、web_fetch_pro 等 11 个工具名不再注册,也没有兼容包装。旧会话里对它们的调用会失败;把调用改成对应动作即可,对照表见旧工具到新动作。模型在 web_call 里写旧工具名会得到新动作名和翻译后的参数,web_index() 根目录也列出同一张对照。已存储的数据(历史、页面、规则、证据、账本)与 ctx.web provider 不受影响。其他不兼容变化与新功能见 CHANGELOG.md。

升级完成后需要完整停止并重新启动 Web profile;仅刷新网页不会重新扫描插件的 client.js。随后依次检查:

  1. browser_call({action:"runtime.status"}):确认 OpenCLI、playwright | patchright 运行时、automationMode 与 usagePolicy 符合预期。
  2. web_call({action:"sources.status"}):确认搜索、CLI、Agent Reach 与浏览器后端是否 ready(浏览器应显示 ready,不是 legacy (unsupported))。
  3. 打开 插件 → 已安装 中两个 bundle 各自的详情页,确认配置表单都已加载;浏览器表单负责自由度、运行时、OpenCLI 与调用缓冲。

> automationMode 和防止过度调用的 usagePolicy 都属于 dsh-browser,升级不会自动改写现有配置。生产 profile 建议保留 standard;unrestricted 只用于隔离的自动化测试 profile,并且仍受并发、突发、页数/深度和 429/503 退避保护。

若 Clash/TUN 使用 fake-IP DNS,原生 HTTP 后端可能看到 198.18.0.0/15、fdfe:dcba:9876::/64 或 2001:2::/48(报错信息会直接提示 resolved to proxy fake-IP …)。可在可视化面板的高级设置中启用 allowProxyFakeIp;默认关闭。该开关只信任这些代理网段的 DNS 解析结果,字面 fake-IP URL、localhost 和其他私网地址仍会被 SSRF 防护拒绝。

快速使用与适用情形

安装并重启后,直接在 DSH 会话里要求模型调用工具即可:

请先用 web_call 的 sources.status 检查后端,然后用 search.run 搜索
"DeepSeek Harness community feedback",指定 exa、fresh=true、返回 8 条来源。

开箱默认值(不改任何设置):默认关闭 Jev(evidence.jevMode: off,证据评分用本地规则,不调用任何模型,也不需要任何模型 Key);只有配置了博查 Key(bochaApiKey / BOCHA_SEARCH_API_KEY 或凭据引用)才会使用博查,没配置时博查不在引擎列表里,也不会被自动规划选中。默认引擎是 seam、exa、ddg、bing、jina(Exa 可走无 Key 的 MCP 回退,ddg / bing 免 Key)。Defaults out of the box: Jev is off by default (evidence.jevMode: off; evidence scoring uses the local rules and no model is called, no model key is needed); Bocha is used only when you configure a key (bochaApiKey / BOCHA_SEARCH_API_KEY / a credentials ref) — without one it is not in the engine list and never planned.

模型通常不需要先翻目录:web_index() 根目录直接给出搜索与读取两个最常用调用,随包的 skill dsh-web-search-pro 带有证据模式的工作示例;没有 skill 服务时根目录附一段精简指南。

情形 推荐入口 说明
日常网页搜索 search.run 默认按配置顺序回退;需要强制刷新时传 fresh=true
语义研究、社区观点 search.run + engines=exa 有 API Key 时走原生 Exa API;只有 Exa MCP 连接时自动经 mcporter 回退
已知 URL 的批量正文 read.contents 直接调用 Exa /contents,必须配置 EXA_API_KEY
GitHub/B站/Reddit 等平台 search.run + platform=… Reddit 等 OpenCLI 平台需要 Chrome 扩展在线;中文受限站点使用 AuthProfile
登录后页面或私有论坛 browserBindings + AuthProfile Cookie 保存在本地 storageState,按域名授权,默认只读
页面改版、懒加载 platformRules 或 RulePack 优先改选择器;需要等待/点击/滚动时再使用有界 RulePack
模型生成多步页面操作 browser_call → automation.run_recipe 只读步骤直接运行;页面交互按 dsh-browser 的 automationMode 决定拒绝/审批/直通
外部模型生成油猴脚本 script.validate → script.run_userscript 强制 @match、@grant none、禁用 @require;仅 unrestricted 跳过审批
有限泛爬取 crawl.crawl 匿名、默认同源;调用参数不能突破浏览器插件的页数/深度预算
OpenCLI 站点适配器或浏览器桥 opencli.status → opencli.catalog → opencli.run 先发现精确 adapter;仅 unrestricted 跳过通用 argv 审批

平台来源

每个平台(GitHub、GitHub 代码 / Issues、B站、YouTube、V2EX、arXiv、PubMed、小红书、Twitter / X、Reddit、Instagram、Facebook、RSS、知乎、微博、豆瓣、贴吧、抖音、快手,以及你的 customPlatforms)都是来源注册表里 kind: platform 的 provider:有描述符(语言、任务类型、站点域名、所需浏览器能力 / 登录 / CLI / Token)和适配器,与网页引擎走同一条路径(探测、冷却、并发合并、shapeSources、重试说明、历史)。每个平台是一个 provider,内部是一条有序的后端链(独立 CLI → 独立 OpenCLI → dsh-browser 的 OpenCLI / 搜索页),顺序可用 platformBackends 改,详见下面的 CLI 适配。sources.status 在同一张列表里按维度报告它们的就绪状态(浏览器安装、已绑定登录、设置开关);目录条目用 provider 指向同名 id。

  • search.run platform=zhihu query=… 只搜这个平台,历史类型仍为 platform;engines=zhihu 在经典搜索里同样可用。url(RSS)、authProfile、rulePack 随 platform 传,browserBindings 补全后两者。
  • 证据模式:platform 可与 task / profile / needs / constraints 同用——该平台成为 S1 / S2 的显式来源,之后门限、读取前几页(有 Browser 时自动升级)、评分、证据包照常。
  • 平台不可用(缺浏览器 / 登录 / CLI / Token、被设置关闭、冷却中)时返回 CAPABILITY_UNAVAILABLE,写明缺什么,并附目录里的安装说明;不会悄悄改搜网页引擎。传 allowFallback=true 才改搜该 profile 的网页引擎,证据包的 notes 会写明。平台已运行但没有结果时返回空列表和平台自己的提示(多半是缺登录),不冷却。
  • 自动规划:平台从不被自动选入第一轮;只有任务带硬 site 约束且命中某平台域名(如 zhihu.com)并且该平台就绪时,它才排第一,并保留一个网页引擎做回退(同一上游家族只取一个,其余留给第二轮)。平台没就绪就沿用网页计划并在 notes 说明。search.recommend 对 experience 类任务可以推荐已就绪的平台(仍至多 3 个)。
  • 自定义平台随设置热更新:新增、修改、删除都会同步注册表;与已有 provider 同名的键不会覆盖内置来源,sources.status 的 notes 会列出被拒绝的键。

先运行 sources.status 判断后端是否 ready(要不要用哪个来源,直接问 search.recommend)。指定单一引擎时失败会原样返回;不指定时才会按 engines 顺序自动回退。所有引擎都返回空结果或不可用(没有运行时错误)时,search.run 返回空结果和说明,不再报错。

两种用法

同一套证据管线有两个入口。模型是否走哪一个,取决于它看到哪些工具;第二种能在模型“顺手用内置 web_search”时仍然让证据管线生效。

(a)直接调用 web_call search.run。 模型加载 skill dsh-web-search-pro(或按常驻提示)调用 search.run,传 task / profile 得到证据包(见下节)。常驻提示和 skill 描述都写明:做网页研究时优先用它,而不是 web_search + web_fetch,因为它只返回过滤后的证据,占用的上下文少得多;读页用 read.fetch(长页用 offset 续读)。

(b)让宿主内置的 web_search / web_fetch 经过本插件。 宿主自带这两个工具,模型常常直接用它们(实测 DeepSeek 在自然任务里就是这样,绕过了 web_index)。把本插件注册并选中为 ctx.web 的 provider 后:

  • web_search 的返回内容 = 本插件的证据包(与 search.run 同一渲染:resultId、缺口 Gaps、“覆盖是启发式的”提示,末尾一行说明可用 web_call history.expand / read.fetch 展开),sources 仍是来源列表;truncated 只在确有来源被截掉时为真。查询即任务(task = query,needs = [query],profile 按规则推断,推断不出为 general,预算为默认值)。
  • 证据运行有自己的期限(provider.deadlineMs,默认 25 秒;到点返回 PARTIAL 的已有结果)。超时、管线报错都退回今天的普通来源列表,不会让内置工具失败;只有调用方取消会原样抛出。为避免递归,这条路径不会再调用 ctx.web 引擎(seam)。
  • web_fetch 沿用同一套抓取管线,上限是 fetchDefaultChars 的两倍;被截断时 truncated 为真,并在正文末尾追加一行 [Continue with web_call read.fetch url=… offset=N]。
  • provider.evidence: off 让 web_search 回到只返回来源列表(与旧行为完全一致)。

怎么选中(宿主的规则,不是本插件的)。 @deepseek-ai/dsh-web 只在两种情况下使用某个 provider:web 条目里写明了它的 id(searchProvider / fetchProvider,环境变量 DSH_WEB_SEARCH_PROVIDER / DSH_WEB_FETCH_PROVIDER 与它们是同一个字段,不是另一条优先级链),或它是唯一可用的已注册 provider。没写 id 又有两个可用 provider 时,每次 web_search 都会以 WEB_PROVIDER_AMBIGUOUS 失败。所以 registerProvider 默认是 false:只注册、不选中是无害的,但默认注册会在没有写 id 的部署里让内置工具直接报错,本插件不会悄悄接管宿主默认 provider。

  1. settings.yaml 的 web-search-pro: 段打开注册(启动时生效,改完重启):
web-search-pro:
registerProvider: true
providerId: web-search-pro # 默认值;与下面的 id 必须一致
provider:
evidence: auto # auto(默认)| off
deadlineMs: 25000
  1. 在 profile 的 cordis.patch.yml($DSH_HOME/profiles//cordis.patch.yml)里把 web 条目指向它:
- id: web
name: '@deepseek-ai/dsh-web'
config:
searchProvider: web-search-pro
fetchProvider: web-search-pro # 只想换搜索、保留宿主抓取时,写宿主抓取 provider 的 id(宿主源码里内置的是 `http`,以所用宿主版本为准),不要省略

或者只在启动环境里设 DSH_WEB_SEARCH_PROVIDER=web-search-pro(需要时再加 DSH_WEB_FETCH_PROVIDER)。配置里的值与环境变量同时存在时以配置为准。不要只注册而不写 fetchProvider:本插件会同时注册搜索与抓取两个 provider,若宿主的 web 条目没有固定抓取 provider,宿主自带的 http 与本插件的会同时可用,web_fetch 会报 WEB_PROVIDER_AMBIGUOUS。

  1. 重启后用 web_call sources.status 检查:ctx.web route 一行会写明是否已注册、web_search / web_fetch 当前是否选中本插件、宿主固定的是哪个 id(未选中时还给出上面的配置提示)。宿主不暴露 provider 状态查询接口,所以本插件读的是 web 运行时已合并好的 id(读不到时只看环境变量,并在状态行里注明)。

和其他“联网调研”skill 并存。 用户自己安装的 skill(例如 agent-reach)也可能在描述里声称负责联网调研;本插件的 skill 描述只陈述自己做什么(中英文触发词:联网搜索 / 查证 / 调研 / 读取网页,web research / look up / verify / read a page),不声称对其他 skill 的优先权,也无法阻止模型选别的 skill。(b)正是为这种情形准备的:不管模型加载了哪个 skill,只要它最终调用内置 web_search / web_fetch,走的就是本插件的证据管线。

证据包模式(search.run 传 task 或 profile)

传 task(一句话目标)或 profile(docs_code / news_fact / academic / experience / compare / general)时,search.run 不返回结果列表,而是按 profile 选择来源(docs_code:ddg/bing/github;academic:arxiv/pubmed/ddg;experience:ddg/bing/v2ex;news_fact:ddg/bing;compare:ddg/bing/github;general:配置的 engines;显式 engines 优先),读取前 4 个保留候选的页面,分块并按每个需求评分,在字符预算(默认 6000,budget 可调)内挑出摘录,并列出未被满足的需求(gaps)。可选参数:needs(; 分隔或 JSON 数组)、constraints(JSON 数组 {kind,value,strength};strength 缺省为 soft,hard 只在确定违反时才丢弃候选)。输出新增 resultId、evidence、coveredNeeds、gaps、partial 等可选字段,原有 sources 仍在;超过总时限(timeoutMs + 30 秒)时返回 partial: true 的已有结果。history.expand 传 evidenceId 可读回摘录所在块及其前后块(至多 4000 字符)。不传 task / profile 时行为和输出与以前完全相同。

相关度门(S4):需求与候选标题/摘要语言不同(如中文需求对英文结果)时,门限判断改用跨语言对齐(需求、query、目标与实体/必含词里的拉丁词一并参与匹配),同语言保持原有的词法规则;若门限之后保留的候选少于 3 个而更多候选存在,则按融合排序补回最靠前的、未违反硬约束的候选,标为“低相关”(sources[].lowConfidence / evidence[].lowConfidence,渲染为 (low relevance),stats.lowConfidence 计数,并在 notes 说明),不会因为相关度启发式而返回空包。

有界第二轮(S8):第一轮之后若有关键需求(critical)没有被满足(gaps 里原因不是 budget),且轮数、查询数、时间都还有余量,管线最多再补搜一轮:以“需求文本 + 任务里的关键实体(entity / must_term / version 约束与 query 里的标识符)”为查询,按各 provider 编译(站点约束等照常下推),优先用第一轮没用过的 provider,其次复用已回答的;只读取新候选里最好的至多 2 页,只对缺口需求评分,再与第一轮结果合并(按 URL 去重)重新挑选。单任务查询总数(一次 provider 调用算一次,GitHub 的放宽重试合并算一次;允许第二轮时第一轮至多用 maxQueries-1 个 provider,留一次给第二轮,显式 engines 不裁剪)不超过 evidence.maxQueries(默认 4),轮数不超过 evidence.maxRounds(默认 2,设 1 即关闭);剩余时间不足 15 秒或预算已用完时跳过并在 notes 说明。证据包 stats.rounds / stats.queries 给出实际轮数与查询数。

块评分默认用本地词法规则。可选的博查 Jev 评分(付费,需环境变量或凭据引用 BOCHA_JEV_API_KEY)由 evidence 配置控制:jevMode: off(默认,不调用)、shadow(规则决定,Jev 评分只记录到存储 evidence_runs.pack_json 供对照)、control(且 scorer: jev 时由 Jev 决定;任何 Jev 失败都回退到规则并在 notes 里说明)、hybrid(规则评分全部块,Jev 只重评需求语言与块语言不一致的 (需求, 块) 对;hybridBorderline: true 时再加规则评分为 1 的边界对;Jev 失败保留规则评分;与 scorer 无关);maxJevQuestions(默认 64)限制每次搜索发送的 (需求, 块) 问题数。规则评分本身对中文需求与英文块做了跨语言对齐(query / 需求 / 约束里的英文词和标识符并入匹配词),默认即生效。发给 Jev 的只有一句话目标、需求文字和页面块文本。

Jev 提示词(rubric):可配置、有版本 / Judge prompts: configurable and versioned

中文 发给 Jev 的问题措辞、评分等级和长度上限是带版本的 rubric(内置 score.support,另有 gate.relevance、gate.constraint 备用)。默认值与离线评测(bench/rubrics/*.v1.json)逐字相同。要调整,在设置文件 evidence.rubrics 里按 rubric id 写覆盖项,无需改代码:

evidence:
jevMode: hybrid
rubrics:
score.support:
version: v2                     # 必填;内容有改动就必须换新版本号(不能是 v1)
instructions: |                 # 只能用 {task} {need} {candidate};必须含 {need} 和 {candidate}(≤2000 字符)
文本块本身是否直接陈述了需求所问的答案,而不只是提到该主题?
需求:{need}
文本块:{candidate}
criteria: [无关, 只提到主题, 部分回答, 直接回答且含证据]   # 2–10 级,从低到高;不是 4 级时分数按比例换算到 0..3
maxStateChars: 200              # 20–2000,任务描述上限
maxCandidateChars: 1200         # 100–8000,每个文本块上限
  • 校验与回退:含未知变量、缺必需变量、等级数不在 2–10、长度越界、未换版本等,整条覆盖被忽略,改用内置版本;原因出现在 sources.status 的 evidence.diagnostics 和证据包的 notes(仅启用 Jev 时)。
  • 版本规则:改了措辞、等级或长度就换新 version(如 v2、v3)。每次 Jev 评分都记录 id@version#内容哈希:证据包 stats.jev.rubric、shadow 日志(evidence_runs.pack_json 的 shadow.rubric)、证据行(evidence_blocks.rubric);离线评测的缓存键同样包含 id、版本和全文,所以改提示词不会复用旧分数。
  • 查看:sources.status 的 evidence.rubrics 列出每个 rubric 当前生效的版本、是否被覆盖。
  • 恢复默认:删除对应的 evidence.rubrics. 条目即可(设置页暂不提供该项的编辑界面,只读设置文件)。
  • 先离线对照再上线:node --experimental-transform-types bench/src/eval-pack.ts --rubric-file bench/rubrics/variants/score.support.v2-example.json,在同一份冻结数据上评估候选版本;不带 --allow-jev N 时不会发出任何请求(用法见 bench/src/eval-pack.ts 文件头注释)。
  • 不让线上模型改提示词:rubric 只能由人通过设置文件修改;插件和任何线上模型都不会自动改写或上线新版本。

English The question wording, grade levels and length caps sent to Jev are versioned rubrics (built in: score.support, plus gate.relevance and gate.constraint for future use). Defaults are byte-identical to the offline-evaluated wording. Override one under evidence.rubrics. in settings.yaml with its own version, optional instructions (variables {task} {need} {candidate} only; {need} and {candidate} required), criteria (2-10 levels, lowest first; other than 4 levels are rescaled to 0..3), maxStateChars, maxCandidateChars. An invalid override (unknown variable, bad level count, out-of-range length, changed content under the old version label) is ignored and the built-in is used; the reason shows in sources.status (evidence.diagnostics) and the pack notes. Bump version whenever the content changes. Every Jev result records id@version#hash (pack stats.jev.rubric, shadow log, evidence_blocks.rubric), and the offline judge-cache keys include id, version and full text, so a changed prompt never reuses old scores. Restore defaults by deleting the evidence.rubrics. entry (there is no settings-page editor for it yet). Compare a candidate offline first with bench/src/eval-pack.ts --rubric-file. Online models must never rewrite or roll out rubrics by themselves: they change only through the settings file.

评分模型 provider 与用量上限 / Judge providers and usage caps

中文 S6 的模型评分分成「协议 × provider」两层,换模型只改配置:

  • 协议:systemone(Jev 兼容的 POST /v1/systemone:博查 Jev、其他 Jev 部署、本地 Laya sidecar);rerank(Jina / Cohere 风格的 {model, query, documents, top_n} → results[{index, relevance_score}],也适用于暴露同形状接口的本地 bge / Qwen reranker);llm(OpenAI 兼容 chat completions,温度 0、严格 JSON 校验,仅供参考/实验,默认关闭,需 evidence.judge.allowLlm: true)。systemone 与 llm 用 score.support rubric;rerank 以需求文本作 query。
  • 内置 provider:bocha-jev(默认;https://jev.bocha.cn,bocha-jev-v1,密钥 BOCHA_JEV_API_KEY,请求与旧版逐字节相同)、typesafe-jev(占位预设,须自行填 baseUrl / model,未验证)、laya-local(http://127.0.0.1:8765,无密钥;实验 r1 里在当前提示词下接近随机,用前必须自己校准)、jina-rerank、cohere-rerank(未验证,从未对真实服务调用过)。
  • 自定义 provider(jevMode / judge.mode 决定怎么用;judge.mode 是 jevMode 的中性写法,两者都设时前者优先,且 control 不再需要 scorer: jev):
evidence:
judge:
mode: hybrid                 # off | shadow | control | hybrid
provider: my-reranker        # 默认 bocha-jev
providers:
my-reranker:
protocol: rerank
baseUrl: http://127.0.0.1:8080/v1   # 非本机必须 https;路径可用 path 覆盖(默认 /rerank)
model: bge-reranker-v2-m3
keyRef: MY_RERANK_KEY    # 可选:凭据引用或环境变量名,永远不写密钥本身
limits: { maxDocumentsPerRequest: 50, blockChars: 1000 }
calibration:             # rerank 必填,见下
version: v1
points: [[0.1, 0], [0.4, 1], [0.7, 2], [0.9, 3]]
bocha-jev:                 # 与预设同名 = 覆盖预设的个别字段
limits: { maxQuestionsPerRequest: 16 }
budget:
perSearchInputTokens: 60000  # 默认
dailyInputTokens: 1000000    # 默认
timezone: Asia/Shanghai      # 日界线时区,默认系统时区
providers: { laya-local: { dailyInputTokens: 200000 } }   # 按 provider 覆盖,取更严格者
  • 校准是硬要求:reranker 的相关度分数不是等级,不同模型/语言差异很大。calibration.points 是 [原始分, 等级0..3] 的单调分段线性映射(原始分严格递增、等级不降;区间外取端点),版本号和内容哈希随结果记录;没有校准的 rerank provider 不会被使用(规则评分继续,并在 notes 说明)。不同 provider 的分数从不混用,离线缓存也按 provider+模型分开(rerank 缓存的是原始分,换校准无需重新请求)。systemone 也可选填 calibration(Laya 建议)。先用 shadow 观察,再考虑 hybrid / control。
  • 用量账本与上限:每次模型调用前按保守估算预留 token、调用后按服务返回的 usage 结算(服务不返回则按估算记账并标 estimated;价格未声明时金额为空,不是 0;price 可选声明)。预留是原子的(SQLite usage_ledger 表,跨搜索、跨进程,重启不清零,未结算的预留继续占用额度)。超过单次搜索或当日上限时跳过模型阶段、回退规则评分,notes 出现 “model budget exceeded”。sources.status 的 evidence.provider / evidence.usage 显示当前 provider 是否可用、今日用量与上限。注意默认单次上限 60000 输入 token 小于 maxJevQuestions: 64 全量发送的估算量,较大的 hybrid 搜索可能提前停在上限处。
  • 离线评测:bench/src/eval-pack.ts --provider [--providers-file providers.json]、bench/src/run-judges.ts --provider;文件格式同 evidence.judge.providers。

English S6 model scoring is split into protocol x provider; switching models is configuration. Protocols: systemone (Jev-compatible API: Bocha Jev, other Jev deployments, the local Laya sidecar), rerank (Jina/Cohere-style query-documents API, also local bge/Qwen servers) and an opt-in llm (OpenAI-compatible chat, temperature 0, strict JSON; off unless evidence.judge.allowLlm). Presets: bocha-jev (default, requests byte-identical to before), typesafe-jev (placeholder, unverified), laya-local (no key; near random with the current prompts, calibrate first), jina-rerank / cohere-rerank (unverified, never called live). Add your own under evidence.judge.providers (same-id entries override a preset's fields); evidence.judge.mode is the neutral name of jevMode. A reranker's relevance score is not a grade: calibration.points (monotone piecewise-linear [raw, grade 0..3]) is mandatory, versioned and recorded with results; provider scores are never mixed and caches are per provider+model. Every model call is reserved before and settled after in a persisted ledger (actual tokens from the API, otherwise a flagged estimate; unknown price = null, never 0), under evidence.budget caps (default 60k input tokens per search, 1M per day, per-provider overrides, day boundary in timezone). Over a cap the model stage is skipped and rule grades are used ("model budget exceeded"). sources.status shows the provider and today's usage. Offline: eval-pack.ts / run-judges.ts --provider.

覆盖判定(S8,可选,默认关闭) 规则覆盖是词法判断,分辨不出“文档里没有”。evidence.coverage: { mode: off | shadow | control, provider?, thresholds?: { weak, covered } }:对规则声称已覆盖的每个需求,向 systemone 模型(默认 bocha-jev)问一道 cover.sufficient noul 题——“这些摘录本身是否已明确给出答案”(一次请求,经用量账本与上限)。shadow 只把原始概率记入 stats.coverage,覆盖不变;control:概率低于 weak 的需求变成缺口 weak_support (judge)(关键需求可触发既有的有界第二轮,不增加轮数),介于 weak 与 covered 之间的保持覆盖并标 (judge unsure)。只有显式设置才启用,不随 jevMode 自动开启;失败、超限、超时、缺 Key、缺阈值时保留规则覆盖并在 notes 说明。阈值只对校准过的 provider + rubric 版本有效(内置 bocha-jev + cover.sufficient@v1:weak 0.0512,covered 0.313,取自 v1 calibration 划分);换 provider、模型或 rubric 版本须自己配 thresholds。离线评测见 bench/README.md “覆盖判定评测”,数字见开发计划 M9:增益有限,所以默认保持关闭,建议先用 shadow 积累数据。

English Optional S8 coverage judge (default off). evidence.coverage: { mode: off | shadow | control, provider?, thresholds?: { weak, covered } } asks a systemone model (default bocha-jev) one cover.sufficient noul question per need the rules claim covered ("do these excerpts by themselves state the answer?"), metered by the usage ledger. shadow records raw probabilities in stats.coverage and changes nothing; control turns probabilities below weak into weak_support (judge) gaps (a critical one may start the existing bounded second round) and marks the band up to covered as (judge unsure). Only its own setting turns it on; any failure, cap, timeout, missing key or missing thresholds keeps the rule coverage and says so in notes. Thresholds are only valid for the provider + rubric version they were calibrated for (shipped: bocha-jev + cover.sufficient@v1).

工具面(索引 → 调用)

常驻上下文只有两个工具,常驻文本(系统提示 + 工具名、描述、参数)约 800 字符(原 11 个工具约 9300 字符):

工具 作用
web_index({group?, action?, query?}) 渐进披露目录:无参数列出能力组、两个最常用调用、旧名对照;group 列出该组动作;action 给出完整参数;query 按关键词检索(至多 8 条)
web_call({action, args}) 执行一个动作,返回统一信封 {ok, action, result \| error{code,message,hint,schema?}, truncation?};参数校验失败(INVALID_ARGS)时附带该动作的精简 schema,一次即可改对;未知动作会给出相近动作名

使用指引放在随包提供的 skill dsh-web-search-pro(证据模式优先、先读 gaps 再下结论、search.recommend 只用 1–2 个来源、read.fetch 的 offset 续读、约束、预算、浏览器交接;参考文件含来源与 Key 配置、评分 provider 与 rubric、排障)。skill 通过可选的 ctx.skills 注册,不写入必需的 inject;宿主没有 skill 服务时,web_index() 根目录附一段精简指南兜底。系统提示只保留一行入口(有 dsh-browser 时再加一行指向 skill dsh-browser / browser_index)。

动作

组 动作 作用
search run 多引擎搜索 + RRF 融合 + 内存/SQLite 双层缓存 + 历史;传 task / profile 得证据包;传 platform 搜单个平台(GitHub/B站/YouTube/V2EX/小红书/Twitter/Reddit/IG/FB/RSS + 知乎/微博/豆瓣/贴吧/抖音/快手,登录态走 Playwright;RSS 用 url 传 feed、query 可选过滤;平台与网页引擎走同一条注册表执行路径,可与 task/profile 同用得到证据包,见“平台来源”)
recommend 按任务推荐至多 3 个来源(已就绪优先,其余给出缺失条件),不发搜索请求
read fetch 可读化抓取(Jina → HTTP+规则抽取 → Playwright 兜底)+ 快照缓存与 offset 续读;auto 按质量升级:每次结果先判为 content / shell / js_shell / login_wall / captcha / error,只有 shell、js_shell、login_wall 且 dsh-browser 就绪时才升级到 Playwright(captcha 与错误页不会,短而有实质内容的事实页不算空壳),取质量最好的一次并在 attempts 里记录各后端结果;不会自动安装任何东西;显式 mode 不升级,只复用同后端缓存
contents 原生 Exa /contents 批量正文抓取(1-100 URL,需 Exa Key)
snapshot Playwright HTML + 文本落盘;screenshot=false 时不生成 PNG(需要 dsh-browser)
history list / replay / expand / export / delete 持久历史:过滤列出 / 按 id 回放 / 读回证据摘录及前后块 / 导出 JSON / 删除一条查询
sources status 无副作用后端探测、失败/冷却诊断与 CLI 状态(Twitter 项同时检查 twitter 命令、设置开关和凭据环境变量,note 说明缺什么)
deps / install 检测 / 安装搜索后端的外部依赖(bili/yt-dlp/twitter/agent-reach/mcporter;每项探测的是后端真正执行的命令);浏览器依赖由 dsh-browser 管理
rules list / upsert / remove / import / export 持久化按站提取规则(脚本猫式);export 会写出可再导入的版本化 JSON rule pack
cache clear / stats 按时间/引擎清缓存 / 存储统计

每个动作的参数与输出 schema 是封闭的(未声明字段不会出现,除必需字段外都是可选字段)。

旧工具到新动作

旧的 web_* 工具名已不存在,也没有兼容包装;模型调用旧名会得到新动作名与翻译后的参数。映射表在 src/actions/legacy.ts,测试逐项验证每个旧参数仍可达。

旧工具(参数) 新动作
web_search_pro search.run(query、task、profile、needs、constraints、budget、engines、count、fresh、multi、Exa 选项原样保留)
web_platform_search search.run,传 platform(另有 url、authProfile、rulePack;现在也支持 fresh)
web_fetch_pro read.fetch
web_exa_contents read.contents
web_snapshot read.snapshot
web_history(过滤) history.list
web_history replay= history.replay {id}
web_history action=expand evidenceId= history.expand {evidenceId}
web_history export=true history.export(同样的过滤参数)
web_cache_clear(olderThanDays / engine) cache.clear
web_cache_clear queryId= history.delete {id}
web_rule action=list\|upsert\|remove\|import\|export rules.list / rules.upsert / rules.remove / rules.import / rules.export
web_search_stats cache.stats
web_backend_status(默认) sources.status
web_backend_status action=recommend search.recommend
web_deps(默认 / action=check) sources.deps
web_deps action=install sources.install

迁移说明:

  • 没有 dsh-browser 的会话里,web_* 旧名的调用会报“工具不存在”(宿主层错误,插件无法拦截);新会话的模型通过系统提示、skill 或 web_index() 找到新名字。
  • 用户在宿主里对旧工具名设置的“总是允许”规则不再生效;web_index 无副作用,web_call 的审批由本插件按动作判断(见下)。
  • web_history 的 replay / export / action=expand 不再与列表过滤混在一次调用里,每个动作只做一件事。
  • 输出路径变化:search.recommend 直接返回推荐本身(不再包在 recommend 字段里);sources.install 返回 install 结果(不再带空的 backends)。

审批、并发与超时(按动作)

  • 审批:sources.install(安装外部命令)、cache.clear、history.delete、rules.upsert / rules.remove / rules.import(改本地存储)会请用户确认;其余动作直通。原先这些规则按工具名写在 dsh-browser 的 tools/pre-execute 钩子里,而 web_call 对它是不透明的,所以规则现在由本插件解析 web_call 的动作后施加,并在 dsh-browser 存在时读取它的 automationMode:read-only 拒绝;安装在 unrestricted 直通;本地写入在 standard 询问、autonomous / unrestricted 直通。没有 dsh-browser 时模式未知,按 standard 处理(询问)——这比旧行为(无 dsh-browser 时完全不审批)更严格。
  • 并发:web_call 的并发安全性由参数里的动作决定:只读动作可并行,修改状态的动作独占(sources.install 现在也独占,旧的 web_deps 因为一个标志同时覆盖 check 与 install 而全部可并行)。
  • 超时:每个动作保持旧工具的上限(搜索与快照 timeoutMs + 60 秒,读取与 Exa 正文 + 30 秒,依赖检测/安装 + 180 秒,历史与状态等 10–20 秒);web_call 的宿主上限取其中最长者,各动作自己的截止时间到期后返回 DEADLINE(修改状态的动作会说明结果未知)。调用方的取消信号会传给执行器。

工具面形态

toolSurface: indexed | flat(设置文件顶层,启动时生效,默认 indexed)。flat 把同一份动作注册表投影成每个动作一个工具,名字为 web_<组>_<动作>(如 web_search_run、web_read_fetch),只用于对照与调试,不是旧工具的兼容层,常驻体积回到全部注入的量级。两种形态共用同一个分发函数,信封、错误码与审批完全一致。

输出预算(所有出口)

每个把正文交给模型的出口都有默认上限;超出部分留在本地存储,按 ID 或偏移续读,不会因为 UI 折叠而仍把全文送进上下文。

出口 默认预算 配置项 超出时
search.run(证据包) 摘录总计 6000 字符,每 URL 至多 2~4 块 参数 budget(至多 30000) 溢出的需求列在 gaps;history.expand 传 evidenceId 读回摘录所在块及前后块
read.fetch 20000 字符 fetchDefaultChars(1000–500000);参数 maxChars 输出 truncated、nextOffset、totalChars,并提示 “more: call read.fetch with offset=N”;offset 从已存的页面快照续读,命中缓存时不重新抓取
read.contents 每 URL 8000、全部 URL 合计 30000 字符;总量不足时较短的文本原样保留、剩余额度均分给较长的 exaContentsPerUrlChars、exaContentsTotalChars 每条结果带 truncated、totalChars,并给出 read.fetch offset 的续读提示
ctx.web 抓取 Provider(内置 web_fetch) fetchDefaultChars 的两倍(默认 40000);WebFetchRequest 没有大小参数 fetchDefaultChars truncated 如实反映是否被截断,正文末尾追加 [Continue with web_call read.fetch url=… offset=N]
ctx.web 搜索 Provider(内置 web_search,provider.evidence: auto) 证据包同上(默认摘录 6000 字符);来源条数取宿主给的 maxResults(1–20) provider.evidence、provider.deadlineMs 期限到点返回 PARTIAL 的已有证据包;失败退回普通来源列表;truncated 仅在确有来源被截掉时为真
read.snapshot 文本、history.replay 的页面文本 fetchDefaultChars fetchDefaultChars 文末带截断标记;全文仍在存储里,用 read.fetch url=… offset=N 读取
search.run(普通列表与平台搜索) 每条摘要 500 字符,条数由 count 限制 searchMaxResults 摘要截断

抓取时页面至少读取并存储 100000 字符(更大的 offset + maxChars 会读更多,上限 500000),所以续读来自 SQLite 快照;超过已存部分的 offset 会自动用更大的上限重新读取。

浏览器脚本与自动化分层

> 本派生版本中不可用:@anweat/dsh-browser 0.2.0 的 peer 范围不包含 0.2.1-rc.2,本仓库不 fork 它,也不做浏览器适配。下面的内容保留自上游,仅作能力说明;相关动作会返回 CAPABILITY_UNAVAILABLE(sources.status 显示浏览器未就绪)。

@anweat/dsh-browser ^0.2.0 提供三类脚本入口:

  1. 内置只读脚本:article-clean、links、jsonld、forms,适合稳定抽取;先用 script.catalog(browser_call)查看。
  2. Recipe:最多 25 步的结构化 Playwright 操作,支持 wait/click/fill/type/press/select/check/hover/scroll/extract/assert/screenshot;交互步骤由自动化模式决定审批。
  3. 外部 UserScript:适合外部模型生成站点专项逻辑。先 script.validate 查看 SHA-256、域名范围与能力提示,再 script.run_userscript(均经 browser_call);它在页面主世界运行,并非安全沙箱。

工具自由度由 dsh-browser 的 automationMode 控制:read-only 隐藏或拒绝页面及 Web Search Pro 写操作;standard(默认)对交互、写 Recipe、外部脚本、OpenCLI、缓存/规则变更和安装操作审批;autonomous 直通页面交互、写 Recipe 以及本地缓存/规则变更,但安装、外部脚本和通用 OpenCLI 仍审批;unrestricted 为隔离测试 profile 提供无审批运行。所有模式仍保留域名、参数、大小和步骤上限校验,并始终应用 dsh-browser 的调用缓冲、退避与爬取预算。

OpenCLI 用于已有站点 adapter 或复用 Chrome 登录会话。推荐顺序是 opencli.catalog 查精确 adapter → network/extract → DOM 操作;先运行 opencli.status。opencli.run 接受 argv 数组而非 shell 字符串,可覆盖 adapter、显式 session 的 browser state/find/get/click/fill/type/select/keys/wait/extract/network 等命令;仅 unrestricted 跳过审批。

更完整的 AuthProfile、脚本元数据与 OpenCLI 示例见 LOGIN.md。

配置

三层,越靠前越日常:

  1. DSH 可视化面板:打开 设置 → 插件 → 插件配置 → Web Search Pro(各分组见下节“设置面板”)。修改先保留为本地草稿,点击“保存”后写入 settings.yaml 并热更新,支持放弃修改和逐字段恢复部署值。
  • Exa、Jina、GitHub、博查与各需 Key 来源的密钥通过 DSH Credentials 写入,面板只显示“已配置/未配置”,不会把明文密钥读回浏览器,也不会把密钥值写进 settings.yaml。
  • platformRules、customPlatforms、browserBindings、Playwright、自定义评分 provider 等使用 JSON 对象编辑器;格式、数值范围或服务端校验不通过时会阻止保存,并在字段下方给出与服务端一致的错误信息。
  • 浏览器工具的审批自由度由 dsh-browser.automationMode 管辖,调用缓冲由 dsh-browser.usagePolicy 管辖;用 browser_call 的 runtime.status 查看当前状态。Web Search Pro 面板只管理搜索插件自己的后端开关,不会绕过浏览器插件的审批或资源策略。
  • 更新带客户端面板的插件版本后需要重启 Web profile,让 DSH 客户端模块扫描器重新装载 client.js。
  1. $DSH_HOME/settings.yaml → web-search-pro: 段(热重载,改完即生效):
web-search-pro:
toolSurface: indexed # indexed(默认,只常驻 web_index / web_call)| flat(每个动作一个工具,仅对照与调试;启动时生效)
exaApiKeyEnv: EXA_API_KEY # 推荐:运行环境或凭据服务,不把密钥写入配置
jinaApiKeyEnv: JINA_API_KEY
bochaApiKeyEnv: BOCHA_SEARCH_API_KEY # 博查 Key 的凭据 / 环境变量名;缺省再试 BOCHA_JEV_API_KEY
# keyedSources: # 付费来源(可选,见“付费 / 需 Key 的来源”):tavily / brave / linkup / serper / metaso / zhipu / baidu-qianfan
#   tavily: { apiKeyEnv: TAVILY_API_KEY }   # 或 apiKey(字面量,不推荐)/ baseUrl;没有 Key 的来源保持不可用
engines: [ddg, bing, exa, seam, jina]
parallelEngines: false
# registerProvider: false # true = 把本插件注册为 ctx.web provider(还需在 web 条目里选中,见“两种用法”)
# provider: { evidence: auto, deadlineMs: 25000 } # 内置 web_search 经本插件时是否返回证据包(auto | off)与其期限
evidence: # 证据包模式的块评分;默认完全不调用 Jev
scorer: rule # rule | jev
jevMode: off # off | shadow | control | hybrid
hybridBorderline: false # 仅 hybrid:同时重评规则边界对
maxJevQuestions: 64
maxRounds: 2 # 证据包补搜轮数上限;1 = 关闭第二轮
maxQueries: 4 # 单任务搜索查询总数(含第一轮;一次 provider 调用算一次)
autoProviders: true # 按任务语言提前就绪的来源(你配置了 Key 的来源,英文无 Key 时的 Exa);false = 只用 profile 表
# sourcePolicy: default # default | anonymous-only(自动规划绝不用需要 Key / 账号 / 登录的来源,见“来源策略”)
# rubrics: ...   # 可选:覆盖 Jev 提示词,见下文“Jev 提示词(rubric)”
# judge: ...     # 可选:选择/自定义模型 provider,见下文“评分模型 provider 与用量上限”
# budget: ...    # 可选:模型输入 token 上限(单次搜索 / 每日),默认 60000 / 1000000
# sources: # 来源偏好与请求额度(全部可选,默认什么都不设)
#   priority: [bocha, exa] # 就绪且适合任务语言 / profile 的来源按此顺序排最前
#   disabled: [bing]       # 自动规划与 engines 列表都不用
#   budget: { bocha: { total: 1000, daily: 50 } } # 请求上限;用完被跳过并回退,不报错
ttlSeconds: 3600
searchMaxResults: 8
browserBindings:
zhihu:
authProfile: china-community
rulePack: zhihu-enhanced
  1. cordis.yml config:(部署级默认值,见 cordis.patch.yml)。
  2. 环境变量 / 凭据:$EXA_API_KEY、$JINA_API_KEY、$BOCHA_SEARCH_API_KEY(或 $BOCHA_JEV_API_KEY)(exaApiKeyEnv/jinaApiKeyEnv/bochaApiKeyEnv 引用)。这些引用名与密钥都可以在面板“来源”分组里设置。

设置面板

面板按以下分组折叠显示(中英文随 DSH 语言;搜索、凭据、运行时默认展开)。嵌套选项(evidence.*、provider.*、keyedSources.*)由面板整体写回各自的顶层字段,不认识的同级键原样保留。

分组 内容
搜索策略 默认引擎顺序、默认结果数、并行融合
网络 allowProxyFakeIp(Clash/TUN fake-IP 症状说明)、timeoutMs
工具面 toolSurface:indexed(默认)/ flat(仅调试),启动时生效
内置 web 工具路由 registerProvider、providerId、provider.evidence(auto / off)、provider.deadlineMs,以及选中本插件所需的 profile patch 片段(随 providerId 变化)
证据管线 evidence.autoProviders、maxRounds、maxQueries,fetchDefaultChars、exaContentsPerUrlChars / TotalChars。minKeep 与证据包字符预算没有配置项(内置默认 / search.run 的 budget 参数)
评分模型 evidence.judge.mode(off / shadow / control / hybrid,同时写旧键 jevMode / scorer 保持一致)、hybridBorderline、provider 下拉(内置预设 + 自定义 id)、maxJevQuestions、allowLlm;覆盖判定 evidence.coverage 的模式、provider、阈值;用量上限 evidence.budget(单次 / 每日 / 时区 / 按 provider);自定义 provider JSON(与服务端同一套校验,拒绝在定义里放密钥,只放 keyRef 名)
提示词(rubric) 列出内置 rubric 与生效版本;逐个覆盖(版本、模板、等级、字符上限),按 rubrics.ts 的规则校验(未知变量、必需变量、等级数、版本必须不同于内置);“恢复默认”删除覆盖
来源 来源策略(evidence.sourcePolicy、sources.priority、sources.disabled)、博查(Key 引用名、接口地址、长摘要)、七个需 Key 的来源(Key 引用名、写入式密钥、接口地址)、每个来源的请求额度(sources.budget..total / daily,已用 / 剩余见 web_call sources.status)、searxngUrl、openalexMailto,以及匿名来源参考表;各来源的实时就绪状态由 web_call sources.status 显示
服务凭据 / 运行时与后端 / 高级 Exa、Jina、GitHub 凭据引用与密钥;CLI、OpenCLI、Agent Reach、Playwright、平台后端顺序 platformBackends、自定义 CLI 适配 cliAdapters(JSON,校验与服务端共用);缓存、排序加权、平台规则、自定义平台、浏览器绑定

校验与服务端共用同一批纯函数(pipeline/rubrics-spec.ts、judges/providers-spec.ts、judges/calibration-spec.ts、coverage.ts、budget-spec.ts),它们不引入 Node 模块,客户端 bundle 仍只依赖宿主模块表里的少数模块(pnpm run test:client-bundle 检查)。

CLI 适配 / CLI adapters

中文 平台不再几乎只靠 dsh-browser 内置的 OpenCLI:本插件有一层声明式的 CLI 适配(src/cli/)。一个适配规格 CliAdapterSpec 写明:命令名(bins,包名可与命令名不同,记在 packageNote)、探测契约(probe:--version、最低版本、--help 里必须出现的子命令 / 参数)、搜索命令(search.argv 是数组,只有 {query}、{count} 两个占位符,永不经过 shell)、输出格式(json / ndjson / yaml / text)与字段映射、emptyWhen / notLoggedInPatterns、环境变量白名单(env.required / passthrough,只写名字)、超时与输出上限。执行器按 UTF-8 解码,超时 / 取消 / 输出超限都有结构化错误:CLI_NOT_FOUND、CLI_CONTRACT_MISMATCH、CLI_NOT_LOGGED_IN(提示“请自行运行 login”)、ENGINE_EMPTY、CLI_FAILED;错误文字里不会出现环境变量的值。

只读保证(内置和用户自定义规格同样适用):规格必须声明 allowedSubcommands,argv 里用到的子命令都得在其中,且不得命中全局拒绝表(login、logout、post、comment、delete*、like、follow、favorite、upvote、save、subscribe、publish、ask、article、pin、setup、init、install、update 等);会读取浏览器 Cookie 或把凭据放进参数的 flag(--cookie-source、--cookies-from-browser、--token、--password……)一律拒绝。插件永不运行任何登录命令,也不代用户登录:需要登录的 CLI 由你自己运行它的 login;没有已保存登录的 xhs / rdt / zhihu 不会被运行(它们在没有登录时会自己去读浏览器 Cookie)。子进程只拿到最小环境(PATH、HOME、代理、证书,加规格点名的变量),不继承你整个环境。

探测只在本地:找命令、跑 --version 和规格里的 --help,检查版本与契约,缓存 60 秒;不搜索、不登录。同名但契约不同的程序(如 PyPI 上另一个 bili-cli)报 incompatible 并写明原因,不会被当成可用。sources.deps 显示每个 CLI 的 installation(missing / detected / incompatible)、版本、适配验证程度;sources.status 的每个平台带 chain:每条后端的顺序、状态、被跳过的原因。

内置规格 命令 已验证版本(2026-10-06) 验证程度
bili(bilibili) bili 0.6.2 live:真实只读搜索并解析
gh(github / github-issues / github-code 的回退) gh 2.101.0 live(仓库搜索);issues / code 按帮助页字段,未运行
omnireach(wechat 与多源 omnireach) omnireach 0.19.0-alpha live(--on wechat);多源命令未运行
yt-dlp(youtube) yt-dlp 2026.08.19 contract-only:帮助与版本,未运行搜索
twitter twitter 0.8.5 contract-only:需要你的 Token,未运行搜索
xhs(xiaohongshu) xhs 0.6.4 contract-only:帮助 + 已装包源码里的输出形状;搜索需要你的登录
zhihu zhihu(PyPI pyzhihu-cli) 0.2.4 contract-only(同上)
rdt(reddit) rdt 0.4.2 contract-only(同上)
独立 opencli(按站点) opencli 1.8.8 contract-only:只用 opencli list -f json 里有只读 search 命令的站点,输出用 -f json
wx-search-cli(wechat 第二后端) wx-search-cli 0.1.0 contract-only:帮助与版本已在真实安装上探测;输出形状按上游 README / 源码,未运行搜索
tanso tanso 2.0.2 docs-only:按上游 README,未安装;只选 bocha_web 与 zhihu_search

目录里另有只列条目、没有适配的 douyin-cli(它的 README 没写搜索记录的字段)。contract-only 的字段映射来自工具自己的帮助 / 源码,并有标成 “constructed” 的夹具测试;它们在真实登录后的输出上还没被确认。

默认后端链(platformBackends 可改,未列出的平台用默认顺序):

平台 默认链
xiaohongshu opencli(独立)→ xhs → browser-opencli(dsh-browser)
reddit rdt → opencli → browser-opencli
zhihu zhihu → browser-search(dsh-browser 搜索页)
twitter twitter → opencli → browser-opencli
bilibili / youtube bili / yt-dlp
github、github-issues、github-code rest(现有 REST)→ gh
wechat(公众号,新) omnireach → wx-search-cli
omnireach(多源,不自动选入) omnireach
instagram / facebook browser-opencli;weibo、douban、tieba、douyin、kuaishou:browser-search

链上缺失、不兼容或未登录的后端被跳过并记下原因;只有整条链都不可用时平台才不可用,错误会列出每条后端缺什么、该安装或运行什么。M0 冷却、并发合并、输出整形、证据模式与显式 platform 的语义不变。

启用一个 CLI:按 sources.deps 给出的命令安装(sources.install 需要你的审批),再自己运行它的登录命令(xhs login、rdt login、zhihu login、gh auth login;twitter 用环境变量 TWITTER_AUTH_TOKEN / TWITTER_CT0)。想优先用它,就改链序:

web-search-pro:
platformBackends:
xiaohongshu: [xhs, opencli, browser-opencli]
cliAdapters: # 自定义只读适配(同样的校验),注册为平台 custom-cli:mytool
mytool:
bins: [mytool]
packageNote: 'mytool (npm i -g mytool)'
platforms: [mytool]
probe: { versionArgs: ['--version'], helpArgs: ['search', '--help'], mustContain: ['--json'] }
allowedSubcommands: [search]
search:
argv: [search, '{query}', '--limit', '{count}', '--json']
maxCount: 10
output: { format: json, itemsPath: data, fields: { url: url, title: title, snippet: summary } }
env: {}
needsLogin: false
timeoutMs: 30000
maxOutputBytes: 1048576

无效的 cliAdapters 条目被忽略,原因出现在 sources.status 的 notes;设置面板里两项都有 JSON 编辑器,校验与服务端是同一批函数。

README 较长,此处只展示前 60 KB。完整内容请到仓库查看 ↗。

常见问题

6 问
答案由本站依据条目字段整理,不引用上游原文
dsh-web-search-pro-plus 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:AlbertZJ/dsh-web-search-pro-plus` 即可。

dsh-web-search-pro-plus 的验证等级是什么意思?

L4 · 沙盒安装通过。安装命令在隔离沙盒内真实执行成功,无依赖错误

dsh-web-search-pro-plus 安全吗?

低风险。

dsh-web-search-pro-plus 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-web-search-pro-plus 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

记忆与知识
按星标排序,可作替代方案

ruflo

ruflo

L3 · 安装规范通过 7.4 万 星

OpenViking

OpenViking

面向 DeepSeek Harness 的 OpenViking 记忆与上下文插件:pre-step 自动召回与画像注入、会话捕获、`vik

L3 · 安装规范通过 3.9 万 星

WeKnora

WeKnora

把 WeKnora 知识库接入 dsh 的四个只读工具:列出知识库、混合检索原文片段、按顺序还原单篇文档,以及直接取用 WeKnora 自己

L4 · 沙盒安装通过 3.3 万 星

distilly

distilly

Distilly — Distill how they think into reusable Skills for any Agent o

L4 · 沙盒安装通过 2.5 万 星

EverOS

EverOS

L4 · 沙盒安装通过 1.3 万 星

MemOS

MemOS

L4 · 沙盒安装通过 1.2 万 星

AlbertZJ 的其它插件

3 个

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 —。