ツール使用

ツール使用(関数呼び出しとも呼ばれます)は、言語モデルが自分のテキストボックスを超えて機能する方法です。実行可能な関数のリストを提供すると、モデルはそれらを使用する時期を判断します。モデル自体は何も実行しません。呼び出しをリクエストするだけで、コードが実際の作業を行います。
モデルだけでは箱の中に閉じ込められています。今日の天気を確認したり、ユーザーをデータベースで検索したり、メールを送信したりすることはできません。学習時に固定された内容から、テキストを予測するだけです。これはLLMの仕組みの同じ図です。ツール使用は、箱の外に到達させる方法であり、エージェントが構築される基礎です。
覚えておくべき言葉は「要求」です。モデルはどの関数を使用したいのか、どのような引数でかを教えます。コードがそれを実行し、結果を返します。あなたは常にコントロール下にあります。
ループ
ツール使用は**行き来**であり、単一の呼び出しではありません。
- ユーザーのメッセージとモデルが使用する可能性のあるツールのリストを送信します。
- モデルは2つの方法のいずれかで応答します。通常の回答、またはツール呼び出しのリクエスト(必要な引数付き)。
- ツール呼び出しを要求した場合、コードはその関数を実行し、結果をモデルに送信します。
- モデルはその結果を使用して最終的な回答を書きます。
これがパターン全体です。モデルは要求し、コードは実行します。ステップ2と3は、モデルが複数のツールを必要とする場合に繰り返される可能性があり、これが数章先のエージェントの種です。
実際に何が起こっているのか
ツール使用はモデルが新しい力を獲得したように感じることができ、それはそうではありません。舞台裏では、モデルは常にやっていることを1つやっています。テキストを予測すること。それが生きている箱に関して何も変わっていません。
リクエストにツール定義を含めると、モデルが予測する コンテキストにそれらを追加しています。モデルは、これらのようなツールが与えられた場合、正しい継続は時々「call get_weather with city トウキョウ」を意味する特別にフォーマットされたメッセージであるという例で訓練されました、通常の文ではなく。したがって、質問がツールを役立つように見える場合、最も可能性の高い次の出力はその構造化された**ツール呼び出しメッセージ**であり、APIはそれをtool_callsとして表示します。
モデルが何かに到達して実行していません。ツール呼び出しが正しい動きであることを予測し、コードが読む方法でそれをリクエストしました。
その後、モデルではなく、あなたが関数を実行します。本当の結果を取得し、メッセージに追加のコンテキストとして戻します。全機能は2つの普通の予測で、その間にコードが実際の作業を行います。
あなたはモデルのテキストボックスと現実世界の橋です。この図を保持し、章の残り、エージェントを含む、神秘的に感じるのをやめます。AIが取るすべてのアクションは、コードが実行することを選択するリクエストの予測です。
tool_callsとして渡します。モデルは決して何も実行しません。呼び出しを予測します。コードは関数を実行し、結果を次の予測のための追加コンテキストとしてフィードバックするため、あなたはモデルと現実世界の橋です。 ツールの定義
各ツールをモデルに記述します。その名前、その機能、およびそれが取る引数。説明はあなたのためのドキュメントではなく、ツール使用のためのモデルへの指示であり、プロンプトのように書いてください。
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "指定された都市の現在の天気を取得します。ユーザーが天気について尋ねる場合に使用してください。",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "都市名(例:'東京')"},
},
"required": ["city"],
},
},
},
]parametersブロックは**スキーマ**であり、構造化出力と同じ考えです。モデルが生成する必要がある引数を定義します。モデルがget_weatherを呼び出すことを決定すると、このスキーマに一致するcity引数を返します。曖昧な説明(「天気を取得します」)はモデルが間違った時点でツールを使用するようにリードします。明確なもの(「ユーザーが天気について尋ねる場合に使用します」)はそれをうまく導きます。
parametersスキーマがあります。説明は本当にプロンプトです。モデルがツールをいつ使用するかを判断するために使用するため、注意深く記述してください。パラメータスキーマは、構造化出力と同じメカニズムであり、モデルが送信する引数を制約します。 呼び出しの処理
モデルがツールを望む場合、応答には最終的な回答の代わりにtool_callsが含まれます。リクエストされた関数と引数を読み、実際の関数を実行し、結果をtoolメッセージとして返します。その後、コードを再度呼び出して、完了できるようにします。
import json
# ツールの実装
def get_weather(city):
# 実際のアプリではこれは気象APIを呼び出しますが、ここでは偽造します
return {"city": city, "tempC": 18, "condition": "cloudy"}
messages = [{"role": "user", "content": "東京の天気は?"}]
# 1. 最初の呼び出し:ツールを提供
response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
tool_calls = response.choices[0].message.tool_calls
tool_call = tool_calls[0] if tool_calls else None
if tool_call:
# 2. リクエストされた関数をモデルの引数で実行
args = json.loads(tool_call.function.arguments)
result = get_weather(args["city"])
# 3. モデルのリクエストと結果を返す
messages.append(response.choices[0].message) # アシスタントのツールリクエスト
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
})
# 4. 再度呼び出して、モデルが結果を使用して回答できるように
response = client.chat.completions.create(model=MODEL, messages=messages)
print(response.choices[0].message.content)
# "現在、東京は18度でくもりです。"引数は**JSON文字列**として到着するため、実際のオブジェクトにjson.loadsしてから、使用する前に確認します。2つのメッセージをhistoryにプッシュします。モデルのツールリクエストとtool result。tool_call_idで接続されます。最終的な呼び出しは、生の気象データを自然な文に変えます。
tool_callsを持ちます。JSON文字列から引数を解析し、実際の関数を実行し、2つのメッセージをプッシュバックします。モデルのリクエストと結果はtool_call_idでリンクされています。最終的なモデル呼び出しは、生の結果を自然な回答に変えます。 実際に
再利用可能な関数と同じフロー。モデルと間にあるのはあなたが書いてコントロール下にあるコードだけであることに注意してください。
import json
tool_impls = {"get_weather": lambda args: get_weather(args["city"])}
def answer_with_tools(user_text):
messages = [{"role": "user", "content": user_text}]
response = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
calls = response.choices[0].message.tool_calls
if not calls:
return response.choices[0].message.content # モデルは直接回答
call = calls[0]
args = json.loads(call.function.arguments)
result = tool_impls[call.function.name](args)
messages.append(response.choices[0].message)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result)})
response = client.chat.completions.create(model=MODEL, messages=messages)
return response.choices[0].message.contentこれは1つのツール呼び出しを処理します。モデルはまた、複数を一度にリクエストすることができます。これは**平行ツール呼び出し**と呼ばれます。これはtool_callsの各エントリをループして処理します。そして、モデルがツールを呼び出し続けるループをさせることができます。それを決める独自のステップを毎回、エージェントを取得します。これは、次の章が正確に進む場所です。

