見出し画像

ChatGPTとの連携を考えてみる②

はじめに

前回の記事を投稿した後、ChatGPT plugins、Function Calling、Code Interpreterといった様々な機能追加がありました。すでに多くの方が記事にされていますので、ここではすこしだけ触れるに留めて、今回はCode Interpreter APIという非公式のOSSを確認してみました。

連携のための機能は揃った

ChatGPT pluginsとFunction Callingは、いずれも外部サービスとの連携を目的とした機能と考えられます。前者はChatGPT上で外部サービスとの連携を実現するのに対し、後者は自身のシステム上で、GPTの応答結果に基づいた処理を実装するのを支援します。

Function Callingを利用することで、自然言語の指示を、適切な関数呼び出しや引数の選択に変換できます。これにより、タスク志向の対話システムの実装が容易となり、前回の記事で気にしていた点は解消できそうです。

事前に設定した関数群に、指示の内容(意図やエンティティなど)をマッチさせることで、構造化データとして処理できます。これにより、GPTの応答をJSON形式に固定することができるため、対話システムだけでなく、バックグラウンド処理などにも有用と考えます。

一方で、関数の情報量が増加すると、プロンプトの肥大化によってトークン数が増えることが懸念されます。これは処理時間や費用に影響を及ぼす可能性があるため、関数の情報量や粒度の最適化は課題として考慮するべきです。さらに、連続した関数呼び出しの対応、引数としてのJSON SchemaやEnumの適切な指定方法などに関する試行錯誤の様子は、多くの方々の記事から香ってきます。

本家のCode Interpreterについて

Code Interpreterは、ChatGPTのPython実行環境で、アップロードしたファイルの分析や加工を自然言語の指示だけで実行できます。インストール済みのライブラリを使用して、探索的データ解析や機械学習を簡単な指示で行うことができ、最適な方法を自動的に選択します。さらに、使用したコードも提示されるため、学習コストが削減され、ノーコードの普及を促進するでしょう。現時点ではβ版として提供されており、Plusの契約をしているユーザーのみが利用可能です。

Code Interpreterを有効化して、ChatGPTに「この環境のCPUやメモリの情報を教えて」と確認したところ、以下のように応答しました。

CPU情報:

アーキテクチャ: x86_64
CPUモード: 32-bit, 64-bit
バイトオーダー: Little Endian
アドレスサイズ: 46ビット(物理), 48ビット(仮想)
CPUの数: 16
オンラインのCPUリスト: 0-15
ベンダーID: GenuineIntel
CPUファミリー: 6
モデル: 85
モデル名: 不明
ステッピング: 不明
CPU MHz: 2095.192
BogoMIPS: 2095.19
仮想化: VT-x
ハイパーバイザーベンダー: Microsoft
仮想化タイプ: full

メモリ情報:

合計: 62Gi
使用中: 274Mi
空き: 62Gi
キャッシュ: 29Mi
利用可能: 62Gi
スワップ: 0B (使用していません)
import os

# Get CPU information
cpu_info = os.popen('lscpu').read()

# Get memory information
mem_info = os.popen('free -h').read()

cpu_info, mem_info

ユーザーごとのリソースの分配方法を確認したところ、以下のように応答しました。

この環境は仮想的なものであり、各ユーザーは専用のインスタンスを持ちます。
したがって、他のユーザーの活動によってリソースが影響を受けることはありません。
OpenAIが提供するChatGPTのバックエンドは、
各ユーザーセッションにリソースを動的に割り当てることで、
隔離された環境を提供します。

これが正しい情報であるならば、セキュリティやパフォーマンスについて一定の考慮がなされているようです。
外部との接続も制限されているため、現時点では個人利用が主となり、直接的な連携はできませんが、一方で、これらの制限を回避してしまう非公式のOSSが出ています。

Code Interpreter APIを試してみる

Code Interpreter API(LangChainを使用)は、OpenAIのライセンスキーがあれば、Plusのユーザーでなくとも、ローカルPCのPython実行環境などを使用して、Code Interpreterを模した処理の実行を可能にするものです。すでに試されている方もいますが、どのようなものか確認してみました。

確認はGoogle ColabとローカルPC(Windows)で行いました。Colabの方が環境を気にせず簡単に試せます。

まずは一式を取得します。

!git clone https://github.com/shroominic/codeinterpreter-api
!pip install "codeinterpreterapi[all]"

「codeinterpreter-api」ディレクトリに移動し、環境変数を設定する「.env」を作成します。

%cd /content/codeinterpreter-api/
!cp .env.example .env

「.env」を編集して、自身のOPENAI_API_KEYを設定します。実行ログを確認するためにVERBOSEをTrueにします。(Colabでは隠しファイルの編集がエラーになったため、一時的にファイル名をリネームして編集しました)

# (set True to enable logging)
VERBOSE=True

# (required)
OPENAI_API_KEY=XXXXX

サンプルプログラムが実行できるようになります。

!python examples/analyze_dataset.py

サンプルでは以下のように、プロンプトとファイルを指定することで、アヤメのデータの分析を行わせています。

user_request = "Analyze this dataset and plot something interesting about it."
files = [
    File.from_path("examples/assets/iris.csv"),
]

Colabではブラウザが起動できず、画像が表示されませんでしたが、ローカルPCでは1~2分ほどかかって、以下の画像が生成されました。(本家のCode Interpreterでも同様の画像が得られました)

「analyze_dataset.py」のプロンプトを以下のように修正することで、Colab上でも同じファイルが作成されました。

"このデータを分析して、興味深い内容をプロットして。ファイルは/content/iris.pngとして保存して。"

また、Colabには多くのライブラリがインストール済みですが、あえて削除すると、処理中に自動で必要なライブラリのインストールを始めます。便利である反面、環境の汚染やセキュリティリスクが懸念されますので、ローカル環境で実行する場合はvenvやコンテナ上で実行すべきでしょう。

Error:
 ModuleNotFoundError: No module named 'seaborn'
Running code:
 !pip install -q seaborn
Output:
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 293.3/293.3 kB 4.2 MB/s eta 0:00:00

ここからは、プロンプトを変更しながら実行してみます。以下の記事を参考にさせていただきました。

弊社の株価を確認してみました。(株価コードを含めないと、まったく異なる会社の株価になってしまいます)

from codeinterpreterapi import CodeInterpreterSession

async with CodeInterpreterSession() as session:
    response = await session.generate_response(
        "2023/1/1から現在までのウイングアーク1stの株価(株価コード4432)をプロットして"
    )

    print("AI: ", response.content)
    for file in response.files:
        file.show_image()

特に指示せずともYahoo! FinanceのAPIを使用して、最新の株価データを取得しに行きます。(プロンプトが日本語の場合、応答も日本語になる場合とならない場合があり、安定しない感じです)

Starting kernel...
Waiting for kernel to start...
DEPRECATION WARNING: Use agenerate_response for async generation.
This function will be converted to sync in the future.
You can use generate_response_sync for now.


> Entering new AgentExecutor chain...

Invoking: `python` with `{'code': "import yfinance as yf\nimport matplotlib.pyplot as plt\n\n# Download stock data\nstock = yf.download('4432.T', start='2023-01-01')\n\n# Plot the close price\nplt.figure(figsize=(14, 7))\nplt.plot(stock['Close'])\nplt.title('Wing Arc 1st Stock Price')\nplt.xlabel('Date')\nplt.ylabel('Close Price (JPY)')\nplt.grid(True)\nplt.show()"}`


import yfinance as yf
import matplotlib.pyplot as plt

# Download stock data
stock = yf.download('4432.T', start='2023-01-01')

# Plot the close price
plt.figure(figsize=(14, 7))
plt.plot(stock['Close'])
plt.title('Wing Arc 1st Stock Price')
plt.xlabel('Date')
plt.ylabel('Close Price (JPY)')
plt.grid(True)
plt.show()
Running code:
 import yfinance as yf
import matplotlib.pyplot as plt

# Download stock data
stock = yf.download('4432.T', start='2023-01-01')

# Plot the close price
plt.figure(figsize=(14, 7))
plt.plot(stock['Close'])
plt.title('Wing Arc 1st Stock Price')
plt.xlabel('Date')
plt.ylabel('Close Price (JPY)')
plt.grid(True)
plt.show()
Output:
 [*********************100%%**********************]  1 of 1 completed

Output:
 [*********************100%%**********************]  1 of 1 completed


Image image-124b60db-c2ee-4487-ba87-9c2dcfb40cbd.png got send to the user.Here is the plot of the closing price of Wing Arc 1st (stock code 4432) from January 1, 2023, to the present. Please note that the data is subject to the availability from the Yahoo Finance API.

> Finished chain.
AI:  Here is the plot of the closing price of Wing Arc 1st (stock code 4432) from January 1, 2023, to the present. Please note that the data is subject to the availability from the Yahoo Finance API.

以下のような指示にも対応してくれました。

"2023/1/1から現在までのウイングアーク1stの株価(株価コード4432)と、日経平均の変動を比較できるグラフを作成して"

プロンプトを変更することで、短期および長期の移動平均のトレンドを比較したり、相関係数を計算することもできました。

尚、「ファイルを保存して」と指示すると、以下の場所に画像ファイルが作成されます。基本的に利用データや生成物は「.codebox」内に保存されるようです。

/content/codeinterpreter-api/.codebox/wing_arc_1st_stock_price.png

ただし指示によっては、別のディレクトリにも保存できたり、参照できたりしますので、こうした点からもサンドボックス化の考慮が必要になりそうです。
また、「ファイルを削除して」という指示には、以下のような応答がありましたので、全ての指示を実行できる訳ではなさそうです。(GPTの応答で拒否されているか、Code Interpreter APIのAgent側で何かしら制限しているのかもしれません)

すみませんが、現在のバージョンのアシスタントは、ファイルの保存やフォルダの削除などのファイル操作をサポートしていません。
また、セキュリティ上の理由から、このような操作は一般的に推奨されません。

実行環境は「CodeBox」という領域が使用されるようですが、CODEBOX_API_KEYを設定しなければ、ローカル環境が使用されます。
基本的にはクラウド上の実行環境(有料)の利用を前提としているように見受けられますが、現在はまだ整備中のようです。 将来的にはベクトルデータベースも利用可能になるとのことです。

INFO: Using a LocalBox which is not fully isolated
      and not scalable across multiple users.
      Make sure to use a CODEBOX_API_KEY in production.
      Set envar SHOW_INFO=False to not see this again.

以下のように、クローリングやスクレイピング、認証が必要なAPIの実行などはできないため、期待する応答にはなりませんでした。できること、できないことの境界が掴みにくいです。

USER:  次のサイトを100文字に要約してください https://ja.wikipedia.org/wiki/ウイングアーク1st

AI:  申し訳ありませんが、現在の私のバージョンはウェブサイトの内容を直接スクレイピングする機能を持っていません。しかし、あなたがそのウェブサイトの特定の部分をコピーしてここに貼り付ければ、私はそれを要約することができます。
USER:  現在のTwitter(X)のトレンドワードをワードクラウドで表示して

AI:  申し訳ありませんが、現在のバージョンのAssistantはTwitterのAPIに直接アクセスすることはできません。そのため、Twitterのトレンドワードを取得してワードクラウドを作成することはできません。
ただし、Pythonのライブラリを使用してTwitterのAPIにアクセスし、トレンドワードを取得し、それを使用してワードクラウドを作成することは可能です。そのためには、`tweepy`というライブラリと`wordcloud`というライブラリが必要です。
以下にその一例を示します。ただし、このコードはTwitterのAPIキーが必要で、また`tweepy``wordcloud`がインストールされている必要があります。

感想

Pythonプログラムで簡単な指示を与えるだけで、Webから必要な情報を収集して、分析結果のファイルを作成してくれますので、以下のようなファイルを仲介した連携もできそうです。

一方で課題もあり、本家のCode Interpreterが制限を設けている点も改めて理解できます。まだ実用の段階ではありませんが、可能性は多いに感じました。




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