2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

GPT Assistantsに日本語フォントを使わせる OpenAI API Code Interpreter コードインタープリター

Last updated at Posted at 2023-12-29

新APIで登場したGPTのAssistants

2023年11月にOpenAIのAPIがリニューアルされAssistantsという機能が追加されました。

今まではGPTのAPIを利用する際にはモデル名(GPT-3.5など)、インストラクション(「英語教師になってください」など)を指定する必要があったのですが、これらをまとめてAssistantとして登録できるようになり、そのアシスタントのIDがあればいちいちこのような指定が不要となりました。

Snapshot_23.PNG
※OpenAIマイページ"Assistants"画面

まさに 「GPTはあなたのアシスタントですよ」 とOpenAIは言わせたいようです。

Assistants APIはβ版です。今後記述方法は変更がありそうです。

Assistantにファイルを渡す

Assistantにはファイルを持たせることができます。

最初は「なんでファイルを?」と思ったのですが、よく使うコード表であったり利用する可能性高いデータを持たせておけるので、いちいち毎回アップして渡す必要がなくなります。

「秘書に資料を持たせる。」 みたいなイメージで使うことができるようです。


渡し方は2つあり、1つは上記Assistants画面のFilesから追加

Snapshot_24.PNG

またはAPIを利用してアップ(※後述)


アップできるファイル形式はtxtなどはもちろんdocxなども渡すことができます。 https://platform.openai.com/docs/assistants/tools/supported-files

Assistantにフォントファイルを渡す

で、今回の目的は日本語フォントファイル(拡張子.ttf)を使わせることです。上記の方法で渡せばよいのですが、現在サポート対象外で.ttfのファイルは渡すことができません。

そもそも今更ですが、なぜフォントファイルを渡したいかというとコードインタープリターを使ってグラフを描いてもらうときタイトルと軸が日本語の際に文字化けしてしまうからです。

a8ea56f6-b398-46c6-91ec-0664428f14cc.png


これはChatGPT Plus(月20ドルの有料版)でも起こっていた問題で、日本語のフォントファイルがGPTのPython環境にないことが原因のようです。なので正しいフォントファイルさえあればこの文字化けが防げるようです。(GPTがPythonのmatplotlibでグラフを描く際に日本語フォントが使えればよい)


で、戻りましてどうしても.ttfのファイルが渡したいのでZIPにして渡してあげます。(ZIPで渡せるなら.ttfでも渡せるようにしろ!って思っちゃいますが現在の仕様なので仕方ありません)

フォントはなんでもよさそうですが今回はGoogleのフォントNoto Sans JPを使います。(ダウンロードは[Download family]から)
https://fonts.google.com/noto/specimen/Noto+Sans+JP

このうちのなんでもいいのですがNotoSansJP-Boldを渡してみます。NotoSansJP-Bold.ttfをzip化しNotoSansJP-Bold.zipとしてアップ。APIを利用してみます。

OpenAIインストール
!pip install openai
OpenAI接続
from openai import OpenAI
import os

# APKIキーのセットとクライアント接続
os.environ["OPENAI_API_KEY"] = 'sk-*********************'

client = OpenAI()
ファイルのアップ
file_response = client.files.create(
    purpose="assistants",
    file=open("NotoSansJP-Bold.zip","rb"),
)

# IDの取得
file_id = file_response.id

print(file_id)
file-eTKaOgE2EY3xPSq9L1Cswzgo

次にこのファイルをアシスタントに渡します。アシスタントは新しく作成した方が早いですが今回は既存のアシスタントに渡すことにします。

※新規のアシスタント作成方法はこちらから
https://qiita.com/nekoniii3/items/7128e1d0cec06e3ff6a4

アシスタントへファイルを渡す
assistant = client.beta.assistants.update(
    assistant_id="asst_KLliLgmfXBEVigIvYV65bDnD"  # 既存のアシスタントID
    ,file_ids=[file_id]  # 先ほどのファイルID "file-eTKaOgE2EY3xPSq9L1Cswzgo"
)

アシスタントへフォントの指示

あとはアシスタントにフォントファイルを使ってもらうだけです。

ただグラフなどのメインの指示とフォントの指示を同時に行うと、失敗する可能性が高いので、まずフォントの解凍の指示のみ行うことをおすすめします。
※回答取得までは前々回の記事と同じです

①スレッドの作成
thread = client.beta.threads.create()
②message作成(フォントの取得)
prompt = "まずNotoSansJP-Bold.zipを解凍してNotoSansJP-Bold.ttfを取得して下さい。"

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content=prompt
)
③RUN作成
assistant_id = "asst_KLliLgmfXBEVigIvYV65bDnD"

run = client.beta.threads.runs.create(
  thread_id=thread.id,
  assistant_id=assistant_id
)
④RUNの実行状態を受け取る
run = client.beta.threads.runs.retrieve(
  thread_id=thread.id,
  run_id=run.id
)

print(run.status)
⑤message受け取り
messages = client.beta.threads.messages.list(
  thread_id=thread.id,
  order = "asc"
)
⑥message表示
for msg in messages:
    print(msg.role + "" + msg.content[0].text.value)
user:まずNotoSansJP-Bold.zipを解凍してNotoSansJP-Bold.ttfを取得して下さい。
assistant:NotoSansJP-Bold.zipファイルからNotoSansJP-Bold.ttfファイルを取得しました。ファイルの準備ができましたので、ご質問があればお知らせください。

正常に解凍してフォントファイルの取得ができたようです。
あとはグラフを描いてもらう際にNotoSansJP-Bold.ttfを使ってもらうだけです。

データファイルのアップ
file_response = client.files.create(
    purpose="assistants",
    file=open("HIKAKIN再生回数推移.csv","rb"),
)

file_id = file_response.id
message作成(グラフ作成の指示)
prompt = "次のファイルはある人気YouTuberの総再生回数のデータです。こちらを棒グラフにして下さい。\
タイトル・各軸名はNotoSansJP-Bold.ttfを使って日本語にして下さい。縦軸の単位は万にしてください。"

message = client.beta.threads.messages.create(
    thread_id=thread.id,
    role="user",
    content=prompt,
    file_ids=[file_id]
)

③RUN作成~⑤message受け取りはフォントの指示の時と同じコードを実行。

messages表示(image_fileのIDも取得)
for msg in messages:

    print(msg.role + "")

    if msg.role == "assistant":

        for content in msg.content:

            image_fileid = ""
            assist_msg = ""

            cont_dict = content.model_dump()  # 辞書型に変換

            if cont_dict.get("image_file") is not None:

                image_fileid = cont_dict.get("image_file").get("file_id")

                print(f"ファイルID:{image_fileid}")

            if cont_dict.get("text") is not None:

                assist_msg = cont_dict.get("text").get("value")

                print(assist_msg)

    else:

        print(msg.content[0].text.value)

user:
次のファイルはある人気YouTuberの年別の総再生回数のデータです。こちらを棒グラフにして下さい。タイトル・各軸名はNotoSansJP-Bold.ttfを使って日本語にして下さい。縦軸の単位は万にしてください。
assistant:
ファイルID:file-ufUPttZASrhmPITuXKrjZ3HF
上記が、年別の総再生回数を示す棒グラフです。また、縦軸の単位は「万」となっております。他にも何かお手伝いできることがありましたら、遠慮なくお知らせください。

では、ファイルIDからグラフの画像を取得してみます。
ファイルの取得
image_fileid = "file-ufUPttZASrhmPITuXKrjZ3HF"

retrieve_file = client.files.with_raw_response.retrieve_content(image_fileid)

content = retrieve_file.content

# ファイル名は適当に付けて下さい
with open(image_fileid + ".png", 'wb') as f:
    f.write(content)

取得した画像です。

file-ufUPttZASrhmPITuXKrjZ3HF.png


タイトル・各項目を日本語で表示させることができました!

おわりに

長々書きましたが、要は日本語フォントをZIPにして渡してあげるだけです。
今のところβ版なので、今後はもっと簡単になることに期待します!

宣伝

コードインタープリターが使えるチャットアプリを作ったのでよかったら試してみてください! ※テスト中はAPIキーなしで利用できます。

ソースはこちら(現在Colabファイルのみ)

動画でのAssistants APIの紹介もあります!

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?