業務活用事例

SLMとRAGを組み合わせて社内検索を強化する方法

SLMとRAGを組み合わせて社内検索を強化する方法

この記事の要点

SLMとRAGを組み合わせると、社内文書に基づいた質問応答システムをAPIコストゼロ・社外送信なしで構築できる。本記事では構成の全体像、実装ステップ、精度向上のポイント、よくある失敗とその対処を解説する。

結論:SLM+RAGは社内専用AIの現実的な最短ルートだ

社内の規程・マニュアル・過去の提案書に対して「この条件の場合どうすればよいか」という質問に答えられるAIを、クラウドにデータを送らずに作れる。それがSLMとRAGを組み合わせたアーキテクチャの価値だ。

RAGとはRetrieval-Augmented Generation、つまり「検索してから生成する」手法だ。質問が来たら、まず関連文書をベクトル検索で引き出し、その文書を根拠として言語モデルが回答を生成する。モデル自身にすべての知識を覚えさせる必要がなく、最新の文書を追加するだけでAIが答えられる範囲を広げられる点が最大の特徴だ。

RAGについての基礎的な説明はRAGとは何かを解説した記事が参考になる。本記事はRAGの概念は理解した上で、SLMと組み合わせて社内に展開する具体的な構成と実装に絞って解説する。

なぜSLMとRAGを組み合わせるのか

クラウドのLLM(大規模言語モデル)でもRAGは構築できる。それでもSLMを選ぶ理由は3つある。

1つ目はAPIコストの問題だ。GPT-4クラスのAPIを月間数万件のクエリで呼び出すと、文書の長さにもよるが月額数十万円規模のコストになることがある。SLMをローカルかプライベートサーバーで動かすと、この変動コストがほぼゼロになる。初期のサーバー費用と保守コストはかかるが、問い合わせ量が増えてもコストが線形に上がらない点が大きい。

2つ目は社外送信の問題だ。クラウドAPIを使う場合、質問文と一緒に検索でヒットした社内文書の断片がAPIサーバーに送信される。規程・契約書・未公開の企画資料などを扱うシステムでは、このリスクを許容できない場合がある。SLMをオンプレミスやプライベートVPCで動かす構成であれば、データは外に出ない。クラウドとオンプレミスのトレードオフ全般についてはクラウドとオンプレのAI比較記事で詳しく解説している。

3つ目は専門知識への適応だ。汎用のLLMは一般的な知識には強いが、特定業界の専門用語や社内固有のプロセスには弱い場面がある。SLMをファインチューニングして社内データでカスタマイズすると、汎用LLMより精度が高くなる領域がある。ファインチューニングの概要についてはファインチューニングとはを解説した記事を参照してほしい。

構成の全体像

SLM+RAGシステムの構成要素は4つだ。

まずドキュメントストア。処理対象の社内文書が置かれる場所で、PDF・Word・テキストファイルなど形式はさまざまだ。これを最初に処理して検索可能な状態にする前処理が必要になる。

次にエンべディングモデル。テキストを数百次元の数値ベクトルに変換するモデルだ。意味的に近い文章は近いベクトルになる。これによって「キーワードは違うが意味が近い」文書を検索で引き当てられる。

そしてベクトルデータベース。エンべディングモデルが生成したベクトルを保存し、クエリに近いベクトルを高速に検索するデータベースだ。

最後がSLM(推論エンジン)。検索でヒットした文書の断片と、ユーザーの質問を合わせてプロンプトを構成し、回答を生成する部分だ。Ollamaで動かすSLMや、vLLMなどの推論サーバーが担う。

データの流れとしては、まず社内文書を取り込んでチャンク分割し、各チャンクをベクトル化してベクトルDBに保存する。これがオフラインの前処理だ。ユーザーが質問すると、その質問もベクトル化され、似ているベクトルのチャンク上位3〜5件がヒットする。ヒットしたチャンクをSLMのコンテキストに埋め込み、「以下の文書に基づいて回答してください」という形式でプロンプトを作り、SLMが回答を生成して返す。

実装のステップ

実装を4つのフェーズに分けて説明する。

フェーズ1:文書の収集と前処理

まず対象文書を収集する。規程・マニュアル・FAQ集・製品仕様書など、システムで答えられるようにしたいテーマに関係する文書を洗い出す。初期構築では範囲を絞ることが重要だ。「経費精算に関する社内規程と手順書」のように対象を限定した方が、品質の検証がしやすく、失敗したときの原因特定も容易だ。

文書はテキストに変換する必要がある。PDFはpdfplumber、pypdf2などのライブラリで処理できる。Wordファイルはpython-docxが使える。OCR処理が必要なスキャンPDFの場合はTesseractなどの外部ツールが別途必要になる。

フェーズ2:チャンク分割とベクトル化

テキストを適切な長さのチャンクに分割する。チャンクとは検索の最小単位だ。長すぎると関係のない情報が混入しやすくなり、短すぎると文脈が失われて検索精度が落ちる。256〜512トークンを出発点に、文書の性質に合わせて調整する。

チャンク間にオーバーラップ(重複)を設けることも有効だ。前のチャンクの末尾50トークンを次のチャンクの先頭に含めるような設定にすると、文章の区切り目で文脈が失われるリスクを減らせる。

各チャンクをエンべディングモデルに通してベクトルに変換し、チャンクのテキストと元の文書名・ページ番号などのメタデータと一緒にベクトルDBに保存する。

フェーズ3:SLMの接続

Ollamaをサーバーモードで起動し、REST APIとして使えるようにしておく。LangChainを使う場合はChatOllamaクラスで簡単に接続できる。LlamaIndexも同様にOllamaのネイティブ統合が提供されている。

プロンプトのテンプレートはRAGシステムの品質に大きく影響する。基本的な構造は次のようなものだ。

以下の文書を参照して質問に答えてください。文書に書かれていないことは答えないでください。

【参照文書】
{retrieved_chunks}

【質問】
{user_question}

【回答】

「文書に書かれていないことは答えないでください」という制約は重要だ。これがないと、SLMが文書の範囲を超えて独自に回答を作り上げてしまうリスクが高まる。

フェーズ4:検索パイプラインの統合

ユーザーの質問を受け取り、エンべディングに変換し、ベクトルDBで検索し、上位チャンクを取得し、プロンプトを構成してSLMに送り、回答を返すという一連のパイプラインをまとめる。LangChainのRetrievalQAチェーンやLlamaIndexのQueryEngineはこのパイプラインを抽象化している。これらを使うと数十行のコードで動作するプロトタイプが作れる。

精度向上のポイント

基本構成で動かしてみると、回答が期待と違う場面が必ずいくつか出てくる。代表的な改善ポイントを挙げる。

チャンク戦略の見直しは最初に試すべき改善だ。固定長で分割するよりも、文書の論理的な区切り(見出し・条番号・段落)で分割する方が、意味のまとまったチャンクになりやすい。LangChainのMarkdownTextSplitterやRecursiveCharacterTextSplitterがこの用途に使える。

リランキングは、ベクトル検索でヒットした上位候補を、別のモデルで再評価して並び替える手法だ。ベクトル検索は計算コストが低い代わりに、微妙なニュアンスを見落とすことがある。リランカーモデルをかませることで精度を上げられる。Cohereのリランカーや、クロスエンコーダーを使ったオープンソースの実装がある。

ハイブリッド検索も有効だ。意味的類似度によるベクトル検索と、キーワードマッチによるBM25検索を組み合わせて使う。製品番号や人名など固有名詞はキーワード検索の方が正確にヒットしやすい。WeaviateなどのベクトルDBはハイブリッド検索をネイティブにサポートしている。

エンべディングモデルの選択も重要だ。英語向けに最適化されたモデルを日本語文書に使うと精度が大幅に落ちる。日本語対応のエンべディングモデルとして、intfloat/multilingual-e5-largeやcl-nagoya/sup-simcseなどが評価されている。最新の比較は公式や技術コミュニティで確認してほしい。

よくある失敗パターンと対処法

「文書に書いてあるはずなのに答えてくれない」問題の多くは、検索でヒットしていないことが原因だ。まず検索だけを単体でテストして、正しいチャンクが上位に返ってきているか確認する。ヒットしていなければ、チャンクサイズの見直し・エンべディングモデルの変更・上位k件を増やす設定変更のいずれかを試す。

「文書に書いていないことを答えてしまう」問題はハルシネーションと呼ばれる。プロンプトに「文書に書かれていないことは答えない」という制約を明記しているにもかかわらず発生する場合、SLM自体の問題である可能性がある。この場合は、指示遵守の精度が高い別のモデルへの変更や、回答の冒頭に「参照した文書:XX」を必ず出力させて人間がチェックしやすい形式にする対策が有効だ。

「回答が長すぎて使いにくい」問題はプロンプトで回答形式を指定することで解決できる。「3行以内で答えてください」「箇条書きで答えてください」のような制約を追加するだけで改善することが多い。

「処理速度が遅くて実用にならない」問題は、SLMの規模の見直し・GPU環境の追加・並列処理の設定変更のいずれかで対処できる。ユーザーインターフェースにストリーミングレスポンスを実装して体感速度を改善する方法も有効だ。

まとめ

SLM+RAGの組み合わせは、社外にデータを出さずに社内文書に基づいた質問応答システムを作る手法として、コストとセキュリティの両面で優れている。構成の核心は「社内文書を検索可能なチャンクに変換しておき、質問に関係する部分だけをSLMに渡す」という仕組みにある。まず対象文書を絞り、LangChainやLlamaIndexを使ったプロトタイプで回答品質を確認するところから始めることを勧める。精度が足りなければ、チャンク戦略・エンべディングモデル・リランキングの順に改善を進めていくのが効率的だ。

よくある質問

SLM+RAGとクラウドLLM+RAGはどちらが精度が高いですか。

クラウドLLMのほうが一般的に回答精度は高い傾向があります。ただし、社内の専門用語や製品名が多い文書に対しては、ファインチューニング済みのSLMがLLMを上回る場合もあります。初期構築はSLM+RAGから始め、品質が不足する部分をLLMで補う段階的なアプローチが現実的です。

ベクトルデータベースは何を使えばよいですか。

小規模(文書数千件以下)であればChromeaやFAISSなどのオープンソースで十分です。大規模かつ運用が本番規模になる場合はPineconeやWeaviateなどのマネージドサービスを検討してください。最新の比較は公式ドキュメントや技術ブログで確認してください。

チャンクサイズはどのくらいが適切ですか。

一般的には256〜512トークンが出発点です。ただし文書の性質によって変わります。規程のような番号付きの条文は1条ごと、技術マニュアルは手順ごとに切るのが検索精度を上げやすい傾向があります。実際には複数のサイズで試して、ヒット精度を計測しながら調整してください。