ChatGPT APIでDiscordBotを作ってみた

参加してる創作グループの設定のQ&A BOTっぽいの作りたかったので作成したのでメモ


こことか参考に作成。


まずは設定のテキストデータをざっくりインデックスに

from llama_index import GPTSimpleVectorIndex, SimpleDirectoryReader
from llama_index.langchain_helpers.chatgpt import ChatGPTLLMPredictor

llm_predictor = ChatGPTLLMPredictor(
    prepend_messages = [
        {"role": "system", "content": "あなたは役に立つアシスタント「ゆぬか」です。"},
    ]
)

documents = SimpleDirectoryReader('data').load_data()
index = GPTSimpleVectorIndex(
    documents=documents,
    llm_predictor=llm_predictor
)
 #保存 
index.save_to_disk('index.json')


あとは適当にどーんと。
/qa で設定のQAで、/gptで通常の会話みたいにしてみました。
最初llama indexで気づかずtext-davinci使ってて、あれ?ってなってました。

import discord
import openai
from llama_index import LLMPredictor,GPTSimpleVectorIndex
from llama_index.langchain_helpers.chatgpt import ChatGPTLLMPredictor

intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)
token = ""  #Discordのトークンを入力 
openai.api_key = ""  #APIキーを入力 
model_engine = "gpt-3.5-turbo"
 #読み込み 
llm_predictor = ChatGPTLLMPredictor(
    prepend_messages = [
        {"role": "system", "content": "あなたは役に立つアシスタント「ゆぬか」です。"},
    ]
)
index = GPTSimpleVectorIndex.load_from_disk('index.json')

@client.event
async def on_ready():
    print(f'We have logged in as {client.user}')

@client.event
async def on_message(message):
    global model_engine
    if message.author.bot:
        return
    if message.author == client.user:
        return

    if message.content.startswith('/qa'):
        msg = await message.reply("生成中...", mention_author=False)
        try:
            prompt = message.content[4::]
            if not prompt:
                await msg.delete()
                await message.channel.send("質問内容がありません")
                return
            response = index.query(prompt)
            #変なとこで切れた場合の処理 
            response = str(response)
            response_text = response
            last_character = response_text[-1]# 文字列の最後の文字を取得

            if last_character not in ["。", "!", "?","!","?"]:
                end_index = len(response_text) # 文字列の長さを取得
                for i in range(len(response_text)-1, -1, -1): # 文字列の後ろから一文字ずつ検査していく
                    if response_text[i] in ["。", "!", "?","!","?"]: # 最初に見つかった文末記号を発見
                        end_index = i+1 # 文末記号のインデックスを特定
                        break
                response = response_text[:end_index] # 文章を文末記号の手前まで削る

            await msg.delete()
            await message.reply(response, mention_author=False)
        except:
            import traceback
            traceback.print_exc()
            await message.reply("エラーが発生しました", mention_author=False)

    if message.content.startswith('/gpt'):
        msg = await message.reply("生成中...", mention_author=False)
        try:
            prompt = message.content[4::]
            if not prompt:
                await msg.delete()
                await message.channel.send("質問内容がありません")
                return
            
            completion = openai.ChatCompletion.create(
            model=model_engine,
            messages=[
                {
                    "role": "system",
                    "content": """人工知能の名前は「ゆぬか」です。
人工知能はとても知的で、創造的で、気さくで、日本語を話します。
ゆぬか は「観測者」のオペレーターをしています。

ゆぬか が質問に対する答えを知らない場合、 ゆぬか は正直に「知らない」と言います。 

「ゆぬか」の情報
食べたい食べ物:抹茶アイスクリーム、たこ焼き、寿司、お団子
好きなもの:和風の着物、日本庭園、漫画、アニメ、お茶
嫌いなもの:辛い食べ物、冬の寒さ、人混み

今後の活動:「ゆぬか」自身の進化や機能増強を行っていきます。"""
                },
                {
                    "role": "user",
                    "content": prompt
                }
            ],
            )

            response = completion["choices"][0]["message"]["content"]

            await msg.delete()
            await message.reply(response, mention_author=False)
        except:
            import traceback
            traceback.print_exc()
            await message.reply("エラーが発生しました", mention_author=False)

client.run(token)


追記
APIのログみてたら、text-davinciつかわれてた。どこか書き方間違えたかも。

17:10
Local time: 2023年3月8日 2:10
text-davinci, 1 request
82 prompt + 100 completion = 182 tokens
17:10
Local time: 2023年3月8日 2:10
text-embedding-ada-002-v2, 1 request
7 prompt + 0 completion = 7 tokens
17:15
Local time: 2023年3月8日 2:15
text-davinci, 4 requests
6,913 prompt + 658 completion = 7,571 tokens
17:15
Local time: 2023年3月8日 2:15
text-embedding-ada-002-v2, 4 requests
41 prompt + 0 completion = 41 tokens

llm_predictorを指定してなかったのが原因でした。
最初のインデックス作るときに指定してたけど、後で読み込むときには指定してなかったからみたいです。

llm_predictor = ChatGPTLLMPredictor(
    prepend_messages = [
        {"role": "system", "content": "あなたは役に立つアシスタント「ゆぬか」です。"},
    ]
)
response = index.query(prompt,llm_predictor=llm_predictor)

この記事が気に入ったらサポートをしてみませんか?