リファレンス ガイド

この包括的なリファレンスでは、エージェント フレームワークのすべてのコンポーネントについて詳しく説明しています。

フォルダ構造

エージェントをビルドするには、そのエージェントのフォルダを作成します。このフォルダには、エージェントの名前が付けられ、少なくとも次のファイルが含まれています。

  • 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] として定義されます。
    • これにより、呼び出しコンテキストに基づいて命令を動的に生成する関数を指定できます。
  • 都道府県

    • 命令は文字列テンプレートです。{var} 構文を使用して、動的な値を命令に挿入できます。

    var

    は、var という名前の状態変数の値を挿入するために使用されます。

    artifact.var

    は、var という名前のアーティファクトのテキスト コンテンツを挿入するために使用されます。
    • 状態変数またはアーティファクトが存在しない場合、エージェントはエラーを発生させます。エラーを無視する場合は、変数名に ? を追加します(例: {var?})。
  • ガイドライン

    • まず、エージェントが誰であるか、エージェントができること、エージェントができないことを説明します。
    • マークダウン形式を使用すると、人間とモデルの両方にとってガイドラインを読みやすくすることができます。
    • エージェントが複数のタスクを実行できる場合は、タスクのリストを用意し、タスクごとに個別のセクションを作成します。
    • タスクに複数のステップがある場合は、ステップのリストと、各ステップの詳細な手順を指定します。
    • エージェントがツールを使用できる場合は、tools 属性にツールをリストします。ツール定義には使用方法が記載されていますが、エージェント インストラクションに、ツールを使用するタイミングに関する詳細な手順を追加してパフォーマンスを向上させることができます。
    • マルチエージェント システムの場合は、他のエージェントに引き継ぐ必要があるタイミングを説明します。
    • 指示に入力と想定される出力の例を含めることができます。また、examples 属性を使用して例を提供することもできます。
    • 指示は詳細かつ具体的にしてください。エージェントをトレーニング プロセスを行っている新入社員として扱います。
    • 100% 遵守しなければならないルールの手順に依存しないでください。モデルには本質的に自由度があり、誤りが発生する可能性があります。ツールとコールバックを使用して厳格なルールを適用する。

説明

  description: str

このエージェントが実行できるアクションを記述します。この記述は、システム インストラクションの一部としてモデルに送信されます。

  1. エージェント自体は、説明に基づいて自身の機能を理解します。

  2. エージェントは、他のエージェントができることを確認し、その説明に基づいて転送するかどうかを決定します。

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 つあります。

  1. 一部のモデルは、コードを直接実行できます。たとえば、ライブモードの Gemini 2.0 モデルは、個別のコード実行ツールを必要とせずに、コードを自動的に生成して実行します。

  2. 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 を返します。この戻り値は、コードを実行するためではなく、モデルが読み取って理解するためのものです。
    • モデルがオペレーションの一般的なステータスを理解できるように、successerrorpending などを示す status キーを用意することをおすすめします。
  • ドキュメント ストリング

    • 関数のドキュメントがツールの説明として使用され、モデルに送信されます。docstring が優れているほど、モデルはツールを適切に使用できます。
  • シンプル

    • 関数の定義には多くの自由度がありますが、モデルがより正確に使用できるように、シンプルで簡単な関数にする必要があります。
    • パラメータの数は少なくしたほうがよい。
    • カスタムクラスではなく、できるだけ単純なデータ型(strint など)を使用してください。
    • 関数名とパラメータは非常に重要です。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: 20estimated_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 関数を定義することもできます。