# Search Hub 架构 ## 项目定位 统一多搜索引擎聚合服务,提供 Web UI + RESTful API + 管理面板。 ## 目录结构 ``` search-hub/ ├── app.py # Flask 主入口 — API 路由 / 页面路由 / 启动 ├── config.py # 配置加载(Hermes 配置 → config.yaml → 管理面板) ├── config.yaml # 搜索源密钥 / base_url 等配置 ├── requirements.txt # Python 依赖 │ ├── providers/ # 搜索源适配器层 │ ├── base.py # 抽象基类 BaseProvider + SearchResult │ ├── tavily_provider.py # Tavily API │ ├── baidu_provider.py # 百度千帆(网页搜索 / 智能检索) │ ├── duckduckgo_provider.py # DuckDuckGo(免费,默认关闭) │ ├── searxng_provider.py # SearXNG 自托管元搜索引擎 │ └── ai_provider.py # AI 总结服务(非搜索源) │ ├── hub/ # 核心逻辑层 │ ├── router.py # 搜索路由器 — 多源路由 / 去重合并 / 自动选择 │ └── config_manager.py # 配置管理 — 读写 config.yaml / 字段 schema / 密钥脱敏 │ ├── templates/ # Jinja2 模板 │ ├── index.html # 搜索页面(Deepseek 风格 UI) │ └── admin.html # 管理面板 + API 文档 │ ├── static/ # 前端资源 │ ├── css/style.css # 全局样式 │ ├── js/app.js # 搜索页交互逻辑 │ └── js/admin.js # 管理面板交互逻辑 │ └── docs/ # 项目文档 ├── architecture.md # 本文件 — 技术架构与设计决策 └── providers.md # 搜索源接入指南 ``` ## 数据流 ``` 用户输入 │ ▼ app.py: /api/search │ ▼ hub/router.py: SearchRouter.search() │ ├─ source='auto' → 按优先级遍历可用源,去重合并 │ ├─ source='tavily' → 单一源搜索 │ └─ source='a,b,c' → 多源并发搜索 │ ▼ providers/*.search() ← 各搜索源适配器调用外部 API │ ▼ SearchResult 列表 → 去重 → 排序 → JSON 响应 ``` ## 配置优先级 管理面板保存 > config.yaml > Hermes 配置 修改配置后调用 `_reload_providers()` 热加载,无需重启。 ## 搜索源优先级 | 源 | 优先级 | API Key | 说明 | |---|---|---|---| | Tavily | 10 | 需要 | 默认首选 | | 百度搜索 | 20 | 需要 | 千帆网页搜索 | | 百度智能检索 | 21 | 需要 | 千帆 AI 检索 | | SearXNG | 25 | 不需要 | 自托管元搜索 | | DuckDuckGo | 30 | 不需要 | 国内不可用,默认关闭 | | AI 总结 | 50 | 需要 | 仅用于总结,非搜索源 |