Community研究&データ分析github.com

Legwork(意思決定リサーチスキル)

Claude Code および Codex 向けの意思決定リサーチスキル。各主張の根拠の確かさを明示し、証拠で決着できない場合はその旨を伝えます。DBHQ による無料ツール。

Legwork(意思決定リサーチスキル) とは?

Legwork は、AI エージェント(Claude Code や Codex)が「どうすべきか」という意思決定を支援するために設計されたリサーチスキルです。学術調査ではなく、実用的な判断材料を提供することに特化しており、網羅性よりも使いやすさを重視します。このスキルは、収集した証拠の「種類」と「独立性」を厳格に評価し、同じ主張を裏付ける複数のソースが独立しているかどうかを確認します。また、リサーチの深さに応じて quick、standard、deep の3段階を用意しており、フェーズはフレーミング、収集、検証、執筆の4段階で構成されます。過去のリサーチをインデックス化して再利用することで無駄な再実行を防ぎ、スクリプト群によって各フェーズを自動化・効率化します。デフォルトの standard モードでは、クレームごとに最適な検索とウェブ取得の手段を段階的に選択し、フェッチログにすべての取得行為を記録します。サブエージェントによる並列取得もサポートし、特に deep モードでは一次ソースの確認や反証の体系的な探索を行います。

対応✓Claude Code✓Codex CLI~Cursor
npx skills add dbhq-uk/legwork-skill

Installed? Explore more 研究&データ分析 skills: affaan-m/uspto-database, affaan-m/scholar-evaluation, affaan-m/literature-review · View all 6 →

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

Legwork

これは何のためか

意思決定リサーチ。学術調査ではない。問いは常に「Xについてどうすべきか」という類のものであり、成果物はそれが使いものになるかどうかで評価され、網羅的かどうかでは評価されない。

それが以下のすべてを形作っている。ある主張は、その主張に対してその情報源が正しい種類のものかどうかで判断され、情報源の分野が立派かどうかでは判断されない。三つの情報源が一致していても、それらが異議を唱えることができた場合にのみ意味を持つ。そして、問いに答えられない実行は、条件付きの長文を生成するのではなく、その旨を伝える。

自律性の原則。 必要なことはコンテキストから推測し、レベルを選び、開始せよ。レベルを一行で宣言して進め、ユーザーに選択を求めない。ユーザーは実行中に方向転換できる。これは、すべての要求に対してブロッキングクエスチョンを投げるよりもはるかにコストが低い。重大なエラーか意味不明なクエリの場合のみ停止する。

レベル

深さが厳密性を高める。長さは決して増えない。

quickstandarddeep
フレーミング意思決定と2〜3のサブ質問さらに明示的な反証仮説さらに二次的な視点
収集SERPのスニペット;数値を確定するためだけにフェッチ発見ごとにトップソースを直接フェッチ発見ごとに一次ソース
検証独立性グループ化のみ発見ごとに一つの反証検索発見ごとの反証パスと発信元監査
形式briefbrief または reportreport
ゲートレベル--level quick--level standard--level deep
おおよその所要時間3〜5分8〜12分20〜40分

デフォルトはstandard。ユーザーが指定したレベル(quick、standard、deep、または「クイックスキャン」「深掘り」などの同等表現)を使用し、それ以外の場合は$LEGWORK_DEFAULT_MODE、それもなければstandardを使用する。「ディープリサーチ」単体はこのスキルの呼び出しフレーズであり、deepレベルを要求するものではない — デフォルトにフォールスルーする。

スコーピングにより、質問がリクエストから想定されるよりも実質的に重要度が高いことが明らかになった場合、静かに1レベル上げ、同じ冒頭行でその旨を伝える。

冒頭行の後、すぐにフェーズ1へ:

standard(約8〜12分)で実行中。一次ソースと反証パスが必要な場合は「deep」と発言してください。

パイプライン

4つのフェーズ。完全な手順はmethodology.mdを参照。

  1. フレーミング - 意思決定、それを決着させるサブ質問、そして答えを変えるような証拠を特定する。
  2. 収集 - 各サブ質問に対して取得を実行し、すべてのフェッチを記録する。
  3. 検証 - 反証ケースを探索する;情報源を独立性でグループ化する。
  4. 執筆 - 成果物を組み立て、ゲートを通過させる。

フェーズ2と3は厳格なゲートとして実行するのではなく、発見ごとにインターリーブされる。

開始前に行うこと

日付を固定する。 date -u +%Y-%m-%d を実行し、その文字列を実行、出力フォルダ名、および日付が関係する可能性のあるすべての検索クエリに使用する。自分の年数感覚に決して頼らず、サブエージェントにそれを自動解決させてはならない。

この実行がすでに行われていないか確認する。 まずインデックスを読む。これはディスパッチャである:過去の実行ごとに1行あり、ワンライナー列はレポートを開くコストを払わずに開くべきか判断できるように存在する。

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py list --base "$OUTPUT_BASE"

次に4つのパスのいずれかを選び、冒頭行でその旨を伝える:

インデックスの内容実行すること
これをカバーする実行があり、古くなっていないそれから回答する。そのレポートを読み、ウェブは読まない。
これをカバーする実行があるが、古いとフラグが立っているリフレッシュする
近い実行があるが、別の質問に答えている新規実行し、相互参照する
一致するものがない新規実行

過去の実行から回答することは成功であり、近道ではない。 レポートを開き、質問に関係する発見を読み、その信頼度帯をそのままにして回答する。それが特定の日付の実行に由来することを明確に述べる。すでに行われ、まだ有効なリサーチを再実行することは、このインデックスが防ごうとしている無駄である。

再実行ではなくリフレッシュ

リフレッシュは既存のレポートをその場で更新する — 同じフォルダ、同じファイル。2つ目のフォルダを作成してはならない:1つの質問を説明する2つのフォルダは、読者がたまたま開いた方に基づいて行動する原因となる。

  1. 新しいフェッチログを開始するのではなく、再開する。フェッチログ内のすべての情報はすでに支払い済みである。

    python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py resume --tsv "$OUT/$BASE.tsv"
    

    これにより、すでに処理された角度、すでにフェッチされたページ、およびまだ引用がないページが表示される。未カバーの角度を処理し、答えを決定する主張を再検証する;すでに記録され、最新のものを再フェッチしてはならない。

  2. 現在間違っているすべての主張を、日付と理由とともに## Supersededに移動する。主張を黙って削除してはならない。 誰かがそれに基づいて行動した可能性があり、将来の実行はこの領域がすでにカバーされていることを知る必要がある。同じ答えが今までに2回覆された場合は、それを明確に伝える — それはドキュメントの中で質問が不安定であることを示す最も強いシグナルである。

  3. 変更内容を## Timeline行に追加する。

  4. インデックス行を更新する。

実行のファイリング

すべての実行はインデックスに格納される。答えられなかった実行も含む — 「調べたが何も見つからなかった」という情報こそ、将来のセッションが再度調べる必要をなくすために必要なものである。

python3 ${CLAUDE_SKILL_DIR}/scripts/index.py add --base "$OUTPUT_BASE" \
  --folder "$BASE" --topic "小規模診療所のアウトルクトリアージ" --level deep \
  --one-liner "E5未満ではネイティブトリアージなし;ギャップは実在するが狭い"

ワンライナーは実行が結論づけたことを述べ、何についてのものかを述べてはならない。6か月後には「プラグインギャラリーに関するメモ」は役に立たないが、「提出経路は存在せず、インストールはURLによるか全くできない」はそれ自体で質問に答えている。ゲートは、存在するインデックスから実行が欠落している場合に警告する。

取得ポリシー

2つのラダー。無料の段を最初に。必要なところまでだけ登る。

検索用:

段呼び出しタイミング
1WebSearch常に。角度ごとに3つのクエリバリエーション。
2platforms.py search --on ...答えがプラットフォームが保持するレコードである場合:スレッド、パッケージ、リポジトリ、日付付きニュースアイテム、ベンダーの変更履歴。無料、キー不要で、それについてのページではなくレコードを返す。
3bd_search.py -m general --engine bing --country XX --language yy3つのバリエーションで結果が薄い場合、または質問が地域固有の場合。2つ目のエンジンを使うために対価を払う理由。
4bd_search.py -m discover --intent "..."2つのエンジンでもまだ薄い場合。

ページを開く用:

段呼び出しタイミング
1fetch.py "<url>" --find "term"常に最初。無料で、ページテキストを生成する唯一の無料トランスポートであるため、数値の追跡と引用の確認が可能。
2WebFetchfetch.py が終了コード3で終了し、そのページに対価を払う価値がない場合。
3bd_search.py "<url>" -m scrapeブロックされた場合:ボット対策、ペイウォール、403エラー。
4bd_search.py "<url>" -m renderクライアントサイドレンダリングのシェルの場合。
5bd_search.py "<url>" -m pipeline --pipeline NAME上記すべてをブロックするプラットフォームの場合。レコード単位で課金;-m redditは、それが唯一の経路であり、最後の手段ではない場合のみ使用。

platforms.py list で10の無料プラットフォームを確認し、bd_search.py --help で有料モードを確認する。終了コード2(認証またはクォータ)の場合、ユーザーに brightdata login を実行するよう伝える。再試行してはならない。

検索結果はリードであり、読むページではない。 standard および deep では、引用するものを開く:ゲートは websearch 行のみに依存する引用を未開封として扱い、standard では警告、deep ではエラーとなる。Quick はスニペット優先が設計上の特徴であり、求められない。

フォールバックの前に失敗を記録する。 開かなかったページは実行に関する証拠であり、--status blocked として記録し、領収書はそれをカウントする。

プルバックする量に上限を設定する。 スクレイプ呼び出しには --max-chars 8000 を使用し、盲目的な上限よりは --find を優先する:長いページでは、最初の8000文字は通常ナビゲーションである。

使用してよい情報源

リサーチとは、部外者が確立できるものである。この境界は両方向で重要である。

ユーザー自身の記録を発見として提示してはならない。 質問がユーザー自身の会社、製品、または市場ポジションに関するものである場合、ユーザーのプライベートアカウント(レジストラ、請求書、受信箱、内部ファイル)にアクセスし、そこで見つけたものを発見されたかのように報告してはならない。ユーザーはすでにそれを知っている。それは循環論法であり、見かけ上の証拠を膨らませ、部外者が実際にどれだけ見ることができるかを隠蔽する。公開されている同等のものを検索し、部外者が見つけるものを報告する。何も見つからなくても、それを報告する。

ユーザーから与えられた排他的アクセスを、第三者に対しては使用してよい。 ユーザーが明示的に提供した有料サブスクリプション、プライベートデータセット、または内部データベースは、競合他社、サプライヤー、または市場を調査する際の真のアドバンテージである。それを使用し、他の情報源と同じように記録し、制限事項にその発見が読者が持っていないかもしれないアクセスに依存していることを明記する。

あるエンティティに公開フットプリントがまったくないことが判明した場合、それが答えである。確認したものをリストし、存在や規模が外部から検証できなかったことを述べ、特権アクセスからギャップを埋めてはならない。これは「答えられなかった」という形状を、質問全体ではなく1つのエンティティに適用したものである。

フェッチログ

すべての取得は、すべてのレベルで、1行を追加する:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log \
  --tsv "$OUT/$BASE.tsv" \
  --url "https://acme.example/pricing" \
  --kind vendor_pricing \
  --angle "競合他社はいくら請求するか" \
  --via webfetch \
  --date 2026-07-01 \
  --title "料金" \
  --quote "チームプラン:月額ユーザーあたり30米ドル、年払い。" \
  --text-file /tmp/page.txt

2つのフィールドが重みを持ち、どちらも後続の処理ではチェックできない。

--angle は、この取得が答えていたサブ質問である。裏付けは情報源ではなく角度でカウントされる。なぜなら、Legwork 自身の展開が情報源の数を水増しするからである。角度を正直に記録せよ — 実行全体で同じ文字列を再利用すると、チェックが黙って破壊され、どのスクリプトもそれを検出できない。

--quote は、その情報源を引用する価値があると判断した根拠となった、そのままの文である。引用するつもりのすべての情報源について、読んだ時点で1つ記録せよ。 すべての発見の約半数は数値を含まないため、その場合、引用が唯一の証拠であり、ページが変更された後も生き残る唯一の部分である。ページテキストがディスク上にある場合(fetch.py で開いたもの、または --out 付きの -m scrape)、引用はそれに対してチェックされ、quote_verified: false はページを誤って引用したことを意味する。

--from-fetch は、URL、タイトル、日付、ページテキストを、これら2つが書き込むサイドカーから入力するため、再入力の必要がない:

python3 ${CLAUDE_SKILL_DIR}/scripts/sources.py log --tsv "$OUT/$BASE.tsv" \
  --from-fetch /tmp/legwork/ab12cd34ef56.json \
  --angle "競合他社はいくら請求するか" --kind vendor_pricing \
  --query "site:acme.example 料金" --quote "チームプラン:月額ユーザーあたり30米ドル..."

sources.py log --help で残りのオプションを確認:--via トランスポート(api、local、mcpを含む)、--text-file 数値抽出、--kind。実際に使用したトランスポートを記録せよ — ログ可能にするために別のトランスポートでページを再フェッチすることは、証跡を歪めるのであって記録することではない。sources.py kinds は、どの情報源の種類がどの主張に適しているかを表示する。

サブエージェント

取得は並列化する価値がある唯一のフェーズであり、角度ごとに1つのサブエージェントを使用する。サブエージェントへの指示は subagent-brief.md から与える。このファイルには、テンプレートの正確な文言、必要な戻り値の形状、および各行がそこにある理由が記載されている。サブエージェントはコンテキストがゼロであるため、必要なものはすべて指示に含める。

3つの事項は、指示ではなく、あなたの側に残る:

  • 角度の形状にモデルを合わせる。 スニペット収集や既知の数値の固定は、安価なモデルで十分に動作する — オーバーライドを明示的に渡し、決してセッションモデルを誤って継承させてはならない。しかし、deep レベルの一次ソース作業、および列挙を再構築するものは、オーケストレータのモデルに留める。 測定値:ある比較では、オーケストレータは安価から高性能の範囲で3、8、32のベンダーページを開き、最も弱いモデルだけが単一のアグリゲータからグリッドのすべてのセルを埋めて成功を報告した。
  • サブエージェントのトランスクリプトを合成に貼り付けてはならない。 構造化された戻り値を受け取り、角度文字列が変更されずに返ってきたことを確認し、各行をログに記録し、ログから作業する。
  • スコーピング、検証、合成は判断を要する。 これらはメインモデルに留める。

スクリプト

すべて標準ライブラリのみ。仮想環境は不要。任意の python3 >= 3.9。

スクリプト目的
fetch.py "<url>" --find TERMページを無料で開き、そのテキストを保持する;ブロックまたはシェルの場合、終了コード3で終了
platforms.py list | search --on X10の無料プラットフォームネイティブソース。ページではなくレコードを返す
sources.py kinds | log | score情報源の種類の語彙、フェッチログ、主張の種類ごとの適合性スコアリング
sources.py receipt領収書行のための取得カウント、ログから取得
sources.py stale --claim-kind Kその主張の種類の半減期に基づいて、ログに記録されたどの情報源が古くなったか
sources.py resume以前の実行がすでにフェッチしたもの。再実行でスキップするため
independence.py groups | check情報源を独立した声にまとめる;角度を認識した裏付けをカウントする
independence.py portfolio1つの発見内ではなく、実行全体にわたる情報源の集中度
index.py add | listリサーチインデックス — 実行をファイルする、過去のものを見つける、古いものを特定する
matrix.py check --report PATH比較マトリックスの完全性
check.py --report PATH --level LEVEL出荷可能かどうかのゲート
finish.py --report PATH --level LEVELゲート、陳腐化スイープ、ファイリングを1回の呼び出しで
bd_search.py "<query|url>" -m MODE --jsonBright Data 取得フォールバック

出力

実行の開始時に一度出力ベースを解決する:

OUTPUT_BASE="${LEGWORK_OUTPUT:-$(git rev-parse --show-toplevel 2>/dev/null || pwd)/docs/research}"
BASE="[Topic]_Research_$(date +%Y%m%d)"
OUT="$OUTPUT_BASE/$BASE"; mkdir -p "$OUT"

…

[翻訳のため省略]

関連スキル