resolve-before-asking について
Resolve Before Asking は、人の身元や役割をユーザーに尋ねる前に、ナレッジシステムと外部情報を確認するエージェントスキルです。順序立てた検索手順を定め、解決できない場合は、判明した情報と仮説を添えて質問します。
主な機能
- 01複数ソースを使った順序付きの身元確認
- 02ナレッジと接続済みソースの検索
- 03タイムラインとグラフの確認
- 04ユーザーへの確認前に外部検索
- 05未解決時の仮説付き質問
- 06取り込み時のプレースホルダー解消
活用シーン
- 01下書きに登場する人物を特定する
- 02エンティティページ作成時に人物の役割を確認する
- 03検索で解決できない場合に限り身元を尋ねる
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ garrytan/ gbrain --skill resolve-before-askingインストール後、Claude Code で/resolve-before-askingを入力して読み込まれたか確認します。
同梱ファイルrouting-eval.jsonl
詳細
尋ねる前に解決する — ユーザーに迷惑をかける前に、思考を尽くす
規約: 基本の検索チェーン(search → query → get_page → 外部 API)については、 conventions/brain-first.md を参照してください。この スキルでは、そのチェーンを人間との境界までさらに一段階延長します。ユーザーへの質問は、 思考と外部へのエスカレーションを尽くした後の最後の手段であり、それらを 迂回する近道ではありません。
規約: _brain-filing-rules.md を参照してください — ingest-resolution セクションが扱うページは、主要な対象に応じてファイルに分類します (
people/、companies/)。
目的
答えがすでに思考内にある場合は、「X は誰ですか?」とユーザーに尋ねてはいけません。
人間に迷惑をかける前に、メモリが答えます — これがこの製品の約束です。 このスキルでは、エンティティを特定する質問をユーザーに送る前に実行する検索チェーンと、 質問が本当に妥当な場合のエスカレーション形式を定義します。
このスキルが防ぐ不具合
典型的なパターン:エージェントが、時系列の記録、会議履歴、インポートされたメッセージ アーカイブなど、豊富な情報を含む思考ページを持つエンティティに遭遇します。ところが、 それらを読まずにユーザーへ「X は誰ですか?」と尋ねます。これは怠惰なエスカレーションです。 システム自身で答えられる質問に、ユーザーの注意を使わせてしまいます。
不具合の例(匿名化済み):
- alice-example — 彼女の思考ページにはすでに役職の記載(「acme-example の Chief of Staff」)と長い会議履歴があった → それでもエージェントは尋ねた。
- charlie-example — インポートされた大量のメールスレッドで、すべての件名が ひとつの共通プロジェクトを示していた → それでもエージェントは尋ねた。
発動条件
これはハーネスのルーティング規約であり、機械的な保証ではありません。以下のいずれかに 当てはまる場合は、必ずここにルーティングしてください —
- 返信の下書きに「[名前] は誰ですか?」または同等の表現が含まれている。
- 誰かの役職、関係性、または身元について尋ねる下書きがある。
- エンティティを「不明」または「未特定」として提示しようとしている。
- 思考ページに
[To be filled by content analysis]または同様のプレースホルダー文がある。 - 人物のリストを作成していて、誰かを「関係性不明」のままにしている。
検索チェーン(順番に実行し、明確な答えが得られた時点で停止)
ステップ 1:think — 思考を横断した統合(ほとんどのケースを解決)
gbrain think "Who is {entity}? What is their relationship to the user? What role do they play? Use all available context — meetings, timeline, imported archives, facts."
think は思考データ全体を横断して統合します。エンティティに、インポート済みの
アクティビティ統計、時系列の記録、会議履歴を含むページがある場合、think はそれらの
点を結び付けます。MCP 経由では、entity("{entity}") でまず LLM を使わないカード
(別名、最終更新日時、上位の関連)を取得します。カードだけでは不十分な場合は、
synthesize がページを横断した詳細な回答を返します。
明確な答えが得られたら → 停止してください。答えを使い、ユーザーには尋ねないでください。
ステップ 2:search + ページ全体の読み込み
gbrain search "{entity}" --limit 5
gbrain get {entity-slug}
確認する項目:
- フロントマターの
relationshipフィールド — 入力済みなら関係性は解決済みです。 - 時系列の記録で繰り返し示される役職の手掛かり(「advisor」、「acme-example の colleague」、「chief of staff」など)。
- 事実テーブル — 役職や関係性に関する事実がないか確認します。
- 会議履歴 — 何に参加していたか、誰と参加していたかを確認します。
時系列の記録で一貫した役職が繰り返し示されている場合 → 停止してください。役職は明白です。 ユーザーには尋ねないでください。
ステップ 3:思考が実際に保持している各マウント済みソースをクエリする
チャンネルを決め打ちしないでください。思考が保持している内容を確認してから、クエリします:
gbrain sources list
gbrain query "emails with {entity}" --limit 10
gbrain query "meetings with {entity}" --limit 5
メールアーカイブ、カレンダーのインポート、チャットの書き起こし、会議メモなど、 何がマウントされていても、いくつかの件名や会議タイトルから通常は関係性が分かります:
- 請求書/スケジュール調整/請求に関する件名 → 専門サービス。
- 参加者が一貫している定期的な 1:1 のタイトル → 同僚。
- 夕食/週末の予定に関するメッセージ → 個人的な友人。
ステップ 4:時系列の確認 + グラフのたどり歩き
gbrain timeline {entity-slug} --limit 20
gbrain backlinks {entity-slug}
gbrain graph {entity-slug} --depth 2
日付付きの出来事、このエンティティについて言及している人物、そしてそれが何とつながって いるかを確認します。企業ページと 3 つの会議ページからバックリンクされている人物は、 不明ではありません。
ステップ 5:ウェブ検索(脳を優先したうえでの外部エスカレーション)
ステップ 1~4 で有用な情報が何も得られなかった場合に限り、一般的なウェブ検索を
"{entity name} {company/domain hints accumulated in steps 1-4}" で実行します。見つかった情報は、使用する前に脳ページへ反映します(brain-ops の読み取り・充実化・書き込みサイクル)。そうすれば、次の検索で同じ作業を繰り返さずに済みます。
ステップ 6:ユーザーにエスカレーションする(最後の手段)— 仮説を添えて質問する
これまでのすべてのステップで結論が得られなかった場合に限ります。
- 何を検索したかを伝えます。
- 見つかった情報を伝えます。部分的な手がかりでも省略しません。
- 具体的で確認可能な質問をします。「X は誰ですか?」ではなく、「{部分的な手がかりから導いた最有力の推測} は {entity} ですか?」
選択のゲートを設ける仕組み(2~4 個の選択肢、回答を見送る選択肢、ターンの終了)には ask-user を使用します。
信頼度のしきい値
- 信頼度が高い(質問しない):
think/synthesizeが明確な答えを示す、または 3 件以上のタイムライン項目に一貫した役割の説明がある、またはページの関係性フィールドに値が入力されている。 - 信頼度が低い(最有力の推測を示して質問する): 手がかりが矛盾している、または非常に少ない。質問します。ただし、質問は仮説から始め、矛盾がある場合はそれも伝えます。
中間の状態はありません。脳から答えが得られた場合はそれを使います。得られなかった場合は、手順を最後まで進めてから仮説を添えて質問します。
取り込み時にプレースホルダーを残さない
何らかの取り込みパイプライン(メールのインポート、カレンダー情報の補完、チャットの文字起こし、会議情報の取り込み)が人物または会社のページを作成、あるいは大幅に更新する場合は、エンティティの身元と関係性を直ちに解決します。プレースホルダーのテキストを残してはいけません。次のようなページは、
[To be filled by content analysis]> Contact from the user's personal network.- 空の
## Contextセクション
バグです。特に、取り込みバッチ自体にその人物が誰なのかを示す手がかりが何百件も含まれている場合は、なおさらです。取り込み後の処理として、バッチが作成または更新したすべてのページに対し、次の手順を実行します。
- プレースホルダーを確認します。 更新対象のページを走査し、マーカー(
[To be filled、Unknown relationship、TBD)を探します。プレースホルダーがなく、関係性も入力済みなら、すでに解決済みなのでスキップします。 - 手順を実行します(上記のステップ 1~4。取り込み時には、バッチが
thinkに必要な手がかりを直前に書き込んでいるため、通常はステップ 1 だけで十分です)。 - 情報を抽出します: 関係性の種類(友人/同僚/アドバイザー/家族/創業者)、職務上の役割(役職+会社)、重要な背景(ユーザーとの知り合い方、いつ頃の関係か)。
- ページを更新します(
put_page):relationshipフロントマターのフィールドを埋め、プレースホルダーの説明を実際の内容を示す 1 行に置き換え、## Contextまたは導入段落を更新します。 - 一括処理の効率化(100 ページ以上):10~20 ページずつ解決します。記録された活動量の多いページを優先します(活動量が多いほど、ブリーフィングでユーザーがその名前を目にする可能性が高いため)。すでに十分な内容があるページはスキップします。
メールのドメインによる近道(証拠ではなく、仮説の生成に使う)
手順を実行する前に、送信者のドメインから仮説の手がかりが得られることがよくあります。
| ドメインの形式 | 仮説 |
|---|---|
@acme-example.com — すでに脳にある会社 | acme-example の従業員である可能性が高いです。会社ページと共通の会議記録で確認してから、情報を入力します。 |
| 脳にない企業ドメイン | 新しい会社です。手順を実行し、companies/ ページの作成も検討します。 |
| 個人用ドメイン(gmail など) | 近道はありません。手順をすべて実行します。 |
品質基準
解決済みのページは、ユーザーがブリーフィング、トリアージ、会議準備でその名前を見たとき、質問しなくてもページの最初の行で相手が誰なのか分かることが基準です。
- 悪い例:
> Contact from the user's personal network. - 良い例:
> Operations lead at acme-example — handles invoicing and vendor onboarding for the user.
契約
このスキルでは、以下を保証します。
- 対象エンティティについて検索チェーン(ステップ1~5)が実行されるまで、本人確認・役割・関係性に関する質問をユーザーにしません。
- エスカレーションでは、何を検索し、何が見つかったかを必ず述べ、仮説を最初に提示します。「Xとは誰ですか?」だけの質問はしません。
- このスキルが扱うページでは、取り込みバッチの処理後にプレースホルダーテキストが残らないようにし、関係性・役割のフィールドは書き込み時に入力します。
- 書き込み先は
writes_to:ディレクトリ内に限り、_brain-filing-rules.mdに従って主要な対象ごとに分類します。 - プライバシー契約を維持します。実名、フォーク固有のファイルシステムパスのリテラル、例における上流フォークへの言及は含めません。
出力形式
出力は次の2種類です。
(a)サイレントに解決 — 現在のフローで本人情報を使用します。ページにプレースホルダーがあった場合は、副作用として入力します(put_page)。検索についてユーザーに伝えるメッセージは送りません。
(b)仮説を添えてエスカレーション — ask-user の選択ゲートに従って形式を整えます。
🔀 **Is {entity} the {best guess}?**
Searched: think, search + page read, mounted sources, timeline/graph, web.
Found: recurring invoices from @widget-co.com; two meetings alongside the
acme-example team. Nothing names their role directly.
1. **Confirm** — {entity} is {best guess}
2. **Correct me** — it's someone else (tell me who)
3. **Skip** — leave unresolved for now
ゲートを出力したら、ターンを終了します(ask-user を参照)。
失敗した場合
gbrain のエラー code、終了コード、[AGENT] ブロック、または通知ブロックが発生した場合は、エージェントオペレータープロトコルに従ってください。このスキル固有の注意事項は以下のとおりです。
- 劣化通知とともにすべての検索結果が空の場合、キーワードのみの検索ではエンティティを見落とすことがあります。いきなり「Xとは誰ですか?」と聞くのではなく、その旨を確認可能な質問に含めてください。
- 推測したスラッグに対する
get_pageがpage_not_foundを返した場合、エンティティが不明だと結論づける前に、タイトルとエイリアスで検索してください。 - ページの入力で
revision_conflictが発生した場合は、再読み込みして内容を統合してください。
アンチパターン
- ❌ 事前に検索せず、「Xとは誰ですか?」と尋ねる。
- ❌ brain のページにタイムラインの項目が数十件あるのに、「あなたとの関係は何ですか?」と尋ねる。
- ❌ 不明な対象をリストで提示し、それぞれについて検索チェーンを実行しない。
- ❌ 数百件のシグナルを含む取り込みバッチを処理したページに、
[To be filled by content analysis]を残す。 - ❌ メールアドレスから勤務先が分かる相手について尋ねる(
[email protected])。 - ❌ エンティティ検索に
memory_searchを使用する。メモリツールはセッションのメモを検索するもので、brain のナレッジグラフは検索しません。brain-first.md ではこれを禁止しています。search/query/entityを使用してください。 - ❌
searchのヒット件数がゼロでないことを、検索チェーンの完了とみなす。ページを読み、「brain に存在しない」と結論づける前に、言い換え表現でqueryを実行してください。 - ❌ 根拠のない確信を持ってエスカレーションする。部分的なシグナルは解決ではなく仮説です。シグナルに矛盾がある場合は、エスカレーションでその矛盾を明示してください。
重複排除(明確な境界)
- query — ユーザーの質問に回答するための検索動作(3 層検索、情報の統合、引用)を担当します。このスキルも同じツールを使いますが、担当するのは検索ではなく、アイデンティティに関する質問をそもそもユーザーに尋ねてよいかどうかの判断です。
- brain-ops — brain とのあらゆるやり取りにおける、読み取り、情報の補完、書き込みの一般的なサイクルを担当します。このスキルは、そのサイクルにおける特定の出口、つまり人間へのアイデンティティに関する質問を許可するかどうかを判断します。
- ask-user — 質問の方法(選択肢を提示する形式、選択肢の数の上限、ターンの終了方法)を担当します。このスキルは、質問することが妥当かどうか、そして質問に何を含めるべきか(検索した内容、見つかった内容、仮説)を判断します。
- enrich — 段階的な情報補完プロトコルに従って、エンティティページを作成、更新します。ここの「取り込み時にプレースホルダーを残さない」セクションは、それらの書き込みが満たすべき合格基準です。プレースホルダーを埋める必要がある場合は、このスキルの手順を実行してから、enrich/brain-ops の規約に従って書き込みます。
- conventions/brain-first.md — すべての検索において、外部 API より先に brain を参照する順序を定めます。このスキルはその順序を継承し、最後の境界、つまり人間に尋ねる前に外部を調べるという要件を追加します。
- 新しいページを作成する前に音韻や別名を照合する、重複排除を目的としたエンティティ作成前チェックは、異なる種類の問題を防ぎます。このチェックは書き込み時に重複ページが作成されるのを防ぎますが、このスキルは質問時に不要な質問をするのを防ぎます。実装された場合は、統合せずに相互参照してください。
基準
この人物の brain ページ(インポートされたアーカイブ、勤務先が分かるメールのドメイン、同じ役職を繰り返し記載したタイムラインの項目)を見て、ユーザーは、エージェントがこの人物について尋ねたのは妥当だと思うでしょうか?
答えが「いいえ」なら、手順を実行できていません。実行してください。