search-layer について
Search Layerは、検索意図に応じてクエリを拡張し、複数の検索元を並列検索して結果を順位付け・統合するスキルです。引用追跡と検索元のフォールバックにも対応し、体系的な調査を行うエージェント向けです。
主な機能
- 01意図を分類して検索方針を選択
- 02クエリを拡張し複数ソースを並列検索
- 03結果の統合・重複排除・順位付け
- 04GitHubの議論に含まれる参照を追跡
- 05件数に応じて結果を整理・統合
- 06検索元の障害時にフォールバック
活用シーン
- 01事実・チュートリアル・公式リソースの検索
- 02技術方式の比較と調査
- 03最新動向の検索とGitHub議論の追跡
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ blessonism/ search-skills --skill search-layerインストール後、Claude Code で/search-layerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/authority-domains.jsonintent-guide.mdresearch-light-regression-samples.mdscripts/chain_tracker.pyfetch_thread.pyrelevance_gate.pysearch.py詳細
Search Layer v2.2 — 意図認識型マルチソース検索プロトコル
4つのソースを同等に扱います:Brave(web_search)+ Exa + Tavily + Grok。意図に応じて戦略を自動選択し、重みを調整して統合します。
実行フロー
用户查询
↓
[Phase 1] 意图分类 → 确定搜索策略
↓
[Phase 2] 查询分解 & 扩展 → 生成子查询
↓
[Phase 3] 多源并行检索 → Brave + search.py (Exa + Tavily + Grok)
↓
[Phase 4] 结果合并 & 排序 → 去重 + 意图加权评分
↓
[Phase 5] 知识合成 → 结构化输出
Phase 1: 意図分類
検索リクエストを受け取ったら、まず意図の種類を判断してから、検索戦略を決定します。ユーザーにどのモードを使うか尋ねないでください。
| 意図 | 認識シグナル | 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をデフォルトにする
Phase 2: クエリの分解と拡張
意図の種類に応じて、ユーザーのクエリを複数のサブクエリに拡張します。
共通ルール
- 技術用語の同義語を自動拡張:k8s→Kubernetes、JS→JavaScript、Go→Golang、Postgres→PostgreSQL
- 中国語の技術クエリ:英語のバリエーションも同時に生成します(例:「Rust 异步编程」→ 追加で「Rust async programming」も検索)
意図別の拡張
| 意図 | 拡張戦略 | 例 |
|---|---|---|
| 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」 |
Phase 3: マルチソース並列検索
Step 1: Brave(すべてのモード)
各サブクエリに対して web_search を呼び出します。意図に freshness の要件がある場合は、freshness パラメーターを渡します。
web_search(query="Deno 2.0 latest 2026", freshness="pw")
Step 2: Exa + Tavily + Grok(Deep / Answer モード)
サブクエリに対して search.py を呼び出し、意図と freshness を渡します。
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 | ✅ | ✅ | ✅ | 3つのソースを並列実行 |
| answer | ❌ | ✅ | ❌ | Tavily のみ(AI answer を含む) |
パラメーターの説明:
| パラメーター | 説明 |
|---|---|
--queries | 複数のサブクエリを並列実行します(単一クエリは位置引数でも指定できます) |
--mode | fast / deep / answer |
--intent | 意図の種類。スコアの重みに影響します(指定しない場合はスコアリングされず、動作は v1 と同じです) |
--freshness | pd(24h) / pw(週) / pm(月) / py(年) |
--domain-boost | カンマ区切りのドメイン。一致した結果の権威性スコアを +0.2 します |
--num | ソースごと、クエリごとの結果数 |
Exa ソースの説明(2層の役割):
- Retrieval lane(デフォルトの主経路):
- デフォルトでは引き続き
/searchを使用しますが、type=autoに固定しません - 現在の最小マッピング:
resource→instantstatus/news→fastexploratory+mode=deep→deep- その他 →
auto
- デフォルトで
contents.highlights.maxCharacters=1200を付与し、snippet の品質を高めます。Exa の結果が要約なしのためにローカルランキングで過小評価されるのを防ぎます freshnessは Exa のstartPublishedDateにマッピングされ、status/news クエリの時間範囲を Tavily/Grok と揃えます- 結果の metadata に
meta.exaTypeを保持し、実際に解決された type を確認できるようにします
- デフォルトでは引き続き
- Research lane(選択的なアップグレード):
- クエリが複雑な
comparison / exploratory / status / newsの状況に該当する場合に限り、標準候補の取得後、Exatype=deepによる研究ブロックを追加で実行し、researchフィールドに出力を付加します researchは追加の contract であり、resultsを置き換えません。旧来の呼び出し側が引き続きresultsのみを読み取れるようにします- 現在の適用条件:comparison は明示的な比較語/判断語/3つ以上のサブクエリが必要です。exploratory は判断語/因果語/比較語が必要です。status/news は判断語/因果語が必要で、通常の複数クエリへの拡張では誤って起動しません
- クエリが複雑な
- 基本の search-layer が大規模な research/synthesis エンジンにならないよう、当面は
deep-reasoning/outputSchemaをデフォルトの主経路に組み込みません - Exa のエンドポイントはデフォルトで
https://api.exa.ai/searchです。独自ホスト/プロキシを使う場合は、EXA_API_BASE/EXA_API_URLまたは~/.openclaw/credentials/search.json内のexaApiBaseで上書きできます(例:https://exa.example.com)
Grok ソースの説明:
- completions API を通じて Grok モデル(
grok-4.1-fast)を呼び出し、リアルタイムの知識を活用して構造化された検索結果を返します - 時間に敏感なクエリを自動検出し、現在の時刻情報を注入します
- deep モードでは Exa、Tavily と並列で実行します
~/.openclaw/credentials/search.jsonで Grok のapiUrl、apiKey、modelを設定する必要があります(または環境変数GROK_API_URL、GROK_API_KEY、GROK_MODELで設定します)- Grok の設定がない場合は、自動的に Exa + Tavily の2ソースにフォールバックします
Step 3: 合并
将 Brave 结果与 search.py 输出合并。按 canonical URL 去重,标记来源。
如果 search.py 返回了 score 字段,用它排序;Brave 结果没有 score 的,用同样的意图权重公式补算。
Phase 3.5: 引用追踪(Thread Pulling)
当搜索结果中包含 GitHub issue/PR 链接,且意图为 Status 或 Exploratory 时,自动触发引用追踪。
自动触发条件
- 意图为
status或exploratory - 搜索结果中包含
github.com/.../issues/或github.com/.../pull/URL
方式 1: search.py --extract-refs(批量)
在搜索结果上直接提取引用图,无需额外调用:
python3 search.py "OpenClaw config validation bug" --mode deep --intent status --extract-refs
输出中会多一个 refs 字段,包含每个结果 URL 的引用列表。
也可以跳过搜索,直接对已知 URL 提取引用:
python3 search.py --extract-refs-urls "https://github.com/owner/repo/issues/123" "https://github.com/owner/repo/issues/456"
方式 2: fetch-thread(单 URL 深度抓取)
对单个 URL 拉取完整讨论流 + 结构化引用:
python3 fetch_thread.py "https://github.com/owner/repo/issues/123" --format json
python3 fetch_thread.py "https://github.com/owner/repo/issues/123" --format markdown
python3 fetch_thread.py "https://github.com/owner/repo/issues/123" --extract-refs-only
GitHub 场景(issue/PR):通过 API 拉取正文 + 全部 comments + timeline 事件(cross-references、commits),提取:
- Issue/PR 引用(#123、owner/repo#123)
- Duplicate 标记
- Commit 引用
- 关联 PR/issue(timeline cross-references)
- 外部 URL
通用 web 场景:web fetch + 正则提取引用链接。
Agent 执行流程
Step 1: search-layer 搜索 → 获取初始结果
Step 2: search.py --extract-refs 或 fetch-thread → 提取线索图
Step 3: Agent 筛选高价值线索(LLM 判断哪些值得追踪)
Step 4: fetch-thread 深度抓取每个高价值线索
Step 5: 重复 Step 2-4,直到信息闭环或达到深度限制(建议 max_depth=3)
Phase 4: 结果排序
评分公式
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
Domain Boost
通过 --domain-boost 参数手动指定需要加权的域名(匹配的结果权威分 +0.2):
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
Phase 5: 知识合成
根据结果数量选择合成策略:
小结果集(≤5 条)
逐条展示,每条带源标签和评分:
1. [Title](url) — snippet... `[brave, exa]` ⭐0.85
2. [Title](url) — snippet... `[tavily]` ⭐0.72
中结果集(5-15 条)
按主题聚类 + 每组摘要:
**主题 A: [描述]**
- [结果1] — 要点... `[source]`
- [结果2] — 要点... `[source]`
**主题 B: [描述]**
- [结果3] — 要点... `[source]`
大结果集(15+ 条)
高层综述 + Top 5 + 深入提示:
[一段综述,概括主要发现]
**Top 5 最相关结果:**
1. ...
2. ...
共找到 N 条结果,覆盖 [源列表]。需要深入哪个方面?
合成规则
- 先给答案,再列来源(不要先说"我搜了什么")
- 按主题聚合,不按来源聚合(不要"Brave 结果:... Exa 结果:...")
- 冲突信息显性标注:不同源说法矛盾时明确指出
- 置信度表达:
- 多源一致 + 新鲜 → 直接陈述
- 单源或较旧 → "根据 [source],..."
- 冲突或不确定 → "存在不同说法:A 认为...,B 认为..."
降级策略
- Exa 429/5xx → 继续 Brave + Tavily + Grok
- Tavily 429/5xx → 继续 Brave + Exa + Grok
- Grok 超时/错误 → 继续 Brave + Exa + Tavily
- search.py 整体失败 → 仅用 Brave
web_search(始终可用) - 永远不要因为某个源失败而阻塞主流程
向后兼容
不带 --intent 参数时,search.py 行为与 v1 完全一致(无评分,按原始顺序输出)。
现有调用方(如 github-explorer)无需修改。
快速参考
| 场景 | 命令 |
|---|---|
| 快速事实 | web_search + search.py --mode answer --intent factual |
| 深度调研 | web_search + search.py --mode deep --intent exploratory |
| 最新动态 | web_search(freshness="pw") + search.py --mode deep --intent status --freshness pw |
| 对比分析 | web_search × 3 queries + search.py --queries "A vs B" "A pros" "B pros" --intent comparison |
| 找资源 | web_search + search.py --mode fast --intent resource |