言語学習モデルにおけるOpenAIの関数呼び出しの力:包括的なガイド

OpenAI Function Calls in Language Learning Models Comprehensive Guide

OpenAIの関数呼び出し機能によるデータパイプラインの変換:PostgreSQLとFastAPIを使用したメール送信ワークフローの実装

はじめに

AIのエキサイティングな世界は、OpenAIの最新のLarge Language Models (LLMs)における関数呼び出し機能の導入により、さらに飛躍しました。この新しい機能により、AIと人間の相互作用が、単純な質問応答形式からよりダイナミックかつアクティブな対話に変換されます。

しかし、これらの関数呼び出し機能とは何でしょうか?そのコアとなるものは、入力指示に基づいて、LLMが会話中にあらかじめ定義された関数を呼び出すことを可能にすることです。これは、会話のコンテキストに基づいて、電子メールの送信からデータベースからのデータの取得まで、何でも可能です。関数呼び出し機能の利点と応用は多岐にわたります。顧客サービスからデータパイプラインの構築方法まで、様々なアプリケーションでAIのダイナミックなユーティリティが大幅に向上します。

顧客サービスAIが、リアルタイムで予約の予約、電子メールアドレスへの情報の送信、顧客詳細の更新などのアクションを実行できることを想像してみてください。また、LLMエージェントがコマンドに応じてデータを取得、更新、操作できるデータパイプラインを考えてみてください。

次のセクションでは、これらのアプリケーションをさらに探求し、電子メール送信パイプラインを構築することによって、この新しい機能を活用する手順のステップバイステップガイドを提供します。

Figure 1: LLMs are becoming intelligent agents that we can work with ( image source )

いつでも、コードは私のGithubで利用可能です。

新しい関数呼び出し機能の理解とLangChainとの比較

OpenAIの新しく導入された関数呼び出し機能がAI競争にもたらすものを理解したいと思います。そのために、LangChainなど市場の他のツールやフレームワークとの違いを理解しましょう。このシリーズの最初の記事でLangChainを紹介しました。これは、AIパワードアプリケーションの開発に広く利用されているフレームワークです。関数呼び出し機能とLangChainは、AIをより使いやすく、多様性に富み、ダイナミックにすることを目的に構築されており、ユニークな利点と機能を持っています。

既に述べたように、関数呼び出し機能は、AIアプリケーションに対する追加の相互作用レイヤーを追加します。会話中に事前に定義された関数を呼び出すことで、LLMのダイナミズムとリアクティビティが向上します。この新しい機能は、AIアプリケーションに機能を追加するプロセスを簡素化する可能性があります。開発者はこれらの関数を定義する必要があり、モデルはコンテキストに応じて会話の一部としてそれらを実行できます。ここでの主な利点は、OpenAIモデルとの直接的な統合であり、OpenAIエコシステムに精通している開発者にとって、使用の容易さ、クイックセットアップ、学習曲線の低下を容易にします。

一方、LangChainは、より複雑でデータに精通し、エージェントのようなAIアプリケーションを開発するために設計された包括的で多目的なフレームワークを提供します。言語モデルが環境と相互作用し、高レベルの指示に基づいて決定を下すことを可能にします。モジュールは、モデル、プロンプト、メモリ、インデックス、チェーン、エージェント、コールバックなどのアプリケーションを構築するための抽象化と標準インターフェースを提供します。

LangChainのアプローチは、LLMが異なる相互作用の間で状態を維持し、さまざまなユーティリティをシーケンス化およびチェーン化し、外部データソースとさえ相互作用できるアプリケーションを構築することを容易にします。これらをステロイドで機能呼び出し能力と見ることができます。したがって、言語モデルを活用した複雑な多段階アプリケーションを開発する開発者にとって特に有用です。追加された複雑さの欠点は、完全に使用するためのより急な学習曲線を作成することです。

ユースケース – データパイプラインの変換

私の見解では、LLMsの新しい関数呼び出し機能がデータパイプラインにとって最も興味深いアプリケーション領域の1つです。データパイプラインは、データを収集、処理、配布するデータ駆動型組織の重要なコンポーネントです。通常、これらのプロセスは静的で、事前定義されており、変更や更新には手動の介入が必要です。これが、上記で議論したLLMのダイナミックな動作が機会を生み出す場所です。

従来、データベースクエリにはSQLなどのクエリ言語の特定の知識が必要でした。LLMsが関数、サービス、およびデータベースを直接呼び出す能力を持つことで、ユーザーは明示的なクエリの形成なしに会話形式でデータを取得できます。LLMは、ユーザーの要求をデータベースクエリに変換し、データをフレンドリーな形式で取得してリアルタイムで返すことができます。この機能により、組織内の異なる役割間でデータアクセスが民主化される可能性があります。

データ変換の変化も考えられます。解析の前に、しばしば別々のデータクリーニングと処理手順が必要です。LLMは、ユーザーの指示に基づいてデータクリーニングや操作タスクをインタラクティブに実行することで、このプロセスを効率化できます。また、会話中にリアルタイムデータを操作することで、より探索的で反復的なデータ分析が可能になります。

3つ目のユースケースはデータ監視です。データパイプライン内のデータの正確性と一貫性を確認するために定期的なチェックが必要です。LLMを使用すると、監視タスクをよりインタラクティブで効率的に行うことができます。例えば、LLMは会話中にデータの不一致をユーザーに通知し、直ちに修正措置を取ることができます。

最後に、LLMはデータレポートの作成と配布も自動化できます。ユーザーは特定の基準に基づいてLLMにレポートの生成を指示し、LLMはデータを取得し、レポートを作成し、関連する受信者に送信することさえできます。

OpenAI関数呼び出し機能を使用した電子メール送信パイプラインの構築

ユーザーに電子メールを送信するパイプラインを作成することを目的としています。これは単純な手順のように聞こえるかもしれませんが、LLMによって制御される異なるコンポーネントの相互作用に美しさがあります。AIモデルは、単に電子メールの本文を生成するだけではなく、ユーザー情報を取得するためにデータベースと動的にやり取りし、文脈に適した電子メールを作成し、その後サービスに送信するように指示します。

当社のパイプラインは、PostgreSQL、FastAPI、およびOpenAI LLMの3つの主要なコンポーネントで構成されています。PostgreSQLを使用して、ユーザーデータを格納します。このデータには、ユーザー名と関連する電子メールアドレスが含まれます。これは、ユーザー情報の真実のソースとして機能します。FastAPIは、PythonでAPIを構築するための現代的で高性能なWebフレームワークです。FastAPIサービスを使用して、電子メールの送信プロセスをシミュレートします。サービスが電子メールの送信要求を受け取ると、送信されたことを確認する応答を返します。LLMは、プロセス全体のオーケストレーターとして機能します。会話を制御し、文脈に基づいて必要なアクションを決定し、PostgreSQLデータベースとやり取りしてユーザー情報を取得し、電子メールメッセージを作成し、FastAPIサービスに電子メールを送信するように指示します。

PostgreSQLデータベースの実装

私たちのパイプラインの最初のコンポーネントは、ユーザーデータを格納するPostgreSQLデータベースです。Dockerを使用することで、PostgreSQLインスタンスのセットアップが簡単かつ再現可能になります。Dockerは、データベース環境をコンテナ化して分離することができるプラットフォームです。

PostgreSQL Dockerコンテナを設定するには、まずDockerをインストールする必要があります。インストール後、PostgreSQLイメージをプルし、コンテナとして実行できます。コンテナのポート5432をホストのポート5432にマップしてデータベースにアクセスします。本番環境では、パスワードを環境変数として設定し、以下のようにコマンドに直接設定しないでください。私たちはこの方法でプロセスを加速するために行っています。

docker run --name user_db -e POSTGRES_PASSWORD=testpass -p 5432:5432 -d postgres

PostgreSQLインスタンスが実行されているので、ユーザーデータを格納するデータベースとテーブルを作成できます。初期化スクリプトを使用して、usersテーブルを作成し、usernameemailの列を持つダミーデータでそれを埋めます。このスクリプトはディレクトリに配置され、そのディレクトリがコンテナ内の/docker-entrypoint-initdb.dディレクトリにマップされます。PostgreSQLは、起動時にこのディレクトリにあるスクリプトを実行します。次に、スクリプト(user_init.sql)の内容を示します。

CREATE DATABASE user_database;\c user_database;CREATE TABLE users (    username VARCHAR(50),    email VARCHAR(50));INSERT INTO users (username, email) VALUES    ('user1', '[email protected]'),    ('user2', '[email protected]'),    ('user3', '[email protected]'),    ...    ('user10', '[email protected]');

LLMは、SQLコマンドを理解することができ、PostgreSQLデータベースのクエリに使用できます。たとえば、LLMにuser10にメールを送信するように依頼した場合、LLMは次のクエリを作成できます。

SELECT  email FROM users WHERE username=’user10'; 

これにより、usersテーブルからuser10の電子メールアドレスを取得できます。LLMは、このメールアドレスを使用してFastAPIサービスに電子メールを送信するように指示することができます。

次のセクションでは、メールを送信するFastAPIサービスの実装の手順を説明します。

FastAPIメールサービスの作成

2つ目のコンポーネントはFastAPIサービスです。 このサービスは、メールの送信プロセスをシミュレートします。 受信者の名前、メールアドレス、およびメール本文が含まれたPOSTリクエストを受け取ります。送信されたメールを確認する応答を返します。 当サービスはDockerを使用して、サービスが分離され、再現可能になるようにします。

まず、Dockerをインストールする必要があります(まだインストールされていない場合)。 次に、FastAPIサービス用の新しいディレクトリを作成し、そこに移動します。 ここで、新しいPythonファイル(例:main.py)を作成し、次のコードを追加します。

from fastapi import FastAPIfrom pydantic import BaseModelapp = FastAPI()class User(BaseModel):    name: str    email: str    body: [email protected]("/send_email")async def send_email(user: User):    return {        "message": f"Email successfully sent to {user.name} with email {user.email}. Email body:\n\n{user.body}"    }

このコードは、単一のエンドポイント /send_email/ を持つFastAPIアプリケーションを定義します。 このエンドポイントは、POSTリクエストを受け付け、受信者の名前、メールアドレス、およびメール本文が含まれたJSONボディを期待します。

次に、同じディレクトリにDockerfileを作成し、次の内容を追加します。

FROM python:3.9-slim-busterWORKDIR /appADD . /appRUN pip install --no-cache-dir fastapi uvicornEXPOSE 1000CMD ["uvicorn", "app:app", "--host", "0.0.0.0", "--port", "1000"]

このDockerfileは、python:3.9-slim-buster イメージをベースにイメージを作成するようにDockerに指示します。このイメージは、Pythonアプリケーションを効率的に実行するための軽量のイメージです。その後、main.pyファイルをイメージの/app/ディレクトリにコピーします。

次のコマンドを使用して、Dockerイメージをビルドできます。

docker build -t fastapi_email_service .

そして、次のコマンドで実行できます。

docker run -d -p 1000:1000 fastapi_email_service

LLMは、FastAPIサービスとPOSTリクエストを使用してやり取りします。 LLMがメールを送信することを決定すると、send_email関数への関数呼び出しを生成します。 この関数呼び出しの引数には、名前、メールアドレス、およびメール本文が含まれます。

Pythonスクリプトによって関数呼び出しが処理され、関数引数が抽出され、それらを使用してPOSTリクエストをFastAPIサービスに送信します。 FastAPIサービスは、メールが正常に送信されたことを示すメッセージで応答します。

これで、パイプラインのすべてのコンポーネントが揃いました。 次のセクションでは、PostgreSQLデータベースとFastAPIサービスの間の相互作用をLLMがオーケストレーションしてメールを送信する方法を説明します。

OpenAI LLMとの統合

パイプラインの最後の部分は、OpenAI LLMの統合です。 LLMはオーケストレーターとして機能し、コマンドを解釈し、ユーザー情報をデータベースからクエリし、FastAPIサービスにメールを送信するよう指示します。

スクリプトは、OpenAIのAPIを使用して、LLMとのチャットベースの補完を行います。 各補完リクエストには、モデルが呼び出す可能性のある関数仕様のリストを含めて、一連のメッセージが含まれます。 アシスタントにプロンプトを提供するユーザーメッセージで会話を開始します。

次に、APIにリクエストを送信するために使用するchat_completion_request関数を示します。

@retry(wait=wait_random_exponential(min=1, max=40), stop=stop_after_attempt(3))def chat_completion_request(messages, functions=None, model=GPT_MODEL):    headers = {        "Content-Type": "application/json",        "Authorization": "Bearer " + openai.api_key,    }    json_data = {"model": model, "messages": messages}    if functions is not None:        json_data.update({"functions": functions})    response = requests.post(        "https://api.openai.com/v1/chat/completions",        headers=headers,        json=json_data,    )    return response

会話履歴を管理するChatクラスを使用しています。 新しいメッセージを履歴に追加し、会話全体を表示するメソッドがあります。

class Chat:    def __init__(self):        self.conversation_history = []    def add_prompt(self, role, content):        message = {"role": role, "content": content}        self.conversation_history.append(message)    def display_conversation(self):        for message in self.conversation_history:            print(f"{message['role']}: {message['content']}")

LLMは、PostgreSQLデータベースとFastAPIサービスとのインタラクションが必要です。これらの関数を定義し、完成リクエストに含めます。以下は、sql_query_emailおよびsend_email関数を定義する方法です。

functions = [    {        "name": "send_email",        "description": "新しいメールを送信する",        "parameters": {            "type": "object",            "properties": {                "to": {                    "type": "string",                    "description": "送信先のメールアドレス。",                },                "name": {                    "type": "string",                    "description": "メールを受信する人の名前。",                },                "body": {                    "type": "string",                    "description": "メールの本文。",                },            },            "required": ["to", "name", "body"],        },    },    {        "name": "sql_query_email",        "description": "ユーザーメールを取得するためのSQLクエリ",        "parameters": {            "type": "object",            "properties": {                "query": {                    "type": "string",                    "description": "ユーザーメールを取得するクエリ。",                },            },            "required": ["query"],        },    },]

完成リクエストを行うと、LLMは意図されたアクションを返します。応答に関数呼び出しが含まれている場合、スクリプトはその関数を実行します。たとえば、LLMがsql_query_email関数を呼び出すことを決定した場合、スクリプトはデータベースからユーザーのメールアドレスを取得し、その結果を会話履歴に追加します。 send_email関数が呼び出されると、スクリプトはFastAPIサービスを使用してメールを送信します。

スクリプトのメインループは、LLMの応答で関数呼び出しをチェックし、適切に動作します。

chat = Chat()chat.add_prompt("user", "ユーザー10に、月額サブスクリプション料金を支払う必要があることを伝えるメールを送信してください。")result_query = ''for i in range(2):    chat_response = chat_completion_request(        chat.conversation_history,        functions=functions    )    response_content = chat_response.json()['choices'][0]['message']    if 'function_call' in response_content:        if response_content['function_call']['name'] == 'send_email':            res = json.loads(response_content['function_call']['arguments'])            send_email(res['name'], res['to'], res['body'])            break        elif response_content['function_call']['name'] == 'sql_query_email':            result_query = query_db(json.loads(response_content['function_call']['arguments'])['query'])            chat.add_prompt('user', str(result_query))    else:        chat.add_prompt('assistant', response_content['content'])

スクリプトを実行すると、次の出力が得られます:

{  "message": "ユーザー10に、メールアドレス[email protected]でメールが正常に送信されました。",  "Email body": "\n\nDear User 10, \n\nThis is a reminder that your monthly subscription fee is due. Please make the payment as soon as possible to ensure uninterrupted service. Thank you for your cooperation. \n\nBest regards, \nYour Subscription Service Team"}

この出力を得るために何が起こったかを説明しましょう。私たちのプロンプトは「ユーザー10に、月額サブスクリプション料金を支払う必要があることを伝えるメールを送信してください」となっています。メッセージにはuser10のメールに関する情報が含まれていないことに注意してください。LLMは欠落している情報を特定し、データベースからメールを取得するためにquery_email関数を理解しました。メールを取得した後、再度2つのことを正しく行いました。最初に、メールの本文を生成する必要があること。2番目に、FastAPIメールサービスを使用してメールをトリガーするためにsend_email関数を呼び出す必要があること。

結論

この記事では、LLMがPostgreSQLデータベースとFastAPIメールサービスを組み合わせたパイプラインを調整する場合のケーススタディを実装し、関数呼び出し機能を探求しました。 LLMは、単一のプロンプトに応答して、ユーザーのメールアドレスをデータベースから取得し、パーソナライズされたメッセージを送信するためにメールサービスを指示することに成功しました。

AIモデルにおける関数呼び出しの影響は、プロセスの自動化や効率化の新しい可能性を開くことができ、データパイプラインは静的でエンジニアリングに重点を置くものから動的なエンティティに変わることができ、自然言語を使用して非技術的なユーザーが最新のデータを素早く取得することができるようになります。

大規模言語モデルの年代記:NLPフロンティアの航海

この記事は、「大規模言語モデルの年代記:NLPフロンティアの航海」という新しい週刊シリーズの一部です。この新しい技術にダイブして、開発者、研究者、エンスージアストがNLPの可能性を引き出し、新しい可能性を開くようにすることを目的としています。

これまでに公開された記事:

  1. ChatGPTを使用して最新のSpotifyリリースを要約する
  2. FAISSとSentence Transformersを使用して数百万のドキュメントをインデックスし、ライトニングファストな推論時間でセマンティックサーチをマスターする
  3. Whisper、WhisperX、およびPyAnnotateを使用した高度な転写およびダイアリゼーション
  4. GPU上でのASRパフォーマンスに関する真実を明らかにするWhisper JAX vs PyTorch
  5. 効率的なエンタープライズグレードの音声認識のためのVosk:評価および実装ガイド
  6. 1162の言語をサポートする大規模多言語音声(MMS)モデルのテスト
  7. 最も強力なオープンソースLLMであるFalcon 40Bモデルの利用

連絡先:LinkedIn

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more