search-layer
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSearch Layer v2.2 — 意图感知多源检索协议
Search Layer v2.2 — Intent-Aware Multi-Source Retrieval Protocol
四源同级:Brave () + Exa + Tavily + Grok。按意图自动选策略、调权重、做合成。
web_searchFour equal-tier sources: Brave () + Exa + Tavily + Grok. Automatically selects strategies, adjusts weights, and performs synthesis based on intent.
web_search执行流程
Execution Flow
用户查询
↓
[Phase 1] 意图分类 → 确定搜索策略
↓
[Phase 2] 查询分解 & 扩展 → 生成子查询
↓
[Phase 3] 多源并行检索 → Brave + search.py (Exa + Tavily + Grok)
↓
[Phase 4] 结果合并 & 排序 → 去重 + 意图加权评分
↓
[Phase 5] 知识合成 → 结构化输出User Query
↓
[Phase 1] Intent Classification → Determine Search Strategy
↓
[Phase 2] Query Decomposition & Expansion → Generate Sub-Queries
↓
[Phase 3] Multi-Source Parallel Retrieval → Brave + search.py (Exa + Tavily + Grok)
↓
[Phase 4] Result Merging & Sorting → Deduplication + Intent-Weighted Scoring
↓
[Phase 5] Knowledge Synthesis → Structured OutputPhase 1: 意图分类
Phase 1: Intent Classification
收到搜索请求后,先判断意图类型,再决定搜索策略。不要问用户用哪种模式。
| 意图 | 识别信号 | Mode | Freshness | 权重偏向 |
|---|---|---|---|---|
| Factual | "什么是 X"、"X 的定义"、"What is X" | answer | — | 权威 0.5 |
| Status | "X 最新进展"、"X 现状"、"latest X" | deep | pw/pm | 新鲜度 0.5 |
| Comparison | "X vs Y"、"X 和 Y 区别" | deep | py | 关键词 0.4 + 权威 0.4 |
| Tutorial | "怎么做 X"、"X 教程"、"how to X" | answer | py | 权威 0.5 |
| Exploratory | "深入了解 X"、"X 生态"、"about X" | deep | — | 权威 0.5 |
| News | "X 新闻"、"本周 X"、"X this week" | deep | pd/pw | 新鲜度 0.6 |
| Resource | "X 官网"、"X GitHub"、"X 文档" | fast | — | 关键词 0.5 |
详细分类指南见references/intent-guide.md
判断规则:
- 扫描查询中的信号词
- 多个类型匹配时选最具体的
- 无法判断时默认
exploratory
Upon receiving a search request, first determine the intent type, then decide the search strategy. Do not ask the user which mode to use.
| Intent | Identification Signals | Mode | Freshness | Weight Bias |
|---|---|---|---|---|
| Factual | "What is X", "Definition of X", "What is X" | answer | — | Authority 0.5 |
| Status | "Latest developments of X", "Current status of X", "latest X" | deep | pw/pm | Freshness 0.5 |
| Comparison | "X vs Y", "Differences between X and Y" | deep | py | Keywords 0.4 + Authority 0.4 |
| Tutorial | "How to do X", "Tutorial for X", "how to X" | answer | py | Authority 0.5 |
| Exploratory | "Deep dive into X", "Ecosystem of X", "about X" | deep | — | Authority 0.5 |
| News | "News about X", "X this week", "X this week" | deep | pd/pw | Freshness 0.6 |
| Resource | "Official website of X", "GitHub of X", "Documentation of X" | fast | — | Keywords 0.5 |
Detailed classification guidelines can be found inreferences/intent-guide.md
Judgment Rules:
- Scan for signal words in the query
- Select the most specific type when multiple types match
- Default to if intent cannot be determined
exploratory
Phase 2: 查询分解 & 扩展
Phase 2: Query Decomposition & Expansion
根据意图类型,将用户查询扩展为一组子查询:
Expand the user's query into a set of sub-queries based on intent type:
通用规则
General Rules
- 技术同义词自动扩展:k8s→Kubernetes, JS→JavaScript, Go→Golang, Postgres→PostgreSQL
- 中文技术查询:同时生成英文变体(如 "Rust 异步编程" → 额外搜 "Rust async programming")
- Automatic expansion of technical synonyms: k8s→Kubernetes, JS→JavaScript, Go→Golang, Postgres→PostgreSQL
- Chinese technical queries: Generate English variants simultaneously (e.g., "Rust 异步编程" → additionally search for "Rust async programming")
按意图扩展
Expansion by Intent
| 意图 | 扩展策略 | 示例 |
|---|---|---|
| Factual | 加 "definition"、"explained" | "WebTransport" → "WebTransport", "WebTransport explained overview" |
| Status | 加年份、"latest"、"update" | "Deno 进展" → "Deno 2.0 latest 2026", "Deno update release" |
| Comparison | 拆成 3 个子查询 | "Bun vs Deno" → "Bun vs Deno", "Bun advantages", "Deno advantages" |
| Tutorial | 加 "tutorial"、"guide"、"step by step" | "Rust CLI" → "Rust CLI tutorial", "Rust CLI guide step by step" |
| Exploratory | 拆成 2-3 个角度 | "RISC-V" → "RISC-V overview", "RISC-V ecosystem", "RISC-V use cases" |
| News | 加 "news"、"announcement"、日期 | "AI 新闻" → "AI news this week 2026", "AI announcement latest" |
| Resource | 加具体资源类型 | "Anthropic MCP" → "Anthropic MCP official documentation" |
| Intent | Expansion Strategy | Example |
|---|---|---|
| Factual | Add "definition", "explained" | "WebTransport" → "WebTransport", "WebTransport explained overview" |
| Status | Add year, "latest", "update" | "Deno 进展" → "Deno 2.0 latest 2026", "Deno update release" |
| Comparison | Split into 3 sub-queries | "Bun vs Deno" → "Bun vs Deno", "Bun advantages", "Deno advantages" |
| Tutorial | Add "tutorial", "guide", "step by step" | "Rust CLI" → "Rust CLI tutorial", "Rust CLI guide step by step" |
| Exploratory | Split into 2-3 perspectives | "RISC-V" → "RISC-V overview", "RISC-V ecosystem", "RISC-V use cases" |
| News | Add "news", "announcement", date | "AI 新闻" → "AI news this week 2026", "AI announcement latest" |
| Resource | Add specific resource types | "Anthropic MCP" → "Anthropic MCP official documentation" |
Phase 3: 多源并行检索
Phase 3: Multi-Source Parallel Retrieval
Step 1: Brave(所有模式)
Step 1: Brave (All Modes)
对每个子查询调用 。如果意图有 freshness 要求,传 参数:
web_searchfreshnessweb_search(query="Deno 2.0 latest 2026", freshness="pw")Call for each sub-query. If the intent has freshness requirements, pass the parameter:
web_searchfreshnessweb_search(query="Deno 2.0 latest 2026", freshness="pw")Step 2: Exa + Tavily + Grok(Deep / Answer 模式)
Step 2: Exa + Tavily + Grok (Deep / Answer Modes)
对子查询调用 search.py,传入意图和 freshness:
bash
python3 /home/node/.openclaw/workspace/skills/search-layer/scripts/search.py \
--queries "子查询1" "子查询2" "子查询3" \
--mode deep \
--intent status \
--freshness pw \
--num 5各模式源参与矩阵:
| 模式 | Exa | Tavily | Grok | 说明 |
|---|---|---|---|---|
| fast | ✅ | ❌ | fallback | Exa 优先;无 Exa key 时用 Grok |
| deep | ✅ | ✅ | ✅ | 三源并行 |
| answer | ❌ | ✅ | ❌ | 仅 Tavily(含 AI answer) |
参数说明:
| 参数 | 说明 |
|---|---|
| 多个子查询并行执行(也可用位置参数传单个查询) |
| fast / deep / answer |
| 意图类型,影响评分权重(不传则不评分,行为与 v1 一致) |
| pd(24h) / pw(周) / pm(月) / py(年) |
| 逗号分隔的域名,匹配的结果权威分 +0.2 |
| 每源每查询的结果数 |
Grok 源说明:
- 通过 completions API 调用 Grok 模型(),利用其实时知识返回结构化搜索结果
grok-4.1 - 自动检测时间敏感查询并注入当前时间上下文
- 在 deep 模式下与 Exa、Tavily 并行执行
- 需要在 TOOLS.md 中配置 、
Grok API URL、Grok API KeyGrok Model - 如果 Grok 配置缺失,自动降级为 Exa + Tavily 双源
Call search.py for sub-queries, passing intent and freshness:
bash
python3 /home/node/.openclaw/workspace/skills/search-layer/scripts/search.py \
--queries "sub-query1" "sub-query2" "sub-query3" \
--mode deep \
--intent status \
--freshness pw \
--num 5Source Participation Matrix by Mode:
| Mode | Exa | Tavily | Grok | Notes |
|---|---|---|---|---|
| fast | ✅ | ❌ | fallback | Prioritize Exa; use Grok if Exa key is unavailable |
| deep | ✅ | ✅ | ✅ | Three sources in parallel |
| answer | ❌ | ✅ | ❌ | Only Tavily (includes AI answer) |
Parameter Explanation:
| Parameter | Description |
|---|---|
| Execute multiple sub-queries in parallel (can also pass a single query as a positional parameter) |
| fast / deep / answer |
| Intent type, affects scoring weights (if not passed, no scoring is performed, behavior is consistent with v1) |
| pd(24h) / pw(week) / pm(month) / py(year) |
| Comma-separated domains, matching results get +0.2 to authority score |
| Number of results per source per query |
Grok Source Notes:
- Call the Grok model () via the completions API, leveraging its real-time knowledge to return structured search results
grok-4.1 - Automatically detects time-sensitive queries and injects current time context
- Executes in parallel with Exa and Tavily in deep mode
- Requires configuring ,
Grok API URL,Grok API Keyin TOOLS.mdGrok Model - If Grok configuration is missing, automatically downgrades to Exa + Tavily dual sources
Step 3: 合并
Step 3: Merging
将 Brave 结果与 search.py 输出合并。按 canonical URL 去重,标记来源。
如果 search.py 返回了 字段,用它排序;Brave 结果没有 score 的,用同样的意图权重公式补算。
scoreMerge Brave results with search.py output. Deduplicate by canonical URL and mark sources.
If search.py returns a field, sort using it; for Brave results without a score, calculate it using the same intent weight formula.
scorePhase 4: 结果排序
Phase 4: Result Sorting
评分公式
Scoring Formula
score = w_keyword × keyword_match + w_freshness × freshness_score + w_authority × authority_score权重由意图决定(见 Phase 1 表格)。各分项:
- keyword_match (0-1):查询词在标题+摘要中的覆盖率
- freshness_score (0-1):基于发布日期,越新越高(无日期=0.5)
- authority_score (0-1):基于域名权威等级
- Tier 1 (1.0): github.com, stackoverflow.com, 官方文档站
- Tier 2 (0.8): HN, dev.to, 知名技术博客
- Tier 3 (0.6): Medium, 掘金, InfoQ
- Tier 4 (0.4): 其他
完整域名评分表见references/authority-domains.json
score = w_keyword × keyword_match + w_freshness × freshness_score + w_authority × authority_scoreWeights are determined by intent (see Phase 1 table). Breakdown of each component:
- keyword_match (0-1): Coverage of query terms in title + abstract
- freshness_score (0-1): Based on publication date, newer results score higher (0.5 if no date)
- authority_score (0-1): Based on domain authority level
- Tier 1 (1.0): github.com, stackoverflow.com, official documentation sites
- Tier 2 (0.8): HN, dev.to, well-known technical blogs
- Tier 3 (0.6): Medium, 掘金 (Juejin), InfoQ
- Tier 4 (0.4): Others
Complete domain scoring table can be found inreferences/authority-domains.json
Domain Boost
Domain Boost
通过 参数手动指定需要加权的域名(匹配的结果权威分 +0.2):
--domain-boostbash
search.py "query" --mode deep --intent tutorial --domain-boost dev.to,freecodecamp.org推荐搭配:
- Tutorial →
dev.to, freecodecamp.org, realpython.com, baeldung.com - Resource →
github.com - News →
techcrunch.com, arstechnica.com, theverge.com
Manually specify domains to boost via the parameter (matching results get +0.2 to authority score):
--domain-boostbash
search.py "query" --mode deep --intent tutorial --domain-boost dev.to,freecodecamp.orgRecommended Pairings:
- Tutorial →
dev.to, freecodecamp.org, realpython.com, baeldung.com - Resource →
github.com - News →
techcrunch.com, arstechnica.com, theverge.com
Phase 5: 知识合成
Phase 5: Knowledge Synthesis
根据结果数量选择合成策略:
Select synthesis strategy based on the number of results:
小结果集(≤5 条)
Small Result Set (≤5 entries)
逐条展示,每条带源标签和评分:
1. [Title](url) — snippet... `[brave, exa]` ⭐0.85
2. [Title](url) — snippet... `[tavily]` ⭐0.72Display each entry with source tags and score:
1. [Title](url) — snippet... `[brave, exa]` ⭐0.85
2. [Title](url) — snippet... `[tavily]` ⭐0.72中结果集(5-15 条)
Medium Result Set (5-15 entries)
按主题聚类 + 每组摘要:
**主题 A: [描述]**
- [结果1] — 要点... `[source]`
- [结果2] — 要点... `[source]`
**主题 B: [描述]**
- [结果3] — 要点... `[source]`Cluster by topic + summary per group:
**Topic A: [Description]**
- [Result1] — Key points... `[source]`
- [Result2] — Key points... `[source]`
**Topic B: [Description]**
- [Result3] — Key points... `[source]`大结果集(15+ 条)
Large Result Set (15+ entries)
高层综述 + Top 5 + 深入提示:
[一段综述,概括主要发现]
**Top 5 最相关结果:**
1. ...
2. ...
共找到 N 条结果,覆盖 [源列表]。需要深入哪个方面?High-level overview + Top 5 + deep dive prompt:
[A paragraph summarizing key findings]
**Top 5 Most Relevant Results:**
1. ...
2. ...
A total of N results found, covering [source list]. Which aspect would you like to explore in depth?合成规则
Synthesis Rules
- 先给答案,再列来源(不要先说"我搜了什么")
- 按主题聚合,不按来源聚合(不要"Brave 结果:... Exa 结果:...")
- 冲突信息显性标注:不同源说法矛盾时明确指出
- 置信度表达:
- 多源一致 + 新鲜 → 直接陈述
- 单源或较旧 → "根据 [source],..."
- 冲突或不确定 → "存在不同说法:A 认为...,B 认为..."
- Provide the answer first, then list sources (do not start with "I searched for...")
- Aggregate by topic, not by source (do not use "Brave results: ... Exa results: ...")
- Explicitly mark conflicting information: Clearly indicate when different sources have contradictory statements
- Express confidence:
- Consistent across multiple sources + fresh → State directly
- Single source or older → "According to [source], ..."
- Conflicting or uncertain → "Different opinions exist: A believes..., B believes..."
降级策略
Degradation Strategy
- Exa 429/5xx → 继续 Brave + Tavily + Grok
- Tavily 429/5xx → 继续 Brave + Exa + Grok
- Grok 超时/错误 → 继续 Brave + Exa + Tavily
- search.py 整体失败 → 仅用 Brave (始终可用)
web_search - 永远不要因为某个源失败而阻塞主流程
- Exa 429/5xx → Continue with Brave + Tavily + Grok
- Tavily 429/5xx → Continue with Brave + Exa + Grok
- Grok timeout/error → Continue with Brave + Exa + Tavily
- search.py fails entirely → Use only Brave (always available)
web_search - Never block the main process due to failure of a single source
向后兼容
Backward Compatibility
不带 参数时,search.py 行为与 v1 完全一致(无评分,按原始顺序输出)。
--intent现有调用方(如 github-explorer)无需修改。
When the parameter is not passed, search.py behavior is fully consistent with v1 (no scoring, output in original order).
--intentExisting callers (e.g., github-explorer) do not need modification.
快速参考
Quick Reference
| 场景 | 命令 |
|---|---|
| 快速事实 | |
| 深度调研 | |
| 最新动态 | |
| 对比分析 | |
| 找资源 | |
| Scenario | Command |
|---|---|
| Quick Facts | |
| Deep Research | |
| Latest Updates | |
| Comparative Analysis | |
| Resource Finding | |