LangChainを用いて大量ファイルをロードするVectorDBを作ってみた(3)

![sky.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/75ac797c-e38d-6673-7029-98dcd0b4b5b4.jpeg)
# はじめに
[前回](https://qiita.com/ogi_kimura/items/ecedd7c85ca1b0b0fc58 "LangChainを用いて大量ファイルをロードするVectorDBを作ってみた(2)")作成した「大量ファイルをロードするVectorDB」を基に、今回は『LangChat完全入門』（田村悠 著）のプログラムを参考にして、生成AI（OpenAI）から回答をもらう仕組みを作ってみました。その実際の流れを文章にしてみました。
Webブラウザ表示については、「chainlit」という直感的にコーディングできるライブラリを用いてみることにしました。

# ソースコードの利用
『LangChat完全入門』（田村悠 著）の「03_retrieval」の「chat_2.py」を修正して、Webブラウザ上で生成AIに質問ができるようにしてみました。以下は、元々の「chat_2.py」です。

```python:chat_2.py
import chainlit as cl
from langchain.chat_models import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.prompts import PromptTemplate
from langchain.schema import HumanMessage
from langchain.vectorstores import Chroma

embeddings = OpenAIEmbeddings(
    model="text-embedding-ada-002"
)

chat = ChatOpenAI(model="gpt-3.5-turbo")

prompt = PromptTemplate(template="""文章を元に質問に答えてください。 

文章: 
{document}

質問: {query}
""", input_variables=["document", "query"])

database = Chroma(
    persist_directory="./.data", 
    embedding_function=embeddings
)

@cl.on_chat_start
async def on_chat_start():
    await cl.Message(content="準備ができました！メッセージを入力してください！").send()

@cl.on_message
async def on_message(input_message):
    print("入力されたメッセージ: " + input_message)
    documents = database.similarity_search(input_message)

    documents_string = ""

    for document in documents:
        documents_string += f"""
    ---------------------------
    {document.page_content}
    """

    result = chat([
        HumanMessage(content=prompt.format(document=documents_string,
                                           query=input_message))
    ])
    await cl.Message(content=result.content).send()
```

このプログラムが利用でいると思ったのは、
```python:
    documents = database.similarity_search(input_message)

    documents_string = ""

    for document in documents:
        documents_string += f"""
    ---------------------------
    {document.page_content}
    """
```

↑この部分に注目しました。
恐らく「similarity_search」は、データベース（SQLite）の中のテーブルを検索した結果を取得して、「documents」にリストとして格納するのでしょう。
それから、forループでリスト内のインスタンスを「document」として１つずつ取り出し、「documents_string」に文字列として加えていく、と読み取れました。これは使える！と思いました。
早速実行しました。

# 生成AIに質問を投げてみる

以下を実行して、「chainlit」を起動させます。
```powershell:
  python -m chainlit run chat_2.py
```

　「chainlit」の画面が起動しました。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/c537299b-f47b-b6d4-ee43-efd97819039c.png)

では早速質問を送信してみます。『LangChat完全入門』で例題であった「飛行車の最高速度は？」を送信してみます。↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/ab69f8a4-323c-3794-99cd-1a3e24ac915c.png)

よしよし、ちゃんと返ってきました。

では次は、ほかの資料についての質問もしてみます。
「日経トレンディの見開き２ページの掲載料金は？」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/3bd2e066-5069-8ce4-d4c7-229282fda5ac.png)


お、正確に返ってきました。
じゃぁ、次はExcelファイルにかかれている内容を確認してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3784222/b0818b19-61e6-df32-04ad-4ed3654c53ca.png)

これもちゃんと返ってきています。
理論的には、フォルダ内のファイル情報をデータベースに蓄積させて、生成AIに質問を送信するプログラムを作ることができました。

# 終わりに
今回は、ネスト構造のフォルダの中にある5つのファイルの情報をVectorDBに蓄積させ、その情報を基に生成AIに質問を送信するプログラムを作成することができました。
次回は、大量のファイルを読込ませたときにどうなるかを実験してみたいと思います。