「Agentic Design Pattern #1: Tool Calling」は、DAGWorks が本番環境でエージェントを信頼できるものにすると見てきたパターンを示し、それぞれを自社の Python ステートマシンライブラリである Burr で実装してみせるシリーズの第 1 回である。記事が述べる動機は、システムのモデリングについて助けを求める Burr ユーザーが急増していること、そして彼らがチャットボットを作った後には決まってエージェントの構築へと移っていくことである。加えて、エージェントは新しく混沌としたものとして扱われているものの、いくつかの共通パターンが現れてきているという観察も挙げている。記事はひとまずの作業上の定義として、エージェントとは、LLM の出力をそのまま繰り返すのではなく、それを使ってユーザーに代わって何かを行うもの全般である、と示す。
記事の大部分はコードが出てくる前の用語の整理に費やされている。著者は、「ツール」、「関数」、「構造化出力」の区別が実際以上に複雑にされていると考えているからである。その答えは率直で、ツールと関数は同義語だというものである。残りの部分は、その用語を使って 関数呼び出し を順に解説する。関数を定義し、それをモデルに説明し、モデルに 1 つを選ばせて引数を与えさせ、それを実行し、結果を整形する、という流れである。結びの節では、グラフの読みやすさ、可観測性、本番運用上の懸念を根拠に、API 呼び出しを直接書くのではなく Burr でこれをオーケストレーションすべきだと論じている。
要点
- エージェントを、モデルのテキストをそのままユーザーに返すのではなく、LLM の出力を使ってユーザーに代わって何かを行うもの全般として定義する。
- 「ツール」と「関数」は同義語だと論じる。ツールはソフトウェアエンジニアリングにおける関数という概念に対応する。コードで構築されたエージェントにとって、ユーザーに代わって行動する最も単純な方法は関数を呼び出すことであり、「ツール」はエージェントにできることを表す、より上位の言葉にすぎないからである。記事は「tool call」という言い回しを、「function call」と「tool use」が混ざり合ったものだとしている。
- 業界はまだ用語について足並みがそろっておらず、主要なモデルプロバイダーが自社の API やドキュメントで同じ機能に異なる名前をつけていると指摘する。
- 構造化出力をツール呼び出しから区別する。モデルがツールを選んだときに返ってくるのは、ツールの名前とその引数を JSON で表現したものであり、この JSON を生成する振る舞いを流用すれば、実際にはツールが背後に存在しない、完全に構造化された応答を得ることができる。記事はこれを、特定のツール呼び出し API に依存せずに一般化する方法として示している。
- このパターンが必要とする発想の転換の核心を示す。現在のモデルはおおむねインターネットから切り離されているため、開発者はモデルに天気がどうかを尋ねるのではなく、X、Y、Z ができるとして天気をどう調べればよいかを尋ねる。モデルの強みは、意図を見極めて何をすべきかを述べることであって、それを実行することではない。
- このパターンの実装を、ツール呼び出しをサポートする任意のプロバイダー API の上の薄いレイヤーとして説明する。ただし例は一貫して OpenAI を前提としている。Python の
inspectモジュールが関数のシグネチャを読み取って OpenAI 互換の型に整形するため、新しいツールを追加することは関数を追加することを意味する。 - すべての質問にツールが必要なわけではないという理由から、モデルが自身の知識から答えられるようにするフォールバックツールを推奨する。
- 単一のディスパッチ用アクションではなく、ツールごとに 1 つのアクションとしてモデリングすべきだと論じる。その目的は、利用可能なすべてのツールがアプリケーショングラフに現れるようにすることである。
- モデルはツールの選択において信頼性が低く、ツールを選ぶこと自体を拒むこともあれば、指示を見失うこともあったと報告し、ライブラリの UI で反復したプロンプトエンジニアリングによって妥当な振る舞いに到達したと述べている。
補足
この記事はベンダーが自社のライブラリについて書いたものであり、記事自身もそれをはっきりと述べている。結びの節の主張は、Burr のオーケストレーションと可観測性は依存関係を追加するに値するというものであり、例はおもちゃのアプリケーションであると認められている。今後を見据えた節では、シリーズで扱う予定のさらに 4 つのパターンを挙げている。質問に答えるためにツールを連鎖させること、一連のツールに並列で問い合わせて呼び出すこと、1 つの質問に複数のエージェントを使うこと、そしてエージェント同士を建設的に協働させることであり、いずれもこの記事では扱われていない。
コードそのものは抽出されたテキストには含まれていない。記事は例をスクリーンショットとして示し、gist やリポジトリの example ディレクトリへのリンクを添えているため、上に記録したのは実装ではなく設計上の議論である。