2023年6月27日火曜日

ChatGPT PluginをGeneXusで作ってみた。

 ずいぶん前に申請していたChatGPTのPlugin developerがようやく招待されたので試してみました。


まずはPlugin Quick Startとして公開されているサンプルを使って実装しました。ソースは以下のGithubになります。(実装および動作確認はここでは省略します)

https://github.com/openai/plugins-quickstart

サンプルがうまく動作したら、同じものをGeneXusを使って実装してみました。サンプルでは登録したTodoデータはメモリ上にしか保持しない仕様になっていますので、サービスを再起動するとデータは失われてしまいます。GeneXusで同じ機能を実装するのであれば、Todoデータはデータベースに登録しておきたいですよね。

という事で、ナレッジを新規作成したらまずはTodoトランザクションを定義します。


  • 主キーはユーザー名+TodoNoの複合キー
  • Todo(Description)以外に完了予定日(DueDate)、完了フラグ(IsDone)、完了日(DoneDate)を追加

続いてAPIオブジェクトを作成し、I/Fを定義します。


サンプルでは、Todo一覧取得、Todo登録、Todo削除だけでしたが、DB化するのでTodo更新機能も追加し、Todo内容の変更や完了登録が出来るようにします。

あとは、それぞれのAPIに対応するプロシージャオブジェクトとパラメータであるSDTを作成します。このあたりは通常のGeneXus開発と変わりませんので、内容の紹介は割愛しますが、サンプルと比較して違う点だけ書き留めておきます。

  • サンプルでは機能ごとにHTTP Methondを指定していました。例えば、Todo削除はDELETEなど。GeneXusのAPIオブジェクトでもRestMethodのアノテーション記述が出来るのですが、DELETE指定の場合、ChatGPTとの連携がうまく出来ませんでした。従って、上記のAPIオブジェクト定義では登録・更新・削除は全てPOSTにしています。
  • サンプルのTodo登録機能では、ユーザー名はHTTPパラメータ、TodoはPost valueと使い分けているのですが(HTTPパラメータはURLRewriteでパス(=ユーザー名)にマッピングさせるため)、GeneXusのプロシージャオブジェクトは、パラメータは全てPost valueになるのと、ユーザー名はプリミティブ変数、その他Todo項目はSDTという複数パラメータがうまく認識されなかったので、送信データは全て一つのSDTに纏めています。



基本的には以上でプラグイン機能の出来上がりです。ビルドしてPostMan等のRestテストツールで動作確認をします。


次にChatGPT Pluginとして登録するのに必要なファイルの定義です。

  • マニフェストファイル(ai-plugin.json)
    • ChatGPTがPluginをインストールした時に読み込むファイルで、Pluginの基本的な説明と、APIの定義情報が書いてあるyamlファイルの場所、ロゴ画像ファイルの場所が記述してあります。こちらはほぼサンプルと同じ内容で場所の指定のみPluginを配置するサーバーの内容に変更しました。
  • yamlファイル(openapi.yaml)
    • APIのインターフェース定義がされているyamlファイル(Open API Documentフォーマット)です。
    • 今回、一番ハマったのはこのファイルでした。yamlファイルはGeneXusでもAPIを作成するとビルド時に自動生成してくれますが、フォーマットは同じでも記述内容が微妙にChatGPTが要求するものと違っており、トライ&エラーで動作するようになりました。以下、ポイントです。
      • operationId GeneXusが生成する内容は「APIオブジェクト名.API名_メソッド」という書式ですが、ChatGPTでは「.」ドットは受け付けておらず、アンダースコアに変更する必要がありました。
      • schema  パラメータをSDTとして定義する場合、GeneXusはyamlの定義をAPI定義→(参照)→パラメータ定義→(参照)→SDT定義(JSONオブジェクト)という風に三段階の参照($ref)で定義します。これがChatGPTでは認められず、二段階(一つの参照のみ)に変更する必要がありました。且つ、type:objectが不足していましたので、こちらも手動で追加しました。
      • description ChatGPTがどうPluginを使うか? はdescriptionの書き方に依存します。特にパラメータとなる各項目の説明は単に名称だけだとこちらの想定通りの挙動にならず(もちろん、名前から推測はしてくれますが)、特に更新や削除をする時に主キー項目は、「データ取得時の主キー項目を使い回すように」といった念押しのような説明の記載をしないと、ChatGPTが適当な値を主キーとして設定するため、更新が空振りしてしまう事態となりました。
  • アイコンファイル
    • Pluginリストや選択時のPluginを識別するためのアイコン画像です。今回は、サンプルにあったTodoアイコンの背景画像をGeneXusっぽく赤色に変更したものを使ってみました。

Pluginに必要なファイルが出来たらデプロイしたアプリの然るべき場所に配置します。

いよいよ、ChatGPTにPluginをインストールします。Plugin developerとして認証されると、Plugin storeにオプションが増え、未認証のPluginや自分で開発したPluginを自由にインストール・使用する事ができるようになります。Pluginをデプロイしたurlを指定します。(Pluginの呼び出しはブラウザ上で行われているようで、localhostも指定出来ます)




では、使ってみましょう。


この様に、TODOリストの一覧表し、登録、更新、削除が会話ベースで行えます。さらに、今回のPluginはユーザー名を主キーとしてテーブルを作成してあるので、ユーザーを切り替えて使う事も出来ます。(認証の仕組みは作っていないので、自動的な設定は出来ていませんが)



色々と試してみて判ったのは、ChatGPT自体が代名詞や文脈を理解するので、Todo情報を正確に記載しなくても「期限は来週月曜日」とか「完了日は昨日」といった指示する側が日常会話レベルの内容でも正しく動作してくれるのがAIらしい使い方だと思いました。


テキストベースではありますが、自然言語でPluginアプリが操作できるという事は、例えばスマホの音声入力を使えば、いちいちキーボーとから打ち込まなくても話し言葉でアプリが操作できますし、その応用編としてはAmazon AlexaやGoogle Echoといったスマートスピーカーに組み込む事が出来るようになれば「何を言っているのか判りません」といったつれない返事によるイライラから解消されるかもしれません。ChatGPT Pluginが飛躍的に活用されるのはこんなユースケースな気がしました。


何かアイディアが思いついたら新しいPluginを作ってみたいと思います。

では。



0 件のコメント:

コメントを投稿