HUOXIU

LLMにツールの使い方を教える | 例を通して関数呼び出しテクニックを探る

編集者注:大規模言語モデルは驚異的な言語理解・生成能力を備えていますが、自律的な意思決定や外部システムとの相互作用といった分野では課題を抱えています。関数呼び出し技術の登場は、この課題を解決するために設計された革新的なソリューションです。関数呼び出し技術は、大規模言語モデルに強力な自律性と外部世界との連携能力を与え、真に知的で自律的なエージェントを実現するための重要な要素となります。

本号では、関数呼び出し技術を用いた自律AIエージェントの構築に関する詳細な技術チュートリアルをご紹介します。関数呼び出しの動作原理と応用シナリオから始め、旅行サービスアシスタントを例に、システムの設計、技術的な詳細、そしてコード実装について段階的に解説します。

この記事が読者にインスピレーションを与え、より賢く、より人間らしい AI エージェントの開発への明るい道を切り開くことを願っています。

著者 | ジュリアン・イップ

編纂者:岳陽

関数呼び出しは新しい概念ではありません。OpenAIは2023年7月にこの機能をGPTモデルに導入し、その後、他の競合他社にも採用されています。例えば、GoogleのGemini APIは最近関数呼び出しのサポートを開始し、AnthropicはClaudeにこれを統合しています。関数呼び出し(特定の関数を呼び出すことでモデルが複雑なタスクを実行できるようにする機能)は、大規模言語モデル(LLM)の重要な機能となり、その応用能力を大幅に向上させています。したがって、この技術を習得することは非常に価値があります。

そのため、基本的な導入部分を超えた内容に焦点を当てた詳細なチュートリアルを作成する予定です(この種のチュートリアルは既に数多く存在します)。このチュートリアルでは、実用的なアプリケーションに焦点を当て、完全自律型AIエージェント(人間の介入なしに自律的に動作し、意思決定を行うことができるAIエージェント)の構築方法と、それをStreamlitと統合してChatGPTのようなWebインターフェースを実現する方法を説明します。このチュートリアルではOpenAIをデモに使用していますが、内容はGeminiなど、関数呼び出しをサポートする他の大規模言語モデルにも同様に当てはまります。

01 関数呼び出しの用途は何ですか?

関数呼び出しにより、開発者は関数(ツールとも呼ばれ、数学的計算や注文の発行など、モデルが実行する操作と見なすことができます)を定義し、モデルがこれらの関数を呼び出すために必要なパラメータを含むJSONオブジェクトをインテリジェントに選択して出力することを可能にします。つまり、このテクノロジーは以下の機能を提供します。

  • 自律的な意思決定: モデルは質問に答えるために必要なツールをインテリジェントに選択できます。
  • 信頼性の高い解析:応答は通常、一般的な対話形式の応答ではなく、JSON形式で提示されます。一見すると些細なことに思えるかもしれませんが、まさにこの技術によって、LLMはAPIとのやり取りなど、構造化された入力を介して外部システムに接続することが可能になります。

この技術は人々にさまざまな新しい機会と可能性をもたらしました。

  • 自律型 AI アシスタント: これらのロボットは、ユーザーの問い合わせに回答できるだけでなく、社内システム (翻訳者注: 企業が社内のビジネス プロセス、データ管理、顧客関係などを処理するために使用する社内システム) と対話して、顧客の注文や返品などのタスクを処理することもできます。
  • 個人用リサーチ アシスタント: たとえば、旅行の計画を立てる必要がある場合、これらのアシスタントにインターネット上のコンテンツの検索、コンテンツのクロール、コンテンツの比較、および Excel での結果の要約を依頼できます。
  • IoT 音声コマンド: このモデルは、検出されたユーザーの意図に基づいてデバイスを制御したり、エアコンの温度調整など操作の提案を提供したりできます。

02 関数呼び出し機能の実行フロー

Geminiの関数呼び出しドキュメント[1]を参照すると、関数呼び出し関数は次のように実行され、OpenAIにおけるこの関数の動作原理は基本的に同じです。

画像出典: Geminiの関数呼び出しドキュメント [1]

1. ユーザーはアプリケーションにプロンプ​​トを送信します。

2. アプリケーションは、モデルに必要なツールに関する説明情報である、ユーザー提供のプロンプトと関数宣言を提供します。

3. 関数の宣言に基づいて、モデルはツール選択の提案と関連するリクエストパラメータを提供します。モデルは提案されたツールとリクエストパラメータを出力するだけで、実際に関数を呼び出すわけではないことに注意してください。

4. & 5. アプリケーションは、モデルの応答に基づいて関連する API を呼び出します。

6. & 7. API 応答をモデルに入力して、人間が読めるコンテンツを生成します。

8. アプリケーションは最終応答をユーザーに返し、その後ステップ 1 に戻り、このプロセスを繰り返します。

上記の紹介は少し複雑に思えるかもしれませんので、以下の例を使用して概念を詳しく説明します。

03 エージェントの全体的な設計とアーキテクチャ

具体的なコードの詳細に入る前に、この記事で説明するエージェントの全体的な設計とアーキテクチャを簡単に紹介しましょう。

3.1 ソリューション: 観光サービスアシスタント

この記事では、旅行中のホテル宿泊客向けのトラベルサービスアシスタントを構築します。この製品では、以下のツール(サービスアシスタントが外部アプリケーションにアクセスできるようにするツール)を使用できます。

  • `get_items` と `purchase_item` : これらのツールは、API を介してデータベース内の製品カタログに接続します。それぞれ、製品リストの取得と製品の購入に使用されます。
  • rag_pipeline_func : Retrieval Enhanced Generation (RAG) を介してドキュメント データに接続して管理し、ホテルのパンフレットなどの非構造化テキストから関連情報を抽出します。

3.2 関連技術スタック

  • 埋め込みモデル:all-MiniLM-L6-v2[2]
  • ベクターデータベース:HaystackのInMemoryDocumentStore[3]
  • 大規模言語モデル(LLM) :OpenRouter[4]を介してGPT-4 Turboにアクセスできます。関数呼び出しがサポートされている限り、他の大規模言語モデル(Geminiなど)も、コードを少し変更するだけで使用できます。
  • LLMフレームワーク:Haystack[5]は使いやすく、ドキュメントが充実しており、パイプライン構築に関して比較的透明性が高いため使用されています。このチュートリアルは、実際にはフレームワークの使用に関するチュートリアル[6]の拡張版です。

それでは紹介を始めましょう!

04. 上記のテクノロジー スタックを使用してエージェントの例を構築します。

4.1 事前準備

このプロジェクトのコードをクローンするには、Github[7]にアクセスしてください。以下の内容はノートブックfunction_calling_demoにあります。

仮想環境を作成してアクティブ化し、「pip install -r requirements.txt」を実行して必要なパッケージをインストールしてください。

4.2 プロジェクトの初期化

まずOpenRouterに接続します。OpenAI APIキーをお持ちの場合は、 api_base_urlパラメータを書き換えずに、オリジナルのOpenAIChatGenerator使用することもできます。

 import osfrom dotenv import load_dotenvfrom haystack.components.generators.chat import OpenAIChatGeneratorfrom haystack.utils import Secretfrom haystack.dataclasses import ChatMessagefrom haystack.components.generators.utils import print_streaming_chunk# thisload_dotenv() を実行する前に、API キーを環境変数として設定してください
OPENROUTER_API_KEY = os.environ.get('OPENROUTER_API_KEY')
chat_generator = OpenAIChatGenerator(api_key=Secret.from_env_var("OPENROUTER_API_KEY"),
api_base_url="https://openrouter.ai/api/v1",
  モデル = "openai/gpt-4-turbo-preview",
ストリーミングコールバック=print_streaming_chunk) 

次に、chat_generator が正常に呼び出されるかどうかをテストします。

 chat_generator.run(messages=[ChatMessage.from_user("このテキストを返します: 'test'")]) 
 ---------- レスポンスは次のようになります ----------{'replies': [ChatMessage(content="'test'", role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'openai/gpt-4-turbo-preview', 'index': 0, 'finish_reason': 'stop', 'usage': {}})]} 

4.3 ステップ1: 適切なデータストレージソリューションを選択して使用する

ここでは、アプリケーションと 2 つのデータ ソース (非構造化テキストのドキュメント ストアと API 経由で接続されたアプリケーション データベース) 間の接続を確立します。

パイプラインを使用してドキュメントをインデックスする

モデルが検索拡張(RAG)を実行するには、システムにサンプルテキストを提供する必要があります。これらのテキストは埋め込み情報に変換され、文書データをメモリに保存するデータストレージスキームを使用して保存されます。

 from haystack import Pipeline, Documentfrom haystack.document_stores.in_memory import InMemoryDocumentStorefrom haystack.components.writers import DocumentWriterfrom haystack.components.embedders import SentenceTransformersDocumentEmbedder# サンプルドキュメントdocuments = [
Document(content="コーヒーショップは午前 9 時に開店し、午後 5 時に閉店します。"),
Document(content="ジムのルームは午前 6 時に開き、午後 10 時に閉まります。")
]# ドキュメントストアを作成するdocument_store = InMemoryDocumentStore()# テキストを埋め込みに変換してドキュメントストアに保存するパイプラインを作成するindexing_pipeline = Pipeline()
indexing_pipeline.add_component( "doc_embedder", SentenceTransformersDocumentEmbedder(model="sentence-transformers/all-MiniLM-L6-v2")
)
indexing_pipeline.add_component("doc_writer", DocumentWriter(document_store=document_store))
indexing_pipeline.connect("doc_embedder.documents", "doc_writer.documents")
indexing_pipeline.run({"doc_embedder": {"documents": documents}}) 

上記のプログラムの出力は、入力サンプル ドキュメント データと一致するはずです。

 {'doc_writer': {'documents_written': 2}} 

APIサービスプロセスを開始する

db_api.py ファイルに、Flask フレームワークを使用して SQLite データベースに接続するための API サービスを作成します。ターミナルで `python db_api.py` を実行してサービスを起動します。

サービスが正常に実行されると、端末には画像に示す情報が表示されます。

いくつかの初期基本データが db_api.py に事前に設定されていることに気付きました。

データベース内のデータサンプル

4.4 ステップ2: 関数を定義する

このステップでは、モデルが後続の関数呼び出しステップで呼び出して実行する実際の関数を準備します (セクション 02「関数呼び出し機能のフロー」のステップ 4 ~ 5 で説明)。

RAG関数

その一つがRAG関数rag_pipeline_funcです。この関数により、モデルはドキュメントストレージに以前保存されたテキストコンテンツを検索し、検索結果に基づいて回答を提供できます。この関数は主にHaystackフレームワークを使用し、RAG(Retrieval Augmentation Generation)検索プロセスをパイプラインとして定義します。

 haystack.components.embedders から SentenceTransformersTextEmbedder をインポートします。haystack.components.retrievers.in_memory から InMemoryEmbeddingRetriever をインポートします。haystack.components.builders から PromptBuilder をインポートします。haystack.components.generators から OpenAIGenerator をインポートします。
テンプレート = """
与えられたコンテキストに基づいて質問に答えます。
コンテクスト:
{% ドキュメント内のドキュメント %}
{{ドキュメント.コンテンツ}}
{% endfor %}
質問: {{ question }}
答え:
rag_pipe = パイプライン()
rag_pipe.add_component("embedder", SentenceTransformersTextEmbedder(model="sentence-transformers/all-MiniLM-L6-v2"))
rag_pipe.add_component("retriever", InMemoryEmbeddingRetriever(document_store=document_store))
rag_pipe.add_component("prompt_builder", PromptBuilder(template=template))# llmへの注意: OpenAIGeneratorではなくOpenAIChatGeneratorを使用しています。後者は入力としてList[str]のみを受け入れ、prompt_builderのstr出力を受け入れることができないためです。rag_pipe.add_component("llm", OpenAIGenerator(api_key=Secret.from_env_var("OPENROUTER_API_KEY"),
api_base_url="https://openrouter.ai/api/v1",
  モデル = "openai/gpt-4-turbo-preview"))
rag_pipe.connect("embedder.embedding", "retriever.query_embedding")
rag_pipe.connect("retriever", "prompt_builder.documents")
rag_pipe.connect("prompt_builder", "llm") 

機能が正しく動作するかどうかをテストします。

クエリ = 「コーヒーショップはいつ開きますか?」
rag_pipe.run({"embedder": {"text": query}, "prompt_builder": {"question": query}}) 

モデルによって実行された `rag_pipeline_func` 関数は、以下の出力を生成します。モデルのレスポンスは、先ほど提供したサンプルドキュメントデータに基づいていることに注意してください。

 {'llm': {'replies': ['コーヒーショップは午前9時に開店します。'], 'meta': [{'model': 'openai/gpt-4-turbo-preview', 'index': 0, 'finish_reason': 'stop', 'usage': {'completion_tokens': 9, 'prompt_tokens': 60, 'total_tokens': 69, 'total_cost': 0.00087}}]}} 

次に、rag_pipe を、他の中間詳細を返さずにクエリに基づいて回答を取得するために必要に応じて rag_pipeline_func(query) を呼び出す関数に変換できます。

定義rag_pipeline_func(query: str): result = rag_pipe.run({"embedder": {"text": query}, "prompt_builder": {"question": query}}) 戻り値{"reply": result["llm"]["replies"][0]} 

データベースと対話するための API を定義します。

ここでは、データベースと対話するためのget_itemspurchase_itemfunctions関数を定義します。

 # Flask のデフォルトのローカル URL。必要に応じて変更してください。db_base_url = 'http://127.0.0.1:5000'# リクエストを使用してデータベースからデータを取得します。import requestimport json# get_categories はプロンプトの一部として提供され、ツールとしては使用されません。def get_categories(): response = requests.get(f'{db_base_url}/category')
data = response.json() return datadef get_items(ids=None,categories=None): params = { 'id': ids, 'category': categories,
}
レスポンス = リクエスト.get(f'{db_base_url}/item', パラメータ = パラメータ)
data = response.json() return datadef purchase_item(id,quantity): headers = { 'Content-type':'application/json',
'承認':'application/json'
}
データ = { 'id': ID, 'quantity': 数量,
}
レスポンス = リクエスト.post(f'{db_base_url}/item/purchase', json=data, headers=headers) レスポンス.json() を返す

ユーティリティ関数のリストを定義する

関数の定義が完了したので、次のステップは、モデルがこれらの関数の使い方を認識し、理解できるようにすることです。そのためには、これらの関数に関する説明情報を提供する必要があります。

ここではOpenAIを使用しているため、これらのツール(関数)をOpenAI [8]で要求される形式で記述する必要があります。

ツール = [
{ "type": "function", "function": { "name": "get_items", "description": "データベースからアイテムのリストを取得します", "parameters": { "type": "object", "properties": { "ids": { "type": "string", "description": "取得するアイテムIDのカンマ区切りリスト",
}, "categories": { "type": "string", "description": "取得するアイテムカテゴリのカンマ区切りリスト",
},
}、 "必須": []、
},
}
},
{ "type": "function", "function": { "name": "purchase_item", "description": "特定の商品を購入する", "parameters": { "type": "object", "properties": { "id": { "type": "string", "description": "指定された商品ID、商品名はここでは受け入れられません。まずデータベースから商品IDを取得してください。",
}, "quantity": { "type": "integer", "description": "購入する商品の数",
},
}、 "必須": []、
},
}
},
{ "type": "function", "function": { "name": "rag_pipeline_func", "description": "ホテルのパンフレットから情報を取得する", "parameters": { "type": "object", "properties": { "query": { "type": "string", "description": "検索で使用するクエリ。ユーザーのメッセージから推測します。質問または文である必要があります",
}
}, "必須": ["クエリ"],
},
},
}
] 

4.5 ステップ3: すべてのシステムコンポーネントを統合する

これで、関数呼び出し機能をテストするために必要なシステムコンポーネントがすべて揃いました。このステップでは、以下の作業を行う必要があります。

  1. モデルに最初のプロンプトとコンテキストを提供します。
  2. 実際のユーザークエリやリクエストをシミュレートするためのサンプルユーザーメッセージを提供します。
  3. 最も重要なステップは、以前に定義したツール関数のリストをtoolsパラメータとしてチャットジェネレータ(翻訳者注:会話応答を生成する言語モデルまたは AI システム)に渡すことです。
 # 1. 初期 promptcontext = f"""あなたはホテルを訪れる観光客のアシスタントです。
観光客が購入できるアイテムのデータベース({get_categories()} を含む)にアクセスでき、ホテルのパンフレットにもアクセスできます。
観光客の質問がデータベースから回答できない場合は、パンフレットを参照できます。
観光客の質問がパンフレットから得られない場合は、ホテルのスタッフに質問するよう観光客に依頼できます。
"""メッセージ = [
ChatMessage.from_system(context), # 2. ユーザーからのサンプルメッセージ ChatMessage.from_user("コーヒーを買ってもいいですか?"),
]# 3. ツールリストを渡してチャットジェネレーターを呼び出すresponse = chat_generator.run(messages=messages, generation_kwargs= {"tools": tools})
応答
 -  -  -  -  -  応答  -  -  -  -  - 
{'返信': [ChatMessage(content='[{"index": 0, "id": "call_AkTWoiJzx5uJSgKW0WAI1yBB", "function": {"arguments": "{\"categories\":\"食品と飲料\"}", "name": "get_items"}, "type": "function"}]', role=<ChatRole.ASSISTANT: 'assistant'>, name=None, meta={'model': 'openai/gpt-4-turbo-preview', 'index': 0, 'finish_reason': 'tool_calls', 'usage': {}})]} 

それでは、モデルの応答を調べてみましょう。

関数呼び出しによって返されるコンテンツには、モデルが呼び出すことを選択した関数自体だけでなく、その関数に渡されるパラメータも含まれることに注意することが重要です。

 function_call = json.loads(レスポンス["返信"][0].content)[0]
function_name = function_call["関数"]["名前"]
function_args = json.loads(function_call["関数"]["引数"])
print("関数名:", function_name)
print("関数の引数:", function_args) 
 ---------- レスポンス ---------- 関数名: get_items 関数引数: {'categories': '食品と飲料'} 

モデルは新しい問題に遭遇すると、その問題を分析し、既存のコンテキスト情報と組み合わせて、利用可能なツール機能のどれが問題の解決に最も役立つかを評価します。

 # 別の質問messages.append(ChatMessage.from_user("コーヒーショップはどこですか?"))# チャットジェネレーターを呼び出し、ツールリストを渡しますresponse = chat_generator.run(messages=messages, generation_kwargs= {"tools": tools})
function_call = json.loads(レスポンス["返信"][0].content)[0]
function_name = function_call["関数"]["名前"]
function_args = json.loads(function_call["関数"]["引数"])
print("関数名:", function_name)
print("関数の引数:", function_args) 
 ---------- 応答 ---------- 関数名: rag_pipeline_func 関数引数: {'query': "コーヒーショップはどこですか?"} 

このステップではまだ関数の呼び出しや実行は行われませんので、ご注意ください。実際の関数呼び出しは次のステップで行われます。

関数の呼び出し

このステップでは、選択した関数にパラメータを入力する必要があります。

 ## 対応する関数を見つけて、指定された引数で呼び出します。available_functions = {"get_items": get_items, "purchase_item": purchase_item,"rag_pipeline_func": rag_pipeline_func}
function_to_call = available_functions[関数名]
function_response = function_to_call(**function_args)
print("関数の応答:", function_response) 
 ---------- レスポンス ---------- 関数レスポンス: {'reply': '指定されたコンテキストでは、コーヒーショップの物理的な場所が指定されておらず、営業時間のみが示されています。したがって、指定された情報に基づいてコーヒーショップの場所を特定することはできません。'} 

次に、 rag_pipeline_funcからのモデル応答をコンテキスト情報としてmessages変数に追加し、モデルがこの追加コンテキストに基づいて最終的な応答を生成できるようにします。

 messages.append(ChatMessage.from_function(content=json.dumps(function_response), name=function_name))
レスポンス = chat_generator.run(メッセージ = メッセージ)
response_msg = レスポンス["返信"][0]
応答メッセージ.content を印刷します。 
 ---------- 回答 ---------- ホテル内のカフェの場所につきましては、ホテルスタッフに直接お問い合わせいただくことをお勧めいたします。スタッフが正確なご案内をさせていただきます。 

これで、ユーザーと AI 間の完全な対話サイクルが完了しました。

4.6 ステップ4: リアルタイムのインタラクティブチャットシステムに変換する

上記のコードは関数呼び出しがどのように実装されるかを示していますが、さらに一歩進んで、これをリアルタイムのインタラクティブなチャット システムに変換したいと考えています。

このセクションでは、2 つの実装方法を説明します。

  1. より基本的な input() メソッドは、会話の内容をノートブックに出力します。
  2. レンダリングは Streamlit を使用して実行され、ChatGPT のような UI エクスペリエンスを提供します。

input() ループ

この部分のコードはHaystackチュートリアル[9]からコピーしたもので、モデルを素早くテストするために使用できます。注意:このアプリケーションは関数呼び出しの概念を示すために作成されたものであり、複数のアイテムの同時ソートをサポートしたり、錯覚が全くなかったりするなど、アプリケーションが完全に堅牢であることを意味するものではありません。

 JSONをインポート
haystack.dataclassesからChatMessageとChatRoleをインポートします
応答 = なし
メッセージ = [
ChatMessage.from_system(コンテキスト)
]
真の場合:
# OpenAIの応答がツール呼び出しの場合
レスポンスがあり、response["replies"][0].meta["finish_reason"] == "tool_calls"の場合:
function_calls = json.loads(レスポンス["返信"][0].content)
function_calls 内の function_call の場合:
## 関数呼び出し情報を解析する
function_name = function_call["関数"]["名前"]
function_args = json.loads(function_call["関数"]["引数"])
## 対応する関数を見つけて、指定された引数で呼び出します
呼び出す関数 = 利用可能な関数[関数名]
function_response = function_to_call(**function_args)
## `ChatMessage.from_function` を使用して関数応答をメッセージ リストに追加します。messages.append(ChatMessage.from_function(content=json.dumps(function_response), name=function_name))
# 通常の会話
それ以外:
#アシスタントメッセージをメッセージリストに追加する
そうでない場合、メッセージ[-1].is_from(ChatRole.SYSTEM):
メッセージ.append(レスポンス["返信"][0])
user_input = input("メッセージを入力してください👇 情報: 停止するには「exit」または「quit」と入力してください\n")
user_input.lower() == "exit" または user_input.lower() == "quit" の場合:
壊す
それ以外:
メッセージ.append(ChatMessage.from_user(user_input))
レスポンス = chat_generator.run(messages=メッセージ、generation_kwargs={"tools": ツール}) 

統合開発環境でインタラクティブチャットアプリを実行する

基本的なインタラクション方法は引き続き機能しますが、より美しくユーザーフレンドリーなインターフェースにより、優れたユーザー エクスペリエンスが実現します。

Streamlitインターフェース

Streamlitは、PythonスクリプトとWeb開発技術を巧みに組み合わせ、共有可能なWebサービスアプリケーションに変換し、このインタラクティブな関数呼び出しアプリケーションのための全く新しいWebインターフェースを構築します。上記のコードはStreamlitアプリケーションに適応されており、コードリポジトリのstreamlitフォルダに保存されています。

次の手順でアプリケーションを実行できます。

  1. まだ実行されていない場合は、 python db_api.pyを使用して API サーバーを起動してください。
  2. Linux の場合やgit bashを使用する場合などは、 export OPENROUTER_API_KEY='@替换为您的API密钥'実行して、 OPENROUTER_API_KEY環境変数として設定します。
  3. ターミナルで、コマンドcd streamlitを使用して streamlit フォルダーに移動します。
  4. streamlit run app.pyを実行してStreamlitを起動します。ブラウザが自動的に新しいタブを作成し、アプリケーションを実行します。

私が言いたかったのは基本的にこれだけです!この記事を楽しんでいただけたら嬉しいです。

流線型のUI

読んでくれてありがとう!

ジュリアン・イップ

マルチクラウド データ アーキテクト | Azure、GCP、Databricks 認定 | ML および MLOps 実践者

終わり

参考文献

[1] https://cloud.google.com/vertex-ai/generative-ai/docs/multimodal/function-calling

[2] https://huggingface.co/sentence-transformers/all-MiniLM-L6-v2

[3] https://docs.haystack.deepset.ai/docs/inmemorydocumentstore

[4] https://openrouter.ai/models/openai/gpt-4-1106-preview

[5] https://haystack.deepset.ai/

[6] https://haystack.deepset.ai/tutorials/40_building_chat_application_with_function_calling

[7] https://github.com/yip-kl/llm_function_calling_demo

[8] https://cookbook.openai.com/examples/function_calling_with_an_openapi_spec

[9] https://haystack.deepset.ai/tutorials/40_building_chat_application_with_function_calling

この記事は、原著者の許可を得てBaihai IDPによって翻訳されました。翻訳の転載をご希望の場合は、お問い合わせください。

オリジナルリンク:

https://towardsdatascience.com/build-autonomous-ai-agents-with-function-calling-0bb483753975