- Slack/コードリポジトリ/ドキュメント/社内データベースを既存の場所から直接収集する Cerebras Knowledge を構築し、リリースから3か月で社員/自動化/エージェントから1日15,000件以上の質問を処理
- すべてのデータを1つのツールに移すのではなく、共通スキーマの Postgres 埋め込みテーブル に接続し、収集/問い合わせ/認証・権限・監査・分析レイヤーを分離して、新しいデータソースを簡単に追加できるよう設計
- Slack検索は原文の埋め込みだけでは不十分なため、全文検索/埋め込み検索/逆文書頻度/時間減衰を併用し、スレッド要約と重要な個別発話のまとまりを別々に埋め込み
- クエリごとにLLMが利用する検索ツールを先に計画し、結果を並列収集したうえで RRFと再ランキングモデル で統合。MCPでは同じ検索機能を小さく安定した基本ツールとして直接公開
- 組織全体を無条件に検索せず、Slackチャンネル/リポジトリ/ドキュメント空間などをまとめた プロジェクト単位の検索範囲 をデフォルトに指定し、チームごとに関連性の高い結果を提供
情報が生成される場所から直接収集
- Cerebrasのデータセンター運用/チップ設計/ハードウェア/学習/推論/クラウドプラットフォームの各チームでは、毎年数百人が新たに加わるなかで「Xはどこにあるのか」「Yの専門家は誰か」「Zとは何か」といった質問が繰り返される
- すべての情報を単一プラットフォームに記録する方式は、実際の業務ではうまく機能しないと判断
- ドキュメントの提案修正、Slackスレッド、GitHubのコード参照、Jiraのステータスメタデータのように、情報はそれぞれの作業に適したツールで生成される
- 各プラットフォームは長年の製品開発と分析を通じて特定分野に最適化されているため、使い方の変更を強制しないことにした
- 収集段階で各プラットフォームに直接接続し、既存の業務行動の変化を最小限に抑える
共通埋め込みテーブルを中心にした構造
- ナレッジベースは3つのレイヤーで構成される
- 社内データを収集して保存するプラットフォーム
- 保存されたデータに問い合わせるプラットフォーム
- 認証/認可/監査/分析を適用するレイヤー
- 中心には、複数のソースからの 埋め込み/原文要約/メタデータ を保存する単一のPostgresテーブルがある
- Slackスレッド、コードリポジトリ、ドキュメントシステム、ネットリスト、カスタムデータベースが同じ埋め込み行インターフェースを使用する
- 各データソースはデータの定義、接続方法、収集周期を指定し、共通テーブルに記録された時点で同じ問い合わせインターフェースから検索可能になる
- Cerebrasの開発者が別途コネクタを作れるよう、データインターフェースは意図的にシンプルに保つ
Slackに必要なハイブリッド検索
- Slackは最新のエンジニアリング議論が行われる最も重要なデータソースだった
- 原文に単純な埋め込みを適用したベクトル検索だけでは、関連情報をすべて見つけるのは難しかった
- 「うん、いいね」のような短いメッセージと、詳細なカーネル説明が同じメッセージ単位で保存される
- 短いメッセージが、より長く詳細なメッセージよりコサイン類似度で上位になることが多い
- 個別メッセージの意味は周囲の会話に依存する
- 各Slackスレッドを4つの方式で同時に検索する
- 全文検索 は、エラー文字列/フラグ名/ホスト名のように埋め込みでは曖昧になる正確なトークンを見つける
- 埋め込み検索 は、「manifest後に復元が止まる」と「NFSマウントでチェックポイントが停止する」のように、異なる語彙で表現された質問と回答を結びつける
- 逆文書頻度(IDF) は、まれな設定フラグを含む短いメッセージの順位を上げ、よくある反応的な文句のスコアを下げる
- 時間減衰 は、同じ関連性を持つ回答の中で、古いインフラを説明している可能性がある過去スレッドより最新スレッドを優先する
- 1つのスコアだけを信頼せず、各検索器が作ったランキングリストをクエリ時点で結合する
Socket Modeベースのリアルタイム収集
- Slackボットをワークスペースにインストールし、Socket Mode の継続的なWebSocket接続ですべてのメッセージイベントを受信する
- Web APIを繰り返し呼び出さなくてもリアルタイムに更新でき、リクエスト速度制限の消費を減らせる
- イベントが到着したら即座に応答し、安定したイベントIDで重複を除去したうえで、収集コンシューマーが処理するようマークする
- 新しいメッセージを独立して保存せず、そのメッセージが属するスレッド全体を再取得する
- 親メッセージとすべての返信を1行として保存する
- 既存スレッドに返信が追加されると、親/兄弟返信/参加者リスト/最終アクティビティ時刻がすべて最新状態に更新される
- Slackチャンネルごとに別のデータソースを設け、インシデント対応チャンネルのように変更が多いチャンネルの収集周期を短く設定できる
スレッドの蒸留と構造化
- 原文のSlackテキストはPostgres GIN全文インデックス により、保存直後からキーワード検索が可能
- ベクトル検索用データは、LLMがスレッド全体から次の項目を抽出する
- エンジニアが実際に検索しそうな一行の質問
- 短い要約
- 解決方法
- 関連システムとコード参照
- 抽出された項目を埋め込んで共通テーブルに保存し、元の会話文そのものは直接埋め込まない
- 実験では、スレッドを一貫した形式に正規化したときに精度が大きく向上し、追加メタデータも意味検索により有用なシグナルを提供した
長いスレッドの個別メッセージを生かすBursting
- スレッド単位の要約だけでは、長い会話の中の重要なメッセージが抜け落ちる問題が残った
- 同じ投稿者が連続して送ったメッセージを 連続発話のまとまり(burst) として結合し、スレッドの主題を文脈として先頭に付けて別途埋め込む
- スレッド要約に含まれていない枝分かれした会話の回答も、独立して検索可能になる
- シグナルの弱い発話がデータベースに入らないよう重み付きシグナルを計算し、しきい値を超えたまとまりだけを保存する
- コーパス全体でIDFが4.0以上のまれなトークンを含む
- 結合後の発話長が最低200文字
- 1つ以上のメッセージにリアクション絵文字があり、社会的な重みを得ている
- 条件を満たしたまとまりは、スレッド単位のレコードとともに共通埋め込みテーブルに保存される
大規模コードリポジトリの差分埋め込み
- Claude Codeのようなコマンドラインツールが広がるなか、コードには
grepだけで十分かもしれないと考えていたが、業界関係者やCursorの大規模コードベース意味検索の結果を検討した後、コード埋め込みを導入した - 一部の社内リポジトリは40GBを超え、全体を継続的に再埋め込みするコストが主要な課題だった
- 複数の実験の後、コードベースのベクトル化に特化したオープンソースのドキュメント埋め込みフレームワーク CocoIndex を選択した
- 言語別の正規表現境界を、大きな単位から小さな単位の順に適用してコードを分割する
- まずクラスのような上位境界を使う
- チャンクが大きすぎる場合は、メソッドやより小さなブロック境界へ下げる
- 1つのファイルから、ファイル単位/関数単位のように異なる粒度の埋め込みが複数生成されることがある
- CocoIndexがPostgresに同期メタデータを保持し、コミットごとに変更されたコードチャンクだけを再埋め込みしてエクスポートする
- リポジトリが増えた後は、チームが直接提出できる設定ファイルによるオンボーディングに切り替え、ファイルパス別の許可リスト/ブロックリストをサポートする
カスタムデータソースの接続
- 一部のチームは、既存データベースの情報をSlackやドキュメントシステムへ移さずに、同じ検索インターフェースを使うことを望んだ
- カスタムソースをプラグインスクリプトとして扱う
- チームが既存システムを読み取り、共通埋め込みテーブル形式の行を出力する小さなPythonモジュールをプルリクエストとして提出する
- 対応するデータソース設定もあわせて追加する
- 共通スキーマで共有データベースに記録するだけで、Slack/コード/ドキュメントと一緒に検索され、残りのシステムでは別途処理は不要
クエリ計画とツールの並列実行
- すべての質問に対して、LLMがまず短い計画ステップを実行し、使用するツールとデータソースを決定する
- 主なツールは次のとおり
subsystem_index: ファイル別のLLM要約search: Slack/Wiki/コード/その他インデックスを統合し、内部でマージ・再ランキングするベクトル検索search_slack: Slack直接検索search_code: ソースリポジトリに対するripgreprecent_prs: 質問に関連する最近のプルリクエストwho_knows: 特定トピックの専門性を実際に示した人物の検索
- プランナーは、プロジェクト一覧/プロジェクト別データソース/各ソースが答えやすい質問を圧縮した説明を使用する
- 実行器は選択されたツールを並列呼び出しし、結果を共通の根拠形式に正規化してから最終合成LLMに渡す
RRFと再ランキング
- クエリと語彙だけを共有し、実際には別の質問に答えている文書が上位に現れる可能性があるため、別の再ランキング段階を設ける
- 異なる検索器のランキングリストを 相互ランク融合(RRF) で結合する
- 各文書が登場したリストごとに
weight / (60 + rank)を加算する - 基本重みは1.0、平滑化定数は60
- 複数の検索器でまんべんなく上位に現れた文書が、単一の検索器だけで1位になった文書を上回ることがある
- 各文書が登場したリストごとに
- 重複チャンクを元データ単位でまとめ、ファイル別の結果数を制限して、多様な上位20件の候補を作る
- 小さな再ランキングモデルが元の質問を基準に各文書へ0〜10点を付け、上位10件を残す
- 最終結果には周辺文脈を再び追加する
- Wikiセクションが一致した場合は、隣接する2つのセクションも一緒に取得し、タイトル/前提条件/注意事項がチャンク分割で失われないようにする
- 検索結果は、複数検索器の結合/元データ単位の重複排除/質問ベースの再ランキング/周辺文脈拡張を経た根拠のまとまりとして返される
MCPとWeb UIの役割分担
- MCPでは、1つの「質問に答える」エンドポイントではなく、
search_slack、search_code、search、who_knowsのような 検索基本機能 をそれぞれツールとして公開する - ツールを高速かつ低コストに呼び出せるよう、可能な限りLLM依存を取り除く
- 入力と出力の範囲を狭く、構造的で安定したものに保つ
- ベクトル検索/語彙検索/
ripgrepのような単一パイプラインに軽量なスコアルールを適用し、生の根拠行を返す
- Claude CodeをはじめとするMCP互換エージェントが、呼び出すツール/順序/結果の組み合わせ方を決めるオーケストレーションエンジンになる
- Web UIでは、同じツールを1つの完全な問い合わせパイプラインにつなぐ
- プランナー が質問とアクティブなプロジェクトを見て、呼び出す検索ツールを選択する
- 実行器 が呼び出しを並列処理し、スコア/新しさ/ソースのヒントを含む共通の根拠スキーマへ変換する
- 合成器 が質問と根拠のまとまりから、引用/注意事項/ソース間の統合を含む回答を生成する
- ユーザーは単に質問して答えを受け取るが、内部ではプランナー → 実行器 → 合成器の流れが実行される
プロジェクト単位の検索範囲
- コーパスが大きくなると、組織全体を常に検索する方式の関連性は急激に低下した
- コンパイラチームはインフラ運用手順が検索結果に出ることを望まず、逆の場合も同様だった
- プロジェクト を、クエリが実行されるデフォルトの作業空間として導入した
- 特定のSlackチャンネル/コードリポジトリ/社内データベース/ドキュメント空間を、チームや課題ごとにまとめる
- 共有インシデントチャンネルや中央プラットフォームリポジトリ1つを複数のプロジェクトから参照でき、データは複製しない
- オンボーディング過程で、ML学習インフラ/Compiler/Data Center Operationsのように業務に合ったデフォルトプロジェクトを選択または作成するようにした
- デフォルトプロジェクトをユーザープロフィールに保存し、すべての問い合わせ範囲を自動的に制限することで、新任エンジニアも関連チャンネルやリポジトリを先に把握しなくても検索を始められる
既存ツールを維持するナレッジベース
- ナレッジベースの動作原則は、情報を1つの硬直したシステムへ移すのではなく、すでに生成されている場所から収集すること
- 複数の検索方式を組み合わせて根拠を素早く見つけつつ、実際の企業データの多様性を受け入れ、組織が成長しても有用性を維持できる構造を作った
まだコメントはありません。