LoginSignup
7
10

More than 1 year has passed since last update.

chatGPTにCSVデータの情報を元に回答させてみる

Posted at

Llamaindex を用いてCSVデータからchatGPTちゃんに回答させてみようと思います。
とりあえずやってみた系の記事なので、雑ですがご了承下さい。

準備

今回は居酒屋的のメニュー的なものを適当に作りました。

csv
項目,タイトル,価格,説明
鴨料理,鴨フィレ肉のカシスソース,930円,鴨フィレ肉を浅めにソテーしロゼ色に。甘酸っぱいカシスと赤ワインのソースで。ピンクペッパーがとても合います。赤ワイン。
鴨料理,鴨刺し,860円,"皮面をパリッと焼き、肉にも焼き目をつけた状態をお刺身。"
鴨料理,鴨南蛮うどん,830円,"鴨と長ネギをごま油で炒め、味を出しています。
合わせだしも引いています。汁まで美味しい一品。小さめの為〆に最適です。"
馬料理,ユッケ,930円,"言わずと知れた生肉ユッケ。
...

以下のライブラリをインストールします。

bash
pip install -U llama-index
pip install -U langchain

llama-indexはEmbeddingsによる検索を簡単に実装できるPythonライブラリです。

langchainはLlamaindexなどのツール群をOpenAI APIと連携できるライブラリです。

こちらは色々とできそうですが詳細割愛します。
近々こちらにスコープして書いてみます。

とりあえずやってみる

分割して記載していきます。

python
import os
import logging
import sys

from llama_index import ServiceContext, GPTSimpleVectorIndex, LLMPredictor
from langchain.chat_models import ChatOpenAI
from llama_index.prompts.prompts import RefinePrompt, QuestionAnswerPrompt
from llama_index import download_loader

os.environ["OPENAI_API_KEY"] = "<OpenAIのAPIキー>"
python
# ログレベルの設定
logging.basicConfig(stream=sys.stdout, level=logging.DEBUG, force=True)

# データの読み込み(CSV)
SimpleCSVReader = download_loader("SimpleCSVReader")

# データの読み込み
documents =  SimpleCSVReader().load_data(file="data.csv")

今回使用したSimpleCSVReaderについてはこちら

python
# tempareture=0をしていて、正確性を最重視
# gpt-3.5-turbo を指定(デフォルトは davinci )
# トークン数制限を500に
service_context = ServiceContext.from_defaults(
    llm_predictor = LLMPredictor(llm= ChatOpenAI(temperature=0,
                                                 model_name="gpt-3.5-turbo",
                                                 max_tokens=500)))

# 読み込んだcsvデータをもとに Embbeddings API を通信してベクター取得しIndexを生成
index = GPTSimpleVectorIndex.from_documents(documents, service_context=service_context)

# jsonでローカルに保存
index.save_to_disk("index.json")

ここまでで、csvに入っていたデータをベクトル化しました。

python
# 質問文
qry ="ラーメンはありますか?"

#質問用のQAプロンプトを生成
QA_PROMPT_TMPL = (
    "私たちは以下の情報をコンテキスト情報として与えます。 \n"
    "---------------------\n"
    "{context_str}"
    "\n---------------------\n"
    "あなたはAIとして、この情報をもとに質問を日本語で答えます。前回と同じ回答の場合は同じ回答を行います。: {query_str}\n"
)
qa_prompt = QuestionAnswerPrompt(QA_PROMPT_TMPL)

#回答要求用のプロンプトを生成
REFINE_PROMPT = ("元の質問は次のとおりです: {query_str} \n"
    "既存の回答を提供しました: {existing_answer} \n"
    "既存の答えを洗練する必要があります \n"
    "(必要な場合のみ)以下にコンテキストを追加します。 \n"
    "------------\n"
    "{context_msg}\n"
    "------------\n"
    "新しいコンテキストを考慮して、元の答えをより良く洗練して質問に答えてください。\n"
    "コンテキストが役に立たない場合は、元の回答と同じものを返します。")

refine_prompt = RefinePrompt(REFINE_PROMPT)

ここではプロンプトの定義をしています。
日本語での回答を強制したかったのでこのようにしました。
公式ではこちらに記載されてます。

python
# 先程生成したベクトルファイルを読み込む
indexFile = GPTSimpleVectorIndex.load_from_disk("index/index.json", service_context=service_context)

# ベクトル検索 + Chat Completion API 実行 + 検索結果TOP3を返す
response = indexFile.query(qry,
                       text_qa_template=qa_prompt,
                       refine_template=refine_prompt,
                       similarity_top_k=3)
#結果確認
print(response)

結果

申し訳ありませんが、この情報にはラーメンの項目が含まれていません。
代わりに、焼酎割りやワインカクテル、ウィスキーやカクテル、
そして梅酒やソフトドリンクなどがあります。
ラーメンをお探しの場合は、他の店舗を探してみてください。

なんでラーメンないんだよっ!!
はい。でもその通りです。csvデータにラーメンは含んでません。

質問文を変えてみました。

# 質問文
qry ="さっぱりしたものが食べたいです。"

結果

当店では、さっぱりとしたメニューを豊富に取り揃えています。
鴨南蛮うどんや春菊のチョレギサラダ、梅水晶などがおすすめです。
また、サワーも白桃&コラーゲンサワーや北海道ハスカップサワー、
アセロラ&ヒアルロンサワーなど、様々な種類をご用意しております。
さらに、ハイボールや焼酎割り、本日のグラスワインもお楽しみいただけます。
焼酎は、(芋)大隅、(芋)金黒、(芋)農家の嫁、(麦)村正、(麦)吟麗玄海、(米)もっこす、(米)鳥飼、(泡盛)三年古酒 瑞泉など、多彩なラインナップを揃えています。
また、日本酒やウィスキー、カクテル、梅酒、ソフトドリンクも充実しています。
お好みに合わせてお選びください。

お酒のメニューを多くしてたから、やたら飲ませようとしてきます。
これがさっぱりしているお酒なのかは分かりませんが、まあ合ってそう。

さいごに

とりあえずやってみた感じですが、簡単にそれっぽい回答を得ることはできました。
ただ公式通りやって動かない事もあったりで…進化が早い分すぐにパラメータが変わったりなんだりしそうですね。まだ実運用には怖いかな…

参考にさせて頂いた記事等

7
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
10