はじめに
今回は、最近リリースされたOpenAIのAgents SDKを紹介する。いま流行りのAIエージェントを作るためのフレームワーク(Pythonライブラリ)である。
環境構築(概略)
まず最初にOpenAIのアカウントを作り、APIキーを作成しておく。次に、「openai-agents」をインストールする。詳細なインストール手順は本家を見てほしい。
サンプルプログラム
本家にアップされているREADME.mdに簡単なサンプルが3つ掲載されている。
- Hello world example
- Handoffs example
- Functions example
それぞれを少しずつアレンジして紹介する。
Hello world example
ユーザの質問に何でも答えるエージェントを作る。サンプルプログラムは以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# _/_/_/ 何でも答えてくれるアシスタント import os from agents import Agent, Runner, set_tracing_export_api_key import src.access_key as access_key os.environ["OPENAI_API_KEY"] = access_key.OPENAI_API_KEY set_tracing_export_api_key(access_key.OPENAI_API_KEY) if __name__ == "__main__": agent = Agent(name="Assistant", instructions="You are a helpful assistant.") result = Runner.run_sync(agent, "川端康成の有名な小説の中から一つ選び、その書き出しを教えてください。") print(result.final_output) |
他のサンプルとも共通するエージェントの作成と実行の基本が書かれている。
- 9行目と10行目:APIキーを環境変数にセットする。
- 13行目:クラスAgentのインスタンスを作成する。
- 14行目:クラスRunnerのクラスメソッド
run_sync
を実行する。
run_sync
は、その名称から分かる通り同期処理を行うメソッドである。他のサンプルでは非同期処理も登場する。上のプログラムの出力は以下の通り。
1 2 3 4 5 |
川端康成の有名な小説の一つ「雪国」の書き出しを紹介します。 「国境の長いトンネルを抜けると雪国であった。」 この一文は非常に有名で、作品全体の雰囲気を象徴する役割を果たしています。 |
Handoffs example
handoffとは「引き継ぎ」と言う意味である。つまり、リクエストを見て適当なエージェントに回答を任せるということである。例えば、リクエストが日本語の場合は日本語エージェントに、リクエストが英語の場合は英語エージェントに引き継ぐ。これを実現するプログラムは以下の通り。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
# _/_/_/ 適切なエージェントにリクエストを転送するエージェント import asyncio import os from agents import Agent, Runner, set_tracing_export_api_key import src.access_key as access_key os.environ["OPENAI_API_KEY"] = access_key.OPENAI_API_KEY set_tracing_export_api_key(access_key.OPENAI_API_KEY) SPANISH_AGENT = Agent(name="Spanish agent", instructions="You only speak Spanish.") JPANENSE_AGENT = Agent(name="Japanese agent", instructions="You only speak Japanese.") ENGLISH_AGENT = Agent(name="English agent", instructions="You only speak English.") TRIAGE_AGENT = Agent( name="Triage agent", instructions="Handoff to the appropriate agent based on the language of the request.", handoffs=[SPANISH_AGENT, JPANENSE_AGENT, ENGLISH_AGENT], ) async def main() -> None: # 日本語で聞けば日本語エージェントに転送される。 # reslt = await Runner.run(TRIAGE_AGENT, "こんにちは、お元気ですか") # 英語で聞けば英語エージェントに転送される。 # reslt = await Runner.run(TRIAGE_AGENT, "Hello, Hou are you?") # スペイン語で聞けばスペイン語エージェントに転送される。 reslt = await Runner.run(TRIAGE_AGENT, "Hola, ¿cómo estás?") print(reslt.final_output) if __name__ == "__main__": asyncio.run(main()) |
- 13行目:スペイン語エージェントを作る。
- 14行目:日本語エージェントを作る。
- 15行目:英語エージェントを作る。
- 16行目:エージェントを選定するエージェントを作る。triageとは選別・選定の意。19行目で各エージェントを渡していることに注意する。
- 23行目:非同期で実行されるメイン関数の定義
- 24行目から33行目:特定の言語でリクエストを投げる(
Runner.run
の実行)。await
があるから、全ての処理が終わるまでこの関数で待つ。 - 37行目:非同期でメイン関数を実行する。
出力は以下の通り。
日本語の場合
1 |
こんにちは、元気です。あなたはどうですか? |
英語の場合
1 |
Hello! I'm good, thank you. How are you? |
スペイン語の場合
1 |
¡Hola! Estoy bien, gracias. ¿Y tú? |
Functions example
ユーザが定義した関数を呼び出すエージェントを作ることができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# _/_/_/ 質問内容から必要な語句を取り出すエージェント import asyncio import os from agents import Agent, Runner, function_tool, set_tracing_export_api_key import src.access_key as access_key os.environ["OPENAI_API_KEY"] = access_key.OPENAI_API_KEY set_tracing_export_api_key(access_key.OPENAI_API_KEY) @function_tool def get_country(country: str) -> str: return f"{country}の首都は東京です。" agent = Agent( name="Hello world", instructions="You are a helpful agent.", tools=[get_country], ) async def main() -> None: result = await Runner.run(agent, input="日本の首都は何ですか") print(result.final_output) if __name__ == "__main__": asyncio.run(main()) |
- 13行目から15行目:エージェントが呼び出す関数を定義する。
- 21行目:Agentのインスタンスを作るとき引数として上の関数
get_country
を渡す。
上のプログラムを実行すると、入力プロンプト「日本の首都は何ですか」から「日本」を抽出し、これを変数country
に代入し、15行目の文章が作られる。出力は以下の通り。
1 |
日本の首都は東京です。 |
応用例
README.mdに書かれていない応用例として、外部ツールを呼び出し今日の天気を返してくれるエージェントを作る。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# _/_/_/ 今日の天気予報を教えてくれるエージェント import asyncio import os from deep_translator import GoogleTranslator import requests from agents import Agent, Runner, function_tool, set_tracing_export_api_key import src.access_key as access_key os.environ["OPENAI_API_KEY"] = access_key.OPENAI_API_KEY set_tracing_export_api_key(access_key.OPENAI_API_KEY) OPENWEATHERMAP_API_KEY = access_key.OPENWEATHERMAP_API_KEY def translate_text(text: str) -> str: translator = GoogleTranslator(source='auto', target='en') result = translator.translate(text) return result @function_tool def get_weather(city: str) -> str: eng_city = translate_text(city) url = f"http://api.openweathermap.org/data/2.5/weather?q={eng_city}&appid={OPENWEATHERMAP_API_KEY}&units=metric" response = requests.get(url) if response.status_code == 200: data = response.json() weather_description = data["weather"][0]["description"] temp = data["main"]["temp"] temp_min = data["main"]["temp_min"] temp_max = data["main"]["temp_max"] humidity = data["main"]["humidity"] return f"The weather in {eng_city} is {weather_description} \ with average temperature of {temp}°C, \ minimum temperature of {temp_min}°C, \ maximum temperature of {temp_max}°C, \ and humidity of {humidity}%." else: return "Sorry, I couldn't retrieve the weather information." agent = Agent( name="Weather Agent", instructions="You are a helpful agent that provides weather information.", tools=[get_weather], ) async def main() -> None: result = await Runner.run(agent, input="今日の名古屋の天気を教えてください。") print(result.final_output) if __name__ == "__main__": asyncio.run(main()) |
ここでは、外部ツールとして、OpenWeatherMapというサービスを利用した。あらかじめアカウントを作り、APIキーを取得しておく必要がある。また、URLに地名を埋め込む際に地名を英訳する必要があるので、deep_translatorというPythonライブラリも利用した(前回取り上げたライブラリ)。
- 21行目から39行目まで:エージェントが呼び出す関数
get_weather
を定義する。 - 23行目:
get_weather
に渡される引数city
は日本語の地名である。これを英訳する。 - 24行目:OpenWeatherMapを利用するためのAPIである。
eng_city
とアクセスキーOPENWEATHERMAP_API_KEY
を埋め込む。 - 29行目から32行目:天気情報を取り出す。
- 33行目から37行目:文章に天気情報を埋め込む。
出力は以下の通り。
1 |
名古屋の今日の天気は晴れです。平均気温は11.65°Cで、最低気温は11.65°C、最高気温は12.79°Cです。湿度は43%です。 |
名古屋を東京や大阪に変えればそれぞれの天気を得ることができる。関数get_weather
が返す文章は英語であるが、最終的な文章は日本語になった。これは予想しなかった振る舞いである。
まとめ
AIエージェントを作成するフレームワークであるAgents SDKを紹介した。AIエージェントを作るフレームワークは既に存在しており、有名なものとしてLangGraphがある。今回、OpenAIから純正のフレームワークが出たことになる。LangGraphは他社の生成AIもバックエンドとして使うことができるので、どちらが良いかは一概には言えないが、OpenAIの生成AIを使うのであれば、Agents SDKを選択すべきであろう。