Cerebras が公開した社内ナレッジベースの作り方:誰にも使い方を変えさせず、資料は元の場所に置いたままAIが自分で取りに行く
- Cerebras のエンジニア3名が、社内ナレッジベース「Cerebras Knowledge」の作り方を公開した。公開から3か月で1日15000件超の質問をさばいており、質問者には社員だけでなく自動化スクリプトや Agent も含まれる。
- 誰にも使い方を変えさせない設計になっている。資料は引き続き Slack、コードリポジトリ、ドキュメントシステムに残したまま、システム側が各プラットフォームからデータを取りに行き、すべて同じ Postgres の1テーブルに集約する。
- もっとも手強いソースは Slack。同じ候補集合に対して、全文一致、ベクトル一致、レア単語の重み付け、時間減衰という4種のスコアリングを同時にかけ、それぞれの盲点を補い合う。
- チャット履歴はそのままベクトル化しない。まずモデルが「一言の質問文+要約+結論+関連システムとコードシンボル」という統一構造に蒸留してから埋め込む。
- 6つの検索器がそれぞれランキングを出し、それを Reciprocal Rank Fusion(RRF)で1本に合成する。定数は60を採用しており、「複数のランキングで上位に入る」文書が「1本のランキングで1位」の文書に勝つ効果が出ている。
1日15000件の質問、その中には Agent からのものも
Cerebras のエンジニア3名が最近、自社ブログで社内ナレッジベース「Cerebras Knowledge」の作り方をまるごと公開した。データ収集から回答のランキングまで、各層でどんなパラメータを使ったかがすべて書かれている。
このシステムは公開から3か月、1日15000件超の質問をさばいている。質問しているのは社員だけでなく、自動化スクリプトや Agent も含まれる。
これを引き起こしている状況は多くの企業に馴染み深いものだ。Cerebras のチームはデータセンター運用、チップ設計、ハードウェア、トレーニング、推論、クラウドプラットフォームなど各方面に分散しており、毎年数百人の新人が入ってくる。コミュニケーションチャンネルは同じ3種類の質問で埋め尽くされる——あれはどこにある、これは誰が一番詳しい、この用語はどういう意味か。
資料を1か所に全部集める、なぜこれまで一度も成功しなかったのか
社内で資料を探すのが難しいのは、検索そのものが難しいからではなく、資料が生まれつき散らばっているからだ。四半期ごとに誰かが同じ「絶妙な案」を出す——今後すべての情報を1つのプラットフォームに記録し、唯一の真実の情報源にしよう、と。この構想は実践でほとんど成功したためしがない。
理由は、情報はどこで作るのが便利かによって生まれる場所が決まるからだ。ドキュメントの中の修正提案、Slack のスレッド、GitHub のコード参照、Jira のステータス欄。これらのプラットフォームはそれぞれの用途に何年もかけて磨き上げられてきた。Google Docs で pull request を議論するのは、体験としてかなりひどいものになる。
そのため Cerebras の最初の決断は、既存の習慣をほぼ変えさせないシステムを設計することだった。収集側のやり方は、各プラットフォームから直接データを抜き出すというものだ。
- 今後すべて統一プラットフォームに書くよう要求する
- 一人ひとりに手間が1つ増え、数週間で元に戻る
- 過去の資料は元の場所に残ったまま、両方とも不完全になる
- 人は引き続き一番使いやすい場所に書く
- ソースごとにコネクタを1本書いてデータを取りに行く
- 取ってきたものを統一フォーマットにして、同じテーブルに落とす
システム全体の核は、1枚のテーブル
このナレッジベースが外部に提供するのは3つ:社内データを置く場所、そのデータを検索する場所、そして認証・権限制御・監査・統計を担う層だ。
核となるのは Postgres の1テーブルで、そこにベクトル、元の要約、メタデータが出どころを問わず同居している。システムは社内各所のデータを継続的に流し込み、常に検索可能な状態を保つ。データインターフェースは意図的にシンプルに作られている。Slack のスレッドから来ようが、チップ設計で使うネットリストファイルから来ようが、同じベクトルテーブルに落ちる。このテーブルに入りさえすれば、同じインターフェースで検索できる。
各データソースが定義する必要があるのは3つだけ:これは何のデータか、どう接続するか、どのくらいの頻度で取得するか。取ってきて生成される各行は、フィールド構造がまったく同じだ。
この設計は他チーム向けの抜け道も用意している。すでに自前のデータベースを持っていて、ナレッジベースに入れるためだけに Slack やドキュメントシステムにデータを移したくないチームもある。その場合は、このソースをプラグインスクリプトとして扱う。チームが pull request を1本提出し、自分のシステムからデータを読んでそのテーブル構造に合う行を吐き出す小さな Python モジュールを用意し、データソースのレコードを1件設定する。同じライブラリに書き込み、同じフィールドセットを使う限り、残りの全パイプラインは1行も変更する必要がない。
Slack で一番難しいのは、どの発言が有用か見分けること
Slack は彼らが最も重視し、かつ最も扱いにくいデータソースだ。社内の最新のエンジニアリング議論はそこで行われる。最初は最も手軽な方法を試した——元のテキストをそのままベクトル化して検索する。だがすぐに、ベクトルだけでは網羅できないことがわかった。
問題はチャット履歴自体が持つ3つの特徴から来ていた。第一に、情報密度の差が極端に大きい。「了解、ありがとう」と、カーネル実装を丸ごと説明する長文が、システムの目にはどちらも「1件のメッセージ」にしか見えない。第二に、メッセージの長さがまちまちで、短いメッセージがベクトル類似度でしばしば長く詳細なメッセージを上回ってしまう。第三に、あるメッセージの意味は前後の会話に依存することが多い。
グループチャットで「マニフェスト読み込み後に復元が止まる」と検索する。実際にこの問題を解決した返信は、元の単語を1つも使わず「checkpoint が NFS マウントポイントで詰まっていた」と言っているかもしれない。一方、文字面が一番似ているのは8か月前の、すでに廃止された古い対処法かもしれない。そして「了解、ありがとう」は、ほぼどんな質問文とも少し似てしまう。
彼らの解決策は、同じコンテンツを複数の検索方式で同時にカバーし、それぞれが他の弱点を補うというものだ。同じクエリ、同じ4件の候補で、スコアリング方式を切り替えると、誰が上がり誰が下がるかが毎回変わる(データは原文の例による)。