From bb1869bb1b73737b609c9d9dc5140f1f18a2586b Mon Sep 17 00:00:00 2001 From: iven Date: Wed, 22 Apr 2026 14:06:20 +0800 Subject: [PATCH] =?UTF-8?q?fix(hands):=20=E6=90=9C=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E6=93=8E=E4=BC=98=E5=85=88=E7=BA=A7=E8=B0=83=E6=95=B4=20?= =?UTF-8?q?=E2=80=94=20=E5=9B=BD=E5=86=85=E7=94=A8=E6=88=B7=E4=BC=98?= =?UTF-8?q?=E5=85=88=E7=99=BE=E5=BA=A6+Bing=20CN?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 中国用户无法使用 Google/DuckDuckGo(被墙),调整策略: 1. Google/DuckDuckGo 路由降级到百度(非Bing) 2. search_native() 所有查询统一百度+Bing CN并行 3. DDG仅作为最后后备(主引擎都空时才尝试) 4. 移除 CJK 分支逻辑 — 百度+Bing CN 对中英文都有效 --- crates/zclaw-hands/src/hands/researcher.rs | 64 +++++++++------------- 1 file changed, 25 insertions(+), 39 deletions(-) diff --git a/crates/zclaw-hands/src/hands/researcher.rs b/crates/zclaw-hands/src/hands/researcher.rs index 829ae7a..742c910 100644 --- a/crates/zclaw-hands/src/hands/researcher.rs +++ b/crates/zclaw-hands/src/hands/researcher.rs @@ -324,11 +324,13 @@ impl ResearcherHand { self.search_native(&query.query, max_results).await? } SearchEngine::DuckDuckGo => { - self.search_duckduckgo_html(&query.query, max_results).await? + // DDG在国内不可用,降级到百度 + tracing::warn!(target: "researcher", "DuckDuckGo在国内不可用,降级到百度"); + self.search_baidu(&query.query, max_results).await? } SearchEngine::Google => { - tracing::warn!(target: "researcher", "Google 不支持直接搜索,降级到 Bing"); - self.search_bing(&query.query, max_results).await? + tracing::warn!(target: "researcher", "Google在国内不可用,降级到百度"); + self.search_baidu(&query.query, max_results).await? } SearchEngine::Bing => { self.search_bing(&query.query, max_results).await? @@ -348,48 +350,32 @@ impl ResearcherHand { Ok(results) } - /// Rust-native multi-engine search with Chinese auto-detection + /// Rust-native multi-engine search — optimized for China mainland users + /// Priority: Baidu + Bing CN (both always work in China) + /// DuckDuckGo as optional fallback (may be blocked by GFW) async fn search_native(&self, query: &str, max_results: usize) -> Result> { - let has_cjk = query.chars().any(|c| is_cjk_char(c)); - - // Strategy: try multiple engines in parallel, merge results let mut all_results = Vec::new(); - if has_cjk { - // Chinese query: Bing CN + Baidu + DuckDuckGo in parallel - let bing_fut = self.search_bing(query, max_results); - let baidu_fut = self.search_baidu(query, max_results); - let ddg_fut = self.search_duckduckgo_html(query, max_results); + // Always use Baidu + Bing CN in parallel (both work in China) + let baidu_fut = self.search_baidu(query, max_results); + let bing_fut = self.search_bing(query, max_results); - let (bing_res, baidu_res, ddg_res) = tokio::join!( - async { bing_fut.await }, - async { baidu_fut.await }, - async { ddg_fut.await }, - ); + let (baidu_res, bing_res) = tokio::join!( + async { baidu_fut.await }, + async { bing_fut.await }, + ); - if let Ok(r) = bing_res { - all_results.extend(r); - } - if let Ok(r) = baidu_res { - all_results.extend(r); - } - if let Ok(r) = ddg_res { - all_results.extend(r); - } - } else { - // English query: DuckDuckGo HTML first, then Bing - let ddg_fut = self.search_duckduckgo_html(query, max_results); - let bing_fut = self.search_bing(query, max_results); + if let Ok(r) = baidu_res { + all_results.extend(r); + } + if let Ok(r) = bing_res { + all_results.extend(r); + } - let (ddg_res, bing_res) = tokio::join!( - async { ddg_fut.await }, - async { bing_fut.await }, - ); - - if let Ok(r) = ddg_res { - all_results.extend(r); - } - if let Ok(r) = bing_res { + // If both primary engines returned nothing, try DDG as last resort + if all_results.is_empty() { + tracing::info!(target: "researcher", "Primary engines empty, trying DuckDuckGo as fallback"); + if let Ok(r) = self.search_duckduckgo_html(query, max_results).await { all_results.extend(r); } }