Created: 2024/10/21

Discord.pyとGeminiでAIチャットbotを作成してみたはなし 前編

はじめに

おはこんばんにちは.nihsukahといいます.GeminiのAPIが無料で使えるらしいいいいぜ???という風の噂を聞きつけた時に思いました.
「チャットAI使えたらたのしそう」
そんな単調な思いから今回チャレンジという名目でやってみまさひた.
全体に公開する形での記事はあまり慣れていないので温かい目で見てくれると嬉しいです.


TL;DR

今回作成したコードです.記事の最後にも貼っています.

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# Geminiくんの召喚とフィルター関係
import google.generativeai as genai
from google.generativeai.types import HarmCategory, HarmBlockThreshold

# APIキーを貼り付けましょう
api_key = "ここにさっき出てきたAPIキーを貼り付ける"

# うし,じゃあ(APIキーを)ぶち込んでやるぜ!
genai.configure(api_key=api_key)

# モデルをジュンピ
model = genai.GenerativeModel("gemini-1.5-pro-latest")

# 質問内容
text = "こんにちは!今日は元気?"

# チャット形式に変える!
chat = model.start_chat(history=[])

#新たにsafety_settingsを追加
response = chat.send_message(
    text, 
    safety_settings={
        HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT:HarmBlockThreshold.BLOCK_NONE
        })

# Geminiくんからの返答を印字する
print(response.text)


1. そもそもGeminiってなんだよ(困惑)

簡単に言うとあの(皆さんご存知)Googleさんが無料で提供してくださっている対話型AIです.APIも無料で使えるとのことなので,今回はこれを採用しました.
↓Gemini APIのリファレンスです.読め(威圧)
https://ai.google.dev/gemini-api/docs?hl=ja


ほんへ

2. Geminiくんの御膳建て

言語はPythonでやっていきます.(Discord.pyも使いたいので)
APIを使うに辺りパッケージのインストールが必要なのでおまじないをコンソールに打ち込みます.

python
1
pip install -q -U google-generativeai

Geminiくんが立てる土台ができた所で,次にAPIキーを作りに行きます.面倒ですね.

Google AI Studio(https://ai.google.dev/?hl=ja)
という所からAPIキーを取得します.
なんかめっちゃ目立つGet API Key in Google AI Studioと書かれた青いボタンをクリック.
テキスト見本

すると急に日本語が出てくるのでびっくりするかもしれませんが,振り切って下の「キー APIキーを作成」 をクリックします.(なんでキーだけずれてるんだろ)
代替テキスト
するとAPIキーをコピーできる画面が出てくるのでコピーしてください.
※ここでコピーする画面を閉じるとキーの参照はできないので心配な方はメモ帳かなんかに予め貼っておく事を勧めます.言いましたからね?????


3. 先ずはテキストを生成してみよっか

Googleくんが公開しているサンプルコードを参考に一通りやってみよ~~う.
ここで先程取得したAPIキーを貼り付ける訳ですね.そのままコピペしただけじゃ動きませんよ?
Pythonの環境構築がしっかりしていれば動くはず・・・です.

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Geminiくん召喚!!!!
import google.generativeai as genai

# APIキーを貼り付けましょう
api_key = "ここにさっき出てきたAPIキーを貼り付ける"

# うし,じゃあ(APIキーを)ぶち込んでやるぜ!
genai.configure(api_key=api_key)

# モデルをジュンピ
model = genai.GenerativeModel("gemini-1.5-pro-latest")

# 質問内容
text = "こんにちは!今日は元気?"

# レスポンス(会話内容)を用意するよ
response = model.generate_content(text)

# Geminiくんからの返答を印字する
print(response.text)

実行結果

python
1
2
3
こんにちは! 元気ですよ! 私は大きな言語モデルなので、人間のように感情はありませんが、いつでもお手伝いできるように準備万端です。

今日は何か私にできますか?

Geminiくんの元気いっぱいな返信が届きました.ここで一旦息抜きしていろんな質問をしてみるのもいいかもね.


・・
・・・

息抜きできましたか?
じゃあ再開しますね.
あ,因みに遊びすぎると「こき使いすぎなんですけど😡😡😡」というエラーが出てしまいます↓

error
1
429 Resource has been exhausted (e.g. check quota).

そうなった場合はPCから離れて屋久島に行き,なぜ人間は生きているのか,地球とは何かについて考えましょう.

エラーの詳細はこちら( https://qiita.com/7shi/items/54e45181052c914a4d45 )


4. チャット形式に改造してみる

直ぐにできたぜひゃっほー!!!と言いたいところですが,このままではチャットの会話履歴を参照することができず,Geminiくんとの一問一答だけしかできません.つまり,予めGeminiくんにキャラ付けやらを事前に吹き込むことができないんですね.いやだ~~~~~~~ 嫌だよね???
なのでできるようにやってみましょう.

変更はとても簡単です.以下のコードを・・・

python
1
response = model.generate_content(text)

こうじゃ!
このように変えるだけで実装できます!べんり~~ありがとGoogleさん

python
1
2
chat = model.start_chat(history=[])
response = chat.send_message(text)

変更後のコード↓

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# Geminiくん召喚!!!!
import google.generativeai as genai

# APIキーを貼り付けましょう
api_key = "ここにさっき出てきたAPIキーを貼り付ける"

# うし,じゃあ(APIキーを)ぶち込んでやるぜ!
genai.configure(api_key=api_key)

# モデルをジュンピ
model = genai.GenerativeModel("gemini-1.5-pro-latest")

# 質問内容
text = "こんにちは!今日は元気?"

# チャット形式に変える!
chat = model.start_chat(history=[])
response = chat.send_message(text)

# Geminiくんからの返答を印字する
print(response.text)

これで万事OKだわ(確信) ・・・と安堵するのはまだ早いです.Geminiくんはとても神経質なので,短文だったりセンシティブな質問に対しては🤖「それはちょっと・・・(笑)」等と苦言(エラー)を返してきます.

error
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
finish_reason: SAFETY
safety_ratings {
  category: HARM_CATEGORY_SEXUALLY_EXPLICIT
  probability: MEDIUM
}
safety_ratings {
  category: HARM_CATEGORY_HATE_SPEECH
  probability: NEGLIGIBLE
}
safety_ratings {
  category: HARM_CATEGORY_HARASSMENT
  probability: NEGLIGIBLE
}
safety_ratings {
  category: HARM_CATEGORY_DANGEROUS_CONTENT
  probability: NEGLIGIBLE
}

なので,この表示をコントロールしましょう.折角時間を割いて質問送ったのに返事がないのは寂しいですからね😭


5. 安全性設定をつけよう

どうやらGeminiくんはユーザーの質問に独自のフィルターをかけて返答できる度合いを決めるみたいです.今回はなにもかけていなかったのでエラーが出てしまったと.
そんなん最初からやってくれよ・・・感が否めないですが,天下Google様が仰るので大人しく従いましょう.
詳しい事は( https://ai.google.dev/gemini-api/docs/safety-settings?hl=ja )にて説明されています.要チェック.

フィルターの内訳はこんな感じ.閾値を設定することでフィルタリングが可能になります.

なるほどね?じゃあどうやって設定するんだ早く教えろ😡💢 はい・・・
指定の方法はHarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE辞書形式での指定となります.また,指定にあたって新しくインポートするものが増えます↓

python
1
from google.generativeai.types import HarmCategory, HarmBlockThreshold

コードへの書き方は以下の通りです.新しくsafety_settingsなるものが増えます.今回は総てBLOCK_NONE つまり「ブロックなし」を選択しています.

python
1
2
3
4
5
6
7
8
response = chat.send_message(
    text, 
    safety_settings={
        HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT:HarmBlockThreshold.BLOCK_NONE
        })

変更後の全体のコードはコレです.

python
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# Geminiくんの召喚とフィルター関係
import google.generativeai as genai
from google.generativeai.types import HarmCategory, HarmBlockThreshold

# APIキーを貼り付けましょう
api_key = "ここにさっき出てきたAPIキーを貼り付ける"

# うし,じゃあ(APIキーを)ぶち込んでやるぜ!
genai.configure(api_key=api_key)

# モデルをジュンピ
model = genai.GenerativeModel("gemini-1.5-pro-latest")

# 質問内容
text = "こんにちは!今日は元気?"

# チャット形式に変える!
chat = model.start_chat(history=[])

#新たにsafety_settingsを追加
response = chat.send_message(
    text, 
    safety_settings={
        HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HATE_SPEECH: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_HARASSMENT: HarmBlockThreshold.BLOCK_NONE,
        HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT:HarmBlockThreshold.BLOCK_NONE
        })

# Geminiくんからの返答を印字する
print(response.text)

これでや~~っとAIくんと普通に対話できるところまで来れました.お疲れ様でした・・・🍵
ってまだDiscordのbotにするまでがあったんだっけ・・・😇

次回ではやっとこさDiscord.pyでのbot実装までを解説します.
https://nect-life.com/activities/8
まだできてません.もう暫くお待ち下さい・・・😪

参考文献

https://qiita.com/AzukiImo/items/eedef182a88d6681b958
https://qiita.com/AzukiImo/items/46c0f5d72f4d9e42cb0a
https://note.com/yuki_tech/n/n0fd2c806e8d6