fix(hands): 搜索引擎优先级调整 — 国内用户优先百度+Bing CN
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled

中国用户无法使用 Google/DuckDuckGo(被墙),调整策略:
1. Google/DuckDuckGo 路由降级到百度(非Bing)
2. search_native() 所有查询统一百度+Bing CN并行
3. DDG仅作为最后后备(主引擎都空时才尝试)
4. 移除 CJK 分支逻辑 — 百度+Bing CN 对中英文都有效
This commit is contained in:
iven
2026-04-22 14:06:20 +08:00
parent 46fee4b2c8
commit bb1869bb1b

View File

@@ -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<Vec<SearchResult>> {
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);
}
}