生成AI／RAGで手持ちのソースコード解析（LangChain）

# はじめに
LangChainやLlamaIndexを利用したり、フレームワークを利用せずにRAGをしている方も多いと思いますが、[「RAGの精度向上のためにできること（＋Llamaindexでできること）」](https://qiita.com/DeepMata/items/3c27394e4475b1b7e7ff)に続いて、LangChainでできることについて、[Templates](https://python.langchain.com/docs/templates)や、[cookbook](https://github.com/langchain-ai/langchain/blob/master/cookbook/README.md)を参考にしながら、気になったトピックスをピックアップしていきます。進化の早い領域ですので、継続して更新していきたいと思います。

# RAGとは
RAGとは、「Retrieval Augmented Generation」の略で、情報検索と言語モデル（LLM）を組み合わせた手法のことです。検索結果をLLMのプロンプトに含めるというアプローチが一般的です。

![RAG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/b2d7ff74-fc9b-9f26-359a-7f317335ad14.png)

# RAGを使ったソースコード解析

#### LangChainでRAGを使ったソースコード解析が紹介されています。

https://python.langchain.com/docs/use_cases/question_answering/code_understanding

![LangChainSource.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1413258/ea694f02-acb6-f45f-5b15-2db7b3ca648b.png)
（引用元：[LangChain](https://python.langchain.com/docs/use_cases/question_answering/code_understanding)）


やりたいことは
- コードがどのように機能するかを理解するためのQ&A
- リファクタリングや改善提案
- コードの文書化


#### コンテキストを認識したコード分割

https://python.langchain.com/docs/integrations/document_loaders/source_code

まだ、Python と JavaScriptだけのようですが便利なコンテキストを認識したコード分割もできるようです。
- コード内の各トップレベル関数とクラスは別々のドキュメントにロード
- 残りは別の文書にまとめる
- 各分割の出所に関するメタデータを保持




# RAGの精度向上にむけて利用できそうなもの
全体的なものについては[こちら](https://qiita.com/DeepMata/items/3c27394e4475b1b7e7ff)に整理しました。ここでは、LangChainで利用できるものをピックアップしていきます。

### ［データのロード］
- [60以上のVectorStore](https://integrations.langchain.com/vectorstores?ref=blog.langchain.dev)から、データのタイプ（テキスト、画像、音声など）やタスクに適したものを選択する。
- 適切なインデックスを作成できるよう、[適切なチャンクサイズに変更](https://github.com/langchain-ai/text-split-explorer?ref=blog.langchain.dev)する。
- 大量のドキュメントを取得する場合、[ドキュメント圧縮 (冗長性の削減)](https://python.langchain.com/docs/integrations/retrievers/cohere-reranker?ref=blog.langchain.dev)する。


### ［クエリ変換］
ユーザーからの質問や入力を受け取り、関連する情報を検索するためのクエリに変換する。

- [HyDE(Hypothetical Document Embeddings)](https://python.langchain.com/docs/templates/hyde)（[paper](https://arxiv.org/abs/2212.10496)）：
与えられたクエリに対して仮説的なドキュメントを生成し、そのドキュメントの埋め込みを使用して意味的検索を行う。

- [Rewrite-Retrieve-Read](https://github.com/langchain-ai/langchain/blob/master/cookbook/rewrite.ipynb?ref=blog.langchain.dev)（[Paper](https://arxiv.org/pdf/2305.14283.pdf?ref=blog.langchain.dev)）：
LLMを使ってユーザークエリを書き換える。


- [Step back prompting](https://github.com/langchain-ai/langchain/blob/master/cookbook/stepback-qa.ipynb?ref=blog.langchain.dev)（[Paper](/https://arxiv.org/pdf/2310.06117.pdf?ref=blog.langchain.dev)）：
抽象化を促す「ステップバック」質問を生成し、その質問と元の質問の両方に関連するドキュメントを取得する。

- [RAG-fusion](https://github.com/langchain-ai/langchain/blob/master/cookbook/rag_fusion.ipynb?ref=blog.langchain.dev)（[ブログ](https://towardsdatascience.com/forget-rag-the-future-is-rag-fusion-1147298d8ad1)）：
複数のクエリを生成し、取得したドキュメントを逆順位融合を使用して再ランクする。

- [Multi Query Retrieval](https://python.langchain.com/docs/modules/data_connection/retrievers/MultiQueryRetriever?ref=blog.langchain.dev)：
LLMを使用して複数のクエリを生成し、すべてのクエリに対するドキュメントを取得する。


# まとめ
LangChainにはいろいろと使える機能がありそうです。詳しく見ながら、試しながら記事を追加していきたいと思います。


# 参考
https://blog.langchain.dev/applying-openai-rag/
https://blog.langchain.dev/query-transformations/
https://blog.langchain.dev/query-construction/
https://python.langchain.com/docs/modules/data_connection/retrievers/MultiQueryRetriever