# dsh-web-search-glm **Repository Path**: dsh-plugin/dsh-web-search-glm ## Basic Information - **Project Name**: dsh-web-search-glm - **Description**: No description available - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-08-28 - **Last Updated**: 2026-08-28 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # dsh-web-search-glm 面向 dsh `ctx.web` 插缝的智谱 GLM 联网搜索 provider。通过 GLM 的 Anthropic 兼容端点执行原生 `web_search_20250305` 服务端工具,并把 GLM 的 `web_search_prime` 结果块映射为规范化的搜索 sources。 ## 工作原理 发出的请求与官方 `@deepseek-ai/dsh-web-search-deepseek` provider 完全同形:`POST {baseURL}/messages`,携带 `web_search_20250305` 服务端工具(由 `max_uses` 限定次数)、`anthropic-version` 头、`redirect: "error"`,并完整支持 `AbortSignal`。 差异全部在响应映射层。GLM 不返回 Anthropic 标准的 `web_search_tool_result` 块,而是返回自家的一对块: - 名为 `web_search_prime` 的 `server_tool_use` 块,配对 - `tool_result` 块,其 `content` 是字符串化的 Python repr 搜索结果列表。 provider 按 id 将 `server_tool_use` 与 `tool_result` 配对(一次响应内的多次搜索会合并),解析 content(先 `JSON.parse`,失败则用手写的小型 Python repr 分词器),把每条 `{title, link, content}` 映射为 `{url, title, snippet}`,并按 `url` 去重。 若响应中没有可用的结构化搜索结果,搜索以 `WEB_PROVIDER_ERROR` 失败——不做抓取/摘要兜底,与官方 provider 语义一致。HTTP 非 2xx 时服务端错误消息原文透传(同为 `WEB_PROVIDER_ERROR`)。其余错误码:无法解析出 API key 时为 `WEB_PROVIDER_CREDENTIAL_MISSING`,取消时为 `WEB_ABORTED`。 端点实测行为(2026-08-27 实跑):GLM 不会拒绝无意义查询——照常执行 web search 并返回约 10 条 sources,因此很少走到「无结果」分支;这是端点自身行为,provider 侧没有(也无需)相应配置。该端点的搜索与对话流量一样走 GLM Coding Plan 计费。 ## 安装 从 dsh 插件市场安装(包上架后): ```bash dsh plugin --profile add dsh-web-search-glm ``` 或从本地路径安装: ```bash dsh plugin --profile add /path/to/dsh-web-search-glm ``` **无论哪种方式,都必须显式选择 provider。** `dsh-web` 从 `web` 行的 config 读取选择——`dsh-base` bundle 写死了 `deepseek-official`,而 `~/.dsh/settings.yaml` 里的 `web:` 节对它不生效。请在 profile 自己的补丁层 `~/.dsh/profiles//cordis.patch.yml`(在所有 bundle 层之后应用)覆盖: ```yaml # ~/.dsh/profiles/web/cordis.patch.yml - id: web config: searchProvider: glm ``` id 定向 patch 会整体替换目标行的 `config`——需复述 base 行拥有的全部键(目前只有 `searchProvider`)。 在启动环境导出 `DSH_WEB_SEARCH_PROVIDER=glm` 也可以。 若不写这一段,而官方 `@deepseek-ai/dsh-web-search-deepseek` provider 也已安装且 available,则多个搜索 provider 同时 `available()`,dsh-web 会抛 `WEB_PROVIDER_AMBIGUOUS` 而不是猜测。 ## 配置 配置位于 `~/.dsh/settings.yaml` 的 `web-search-glm` 节: | 键 | 默认值 | 说明 | | --- | --- | --- | | `apiKey` | — | 字面 API key(secret)。推荐改用 `apiKeyEnv` 凭据引用。 | | `apiKeyEnv` | `ZAI_API_KEY` | 凭据引用名。与你 dsh settings 中 `zai` provider 的 `apiKeyEnv` 保持一致,即可共用同一把已存储的 key。 | | `baseURL` | `https://open.bigmodel.cn/api/anthropic/v1` | Anthropic 兼容端点;`/messages` 由 provider 拼接。海外部署可指向 `https://api.z.ai/api/anthropic/v1`。 | | `model` | `glm-5.3` | 执行原生 web search 的模型。已实测可用——见[模型说明](#模型说明)。 | | `apiVersion` | `2023-06-01` | `anthropic-version` 头的取值。 | | `maxTokens` | `4096` | Messages 请求生成 token 的上限。 | | `maxUses` | `5` | 每次请求 `web_search` 服务端工具的最大使用次数。 | 示例: ```yaml # ~/.dsh/settings.yaml —— 插件选项(provider 选择在 profile 补丁层,见「安装」): web-search-glm: apiKeyEnv: ZAI_API_KEY # baseURL: https://api.z.ai/api/anthropic/v1 # 海外端点 # model: glm-5.3-flash # 实测可用的备选,见「模型说明」 ``` **凭据解析链。** key 按每次搜索解析,顺序为:`web-search-glm` 节中设置的字面 `apiKey` → 凭据服务(经 `apiKeyEnv` 引用)→ 启动环境中的同名变量。全部解析不到时,搜索以 `WEB_PROVIDER_CREDENTIAL_MISSING` 失败。 **端点环境变量兜底。** 若 `web-search-glm` 节未设置 `baseURL`,先查启动环境的 `GLM_SEARCH_BASE_URL`,再落到内置默认值。该变量刻意与任何 chat-completions base URL 变量区分命名——搜索走 Anthropic 兼容 Messages API、有独立地址(对齐上游 `DEEPSEEK_SEARCH_BASE_URL` 的模式)。 ## 模型说明 - `glm-5.3`(默认)——2026-08-27 实测可用:英文、中文查询各返回 10 条 sources,原生 web search 确已执行。 - `glm-5.3-flash`——2026-08-27 实测可用:四案例(english / chinese / nonsense / bad-key)行为与 `glm-5.3` 完全一致,真实搜索确已执行(英文、中文各返回 10 条 sources)。可作为备选——把配置设为 `model: glm-5.3-flash` 即可。 - `glm-5-flash`——该端点上不存在此模型名。每次请求都被服务端以 `[1214][modelCode:不存在]` 拒绝(以 `WEB_PROVIDER_ERROR` 呈现)。请勿使用此名称。 包的默认值仍为 `glm-5.3`;不因 flash 变体可用而更改默认。 ## 兼容性 - 面向 `dsh >= 0.1.1-rc.2` 的 dsh 插缝协议(peer 依赖 `@deepseek-ai/dsh-*` `^0.1.1-rc.2`)。 - MIT License——见 [LICENSE](LICENSE)。 ## 开发 - `npm test`——基于内置 `node:test` 运行器的解析器单测;无额外 dev 依赖。fixtures 为实抓的 GLM 响应样本,位于 `test/fixtures/`。 - `npm run capture`——一次性实跑抓取,刷新 `test/fixtures/`(`scripts/capture.mjs`)。需要 `ZAI_API_KEY`(回落 `ANTHROPIC_AUTH_TOKEN`)。 - `npm run smoke`——实跑端点的冒烟,四案例(english / chinese / nonsense / bad-key):`node scripts/smoke.mjs [model]`。需要 `ZAI_API_KEY`(回落 `ANTHROPIC_AUTH_TOKEN`)。 live 脚本刻意放在 `scripts/` 而非 `test/`——否则 Node 26 的 `node --test` 自动发现会在 `npm test` 时执行它们——且它们不随 npm 包发布。