見出し画像

【2024年最新】RAGとOpenAI APIの料金と使い方 - LangChainとLlamaIndexを解説

RAGをOpenAI APIで実現する方法を丁寧に解説。実際のコードや具体例を交えながら、LangChainとLlamaIndexの基本知識、導入手順、カスタマイズ、料金に関する詳細情報を提供し、GPT-4oモデルの使用例も紹介します。

当記事の前提:OpenAIのAPIキーを取得済み
取得の仕方がわからない方はこちらの記事でAPIキーの取得方法を説明しておりますので、是非ご活用ください!


OpenAI APIのモデル

モデルの種類と特徴

今回の記事で用いるモデルはテキスト生成のものです。
なので、GPT-4o・GPT-4 Turbo・GPT-4・GPT-3.5 Turboが対象となります。
※2024年6月現在

各モデルの簡単な説明

各モデルの説明
各モデルの説明
  • GPT-4o: 最新のモデルであり、非常に高速で高精度な回答を生成します。複雑な質問に対しても正確な応答が期待できます。
    input:$5.00 / 1M tokens
    output:$15.00 / 1M tokens

  • GPT-4 Turbo: GPT-4oよりもやや遅いが、依然として高精度な回答を提供します。
    input:$10.00 / 1M tokens
    output:$30.00 / 1M tokens

  • GPT-4: GPT-3.5 Turboよりも高い回答精度を持ち、より詳細で正確な応答が得られますが、応答速度は遅めです。
    input:$30.00 / 1M tokens
    output:$60.00 / 1M tokens

  • GPT-3.5 Turbo: 他のモデルと比較すると回答の精度はやや劣るものの、依然として実用的なレベルの応答を生成します。速度も速く、コスト効率が高いです。
    input:$0.5 / 1M tokens
    output:$1.5 / 1M tokens

表を見ていただければわかる通り、性能やコストパフォーマンス面においてGPT-4oとGPT-3.5 Turboを使用するのがおすすめです。

LangChainとは

LangChainの概要

簡単に説明すると…
人間とAIが円滑に会話出来るようにサポートしてくれるライブラリです。

主な機能と利点

Langchainの主な機能は大きく分けると以下になります。

  • プロンプトエンジニアリング:AIが適切な回答を生成するための最適な入力(プロンプト)を設計します。

  • チェーンの作成:複数のステップを連鎖させて実行し、複雑なタスクをシンプルにこなせるようにします。

  • データ連携:外部データソースと連携して、最新かつ正確な情報を提供します。

  • 後処理:生成されたテキストを整形し、ユーザーにとって理解しやすい形にします。

LlamaIndexとは

LlamaIndexの概要

簡単に説明すると…
AIにテキスト学習機能を授けるライブラリです。

主な機能と利点

LlamaIndexの主な機能は大きく分けると以下になります。

  • インデックス作成:大量のテキストデータを効率的にインデックス化し、迅速な検索やデータの取得を可能にします。

  • 高度な検索機能:自然言語処理(NLP)技術を活用して、ユーザーのクエリに対して正確かつ関連性の高い結果を提供します。

  • スケーラビリティ:大規模なデータセットに対しても高速かつスケーラブルな処理を実現し、企業や研究機関のニーズに応えます。

  • カスタマイズ可能なモデル:ユーザーが自身のニーズに合わせてインデックスや検索アルゴリズムをカスタマイズできる柔軟性を提供します。

LlamaIndexを使ったRAG

RAGの基本概念

簡単に説明すると…
RAG(Retrieval-Augmented Generation)は、AIが必要な情報を検索し、それを元に最適な回答を生成する技術です。
例えば、企業のマニュアルや技術文書といったテキスト情報を生成AIに読み込ませ、その内容に基づいて質問に答えさせることができる仕組みです。

LlamaIndexを用いたRAGの実装方法

以下に、基本的な実装方法を示します。
また、その後、さまざまなカスタマイズについても記載します。
まず、以下のコマンドをGitbashなどのコマンドラインツールで実行してください。

pip install llama-index-llms-openai
pip install llama-index

次に任意の場所に「index.py」というファイルを作成し、以下のコードをコピペします。

import openai
import os
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader

# 「API_KEY_HERE」をご自身のOpenAI APIキーに変えてください。
os.environ["OPENAI_API_KEY"] = "API_KEY_HERE"
openai.api_key = os.environ["OPENAI_API_KEY"]

# このファイルと同じフォルダ内にdataフォルダを作成し、読み込ませたいファイルを入れる。
data = SimpleDirectoryReader(input_dir="data").load_data()
index = VectorStoreIndex.from_documents(data)
 
chat_engine = index.as_chat_engine(
    chat_mode="context",
)
response = chat_engine.chat("質問(ユーザーメッセージ)をここに入れる")
print(response)

その後、コマンドラインツールでindex.pyが格納されているフォルダに移動し、

python index.py

を実行します。

さまざまなカスタマイズ

  • システムプロンプトを設定する
    システムプロンプトとは?
    AIモデルに対して全体の役割や動作方針を設定することが出来ます!
    例えば、以下のように設定します。

chat_engine = index.as_chat_engine(
    chat_mode="context",
    system_prompt=(
        "あなたはお問い合わせ対応AIチャットボットです。\n"
        "初めに必ず「お問い合わせありがとうございます。」と付けてください。/n"
    ),
)

上記を設定すると、、

ユーザー:営業時間を教えて下さい。
AI:お問い合わせありがとうございます。営業時間は…

のような回答が可能になります。

  • OpenAI APIの使用するモデルを選ぶ
    使用するモデルを選択することが出来ます。
    未選択の場合は自動的にGPT-3.5 Turboが使用されます。
    下記のようにllmを定義し、chat_engine設定時に指定のモデルを適用します。
    *例ではGPT-4oを選択しています。

from llama_index.llms.openai import OpenAI

llm = OpenAI(model="gpt-4o")

chat_engine = index.as_chat_engine(
    chat_mode="context",
    llm=llm,
)
  • DBに保存しているテキストを読み込ませる
    DBに保存しておいたテキストをRAG使用時に呼び出して読み込ませることも可能です。
    例えば、db.sqlite3のupload_textテーブルのtext_contentフィールドにテキストを保存していた場合、以下のコードでそのテキストを読み込みます。

import sqlite3
import openai
import os
from llama_index.core import VectorStoreIndex, Document
from llama_index.llms.openai import OpenAI

# APIキーの設定
os.environ["OPENAI_API_KEY"] = "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"
openai.api_key = os.environ["OPENAI_API_KEY"]

# 手順1: SQLite3データベースからテキストデータを取得
def fetch_text_from_db(db_path, table_name, field_name):
    # データベースに接続
    conn = sqlite3.connect(db_path)
    cursor = conn.cursor()
    
    # テキストデータを取得
    cursor.execute(f'SELECT {field_name} FROM {table_name}')
    rows = cursor.fetchall()
    
    # データベース接続を閉じる
    conn.close()
    
    # 取得したデータをリストに格納
    return [row[0] for row in rows]

# テキストデータをデータベースから取得
db_path = 'db.sqlite3'
table_name = 'upload_text'
field_name = 'text_content'
related_files = fetch_text_from_db(db_path, table_name, field_name)

# 手順2: 取得したデータを結合
additional_info = "\n".join([file for file in related_files if file])

# 手順3: ベクトル化
# ドキュメントの作成
documents = [Document(text=additional_info)]

# インデックスの作成
index = VectorStoreIndex.from_documents(documents)

# チャットエンジンの設定
llm = OpenAI(model="gpt-4o", temperature=0)
chat_engine = index.as_chat_engine(
    chat_mode="context",
    llm=llm,
)

# 質問に対する応答
response = chat_engine.chat("質問(ユーザーメッセージ)をここに入れる")
print(response)
  • 会話履歴を持たせる
    LlamaIndexではデフォルトでは一問一答形式で、それまでの会話の履歴を考慮しません。
    そのため、例えばLlamaIndexが生成した回答に対して「なぜそのようになるのですか?」と質問しても、「そのようにとは何ですか?」と返されてしまうことがあります。
    この問題を解決するために、「memory」という変数を用いることで会話の履歴を保持することができます。
    以下にその使い方を示します。

from llama_index.core.memory import ChatMemoryBuffer

memory = ChatMemoryBuffer.from_defaults(token_limit=1500)

chat_engine = index.as_chat_engine(
    chat_mode="context",
    memory=memory,
)

RAGでのリスク

  • 間違った情報や機密情報を読み込ませてしまうとそれがそのまま出力される
    読み込ませた情報がそのまま出力されるため、情報が間違っていたり古かった場合、誤った情報を提供してしまう危険性があります。
    また、機密情報が出力されることで、情報漏洩のリスクも高まります。

具体例:

  1. 価格情報の誤り
    商品Aの価格が1500円から1600円に変更されたが、読み込ませた資料には古い価格の1500円が記載されていた場合。
    ユーザーが商品Aについて質問した際、「商品Aは~というもので、価格は1500円です。」と古い情報を基に回答してしまう。

  2. 機密情報の漏洩
    顧客対応マニュアルに顧客リストが含まれている場合。
    ユーザーが「お問い合わせ先の電話番号を教えてください」と質問した際、誤って顧客の電話番号を含む機密情報を返答してしまう。
    例: 「○○様 090-○○○○-○○○○、○○様 090-○○○○-○○○○、…」と具体的な顧客情報を漏洩してしまう。

  • 読み込ませていない情報に対しても返答してしまう
    読み込ませた情報以外にも、一般的な質問に対しては普遍的な回答をしてしまうことがあります。

具体例:

  1. ユーザーが「猫の種類を教えてください」と質問すると、「猫の種類は…」と読み込ませた情報に関係なく一般的な知識を基に返答してしまう。

対策:

  1. Temperatureの設定
    LLMの設定でtemperatureを0に設定する。temperatureは0から2.0まで設定でき、値が高くなるほど返答の多様性が高まります。0に設定することで、予想外の返答をほぼなくすことができます。
    コード例:llm = OpenAI(model="gpt-4o", temperature=0)

  2. System Promptの設定
    System promptに「与えた情報に記載されていないことには答えないでください」と設定する。これにより、AIが与えられた情報外の質問には答えないようになります。

LlamaIndexを使ったRAGでかかる費用

RAGでのGPTモデルごとの返答トークンの平均と料金

もちろん、入力する内容によって、返答のトークン数は大きく変動します。
今回は簡単な質問から複雑な質問での返答トークンの平均を取りました。
*入力は平均20トークンとします。
 また、読み込ませるテキスト量を日本語で5万文字とします。

〇GPT-4o
約300トークン
input:$5.00 / 1M tokens
output:$15.00 / 1M tokens
〇GPT-3.5 turbo
約200トークン
input:$0.5 / 1M tokens
output:$1.5 / 1M tokens
〇text-embedding-ada-002
約57,000トークン
$0.10 / 1M tokens

RAGでの会話当たりの費用

以下にGPT-4oとGPT-3.5 turboを使用した場合の会話の費用を記載します。
※あくまで目安であり仕様により異なります。
※2024年6月現在

RAGでの会話当たりの費用
RAGでの会話当たりの費用

RAGの仕組みを使用したクラウドサービス


AIチャットボット POPAUP(ポパップ)

1からRAGを構築すると技術的な知見やリソースの確保が必要です。そのため、利用用途がはっきりしている場合は、既存のRAGを取り入れているサービスを利用することもおすすめです。
株式会社ユリーカではRAGの仕組みを使用したクラウドサービス「POPAUP(ポパップ)」を運営しております。POPAUPはWebサイトにオリジナルのチャットボットを設置できるサービスでECサイトやHP、ランディングページといったHTMLタグを挿入できるサイトに設置することで、お問い合わせの工数削減や24時間365日、訪問者からの質問へ生成AIが返答してくれます。
詳しくはこちらをご覧ください。↓

まとめ

今回はOpenAIもモデルやLangchainとLlamaIndexを使用して、テキスト情報を生成AIに読み込ませ、その内容に基づいて質問に答えさせる「RAG」という仕組みの構築方法を紹介しました。次回はLangchainとLlamaIndexの関係性についてもう少し深堀りしようと思います。