ltl0312/my-dsh-plugins--packages-tlsearch ↗★ 0
dsh-plugin-tlsearch
Low-token web search for dsh: compact, sanitized {title, url, snippet} results with a pluggable, auto-failing-over backend chain (Tavily / Exa / SearXNG / Brave / Google CSE) and a token budget you control
Install
npx -p @deepseek-ai/dsh dsh plugin --profile web add github:ltl0312/my-dsh-plugins#9666eb5f4a0ebf028e0496b4ee0e1bb9bafb8fae&path:packages/tlsearchREADME
Read the full README ↗📊 额度自查工具 tlsearch_usage
配置里存在 Tavily 后端时,会额外注册一个无入参的 tlsearch_usage 工具,
返回一行额度信息:
Tavily "Researcher": 137/1000 credits used this cycle; 863 remaining (each search costs 1 credit).
用途:让 agent 在搜索开始出现配额/限流错误时(或准备发起大批搜索前)自己查一下余量, 据此收敛搜索频率,而不是把额度打空后才发现。
设计取舍:只在配置了 Tavily 时注册。其余后端(Brave / SearXNG / Google / Exa) 没有机器可读的额度接口,注册一个永远只会说「请去控制台看」的工具纯粹是每轮 Token 浪费。 被调用时若后端确实不支持,会如实说明而不是编一个看起来合理的数字—— 一个假的剩余额度比没有额度信息更糟。
⚙️ 配置
配置有两条路径:宿主 GUI 的 Settings > Plugins > Plugin configuration > tlsearch,
或在 Profile 目录下的 ~/.dsh/profiles/web/cordis.patch.yml 里按 id 覆盖
(注意是覆盖,不是再插一条 - insert: —— 挂载已由 bundle 完成,重复插入会挂载两次):
- id: dsh-plugin-tlsearch
config:
provider: searxng # tavily | searxng | google | brave | exa
baseUrl: "http://localhost:8080" # SearXNG 必填;也可指向自建代理
# apiKey: "…" # SearXNG 不需要;其余后端必填
# cx: "…" # 仅 provider=google 需要(CSE 引擎 ID)
fallback: # 可选:主后端失败/熔断时自动改用备用后端
provider: tavily
apiKey: "tvly-xxxxxxxxxxxx"
maxResults: 5 # 1-10,默认 5
maxSnippetChars: 250 # 单条摘要字符上限,默认 250(控制 Token 的主旋钮)
timeoutMs: 15000 # 单次请求超时(毫秒),默认 15000
outputFormat: markdown # markdown(最省)| json
language: "" # 如 zh / en;留空由后端判定
includeAnswer: false # 是否附带后端的一句话答案(默认 false 以省 Token)
也可以完全不在这里写
apiKey,改用环境变量(见下节),配置层就不必碰密钥。
配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
provider | tavily | 主后端:tavily / searxng / google / brave / exa |
apiKey | '' | 主后端密钥;留空时回退环境变量(SearXNG 可留空) |
baseUrl | 后端默认端点 | 主后端端点根地址;SearXNG 必填 |
cx | '' | Google CSE 引擎 ID;provider=google 时必填(与 apiKey 缺一不可) |
fallback | none | 单个备用后端(简写,等价于 chain 的第一个元素)。字段同 chain 的元素 |
chain[] | [] | 后备后端链:主后端失败/熔断时按数组顺序依次尝试。每项含 provider / apiKey / baseUrl / cx。重复的 provider 只保留首次出现 |
maxResults | 5 | 返回条数上限(钳制在 1-10) |
maxSnippetChars | 250 | 单条摘要字符上限(钳制在 40-2000) |
timeoutMs | 15000 | 单次请求超时(钳制在 1000-60000) |
language | '' | 检索语言(Tavily 不发送该字段) |
includeAnswer | false | 是否附带一句话答案(Tavily answer / SearXNG answers) |
outputFormat | markdown | markdown(最省 Token)或 json(结构化,便于精确解析) |
越界值一律钳制而非报错;
null/ 空串等「未提供」形态退回默认值而不是被压成下限。 配置不完整不会导致插件装载失败——工具照常注册,调用时返回分类错误, 便于模型把「去哪儿补配置」原样转述给你。
环境变量回退
配置留空时按顺序回退(通用变量优先于后端专用变量):
| 用途 | 变量 |
|---|---|
| 通用密钥 | TLSEARCH_API_KEY |
| 通用端点 | TLSEARCH_BASE_URL |
| 通用 Google 引擎 ID | TLSEARCH_CX |
| Tavily | TAVILY_API_KEY、TAVILY_BASE_URL |
| Brave | BRAVE_SEARCH_API_KEY、BRAVE_API_KEY、BRAVE_BASE_URL |
| SearXNG | SEARXNG_BASE_URL |
GOOGLE_CSE_API_KEY、GOOGLE_API_KEY、GOOGLE_CSE_ID、GOOGLE_CSE_CX | |
| Exa | EXA_API_KEY、EXA_BASE_URL |
与原生 web_search 的关系
两者可以并存(模型按需选用)。若要替代原生搜索,在 dsh-tool-web 的配置里关掉它的搜索工具:
- id: tool-web
config:
search: false # 保留 web_fetch,仅关闭原生 web_search
配置项
| 配置项 | 默认值 | 说明 |
|---|---|---|
provider | tavily | 主后端:tavily / searxng / google / brave / exa |
apiKey | '' | 主后端密钥;留空时回退环境变量(SearXNG 可留空) |
baseUrl | 后端默认端点 | 主后端端点根地址;SearXNG 必填 |
cx | '' | Google CSE 引擎 ID;provider=google 时必填(与 apiKey 缺一不可) |
fallback | none | 单个备用后端(简写,等价于 chain 的第一个元素)。字段同 chain 的元素 |
chain[] | [] | 后备后端链:主后端失败/熔断时按数组顺序依次尝试。每项含 provider / apiKey / baseUrl / cx。重复的 provider 只保留首次出现 |
maxResults | 5 | 返回条数上限(钳制在 1-10) |
maxSnippetChars | 250 | 单条摘要字符上限(钳制在 40-2000) |
timeoutMs | 15000 | 单次请求超时(钳制在 1000-60000) |
language | '' | 检索语言(Tavily 不发送该字段) |
includeAnswer | false | 是否附带一句话答案(Tavily answer / SearXNG answers) |
outputFormat | markdown | markdown(最省 Token)或 json(结构化,便于精确解析) |
越界值一律钳制而非报错;
null/ 空串等「未提供」形态退回默认值而不是被压成下限。 配置不完整不会导致插件装载失败——工具照常注册,调用时返回分类错误, 便于模型把「去哪儿补配置」原样转述给你。
🔧 后端配置要点
SearXNG(最常见的坑):默认只对浏览器提供 HTML,必须在其 settings.yml 中启用 JSON:
search:
formats:
- html
- json
未启用时本插件会返回明确提示(而不是把 HTML 页面当成结果解析)。
自建 / 中转网关:baseUrl 支持带路径前缀,例如 https://proxy.example/tavily;
Tavily 的密钥同时以请求头与请求体两种形式携带,因此 new-api 这类只读请求体的网关也能直接用。
Brave:需要有效的订阅令牌(X-Subscription-Token);本插件已在请求侧关闭文本装饰
并限定 result_filter=web,避免 `` 标记与 infobox/FAQ 噪声进入上下文。
单元测试(112 个用例,零网络:全部使用假 fetch 与假 Cordis 上下文)
pnpm --filter dsh-plugin-tlsearch run test