tavily-dynamic-search
プログラム的なWeb検索をコンテキストを汚染せずに実行するスキルです。「検索して」「調べて」「最新情報を教えて」など現在のWeb情報が必要なクエリや、「重要な部分だけ抽出して」「ノイズを除いて要約して」といった要求に対してトリガーされ、生のHTMLや余分なコンテンツを除いた精度の高い情報のみを返します。Web調査が必要な場面でのデフォルトスキルです。
description の原文を見る
| Programmatic web search with context isolation. Use this skill for any research task where you need to search the web, filter results, and extract specific information — without polluting your context window with raw HTML and boilerplate. This is the default skill for web research. Triggered by "search for", "look up", "find", "research", "what's the latest on", or any query that requires current web information. Also use when asked to "search and filter", "find the important parts", or "extract the key details" — any case where the user wants curated, noise-free content.
SKILL.md 本文
Tavily Dynamic Search
ウェブを検索し、結果をフィルタリングしてコンテンツを抽出して、生の検索データがコンテキストウィンドウに入ることのないようにする。あなたのキュレーションされた print() 出力のみが返ってきます。
なぜこれが重要なのか
典型的な tvly search --include-raw-content は 8 件の結果 × 30-50K 文字 = 約 300K 文字の生のページコンテンツを返します。これがコンテキストウィンドウに入ると、ナビゲーションバー、クッキーバナー、定型文を読むのにトークンを浪費してしまい、ノイズの中で推論品質が低下します。Python スクリプト内で結果を処理することで、コンテキストに入るのはあなたの print() 出力のみです。通常は1-3K 文字の純粋なシグナルです。これは 100-200 倍削減です。
背景: Programmatic Tool Calling (PTC)
このスキルは、ウェブ検索のための Anthropic's Programmatic Tool Calling (PTC) のアーキテクチャを複製しています。PTC により、モデルはサンドボックス内でツール呼び出しを協調させるコードを書くことができます。中間結果はサンドボックスに留まり、最終的な print() 出力のみがモデルのコンテキストウィンドウに到達します。
このスキルはローカル Python 実行を使って同じ原理を適用します。 Python プロセスがサンドボックスです。メモリ内の変数が生のデータを保持します。print() を実行したもののみがコンテキストウィンドウに到達します。フィルタリングロジックはあなたが書きます。各クエリで何が重要かを決定するのはあなたです。
コマンドを実行する前に
tvly が PATH 上にない場合、まずインストールしてください:
curl -fsSL https://cli.tavily.com/install.sh | bash && tvly login
コアルール
決して tvly をベアコマンドとして実行しないでください。常に Python を通じて出力を処理して、コンテキストに入るものを制御してください。
# 誤り — 生の結果がコンテキストに大量に流れ込む
tvly search "quantum computing 2025" --json
# 正解 — あなたの print() 出力のみがコンテキストに入る
tvly search "quantum computing 2025" --json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
for r in data['results']:
print(f'[{r[\"score\"]:.2f}] {r[\"title\"]}')
print(f' {r[\"url\"]}')
"
JSON スキーマ
正しいフィルタリングコードを書くために必要です。
tvly search --json
{
"query": "string",
"answer": "string | null",
"results": [
{
"url": "string",
"title": "string",
"content": "string (snippet, ~500-1500 chars)",
"score": 0.0-1.0,
"raw_content": "string | null (full page, only with --include-raw-content)"
}
],
"response_time": 0.0
}
tvly extract --json
{
"results": [
{
"url": "string",
"title": "string",
"raw_content": "string (full page markdown)",
"images": []
}
],
"failed_results": [],
"response_time": 0.0
}
検索方法
2 つの基本的なビルディングブロックと 2 つの実行方法があります。クエリの要求に応じてこれらを自由に組み合わせてください。固定されたパターンはありません。必要な内容に基づいてアプローチを決定するのはあなたです。
ビルディングブロック
tvly search — タイトル、URL、スニペット、スコアを返します。オプションで --include-raw-content markdown で全ページコンテンツを含めることができます。
tvly extract — 特定の URL の全ページコンテンツを取得します。検索から URL を見つけ、さらに詳細が必要な場合に使用します。
実行モード
パイプモード — シンプルなフィルタ (3-5 行) 用。tvly の出力を python3 -c にパイプします:
tvly search "query" --json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
# ここにフィルタリングコードを記述
"
Heredoc モード — より複雑な場合に。単一の Bash 呼び出し、クリーンな複数行 Python、エスケープなし、一時ファイルなし:
python3 << 'PYEOF'
import json, subprocess
raw = subprocess.check_output(
['tvly', 'search', 'query', '--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
for r in data['results']:
print(f"[{r['score']:.2f}] {r['title']}")
print(f" {r['url']}")
PYEOF
シングルクォート heredoc (<< 'PYEOF') は何も解釈しません。エスケープは不要です。これはほとんどのタスクのデフォルトです。
スクリプトモード — 複数のターンで同じスクリプトを再利用する場合のみ。ワンショットスクリプトを /tmp/ に書かないでください。1 回実行するなら、heredoc を使用してください。
重要: データを /tmp/ に保存し、コードではなく。 /tmp/tavily_results.json (後のターン用のデータ) を書く = 良い。/tmp/my_filter.py (ワンショットコード) を書く = 無駄。heredoc を代わりに使用してください。
マルチターン反復
複雑なクエリでは、抽出する前に探索する必要があることが多い — PTC のようです。モデルが検索して、タイトルを見て、どの結果を掘り下げるかを決定し、抽出します。
重要: 生の結果をファイルに保存し、その後別のステップで処理する。 ファイルはターン間の永続的な状態です。
ターン 1: 検索と探索
検索してタイトル + スコアのみをプリント。生の結果をディスクに保存して後のターン用に:
python3 << 'PYEOF'
import json, subprocess
raw = subprocess.check_output(
['tvly', 'search', 'solid-state battery commercialization 2025',
'--include-raw-content', 'markdown', '--max-results', '8', '--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
# 生の結果を保存 — これはディスクに留まり、決してコンテキストに入りません
with open('/tmp/tavily_results.json', 'w') as f:
json.dump(data, f)
# 次のステップを決定するのに必要なもののみをプリント
print(f'{len(data["results"])} results saved to /tmp/tavily_results.json\n')
for i, r in enumerate(data['results']):
print(f'[{i}] [{r["score"]:.2f}] {r["title"][:90]}')
print(f' {r["url"]}')
print(f' {r["content"][:150]}')
print()
PYEOF
コンテキストは受け取ります: タイトル + スニペットの ~800 トークン。300K の生のページコンテンツは /tmp/tavily_results.json に、未処理のまま。
ターン 2: 見たものに基づいて抽出
これでもう結果の内容がわかります。ターゲット化された抽出を書いてください。あなたが決定するどの結果を掘り下げるか、何をフィルタリングするか:
python3 << 'PYEOF'
import json
data = json.load(open('/tmp/tavily_results.json'))
# ターン 1 で見たタイトルに基づいてこれらのインデックスを選択しました
for i in [0, 2, 5]:
r = data['results'][i]
raw = r.get('raw_content', '') or ''
if not raw:
continue
print(f'## {r["title"]}')
print(f'URL: {r["url"]}\n')
# クエリに基づいてフィルタリングロジックをあなたが書きます
# この例は特定企業に関する段落を抽出します
for para in raw.split('\n\n'):
para = para.strip()
if len(para) > 80 and any(kw in para.lower() for kw in
['toyota', 'quantumscape', 'samsung', 'commercializ', 'production']):
print(para)
print()
print('---\n')
PYEOF
コンテキストは受け取ります: ターゲット化されたコンテンツの ~600 トークン。何を保持するかの決定はあなたがしました。
ターン 3 (オプション): より詳細を取得
特定の情報源からさらに詳細が必要な場合:
python3 << 'PYEOF'
import json, subprocess
# 特定の URL を取得して、あなたが識別したもの
raw = subprocess.check_output(
['tvly', 'extract', 'https://example.com/article', '--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
page = data['results'][0]
content = page.get('raw_content', '')
# 潜在的なさらなる処理のために保存
with open('/tmp/page_detail.txt', 'w') as f:
f.write(content)
# あなたが気にする部分のみをプリント
for line in content.split('\n'):
if any(kw in line.lower() for kw in ['timeline', '2025', '2026', 'mass production']):
print(line.strip())
PYEOF
マルチターン対シングルターンの使い分け
シングルターン (パイプモード または 1 つのスクリプト): あなたが事前に何を探しているかわかっているとき。具体的な事実クエリ、既知のキーワード。
マルチターン (保存 + 探索 + 抽出): 何を抽出するか決定する前に、利用可能なものを見る必要があるとき。オープンエンドな調査、複雑なトピック、正しいキーワードをまだ知らないクエリ。
例
シンプルな事実検索 (シングルターン、パイプモード)
tvly search "Python 3.13 release date" --max-results 5 --json 2>/dev/null | python3 -c "
import json, sys
data = json.load(sys.stdin)
for r in data['results'][:3]:
print(f'{r[\"title\"]}')
print(f'{r[\"content\"][:300]}')
print()
"
財務データ抽出 (シングルターン、heredoc)
python3 << 'PYEOF'
import json, subprocess
raw = subprocess.check_output(
['tvly', 'search', 'NVIDIA Q4 2025 earnings revenue',
'--include-raw-content', 'markdown', '--max-results', '5',
'--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
for r in data['results']:
raw_content = r.get('raw_content', '') or ''
# 財務クエリの場合、数字を含む行を探す
financial_lines = [
line.strip() for line in raw_content.split('\n')
if any(kw in line.lower() for kw in
['revenue', 'eps', 'earnings', 'margin', 'guidance', 'billion'])
and any(c.isdigit() for c in line)
and len(line.strip()) > 30
]
if financial_lines:
print(f'## {r["title"]}')
print(f'URL: {r["url"]}')
for line in financial_lines[:15]:
print(f' {line}')
print()
PYEOF
マルチソース調査 (マルチターン)
ターン 1 — 広範な検索 + トリアージ:
python3 << 'PYEOF'
import json, subprocess
# 複数の角度から検索
queries = [
('broad', 'EU AI Act implementation timeline 2025'),
('specific', 'EU AI Act high-risk AI systems obligations'),
]
all_results = []
for label, query in queries:
raw = subprocess.check_output(
['tvly', 'search', query, '--max-results', '8', '--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
for r in data['results']:
r['_query'] = label
all_results.extend(data['results'])
# URL で重複排除
seen = set()
unique = []
for r in all_results:
if r['url'] not in seen:
seen.add(r['url'])
unique.append(r)
# すべての結果を保存
with open('/tmp/eu_ai_results.json', 'w') as f:
json.dump(unique, f)
# トリアージをプリント
unique.sort(key=lambda r: r['score'], reverse=True)
print(f'{len(unique)} unique results from {len(queries)} queries\n')
for i, r in enumerate(unique[:10]):
print(f'[{i}] [{r["score"]:.2f}] ({r["_query"]}) {r["title"][:80]}')
print(f' {r["url"]}')
print(f' {r["content"][:120]}')
print()
PYEOF
ターン 2 — トリアージを見て、最良のソースを選択して抽出:
python3 << 'PYEOF'
import json, subprocess
results = json.load(open('/tmp/eu_ai_results.json'))
# 上位 3 件のフルコンテンツを取得 (ターン 1 に基づいてあなたが選択)
for r in [results[0], results[2], results[4]]:
try:
raw = subprocess.check_output(
['tvly', 'extract', r['url'], '--json'],
stderr=subprocess.DEVNULL, timeout=30
)
page = json.loads(raw)
if not page.get('results'):
continue
content = page['results'][0].get('raw_content', '')
# あなたのフィルタリングロジック — このクエリに調整
print(f'## {r["title"]}')
print(f'URL: {r["url"]}\n')
for para in content.split('\n\n'):
para = para.strip()
if len(para) > 100 and any(kw in para.lower() for kw in
['high-risk', 'prohibited', 'deadline', 'obligation',
'compliance', 'penalty', 'fine', 'article']):
print(para)
print()
print('---\n')
except Exception:
continue
PYEOF
ターン全体で手がかりを追う
ターン 2 が新しい URL またはトピックを明らかにすることがあります。反復し続けることができます:
python3 << 'PYEOF'
import json, subprocess
# 以前保存したページを読み込む
with open('/tmp/page_detail.txt') as f:
content = f.read()
# 特定の規制文書への参照に気づきました
# それを具体的に検索
raw = subprocess.check_output(
['tvly', 'search', 'EU AI Act Annex III high-risk list',
'--include-domains', 'eur-lex.europa.eu',
'--max-results', '3', '--json'],
stderr=subprocess.DEVNULL
)
data = json.loads(raw)
for r in data['results']:
print(f'## {r["title"]}')
print(f'URL: {r["url"]}')
print(r['content'])
print()
PYEOF
各ターン、データを /tmp/ に保存し、次に何を探索するか決定し、heredoc として新しいフィルタリングコードを書きます。生のデータはディスクに蓄積されます。あなたのコンテキストは精動きを保ちます。
フィルタリングコードを書く
あなたが書く Python はフィルタリングロジックです。固定されたテンプレートはありません。特定のクエリに意味のあるコードを書きます。これらはルールではなく、原則です:
まずトリアージしてください。 完全なページを取得する前にタイトルとスコアを検査してください。盲目的にすべてを抽出しないでください。
具体的であってください。 財務クエリは数字と財務用語をフィルタリングすべきです。技術クエリはコードブロックと仕様を探すべきです。ニュースクエリは日付と引用を探すべきです。フィルタリングをクエリに合わせてください。
構造的なフィルタリングが役立ちます。 約 50-80 文字より短い行をスキップしてください (通常はナビ要素)。一般的な定型文を スキップ。見出しとその後に続く段落を保持。しかし、これらは出発点です。見たものに基づいて適応してください。
構造化された出力をプリント。 出力を簡単に推論できるようにフォーマットしてください:
print(f'## {title}')
print(f'URL: {url}')
print(relevant_content)
print()
エラーをハンドル。 ページは失敗し、URL は 404、抽出はタイムアウト。try/except を使い失敗をスキップ:
try:
raw = subprocess.check_output(['tvly', 'extract', url, '--json'],
stderr=subprocess.DEVNULL, timeout=30)
except Exception:
continue
トークン予算の意識。 あなたの print() 出力がコンテキストに入ります。ソースあたり 150-600 トークンを目指してください。単一ページから 5000+ 文字をプリントしている場合、おそらく十分にフィルタリングしていません。ただし、ソースに重大なデータテーブルがある場合、より多くを保持する方が大丈夫です。
オプション
すべての標準 tvly search オプションが機能します:
| オプション | 説明 |
|---|---|
--max-results | 結果の数 (デフォルト: 5、最大: 20) |
--depth | ultra-fast, fast, basic (デフォルト), advanced |
--time-range | day, week, month, year |
--include-domains | カンマ区切りホワイトリスト |
--exclude-domains | カンマ区切りブラックリスト |
--include-raw-content | フルページコンテンツ (markdown または text) |
--country | 国からの結果をブースト |
フォールバック: jq
python3 が利用できない場合、基本的なフィルタリングに jq を使用します:
tvly search "query" --json 2>/dev/null | jq '[.results[] | select(.score > 0.5) | {title, url, content}]'
jq は複数ステップの検索-抽出または複雑なフィルタリングはできません。シンプルな検索のみに使用してください。
ライセンス: MIT(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- tavily-ai
- リポジトリ
- tavily-ai/skills
- ライセンス
- MIT
- 最終更新
- 不明
Source: https://github.com/tavily-ai/skills / ライセンス: MIT
関連スキル
doubt-driven-development
重要な判断はすべて、本番環境への展開前に新しい視点から対抗的レビューを実施します。速度より正確性が重要な場合、不慣れなコードを扱う場合、本番環境・セキュリティに関わるロジック・取り消し不可の操作など影響度が高い場合、または後でバグを修正するよりも今検証する方が効率的な場合に活用してください。
apprun-skills
TypeScriptを使用したAppRunアプリケーションのMVU設計に関する総合的なガイダンスが得られます。コンポーネントパターン、イベントハンドリング、状態管理(非同期ジェネレータを含む)、パラメータと保護機能を備えたルーティング・ナビゲーション、vistestを使用したテストに対応しています。AppRunコンポーネントの設計・レビュー、ルートの配線、状態フローの管理、AppRunテストの作成時に活用してください。
desloppify
コードベースのヘルスチェックと技術負債の追跡ツールです。コード品質、技術負債、デッドコード、大規模ファイル、ゴッドクラス、重複関数、コードスメル、命名規則の問題、インポートサイクル、結合度の問題についてユーザーが質問した場合に使用してください。また、ヘルススコアの確認、次の改善項目の提案、クリーンアップ計画の作成をリクエストされた際にも対応します。29言語に対応しています。
debugging-and-error-recovery
テストが失敗したり、ビルドが壊れたり、動作が期待と異なったり、予期しないエラーが発生したりした場合に、体系的な根本原因デバッグをガイドします。推測ではなく、根本原因を見つけて修正するための体系的なアプローチが必要な場合に使用してください。
test-driven-development
テスト駆動開発により実装を進めます。ロジックの実装、バグの修正、動作の変更など、あらゆる場面で活用できます。コードが正常に動作することを証明する必要がある場合、バグ報告を受けた場合、既存機能を修正する予定がある場合に使用してください。
incremental-implementation
変更を段階的に実施します。複数のファイルに影響する機能や変更を実装する場合に使用してください。大量のコードを一度に書こうとしている場合や、タスクが一度では完結できないほど大きい場合に活用します。