私の最新の投稿では、JSON モード、関数呼び出し、構造化出力を使用して、LLM からの応答として構造化された機械可読出力を取得する方法を説明しました。その投稿では、構造化された応答を取得する方法として関数呼び出しを見て、関数呼び出しのアイデアについて簡単に説明しました。しかし、関数呼び出しは、基本的にモデルのバックボーンであるため、単にモデルから構造化データを取得することをはるかに超えたものです。 エージェントAIワークフロー。そこで、今日の投稿では、まさにこのトピックについて詳しく見ていきます。
これまで取り上げてきたすべての例では、LLM は受動的な応答者としてのみ使用されています。つまり、質問を受信して回答を生成するだけです。しかし、LLM を何かに対する答えだけでなく、何かを行うものにもしたい場合はどうすればよいでしょうか? 何かをする?より正確に言えば、モデルの応答に基づいてアクションをトリガーしたい場合はどうすればよいでしょうか?このアクションには、ライブ データの表示、メッセージの送信、データベースのクエリ、外部 API の呼び出しなど、あらゆるものが含まれます。
それが可能になりました ツール呼び出し。ツール呼び出しにより、LLM は非常にスマートなテキスト ジェネレーターから、実際にアクションをトリガーし、周囲の世界と対話できるものに変換されます。
それでは、見てみましょう!
ツール呼び出しとは何ですか?
ツール呼び出し (関数呼び出しとも呼ばれる) は、LLM が応答生成の一部として外部関数または API の実行を要求できるメカニズムです。つまり、モデルは単にテキストを返すのではなく、ユーザーのリクエストへの応答として特定の引数を使用して特定の関数を実行できます。
ここで理解すべき主なことは、 モデル自体はツールを実行しません。それだけ 決める どのツールをどの引数で呼び出すか。選択したツールの実際の実行は、AI モデルへのリクエストを含む独自のコードで行われます。次に、ツールの結果を AI モデルにフィードバックし、AI モデルがそれを使用してユーザーへの最終応答を生成します。
このツールは呼び出しループであり、次の手順で構成されます。
- ユーザーがメッセージを送信する
- AI モデルはメッセージを入力として受け取り、出力を生成します。これは基本的に、どのツールをどの引数とともに使用するかについて決定します。
- 使用するツールの選択と関連する引数を含むモデルからの応答がコードに返されます。このコードは、AI モデルを介さずに、選択された引数を使用して選択されたツールを実行します。この実行により何らかの結果 (計算、API から取得した情報など) が生成され、この結果が AI モデルに返されます。
- AI モデルはツールの結果を入力として受け取り、それに基づいてユーザーに最終的な応答を返します。

繰り返しますが、モデルはツールの実行ではなくツール呼び出しを生成します。この 2 つはまったく異なるものであり、これらを混合することは最も一般的な混乱の原因の 1 つです。
しかし、ツール呼び出しとは正確には何でしょうか?実際には、これは、前の投稿で見たように、モデルが関数呼び出しを使用して構造化された機械可読な応答を返すことを意味します。この反応では、成分は次のとおりです。 None;自然言語による答えはなく、どのツールをどの引数で呼び出すかを指示する構造化された命令があるだけです。ツールを実行して結果を送り返した後でのみ、モデルはユーザーに実際のテキスト応答を生成します。
しかし、実際に見てみましょう!
1 つのツールと 1 つの呼び出しだけを使用する簡単な例から始めて、徐々により興味深いシナリオを構築していきます。
1. 単一ツール: Weather API
AI を備えたツールを使用する最も一般的な例として思い浮かぶのは、天気 API (カスタムのライブ データの基礎) だと思います。そこで、天気アシスタントを構築していると想像してみましょう。具体的には、ユーザーが天気について尋ねるメカニズムを作成したいと考えています。AI モデルに何かを作成させる代わりに (モデルは喜んでそれを行います 🙃)、AI モデルが実際の天気関数を呼び出して、LLM の外部の別の場所から天気に関する実際のデータを取得できるようにしたいと考えています。気象データを取得するには、API キーを必要としない無料のオープンソース気象 API である open-meteo を使用します。
ツールを使用するには、最初にそれを宣言する必要があります tools。
from openai import OpenAI
import json
client = OpenAI(api_key="your_api_key")
# Step 1: define the tool
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "The name of the city, e.g. Athens"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit to use"
}
},
"required": ["city"]
}
}
}
]
実際に使用されるツール (Weather API) については、この時点ではどこにも言及されていないことに注意してください。代わりに、モデルは次の 3 つのことに基づいてどのツールを呼び出すかを決定します: 関数の説明 (「指定された都市の現在の天気を取得する」)、パラメータの説明(「都市名、たとえばアテネ」)、および該当するスキーマ。モデルは、この情報のみから、特定のユーザー メッセージを呼び出すのに適切なデバイスであるかどうか、またどのような引数を使用して呼び出すかを判断します。したがって、ツールを定義するときに明確で正確な説明を記述することは、モデルがユーザーの入力に基づいて正しいツールを適切に識別して呼び出すために非常に重要です。
したがって、ツール変数を定義した後、AI モデルにリクエストを行うことができます。
# Step 2: send the user message along with the tool definition
messages = [
{"role": "user", "content": "What's the weather like in Athens right now?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
print(response.choices[0].message)
このリクエストを行うとどうなりますか。モデルはユーザーのメッセージを読み取り、 「アテネは今どんな天気ですか?」利用可能なツールがあることを理解しています get_current_weather 実際のライブデータを使用してこの質問に答えると役立つ場合があります。したがって、テキスト応答を直接生成する代わりに、最初にツールを呼び出すことにします。より具体的には、この時点でのモデルの応答は次のようになります。
ChatCompletionMessage(
content=None,
role='assistant',
tool_calls=[
ChatCompletionMessageToolCall(
id='call_abc123',
type='function',
function=Function(
name='get_current_weather',
arguments='{"city": "Athens", "unit": "celsius"}'
)
)
]
)
内容がどうなっているかに注目してください Noneモデルはテキスト応答を返さないため、 しかしツール呼び出し。ここでの仕事は、ツール、選択したモデルを実際に実行し、結果を返すことです。私たちの場合、AI モデルの応答で指定された引数 (つまり、都市と測定単位) を使用して、Weather API への API リクエストを作成します。
# Step 3: execute the tool using the Open-Meteo API
import requests
def get_current_weather(city: str, unit: str = "celsius"):
# geocode the city name to coordinates
geo = requests.get(
"https://geocoding-api.open-meteo.com/v1/search",
params={"name": city, "count": 1}
).json()
lat = geo["results"][0]["latitude"]
lon = geo["results"][0]["longitude"]
# fetch current weather
weather = requests.get(
"https://api.open-meteo.com/v1/forecast",
params={
"latitude": lat,
"longitude": lon,
"current": "temperature_2m,weather_code",
"temperature_unit": unit
}
).json()
temp = weather["current"]["temperature_2m"]
return {"city": city, "temperature": temp, "unit": unit}
# extract the tool call from the response
tool_call = response.choices[0].message.tool_calls[0]
arguments = json.loads(tool_call.function.arguments)
# call the actual function
weather_result = get_current_weather(**arguments)
次に、ツールの結果をメッセージ履歴に追加し、すべてをモデルに送り返すことができます。
# Step 4: add the assistant's tool call AND the tool result to the message history
messages.append(response.choices[0].message) # important: append the tool call first
messages.append({
"role": "tool",
"tool_call_id": tool_call.id, # links the result back to the specific tool call
"content": json.dumps(weather_result)
})
# Step 5: send everything back to the model for a final response
final_response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
print(final_response.choices[0].message.content)
そして今、ついに適切なテキスト応答が得られました。
It's currently 29°C in Athens. Sounds like a great day to be outside!
🍨 データクリーム は、AI、データ、テクノロジーに関するストーリーやチュートリアルを特集したニュースレターです。これらのトピックに興味がある場合は、 ここから購読してください!
2. モデルに複数のツールから選択させる
次に、より現実的な例を見てみましょう。実際のエージェント アプリケーションでは、モデルは通常、1 つではなく、 複数 その結果、ユーザーの要求に基づいてどれを使用する必要があるかを判断する必要があります。
通貨用のツールを追加して、最初の Weather API の例を拡張してみましょう。このために、API キーを必要とせずに欧州中央銀行に日次レートを提供する通貨 API である Frankfurter を使用します。それでは、私たちのものを更新しましょう tools 通貨を変換する 2 番目のツールを追加することで変換可能:
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather for a given city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "The name of the city"},
"unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}
},
"required": ["city"]
}
}
},
{
"type": "function",
"function": {
"name": "convert_currency",
"description": "Convert an amount from one currency to another",
"parameters": {
"type": "object",
"properties": {
"amount": {"type": "number", "description": "The amount to convert"},
"from_currency": {"type": "string", "description": "The source currency code, e.g. USD"},
"to_currency": {"type": "string", "description": "The target currency code, e.g. EUR"}
},
"required": ["amount", "from_currency", "to_currency"]
}
}
}
]
そして実際の convert_currency Frankfurter API を使用して作業します。
def convert_currency(amount: float, from_currency: str, to_currency: str):
response = requests.get(
f"https://api.frankfurter.dev/v2/rate/{from_currency}/{to_currency}"
).json()
rate = response["rate"]
converted = round(amount * rate, 2)
return {
"amount": amount,
"from_currency": from_currency,
"to_currency": to_currency,
"converted_amount": converted,
"rate": rate
}
このようにして、モデルは幅広いユーザーのリクエストを処理できます。天気以外にも通貨についても答えられるようになりました。さて、ユーザーが尋ねたら 「アテネの天気はどんな感じですか?」モデルは電話する必要があります get_current_weather。彼らが尋ねたら 「100 ドルはユーロでいくらですか?」それを呼ぶべきです convert_currency。また、天気にも通貨にも無関係で、利用可能なツールがどれも役に立たない質問をした場合、モデルはツールを呼び出すことなく、単純にテキストで答えます。
しかし、実際に試してみましょう。
messages = [
{"role": "user", "content": "How much is 200 USD in EUR?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
tool_call = response.choices[0].message.tool_calls[0]
反応を見てみましょう:
print(tool_call.function.name)
それは私たちに与えます convert_currency。したがって、モデルはその質問を理解しました 「200 ドルはユーロでいくらですか?」 に関連する convert_currency 道具。引数も見てみましょう。
print(tool_call.function.arguments)
それは私たちに与えます
'{"amount": 200, "from_currency": "USD", "to_currency": "EUR"}'
したがって、モデルは正しく識別します convert_currency 必要に応じて、適切なツールの説明を提供し、ユーザーに適切なメッセージを提供すること以外は何もせずに、適切なロジックを入力します。ツール呼び出しがエージェント システムの基礎となるのは、この正確な意思決定メカニズムです。
3. 複数のツールを同時に呼び出す
もう 1 つの興味深いツール呼び出しシナリオは、多くのモデル (例: gpt-4oユーザーのリクエストに応じて、単一の応答で複数のツールを呼び出すことができます。これは、並列ツール呼び出しとして知られています。
たとえば、ユーザーが 1 つのリクエストで何かを要求し、その両方の使用が必要になるシナリオを想像してみましょう。 get_current_weather そして convert_currency 必要な情報を取得するためのツール:
messages = [
{"role": "user", "content": "What's the weather in Athens and how much is 100 USD in EUR?"}
]
response = client.chat.completions.create(
model="gpt-4o-mini",
tools=tools,
messages=messages
)
for tool_call in response.choices[0].message.tool_calls:
print(tool_call.function.name)
print(tool_call.function.arguments)
この場合、得られる応答は次のとおりです。
get_current_weather
{"city": "Athens"}
convert_currency
{"amount": 100, "from_currency": "USD", "to_currency": "EUR"}
両方のツールが同じモデル応答でどのように呼び出されるかに注目してください。次に、指定された引数を使用して対応するツールを実行し、ツールの結果を一緒にモデルに送り返すことができます。これは、順次呼び出しよりもはるかに効率的であり、より高度なエージェントがマルチパート リクエストを処理する方法です。
私の考えでは、それでは、何がエージェントになるのでしょうか?
私がいつも気になるのは、あらゆるものに「エージェント」という言葉が飛び交うことです。エージェント、エージェントワークフロー、その言葉に由来するもの 代表 最近はとてもセクシーですが、すでにお気づきかもしれませんが、エージェントとして販売されているものすべてが実際にセクシーであるわけではありません。
それでは、一歩下がって、エージェントとは実際何なのかを考えてみましょう。本質的に、エージェントとは、環境を感知し、その情報を何らかの方法で処理し、目標を持ち、それを達成するためにどのような行動を取るかを決定する人です。ツール呼び出しメカニズムが何をしているのか考えてみましょう。利用可能なツールを理解し、ユーザーのリクエスト (存在する場合) に対処するのにどれが適切かを決定し、その決定をコードの残りの部分に渡して実行します。それは、最も単純な形では、代理店です。
実際のエージェント アプリケーションでは、ツール呼び出しループは 1 回ではなく複数回実行され、モデルは 1 回のツール呼び出しの結果を使用して次の呼び出しを行うかどうかを決定します。これは React ループ (Reason + Act) と呼ばれることもあり、エージェントは 1 回の通話では解決できない複雑な複数ステップのタスクを処理できます。
結局のところ、私がツール呼び出しで最も魅力的だと思うのは、それが LLM の性質をどのように変えるかということです。この時点まで、言語モデルは本質的に とても テキストを入力として受け取り、テキストを出力として生成する高度な入出力機能。しかし、ツール呼び出しを使用すると、追加機能の無限のコレクションにアクセスできるようになり、LLM の推論能力と組み合わせて、どちらの機能よりもはるかに高性能なシステムを作成できます。
読んでいただきありがとうございます! ▪️
ここまで進んだなら、 ピアゴリズムが役立つかもしれません – 私たちは、チームが組織の知識を 1 か所で安全に管理できるようにするプラットフォームを構築しています。
この投稿は気に入りましたか?参加してください 💌サブスタック そして💼リンクトイン
特に明記されていない限り、すべての画像は作者によるものです。








Leave a Reply