💬

文字数制限のないFAQチャットボットの実装方法【Python / LangChain / ChatGPT】

2023/07/28に公開

はじめまして、ますみです!

株式会社Galirage(ガリレージ)という「生成AIに特化して、システム開発・アドバイザリー支援・研修支援をしているIT企業」で、代表をしております^^

自己紹介.png

この記事では、「LangChain」というライブラリを使って、「文字数制限のないFAQチャットボットの作り方」を解説します。

ChatGPTやLangChainやについてまだ詳しくない方は、こちらを先にご覧ください◎

https://zenn.dev/umi_mori/books/chatbot-chatgpt
https://zenn.dev/umi_mori/books/prompt-engineer

具体的には、「Map Reduce」「Map Rerank」「Refine」の3つのアルゴリズムの実装方法を説明します。
これらの概念がまだ知らない方は、先に下記の記事をご覧ください。
https://zenn.dev/umi_mori/articles/langchain-chains-long-text-algorithm

1. ゴールとシステム設計

今回の目標は、YouTubeの長文字幕に対して質問ができるチャットボットを作ることです。
そのためのシステム設計について説明します。

  1. YouTubeから字幕情報を取得します。
  2. 取得した字幕情報に対して、「Map Reduce」「Map Rerank」「Refine」の3つのアルゴリズムを適用します。
  3. これらのアルゴリズムを用いて、質問に対する回答を生成します。

具体的な実装方法としては、Pythonというプログラミング言語を使います。
その中でも、LangChainというライブラリを活用します。

この時、LangChainの中にある「Chains」という機能を使います。
Chainsは、複数のプロンプト入力を実行する機能です。

以上が、今回のゴールとシステム設計の概要です。
次の章では、具体的な実装方法について詳しく説明します。

2. 環境構築

Pythonでの作業を始める前に、必要なツールを揃えましょう。
まずは、LangChainというライブラリをインストールします。
次に、OpenAIのモデルを使うための準備をします。
最後に、YouTubeの字幕情報を取得するためのライブラリと、Chainで使うライブラリをインストールします。

  • LangChainのインストールpip install langchainでインストールします。
  • OpenAIのインストールpip install openaiでインストールします。
  • YouTube字幕取得ライブラリのインストールyoutube-transcript-apiでインストールします。
  • トークン数の計算ライブラリのインストールpip install tiktokenでインストールします。
  • APIキーの設定:OpenAIを使うためには、APIキーが必要です。自分で発行したAPIキーを、指定の場所に設定します。

APIキーの発行方法がわからない方は、下記の記事を参考にしてください。
https://zenn.dev/umi_mori/books/chatbot-chatgpt/viewer/how_to_use_openai_api

具体的なインストール方法は次の通りです。

shell
pip install langchain==0.0.149
pip install openai==0.27.6
pip install youtube-transcript-api==0.6.1
pip install tiktoken==0.4.0

また、APIキーを設定する方法は、次のとおりです。

python
import os

#TODO: APIキーの登録が必要
os.environ["OPENAI_API_KEY"] = "..."

これで、Pythonでプログラムを作る準備が整いました。

3. 「Map Reduce」の実装方法

この章では、「Map Reduce」の実装方法を解説します。

具体的な流れは次の通りです。

  1. 「YoutubeLoader」でYouTubeの動画を読み込みます。
  2. 「CharacterTextSplitter」でテキストを分割します。
  3. 分割したテキストは、ドキュメントのリストとして格納します。
  4. 「load_qa_chain」モジュールを使い、「map_reduce」を行います。
  5. 生成されたChainを実行します。

実際に、以下のYouTubeの動画に対して、「YouTubeを学習したChatGPTを実装するために、インストールが必要なライブラリを教えて。」と質問してみましょう。
https://www.youtube.com/watch?v=TQvaocfmvaI

具体的なコードは以下のとおりです。

python
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import YoutubeLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.docstore.document import Document
from langchain.chains.question_answering import load_qa_chain
import time

start_time = time.time()

youtube_url = "https://www.youtube.com/watch?v=TQvaocfmvaI"
loader = YoutubeLoader.from_youtube_url(youtube_url, language="ja")
transcript_text = loader.load()[0].page_content
print(f"{transcript_text = }")
print(f"{len(transcript_text) = }")

text_splitter = CharacterTextSplitter(separator=" ", chunk_size=500)
texts = text_splitter.split_text(transcript_text)
print(f"{len(texts) =}")

docs = [Document(page_content=t) for t in texts]

chat = ChatOpenAI(model_name="gpt-3.5-turbo")
chain = load_qa_chain(
    llm=chat,
    chain_type="map_reduce",
    verbose=True,
)

question = "YouTubeを学習したChatGPTを実装するために、インストールが必要なライブラリを教えて。"

output = chain(
    {
        "input_documents": docs,
        "question": question,
    },
    return_only_outputs=True,
)["output_text"]
print(output)

print(f"{time.time() - start_time}")

このコードを実行すると、YouTubeの動画から字幕が取得され、5分割されます。
「Map Reduce」では、5分割された各塊に対して指示文が実行されます。
最後に、すべてを統合して指示文が実行され、結果が出力されます。

ちなみに、「Map Reduce」の実行には、合計で「52秒」かかりました。

4. 「Map Rerank」の実装方法

次に、「Map Rerank」の実装方法を見ていきましょう。

「Map Rerank」は、「map_reduce」の「chain_type」を「map_rerank」に変更するだけで実装できます。

実行すると、ChatGPTが出す自信度の強さが出力されます。
ちなみに、実行時間は「10秒」でした。

「Map Rerank」の特徴として、以下の点が挙げられます。

  • 環境構築に関する部分は全体の文章の中の一部分に集中しているため、「Map Rerank」の方が精度が高いと考えられます。
  • 「Map Reduce」よりも「Map Rerank」の方が、最後の統合する時のChatGPTの実行が不要なため、実行時間が短いと考えられます。

それでは、具体的なコードを見ていきましょう。

python
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import YoutubeLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.docstore.document import Document
from langchain.chains.question_answering import load_qa_chain
import time

start_time = time.time()

youtube_url = "https://www.youtube.com/watch?v=TQvaocfmvaI"
loader = YoutubeLoader.from_youtube_url(youtube_url, language="ja")
transcript_text = loader.load()[0].page_content
print(f"{transcript_text = }")
print(f"{len(transcript_text) = }")

text_splitter = CharacterTextSplitter(separator=" ", chunk_size=500)
texts = text_splitter.split_text(transcript_text)
print(f"{len(texts) =}")

docs = [Document(page_content=t) for t in texts]

chat = ChatOpenAI(model_name="gpt-3.5-turbo")
chain = load_qa_chain(
    llm=chat,
    chain_type="map_rerank",
    verbose=True,
)

question = "YouTubeを学習したChatGPTを実装するために、インストールが必要なライブラリを教えて。"

output = chain(
    {
        "input_documents": docs,
        "question": question,
    },
    return_only_outputs=True,
)["output_text"]
print(output)

print(f"{time.time() - start_time}")

以上が、「Map Rerank」の実装方法です。
次の章では、「Refine」の実装方法について説明します。

5. 「Refine」の実装方法

最後に、「Refine」の実装方法を見ていきましょう。
具体的な手順としては、「chain_type」を「refine」に設定します。

「Refine」では、1つ目の塊の結果を2つ目の塊にバトンタッチする形になります。

それでは、具体的なコードを見ていきましょう。

python
from langchain.chat_models import ChatOpenAI
from langchain.document_loaders import YoutubeLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.docstore.document import Document
from langchain.chains.question_answering import load_qa_chain
import time

start_time = time.time()

youtube_url = "https://www.youtube.com/watch?v=TQvaocfmvaI"
loader = YoutubeLoader.from_youtube_url(youtube_url, language="ja")
transcript_text = loader.load()[0].page_content
print(f"{transcript_text = }")
print(f"{len(transcript_text) = }")

text_splitter = CharacterTextSplitter(separator=" ", chunk_size=500)
texts = text_splitter.split_text(transcript_text)
print(f"{len(texts) =}")

docs = [Document(page_content=t) for t in texts]

chat = ChatOpenAI(model_name="gpt-3.5-turbo")
chain = load_qa_chain(
    llm=chat,
    chain_type="refine",
    verbose=True,
)

question = "YouTubeを学習したChatGPTを実装するために、インストールが必要なライブラリを教えて。"

output = chain(
    {
        "input_documents": docs,
        "question": question,
    },
    return_only_outputs=True,
)["output_text"]
print(output)

print(f"{time.time() - start_time}")

出力結果は、英語で表示されます。
そのため、「次の文章を和訳して。」というプロンプトを実行します。

from langchain.schema import HumanMessage

print(chat([HumanMessage(
    content=f"""
    次の文章を和訳して。
    {output}
""")
]).content)

「Refine」を使うと、英語で出力されることが多いため、最後に和訳のプロンプトを挟むことをおすすめします。

ちなみに、「Map Refine」の実行には、合計で「1分7秒」かかりました。
「Refine」は、順番に1つずつ実行する必要があるため、「Map Reduce」と「Map Rerank」よりも時間がかかります。

以上が、「Refine」の実装方法です。

最後に

最後まで読んでくださり、ありがとうございました!
この記事を通して、少しでもあなたの学びに役立てば幸いです!

おまけ①:Raggle

RAGの精度改善に挑戦しませんか?

Raggleにて、「法務RAGシステムの性能改善ハッカソン」を開催中です!(10月20日に募集締切)

Raggleは、RAGの性能改善技術を競い合い、AIエンジニアのスキルアップを支援するプラットフォームです🥇

優勝者(GOLD🥇)の賞金は、なんと30万円!!!

SILVERは10万円、BRONZEでも5万円の賞金を用意しています!

また、参加賞として、大会終了後に「RAG精度改善ハンドブック」を贈呈予定なため、初学者の方もぜひ挑戦してみてください 🔰

みなさん、奮ってご参加ください🔥

※ 生成AIエンジニアの権利を守るため、投稿されたソースコードの著作権は、投稿者に帰属する規約としているため、その点もご安心ください◎

▼ エントリーはこちら ▼
https://bit.ly/raggle_zenn

おまけ②:書籍出版のお知らせ

ついに『AIとコミュニケーションする技術(インプレス出版)』という書籍の事前予約が始まりました🎉

これからの未来において「変わらない知識」を見極めて、生成AIの業界において、読まれ続ける「バイブル」となる本をまとめ上げました。

かなり自信のある一冊なため、もしもよろしければ、ご一読いただけますと幸いです^^

▼ Amazonの事前予約はこちらから ▼
https://amzn.to/3ME8mLF

おまけ③:生成AIアカデミー

より専門的な「生成AIエンジニア人材」を目指しませんか?

そんな方々に向けて、「生成AIアカデミー(旧:生成AIエンジニア塾)」というプログラムを始めました🎉

最終的なゴールとして、『エンタープライズ向けの生成AIシステムを構築するためのスキルを習得し、大手案件で活躍できる人材』を目標とします。

また、一人一人にしっかりと向き合って、メンタリングをできるようにするため、現在メンバーの人数制限をしております。本気度やスキルレベルの高い人から、順番にご案内しております。

▼ 登録はこちらから ▼
https://bit.ly/generative_ai_engineer_school_by_zenn

おまけ④:AI Newsletter for Biz

最新のAIニュースの情報を収集しませんか?

AI Newsltter for Bizは、ビジネスパーソン向けに「AIニュース」を定期配信する完全無料のニュースレターです📩

一人でも多くの方にとって、「AI人材としてのスキルアップ」につながれば幸いです^^

また、現在、登録者限定で「明日から使える 無料AIサービス3選」のPDFを配布中です 🎁
※ ご登録完了のメールに、PDFリンクを添付いたします。

▼ 登録はこちらから ▼
https://bit.ly/ai_newsletter_for_biz_zenn

おまけ⑤:生成AIの仕事をしたい仲間を募集中 🤝

弊社Galirageでは常に、40-50件ほどの生成AI案件が走っております。

そして、ほとんどが「生成AIの案件(RAGシステム開発 / 精度改善の研究開発など)」の仕事になります!

かなり人手が不足しており、以下のポジションの仲間を募集しています💪

  • RAGエンジニア(RAG / LangChain / Python)
  • バックエンドエンジニア(Python / FastAPI)
  • フロントエンジニア(Next.js / TypeScript)
  • Azureエンジニア(AOAI / AI Search)
  • UI/UXデザイナー
  • 生成AIリサーチャー(研究開発 / 論文執筆)
  • 生成AIコンサルタント
  • PM / PMO

ご興味がある方は、下記のフォームよりお気軽にご連絡ください!

https://forms.gle/XMd19irZU4Fi7VAQ9

採用基準は下記の通りです。
  • 平日の日中に動ける方だと嬉しいですが、週8時間くらいの副業でもOKです!
  • 開始時期は、直近だと嬉しいですが、遠い未来でもOKです!まずはカジュアルに話しましょう😊
  • 年齢は不問です!現状は、平均年齢は30歳前後の会社です!
  • 「スキルセット」よりも「カルチャーマッチ・仕事への姿勢・ものづくりへのワクワク」を重視します。
    • 10月には新しく10名採用しました。
    • その内、エンジニア経験が3年未満の方は、4名いました。
    • スキルについては、ジョインした後に、必要に応じて、キャッチアップする時間を作ります。
    • 弊社は、正社員7名、業務委託80名の組織で構成されており、業務委託の仲間に支えられているため、正社員と業務委託の間にあまり差をつけていません。
    • 契約形態に関わらず、一緒に働く仲間として受け入れたその日から、大切な仲間です!
    • 新卒や転職の正社員採用もしていますが、業務委託での仕事を通して、お互いにWin-Winだと判断できた方のみを採用しています。
    • 私自身、フリーランスを5年間やっていたため、個人事業主と正社員のメリデメは両方の立場から理解しています。
  • 人手不足ではあるものの、採用基準をかなり厳しくしています。目の前の売上よりも、カルチャーのマッチする人だけを入れることにこだわっています。
  • ちなみに、弊社のリーダーを紹介したプロフィールページはこちらです!
    • Galirageに、本当に素敵な方が多いことは、保証します!

参考文献

https://github.com/hwchase17/langchain

https://colab.research.google.com/drive/1A6TCp2w1nHA-HGhvUyh1AoY9WdGinCzP?usp=drive_link

https://youtu.be/MoQcV4s7hQw

https://zenn.dev/umi_mori/books/chatbot-chatgpt

https://zenn.dev/umi_mori/books/prompt-engineer

https://www.youtube.com/playlist?list=PLakzeSUr4kaL32nyYvr067UgGMjCeRFjP

https://www.youtube.com/playlist?list=PLakzeSUr4kaItFFLVi5DnqFu5gmvZSkcN

https://www.youtube.com/playlist?list=PLakzeSUr4kaIiamwsc0NUo8dV4xAIIq93

Discussion