この包括的なリファレンスでは、エージェント フレームワークのすべてのコンポーネントについて詳しく説明しています。
フォルダ構造
エージェントをビルドするには、そのエージェントのフォルダを作成します。このフォルダには、エージェントの名前が付けられ、少なくとも次のファイルが含まれています。
agent.py
: エージェントのメインファイル。ルート エージェントは、グローバル変数root_agent
の下に定義する必要があります。__init__.py
: Python モジュール ファイル。少なくとも、Agent
クラスをインポートする行from agents import Agent
を含める必要があります。
必要に応じて、次のファイルを追加することをおすすめします。
requirements.txt
: エージェントの Python 要件ファイル。README.md
: エージェントの README ファイル。エージェントの設定と実行の手順が含まれている必要があります。
最小限の agent.py
エージェントの作成は、Agent
クラスのインスタンスを作成することから始まります。最低限のエージェントには次の属性が必要です。
name
: エージェントの名前。model
: 使用する LLM モデルの名前。instruction
: エージェント向けの自然言語による指示。
次に例を示します。
from agents import Agent
root_agent = Agent(
model='gemini-1.5-flash',
name='root_agent',
instruction="Be polite and answer all users' questions.",
)
最小限のエージェントを作成するには、フォルダ _empty_agent
をコピーして agent.py
ファイルを変更します。
属性
name
name: str
エージェントの名前。
識別子
- 名前は識別子の命名規則に従っている必要があります。
- 英数字(a ~ z、0 ~ 9)、アンダースコア(_)のみを含む文字列は、有効な識別子と見なされます。有効な識別子の先頭に数字を使用することはできません。また、スペースを含めることもできません。
一意
- 名前はエージェント ツリー全体で一意である必要があります。
ルート エージェント
- ルート エージェントの変数の名前は
root_agent
にする必要がありますが、ルート エージェントのよりわかりやすい名前属性を設定できます。
- ルート エージェントの変数の名前は
モデル
model: str
使用する LLM モデルの名前。
LLM エージェントの場合必須
- model 属性は LLM エージェントでのみ必須です。
- Sequential、Loop、その他の LLM 以外のエージェントの場合、モデル属性を設定する必要はありません。
親エージェント
- model 属性は省略できます。この場合、エージェントは親 / 祖先エージェントのモデル属性を使用します。
形式
- モデル名の形式は LLM のベンダーによって異なります。
- Gemini の場合は、
gemini-1.5-flash
またはgemini-2.0-flash-exp
のようになります。 - Vertex 上の Anthropic の場合は
claude-3-5-sonnet-v2@20241022
になります。 - フレームワークの設計では任意のモデル ベンダーを使用できますが、現在 Vertex でサポートされているのは Gemini と Anthropic のみです。
指示
instruction: str | InstructionProvider
エージェントに対する自然言語による指示。
LLM エージェントの場合必須
- この手順は LLM エージェントの場合のみ必要です。
- シーケンシャル エージェント、ループ エージェント、その他の LLM 以外のエージェントには、命令属性を設定する必要はありません。
データ型
- 命令は文字列にできます。
- 命令は、呼び出し可能な InstructionProvider にすることもできます。
InstructionProvider
- InstructionProvider は
Callable[[InvocationContext], str]
として定義されます。 - これにより、呼び出しコンテキストに基づいて命令を動的に生成する関数を指定できます。
- InstructionProvider は
都道府県
- 命令は文字列テンプレートです。{var} 構文を使用して、動的な値を命令に挿入できます。
var
は、var という名前の状態変数の値を挿入するために使用されます。artifact.var
は、var という名前のアーティファクトのテキスト コンテンツを挿入するために使用されます。- 状態変数またはアーティファクトが存在しない場合、エージェントはエラーを発生させます。エラーを無視する場合は、変数名に
?
を追加します(例:{var?}
)。
ガイドライン
- まず、エージェントが誰であるか、エージェントができること、エージェントができないことを説明します。
- マークダウン形式を使用すると、人間とモデルの両方にとってガイドラインを読みやすくすることができます。
- エージェントが複数のタスクを実行できる場合は、タスクのリストを用意し、タスクごとに個別のセクションを作成します。
- タスクに複数のステップがある場合は、ステップのリストと、各ステップの詳細な手順を指定します。
- エージェントがツールを使用できる場合は、
tools
属性にツールをリストします。ツール定義には使用方法が記載されていますが、エージェント インストラクションに、ツールを使用するタイミングに関する詳細な手順を追加してパフォーマンスを向上させることができます。 - マルチエージェント システムの場合は、他のエージェントに引き継ぐ必要があるタイミングを説明します。
- 指示に入力と想定される出力の例を含めることができます。また、
examples
属性を使用して例を提供することもできます。 - 指示は詳細かつ具体的にしてください。エージェントをトレーニング プロセスを行っている新入社員として扱います。
- 100% 遵守しなければならないルールの手順に依存しないでください。モデルには本質的に自由度があり、誤りが発生する可能性があります。ツールとコールバックを使用して厳格なルールを適用する。
説明
description: str
このエージェントが実行できるアクションを記述します。この記述は、システム インストラクションの一部としてモデルに送信されます。
エージェント自体は、説明に基づいて自身の機能を理解します。
エージェントは、他のエージェントができることを確認し、その説明に基づいて転送するかどうかを決定します。
global_instruction
global_instruction: str | InstructionProvider
エージェント ツリー全体に対するグローバルな指示。
指示は特定のエージェントに何をどのように行うかを指示しますが、グローバル指示はエージェント ツリー全体のすべてのエージェントに適用されます。
グローバル インストラクションの使用方法は、データ型、InstructionProvider のサポート、状態変数とアーティファクトへのアクセス機能など、インストラクション 属性と類似しています。
- 識別と動作
- グローバル インストラクションを使用すると、特定のエージェントに対して特定のタスクを行う方法ではなく、エージェント ツリー全体の ID と動作 / 標準を設定できます。
generate_content_config
generate_content_config: google.genai.types.GenerateContentConfig
エージェントの追加モデル構成。これらは、モデルへのリクエストに統合されます。
フレームワークによって管理されるため、このフィールドに設定しない属性がいくつかあります。- tools
- system_instruction
- response_schema
例
examples: list[Example] | BaseExampleProvider
エージェントの少数ショットの例。調査によると、少数ショットの例を提供することで、エージェントのパフォーマンスを向上させることができます。
- 静的例
- 静的な例のリストを指定できます。例は次のように定義されます。ここで、
input
は入力コンテンツ、output
は期待される出力コンテンツです。
- 静的な例のリストを指定できます。例は次のように定義されます。ここで、
class Example(BaseModel):
input: types.Content
output: list[types.Content]
出力リスト
- 出力は
Content
のリストにできます。 - そのため、想定される出力としてコンテンツのシーケンスを定義できます。たとえば、モデルはまず関数呼び出しを行い、次にテキストを生成する必要があります。
- 出力は
BaseExampleProvider
BaseExampleProvider
クラスのインスタンスを指定することもできます。BaseExampleProvider
クラスにはget_examples(query: str)
メソッドがあり、Example
のリストを返します。BaseExampleProvider
を使用すると、クエリに基づいて例を動的に生成できます。
greeting_prompt
greeting_prompt: str
モデルに送信されるプロンプトを設定して、挨拶メッセージを生成できます。応答メッセージは、空のセッションと空のユーザー入力でエージェントを呼び出すときに使用されます。
計画
planning: bool
planning
を True に設定すると、エージェントのプランニング モードが有効になります。プランニング モードでは、エージェントはまずユーザーのクエリに対応するプランを生成し、次にプランを段階的に実行します。
code_executor
code_executor: BaseCodeExecutor
作成したエージェントは、コードを記述して実行することで問題を解決できます。
コードの実行を有効にする方法は 2 つあります。
一部のモデルは、コードを直接実行できます。たとえば、ライブモードの Gemini 2.0 モデルは、個別のコード実行ツールを必要とせずに、コードを自動的に生成して実行します。
code_executor
属性をBaseCodeExecutor
クラスのインスタンスに設定して、コードの実行を有効にできます。現在、Vertex AI でコードを実行するために使用できるVertexCodeExecutor
クラスとUnsafeLocalCodeExecutor
クラスがあります(LLM によって生成されたコードは破壊的である可能性があるため、プロトタイピングにはUnsafeLocalCodeExecutor
のみを使用します)。今後、さらに多くのコード実行ツールが追加される予定です。
input_schema
input_schema: type[BaseModel]
Pydantic モデルを input_schema
として指定すると、エージェントは入力スキーマを適用します。入力コンテンツは、スキーマに準拠した JSON 文字列である必要があります。
output_schema
output_schema: type[BaseModel]
Pydantic モデルを output_schema
として指定すると、エージェントは出力スキーマを適用します。出力コンテンツは常に、スキーマに準拠した JSON 文字列になります。
output_key
output_key: str
エージェントは、output_key
属性で指定された名前で状態変数に出力を保存します。
include_contents
include_contents: Literal['default', 'none']
エージェントは、デフォルトでセッション履歴(チャット履歴)の内容を含めます。include_contents
属性を none
に設定して、この動作を無効にできます。この場合、特定のエージェントにはチャットの履歴が表示されません。これは、エージェントがチャット履歴を確認する必要がない場合に便利です。
ツール
ツールを使用できるかどうかで、エージェントとモデルの違いが決まります。ツールを複雑で多用途に使用できる能力が人間の特徴とみなされるのと同じです。
エージェント フレームワークでは、tools
属性を使用してエージェントにツールを渡します。tools
属性はツールのリストです。各ツールは次のいずれかです。
- Python 関数。
BaseTool
クラスを実装するクラス。
Python 関数ツール
Python 関数をツールとして定義できます。
パラメータ
- 関数には任意の数のパラメータを指定できます。
- 各パラメータは、JSON シリアル化可能な任意の型にできます。
- パラメータにデフォルト値を設定しないでください。これはモデルでサポートされていません。
戻り値の型
- 戻り値の型は辞書にする必要があります。
- 辞書以外のものを返すと、フレームワークはそれを 1 つのキー
result
を持つ辞書にラップします。 - 戻り値はわかりやすく記述してください。たとえば、数値のエラーコードを返す代わりに、人が読めるエラー メッセージを含む
error_message: str
を返します。この戻り値は、コードを実行するためではなく、モデルが読み取って理解するためのものです。 - モデルがオペレーションの一般的なステータスを理解できるように、
success
、error
、pending
などを示すstatus
キーを用意することをおすすめします。
ドキュメント ストリング
- 関数のドキュメントがツールの説明として使用され、モデルに送信されます。docstring が優れているほど、モデルはツールを適切に使用できます。
シンプル
- 関数の定義には多くの自由度がありますが、モデルがより正確に使用できるように、シンプルで簡単な関数にする必要があります。
- パラメータの数は少なくしたほうがよい。
- カスタムクラスではなく、できるだけ単純なデータ型(
str
、int
など)を使用してください。 - 関数名とパラメータは非常に重要です。
do_stuff()
という関数がある場合、フライトのキャンセルに使用されていることをモデルに伝えても、モデルがその関数を使用できないことがあります。 - 複雑な関数を小さな関数に分割します。たとえば、
update_profile(profile: Profile)
をupdate_name(name: str)
、update_age(age: int)
などに分割します。
手順のリファレンス
- 手順でツールを参照するには、その名前を使用します。
- 関数の名前とドキュメントが十分に詳細であれば、手順でツールを使用するタイミングにのみ焦点を当てることができます。
- さまざまな戻り値に対処する方法をエージェントに指示します。たとえば、ツールからエラー メッセージが返された場合、エージェントは諦めるか、再試行するか、詳細情報を尋ねるべきか。
- ツールは順番に使用できます。1 つのツールは別のツールの出力に依存できます。手順の順序を説明します。
ツールの概要
ツール関数に特別なパラメータ tool_context:
ToolContext
を追加すると、ツールが呼び出されるコンテキストに関する追加情報を取得できます。
ToolContext
クラスは agents.types
モジュールにあり、次の属性があります。
function_call_event_id: str
- ツール呼び出しがトリガーされたイベントの ID。
function_call_id: str
- 関数呼び出しの ID。
state: State
- 状態変数を読み取り、更新する辞書のようなオブジェクト。
actions: EventActions
- ツールで実行できる追加のアクション。
EventActions
クラスは agents.events
モジュールにあり、ツールが追加のアクションを実行できるように次の属性があります。
skip_summarization: bool
- True に設定すると、ツールが呼び出されたイベントの要約ステップがスキップされます。
transfer_to_agent: str
- 設定すると、フレームワークは
transfer_to_agent
属性で指定された名前のエージェントに転送されます。
- 設定すると、フレームワークは
escalate: bool
- True に設定すると、エージェントはクエリを親エージェントにエスカレーションします。LoopFlow 内の子エージェントからのエスカレーションは、ループの終了を意味します。
AsyncFunctionTool
AsyncFunctionTool は FunctionTool のサブクラスです。完了までに時間がかかるツール向けに設計されています。
AsyncFunctionTool を作成するには、通常の Python 関数を定義し、それを AsyncFunctionTool
クラスにラップする必要があります。次のようにします。
AsyncFunctionTool(func=your_function)
AsyncFunctionTool は引き続き Python 関数を呼び出します。ここで、時間がかかるタスクを開始できます。中間結果をモデルに返して、タスクがまだ完了していないことをモデルに知らせることができます。status: 'pending'
、progress: 20
、estimated_completion_time: '...'
などの情報を追加すると、モデルがユーザーに有意なレスポンスを提供できるようになります。
後でオペレーションが完了したら、新しい FunctionResponse を使用してエージェントを呼び出し、最終結果を提供できます。その時点で、エージェントはユーザーへの最終レスポンスを生成します。
AgentTool
AgentTool を使用すると、別のエージェントを呼び出してタスクを実行できます。これは、Python 関数を作成し、関数の引数で別のエージェントを呼び出し、そのエージェントのレスポンスを関数の戻り値として使用することと同等です。
AgentTool は子エージェントとは異なります。
- エージェント A がエージェントツールとしてエージェント B を呼び出すと、エージェント B の回答がエージェント A に渡され、エージェント A は回答を要約してユーザーへのレスポンスを生成します。今後のユーザー入力は、引き続きエージェント A が回答します。
- エージェント A が子エージェントとしてエージェント B を呼び出すと、ユーザーへの応答の責任はエージェント B に完全に移行されます。エージェント A は画面から消えます。この場合、今後のユーザー入力はエージェント B が対応します。
エージェントをツールとして使用するには、AgentTool
クラスを使用してエージェントをラップします。例: tools=[AgentTool(agent=agent_b)]
AgentTool には、動作をカスタマイズするための次の属性があります。
skip_summarization
- True に設定すると、フレームワークは LLM の呼び出しをスキップして、ツール エージェントのレスポンスを要約します。
コールバック
コールバックの種類
コールバックを定義することで、エージェントの動作をさらにカスタマイズできます。次の 2 種類のコールバックがサポートされています。
- BeforeCallbacks は、エージェントがアクションを実行する前に呼び出されます。アクションを変更したり、アクションをスキップしたり、追加のアクションを実行したりできます。
- AfterCallbacks は、エージェントがアクションを実行した後に呼び出されます。このコールバックを使用して、アクションの結果を変更したり、追加のアクションを実行したりできます。
サポートされているアクション
次のアクションには、BeforeCallbacks と AfterCallbacks があります。
- エージェントに電話する。
- LLM を呼び出す。
- ツールの呼び出し。
コールバックのリスト
その結果、次の 6 つのコールバックが作成されます。これらはすべて Agent
クラスの属性です。
before_agent_callback
def before_agent_callback(invocation_context: InvocationContext) -> Content | None
- 呼び出しには複数のエージェント呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
Content
を返すと、エージェントは現在のエージェント呼び出しをスキップし、返されたContent
をレスポンスとして使用します。
after_agent_callback
def after_agent_callback(invocation_context: InvocationContext) -> Content | None
- 呼び出しには複数のエージェント呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
Content
を返すと、エージェントは返されたContent
を自身のレスポンスの後に追加します。
before_model_callback
def before_model_callback(
invocation_context: InvocationContext,
llm_request: LlmRequest) -> LlmResponse | None
- エージェント呼び出しには複数の LLM 呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
LlmResponse
を返すと、エージェントは返されたLlmResponse
をレスポンスとして使用し、モデルの呼び出しをスキップします。
before_model_callback
def after_model_callback(
invocation_context: InvocationContext,
llm_response: LlmResponse) -> LlmResponse | None
- エージェント呼び出しには複数の LLM 呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
LlmResponse
を返すと、エージェントはモデルによって生成されたレスポンスではなく、返されたLlmResponse
をレスポンスとして使用します。
before_tool_callback
def before_tool_callback(
invocation_context: InvocationContext,
tool: BaseTool,
args: dict[str, Any],
tool_context: ToolContext) -> dict | None
- モデル呼び出しには複数のツール呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
dict
を返すと、エージェントは返されたdict
をレスポンスとして使用し、ツールの呼び出しをスキップします。
after_tool_callback
def after_tool_callback(
invocation_context: InvocationContext,
tool: BaseTool,
args: dict[str, Any],
tool_context: ToolContext,
response: dict) -> dict | None
- モデル呼び出しには複数のツール呼び出しを含めることができます。そのため、このコールバックは複数回呼び出される可能性があります。
- このコールバックから
dict
を返すと、エージェントはツールによって生成されたレスポンスではなく、返されたdict
をレスポンスとして使用します。
セッション
エージェントを構築するときに、セッション オブジェクトを直接操作する必要はありません。セッション オブジェクトはフレームワークによって管理されます。ただし、セッションの概要と仕組みを理解しておくことは有用です。
Agent Framework のセッションには、次の 2 つの主要コンポーネントがあります。
- イベント: イベントのリスト。
- State: 状態変数の辞書型オブジェクト。
イベント
Events は、イベント オブジェクトの単純なリストです。これは、ユーザーとエージェント間、またはエージェント間のチャット履歴と考えることができます。ユーザーやモデルからの単語だけでなく、エージェントが行うすべてのアクション(ツールの呼び出し、ツールのレスポンス、別のエージェントの呼び出しなど)も記録されます。
イベントリストは追記専用のリストです。リストにイベントを追加することはできますが、イベントの削除や変更はできません。イベントが発生した時点で、変更することはできません。システムがシンプルになり、いつでも特定の時点に戻ってシステムの正確なスナップショットを確認できるようにするためです。
州
状態は、すべての状態変数を含む辞書のようなオブジェクトです。以下の場所からアクセスできます。
- 命令から、
{var}
構文を使用して、var という名前の状態変数の値を挿入できます。 - コールバックから状態変数にアクセスするには、
invocation_context.state['key']
を使用します。invocation_context.state['key'] = value
を使用して状態変数を更新することもできます。 - ツールから状態変数にアクセスするには、
tool_context.state['key']
を使用します。tool_context.state['key'] = value
を使用して状態変数を更新することもできます。
状態は特定のセッションに関連付けられます。そのため、このセッションのコンテキストで役立つ情報を保存するのに最適な場所です。
状態には、エージェント ツリー内のすべてのエージェントがアクセスできるため、エージェント間の通信に最適です。1 つのエージェントがアクションを実行し、その結果を状態に保存すると、別のエージェントが状態から結果を読み取って作業を続行できます。
アーティファクト
モデルまたはツールによってファイル(画像、動画、ドキュメントなど)が作成された場合は、アーティファクトとして保存できます。アーティファクトは、特定のセッションに関連付けられたファイルで、エージェントまたは独自のコードからアクセスできます。
ユースケース
- エージェントがユーザーと連携してファイルを作成または変更する場合。たとえば、ユーザーが画像の生成と編集を支援するエージェントなどです。
- エージェントにファイルに関する質問に回答してもらいたい場合や、ユーザーの指示に基づいてファイルを編集してもらいたい場合。
パフォーマンス上のメリット
大規模なファイルを処理するもう 1 つの方法は、バイトとしてチャット履歴に保存することです。ただし、このアプローチにはいくつかのデメリットがあります。
- セッション履歴の処理速度が低下します。
- チャット履歴からファイルを取得するのは困難です。
- 会話がこれらのファイルと関係がない場合でも、すべてのリクエストでバイトがモデルに送信されます。
アーティファクトへのアクセス
アーティファクトにアクセスする方法はいくつかあります。
- この命令では、
{artifact.var}
構文を使用して、var という名前のアーティファクトのテキスト コンテンツを挿入できます。バイナリ アーティファクトはまだサポートされていません。 - コールバックで、
invocation_context.get_artifact('key')
を使用してアーティファクトにアクセスできます。アーティファクトはinvocation_context.set_artifact('key', value)
で更新できます。 - ツールでアーティファクトにアクセスするには、
tool_context.get_artifact('key')
を使用します。アーティファクトはtool_context.set_artifact('key', value)
で更新できます。
マルチエージェント システム
単一のエージェントとリストツールを使用して、複雑なシステムを構築できます。ただし、ロジックを複数のエージェントに分離することで、システム全体のパフォーマンスとメンテナンス性が向上する場合があります。
次のような場合は、複数のエージェントを使用することを検討してください。
- エージェントの指示が長すぎる場合(複数のタスクがあり、各タスクに複数の手順がある場合)。
- 実行するワークフローが確定的である場合。たとえば、調査エージェントの場合、常にプランを生成し、プランを実行してから、検出結果を要約します。
階層エージェント ツリー
children: list[BaseAgent]
マルチエージェント システムを構築するには、階層エージェント ツリーを作成します。ルート エージェントはシステムのエントリ ポイントであり、構成に応じて他のエージェントを呼び出すことができます。
エージェントには複数の子エージェントを設定できます。子エージェントは、独自の子エージェントを持つこともできます。エージェント ツリーは任意の深さにできますが、パフォーマンス上の理由から、浅いツリーをおすすめします。
エージェント ツリーを形成するには、他のエージェントを親エージェントの子として配置します。
フロー
flow: str | BaseFlow | FlowCallable
エージェントは、ユーザーのクエリを受け取ったときに、クエリを自分で処理するか、別のエージェントに引き継ぐかを選択できます。これは flow
属性で定義します。
事前定義されたフローもありますが、独自のフローを定義することもできます。
sequential
: エージェントは、子エージェントを順番に 1 つずつ呼び出します。loop
: エージェントは、子エージェントをループで呼び出します。いずれかの子エージェントがtool_context.actions.escalate
を True に設定するまで。single
: これは LLM ベースのフローです。エージェントは LLM を呼び出してユーザーのクエリに回答し、必要に応じてツールを呼び出します。auto
: これは LLM ベースのフローです。エージェントは LLM を呼び出してユーザーのクエリに回答し、必要に応じてツールを呼び出します。また、子、兄弟、親にクエリを転送することもできます。- カスタムフロー:
BaseFlow
クラスを実装して独自のフローを定義することも、インターフェースに沿って Python 関数を定義することもできます。