资讯动态

OpenClaude Web Search 多后端搜索提供者接入指南:环境变量、请求格式与安全防护全解析

发布时间:2026/9/10 16:18:41 来源:尧图企业网站定制
OpenClaude Web Search 多后端搜索提供者接入指南环境变量、请求格式与安全防护全解析【免费下载链接】openclauderuns anywhere. uses anything项目地址: https://gitcode.com/GitHub_Trending/op/openclaude本文以 OpenClaude 仓库中的 README_SEARCH_PROVIDERS.md 为骨架系统讲解 WebSearchTool 的搜索提供者Provider适配架构支持的后端清单、WEB_SEARCH_PROVIDER选择模式、每个后端的请求/响应格式、Custom API 的灵活配置、鉴权方式、响应解析规则以及自定义提供者的安全护栏。读完本文你将能够根据自身网络环境与成本预算为 OpenClaude 配置一条可靠、可控、可回退的 Web 搜索链路并能对照源码理解每个环境变量的底层影响。一、架构总览Provider 适配器系统OpenClaude 的 Web 搜索能力通过一套 Provider 适配器系统接入多种后端而非绑定单一搜索 API。核心入口在 WebSearchTool.ts其中runSearch、getProviderMode、getAvailableProviders均来自 providers/index.ts。从源码结构看每个后端都实现统一的SearchProvider接口定义在 providers/types.tsexport interface SearchProvider { readonly name: string // 用于 tool_use_id 与日志 isConfigured(): boolean // 所需环境变量是否就绪 search(input: SearchInput, signal?: AbortSignal): PromiseProviderOutput }ProviderOutput统一输出hitsSearchHit[]、providerName与durationSeconds。域名过滤、摘要格式化、结果块构造等共享逻辑放在 Tool 层而非各适配器内部——这正是所有后端能保持行为一致的原因。当前支持的提供者如下表所示完整信息见 README_SEARCH_PROVIDERS.mdProviderEnv VarAuth HeaderMethodCustom APIWEB_SEARCH_APIConfigurableGET/POSTSearXNGWEB_PROVIDERsearxng—GETGoogleWEB_PROVIDERgoogleGOOGLE_CSE_ID(query param?key)GETBrave (preset)WEB_PROVIDERbraveX-Subscription-TokenGETBrave (adapter)BRAVE_API_KEYX-Subscription-TokenGETSerpAPIWEB_PROVIDERserpapiAuthorization: BearerGETFirecrawlFIRECRAWL_API_KEYInternalSDKTavilyTAVILY_API_KEYAuthorization: BearerPOSTExaEXA_API_KEYx-api-keyPOSTYou.comYOU_API_KEYX-API-KeyGETJinaJINA_API_KEYAuthorization: BearerGETBingBING_API_KEYOcp-Apim-Subscription-KeyGETMojeekMOJEEK_API_KEYAuthorization: BearerGETLinkupLINKUP_API_KEYAuthorization: BearerPOSTDuckDuckGo(default)—SDK其中 DuckDuckGo 是内置默认回退项无需任何配置即可使用其余均需要对应 API Key。二、快速开始按需选择其一即可启用搜索# Tavily面向 AI 推荐快速、RAG-ready export TAVILY_API_KEYtvly-your-key # Exa神经搜索适合语义化查询 export EXA_API_KEYyour-exa-key # Brave独立索引免费额度友好 export BRAVE_API_KEYyour-brave-key # Bing export BING_API_KEYyour-bing-key # 自托管 SearXNG免费、私密 export WEB_PROVIDERsearxng export WEB_SEARCH_APIhttps://search.example.com/search三、提供者选择模式WEB_SEARCH_PROVIDERWEB_SEARCH_PROVIDER控制搜索的启用与回退行为其取值在 providers/index.ts 中被解析为ProviderModeModeBehaviorauto(default)Try all configured providers in order, fall through on failuretavilyTavily only — throws on failureexaExa only — throws on failurebraveBrave only — throws on failurecustomCustom API only — throws on failure.Not in the auto chain— must be explicitly selectedfirecrawlFirecrawl only — throws on failureddgDuckDuckGo only — throws on failurenativeAnthropic native / Codex onlyAuto 模式优先级firecrawl → tavily → exa → you → jina → brave → bing → mojeek → linkup → ddg注意custom提供者被有意排除在auto链之外只有在显式设置WEB_SEARCH_PROVIDERcustom时才会被使用。这是为了防止通用的出站 HTTP 提供者在未授权的情况下悄悄成为默认后端。这一顺序在 providers/index.ts 的ALL_PROVIDERS数组中固化源码注释还解释了排序依据DDG 免费但易被限流故放最后Brave 因运行独立索引不依赖 Google/Bing且有可用免费额度而排在 Bing 之前Bing 托管 API 对新增用户已停售。# Tavily 宕机时直接报错不静默切换后端 export WEB_SEARCH_PROVIDERtavily # 全部尝试优雅回退 export WEB_SEARCH_PROVIDERautoauto是唯一会静默回退到下一个提供者的模式其他模式失败即抛错不做后端切换。runSearch的实现细节特定模式下若目标提供者未配置会直接抛出Search provider mode is not configured并提示设置对应*_API_KEY环境变量或切回auto若用户主动中断AbortError则立即停止不会回退到其他提供者。另外在auto/native模式下原生路径优先于适配器当 API Provider 为 firstParty官方 Anthropic 端点、Vertex 或 Foundry或启用 Codex Responses 时会优先走 Anthropicweb_search_20250305原生工具或 Codex 的web_search只有无原生路径可用时才落到适配器链对应 WebSearchTool.ts 的shouldUseAdapterProvider。四、内置提供者超时机制内置适配器提供者统一使用15 秒请求超时这样auto模式在后端卡死时可以及时回退到下一个提供者。可用以下变量覆盖export WEB_SEARCH_TIMEOUT_SEC30超时解析逻辑在 providers/timeout.ts非法值、小数、零、负数或超大值超过 300 秒都会回退到默认 15 秒——环境变量必须匹配/^\d$/且落在(0, 300]区间内的安全整数才生效。Custom API 提供者保留独立的WEB_CUSTOM_TIMEOUT_SEC默认 120s因为自托管端点可能需要不同的预算。此外Custom 适配器还通过createCombinedAbortSignal将调用方信号与超时信号组合每次尝试都使用全新的超时并正确清理 abort 监听器避免泄漏。五、各提供者的请求与响应格式以下格式均为 OpenClaude 实际发出的 HTTP 请求及解析目标可直接用于联调或自建兼容端点。Tavilyexport TAVILY_API_KEYtvly-your-keyRequest:POST https://api.tavily.com/search Authorization: Bearer tvly-your-key Content-Type: application/json {query: search terms, max_results: 10, include_answer: false}Response:{ results: [ { title: Result Title, url: https://example.com/page, content: Full text snippet from the page..., score: 0.95 } ] }源码 tavily.ts 实际发送max_results: 15并将响应的content ?? snippet映射为description。Exaexport EXA_API_KEYyour-exa-keyRequest:POST https://api.exa.ai/search x-api-key: your-exa-key Content-Type: application/json {query: search terms, numResults: 10, type: auto}Response:{ results: [ { title: Result Title, url: https://example.com/page, snippet: A short summary of the page content..., score: 0.89 } ] }exa.ts 的实现有两个值得注意的点请求体额外携带contents: { highlights: true }——Exa 官方文档明确推荐 Agent 工作流使用 highlights比全文少 10 倍 token且只返回与查询最相关的片段同时会把allowed_domains/blocked_domains转换为服务端参数includeDomains/excludeDomains由 Exa 在服务端完成域名过滤而不是在客户端事后过滤。You.comexport YOU_API_KEYyour-you-keyRequest:GET https://api.ydc-index.io/v1/search?querysearchterms X-API-Key: your-you-keyResponse:{ results: { web: [ { title: Result Title, url: https://example.com/page, snippets: [First snippet from the page..., Second snippet...], description: Page description } ] } }Jinaexport JINA_API_KEYyour-jina-keyRequest:GET https://s.jina.ai/?qsearchterms Authorization: Bearer your-jina-key Accept: application/jsonResponse:{ data: [ { title: Result Title, url: https://example.com/page, description: Snippet from the page... } ] }Bingexport BING_API_KEYyour-bing-keyRequest:GET https://api.bing.microsoft.com/v7.0/search?qsearchtermscount10 Ocp-Apim-Subscription-Key: your-bing-keyResponse:{ webPages: { value: [ { name: Result Title, url: https://example.com/page, snippet: A short excerpt from the page..., displayUrl: example.com/page } ] } }Mojeekexport MOJEEK_API_KEYyour-mojeek-keyRequest:GET https://www.mojeek.com/search?qsearchtermsfmtjson Authorization: Bearer your-mojeek-keyResponse:{ response: { results: [ { title: Result Title, url: https://example.com/page, snippet: Excerpt from the page... } ] } }Linkupexport LINKUP_API_KEYyour-linkup-keyRequest:POST https://api.linkup.so/v1/search Authorization: Bearer your-linkup-key Content-Type: application/json {q: search terms, search_type: standard}Response:{ results: [ { name: Result Title, url: https://example.com/page, snippet: A short description of the result... } ] }SearXNG内置 Presetexport WEB_PROVIDERsearxng export WEB_SEARCH_APIhttps://search.example.com/searchRequest:GET https://search.example.com/search?qsearchtermsResponse:{ results: [ { title: Result Title, url: https://example.com/page, content: Snippet from the page..., engine: google } ] }注意 custom.ts 中 SearXNG preset 的默认 URL 模板是https://localhost:8080/search——用户必须用WEB_SEARCH_API覆盖为真实实例地址。由于 HTTPS-only 护栏的存在原先的http://默认值已被有意移除。Google Custom Search内置 Preset⚠️Sunset 2027-01-01。Google 已宣布 Custom Search JSON API 将于 2027 年 1 月 1 日停止服务且已对新客户关闭。新项目请使用 Brave / Tavily / Exa。export WEB_PROVIDERgoogle export WEB_KEYyour-google-api-key export GOOGLE_CSE_IDyour-programmable-search-engine-idGOOGLE_CSE_ID即 Programmable Search Engine 中的cx值——API Key 与引擎 ID 两者缺一不可。Request:GET https://www.googleapis.com/customsearch/v1?qsearchtermskeyyour-google-api-keycxyour-engine-idResponse:{ items: [ { title: Result Title, link: https://example.com/page, snippet: A short excerpt..., displayLink: example.com } ] }源码层面Google preset 通过authQueryParam: key将密钥放在查询参数而非 Header并通过envQueryParams: { cx: GOOGLE_CSE_ID }要求GOOGLE_CSE_ID必须设置否则请求会快速失败并给出明确错误——而不是等到上游返回 4xx。Brave一级适配器推荐方式——自动检测自动加入 auto 回退链。export BRAVE_API_KEYyour-brave-keyRequest:GET https://api.search.brave.com/res/v1/web/search?qsearchtermscount15 X-Subscription-Token: your-brave-keybrave.ts 发送裸 token无Bearer前缀并请求Accept: application/json与count15。Brave内置 Preset替代方案适合偏好通用 preset 路径的用户功能上与上面的适配器等价二选一即可。export WEB_PROVIDERbrave export WEB_KEYyour-brave-keyResponse:{ web: { results: [ { title: Result Title, url: https://example.com/page, description: Page description... } ] } }SerpAPI内置 Presetexport WEB_PROVIDERserpapi export WEB_KEYyour-serpapi-keyRequest:GET https://serpapi.com/search.json?qsearchterms Authorization: Bearer your-serpapi-keyResponse:{ organic_results: [ { title: Result Title, link: https://example.com/page, snippet: A short excerpt..., displayed_link: example.com } ] }DuckDuckGo默认回退无需任何配置。底层使用duck-duck-scrapenpm 包运行时依赖isConfigured()恒为true# 设为仅显式使用的后端 export WEB_SEARCH_PROVIDERddgduckduckgo.ts 的实现还包含最多 3 次重试、指数退避加抖动1s/2s/4s ± 20%、SafeSearchType.STRICT安全搜索当命中 anomaly in the request数据中心 IP / 高频请求被 DDG 反爬拦截时会抛出可操作的提示引导用户配置其他后端。这正是文档中 DuckDuckGo 是默认但易被限流 警告的源码印证。六、Custom API 配置custom提供者是最灵活的路径任何 HTTP 端点都可以接入且默认带安全护栏。以下环境变量均在 custom.ts 的resolveConfig/buildRequest中解析。标准 GETGET https://api.example.com/search?qhelloexport WEB_SEARCH_APIhttps://api.example.com/search export WEB_QUERY_PARAMqWEB_QUERY_PARAM指定查询词所在参数名默认q。查询词放在 URL 路径中GET https://api.example.com/v2/search/helloexport WEB_URL_TEMPLATEhttps://api.example.com/v2/search/{query}模板中的{query}占位符会被encodeURIComponent(query)替换。若模板不含{query}则查询词作为WEB_QUERY_PARAM参数附加。POST 自定义请求体POST https://api.example.com/v1/query Content-Type: application/json {input: {text: hello}}export WEB_SEARCH_APIhttps://api.example.com/v1/query export WEB_METHODPOST export WEB_BODY_TEMPLATE{input:{text:{query}}}WEB_BODY_TEMPLATE中的{query}同样会被替换未设置时POST 默认发送{q: query}参数名取WEB_QUERY_PARAM。附加静态参数export WEB_PARAMS{lang:en,count:10}WEB_PARAMS为 JSON 对象会以url.searchParams.set方式合并进 URL。七、鉴权API Key 一律通过 HTTP Header 发送绝不放查询字符串Google 是唯一例外因其上游只接受?key。# 默认Authorization: Bearer key export WEB_KEYyour-key # 自定义 Header export WEB_AUTH_HEADERX-Api-Key export WEB_AUTH_SCHEME # 附加 Header分号分隔的 key: value 对 export WEB_HEADERSX-Tenant: acme; Accept: application/jsonWEB_AUTH_SCHEME表示裸 token如 Brave 的X-Subscription-TokenWEB_AUTH_HEADER表示完全禁用鉴权头。preset 可覆盖默认行为例如 SearXNG 无鉴权、Brave 用X-Subscription-Token、Google 用查询参数。WEB_HEADERS中每个 Header 名都会经过安全名单校验见下文。八、响应解析工具会自动识别多种常见响应格式无需额外配置{ results: [{ title: ..., url: ... }] } // flat array { items: [{ title: ..., link: ... }] } // Google-style { results: { engine: [{ title: ..., url: ... }] } } // nested map [{ title: ..., url: ... }] // bare array字段名别名见 types.ts 的normalizeHit标题title/headline/name/heading链接url/link/href/uri/permalink描述description/snippet/content/preview/summary/text/body对于深层嵌套响应可指定 JSON 路径export WEB_JSON_PATHresponse.payload.resultsextractHits的实现会先尝试jsonPath再按results、items、data、web、organic_results、hits、entries等键自动探测数组。九、重试策略Custom 提供者的失败请求网络错误、5xx会在500ms 后重试一次客户端错误4xx不重试默认超时120 秒。重试逻辑位于 custom.ts 的fetchWithRetry且调用方主动中断abort时不做重试。十、Custom 提供者安全护栏由于custom是一个通用出站 HTTP 客户端为降低 SSRF 与数据外泄风险默认强制以下护栏GuardrailDefaultOverrideHTTPS-only✅WEB_CUSTOM_ALLOW_HTTPtrueBlock private IPs / localhost✅WEB_CUSTOM_ALLOW_PRIVATEtrueHeader allowlist✅WEB_CUSTOM_ALLOW_ARBITRARY_HEADERStrueMax POST body300 KBWEB_CUSTOM_MAX_BODY_KBkbRequest timeout120sWEB_CUSTOM_TIMEOUT_SECsecondsAudit log (one-time warning)✅—自托管 SearXNG 示例export WEB_PROVIDERsearxng export WEB_SEARCH_APIhttps://search.mydomain.com/search export WEB_CUSTOM_ALLOW_PRIVATEtrue # SearXNG 在内网 IP 时需要Header 白名单默认仅允许以下 Headeraccept,accept-encoding,accept-language,authorization,cache-control,content-type,if-modified-since,if-none-match,ocp-apim-subscription-key,user-agent,x-api-key,x-subscription-token,x-tenant-id源码纵深私网检测并非简单的正则而是基于 WHATWGnew URL()的规范化 hostname 做 IPv4/IPv6 全面校验——127.1、2130706433、0x7f000001、0177.0.0.1等短格式/十进制/十六进制/八进制 IPv4 变体都会被归一化为127.0.0.1并拦截IPv6 处理覆盖::压缩、内嵌 IPv4如::ffff:127.0.0.1、ULAfc00::/7、link-localfe80::/10、loopback::1等见 custom.ts 的isPrivateHostname。此外还有一次性的审计日志警告提示出站请求去向防止静默数据外泄。十一、新增一个 Provider适配器架构让新增后端非常轻量只需两步创建providers/myprovider.tsimport type { SearchInput, SearchProvider } from ./types.js import { applyDomainFilters, type ProviderOutput } from ./types.js export const myProvider: SearchProvider { name: myprovider, isConfigured() { return Boolean(process.env.MYPROVIDER_API_KEY) }, async search(input: SearchInput): PromiseProviderOutput { const start performance.now() // ... call API, map to SearchHit[] ... return { hits: applyDomainFilters(hits, input), providerName: myprovider, durationSeconds: (performance.now() - start) / 1000, } }, }在providers/index.ts中注册——添加 import 并 push 到ALL_PROVIDERS。需要注意的是ALL_PROVIDERS的顺序即 auto 模式的优先级若新增提供者要加入 auto 链需按业务诉求放在合适位置。若希望像custom一样被排除在 auto 链之外则只注册到PROVIDER_BY_NAME即可。新适配器建议统一使用fetchJsonWithWebSearchTimeout或withWebSearchTimeout以继承 15 秒默认超时与WebSearchTimeoutError语义并复用applyDomainFilters保证域名过滤行为与其他提供者一致。十二、与 Tool 层的联动从环境变量到搜索结果理解配置后可再沿调用链看清全貌WebSearchTool.ts启用判断isEnabled()根据WEB_SEARCH_PROVIDER模式、已配置适配器、原生路径可用性firstParty/Vertex/Foundry 或 Codex Responses综合决定工具是否可用。Vertex 仅对 Claude 4.x 系列模型启用原生 web search。执行分支call()依次判断——适配器路径shouldUseAdapterProvider→ Codex Responses 路径 → 原生 Anthropic 路径。auto模式下原生路径优先适配器失败时仅对瞬时错误网络、超时、5xx回退配置类/护栏类错误HTTPS、私网地址、Header 白名单、URL 非法等必须立即浮出见isTransientError。空结果提示当适配器返回 0 条结果、而当前模型提供商又没有原生搜索回退时如 moonshot/minimax/nvidia-nim 等 openai-shim 提供商工具会返回可操作的诊断提示说明 DDG 默认后端在数据中心 IP / VPN 下易被限流建议配置FIRECRAWL_API_KEY等密钥。输入校验query必填allowed_domains与blocked_domains不能同时出现。输出归一适配器输出统一格式化为文本摘要 带链接的结果块并在最终 tool_result 中提醒模型必须用 Markdown 超链接引用来源。十三、选型建议与适用前提追求开箱即用什么都不配DDG 兜底但注意数据中心 IP 限流风险。追求可靠与 AI 友好优先 TavilyRAG-ready或 Firecrawl爬虫能力强的 SDK语义检索场景选 Exaneural search。自托管/隐私敏感SearXNG配合WEB_CUSTOM_ALLOW_PRIVATEtrue打通内网实例。作为后备Brave 独立索引 免费额度友好适合排在 auto 链靠前位置。以上配置项与行为均以当前仓库源码为准providers 目录下有各提供者的实现与测试用例如 brave.test.ts、custom.test.ts、timeout.test.tsGoogle Custom Search 已进入 Sunset 倒计时2027-01-01新接入请优先考虑 Brave/Tavily/Exa。【免费下载链接】openclauderuns anywhere. uses anything项目地址: https://gitcode.com/GitHub_Trending/op/openclaude创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价