🔌

複数の ChatGPT プラグインを開発し AI オーケストレーションを実行するサンプルコード

2023/07/03に公開

今回は Copilot stack のカスタマイズの中心となるプラグイン開発について紹介します。

Copilot stack

Copilot stack は大規模 LLM をオーケストレーターとして利用し、複数のプラグインや外部システムの情報と連携させて GPT-4 のプラグイン機能や Microsoft の各製品に搭載される Copilot と連携したり独自の Copilot を開発できるフレームワークです。

https://qiita.com/nohanaga/items/c3e92c9adeca7c84a8d5

プラグイン開発

ChatGPT 規格のプラグインを開発すれば、以下のようにブラウザ版 GPT-4 だけでなく、Bing や Microsoft 365 Copilot、Windows Copilot などからも利用可能になります。当然、組織独自の Copilot と統合することもできます。このプラグインによって、最新の情報や組織内のデータを反映させた(Grounding)回答を行ったり、ReAct などのタスクを実行させることが可能になります。Microsoft では、業界全体の連携を推進するために、プラグインの標準として OpenAPI プラグイン仕様の採用を進めています。

複数のシステムをプラグイン化する

はい、いつもの戦国武将ネタでデモを行おうと思います。コードはデモ用に極限までシンプル化しています。

今回はこのような 2 つの異なるシステムを ChatGPT プラグインとして公開し、これを AI オーケストレーターである Langchain から呼ぶデモを構築します。

源範頼に関連するカフェ名を検索して、7/1の18時に予約に空きがあるか教えて。もし空いていたら予約しておいて。」というユーザーからの指示に回答できるようなシステムを構築します。

開発するプラグインとエンドポイント

  • 武将カフェ検索プラグイン: カフェ検索システム
    • /search カフェ検索
  • レストラン予約プラグイン: レストラン予約システム
    • /search 予約検索
    • /reserve 予約

フロー解説

  1. UI からユーザーの指示が投げられます。
  2. クエリは LangChain が受け取り、ZERO_SHOT_REACT_DESCRIPTION Agent が Reasoning を行います。
  3. 武将カフェ検索プラグインにアクセスし、 API 仕様をロードし、エンドポイントの情報と説明書きを受け取ります。その結果、検索ができそうだと判定します。実際に検索するには、「GET リクエストを /search エンドポイントに送信して、クエリパラメータとしてカフェの名前を指定する必要があります。」と考えて、「源範頼」を 5005 番ポートに検索リクエストを投げます。
  4. 次にレストラン予約プラグインを呼び出して、「カフェかば殿」で 7/1 の 18 時に予約が可能かどうかを確認します。「そのためには、/search エンドポイントをGETリクエストで使用します。パラメータとして q (レストラン名)と datetime (日時)を必要とします。」と考えます。5006 ポートにアクセスして、カフェ名と空き状況の情報を検索してます。
  5. このカフェでは予約可能であることが確認できましたので、今度は /reserve エンドポイントに POST リクエストを送信して予約を行います。OK が返ってきましたので予約完了です。
  6. 最後に UI に「カフェかば殿で 7/1 の 18-19 時で予約を行いました」と返却します。

AIPluginTool へプラグインをロード

llm = ChatOpenAI(model_name="gpt-4-0613", temperature=0)
tools = load_tools(["requests_all"])
plugin_urls = ["http://localhost:5005/.well-known/ai-plugin.json", "http://localhost:5006/.well-known/ai-plugin.json"]

tools += [AIPluginTool.from_plugin_url(url) for url in plugin_urls]

Agent の初期化

制約条件や言語の設定をプロンプトに含めています。

SUFFIX = """
'Answer should be in Japanese. Use http instead of https for endpoint.
If there is no year in the reservation, use the year 2023. 
"""

# Responsible AI MetaPrompt
#**IMPORTANT**
#If a restaurant reservation is available, must check with the user before making a reservation if yes.'

agent_chain = initialize_agent(tools,
                            llm,
                            agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True,
                            agent_kwargs=dict(suffix=SUFFIX + prompt.SUFFIX))

Function calling

gpt-4-0613gpt-3.5-turbo-0613 の最新モデルでは Function calling 機能が追加され、これまでAgent 、プロンプトでやっていた必要なツールの選定をモデル側でやってくれます。Langchain ではいち早く連携され、AgentType.OPENAI_FUNCTIONS と指定するだけで利用することができます。コチラを使うと Reasoning 全体の速度がめちゃくちゃ速くなります。

import langchain
langchain.debug = True

agent_chain = initialize_agent(tools,
              llm,
              agent=AgentType.OPENAI_FUNCTIONS, verbose=True)

AgentType.OPENAI_MULTI_FUNCTIONS を使用すると呼び出しを並列化してコストを削減することもできます。

langchain.debug = True を設定すると LangChain によって隠蔽化されているリクエストの中身を見ることができるので便利です。

※Azure OpenAI では Function calling 機能についてはもう間もなく対応します。

AI 安全性

このデモでは単純化するために、ユーザーへの確認プロセスなどを省いていますが、AI の安全性、 Responsible AI の観点から実際にアクションを実行する直前には人間からの最終確認のプロセスを導入することも検討してください。

今後

Azure AI Studio が使えるようになると、このような AI オーケストレーターをクラウド上で構築し、テストやエンドポイントのデプロイまでできるようになります。早く使えるようになって欲しいです。

サンプルコードと Notebook

https://github.com/nohanaga/busho-plugins-demo

このデモだけのために究極に単純化したコードを Github に上げておきましたのでご参考まで。この部分、複数の社内システムですとか、開発した機械学習モデルですとかと繋げてみていただければできることが非常に広がるのではないでしょうか。

Discussion