「.NET 開発基盤部会 Wiki」は、「Open棟梁Project」,「OSSコンソーシアム .NET開発基盤部会」によって運営されています。
目次 †
概要 †
RAG(Retrieval-Augmented Generation)
- LLMと情報検索を組み合わせた技術。
- 情報取得や質問応答の分野で強力。
開発方法 †
フレームワークやVDBを使用する。
機能・コンポーネント †
チャンク(Chunk) †
- Chunkは、大量のデータを小さなSegment(Chunk)に分割する。
- このプロセスにより、特定の情報を検索し易くなる。
- 各Chunkは、独立して検索可能な単位となる。
埋め込み(Embedding) †
- Embeddingは、テキストデータを数値ベクトルに変換するプロセス。
- ベクトル化により、テキストデータの意味的な類似性を計算が容易になる。
- RAGでは、Embeddingを使用して、検索QueryとDB内のChunkとの類似性を計算し、最も関連性の高いChunkを特定する。
検索(Retrieval) †
- 検索部分では、Queryに対して関連性の高い情報をDBから取得する。
- 具体的には、プロンプトに対して最も関連性の高いChunkを検索エンジンや埋め込みベクトルの類似性に基づいて見つけ出す。
拡張(Augmented) †
ユーザ入力+取得した情報を統合して拡張。
生成(Generation) †
生成部分では、統合情報を入力し、LLMがユーザーに回答を提供する。
プロセス †
知識情報の分割 †
ユーザーが知識情報を入力
知識情報の埋め込み †
Embeddingで知識情報を埋め込みベクトルに変換
質問の入力(Query Input) †
ユーザーが質問を入力
質問の埋め込み(Query Embedding) †
Embeddingで質問を埋め込みベクトルに変換
情報の検索(Information Retrieval) †
質問の埋め込みベクトルを使用して、DB内の関連Chunkを検索
情報の生成(Information Generation) †
- 検索されたChunkを基にプロンプトを生成
- LLMが生成されたプロンプトを元に回答を生成
回答の提供(Answer Delivery) †
最終的にユーザーに回答を提供
キーワード †
埋め込みベクトル(Embedding Vector) †
Embeddingで、テキストをベクトルに変換した表現方法。
類似性計算(Similarity Calculation) †
埋め込みベクトル間の類似性を内積、距離などで計算するプロセス。
詳細 †
RAGの拡張手法について
手法 †
代表的な手法
Chunk拡張 †
- 非常に単純な手法で、検索でヒットしたChunkの前後のChunkもコンテキストに含めてLLMに渡すという方法
- Chunkサイズを大きくする場合と効果は似ているが、Chunkサイズを大きくすると、検索精度が落ちる問題があった。
Re-Rank †
- 検索で得たChunkに対して、クエリとの類似度が高い順に並び変え再度ランク付けをする手法
- Chunkを得るための検索はベクトルの内積計算にして、Re-RankでTransformerやLLMを使用する。
- これにより、高コストの処理を減らし、消費するリソースを削減できる。
RAG-Fusion †
- 入力クエリに類似したクエリをLLMにより幾つか生成し、それぞれのクエリの検索結果を統合する方法。
- 類似クエリでも上位に来るChunkは重要なChunkだと言う仮定から、投票制で重要なChunkを取得する。
Hybrid-Query †
ハイブリッド・サーチ、ハイブリッド検索
- 性質の異なる複数の検索方式(例えばベクトル検索とキーワード検索)を組み合わせて検索精度を向上させる手法
- キーワードベースの検索とベクトル検索を組み合わせたハイブリッド検索で精度が高く出るという結果が報告されている。
- キーワード検索
「文書の内容に沿った」キーワード検索を実現
- ベクトル検索
文の意味ベースの類似性によって検索する。
- BERT
- Sentence-Transformers
- その他の検索(従来型)
- 非構造化データの全文検索
- 構造化データの検索(階層構造、テーブル構造)
- その他の検索(新型)
- GraphDBのGraph検索(LLMを使用しネットワーク構造のインデックスを構築し検索)
- ...
Sub Query †
- 入力クエリが複雑な場合や、複合的な意味を持っている場合に有効な手法
- 入力クエリをSub Queryに分解し、それぞれのSub Queryでのレスポンスを最後に合成して回答する
- Sub Query1
Xの詳細な定義とその意味は何ですか?
- Sub Query2
Yの詳細な定義とその意味は何ですか?
Multi Step Query †
- クエリの分解と段階的な推進により、複数のChunkを取得して回答を洗練させる手法
- 入力クエリ: 著者が始めた事業共創プログラムの最初のメンバーには誰が参加しましたか?
- クエリの分解1:
- Q:著者はどのような事業共創プログラムを開始しましたか?
- A:著者は、Y Combinator (YC) という事業共創プログラムを開始しました。
- クエリの分解2:
- Q:Y Combinator の事業共創プログラムの最初のメンバーは誰ですか?
- 2005 年に開始された Y Combinator の事業共創プログラムの最初のバッチには、次のようなスタートアップ企業が含まれていました。
- 最終的な回答:
Y Combinator 事業共創プログラムの最初のバッチには、
Reddit (Steve Huffman と Alexis Ohanian によって設立)、
Loopt、Weebly、Twitch (Justin Kan によって設立) などのスタートアップが含まれていました。
HyDE †
- Hypothetical Document Embeddingsの略で、LLMに仮の回答を作らせて、その仮の回答をベクトル化して検索に使うという方法。
- 本来はQ&AでQからA(が書かれているだろうChunk)を当てに行くが、QからLLMで生成したA'を使用してAを当てに行く。
- LLMが「A」についての基礎知識を有しており「A'」を肉付けしたものが「A」になるようなケースで利用できる可能性がある。
Stepback Prompt †
- 入力Promptを一段抽象化させたStepback Promptをクエリに用いてChunk検索した結果と合成する。
- Promptに対してピンポイントなChunkがないケースでもStepback Promptで推論が可能になるケースがある。
- Stepback Promptで定義、歴史、計算式などの「基礎的なChunk」を取得して回答を行う。
- 入力PromptでChunk検索した結果の「派生のChunk」を使用すると不適切な回答が生成される事がある。
- 例
- X氏は19XX年のY月~Z月まで何をしていたか?と言う質問があったとする。
- X氏に関して、19XX年と言う文字列に該当する経歴の情報が無い場合がある。
- ステップバック質問でX氏の経歴情報を取得する。ココに 19YY < 19XX < 19ZZ の情報が書かれていれば回答可能。
Pandas Dataframe †
- PandasのDFをChunkに分割せず、テーブル構造を保持したまま処理する。
- 文字列としてではなくLLM を使用しプロンプトからPandas Pythonコードの回答を得てコレを実行した結果から回答を取得する。
- LlamaIndexではTextToSQLと共に、構造化データを処理する機能の一部。
TextToSQL †
体系 †
以下は各種、手法の分類
Query Translation †
Routing †
- 適切なChunkを取得できるようにデータストアやプロンプト(システム・プロンプト、プロンプト・テンプレート)を選択するプロセス
- 手法例:Logical Routing(データストア)、Semantic Routing(システム・プロンプト、プロンプト・テンプレート)
Query Construction †
Indexing - Chunking †
適切なChunkを取得できるようにIndexingプロセス「のChunkingを」工夫する。
- Recursive Chunking
- 難易度2
- 設定サイズを下回るまで再帰的にChunking
- 分割は区切り文字的なモノを目安に行う。
- Document Based Chunking
- 難易度3
- 文書ごと(MarkdownやPythonプログラムなど)にChunking
- Semantic Chunking
- 難易度4
- 文単位で分割・Embeddingをして、次の文との類似度が大きく「異なる」箇所でChunking
- EmbeddingにはLLMを使用、コサイン類似度を計算し、ClusteringアルゴリズムでChunking
- Agentic Chunking
- 難易度5
- LLMで文書から命題を作り、命題内容に応じたChunk作成(Dense Xと同じ)
Indexing - Embedding †
適切なChunkを取得できるようにIndexingプロセス「のEmbeddingを」工夫する。
- Summary Embedding
- LLMが元文書を要約し要約でIndexing
- Index対象:元文書の要約(LLMが要約)
- Retrireve対象:元文書
- Specialized Embeddings
特別なEmbedding方法
- Fine-tuning Indexing
クエリと文書をEmbeddingするモデルをファインチューニング
- ColBERT Indexing
クエリと文書をToken単位でEmbeddingし、両者の最大類似度でスコアリング
Indexing - Indexing †
適切なChunkを取得できるようにIndexingプロセス「のIndexingを」工夫する。
- Multi-representation Indexing
文書をRetrieveしやすい単位・複数形式に変換してIndexing
- Parent Document Indexing
- 文書(Parent)を文書(Child)に分割
- Index対象:文書(Child)
- Retrireve対象:文書(Parent)
- Dense X Indexing
LLMが元文書を複数の命題に変換し、これらの命題でIndexing
- Index対象:元文書の命題(LLMが命題に変換)
- Retrireve対象:元文書
- 質問: ピサの斜塔の角度は何ですか?
- 文章: 1990 年から 2001 年にかけて修復工事が行われる前は、塔は 5.5 度傾いていましたが、現在は[約 3.99 度傾いています。]
これは、ピサの斜塔の頂上が中心から水平方向に 3.9 メートル (12 フィート 10 インチ) ずれていることを意味します。
- 文 : 1990 年から 2001 年にかけて修復工事が行われる前は、塔は 5.5 度傾いていましたが、現在は[約 3.99 度傾いています。]
- 命題: [ピサの斜塔は現在約 3.99 度傾いています。]
- Hierarchical Indexing
再帰的抽象化処理による階層的なツリー構造のIndexing
- RAPTOR Indexing
元文書をEmbedding、Clustering、要約を繰り返しルート要約Embeddingまで作成して検索
- Index対象:要約文書の
- Retrireve対象:元文書のリーフ
Retrieval †
Generation †
- RAG内で使用するLLMのGenerationプロセスを工夫する。
- 手法例:Active Retrieval(Self-RAG、RRR)
Semantic Search †
概要 †
所謂、文書のEmbeddingによるベクトル化と内積による類似度の計算
- Sentence-Transformersなどを用いて文章をベクトル化する。
- 文全体の意味を文脈に基づいてベクトル化するため、
- 文章間の意味合い的な比較、類似文章検索やクラスタリングなどが可能になる。
- 短く単純な文なら加法構成性が有効に働くケースもある。
実装 †
Sentence BERTの論文(+α)を実装したもの
処理 †
...
GraphRAG †
概要 †
Graphとは主にノードとエッジから構成されるデータモデル
- ノードはモノ・概念を定義し、エッジはノード間の関係性を表す。
- SNSのアカウント同士の関係性を表すのに使用されているアレ
- RDBと違い、複座なネットワーク構造を比較的容易に表現できる。
- 次のような用途で使用される「因果関係をモデル化」「相互作用をモデル化」
- 対象のテキストが因果関係、相互作用を含むナレッジの場合、効果が高くなる。
- ペルソナベースのレコメンデーション
- ソーシャルネットワーク分析
- 医療診断と治療提案
- 法律文書の分析
- 科学研究分野のデータ分析
実装 †
- VDBの代わりにGraphDBを利用するRAG。
- ベクトル検索に加えGraph検索の結果を使用するHybrid-Query。
処理 †
以下は、参考の内容を分解したもの。
- 必要なライブラリをインストール(LangChainからNeo4jなど)
- Wikipediaから「サザエさん」についての情報を取得する。
- LangChainのTokenTextSplitter?を使用してチャンク分割する。
- LLMでチャンクからグラフ構造(ノードとエッジ)を抽出・付加する。
- グラフ構造を抽出・付加したデータをGraphDBにロードする。
- GraphDBのUIからグラフィカルにノードとエッジを参照できる。
- GraphDBのHybrid-Query機能で全文検索のインデックスを作成する。
- 質問文章から検索キーになるキーワードをLLMを用いて抽出するチェーンを定義
- 上記チェーンで得たキーワードで全文検索した結果からCypherクエリで関連ノードを反復抽出する関数を定義
- 上記で定義した関数を使用して質問「ワカメのお母さんは誰ですか?」を処理すると、
「波平 - PARENT -> 磯野ワカメ」「フネ - PARENT -> 磯野ワカメ」などの結果が得られる。
- 上記の全文検索+グラフ検索にベクトル検索も追加しGraphRAGのパイプラインを構成して実行すると良い結果が得られる。
※ 分析:LangChainなので詳細が不明、3種の検索でそれぞれ、どのようなチャンクが取得できているか?の情報が欲しかった。
参考 †
理論 †
Semantic Search †
GraphRAG †
実装 †
Semantic Search †
一般知識(単語を文脈予測アプローチでベクトル化の延長上)でOK
GraphRAG †
ライブラリ †
Neo4j †