omh-deep-research について
omh-deep-researchは、複数の情報源から得た知見を統合・検証し、レポートを作成するマルチフェーズのウェブ調査スキルです。単一検索では足りない調査向けに、検索、ギャップ確認、統合、検証を段階的に進めます。
主な機能
- 01トピックを調査サブトピックに分解
- 02研究タスクをバッチで並列実行
- 03調査結果のギャップを確認
- 04知見を統合してレポートを作成
- 05レポートと引用を検証
活用シーン
- 01複数のウェブ情報源に基づくレポート作成
- 02計画前の未知分野の調査
- 03包括的な問いに向けた根拠の統合
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ witt3rd/ oh-my-hermes --skill omh-deep-researchインストール後、Claude Code で/omh-deep-researchを入力して読み込まれたか確認します。
詳細
OMH ディープリサーチ — 引用の検証を伴う複数フェーズのウェブ調査
使用する場合
- ユーザーが「〜について深く調査して」「〜についての調査レポート」 「包括的な調査」「Xを調査して」「Yについて何がわかっているか」と依頼した場合
- omh-deep-interview が未知の領域に遭遇し、背景情報を必要としている場合
- omh-ralplan が責任ある計画を立てる前に、外部の情報を必要としている場合
- ユーザーの質問に対して、単一の検索ではなく、3つ以上のウェブソースを ひとつの一貫した回答にまとめる必要がある場合
使用しない場合
- このトピックについて、
status: confirmedの.omh/research/{slug}-report.mdがすでに存在する場合 — 代わりにそれを確認します - 質問が単一の web_search 呼び出しで回答できる場合
- ユーザーがリアルタイム/時事データのみを求めている場合(このスキルは 最新性ではなく、長く活用できる統合を重視します)
- この Hermes インストールで
webツールセットが利用できない場合(前提条件を参照)
前提条件
以下のいずれかが不足している場合、このスキルは即座に失敗します。
webツールセット —web_searchとweb_extractを提供します。どちらかが 利用できない場合は、次を出力します。
作業を行う前に終了します。omh-deep-research requires the `web` toolset (web_search + web_extract); aborting.omh_stateツール — 推奨される方法です。存在しない場合は、.omh/state/research--{slug}.jsonを手動で読み書きします(インスタンスごと —{slug}はフェーズ1で生成される kebab+date+random4 です。複数の調査 トピックを並行して実行できます)。どちらも書き込み可能でない場合は、 明確なエラーを出して即座に失敗します。- 状態、計画、調査結果、レポート、ログ用の
.omh/への書き込みアクセス
Hermes での検出:hermes skills list | grep omh-deep-research を実行すると、
インストール後にこのスキルが表示されるはずです。
インストール(Hermes に検出させるためのシンボリックリンク)
mkdir -p ~/.hermes/skills/omh && ln -snf <repo>/plugins/omh/skills/omh-deep-research ~/.hermes/skills/omh/omh-deep-research
シンボリックリンクを作成する前に、親ディレクトリを必ず作成してください。
アーキテクチャ
5つの呼び出しフェーズがあり、任意の2つのフェーズ間で安全に終了できます。
| # | フェーズ | 読み込み | 書き込み | サブエージェント |
|---|---|---|---|---|
| 1 | 分解 | ユーザークエリ | {slug}-plan.md、state.phase=search | なし |
| 2 | 検索 | 計画、状態、findings/ | 新しい調査結果ファイル、state.completed_subtopics、phase | 1〜3 [omh-role:researcher] 並列 |
| 3 | ギャップ確認 | すべての調査結果 | 任意の _followup.md、または直接フェーズを切り替え | 0 または 1 [omh-role:researcher] |
| 4 | 統合 | すべての調査結果(親がインライン化) | {slug}-report.md status: draft、phase=verify | 1 [omh-role:research-synthesist] |
| 5 | 検証 | レポートと調査結果(親がインライン化) | confirmed frontmatter/状態の変更/ブロック | 1 [omh-role:research-verifier] |
インスタンスごとの状態。 各調査セッションは
.omh/state/research--{slug}.json に保存されます(エンジンが instance_id
をファイル名用の slug に変換します)。複数のトピックを同時に進行できます —
フェーズ1で生成された slug が instance_id となり、その後の
すべての omh_state(...) 呼び出しで instance_id="{slug}" を渡します。
セッションごとの成果物(計画、調査結果、レポート)は
.omh/research/ 内で slug をキーとして管理されます。以前の仕様にあった
research-{id}.json および
research-state.json(単一インスタンス)という表記は
廃止されています。
ファイルシステムの管理者は親です。 ウェブツールはすべて、委任された
サブエージェント内で使用します。親は調査結果ファイルを読み込み、その内容を
synthesist と verifier の context フィールドにインライン化します。
サブエージェントはテキストのみを返します。
ロールは参照し、インライン化しません。 [omh-role:NAME] マーカーを使用します。
ロールの本文全体は plugins/omh/references/role-*.md にあります。
手順
フェーズ 0:既存の状態とセンチネルを確認する
新しい調査セッションを開始する前に:
- 新しいリクエスト用の候補スラッグを生成します(フェーズ 1 のルールを参照)。
これを
new_slugとします。後述の列挙で判別するために必要です。 - 既存の調査インスタンスを一覧表示します —
omh_state(action="list_instances", mode="research")。ツールが 利用できない場合は、.omh/state/research--*.jsonを手動で glob します。各エントリにはinstance_id(== スラッグ)とactiveフラグが含まれます。 - 各アクティブエントリについて、まずキャンセル確認を実行します:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 キャンセルされている場合は、CANCELLED slug={slug}を記録し、omh_state(action="clear", mode="research", instance_id="{slug}")でそのインスタンスを消去します。 - センチネルの自己修復(確認後、消去前にクラッシュした場合の復旧)。 残っているアクティブエントリのうち、
.omh/research/{slug}-report.mdのフロントマターにstatus: confirmedがあるものは、 前回の実行がセンチネルを書き込んだ後、状態を消去する前にクラッシュしたことを意味します。完了済みとして扱い、REPORT_CONFIRMED_RECOVERED slug={slug}を記録して、omh_state(action="clear", mode="research", instance_id="{slug}")で消去します。 - トピック一致による再開 — 残っているアクティブエントリの
topicが新しいリクエストと 一致する場合は、そのスラッグのフェーズ 2/3/4/5 に直接進みます(既存のinstance_idを使用します)。new_slugは生成しないでください。 - このトピックについてすでに確認済み —
status: confirmedがあり、新しいトピックに一致する{slug}-report.mdが存在する場合は、更新(新しいスラッグを生成して再実行)/既存のレポートを表示/キャンセルのいずれかを選ぶよう促します。 - 競合なし —
new_slugでフェーズ 1 に進みます。異なるトピックでの調査は同時に実行できます。ブロックしないでください。
フェーズ 1:分解する
- キャンセル確認:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 - スラッグを生成します — 具体的なルール:
slug = kebab(topic)[:40] + '-' + YYYYMMDD + '-' + random4ここでrandom4は 4 文字の小文字の 16 進数です。kebab()= 小文字に変換し、英数字以外の連続文字を-に置き換え、 先頭と末尾の-を削除し、40 文字に切り詰めます。 - ユーザーのトピックを 3~5 個のサブトピックに分解します。各サブトピックについて、 検索クエリ候補を 2~3 個作成します。
.omh/research/{slug}-plan.mdに、フロントマターを含む計画をアトミックに書き込みます(一時ファイル → fsync → rename)。--- status: planning topic: {original user topic} slug: {slug} subtopics: - name: {subtopic 1 name} queries: [{q1}, {q2}, {q3}] - ... ---omh_state(action="write", mode="research", instance_id="{slug}", data={...})で状態を初期化します:{ "phase": "search", "slug": "{slug}", "topic": "{topic}", "subtopic_count": N, "completed_subtopics": [], "started_at": "{ISO-8601}", "session_id": "{uuid4}", "synthesis_attempts": 0 }STARTED slug={slug}とPLAN_WRITTEN slug={slug} subtopics=Nを記録します。- 終了します。再度呼び出すと、フェーズ 0 の再開処理を経由してフェーズ 2 から再開します。
フェーズ 2:検索(並列バッチ処理、再入可能)
このフェーズは再入可能です。1 回の実行につき、最大 3 つのリサーチャーサブエージェントで構成されるバッチを 1 つディスパッチして終了します。次のバッチをディスパッチするには、再度実行してください。再入は state.completed_subtopics によって制御されます。
- キャンセルを確認します:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 - 状態と
{slug}-plan.mdのフロントマターを読み取ります。 pending = [s for s in plan.subtopics if s.name not in state.completed_subtopics]を計算します。- 次の
batch = pending[:3](最大 3 つを並列で)を取得します。 [omh-role:researcher]マーカーを付けて、バッチ呼び出しを 1 回ディスパッチします:
各タスクのdelegate_task(tasks=[ { "goal": "<self-contained: topic, subtopic name, exact queries to run, output template per [omh-role:researcher]>", "context": "<plan excerpt for this subtopic; no other subagent's findings>", }, ...up to 3... ])goalはそれだけで完全に完結しており、サブエージェント間の依存関係はありません。サブエージェントがロールを読み込めるように、各goalに[omh-role:researcher]ロールマーカーを必ず含めてください。- (厳守する書き込み順序 — 絶対に逆にしないでください):
- このバッチのすべての調査結果ファイルをアトミックに書き込みます
(tmp → fsync → rename)。各ファイルは
.omh/research/{slug}-findings/{subtopic-slug}.mdに配置し、 サブエージェントから返された SOURCES ブロックにあるsubtopic、source_urls、信頼性タグをフロントマターに 記録します。 state.completed_subtopicsを更新します(リストに追加し、omh_state(action="write", mode="research", instance_id="{slug}", data=...)で永続化します)。- 終了します。
- このバッチのすべての調査結果ファイルをアトミックに書き込みます
(tmp → fsync → rename)。各ファイルは
- フェーズ遷移。 次回の実行では、フェーズ 0 によってここに戻ります。書き込み後に
pendingが空になった場合は、終了する前にstate.phase = "gap_check"を設定します(調査結果の書き込みの後も順序は同じです:調査結果 → completed_subtopics → フェーズ切り替え)。 - バッチごとに
BATCH_COMPLETE batch=N subtopics=[name1,name2,...]をログに記録します。
フェーズ 2 固有の注意点:
- サブトピック間の重複排除。 2 人のリサーチャーが同じ URL を提示する場合があります。統合担当(フェーズ 4)が Sources の全体的な番号の振り直しによってサブトピック間の重複を処理するため、フェーズ 2 でファイル間の重複を排除する必要はありません。
- 調査結果ファイル名のスラッグ。
kebab(subtopic.name)[:60]を使用します。2 つのサブトピックが同じスラッグに変換される場合は、末尾に-2、-3などを追加します。 - 親は
web_searchやweb_extractを直接呼び出しません。 Web ツールの使用はすべて、委譲された[omh-role:researcher]サブエージェント内で行います。親の役割はディスパッチとディスク操作です。
フェーズ 3:ギャップチェック(分岐は 2 つのみ)
親スキルは web_search や web_extract を直接呼び出しません。Web ツールの使用はすべて、委譲されたサブエージェント内で行われます。
-
キャンセルを確認します:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
.omh/research/{slug}-findings/*.mdの全ファイルを読み取ります。各ファイルからGAPS:の箇条書きリストを抽出します。すべてを連結し、辞書順で重複を排除します (大文字と小文字を区別せず、前後の空白を除いて比較し、最初の出現順を維持します)。 -
分岐は 2 つのみです:
-
(a) ギャップ 0 件 —
state.phase = "synthesize"を設定し、GAP_CHECK_COMPLETE gaps=0をログに記録して終了します。 -
(b) ギャップ 1 件以上 —
[omh-role:researcher]サブエージェントを 1 つ委譲します。 目標:重複排除したギャップリストを検索クエリとする、_followupという名前の 合成「サブトピック」。返されたテキストを親が.omh/research/{slug}-findings/_followup.mdにアトミックに書き込みます。state.phase = "synthesize"を設定し、GAP_CHECK_COMPLETE gaps=Nをログに記録して終了します。
しきい値による段階分けはありません。N と M によるギャップの分岐はありません。インラインの web_search 分岐もありません。分岐は 2 つのみ — これが契約です。
-
フェーズ 4:統合(親が調査結果をインライン化し、親がレポートを作成)
-
キャンセル確認:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
親が調査結果をインライン化します。
.omh/research/{slug}-findings/以下のすべてのファイル(存在する場合は_followup.mdも含む)を読み込みます。内容全体を連結し、委任タスクのcontextフィールドに含めます。統合サブエージェントはファイルシステムにアクセスできません。予算超過時の回避策(安全性確認済み)。 連結した内容がオーケストレーターのツール引数の予算を超える場合(5 件以上の調査結果ファイルで約 40KB 以上は目安)、親は各調査結果ファイルの SYNTHESIS セクションを要約してもかまいません。ただし、以下は維持します。
- SOURCES の
[N]ブロック全体を原文のまま(タイトル+URL+タグ+日付) - すべての GAPS セクションを原文のまま
_followupブロックを原文のまま(通常、最も短く、主張の密度が高い部分です) URL、引用タグ、数値の主張は削除も言い換えもしないでください。 2026-04 年の実地検証では、SYNTHESIS 本文を要約し、ソース一覧を原文のまま保持した、5 サブトピック+1 フォローアップの実行が、グローバルに再採番された 28 件の引用をすべて保持したまま、高い信頼度で検証を通過しました。 判断に迷う場合は、全文をインライン化してください。やむを得ない場合にのみ要約します。
- SOURCES の
-
[omh-role:research-synthesist]タスクを 1 件ディスパッチします。delegate_task( goal="<self-contained: produce report per [omh-role:research-synthesist] template; topic={topic}; reference inlined plan + findings>", context="<plan frontmatter + every findings file content, fully inlined>", ) -
再試行時のコンテキスト。
state.synthesis_attempts > 0の場合、前回の検証担当者による REQUEST_CHANGES フィードバック(state.last_verifier_feedbackに保存)を、以下の形式でゴールに追加します。Address these prior verifier findings: {feedback} -
親は必ず、返されたテキストで
.omh/research/{slug}-report.mdを上書きします。フロントマターはstatus: draftから始めます。-v2のような接尾辞は付けません。以前の判定はディスク上ではなく、state にのみ保持されます。 -
C3 の引き継ぎ。 親は返されたレポートを編集しません。
(insufficient sources for this subtopic)の文字列はそのまま残します。 -
state.phase = "verify"を設定し、REPORT_DRAFTをログに記録して終了します。
フェーズ 5:検証(親がインライン化;3 回の失敗で停止;順序を厳守)
-
キャンセル確認:
omh_state(action="cancel_check", mode="research", instance_id="{slug}")。 -
親がレポートと調査結果をインライン化します。
{slug}-report.mdと{slug}-findings/*.mdの全ファイルを読み込みます。両方の内容を連結し、検証担当への委任のcontextフィールドに含めます。検証サブエージェントはファイルシステムにアクセスできません。 -
ツール許可リスト(A5)。 ディスパッチ時には、Hermes が呼び出し単位のツール範囲指定に対応している場合、書き込み/編集/ファイルシステムのツールを除外したツール許可リストを渡します。Hermes が呼び出し単位の範囲指定に対応していない場合は、Known Gaps にその旨を記載し、
role-research-verifier.mdの読み取り専用に関する契約に従います。 -
[omh-role:research-verifier]タスクを 1 件ディスパッチします。返された VERDICT を解析します。 -
VERDICT が PASS の場合 — 順序を厳守(逆順は絶対禁止):
{slug}-report.mdにフロントマターstatus: confirmedを設定して書き込みます(アトミック処理;冪等なセンチネル;これが信頼できる情報源であり、最初に反映する必要があります)。- イベントログに
REPORT_CONFIRMED slug={slug}を追加します。 omh_state(action="clear", mode="research", instance_id="{slug}")で state をクリアします。- ユーザーに概要を表示して終了します。
ステップ 1 とステップ 3 の間にクラッシュが発生した場合、フェーズ 0 が自己修復します(confirmed センチネルを検出し、残存する state をクリアします)。
-
VERDICT が FAIL で、
state.synthesis_attempts < 3の場合:state.synthesis_attemptsをインクリメントします。- 検証担当者の REQUEST_CHANGES 判定(本文全体)を
state.last_verifier_feedbackに保存します。 state.phase = "synthesize"を設定します。VERIFY_FAIL slug={slug}とSYNTHESIS_RETRY attempt={N}をログに記録します。- 終了します。再実行時はフィードバックのコンテキストを付けてフェーズ 4 を再実行します。
-
VERDICT が FAIL で、
state.synthesis_attempts == 3の場合:state.phase = "blocked"を設定します。- 検証担当者が示した不足点の一覧をユーザーに提示します。
VERIFY_FAIL slug={slug}とBLOCKED_RETRIES_EXHAUSTED slug={slug}をログに記録します。- 終了します。state は保持されるため、ユーザーは確認やエスカレーションを行えます(フェーズ 0 はブロックされたセッションを自動再開しません)。
ログ記録
.omh/logs/research-{session_id}.log に追記専用のイベントを記録します。イベントは判断とフェーズ遷移のみで、調査結果の内容は記録しません(omh-deep-interview の規約に準拠)。
文書化されているイベント語彙:
STARTED slug={slug}PLAN_WRITTEN slug={slug} subtopics=NBATCH_COMPLETE batch=N subtopics=[...]GAP_CHECK_COMPLETE gaps=NREPORT_DRAFTVERIFY_PASSVERIFY_FAILSYNTHESIS_RETRY attempt=NBLOCKED_RETRIES_EXHAUSTED slug={slug}REPORT_CONFIRMED slug={slug}REPORT_CONFIRMED_RECOVERED slug={slug}BLOCKED slug={slug}CANCELLED
センチネル
後続のスキル(omh-deep-interview、omh-ralplan、omh-autopilot)は、次のファイルによって調査セッションの完了を検出します。
.omh/research/{slug}-report.md with frontmatter `status: confirmed`
このファイルが永続的な契約です。状態は一時的なものであり、センチネルが信頼できる唯一の情報源です。
注意点
- 親から
web_searchやweb_extractを呼び出さないでください。 Web ツールの利用はすべて、委譲先の[omh-role:researcher]サブエージェント内で行います。 - ロールのテキストを直接埋め込まないでください。
[omh-role:NAME]マーカーを使用してください。本文はplugins/omh/references/role-*.mdにあります。 - フェーズ境界はコミットポイントです。 各フェーズは、出力の書き込みと状態の更新を終えたら、必ず正常に終了する必要があります。複数の委譲にまたがる長時間実行のフェーズは、安全に終了できません。
- プロジェクトごとに実行できる調査セッションは一つだけです。 フェーズ 0 でこれを強制します。並行する調査状態を作成しないでください。
- スラッグの衝突はユーザーに見えます。
random4接尾辞により、同じトピックを同じ日に再実行しても、互いの結果が上書きされません。
既知の不足事項
- Wiki/fact_store/メモリへの永続化はまだ統合されていません。v1 で永続的なインターフェースとなるのは、センチネルレポートのみです。(Q2)
[omh-role:research-verifier]に対する呼び出しごとのサブエージェントツールのスコープ設定は、Hermes のインストール環境によっては利用できない場合があります。その場合は、role-research-verifier.mdの文章で読み取り専用の契約を適用します。(A5)