Tavily 弹性搜索 frederico-kluser/dsh-tavily-resilient-search
DeepSeek Harness多密钥轮换调用 Tavily 实时联网搜索
29.6/100
综合分
0
GitHub 星标
—
npm 周下载
—/5
用户评分
数据截至 2026/9/28 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add frederico-kluser/dsh-tavily-resilient-search该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)
状态速览
判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态信任档位:已验证
是什么
dsh 原生插件 · search
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
更新放缓:最近一次提交在 37 天前
档位由哪些信号合成
本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。
社区实装还没有人打卡 · 装过的第一个就是你
安全扫描自动 · 静态分析源码v2.7.0🟢 扫描:未发现敏感能力尚无人工评估展开查看扫描说明与证据 ↓
安全扫描自动 · 静态分析源码
v2.7.0静态扫描未发现敏感能力:最多只发网络请求、读取自身元数据或只读文件,未发现执行命令、文件写入或敏感信息读取。
发起外部网络请求
查看扫描证据(共 2 处,展示前 2 条)
- 发起网络请求client/client.js:35
const res = await fetch(API + "/health"); - 发起网络请求client/client.js:51
const res = await fetch(API + path, {
扫描于 2026/11/1(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库
静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/dsh-agent@deepseek-ai/dsh-client-ui-settings@deepseek-ai/dsh-host-webserver@deepseek-ai/dsh-invariants@deepseek-ai/dsh-llm@deepseek-ai/dsh-ptc-runtime@deepseek-ai/dsh-sandbox@deepseek-ai/dsh-sandbox-policy@deepseek-ai/dsh-scope@deepseek-ai/dsh-session@deepseek-ai/dsh-system-prompt给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个
功能亮点
- 多密钥轮换调用
- 实时联网搜索
- 密钥池弹性轮换
Tavily 网页搜索插件,给 DeepSeek Harness(Cordis 插件)用,支持 API 密钥池原子化弹性轮换——限流、月度配额、密钥吊销都不打断智能体循环。
README
由 DeepSeek 最新模型翻译生成dsh-tavily-resilient-search
通过 Tavily API 为 DeepSeek Harness(DSH)提供实时网络搜索,具备凭证池的原子化、弹性轮换以及无密钥应急方案——当密钥达到速率限制(429)、月度配额耗尽(432/433)或被撤销(401)时,不会中断 agent loop。
独立的 Cordis 插件:通过清单安装,无需对 DSH 代码进行 fork,并且能在热重载/卸载后存活,不会产生泄漏或孤立的监听器。
它解决的问题
在朴素的实现中,HTTP 429 或 432 会作为 promise 拒绝传播到轮次例程:该轮次会突然终止——或者模型会错误地得出结论,认为“互联网已经不存在了”。在这里,语义意图(搜索)与物理层(当前由哪个凭证来派发)是解耦的:
- 饱和/计费错误会改变引发问题的密钥状态,并且该调用会以原封不动的 payload 立即重新发出,由下一个无阻碍的凭证(round-robin)执行;
- 当整个池都受阻时,会启用无密钥应急方案(X-Tavily-Access-Mode: keyless);
- 只有当所有传输备选方案都耗尽时,该工具才会返回结构化的警告结论——绝不抛出会驱逐宿主进程的异常。
展开完整文档(README 剩余 1 节)
dsh-tavily-resilient-search
通过 Tavily API 为 DeepSeek Harness(DSH)提供实时网络搜索,具备凭证池的原子化、弹性轮换以及无密钥应急方案——当密钥达到速率限制(429)、月度配额耗尽(432/433)或被撤销(401)时,不会中断 agent loop。
独立的 Cordis 插件:通过清单安装,无需对 DSH 代码进行 fork,并且能在热重载/卸载后存活,不会产生泄漏或孤立的监听器。
它解决的问题
在朴素的实现中,HTTP 429 或 432 会作为 promise 拒绝传播到轮次例程:该轮次会突然终止——或者模型会错误地得出结论,认为“互联网已经不存在了”。在这里,语义意图(搜索)与物理层(当前由哪个凭证来派发)是解耦的:
- 饱和/计费错误会改变引发问题的密钥状态,并且该调用会以原封不动的 payload 立即重新发出,由下一个无阻碍的凭证(round-robin)执行;
- 当整个池都受阻时,会启用无密钥应急方案(X-Tavily-Access-Mode: keyless);
- 只有当所有传输备选方案都耗尽时,该工具才会返回结构化的警告结论——绝不抛出会驱逐宿主进程的异常。
安装
dsh plugin --profile web add dsh-tavily-resilient-search
激活是自动的:该包声明了 dsh.bundle.patch(只有 dsh.bundle.patch 才能激活插件——空的 bundle: {} 不会激活任何东西),并且清单 cordis.patch.yml 会进入组合的 Bundle 层。
通过环境变量定义凭证(切勿以明文形式):
export TAVILY_API_KEY_A="tvly-..."
export TAVILY_API_KEY_B="tvly-..." # tantas quantas as contas disponíveis
export TAVILY_API_KEY_C="tvly-..."
export TAVILY_API_KEY_D="tvly-..."
没有任何密钥时,插件不会导致启动崩溃:它会降级为仅无密钥模式(限制要严格得多)并大声警告。已记录的合法状态:“尚未配置”。
通过界面管理密钥
池的所有 CRUD 都集中在一个唯一位置:设置(Settings)中的 “Tavily Keys” 部分——由客户端 bundle(client/client.js,在官方示例中测量的 __ModuleLoader__ 格式)贡献给 settings.section 槽位,并使用 DSH 的设计系统进行样式化。
- 在单一屏幕上完成完整 CRUD:添加(C,使用 Enter)、以卡片形式列出状态(R)、编辑/替换(U,Enter 保存,Esc 取消)、移除(D)以及测试(针对 API 进行验证——1 个信用点)。
- 每个操作都有反馈:请求期间显示 spinner,并立即显示 ✓/⚠ 确认——绝不会有点击后毫无响应的情况。
- 侧边区域的 “🔑 Tavily Keys” 按钮仅在不存在有效密钥时显示(一旦有可用凭证就会消失);它会直接打开定义。没有并行屏幕:旧的独立页面响应 410。
- 面板中的有用链接:app.tavily.com 用于获取密钥、文档以及 token 所在位置。
管理 token(用于打开面板):在首次启动时由 CSPRNG 生成,保存在 ~/.dsh/dsh-tavily-resilient-search/admin-token.txt (0600),并在 DSH 日志(logger 'tavily-pool')中打印一次。丢失了?
用 DSH_TAVILY_ADMIN_RESET=1 重新加载。也可以设置 DSH_TAVILY_ADMIN_TOKEN。
- 边界:来源(socket + Origin)→ Host → 凭据,按此固定顺序;拒绝响应字节级相同(无 oracle)。默认:仅 loopback(admin.trustedRemotes / admin.allowedHosts)。
- 暴力破解:NIST SP 800-63B-4 预算(100 次失败 → 以相同的 401 锁定)。
- 破坏性操作(删除以及替换/编辑)需要一次性确认 nonce。
- 审计:audit.log 可追加(0600,O_NOFOLLOW),记录所有可变决策和拒绝。
- 从环境中移除的密钥会在下次启动时恢复(移除是易失的,面板会提示);通过面板持久化/移除的密钥是永久性的。
- 在公共绑定(0.0.0.0)上,面板拒绝启动(fail-closed,高噪声),直到 admin.allowPublicBind: true —— 搜索工具在任何情况下都继续工作。
配置
在 Profile 层($DSH_HOME/profiles//cordis.patch.yml)、Home ($DSH_HOME/cordis.patch.yml)或 CLI overlay(dsh --patch ./o.yml)中覆盖任何字段。解析是整项替换(whole-entry replace),从不 deep-merge:始终指向插件自身的 id。
| 字段 | 类型 | 默认值 | 作用 |
| apiKeys | string[] | [] | 凭据分组(round-robin)。为空 = keyless-only。 |
| searchDepth | ultra-fast\|fast\|basic\|advanced | basic | 当模型未选择时的默认深度。 |
| maxResults | 1..100(钳制到 10) | 5 | 合格来源的最大数量。 |
| includeAnswer | boolean | true | 注入初步的摘要回答。 |
| timeoutMs | 250..300000 | 15000 | 每次尝试 HTTP 的超时。 |
| callTimeoutMs | ≥ timeoutMs | 120000 | 调用的总协作预算(所有轮换)。 |
| projectId | string | — | 按项目隔离(X-Project-ID)。 |
| admin.enabled | boolean | true | 通过界面管理密钥的面板。 |
| admin.trustedRemotes | string[] | loopback | 面板允许的套接字来源。 |
| admin.allowedHosts | string[] | 127.0.0.1、localhost、::1 | 允许的 Host 名称(防 DNS-rebinding)。 |
| admin.stateDir | string | $DSH_HOME/dsh-tavily-resilient-search | 状态目录(0700)。 |
| admin.allowPublicBind | boolean | false | 显式选择退出对非 loopback 绑定的拒绝。 |
| securityProfile | {sandbox, approval} | 必填 | 安装配置文件的证明(见安全)。 |
示例(Bundle 层,已包含在包中):
- insert:
- id: dsh-tavily-resilient-search
name: 'dsh-tavily-resilient-search'
config:
searchDepth: 'basic'
maxResults: 5
includeAnswer: true
timeoutMs: 15000
callTimeoutMs: 120000
securityProfile:
sandbox: 'workspace-write'
approval: 'ask'
apiKeys: !!js >
(() => { try { return [process.env.TAVILY_API_KEY_A, process.env.TAVILY_API_KEY_B, process.env.TAVILY_API_KEY_C, process.env.TAVILY_API_KEY_D].filter(Boolean) } catch { return [] } })()
清单的实测规则(@deepseek-ai/dsh 0.1.x-rc):行的顺序不承载加载语义(激活由 inject 驱动),并且*一个在加载时抛出异常的 !!js 会阻止所有安装者的 DSH 启动——上面的表达式是防御性的,在失败时返回 []。
暴露的工具:web_search
| 参数 | 类型 | 必填 | 描述 |
| query | string | 是 | 客观关键词(建议 < 1500 个字符;硬性上限 4000)。 |
| search_depth | enum | 否 | ultra-fast/fast(< 800 ms)· basic · advanced(仅限复杂文档)。 |
| max_results | integer | 否 | 1 到 10(默认 5)。 |
| topic | enum | 否 | general \| news。 |
规范结果(完整形式,不适用时显式 null):
ok、query、answer、sources[](title、url、snippet、score)、
responseTime、resultsTruncated、keylessFallbackUsed、error、detail、 suggestion。向模型的投影始终包含一条关于网页内容的不可信警告(间接注入遏制)。
按 HTTP 状态码的行为
| HTTP | 条件 | 插件行为 |
| 200 | 成功 | 解码、规范化、应用 50 KB 上限、返回结果。 |
| 400 | 参数格式错误 | 不轮换——返回错误 + 修正建议。 |
| 401 | 密钥无效/已撤销 | 永久禁用(REVOKED)并立即前进到下一个。 |
| 403 | 域名/路由被禁止 | 不轮换——告知无法访问。 |
| 429 | 速率限制 | 读取 Retry-After(秒或 HTTP 日期),冷却该密钥并轮换。 |
| 432 | 月度配额耗尽 | 暂停至下个月 UTC 午夜并轮换。 |
| 433 | 达到 PAYGO 上限 | 同 432(定时暂停)。 |
| 5xx | 瞬时不稳定 | 使用备选方案重试;密钥状态不变。 |
密钥池状态机
┌──────────────┐ 401 ┌──────────┐
┌────────►│ ACTIVE │───────►│ REVOKED │ (definitivo)
│ └──────┬───────┘ └──────────┘
│ cooldown │ 429
│ expirado ▼
┌─────┴────────┐ ┌──────────────┐
│ (轮询)│◄─│ RATE_LIMITED │ T = Retry-After 或 min(Tmax, T0·2^k) + δ
└──────────────┘ └──────────────┘
▲
│ 每月补充(第 1 天,UTC) ┌─────┴───────────┐ │ QUOTA_EXHAUSTED │ 432/433 → 暂停至下月 UTC 午夜 └─────────────────┘
T₀ = 500 ms,T_max = 60 s,抖动 δ ∈ 0, 500) ms,用于对抗整批重新饱和。恢复是惰性的(无定时器):过期在下次选择时生效,从而保持读取纯净、事件循环干净。
安全
摘要(完整内容见 [docs/seguranca.md):
- sandbox: danger-full-access + approval: never 的组合在加载时被拒绝(fail-loud,故意不可恢复)。securityProfile 是操作员的强制性证明——配置缺失也会高声失败。
- 按值的机密金丝雀:凭据材料会从所有输出文本和日志中被脱敏(一个恶意响应体即使回显了 Authorization 密钥也绝不会将其传播);日志中仅以掩码 …últimos4 标识。
- 每次调用 50 KB 的体积上限:炸弹文档不会撑爆上下文窗口(include_raw_content 从不发送)。
- 网页内容是不可信数据:模型投影携带针对间接指令注入的永久警告。
| Sandbox \ Approval | ask | never |
| workspace-write | 审慎(默认) | 受控自动化 |
| danger-full-access | 受监控的扩展 | 禁止——加载时拒绝 |
经测量验证的 API(绝不靠散文)
所使用的接口是从已发布的 npm tarball 内的 .d.ts 中读取的(sha256 记录于 types/;由 pnpm run check:upstream 重新验证),并由一个契约测试锁定,一旦公共 API 偏离即失败。经测量的事实纠正了流传的文档:
| 已死的说法 | 实测的真实行为 |
| inject: ['tools', 'logger'] | logger 不是 Cordis 的 Service:该 fiber 会永远处于 PENDING。应使用 ctx.logger(nome);inject = ['tools']。 |
| dsh.bundle: {} 激活插件 | 只有 dsh.bundle.patch 才会激活(在 @deepseek-ai/dsh 0.1.0-rc.7+ 中实测)。 |
| 参数中的 required: false | DSL 用 required?: true 标记必填——可选 = 省略该键。 |
| output: { schema: { type: 'object' } } | 对象要求显式的 additionalProperties: boolean。 |
| ctx.httpServer / spawn(cmd, args) | ctx.webServer / ctx.subprocess.spawn(spec)(在 0.1.x-rc 范围内验证)。 |
支持的行:@deepseek-ai/dsh-tools ^0.1.1-rc.1 || ^0.1.7-rc.1(两者之间的
漂移仅为增量)以及 @deepseek-ai/cordis ~4.0.4。注意:dsh- 子包的 dist-tag latest 指向最旧的发布——活跃行是 next。
开发
pnpm install
pnpm run gate # lint + typecheck + build + test + check:tarball
pnpm run check:upstream # 通过网络重新验证 tarballs/sha256(Q-1)
四层测试(node:test + tsx,确定性——注入时钟和 RNG,无 sleep):
| 层 | 证明 |
| test/unit | 纯核心:状态机、字节上限、fail-loud 校验、token/nonce/lockout、0600 持久化 + 防符号链接审计 |
| test/integration | 基于传输替身的原子轮换,以及基于真实 HTTP 服务器(端口 0)的面板路由器 |
| test/adversarial | 尝试突破:机密金丝雀、炸弹文档、间接注入、YOLO 配置、P-09 回归、启动安全、字节级相同的 CSRF/rebinding、无预言机暴力破解、nonce、拒绝公网绑定 |
| test/contract | types/ 镜像与已发布的 .d.ts 逐字一致 |
打包与发布
发布预编译产物(dist/),消费者安装时不运行构建脚本(供应链风险)。files 是允许列表:dist/、cordis.patch.yml、README.md、LICENSE、CHANGELOG.md。发布门禁是
pnpm run gate && publint && attw --pack . && node scripts/check-tarball.mjs
(最后一项检查真实 tarball)。版本说明通过 changesets;在 0.x 中,minor 即为破坏性变更。CI 中的发布使用可信发布(OIDC)——需在 npm 控制台为此仓库配置一次。
许可证
MIT预览分享卡片长什么样 ↓
分享 · DeepSeek Harness Hub
frederico-kluser/dsh-tavily-resilient-search
多密钥轮换调用 Tavily 实时联网搜索
相关插件 · 搜索 / 抓取
LLM 知识平台Tencent/WeKnora
概览 ·快速开始 ·新特性 ·功能 ·客户端 ·文档 ·开发
★ 36,032已汉化DSH
72.1
智能体记忆系统MemTensor/MemOS
MemOS 2.0 Stardust星尘
★ 12,195已汉化DSH
71.2
跨代理记忆库zilliztech/memsearch
跨平台语义记忆,专为 AI 编程智能体打造。
★ 2,799已汉化DSH
70.9
技能语料库EverMind-AI/SkillCorpus
SkillCorpus 能给你什么
★ 694已汉化DSH
69.7
代码图谱记忆syncable-dev/memtrace-public
你的智能体值得拥有结构化记忆。
★ 509已汉化MCP
67.9
AnySearch 搜索插件anysearch-team/anysearch-dsh
AnySearch 网页搜索服务商,为 DeepSeek Harness(DSH)提供高级搜索工具
★ 457已汉化DSH
66.6