Cerebras が公開した社内ナレッジベースの作り方:誰にも使い方を変えさせず、資料は元の場所に置いたままAIが自分で取りに行く

公開から3か月で1日15000件超の質問をさばく。四方向スコアリング、スレッド蒸留、ランキング融合の具体的なパラメータまで公開されている。
著者:Cerebras07-18 · 12 分で読了⚑ チュートリアル
🎧 ポッドキャスト版0:00 / --:--
0:00 / --:--
深掘り · 小互解読
1分でわかる要点
  • Cerebras のエンジニア3名が、社内ナレッジベース「Cerebras Knowledge」の作り方を公開した。公開から3か月で1日15000件超の質問をさばいており、質問者には社員だけでなく自動化スクリプトや Agent も含まれる。
  • 誰にも使い方を変えさせない設計になっている。資料は引き続き Slack、コードリポジトリ、ドキュメントシステムに残したまま、システム側が各プラットフォームからデータを取りに行き、すべて同じ Postgres の1テーブルに集約する。
  • もっとも手強いソースは Slack。同じ候補集合に対して、全文一致、ベクトル一致、レア単語の重み付け、時間減衰という4種のスコアリングを同時にかけ、それぞれの盲点を補い合う。
  • チャット履歴はそのままベクトル化しない。まずモデルが「一言の質問文+要約+結論+関連システムとコードシンボル」という統一構造に蒸留してから埋め込む。
  • 6つの検索器がそれぞれランキングを出し、それを Reciprocal Rank Fusion(RRF)で1本に合成する。定数は60を採用しており、「複数のランキングで上位に入る」文書が「1本のランキングで1位」の文書に勝つ効果が出ている。
導入 · 公開から3か月

1日15000件の質問、その中には Agent からのものも

Cerebras のエンジニア3名が最近、自社ブログで社内ナレッジベース「Cerebras Knowledge」の作り方をまるごと公開した。データ収集から回答のランキングまで、各層でどんなパラメータを使ったかがすべて書かれている。

このシステムは公開から3か月、1日15000件超の質問をさばいている。質問しているのは社員だけでなく、自動化スクリプトや Agent も含まれる。

これを引き起こしている状況は多くの企業に馴染み深いものだ。Cerebras のチームはデータセンター運用、チップ設計、ハードウェア、トレーニング、推論、クラウドプラットフォームなど各方面に分散しており、毎年数百人の新人が入ってくる。コミュニケーションチャンネルは同じ3種類の質問で埋め尽くされる——あれはどこにある、これは誰が一番詳しい、この用語はどういう意味か。

◆注目すべきは、これがデモレベルの RAG 構築チュートリアルではないという点だ。1日15000件のクエリが実際の社内データの上で動いており、各層の取捨選択としきい値まで公開されている。3072次元ベクトル、レア単語のしきい値 IDF 4.0以上、burst 統合後最低200文字、ランキング融合定数は60、リランク後は証拠を10件に絞り込む、といった具合だ。
Cerebras Knowledge の6層アーキテクチャ全体像
元画像の表記は英語。6層は上から順に:① SOURCES データソース、Slack、Wiki、コード、インシデント記録 ② DISTILLATION 蒸留、モデルが元コンテンツを統一構造に抽出 ③ EMBEDDINGS ベクトル、Postgres の pgvector に保存、3072次元、HNSW というインデックス構造で最も近いベクトルを高速に見つける ④ RETRIEVAL 検索、6本のランキングを並行実行 ⑤ FUSION + RERANK 融合とリランク、まず RRF で融合してから小型モデルでリランク ⑥ SYNTHESIS 合成、引用付きの回答を生成。出典:Cerebras
設計判断 · データをどこに置くか

資料を1か所に全部集める、なぜこれまで一度も成功しなかったのか

社内で資料を探すのが難しいのは、検索そのものが難しいからではなく、資料が生まれつき散らばっているからだ。四半期ごとに誰かが同じ「絶妙な案」を出す——今後すべての情報を1つのプラットフォームに記録し、唯一の真実の情報源にしよう、と。この構想は実践でほとんど成功したためしがない。

理由は、情報はどこで作るのが便利かによって生まれる場所が決まるからだ。ドキュメントの中の修正提案、Slack のスレッド、GitHub のコード参照、Jira のステータス欄。これらのプラットフォームはそれぞれの用途に何年もかけて磨き上げられてきた。Google Docs で pull request を議論するのは、体験としてかなりひどいものになる。

そのため Cerebras の最初の決断は、既存の習慣をほぼ変えさせないシステムを設計することだった。収集側のやり方は、各プラットフォームから直接データを抜き出すというものだ。

引っ越し案
  • 今後すべて統一プラットフォームに書くよう要求する
  • 一人ひとりに手間が1つ増え、数週間で元に戻る
  • 過去の資料は元の場所に残ったまま、両方とも不完全になる
コネクタ案(採用した方式)
  • 人は引き続き一番使いやすい場所に書く
  • ソースごとにコネクタを1本書いてデータを取りに行く
  • 取ってきたものを統一フォーマットにして、同じテーブルに落とす

システム全体の核は、1枚のテーブル

このナレッジベースが外部に提供するのは3つ:社内データを置く場所、そのデータを検索する場所、そして認証・権限制御・監査・統計を担う層だ。

核となるのは Postgres の1テーブルで、そこにベクトル、元の要約、メタデータが出どころを問わず同居している。システムは社内各所のデータを継続的に流し込み、常に検索可能な状態を保つ。データインターフェースは意図的にシンプルに作られている。Slack のスレッドから来ようが、チップ設計で使うネットリストファイルから来ようが、同じベクトルテーブルに落ちる。このテーブルに入りさえすれば、同じインターフェースで検索できる。

各データソースが定義する必要があるのは3つだけ:これは何のデータか、どう接続するか、どのくらいの頻度で取得するか。取ってきて生成される各行は、フィールド構造がまったく同じだ。

ソース1つにコネクタ1本、同じテーブル・同じインターフェース
Slack チャンネル
Wiki / Confluence
コードリポジトリ
ネットリストファイル
社内ドキュメント
チーム独自のデータベース
→
EMBEDDINGS(1枚のテーブル)
document 正規化された本文
embedding 3072次元ベクトル
metadata チャンネル、投稿者、システム
source + タイムスタンプ
MCP ツールWeb インターフェースAgent
出典:Cerebras(原文のアーキテクチャ図をもとに日本語で再構成)。このテーブルが以降のすべての仕組みの共通基盤になる。新しいデータソースを1つ追加しても、クエリ側は一切変更不要。

この設計は他チーム向けの抜け道も用意している。すでに自前のデータベースを持っていて、ナレッジベースに入れるためだけに Slack やドキュメントシステムにデータを移したくないチームもある。その場合は、このソースをプラグインスクリプトとして扱う。チームが pull request を1本提出し、自分のシステムからデータを読んでそのテーブル構造に合う行を吐き出す小さな Python モジュールを用意し、データソースのレコードを1件設定する。同じライブラリに書き込み、同じフィールドセットを使う限り、残りの全パイプラインは1行も変更する必要がない。

Slack · ハイブリッド検索

Slack で一番難しいのは、どの発言が有用か見分けること

Slack は彼らが最も重視し、かつ最も扱いにくいデータソースだ。社内の最新のエンジニアリング議論はそこで行われる。最初は最も手軽な方法を試した——元のテキストをそのままベクトル化して検索する。だがすぐに、ベクトルだけでは網羅できないことがわかった。

問題はチャット履歴自体が持つ3つの特徴から来ていた。第一に、情報密度の差が極端に大きい。「了解、ありがとう」と、カーネル実装を丸ごと説明する長文が、システムの目にはどちらも「1件のメッセージ」にしか見えない。第二に、メッセージの長さがまちまちで、短いメッセージがベクトル類似度でしばしば長く詳細なメッセージを上回ってしまう。第三に、あるメッセージの意味は前後の会話に依存することが多い。

この3つの特徴が合わさると何が起きるか

グループチャットで「マニフェスト読み込み後に復元が止まる」と検索する。実際にこの問題を解決した返信は、元の単語を1つも使わず「checkpoint が NFS マウントポイントで詰まっていた」と言っているかもしれない。一方、文字面が一番似ているのは8か月前の、すでに廃止された古い対処法かもしれない。そして「了解、ありがとう」は、ほぼどんな質問文とも少し似てしまう。

彼らの解決策は、同じコンテンツを複数の検索方式で同時にカバーし、それぞれが他の弱点を補うというものだ。同じクエリ、同じ4件の候補で、スコアリング方式を切り替えると、誰が上がり誰が下がるかが毎回変わる(データは原文の例による)。

クエリ:restore hangs after manifest load
(マニフェスト読み込み後に復元が止まる)
単語をそのまま照合する。エンジニアがエラーメッセージをそのまま貼り付けたとき、文字面が一致していることこそが一番硬い証拠になる。意味がどれだけ近くても、それより上に来てはいけない。代償は、別の言い回しで同じことを説明している方が、一語も一致しないこと。
意味で照合する。質問者は「復元が止まった」と言い、回答者は「checkpoint が NFS マウントポイントで停止した」と言う。両者に共通の単語が1つもないこともある。この層はまさにそういうケースを拾うためのものだ。代償は、あいさつ文がベクトル空間上ではどの質問文からもそう遠くない位置にあること。
単語がどれだけ珍しいかで重みを付ける。短いメッセージでも珍しい設定項目名を使っていれば、上位に来る価値がある。一方「了解、ありがとう」は、単語の希少度でスコアを計算するとほぼゼロに近づく。
時間で割引する。両方とも同じ質問に答えられる内容だとしても、8か月前のものが説明しているインフラはもう存在しないかもしれない。関連度が同程度なら、新しい方を優先する。
2週間前 · スレッド
Checkpoint が NFS マウントポイントで詰まっている。CKPT_PREFETCH を4に設定して。
共通の単語が1つもない 言い回しは違うが意味が一致 CKPT_PREFETCH は極めて珍しい 2週間以内、同点なら勝つ
1日前 · 単発メッセージ
ERR_MANIFEST_TIMEOUT:マニフェスト読み込み後に復元が止まる。
原文の単語が逐語一致 エラーコードはレア単語
3時間前 · 単発メッセージ
了解、ありがとう、試してみる。
誰にでも少し似てしまう偽の隣人 よくある単語ばかり、スコアはほぼゼロ
8か月前 · スレッド
マニフェスト読み込み後に復元が止まる、LEGACY_FETCHER=1 に切り替えて対処。
文字面がほぼ同一 8か月経過、時間で割引
塗りつぶし=このスコアリングで押し上げられる 破線グレー=押し下げられる 白地でラベルなし=このスコアリングでは明確な影響なし データは原文の例による。出典:Cerebras
このコンポーネントが示していること

4つのタブを切り替えてみると、押し上げられるものと押し下げられるものが毎回違うことがわかる。2週間前の、言い回しを変えて、珍しいパラメータ名を含むあのスレッドこそ、実際に問題を解決した答えだが、全文一致の列では一語も一致していない。ベクトル一致、レア単語の重み、時間減衰の3列だけがそれを認めている。逆に、8か月前の文字面がほぼ同一の古い答えは、全文一致では最も高く評価されるが、時間減衰の列でようやく割り引かれる。どのスコアリングも単独で使えば、本当の答えを見逃すか、古い答えを上位に並べてしまうかのどちらかになる。だからこそ4種のスコアリングがそれぞれランキングを1本ずつ出し、クエリ時にそれを合算する。

Slack · 蒸留と補完取得

チャット履歴はそのままベクトル化しない

元の Slack テキストは、そのまま置くだけでキーワード検索できる。Postgres 上で元テキストに全文インデックスを維持しているからだ。しかしベクトル検索を本当に使えるものにするには、もう一段の加工が必要だった。

この工程を蒸留と呼ぶ。モデルにスレッド全体を読ませ、4つのものを抽出させる——エンジニアが実際に検索しそうな一言の質問文、簡潔な要約、最終的な結論、そして過程で言及されたシステムとコードシンボルだ。ベクトル化されるのはこの4つであり、逐語のチャット記録そのものはベクトルデータベースに入らない。実測では、スレッドを統一フォーマットに正規化することで精度がはっきり向上し、追加されたメタデータが意味的マッチングにより多くの手がかりを与えている。

1本のスレッド、3段階の加工
① 元のスレッド
09:14 Maya大規模クラスタで復元がマニフェスト読み込み後に止まる。小規模だと問題ない。
09:17 Owen128シャードで再現する。ログはキャッシュのウォームアップ前で止まっている。
09:18 Sam自分のノートPCも月曜になるといつも止まる。
09:21 MayaCKPT_PREFETCH=4 に設定したら完走した。デフォルト値は NFS マウントポイントには高すぎる。
→
② 構造体として抽出
questionなぜ復元がマニフェスト読み込み後に止まるのか?
summary大規模な復元がキャッシュのウォームアップ前で停止する。
resolutionNFS マウントポイントに CKPT_PREFETCH=4 を設定する。
systemscheckpoint 復元、NFS
code_refsCKPT_PREFETCH
→
③ 1行のベクトルレコード
正規化後の本文質問+要約+結論+システム+コードシンボル
sourceslack_thread
source_idthread_8f42
embedding3,072次元
metadataチャンネル+参加者+時刻
出典:Cerebras(原文の図解をもとに日本語で再構成)。3件目のメッセージ「自分のノートPCも月曜になるといつも止まる」は脱線した内容である点に注意。元の記録には出てくるが、抽出された構造体には含まれていない。
データがどうリアルタイムで入ってくるか:Socket Mode とスレッド丸ごと再取得

収集側では、彼らはワークスペースに Slack ボットを設置し、Socket Mode で動かしている。Slack は1本の長時間接続を通じてメッセージイベントを逐一プッシュしてくるので、Web API を繰り返しポーリングする必要がなく、API のレート制限にも引っかからない。

イベントが届くとすぐに受信確認を返し、安定したイベント ID で重複排除したうえで、取り込みプログラムにマークを付ける。この取り込みステップには見落としがちな設計がある——新しいメッセージだけを単独で保存するのではなく、まずそのメッセージがどのスレッドに属するかを特定し、Slack API から会話全体(最初の投稿とそれ以降のすべての返信)を改めて取得し直し、スレッド全体を1行として書き戻す。したがって、新しい返信が1件届くたびに、親メッセージと同階層のすべての返信が再取得される。保存される本文、参加者リスト、最終アクティブ時刻は、常に会話全体の現在の状態を反映している。

また、システム内では各 Slack チャンネルがそれぞれ独立したデータソースとして扱われ、収集頻度を個別に調整できる。あるチームは自分たちの高頻度な障害対応チャンネルをより頻繁に更新させることができる。

長いスレッドの中で、要約に漏れてしまうメッセージ

ここまでで Slack の検索はすでに使えるものになっていたが、彼らは繰り返し同じ問題にぶつかった。長いスレッドの中の重要なメッセージが、スレッド全体の要約に必ずしも痕跡を残すとは限らないのだ。

この対策が bursting と呼ばれる手法だ。バーストとは、同じ人が連続して投稿した複数のメッセージのことを指す。彼らは各バーストを個別にベクトル化し、その前にスレッド全体の話題をコンテキストとして付加する。こうすることで、答えが脱線した枝分かれの中に埋もれていて、使われている単語がスレッド全体の要約に一度も出てこないようなケースでも、単独で検索できるようになる。

低価値なコンテンツがデータベースに大量に流れ込まないよう、各バーストは加重スコアリングを通過して初めてベクトル化される。判定基準は3つ:全社的なコーパスの中で十分珍しい単語を含んでいること(希少度のしきい値は IDF 4.0以上)、統合後に最低200文字あること、そのバースト内のメッセージに同僚からの絵文字リアクションが付いていること(これは同僚からの承認とみなされる)。

5件のメッセージ、2つのバースト、うち1つは弾かれる
投稿者A短いメッセージ
投稿者A補足
投稿者B技術的な詳細
投稿者B結論を提示
投稿者C了解
→
BURST 01 弾かれる
短すぎて、よくある単語ばかり、絵文字リアクションもない。3つの判定基準を1つも満たさない。
BURST 02 登録される
十分な長さがあり、レア単語を含み、絵文字リアクションも付いている。ベクトル化され、スレッド全体のレコードと並んで同じテーブルに保存される。
出典:Cerebras(原文の図解をもとに日本語で再構成)。投稿者Cは「了解」の1件だけで単独のバーストを構成するが、これも同様にしきい値を通過できない。同じスレッドでも、こうして粒度の異なる2種類のレコードがデータベースに存在することになる——スレッド全体で1件、そして基準を満たしたバーストがいくつか。
コードリポジトリ · チャンク分割と増分更新

40GBのコードリポジトリを、どうやって最新に保つか

コードリポジトリをベクトル化すべきかどうか、彼らは最初ためらっていた。Claude Code のようなコマンドラインツールが登場した今、コード用のベクトルインデックスを作るのは少し直感に反するように見える——grep があれば十分ではないかと感じてしまう。同業者と話し、大規模コードベースの意味検索についての Cursor の知見を読んだうえで、彼らは試してみることにした。

本当の懸念は別のところにあった。社内のリポジトリは数が多く、1つで40GBを超えるものもある。それを許容できるコストで常に最新のインデックスに保つにはどうすればよいか、という点だ。

最終的に落ち着いたのは CocoIndex という、コードリポジトリのベクトル化専用に作られたオープンソースフレームワークだ。チャンク分割のルールは言語の構文境界に従い、粗いものから細かいものへと順に試す。まずクラスのような上位の境界を試し、切り出したチャンクがまだ大きすぎればメソッド境界まで下がり、それでもだめならさらに小さなコードブロックまで下がる。同じファイルからこうして複数の粒度のベクトルが生まれる。たとえばファイル単位で1本、関数単位でそれぞれ1本ずつといった具合だ。

N トークンごとに機械的に切る
  • 切れ目は長さだけで決まる
  • 1つの関数が途中で分断されることもある
  • 切り出したチャンクは前後が欠けて、何をしているか読み取れないことが多い
構文境界に従い粗→細
  • まずクラスで切り、大きすぎればメソッド、さらに条件分岐やループの単位まで下げる
  • 各チャンクが完全な構文単位になっている
  • 同じファイルから複数の粒度が生まれ、粗いものも細かいものも検索できる
構文境界によるチャンク分割のサンプルコード
原文のチャンク分割例、表記は英語。左側のコードで薄い色の背景が付いている箇所が識別された意味的チャンクで、行末の注釈には各チャンクが何段階目で切り出されたかが書かれている——まず class を試し、LoadManifest()、WarmShardCache()、Restore() の3つのメソッドまで進み、メソッド内がまだ大きい場合は if や for のレベルまで下げる。末尾のプライベートフィールド領域は単独のチャンクになる。右側の2つのボックスは上の対照表にある2つの分割方式(01 NAIVE WINDOWS:Nトークンごとに機械的に切る、02 LANGUAGE-AWARE:構文境界による分割。図で選択されているのは後者)。下部の凡例では SEMANTIC NODE は意味的チャンク、FIXED SPLIT は固定長の切れ目を指す。出典:Cerebras

更新面はこの方式が本当に手間を省いてくれるところだ。CocoIndex は同期用のメタデータも Postgres に保存しており、コミットのたびに変更のあったコードチャンクだけを作り直せばよく、リポジトリ全体を再計算する必要がない。同期状態とベクトルが同じデータベースに保存されている点は、彼らにとって特に都合が良かった。

接続するコードリポジトリが増えるにつれ、リポジトリ接続そのものが設定ファイルとして扱われるようになり、各チームが自分で提出できるようになった。ファイルパス単位でホワイトリストとブラックリストを設定することもできる。

クエリ側 · ツール選択と証拠取得

質問が来たあと、システムは何をしているのか

質問を受け取るたびに、システムはまず短いプランニングを1回走らせる。モデルがこの質問にどのツール、どのデータソースが必要そうかを判断し、選ばれたツールを並行して発行する。

プランニング → 並行証拠取得 → 合成
プランニングPLANNER
searchSlack、Wiki、コードなどすべてのソースを横断する統一ベクトル検索。内部ですでに融合とリランクを済ませている
search_slackSlack を直接検索
search_codeソースコードリポジトリに対して ripgrep(コマンドラインの高速全文検索ツール)を実行
subsystem_indexファイル単位で生成された個別の要約
recent_prs質問に関連する直近の pull request
who_knowsあるトピックについて実際に貢献したことがある人
合成回答+引用
出典:Cerebras(原文のフローチャートをもとに日本語で再構成)。このプランニング段階が見ているのは、圧縮されたインデックスの説明——どの project があり、各 project にどのソースがあり、各ソースがどんな質問に強いか——だ。これに基づいてツールを選び、実行層が並行して発行し、返ってきた結果をスコア・時刻・出典情報付きの統一された証拠フォーマットに正規化してから、最後のモデルの1回のパスに渡して回答を合成する。

MCP 側では、ツールを直接 Agent に渡して自分で組み立てさせる

Web インターフェースでは、上記のパイプラインはエンドツーエンドで実行される。プランニングがツールを選び、実行層が並行して証拠を取得してスコア・時刻・出典のヒント付きの統一された証拠に正規化し、最後のモデルのパスがそれに基づいて引用と注意事項付きの回答を生成する。利用者から見れば、質問して回答を受け取るだけだ。

MCP 統合はこれと逆のアプローチを取っている。検索機能を「この質問に答えて」という1つの大きなインターフェースの裏に隠すのではなく、1つずつ直接呼び出せるツールとしてバラして公開する。これらのツールは意図的にシンプルに作られており、できるだけモデルを介在させない。そのためクライアント側は速く、安価に検索できる。各 MCP ツールは最も基本的な検索動作1つに対応しており、入出力は狭く、構造化されていて、安定している。どんなクライアントや Agent でも直接呼び出せる。ほとんどのツールは1本のクエリ経路だけを実行する——意味で検索する、文字面で検索する、あるいは直接 ripgrep を実行する——その上に軽量なスコアリングを1層かけて、元の証拠行を返す。

こうすることで、組み立てる作業は Claude Code のような MCP 対応の Agent に任せられる。どのツールをどの順序で呼ぶか、結果をどう最終的な回答や1回のコード修正にまとめるかは、Agent 自身が判断する。検索層はこれらのモデル判断に依存しなくても、通常どおりサービスを提供できる。

ランキング · ランク融合

6本のランキングを、どう1本に合成するか

ある文書が最上位に来るのは、単に検索語と文字面がたまたま一致しただけで、実際には別のことに答えているだけかもしれない。さらに厄介なのは、6つの検索器が出すスコアが互いに直接比較できないことだ。ベクトルのコサイン類似度と全文検索の関連度は、まったく違う物差しだ。

彼らのやり方は、まずスコアを見ず、順位だけを見ることだ。このアルゴリズムは Reciprocal Rank Fusion(RRF、逆順位融合)と呼ばれる。ある文書が1本のランキングに載るたびにスコアを加算する。加算量は「1 割る(60 足す そのランキングでの順位)」で、重みはデフォルトで1.0、60というのは平滑化定数だ。

6本のランキング、それぞれの上位5件
ベクトル
1 CKPT_LOADER.CC
2 CLASS: CHECKPOINTLOADER
3 WIKI: チェックポイント形式
4 THREAD: NFS が詰まる
5 INC-82: 復元が遅い
全文
1 WIKI: チェックポイント形式
2 CKPT_LOADER.CC
3 RUNBOOK: NFS マウント
4 INC-82: 復元が遅い
5 THREAD: キャッシュのウォームアップ
スレッド要約
1 THREAD: NFS が詰まる
2 THREAD: キャッシュのウォームアップ
3 CLASS: CHECKPOINTLOADER
4 WIKI: 読み込みが止まる
5 INC-82: 復元が遅い
関係グラフ
1 CLASS: CHECKPOINTLOADER
2 MANIFEST_PARSER.H
3 RUNBOOK: NFS マウント
4 THREAD: NFS が詰まる
5 WIKI: チェックポイント形式
Wiki ベクトル
1 WIKI: チェックポイント形式
2 WIKI: 読み込みが止まる
3 RUNBOOK: NFS マウント
4 INC-82: 復元が遅い
5 CLASS: CHECKPOINTLOADER
Slack 全文
1 THREAD: NFS が詰まる
2 THREAD: キャッシュのウォームアップ
3 BURST: タイムアウトパラメータ
4 INC-82: 復元が遅い
5 CLASS: CHECKPOINTLOADER
合成後の総合ランキング
1 CLASS: CHECKPOINTLOADER0.0792
2 INC-82: 復元が遅い0.0776
3 WIKI: チェックポイント形式0.0640
4 THREAD: NFS が詰まる0.0640
5 THREAD: キャッシュのウォームアップ0.0476
6 RUNBOOK: NFS マウント0.0476
出典:Cerebras(原文の交流図をもとに日本語で再構成。項目名とスコアは原文のデータ)。ハイライトされている文書は6本のランキングのうち5本に入っている。

総合ランキング1位を計算してみると、この仕組みがはっきり見えてくる。CLASS: CheckpointLoader は6本のランキングのうち5本に入り、順位はそれぞれ1位、2位、3位、5位、5位だ。

CLASS: CheckpointLoader 関係グラフ 1位 1 / (60 + 1) = 0.01639 ベクトル 2位 1 / (60 + 2) = 0.01613 スレッド要約 3位 1 / (60 + 3) = 0.01587 Wiki 5位 1 / (60 + 5) = 0.01538 Slack 5位 1 / (60 + 5) = 0.01538 合計スコア 0.0792 → 総合1位 INC-82: 復元が遅い(一度も1位を取っていない) 4位、5位、5位、4位、4位 合計スコア 0.0776 → 総合2位
60 というこの定数が何をしているか

順位の前に60を足すことで、1位と5位のスコア差はわずか6%(0.01639 対 0.01538)にしかならない。もしこの定数を足さず、順位の逆数をそのまま取ると、5位のスコアは1位の5分の1にまで落ちてしまう。つまり60の役割は「順位が高いこと」のメリットを平坦にならし、単一の強い1票よりもコンセンサスを優先させることにある——複数の検索器で上位に入る文書が、そのうちの1つだけで1位を取った文書に勝つ。上の INC-82 がその例で、一度も1位を取っていないのに、5本のランキングすべてに安定して入ることで総合2位に食い込んでいる。

順位がもたらすスコア、この定数を足すか足さないかでどれだけ違うか
定数60を足す場合:5位でもわずか6%減 定数を足さない場合:5位は5分の1にまで減 高 低 1 5 10 文書があるランキングでの順位 その順位でのスコア
縦軸はあるランキングでの順位が得られるスコアで、両線ともそれぞれの1位を基準に正規化している。実線が実際に採用されている k=60 で、1位から10位までほぼ平らな線になる。破線は定数を足さずに順位の逆数をそのまま取った場合で、2位ですでに半分近くまで下がる。出典:Cerebras(数式と定数は原文から、曲線はその式に基づいて描画)。

合成後にもう3つの工程がある

融合して出てきたランキングは、そのまま回答の生成には送られない。次にまず同じ出典から分割されて重複しているチャンクを1つに統合し、続いて1ファイルが貢献できる結果数に上限を設けて、より分散した上位20件を得る。この20件は元の質問文とともに小型のリランクモデルに渡され、各件に0〜10点のスコアを付けて上位10件を残す。

融合後から証拠を出すまで、間にはこの工程が挟まる
STEP 1同じ出典から分割された重複チャンクを1つに統合
STEP 21ファイルが貢献できる件数に上限を設け、結果をより分散させる
STEP 3上位20件の候補を残す
STEP 4小型リランクモデルが各件に0〜10点を採点、上位10件を残す
STEP 5ヒットした段落に前後の文脈を補って戻す
出典:Cerebras(原文の説明をもとに描画)。前半3ステップは削減と重複排除、後半2ステップは品質の絞り込みと文脈の補完を行う。

順位が決まったあと、コンテキストを補い戻す。たとえばヒットしたのが Wiki のあるセクションだった場合、その前後2セクションも一緒に引っ張ってくる。チャンク分割で見出しや前提条件、注意事項が分断されて失われるのを防ぐためだ。こうすることで、読者の手元に届くのは前提を欠いた孤立した断片ではなく、完全な形の引用になる。

この一連の工程を経て、検索ステップが引き渡すのは1パックの証拠だ——異なる検索器から集まり、融合を経て、出典レベルで重複排除され、実際の質問に対してリランクされ、最後に周辺の文脈が付け加えられたものになっている。

組織 · 検索範囲

全社検索すると、逆に役立つものが見つからなくなる

コーパスが大きくなっていくにつれ、「なんでも検索する」というやり方はすぐに使いづらくなった。コンパイラを作っているエンジニアは、結果の中にデータセンター運用マニュアルが出てきてほしくないし、その逆も同じだ。

彼らはこれを解決するために project という層を導入した。project とは、データソースを名前付きでまとめたグループのことだ——指定した複数の Slack チャンネル、複数のコードリポジトリ、複数の社内データベース、複数のドキュメントスペースを、あるチームやあるプロジェクトグループを中心に構成する。project は意図的に軽量に作られている。同じデータソース、たとえば全社共通の障害対応チャンネルや中央プラットフォームのリポジトリは、複製することなく複数の project から同時に参照できる。

新人が入社すると、自分の仕事に最も近いデフォルトの project を1つ選ぶか作るよう案内される。たとえばトレーニング基盤、コンパイラ、データセンター運用といった具合だ。このデフォルト値はユーザープロファイルに保存され、以降のすべてのクエリが自動的にこの範囲に限定される。効果として、新しく入ったエンジニアはどの Slack チャンネル、どのリポジトリ、どのドキュメントスペースが自分に関係あるのかを先に調べる時間をかける必要がなくなり、最初から関連性のある結果が手に入る。

全社範囲
  • コンパイラの質問に、データセンター運用マニュアルが混ざる
  • 関連度をアルゴリズムだけで無理やり支える
  • 新人はどれを信じればいいかわからない
1つの project に限定
  • そのチームが関心を持つソースだけを検索する
  • 範囲そのものが関連性を一段支えてくれる
  • 入社時に1度選べば、以降は自動で有効になる
このナレッジベースが機能しているのは、情報が本来あった場所でそのまま人を受け止めているからであり、すべてを1つの硬直したシステムに詰め込んでいるからではない。 Cerebras、『How we built our knowledge base』
データ一覧

原文に登場した具体的な数字

15000+
1日に受ける質問の件数。質問者には社員、自動化スクリプト、Agent を含む
3か月
公開から現在までの期間。すでに社内で最も広く使われているツールの1つ
3,072次元
各レコードのベクトル次元数。Postgres の pgvector に保存
IDF ≥ 4.0
バーストが登録されるための最低条件。これほど珍しい単語を最低1つ含む必要がある
200文字
バースト統合後の長さのしきい値。これより短いと登録されない
k = 60
ランク融合の平滑化定数。コンセンサスが単一の強い1票に勝つようにする
20 → 10
融合・重複排除後に候補を20件残し、リランクモデルの採点後に上位10件を残す
40 GB以上
社内の単一コードリポジトリの規模。増分再計算でしか追いつけない
✅ 同種のシステムを作るとき、1つずつ照らし合わせられる8つの判断
出典:Cerebras 公式ブログ『How we built our knowledge base』、著者 Isaac、Daniel、Zenghao。本文中のデータ、パラメータ、事例はすべて同記事とその図解に基づく。アーキテクチャ図とコードチャンク分割の図は原文の図解、その他の可視化は原文の交流図をもとに日本語で再構成した。Cerebras Knowledge は社内向けツールであり、外部には公開されていない。
出典
CerebrasCerebras·原文を見る
↑ 本文ここまで
✓ この記事は全文無料です

メンバーは全文 Markdown のコピー・保存に加え、自分の AI に購読・質問させることができます。

原文を読む ↗
📮 新着解説をメールでいち早く

役に立ちましたか?メールを登録すると、新着解説を公開と同時にお届けします。解除はいつでも。