開発者向けクロスツール検索:コードベースで探すのは間違い
開発者の意思決定の多くはコードの外にある。Slack、Linear、GitHub、Notionを横断するクロスツール検索の構築方法を解説します。
By Ellis Keane · 2026-03-17
コードベースは、意思決定の理由を調べるうえで最も役に立たない場所です。
逆説的に聞こえるのはわかります。私たちはripgrepのフラグを学んだり、IDEの検索を設定したり、正規表現パターンを覚えたりするのに何年もの時間を費やします。しかし、問いが「この関数はどこにある?」ではなく、「議論した三つの代替案ではなくこのアプローチを選んだ理由は何か?」であるとき、それらはまったく役に立ちません。その二番目の問いへの答えは、ほぼコードの中にはありません。四か月前のSlackスレッドにあり、ステータス更新の下に埋もれたLinearコメントにあり、誰かが始めて途中で止めてしまったNotionドキュメントにあり、本当の議論が返信の返信の返信で行われたPRレビューにあります。
これが開発者のクロスツール検索問題です。意思決定のコンテキストが、統一されたクエリパスのない複数のツールに分散しています。各ツール内では検索がうまく機能します。Slackの検索はまずまずで、GitHubのコード検索は優秀、Linearにはあらゆるフィルターがあります。しかし、それらを横断して検索するものは何もありません。あなたのアーキテクチャを形成した意思決定は五つの異なる場所に存在し、どこを見ればよいかを覚えておくことが求められます。
では、すでに持っているものを使ってクロスツール検索を構築する方法を紹介します。新しいツールは不要です(ほぼ不要ですが、最後に一つ紹介します。ただし、それなしでも機能します)。
分散した意思決定の解剖
具体的な例を見てみましょう。昨年、ジョブキューにBullMQとTemporalのどちらを使うかを決定していました。その意思決定が実際にどこに存在したかを示します:
- Slack (#engineering):二日間にわたる三つの別々のスレッド。最初は誰かがTemporalのブログ投稿へのリンクをシェアしたもの。二番目は耐久実行が必要かどうかの議論。三番目(一週間後、別のチャンネル)は「あ、キューの件って決まったっけ?」という質問。
- Linear:「ジョブキューオプションの評価」というタイトルのイシューに六つのコメントがあり、そのうちの一つはエンジニアの一人が午後をかけて作成した比較表を含んでいました。
- GitHub:BullMQ実装のPRの説明には「議論の通り」と書かれ、議論が行われた場所へのリンクはゼロ。
- Notion:Temporalのメリットをまとめたものの、最終決定では更新されなかった半完成のアーキテクチャ決定記録。
- Google Docs:実際に決定を下したコールのミーティングノートで、二つの無関係な議題項目の間の箇条書きに埋もれていました。
五つのツール。一つの意思決定。どれか一つのツールを検索しても断片しか見つかりません。PRが選んだものを教えてくれます。Slackスレッドが検討したものを教えてくれます。Linearイシューがトレードオフを教えてくれます。Notionドキュメントが推論の半分を教えてくれます。ミーティングノートが決定された瞬間を教えてくれます。
これは珍しいことではありません。これが2026年のエンジニアリングチームにおける意思決定追跡の、ある意味での最先端です。コードを生成するAIやインターネット全体をインデックスする検索エンジンを持ちながら、チームがなぜTemporalではなくBullMQを選んだのかを調べるには、五つのアプリを確認し、誰かの記憶に頼らなければなりません。
開発者にとってクロスツール検索が難しい理由
APIの問題ではありません。私たちが使うすべてのツールには完全に機能する検索APIがあります。問題はそれよりも奇妙なことです:
データの形状が異なる。 SlackはタイムスタンプとチャンネルIDを持つメッセージを返します。Linearは状態とラベルを持つイシューを返します。GitHubはコミット、PR、コードマッチを完全に異なるレスポンス形式で返します。これらを一貫したタイムラインにマージするには正規化が必要ですが、誰も構築しようとしません(正直なところ、スプリントのデモには映えない作業だからです)。
コンテキストの断片化。 「オプションBで行きましょう」というSlackメッセージは、オプションA、B、Cを定義したスレッドなしでは意味がありません。しかし、Slackの検索は個々のメッセージを返し、会話のアークは返しません。推論なしに結論を見つけることになります。
時間的ドリフト。 意思決定プロセスは、全員が他の作業に没頭していたために何も起こらない空白を挟んで、数日または数週間にわたることがよくあります。キーワード検索は、異なる段階で異なる言葉が使われたという理由だけで、会話の始まりと終わりを浮かび上がらせながら、重要な中間部分を見落とすかもしれません。
開発者向けクロスツール検索はAPIの問題ではありません。すべてのツールに十分に機能する検索エンドポイントがあります。コンテキストの問題です。意思決定は互換性のない形状で複数のツールに分散し、会話のアークによって断片化され、時間的ドリフトによって切断されています。キーワード検索は断片を見つけますが、全体像を見つけるのはつながったコンテキストだけです。
すでに持っているものでクロスツール検索を構築する
ここが実践的な部分です。読み取り専用の検索で三〜四つのツールを対象とする場合、MVPを動かすまでに半日かかると想定してください。そのほとんどは検索ロジック自体ではなく、認証設定とレスポンスの正規化に費やされます。
APIアクセスの設定
各ツールのトークンが必要です:
- Slack:
search:read スコープを持つユーザートークン(Slackの検索メソッドはボットトークンではなくユーザートークンが必要です。Slack APIアプリページから作成してください)
- Linear:設定のAPIから個人APIキー
- GitHub:リポジトリへの読み取りアクセスを持つきめ細かいPAT
- Notion:設定のコネクションから内部インテグレーショントークン
ファンアウトクエリスクリプト
基本的なパターンは驚くほどシンプルです。同じ検索クエリをすべてのAPIに送信し、結果を収集します:
```typescript interface SearchResult { source: 'slack' | 'linear' | 'github' | 'notion'; title: string; snippet: string; url: string; timestamp: Date; }
async function crossToolSearch(query: string): Promise<SearchResult[]> { const results = await Promise.all([ searchSlack(query), searchLinear(query), searchGitHub(query), searchNotion(query), ]);
return results .flat() .sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime()); } ```
各search*関数はそれぞれのAPIをラップします。Slackの場合はsearch.messages、Linearの場合は検索フィールドに対するGraphQLクエリ、GitHubの場合はREST検索エンドポイント、Notionの場合はqueryパラメーターを持つ検索エンドポイントです。
正規化と重複排除
難しい部分は検索ではなく、結果を有用にすることです。以下の処理が必要です:
- タイムスタンプの正規化:ツール間で統一します(SlackはUnixエポック、LinearはISO文字列、GitHubはタイムゾーンオフセット付きISOを使用)
- 関連結果のグループ化:同じSlackスレッドが三つのメッセージにマッチして三回出現する場合、スレッドURLを持つ一つの結果にまとめます
- 関連度によるランキング:ほとんどのAPIは独自の関連度スコアを返しますが、ツール間で比較できません。シンプルなヒューリスティック:タイトルの完全キーワードマッチは本文マッチより上位に、関連度が同等の場合は新しい結果が古いものより上位になります
CLIでラップする
私はCommander.jsを使っています(主に習慣ですが、何でも機能します):
```bash $ cross-search "bullmq vs temporal"
Found 14 results across 4 tools:
[Slack] #engineering – 2025-11-14 "I've been comparing BullMQ and Temporal for the job queue..." https://myteam.slack.com/archives/C0X.../p17318...
[Linear] ENG-342 – 2025-11-15 "Evaluate job queue options – BullMQ vs Temporal" https://linear.app/myteam/issue/ENG-342
[GitHub] PR #289 – 2025-11-22 "feat: implement BullMQ job queue (as discussed)" https://github.com/myorg/myrepo/pull/289
[Notion] Architecture Decisions – 2025-11-13 "Job Queue Evaluation: Temporal vs BullMQ" https://notion.so/myteam/abc123... ```
四つのツールにわたる、時間順に並んだ14件の結果。意思決定の全体のアークを一か所で確認できます。Notionドキュメントが最初に始まり、次にSlackの議論が起こり、次に追跡のためにLinearイシューが作成され、最後に一週間後にPRがマージされました。
より良くする方法
基本バージョンは機能しますが、いくつかの不満な点があります。改善方法を紹介します:
Slackのスレッド展開。 マッチするメッセージを見つけたら、conversations.repliesでスレッド全体を取得します。マッチするメッセージは「そうですね、BullMQにしましょう」かもしれませんが、それ以前の40件の議論メッセージなしでは役に立ちません。マッチするメッセージだけでなく、スレッドのスニペットを表示してください。
PRレビューコメント。 GitHubの検索APIはPRを検索する際にレビューコメントを表示しません。それらを取得するには、プルリクエストレビューエンドポイントへの別の呼び出しが必要です。そこに実際の技術的な議論があります。
バックリンク。 Linearイシューを見つけたら、そのイシューのURLを含むSlackメッセージがあるか確認します。Slackの検索はキーワードと組み合わせたhas:linkフィルターをサポートしています。これにより、正式な追跡の周辺で起こった非公式の議論が浮かび上がります。
キャッシング。 チームが多くのコンテンツを生成する場合(そうでないチームはほとんどありません)、すぐにレート制限に達します。TTLが30分のローカルキャッシュで結果をキャッシュしてください。ほとんどの過去の意思決定はそれほど速く変わりません。
テキスト検索の限界
ここで、制限について正直に話しましょう。ツール間のキーワード検索は驚くほど遠くまで機能し、その後壁にぶつかります。
その壁とは:意思決定は進化するということです。「ジョブキュー」に関するSlackスレッドは「BullMQ」という名前を一度も言及しないかもしれません。代わりに、誰かがリンクをシェアし、別の人が「Redisベースのオプションが好きです」と言い、三人目が「賛成です、それにしましょう」と言いました。「BullMQ」の検索はそのスレッド全体を見落とします。なぜなら、その言葉が使われなかったからです。スレッドの参加者は「Redisベースのオプション」が何を意味するかを知っていました。あなたの検索はそれを知りません。
これは根本的にグラフの問題であり、テキストの問題ではありません。実際に必要なのは「PR #289につながった意思決定に関連するすべてを表示してください」ということです。つまり、PRがLinearイシューを参照し、それはSlackの議論の後に作成され、Notionドキュメントを誰かが読んだことで始まったということを理解する必要があります。その接続は暗黙的です。人間がURLをコピーして「議論の通り」と言うことで作りました。キーワード検索はそれを再構築できません。
リンクをたどることで部分的に解決できます。SlackメッセージやPRの説明、LinearコメントからURLを解析します。シンプルな隣接リスト(このSlackスレッドがこのLinearイシューにリンクし、このPRで参照されている)を作成します。誰かが検索した際には、キーワードにマッチしなくてもリンクされたアイテムを含むように結果を展開できます。
その隣接リストアプローチは、本質的に初歩的なナレッジグラフです。そして、開発者向けクロスツール検索の実際の価値がそこにあります。個々のメッセージを見つけることではなく、意思決定のスレッドを触れたすべてのツールにわたって追うことです。それは「検索」というよりも開発者ナレッジマネジメントです。情報がツール間でどのように流れているかを理解し、必要なときにコンテキストを再構築できるようにすることです。
メンテナンスの問題(そして近道)
スクリプトアプローチは三か月ほど素晴らしく機能し、その後、誰かがSlackワークスペースを変更したり、LinearがGraphQLスキーマを更新したり、新しいツールを追加したのに検索スクリプトを更新することを誰も覚えていなかったりします。私はこれをまったく同じように二回構築して二回放棄しました(それはアプローチ自体よりも私のメンテナンスへのコミットメントについて多くを物語っているかもしれませんが)。
手間をかけずに最新の状態を保つクロスツール検索が必要なら、Sugarbugのようなツールがそのために作られています。ツールが変わってもナレッジグラフを自動的に維持し、接続を生き続けさせます。しかし、メンテナンスを厭わないなら、上記のDIYバージョンは本当に役立ちます。
五つのツールを別々に検索するのはやめましょう。Sugarbugはナレッジグラフを構築し、任意の意思決定、議論、またはコミットを一か所で見つけられるようにします。
Q: 複数の開発者ツールを一度に横断検索するにはどうすればよいですか? A: 各ツールのAPI(Slackのsearch.messages、LinearのissueSearch、GitHubのコード検索エンドポイント)を組み合わせ、クエリを一括送信して結果をタイムスタンプでマージする軽量なクロスツール検索スクリプトを構築できます。上記のコードサンプルで午後には始められます。主な課題は検索自体ではなく、異なるレスポンス形式を一貫したタイムラインに正規化することです。
Q: SugarbugはCross-tool Searchを提供していますか? A: はい。SugarbugはLinear、GitHub、Slack、Figma、Notionなどのツールからシグナルを取り込み、ナレッジグラフに統合します。これにより、意思決定や議論を検索すると、関連するすべてのスレッド、イシュー、コミットを一か所で確認できます。正規化、重複排除、リンクの追跡を自動的に処理し、DIYアプローチが時間の経過とともに壊れやすくなる部分をカバーします。
Q: アーキテクチャの意思決定をコードベースで見つけられないのはなぜですか? A: ほとんどの意思決定はSlackスレッド、Linearコメント、Notionドキュメント、PRレビューで行われ、コード自体には記録されないからです。コードは意思決定の結果(関数が存在し、ライブラリが選択された)を記録しますが、推論、トレードオフ、議論された代替案はコミュニケーションツール全体に分散しています。git blameは誰がいつ行を変更したかを教えてくれますが、なぜそのアプローチが代替案より選ばれたかは教えてくれません。
Q: SugarbugはADRドキュメントの代わりになりますか? A: SugarbugはADRを置き換えるものではありませんが、ADRに記録されない意思決定を捕捉します。ほとんどのチームはアーキテクチャの選択の約10%についてADRを書くだけで、残りはSlackスレッドやPRコメントに溶け込んでしまいます。Sugarbugは会話とそれが生み出したコード変更を接続することで、これらを浮かび上がらせ、誰のワークフローも変えることなく残りの90%の意思決定追跡を提供します。