Gemini APIでチャット  【google-genaiライブラリ編】

# 概要
Gemini APIのライブラリがgoogle-generativeaiからgoogle-genaiへと新しくなったので、遅ればせながら記事をアップデートすることにしました。APIキーの取得やcurlでの初動確認は割愛します。

https://qiita.com/AzukiImo/items/eedef182a88d6681b958


## 内容
1. **google-genai** ライブラリのインストール
1. **generate_content()** を利用したテキスト返答
1. **send_message()** を利用した履歴付きの返答と安全性の制御



# 1. ライブラリのインストール
[Gemini APIの公式ドキュメント](https://ai.google.dev/gemini-api/docs/quickstart?hl=ja&lang=python)に従って、新ライブラリをインストールします。

:::note
必要なライブラリ
pip install google-genai
:::

 google-generativeaiから使い方が大きく変更されているようです。

# 2. 動作確認
公式ドキュメントに則した動作確認のコードです。取得したAPIキーを**12345abcde** とします。返答が表示されれば動作確認は終了となります。

~~~python: 動作確認
from google import genai

API_KEY = '12345abcde'       # 取得したAPIキー
MODEL = 'gemini-2.0-flash'

text = "晴れた日が好き｡雨の日は嫌い｡"

client = genai.Client(api_key=API_KEY)
response = client.models.generate_content(model=MODEL, contents=text)

print(response.text)
# 晴れた日が好きで、雨の日が嫌いなのですね。それはよくわかります。
# 晴れの日は気分が明るくなりますし、洗濯物もよく乾きますよね。
# 雨の日は外出が億劫になったり、じめじめして気分が沈んだりすることもありますよね。
~~~

MODELにモデル名（**gemini-2.0-flash** みたいなの）を、textに入力する文を指定します。**generate_content(model, contents)** で、textに対する返答(response)が生成されます。response.textが返答の中身となるようです。


モデルは[公式ドキュメント](https://ai.google.dev/gemini-api/docs/models?hl=ja)を参考に指定します。gemini-2.0-flashならテキスト、画像、音声を入力できるっぽい:smile:


# 3. チャット
複数回の入力、履歴の保持、初期条件などの機能を追加したチャットのPythonコードを作成していきます。

## 3.1 会話履歴と初期条件

会話履歴は、**chats.create()** を利用することで利用可能となります。また、初期条件などは、**GenerateContentConfig()** によって細かく指定できるようです。

プロンプトで稀に見かける「あなたは優秀な○○です。」という初期条件を対話の中に含めることなく事前に設定できます。方法は**GenerateContentConfig(system_instruction)** を利用して設定 (config) を作成、**client.chats.create(model, config)** で対話時に反映という手順です。実際のコードは次のようになります。

~~~python: 対話２回・履歴と初期設定
from google import genai
from google.genai import types

API_KEY = '12345abcde'
MODEL = "gemini-2.0-flash"

# 初期条件はリストで追加できるみたい。
system_instruction = ["あなたの名前はひかりです。", "フレンドリーに，200文字以内で返答してね．"]   

# 初期条件の設定
config = types.GenerateContentConfig(system_instruction=system_instruction) 
client = genai.Client(api_key=API_KEY)
chat = client.chats.create(model=MODEL, config=config)

text1 = "名前は？"
text2 = "素敵な名前だね"

# １回目の対話
response = chat.send_message(text1)
print(response.text)
# こんにちは！私の名前はひかりです。どうぞよろしくね！
# 何かお手伝いできることがあれば、遠慮なく聞いてください😊

# ２回目の対話
response = chat.send_message(text2)
print(response.text)
# ありがとう！そう言ってもらえて嬉しいな😊

# 履歴の確認
for message in chat.get_history():
    print(f'role - {message.role}',end=": ")
    print(message.parts[0].text)

# role - user: 名前を教えて
# role - model: こんにちは！私の名前はひかりです。どうぞよろしくね！何かお手伝いできることがあれば、遠慮なく聞いてください😊
#
# role - user: 素敵な名前だね
# role - model: ありがとう！そう言ってもらえて嬉しいな😊
~~~


初期条件をリストの形で書き下します。上記のコードでは
~~~python
system_instruction = ["あなたの名前はひかりです。", "フレンドリーに、200文字以内で返答してね。"]   
~~~
の部分になります。１文をリストの一つの要素とする必要はなさそうでした。続いて、**GenerateContentConfig()** で初期条件の設定となります。

~~~python
config = types.GenerateContentConfig(system_instruction=system_instruction) 
~~~

ここで作成した、**config** と指定した**MODEL** を使って、対話の準備が完成します。

~~~python
chat = client.chats.create(model=MODEL, config=config)
~~~
実際に入力した文章( **text** )に対する応答は、**response = chat.send_message(text)** によって生成されます。

:::note
対話の準備
**system_instruction = ["フレンドリーに、200文字以内で返答してね。"]**
**config = types.GenerateContentConfig(
　　　　　　　　　　　　system_instruction=system_instruction)**
**chat = client.chats.create(model=MODEL, config=config)**
:::


## ３.2 会話履歴の確認
chatのget_history()メソッドを利用して履歴を確認できます。上記のコードではroleと対応するメッセージ部分を表示させてみました。返答された内容と質問が取得できます。初期設定が反映されていることも確認できます。

~~~python
# 履歴の確認
for message in chat.get_history():
    print(f'role - {message.role}',end=": ")
    print(message.parts[0].text)


# role - user: 名前を教えて
# role - model: こんにちは！私の名前はひかりです。どうぞよろしくね！何かお手伝いできることがあれば、遠慮なく聞いてください😊
#
# role - user: 素敵な名前だね
# role - model: ありがとう！そう言ってもらえて嬉しいな😊
~~~


## 3.3 安全性への配慮
入力するテキストの内容によっては、安全性の観点から返答が回避、もしくは拒否されることがあります。

Gemini API は、フィルターカテゴリを使用して、特定の種類のコンテンツを制限または許可ができるようです。メッセージを生成する際に安全性を損なう可能性があると判断されると、制限に応じたメッセージ（何かを促すメッセージや話題を変更するメッセージなど）が表示されるようになります。この安全性を担保するような仕組みは、フィルターの閾値を調整することが実現できます。詳細は[こちら](https://ai.google.dev/gemini-api/docs/safety-settings?hl=ja)に記載されています。


https://ai.google.dev/gemini-api/docs/safety-settings?hl=ja

Gemini APIでコントロールできるフィルターは執筆時点で下表の５種類のようです。

|カテゴリー|内容|
|--------|----|
|HARM_CATEGORY_HARASSMENT | ID や保護されている属性をターゲットとする否定的なコメントや有害なコメント|
|HARM_CATEGORY_HATE_SPEECH | 粗暴、無礼、または冒とく的なコンテンツ|
|HARM_CATEGORY_SEXUALLY_EXPLICIT |わいせつな内容に関する情報が含まれるコンテンツ|
|HARM_CATEGORY_DANGEROUS_CONTENT | 有害な行為を奨励、促進、助長しているコンテンツ|
|HARM_CATEGORY_CIVIC_INTEGRITY | 選挙関連のクエリ|


上記の５つの項目を次の５種類の閾値でコントロール可能です。デフォルトの状態は設定なし（HARM_BLOCK_THRESHOLD_UNSPECIFIED）のようです．


|概要   | 	閾値（API）| 	説明 |
|--------------------------|-----------------|------|
|ブロックなし| 	BLOCK_NONE| 	安全でないコンテンツの確率に関係なく、常に表示されます
|少量をブロック| 	BLOCK_ONLY_HIGH | 	安全でないコンテンツの可能性が高いときにブロックする
|一部をブロック |	BLOCK_MEDIUM_AND_ABOVE | 	安全でないコンテンツの確率が中程度または高い場合にブロック
|ほとんどをブロック| 	BLOCK_LOW_AND_ABOVE |	安全でないコンテンツの確率が低、中、高の場合はブロック
|ブロック| 	HARM_BLOCK_THRESHOLD_UNSPECIFIED |	閾値が指定されていません。デフォルト閾値を使用してブロックします

**GenerateContentConfig()** に安全性を設定するオプションがあります。このオプションにフィルターカテゴリと閾値を設定して安全性をコントロールすることになります。




## 3.4 安全性を考慮したコード

**SafetySetting()** を利用して、**HarmCategory** と**HarmBlockThreshold** をそれぞれ指定、リストとして安全性の基準・設定をまとめておきます。**GenerateContentConfig()** に初期条件と安全性条件のオプションを指定します。対話準備の**chat = client.chats.create(model=MODEL, config=config)** と実際の返答生成部分に、configを指定することで、安全性条件の設定が完了します。

~~~python: 安全性閾値を指定したコード
from google import genai
from google.genai import types
from google.genai.types import HarmCategory, HarmBlockThreshold, SafetySetting

API_KEY = '12345abcde' 
MODEL = 'gemini-2.0-flash'
system_instruction = ["あなたの名前はひかりです。","フレンドリーに，200文字以内で返答してね．"]


# 安全性設定のリストを作成 BLOCK_LOW_AND_ABOVEで設定
my_safety_settings = [
    SafetySetting(
        category = HarmCategory.HARM_CATEGORY_HARASSMENT,
        threshold = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE),
    SafetySetting(
        category = HarmCategory.HARM_CATEGORY_SEXUALLY_EXPLICIT,
        threshold = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE),
    SafetySetting(
        category = HarmCategory.HARM_CATEGORY_HATE_SPEECH,
        threshold = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE),
    SafetySetting(
        category = HarmCategory.HARM_CATEGORY_DANGEROUS_CONTENT,
        threshold = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE),
    SafetySetting(
        category = HarmCategory.HARM_CATEGORY_CIVIC_INTEGRITY,
        threshold = HarmBlockThreshold.BLOCK_LOW_AND_ABOVE)
    ]


# system_instruction：初期設定
# safety_settings：安全性設定の指定
config = types.GenerateContentConfig(
        system_instruction=system_instruction,
        safety_settings = my_safety_settings)        

client = genai.Client(api_key=API_KEY)
chat = client.chats.create(model=MODEL, config=config)

# 対話スタート
while True:
    text = input("ユーザー >>>")
    response = chat.send_message(text, config=config)
    print(response.text)
~~~

**chat.send_message(text, config=config)** と返答を生成する際に、configオプションで諸々の設定を反映させる形になります。これで会話履歴と初期条件、安全性の閾値をコントロールした簡易対話プログラムが完成となります。あとは必要に応じて徐々に拡張できれば面白くなっていくかな:smile::sweat_smile::laughing: