From ece647b93f02e8ed3c8c3ee1d10c035e10c65984 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Tue, 8 Apr 2025 22:41:48 +0900 Subject: [PATCH 01/21] Add i18n support to the documents (#460) --- Makefile | 5 + docs/ja/agents.md | 147 ++++++++++++++++++ docs/ja/config.md | 94 ++++++++++++ docs/ja/context.md | 77 ++++++++++ docs/ja/examples.md | 40 +++++ docs/ja/guardrails.md | 154 +++++++++++++++++++ docs/ja/handoffs.md | 113 ++++++++++++++ docs/ja/index.md | 52 +++++++ docs/ja/mcp.md | 59 ++++++++ docs/ja/models.md | 93 ++++++++++++ docs/ja/multi_agent.md | 37 +++++ docs/ja/quickstart.md | 188 +++++++++++++++++++++++ docs/ja/results.md | 52 +++++++ docs/ja/running_agents.md | 95 ++++++++++++ docs/ja/streaming.md | 87 +++++++++++ docs/ja/tools.md | 269 +++++++++++++++++++++++++++++++++ docs/ja/tracing.md | 102 +++++++++++++ docs/ja/visualization.md | 83 ++++++++++ docs/ja/voice/pipeline.md | 75 +++++++++ docs/ja/voice/quickstart.md | 194 ++++++++++++++++++++++++ docs/ja/voice/tracing.md | 14 ++ docs/scripts/translate_docs.py | 158 +++++++++++++++++++ mkdocs.yml | 188 ++++++++++++++--------- pyproject.toml | 2 + uv.lock | 16 ++ 25 files changed, 2321 insertions(+), 73 deletions(-) create mode 100644 docs/ja/agents.md create mode 100644 docs/ja/config.md create mode 100644 docs/ja/context.md create mode 100644 docs/ja/examples.md create mode 100644 docs/ja/guardrails.md create mode 100644 docs/ja/handoffs.md create mode 100644 docs/ja/index.md create mode 100644 docs/ja/mcp.md create mode 100644 docs/ja/models.md create mode 100644 docs/ja/multi_agent.md create mode 100644 docs/ja/quickstart.md create mode 100644 docs/ja/results.md create mode 100644 docs/ja/running_agents.md create mode 100644 docs/ja/streaming.md create mode 100644 docs/ja/tools.md create mode 100644 docs/ja/tracing.md create mode 100644 docs/ja/visualization.md create mode 100644 docs/ja/voice/pipeline.md create mode 100644 docs/ja/voice/quickstart.md create mode 100644 docs/ja/voice/tracing.md create mode 100644 docs/scripts/translate_docs.py diff --git a/Makefile b/Makefile index accf2d91..5c6aba42 100644 --- a/Makefile +++ b/Makefile @@ -42,6 +42,11 @@ old_version_tests: build-docs: uv run mkdocs build +.PHONY: build-full-docs +build-full-docs: + uv run docs/scripts/translate_docs.py + uv run mkdocs build + .PHONY: serve-docs serve-docs: uv run mkdocs serve diff --git a/docs/ja/agents.md b/docs/ja/agents.md new file mode 100644 index 00000000..e9e303bc --- /dev/null +++ b/docs/ja/agents.md @@ -0,0 +1,147 @@ +# エージェント + +エージェント はアプリケーションの基本的な構成要素です。エージェント は、大規模言語モデル(LLM)であり、 instructions と tools を用いて設定されます。 + +## 基本設定 + +エージェント の設定でよく使われるプロパティは以下の通りです。 + +- `instructions` : 開発者メッセージまたはシステムプロンプトとも呼ばれます。 +- `model` : 使用する LLM を指定します。オプションで `model_settings` を指定し、temperature や top_p などのモデル調整パラメータを設定できます。 +- `tools` : エージェント がタスクを達成するために使用できるツールです。 + +```python +from agents import Agent, ModelSettings, function_tool + +@function_tool +def get_weather(city: str) -> str: + return f"The weather in {city} is sunny" + +agent = Agent( + name="Haiku agent", + instructions="Always respond in haiku form", + model="o3-mini", + tools=[get_weather], +) +``` + +## コンテキスト + +エージェント は、 `context` 型に対してジェネリックです。コンテキストは依存性注入のためのツールであり、作成したオブジェクトを `Runner.run()` に渡すことで、各エージェント、ツール、ハンドオフなどに渡されます。これはエージェントの実行に必要な依存関係や状態をまとめて保持するためのものです。任意の Python オブジェクトをコンテキストとして提供できます。 + +```python +@dataclass +class UserContext: + uid: str + is_pro_user: bool + + async def fetch_purchases() -> list[Purchase]: + return ... + +agent = Agent[UserContext]( + ..., +) +``` + +## 出力タイプ + +デフォルトでは、エージェント はプレーンテキスト(つまり `str` )を出力します。特定の型の出力を生成させたい場合は、 `output_type` パラメータを使用します。一般的には [Pydantic](https://docs.pydantic.dev/) オブジェクトを使用しますが、Pydantic の [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) でラップ可能な型(データクラス、リスト、TypedDict など)であればどのような型でもサポートしています。 + +```python +from pydantic import BaseModel +from agents import Agent + + +class CalendarEvent(BaseModel): + name: str + date: str + participants: list[str] + +agent = Agent( + name="Calendar extractor", + instructions="Extract calendar events from text", + output_type=CalendarEvent, +) +``` + +!!! note + + `output_type` を指定すると、モデルは通常のプレーンテキストのレスポンスではなく、 [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用します。 + +## ハンドオフ + +ハンドオフ は、エージェント が処理を委譲できるサブエージェントです。ハンドオフのリストを提供すると、エージェント は必要に応じてそれらに処理を委譲できます。これは、特定のタスクに特化したモジュール型のエージェントを組み合わせて調整するための強力なパターンです。詳細は [ハンドオフ](handoffs.md) のドキュメントを参照してください。 + +```python +from agents import Agent + +booking_agent = Agent(...) +refund_agent = Agent(...) + +triage_agent = Agent( + name="Triage agent", + instructions=( + "Help the user with their questions." + "If they ask about booking, handoff to the booking agent." + "If they ask about refunds, handoff to the refund agent." + ), + handoffs=[booking_agent, refund_agent], +) +``` + +## 動的な instructions + +多くの場合、エージェント 作成時に instructions を指定しますが、関数を通じて動的に instructions を提供することも可能です。この関数はエージェントとコンテキストを受け取り、プロンプトを返します。通常の関数と `async` 関数の両方が使用可能です。 + +```python +def dynamic_instructions( + context: RunContextWrapper[UserContext], agent: Agent[UserContext] +) -> str: + return f"The user's name is {context.context.name}. Help them with their questions." + + +agent = Agent[UserContext]( + name="Triage agent", + instructions=dynamic_instructions, +) +``` + +## ライフサイクルイベント(フック) + +エージェント のライフサイクルを監視したい場合があります。例えば、イベントをログに記録したり、特定のイベント発生時にデータを事前取得したりできます。エージェント のライフサイクルにフックするには、 `hooks` プロパティを使用します。[`AgentHooks`][agents.lifecycle.AgentHooks] クラスをサブクラス化し、関心のあるメソッドをオーバーライドします。 + +## ガードレール + +ガードレール を使用すると、エージェント の実行と並行してユーザー入力に対するチェックや検証を実行できます。例えば、ユーザー入力の関連性を検証できます。詳細は [ガードレール](guardrails.md) のドキュメントを参照してください。 + +## エージェント の複製(クローン) + +エージェント の `clone()` メソッドを使用すると、エージェント を複製し、必要に応じてプロパティを変更できます。 + +```python +pirate_agent = Agent( + name="Pirate", + instructions="Write like a pirate", + model="o3-mini", +) + +robot_agent = pirate_agent.clone( + name="Robot", + instructions="Write like a robot", +) +``` + +## ツール使用の強制 + +ツールのリストを提供しても、必ずしも LLM がツールを使用するとは限りません。ツールの使用を強制するには、 [`ModelSettings.tool_choice`][agents.model_settings.ModelSettings.tool_choice] を設定します。有効な値は以下の通りです。 + +1. `auto` : LLM がツールを使用するかどうかを決定します。 +2. `required` : LLM にツールの使用を強制します(ただし、どのツールを使用するかは LLM が判断します)。 +3. `none` : LLM にツールを使用しないことを強制します。 +4. 特定の文字列(例: `my_tool` )を設定すると、LLM はその特定のツールを使用することを強制されます。 + +!!! note + + 無限ループを防ぐため、フレームワークはツール呼び出し後に自動的に `tool_choice` を "auto" にリセットします。この動作は [`agent.reset_tool_choice`][agents.agent.Agent.reset_tool_choice] で設定可能です。無限ループは、ツールの実行結果が LLM に送信され、再びツール呼び出しが生成されるために発生します。 + + ツール呼び出し後に完全に停止させたい場合(自動モードで続行しない場合)は、 [`Agent.tool_use_behavior="stop_on_first_tool"`] を設定すると、ツールの出力を最終レスポンスとして直接使用し、それ以上の LLM 処理を行いません。 \ No newline at end of file diff --git a/docs/ja/config.md b/docs/ja/config.md new file mode 100644 index 00000000..6a764eb7 --- /dev/null +++ b/docs/ja/config.md @@ -0,0 +1,94 @@ +# SDK の設定 + +## API キーとクライアント + +デフォルトでは、SDK はインポート時に LLM リクエストおよびトレーシング用の環境変数 `OPENAI_API_KEY` を参照します。アプリケーションの起動前にこの環境変数を設定できない場合は、[set_default_openai_key()][agents.set_default_openai_key] 関数を使用してキーを設定できます。 + +```python +from agents import set_default_openai_key + +set_default_openai_key("sk-...") +``` + +また、使用する OpenAI クライアントを設定することも可能です。デフォルトでは、SDK は環境変数または上記で設定したデフォルトキーを使用して `AsyncOpenAI` インスタンスを作成します。これを変更するには、[set_default_openai_client()][agents.set_default_openai_client] 関数を使用します。 + +```python +from openai import AsyncOpenAI +from agents import set_default_openai_client + +custom_client = AsyncOpenAI(base_url="...", api_key="...") +set_default_openai_client(custom_client) +``` + +さらに、使用する OpenAI API をカスタマイズすることもできます。デフォルトでは OpenAI Responses API を使用しますが、[set_default_openai_api()][agents.set_default_openai_api] 関数を使用して Chat Completions API に変更できます。 + +```python +from agents import set_default_openai_api + +set_default_openai_api("chat_completions") +``` + +## トレーシング + +トレーシングはデフォルトで有効になっています。デフォルトでは、前述のセクションで設定した OpenAI API キー(環境変数またはデフォルトキー)を使用します。トレーシング専用の API キーを設定するには、[`set_tracing_export_api_key`][agents.set_tracing_export_api_key] 関数を使用します。 + +```python +from agents import set_tracing_export_api_key + +set_tracing_export_api_key("sk-...") +``` + +また、[`set_tracing_disabled()`][agents.set_tracing_disabled] 関数を使用してトレーシングを完全に無効化することもできます。 + +```python +from agents import set_tracing_disabled + +set_tracing_disabled(True) +``` + +## デバッグログ + +SDK はデフォルトでハンドラーが設定されていない 2 つの Python ロガーを持っています。デフォルトでは、警告およびエラーが `stdout` に送信され、それ以外のログは抑制されます。 + +詳細なログを有効にするには、[`enable_verbose_stdout_logging()`][agents.enable_verbose_stdout_logging] 関数を使用します。 + +```python +from agents import enable_verbose_stdout_logging + +enable_verbose_stdout_logging() +``` + +また、ハンドラー、フィルター、フォーマッターなどを追加してログをカスタマイズすることも可能です。詳細については、[Python logging ガイド](https://docs.python.org/3/howto/logging.html) を参照してください。 + +```python +import logging + +logger = logging.getLogger("openai.agents") # トレーシング用ロガーの場合は openai.agents.tracing + +# すべてのログを表示する場合 +logger.setLevel(logging.DEBUG) +# INFO 以上を表示する場合 +logger.setLevel(logging.INFO) +# WARNING 以上を表示する場合 +logger.setLevel(logging.WARNING) +# その他、必要に応じて設定 + +# 必要に応じてカスタマイズ可能ですが、デフォルトでは `stderr` に出力されます +logger.addHandler(logging.StreamHandler()) +``` + +### ログ内の機密データ + +一部のログには機密データ(ユーザーデータなど)が含まれる場合があります。このデータのログ記録を無効化したい場合は、以下の環境変数を設定してください。 + +LLM の入力および出力のログ記録を無効化する場合: + +```bash +export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 +``` + +ツールの入力および出力のログ記録を無効化する場合: + +```bash +export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 +``` \ No newline at end of file diff --git a/docs/ja/context.md b/docs/ja/context.md new file mode 100644 index 00000000..9ad6dc33 --- /dev/null +++ b/docs/ja/context.md @@ -0,0 +1,77 @@ +# コンテキスト管理 + +コンテキストという用語は多義的です。主に次の 2 種類のコンテキストがあります。 + +1. コード内でローカルに利用可能なコンテキスト:これは、関数ツールの実行時、`on_handoff` などのコールバック時、ライフサイクルフック時などに必要となるデータや依存関係です。 +2. LLM が利用可能なコンテキスト:これは、LLM が応答を生成する際に参照するデータです。 + +## ローカルコンテキスト + +これは [`RunContextWrapper`][agents.run_context.RunContextWrapper] クラスと、その内部の [`context`][agents.run_context.RunContextWrapper.context] プロパティを通じて表現されます。動作の仕組みは以下の通りです。 + +1. 任意の Python オブジェクトを作成します。一般的にはデータクラスや Pydantic オブジェクトを使用します。 +2. 作成したオブジェクトを各種の実行メソッドに渡します(例:`Runner.run(..., context=whatever)`)。 +3. すべての関数ツール呼び出しやライフサイクルフックなどには、ラッパーオブジェクト `RunContextWrapper[T]` が渡されます。ここで `T` はコンテキストオブジェクトの型を表し、`wrapper.context` を通じてアクセスできます。 + +**最も重要な点** は、特定のエージェント実行において、すべてのエージェント、関数ツール、ライフサイクルフックなどが同じコンテキストの _型_ を使用しなければならないということです。 + +コンテキストは以下のような用途で使用できます。 + +- 実行時のコンテキストデータ(ユーザー名や UID など、ユーザーに関する情報) +- 依存関係(ロガーオブジェクト、データ取得用オブジェクトなど) +- ヘルパー関数 + +!!! danger "注意" + + コンテキストオブジェクトは LLM には送信され **ません**。これは純粋にローカルなオブジェクトであり、読み取り、書き込み、メソッド呼び出しが可能です。 + +```python +import asyncio +from dataclasses import dataclass + +from agents import Agent, RunContextWrapper, Runner, function_tool + +@dataclass +class UserInfo: # (1)! + name: str + uid: int + +@function_tool +async def fetch_user_age(wrapper: RunContextWrapper[UserInfo]) -> str: # (2)! + return f"User {wrapper.context.name} is 47 years old" + +async def main(): + user_info = UserInfo(name="John", uid=123) + + agent = Agent[UserInfo]( # (3)! + name="Assistant", + tools=[fetch_user_age], + ) + + result = await Runner.run( # (4)! + starting_agent=agent, + input="What is the age of the user?", + context=user_info, + ) + + print(result.final_output) # (5)! + # The user John is 47 years old. + +if __name__ == "__main__": + asyncio.run(main()) +``` + +1. これがコンテキストオブジェクトです。ここではデータクラスを使用していますが、任意の型を使用できます。 +2. これは関数ツールです。`RunContextWrapper[UserInfo]` を引数として受け取り、コンテキストからデータを読み取っています。 +3. エージェントにジェネリック型 `UserInfo` を指定することで、型チェッカーがエラーを検出できるようにしています(例えば、異なるコンテキスト型を取るツールを渡そうとした場合など)。 +4. コンテキストを `run` 関数に渡しています。 +5. エージェントが正しくツールを呼び出し、年齢を取得しています。 + +## エージェント / LLM コンテキスト + +LLM が呼び出される際、参照できるデータは会話履歴に含まれるもの **のみ** です。そのため、新しいデータを LLM に提供したい場合は、会話履歴に含まれるようにする必要があります。これを実現する方法はいくつかあります。 + +1. エージェントの `instructions` に追加する方法です。これは「システムプロンプト」または「開発者メッセージ」とも呼ばれます。システムプロンプトは静的な文字列でもよく、またはコンテキストを受け取って文字列を出力する動的な関数でも構いません。これは常に有用な情報(ユーザー名や現在の日付など)を提供する際によく使われる手法です。 +2. `Runner.run` 関数を呼び出す際の `input` に追加する方法です。これは `instructions` と似ていますが、[指揮系統(chain of command)](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command) の下位に位置するメッセージを設定できます。 +3. 関数ツールを通じて公開する方法です。これは _オンデマンド_ なコンテキストに有効で、LLM が必要なデータを判断し、そのデータを取得するためにツールを呼び出します。 +4. 検索(retrieval)やウェブ検索を使用する方法です。これらはファイルやデータベースから関連データを取得(検索)したり、ウェブからデータを取得(ウェブ検索)したりする特殊なツールです。これは関連するコンテキストデータに基づいて応答を「根拠付ける(grounding)」際に有効です。 \ No newline at end of file diff --git a/docs/ja/examples.md b/docs/ja/examples.md new file mode 100644 index 00000000..6d9252aa --- /dev/null +++ b/docs/ja/examples.md @@ -0,0 +1,40 @@ +# コード例 + +SDK のさまざまな実装サンプルについては、[リポジトリ](https://github.com/openai/openai-agents-python/tree/main/examples) のコード例セクションをご覧ください。コード例は、異なるパターンや機能を示す複数のカテゴリに分類されています。 + +## カテゴリ + +- **[agent_patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns):** + このカテゴリのコード例では、一般的なエージェント設計パターンを示しています。例えば、 + + - 決定論的ワークフロー + - ツールとしてのエージェント + - エージェントの並列実行 + +- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):** + SDK の基本的な機能を示すコード例です。例えば、 + + - 動的なシステムプロンプト + - ストリーミング出力 + - ライフサイクルイベント + +- **[tool examples](https://github.com/openai/openai-agents-python/tree/main/examples/tools):** + Web 検索やファイル検索などの OpenAI がホストするツールの実装方法と、それらをエージェントに統合する方法を学べます。 + +- **[model providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):** + SDK で OpenAI 以外のモデルを使用する方法を確認できます。 + +- **[handoffs](https://github.com/openai/openai-agents-python/tree/main/examples/handoffs):** + エージェントのハンドオフに関する実践的なコード例を参照できます。 + +- **[mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp):** + MCP を使用したエージェントの構築方法を学べます。 + +- **[customer_service](https://github.com/openai/openai-agents-python/tree/main/examples/customer_service)** および **[research_bot](https://github.com/openai/openai-agents-python/tree/main/examples/research_bot):** + 実際のアプリケーションを示す、より具体的なコード例です。 + + - **customer_service**:航空会社向けのカスタマーサービスシステムのコード例。 + - **research_bot**:シンプルな詳細調査クローンのコード例。 + +- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):** + TTS および STT モデルを使用した音声エージェントのコード例を参照できます。 \ No newline at end of file diff --git a/docs/ja/guardrails.md b/docs/ja/guardrails.md new file mode 100644 index 00000000..1c55b0e0 --- /dev/null +++ b/docs/ja/guardrails.md @@ -0,0 +1,154 @@ +# ガードレール + +ガードレールは、エージェント と _並行して_ 実行され、ユーザー入力のチェックや検証を可能にします。例えば、顧客のリクエストを処理するために非常に高性能(したがって遅く高価)なモデルを使用する エージェント があるとします。悪意のあるユーザーがそのモデルに数学の宿題を解かせるようなことは避けたいでしょう。そのため、高速で安価なモデルを使った ガードレール を実行できます。ガードレール が悪意のある使用を検知すると、即座にエラーを発生させ、高価なモデルの実行を停止し、時間とコストを節約できます。 + +ガードレール には 2 種類あります: + +1. 入力ガードレール:最初のユーザー入力に対して実行されます。 +2. 出力ガードレール:最終的な エージェント の出力に対して実行されます。 + +## 入力ガードレール + +入力ガードレール は次の 3 ステップで実行されます: + +1. 最初に、ガードレール は エージェント に渡されたものと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`InputGuardrailResult`][agents.guardrail.InputGuardrailResult] にラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な応答や例外処理が可能になります。 + +!!! Note + + 入力ガードレール はユーザー入力に対して実行されるため、エージェント の ガードレール は、その エージェント が *最初の* エージェント である場合にのみ実行されます。なぜ `guardrails` プロパティが エージェント にあり、`Runner.run` に渡されないのか疑問に思うかもしれませんが、これは ガードレール が実際の エージェント に関連付けられる傾向があるためです。異なる エージェント には異なる ガードレール を実行するため、コードを同じ場所に配置することで可読性が向上します。 + +## 出力ガードレール + +出力ガードレール は次の 3 ステップで実行されます: + +1. 最初に、ガードレール は エージェント に渡されたものと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] にラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な応答や例外処理が可能になります。 + +!!! Note + + 出力ガードレール は最終的な エージェント の出力に対して実行されるため、エージェント の ガードレール は、その エージェント が *最後の* エージェント である場合にのみ実行されます。入力ガードレール と同様に、これは ガードレール が実際の エージェント に関連付けられる傾向があるためです。異なる エージェント には異なる ガードレール を実行するため、コードを同じ場所に配置することで可読性が向上します。 + +## トリップワイヤ(Tripwires) + +入力または出力が ガードレール を通過できない場合、ガードレール はトリップワイヤを使ってこれを通知します。トリップワイヤがトリガーされた ガードレール を検知すると、即座に `{Input,Output}GuardrailTripwireTriggered` 例外を発生させ、エージェント の実行を停止します。 + +## ガードレール の実装 + +入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を返す関数を提供する必要があります。この例では、内部で エージェント を実行することでこれを実現します。 + +```python +from pydantic import BaseModel +from agents import ( + Agent, + GuardrailFunctionOutput, + InputGuardrailTripwireTriggered, + RunContextWrapper, + Runner, + TResponseInputItem, + input_guardrail, +) + +class MathHomeworkOutput(BaseModel): + is_math_homework: bool + reasoning: str + +guardrail_agent = Agent( # (1)! + name="Guardrail check", + instructions="Check if the user is asking you to do their math homework.", + output_type=MathHomeworkOutput, +) + + +@input_guardrail +async def math_guardrail( # (2)! + ctx: RunContextWrapper[None], agent: Agent, input: str | list[TResponseInputItem] +) -> GuardrailFunctionOutput: + result = await Runner.run(guardrail_agent, input, context=ctx.context) + + return GuardrailFunctionOutput( + output_info=result.final_output, # (3)! + tripwire_triggered=result.final_output.is_math_homework, + ) + + +agent = Agent( # (4)! + name="Customer support agent", + instructions="You are a customer support agent. You help customers with their questions.", + input_guardrails=[math_guardrail], +) + +async def main(): + # This should trip the guardrail + try: + await Runner.run(agent, "Hello, can you help me solve for x: 2x + 3 = 11?") + print("Guardrail didn't trip - this is unexpected") + + except InputGuardrailTripwireTriggered: + print("Math homework guardrail tripped") +``` + +1. この エージェント を ガードレール関数 内で使用します。 +2. これは エージェント の入力とコンテキストを受け取り、結果を返す ガードレール関数 です。 +3. ガードレール の結果に追加情報を含めることができます。 +4. これはワークフローを定義する実際の エージェント です。 + +出力ガードレール も同様です。 + +```python +from pydantic import BaseModel +from agents import ( + Agent, + GuardrailFunctionOutput, + OutputGuardrailTripwireTriggered, + RunContextWrapper, + Runner, + output_guardrail, +) +class MessageOutput(BaseModel): # (1)! + response: str + +class MathOutput(BaseModel): # (2)! + reasoning: str + is_math: bool + +guardrail_agent = Agent( + name="Guardrail check", + instructions="Check if the output includes any math.", + output_type=MathOutput, +) + +@output_guardrail +async def math_guardrail( # (3)! + ctx: RunContextWrapper, agent: Agent, output: MessageOutput +) -> GuardrailFunctionOutput: + result = await Runner.run(guardrail_agent, output.response, context=ctx.context) + + return GuardrailFunctionOutput( + output_info=result.final_output, + tripwire_triggered=result.final_output.is_math, + ) + +agent = Agent( # (4)! + name="Customer support agent", + instructions="You are a customer support agent. You help customers with their questions.", + output_guardrails=[math_guardrail], + output_type=MessageOutput, +) + +async def main(): + # This should trip the guardrail + try: + await Runner.run(agent, "Hello, can you help me solve for x: 2x + 3 = 11?") + print("Guardrail didn't trip - this is unexpected") + + except OutputGuardrailTripwireTriggered: + print("Math output guardrail tripped") +``` + +1. これは実際の エージェント の出力タイプです。 +2. これは ガードレール の出力タイプです。 +3. これは エージェント の出力を受け取り、結果を返す ガードレール関数 です。 +4. これはワークフローを定義する実際の エージェント です。 \ No newline at end of file diff --git a/docs/ja/handoffs.md b/docs/ja/handoffs.md new file mode 100644 index 00000000..2d5433f4 --- /dev/null +++ b/docs/ja/handoffs.md @@ -0,0 +1,113 @@ +# ハンドオフ + +ハンドオフを使用すると、あるエージェントが別のエージェントにタスクを委任できます。これは、異なるエージェントがそれぞれ特定の分野を専門としている場合に特に役立ちます。例えば、カスタマーサポートアプリでは、注文状況、返金、FAQ などのタスクをそれぞれ専門に処理するエージェントを用意できます。 + +ハンドオフは、LLM に対してツールとして表現されます。例えば、`Refund Agent` という名前のエージェントへのハンドオフがある場合、そのツールは `transfer_to_refund_agent` と呼ばれます。 + +## ハンドオフの作成 + +すべてのエージェントは [`handoffs`][agents.agent.Agent.handoffs] パラメータを持ち、これは直接 `Agent` を指定するか、またはカスタマイズされた `Handoff` オブジェクトを指定できます。 + +Agents SDK が提供する [`handoff()`][agents.handoffs.handoff] 関数を使用してハンドオフを作成できます。この関数を使用すると、ハンドオフ先のエージェントを指定し、オプションでオーバーライドや入力フィルターを設定できます。 + +### 基本的な使用方法 + +シンプルなハンドオフの作成方法は以下の通りです。 + +```python +from agents import Agent, handoff + +billing_agent = Agent(name="Billing agent") +refund_agent = Agent(name="Refund agent") + +# (1)! +triage_agent = Agent(name="Triage agent", handoffs=[billing_agent, handoff(refund_agent)]) +``` + +1. エージェントを直接指定する方法(`billing_agent` のように)と、`handoff()` 関数を使用する方法があります。 + +### `handoff()` 関数を使用したハンドオフのカスタマイズ + +[`handoff()`][agents.handoffs.handoff] 関数を使用すると、以下の項目をカスタマイズできます。 + +- `agent`:ハンドオフ先のエージェントを指定します。 +- `tool_name_override`:デフォルトでは `Handoff.default_tool_name()` 関数が使用され、`transfer_to_` という形式になりますが、これをオーバーライドできます。 +- `tool_description_override`:デフォルトのツール説明(`Handoff.default_tool_description()`)をオーバーライドします。 +- `on_handoff`:ハンドオフが呼び出された際に実行されるコールバック関数です。これは、ハンドオフが呼ばれた時点でデータ取得などの処理を開始する場合に便利です。この関数はエージェントのコンテキストを受け取り、オプションで LLM が生成した入力も受け取れます。入力データは `input_type` パラメータで制御されます。 +- `input_type`:ハンドオフが期待する入力の型を指定します(オプション)。 +- `input_filter`:次のエージェントが受け取る入力をフィルタリングできます。詳細は後述します。 + +```python +from agents import Agent, handoff, RunContextWrapper + +def on_handoff(ctx: RunContextWrapper[None]): + print("Handoff called") + +agent = Agent(name="My agent") + +handoff_obj = handoff( + agent=agent, + on_handoff=on_handoff, + tool_name_override="custom_handoff_tool", + tool_description_override="Custom description", +) +``` + +## ハンドオフの入力 + +特定の状況では、LLM がハンドオフを呼び出す際に何らかのデータを提供するようにしたい場合があります。例えば、「Escalation agent(エスカレーションエージェント)」へのハンドオフを考えると、ログ記録のために理由を提供してほしい場合があります。 + +```python +from pydantic import BaseModel + +from agents import Agent, handoff, RunContextWrapper + +class EscalationData(BaseModel): + reason: str + +async def on_handoff(ctx: RunContextWrapper[None], input_data: EscalationData): + print(f"Escalation agent called with reason: {input_data.reason}") + +agent = Agent(name="Escalation agent") + +handoff_obj = handoff( + agent=agent, + on_handoff=on_handoff, + input_type=EscalationData, +) +``` + +## 入力フィルター + +ハンドオフが発生すると、新しいエージェントが会話を引き継ぎ、それまでの会話履歴全体を参照できるようになります。これを変更したい場合は、[`input_filter`][agents.handoffs.Handoff.input_filter] を設定できます。入力フィルターは、既存の入力を [`HandoffInputData`][agents.handoffs.HandoffInputData] として受け取り、新しい `HandoffInputData` を返す関数です。 + +よくあるパターン(例えば履歴からすべてのツール呼び出しを削除するなど)は、[`agents.extensions.handoff_filters`][] にあらかじめ実装されています。 + +```python +from agents import Agent, handoff +from agents.extensions import handoff_filters + +agent = Agent(name="FAQ agent") + +handoff_obj = handoff( + agent=agent, + input_filter=handoff_filters.remove_all_tools, # (1)! +) +``` + +1. これにより、`FAQ agent` が呼び出された際に履歴からすべてのツールが自動的に削除されます。 + +## 推奨プロンプト + +LLM がハンドオフを適切に理解できるようにするため、エージェントのプロンプトにハンドオフに関する情報を含めることを推奨します。推奨されるプレフィックスは [`agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX`][] に用意されています。または、[`agents.extensions.handoff_prompt.prompt_with_handoff_instructions`][] を呼び出して、推奨データをプロンプトに自動的に追加できます。 + +```python +from agents import Agent +from agents.extensions.handoff_prompt import RECOMMENDED_PROMPT_PREFIX + +billing_agent = Agent( + name="Billing agent", + instructions=f"""{RECOMMENDED_PROMPT_PREFIX} + .""", +) +``` \ No newline at end of file diff --git a/docs/ja/index.md b/docs/ja/index.md new file mode 100644 index 00000000..87b419fd --- /dev/null +++ b/docs/ja/index.md @@ -0,0 +1,52 @@ +# OpenAI Agents SDK + +[OpenAI Agents SDK](https://github.com/openai/openai-agents-python) は、軽量で使いやすく、抽象化を最小限に抑えたエージェントベースの AI アプリケーションを構築できるようにします。これは、以前のエージェント実験である [Swarm](https://github.com/openai/swarm/tree/main) を本番環境向けにアップグレードしたものです。Agents SDK は非常に少数の基本コンポーネント(primitives)で構成されています。 + +- **エージェント** : instructions と tools を備えた LLM +- **ハンドオフ** : 特定のタスクを他のエージェントに委任する仕組み +- **ガードレール** : エージェントへの入力を検証する仕組み + +これらの基本コンポーネントを Python と組み合わせることで、ツールとエージェント間の複雑な関係を表現でき、急な学習曲線なしに実世界のアプリケーションを構築できます。さらに SDK には、エージェントのフローを視覚化・デバッグし、評価やモデルのファインチューニングまで可能にする組み込みの **トレーシング** 機能が備わっています。 + +## Agents SDK を使う理由 + +SDK は以下の 2 つの設計原則に基づいています。 + +1. 利用価値のある十分な機能を備えつつ、迅速に習得できるよう基本コンポーネントを最小限に抑える。 +2. そのままでも優れた動作をするが、必要に応じて細かくカスタマイズ可能。 + +SDK の主な機能は以下の通りです。 + +- **エージェントループ** : ツールの呼び出し、LLM への実行結果の送信、LLM が完了するまでのループ処理を組み込みで提供。 +- **Python ファースト** : 新しい抽象化を学ぶ必要なく、Python の言語機能を使ってエージェントの連携やチェーンを構築可能。 +- **ハンドオフ** : 複数のエージェント間での調整やタスク委任を可能にする強力な機能。 +- **ガードレール** : エージェントと並行して入力の検証やチェックを実行し、チェックが失敗した場合は早期に処理を中断。 +- **関数ツール** : 任意の Python 関数をツールに変換し、自動的なスキーマ生成と Pydantic による検証を提供。 +- **トレーシング** : ワークフローの視覚化、デバッグ、モニタリングを可能にする組み込みのトレーシング機能。OpenAI が提供する評価、ファインチューニング、蒸留ツールも利用可能。 + +## インストール + +```bash +pip install openai-agents +``` + +## Hello World の例 + +```python +from agents import Agent, Runner + +agent = Agent(name="Assistant", instructions="You are a helpful assistant") + +result = Runner.run_sync(agent, "Write a haiku about recursion in programming.") +print(result.final_output) + +# Code within the code, +# Functions calling themselves, +# Infinite loop's dance. +``` + +(_実行する場合は、環境変数 `OPENAI_API_KEY` を設定してください。_) + +```bash +export OPENAI_API_KEY=sk-... +``` \ No newline at end of file diff --git a/docs/ja/mcp.md b/docs/ja/mcp.md new file mode 100644 index 00000000..52ed1558 --- /dev/null +++ b/docs/ja/mcp.md @@ -0,0 +1,59 @@ +# Model context protocol (MCP) + +[Model context protocol](https://modelcontextprotocol.io/introduction)(別名 MCP)は、LLM にツールやコンテキストを提供するための方法です。MCP のドキュメントから引用します: + +> MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンなプロトコルです。MCP は AI アプリケーションにおける USB-C ポートのようなものです。USB-C がデバイスをさまざまな周辺機器やアクセサリに接続するための標準化された方法を提供するのと同様に、MCP は AI モデルをさまざまなデータソースやツールに接続するための標準化された方法を提供します。 + +Agents SDK は MCP をサポートしています。これにより、さまざまな MCP サーバーを使用して、エージェントにツールを提供できます。 + +## MCP サーバー + +現在、MCP の仕様では、使用するトランスポートメカニズムに基づいて 2 種類のサーバーが定義されています: + +1. **stdio** サーバーはアプリケーションのサブプロセスとして実行されます。これらは「ローカル」で実行されると考えることができます。 +2. **HTTP over SSE** サーバーはリモートで実行されます。これらには URL を介して接続します。 + +これらのサーバーに接続するには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] および [`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用できます。 + +例えば、[公式 MCP ファイルシステムサーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem)を使用する場合は以下のようになります: + +```python +async with MCPServerStdio( + params={ + "command": "npx", + "args": ["-y", "@modelcontextprotocol/server-filesystem", samples_dir], + } +) as server: + tools = await server.list_tools() +``` + +## MCP サーバーの使用方法 + +MCP サーバーはエージェントに追加できます。Agents SDK はエージェントが実行されるたびに MCP サーバーの `list_tools()` を呼び出します。これにより、LLM は MCP サーバーのツールを認識します。LLM が MCP サーバーのツールを呼び出すと、SDK はそのサーバーの `call_tool()` を呼び出します。 + +```python +agent=Agent( + name="Assistant", + instructions="Use the tools to achieve the task", + mcp_servers=[mcp_server_1, mcp_server_2] +) +``` + +## キャッシュ + +エージェントが実行されるたびに、MCP サーバーの `list_tools()` が呼び出されます。特にサーバーがリモートの場合、これはレイテンシの原因となる可能性があります。ツールのリストを自動的にキャッシュするには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] の両方に `cache_tools_list=True` を渡します。これは、ツールのリストが変更されないことが確実な場合にのみ行ってください。 + +キャッシュを無効化したい場合は、サーバーの `invalidate_tools_cache()` を呼び出します。 + +## エンドツーエンドのコード例 + +完全な動作コード例については、[examples/mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp) を参照してください。 + +## トレーシング + +[トレーシング](./tracing.md) は、以下を含む MCP 操作を自動的にキャプチャします: + +1. MCP サーバーへのツール一覧取得の呼び出し +2. 関数呼び出しに関する MCP 関連情報 + +![MCP トレーシングのスクリーンショット](../assets/images/mcp-tracing.jpg) \ No newline at end of file diff --git a/docs/ja/models.md b/docs/ja/models.md new file mode 100644 index 00000000..b333666a --- /dev/null +++ b/docs/ja/models.md @@ -0,0 +1,93 @@ +# モデル + +Agents SDK は、OpenAI モデルを以下の 2 種類の形式で標準サポートしています。 + +- **推奨** : 新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使用して OpenAI API を呼び出す [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] +- [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使用して OpenAI API を呼び出す [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] + +## モデルの混在と組み合わせ + +単一のワークフロー内で、各エージェントごとに異なるモデルを使用したい場合があります。例えば、トリアージには小型で高速なモデルを使用し、複雑なタスクにはより大きく高性能なモデルを使用することができます。[`Agent`][agents.Agent] を設定する際、以下のいずれかの方法で特定のモデルを選択できます。 + +1. OpenAI モデルの名前を直接指定する。 +2. 任意のモデル名と、その名前をモデルインスタンスにマッピングできる [`ModelProvider`][agents.models.interface.ModelProvider] を指定する。 +3. [`Model`][agents.models.interface.Model] 実装を直接指定する。 + +!!! note + + SDK は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] と [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] の両方の形式をサポートしていますが、各ワークフローでは単一のモデル形式を使用することを推奨します。これは、2 つの形式が異なる機能やツールをサポートしているためです。ワークフローで複数のモデル形式を混在させる必要がある場合は、使用するすべての機能が両方の形式で利用可能であることを確認してください。 + +```python +from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel +import asyncio + +spanish_agent = Agent( + name="Spanish agent", + instructions="You only speak Spanish.", + model="o3-mini", # (1)! +) + +english_agent = Agent( + name="English agent", + instructions="You only speak English", + model=OpenAIChatCompletionsModel( # (2)! + model="gpt-4o", + openai_client=AsyncOpenAI() + ), +) + +triage_agent = Agent( + name="Triage agent", + instructions="Handoff to the appropriate agent based on the language of the request.", + handoffs=[spanish_agent, english_agent], + model="gpt-3.5-turbo", +) + +async def main(): + result = await Runner.run(triage_agent, input="Hola, ¿cómo estás?") + print(result.final_output) +``` + +1. OpenAI モデルの名前を直接指定しています。 +2. [`Model`][agents.models.interface.Model] 実装を指定しています。 + +## 他の LLM プロバイダーの使用 + +他の LLM プロバイダーを使用するには、以下の 3 つの方法があります(コード例は [こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/))。 + +1. [`set_default_openai_client`][agents.set_default_openai_client] は、グローバルに `AsyncOpenAI` インスタンスを LLM クライアントとして使用したい場合に便利です。これは、LLM プロバイダーが OpenAI 互換の API エンドポイントを持ち、`base_url` と `api_key` を設定できる場合に使用します。設定可能なコード例は [examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) を参照してください。 +2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで指定します。これにより、「この実行におけるすべてのエージェントにカスタムモデルプロバイダーを使用する」と指定できます。設定可能なコード例は [examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) を参照してください。 +3. [`Agent.model`][agents.agent.Agent.model] は特定のエージェントインスタンスにモデルを指定できます。これにより、異なるエージェントに異なるプロバイダーを組み合わせて使用できます。設定可能なコード例は [examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) を参照してください。 + +`platform.openai.com` の API キーを持っていない場合は、`set_tracing_disabled()` を使用してトレーシングを無効化するか、[別のトレーシングプロセッサ](tracing.md) を設定することを推奨します。 + +!!! note + + これらのコード例では Chat Completions API / モデルを使用しています。これは、多くの LLM プロバイダーがまだ Responses API をサポートしていないためです。使用する LLM プロバイダーが Responses API をサポートしている場合は、Responses の使用を推奨します。 + +## 他の LLM プロバイダー使用時の一般的な問題 + +### トレーシングクライアントのエラー 401 + +トレーシングに関連するエラーが発生する場合、これはトレースが OpenAI サーバーにアップロードされるためであり、OpenAI API キーを持っていないことが原因です。解決方法は以下の 3 つです。 + +1. トレーシングを完全に無効化する : [`set_tracing_disabled(True)`][agents.set_tracing_disabled] +2. トレーシング用に OpenAI キーを設定する : [`set_tracing_export_api_key(...)`][agents.set_tracing_export_api_key]。この API キーはトレースのアップロードのみに使用され、[platform.openai.com](https://platform.openai.com/) から取得する必要があります。 +3. OpenAI 以外のトレースプロセッサを使用する : 詳細は [トレーシングドキュメント](tracing.md#custom-tracing-processors) を参照してください。 + +### Responses API のサポート + +SDK はデフォルトで Responses API を使用しますが、多くの他の LLM プロバイダーはまだこれをサポートしていません。そのため、404 エラーなどが発生する場合があります。解決方法は以下の 2 つです。 + +1. [`set_default_openai_api("chat_completions")`][agents.set_default_openai_api] を呼び出す。これは環境変数で `OPENAI_API_KEY` と `OPENAI_BASE_URL` を設定している場合に有効です。 +2. [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] を使用する。コード例は [こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/) を参照してください。 + +### structured outputs のサポート + +一部のモデルプロバイダーは [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) をサポートしていません。そのため、以下のようなエラーが発生する場合があります。 + +``` +BadRequestError: Error code: 400 - {'error': {'message': "'response_format.type' : value is not one of the allowed values ['text','json_object']", 'type': 'invalid_request_error'}} +``` + +これは一部のモデルプロバイダーの制限であり、JSON 出力はサポートしていますが、出力に使用する `json_schema` を指定できないためです。この問題への対応を進めていますが、現時点では JSON スキーマ出力をサポートするプロバイダーを使用することを推奨します。そうでない場合、アプリケーションが不適切な JSON により頻繁に破損する可能性があります。 \ No newline at end of file diff --git a/docs/ja/multi_agent.md b/docs/ja/multi_agent.md new file mode 100644 index 00000000..4c8be96d --- /dev/null +++ b/docs/ja/multi_agent.md @@ -0,0 +1,37 @@ +# 複数のエージェントのオーケストレーション + +オーケストレーションとは、アプリ内でのエージェントの流れを指します。どのエージェントがどの順序で実行され、次に何を行うかをどのように決定するかを意味します。エージェントをオーケストレーションする主な方法は 2 つあります。 + +1. LLM に判断を任せる方法:LLM の知性を利用して計画、推論を行い、それに基づいて次のステップを決定します。 +2. コードによるオーケストレーション:コードを通じてエージェントの流れを決定します。 + +これらのパターンは組み合わせて使用することも可能です。それぞれのトレードオフについて以下で説明します。 + +## LLM によるオーケストレーション + +エージェントとは、LLM に instructions、tools、handoffs を与えたものです。これにより、自由度の高いタスクを与えられた場合でも、LLM は自律的にタスクの取り組み方を計画し、tools を使ってアクションを実行したりデータを取得したり、handoffs を使ってサブエージェントにタスクを委任したりできます。例えば、調査エージェントには以下のようなツールを装備できます。 + +- Web 検索:オンラインで情報を検索 +- ファイル検索と取得:独自データや接続先から情報を検索 +- コンピュータ操作:コンピュータ上でアクションを実行 +- コード実行:データ分析を実施 +- ハンドオフ:計画立案やレポート作成などに特化したエージェントにタスクを委任 + +このパターンは、自由度の高いタスクで LLM の知性に頼りたい場合に適しています。ここで重要な戦術は以下の通りです。 + +1. 良質なプロンプトに投資する。利用可能なツール、使用方法、動作パラメータを明確にする。 +2. アプリを監視し、繰り返し改善する。問題が発生した箇所を特定し、プロンプトを改善する。 +3. エージェントが自己内省し改善できるようにする。例えばループ内で実行し、自らを批評させたり、エラーメッセージを与えて改善させたりする。 +4. 汎用的なエージェントにあらゆるタスクを任せるのではなく、特定のタスクに秀でた専門エージェントを用意する。 +5. [evals](https://platform.openai.com/docs/guides/evals) に投資する。これによりエージェントを訓練し、タスクの遂行能力を向上させることができる。 + +## コードによるオーケストレーション + +LLM によるオーケストレーションは強力ですが、コードによるオーケストレーションは速度、コスト、パフォーマンスの観点でより決定論的で予測可能になります。ここでの一般的なパターンは以下の通りです。 + +- [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用して、コードで検査可能な適切な形式のデータを生成する。例えば、エージェントにタスクをいくつかのカテゴリに分類させ、そのカテゴリに基づいて次のエージェントを選択することができます。 +- 複数のエージェントを連鎖させ、一つのエージェントの出力を次のエージェントの入力に変換する。例えばブログ記事を書くというタスクを、調査、アウトライン作成、記事執筆、批評、改善という一連のステップに分解できます。 +- タスクを実行するエージェントを、評価とフィードバックを行うエージェントと共に `while` ループ内で実行し、評価エージェントが出力が一定の基準を満たすと判断するまで繰り返します。 +- 複数のエージェントを並列で実行する。例えば Python の基本コンポーネント (`asyncio.gather` など) を使用します。これは、互いに依存しない複数のタスクを高速に処理する場合に有効です。 + +[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) に多数のコード例があります。 \ No newline at end of file diff --git a/docs/ja/quickstart.md b/docs/ja/quickstart.md new file mode 100644 index 00000000..691761a2 --- /dev/null +++ b/docs/ja/quickstart.md @@ -0,0 +1,188 @@ +# クイックスタート + +## プロジェクトと仮想環境の作成 + +以下の操作は一度だけ行います。 + +```bash +mkdir my_project +cd my_project +python -m venv .venv +``` + +### 仮想環境の有効化 + +新しいターミナルセッションを開始するたびに、この操作を行います。 + +```bash +source .venv/bin/activate +``` + +### Agents SDK のインストール + +```bash +pip install openai-agents # または `uv add openai-agents` など +``` + +### OpenAI API キーの設定 + +API キーをお持ちでない場合は、[こちらの手順](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)に従って OpenAI API キーを作成してください。 + +```bash +export OPENAI_API_KEY=sk-... +``` + +## 最初のエージェントの作成 + +エージェント は、 instructions 、名前、およびオプションの設定( `model_config` など)で定義します。 + +```python +from agents import Agent + +agent = Agent( + name="Math Tutor", + instructions="You provide help with math problems. Explain your reasoning at each step and include examples", +) +``` + +## さらに複数のエージェントを追加する + +追加のエージェントも同様に定義できます。 `handoff_description` は、ハンドオフのルーティングを決定するための追加のコンテキストを提供します。 + +```python +from agents import Agent + +history_tutor_agent = Agent( + name="History Tutor", + handoff_description="Specialist agent for historical questions", + instructions="You provide assistance with historical queries. Explain important events and context clearly.", +) + +math_tutor_agent = Agent( + name="Math Tutor", + handoff_description="Specialist agent for math questions", + instructions="You provide help with math problems. Explain your reasoning at each step and include examples", +) +``` + +## ハンドオフの定義 + +各エージェントに対して、タスクを進める方法を決定するために選択可能なハンドオフのオプションを定義できます。 + +```python +triage_agent = Agent( + name="Triage Agent", + instructions="You determine which agent to use based on the user's homework question", + handoffs=[history_tutor_agent, math_tutor_agent] +) +``` + +## エージェントのオーケストレーションを実行する + +ワークフローが正しく動作し、トリアージエージェントが 2 つの専門エージェント間で適切にルーティングすることを確認しましょう。 + +```python +from agents import Runner + +async def main(): + result = await Runner.run(triage_agent, "What is the capital of France?") + print(result.final_output) +``` + +## ガードレールの追加 + +入力または出力に対して実行するカスタムのガードレールを定義できます。 + +```python +from agents import GuardrailFunctionOutput, Agent, Runner +from pydantic import BaseModel + +class HomeworkOutput(BaseModel): + is_homework: bool + reasoning: str + +guardrail_agent = Agent( + name="Guardrail check", + instructions="Check if the user is asking about homework.", + output_type=HomeworkOutput, +) + +async def homework_guardrail(ctx, agent, input_data): + result = await Runner.run(guardrail_agent, input_data, context=ctx.context) + final_output = result.final_output_as(HomeworkOutput) + return GuardrailFunctionOutput( + output_info=final_output, + tripwire_triggered=not final_output.is_homework, + ) +``` + +## すべてを統合する + +ハンドオフと入力ガードレールを使用して、ワークフロー全体を統合して実行しましょう。 + +```python +from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner +from pydantic import BaseModel +import asyncio + +class HomeworkOutput(BaseModel): + is_homework: bool + reasoning: str + +guardrail_agent = Agent( + name="Guardrail check", + instructions="Check if the user is asking about homework.", + output_type=HomeworkOutput, +) + +math_tutor_agent = Agent( + name="Math Tutor", + handoff_description="Specialist agent for math questions", + instructions="You provide help with math problems. Explain your reasoning at each step and include examples", +) + +history_tutor_agent = Agent( + name="History Tutor", + handoff_description="Specialist agent for historical questions", + instructions="You provide assistance with historical queries. Explain important events and context clearly.", +) + +async def homework_guardrail(ctx, agent, input_data): + result = await Runner.run(guardrail_agent, input_data, context=ctx.context) + final_output = result.final_output_as(HomeworkOutput) + return GuardrailFunctionOutput( + output_info=final_output, + tripwire_triggered=not final_output.is_homework, + ) + +triage_agent = Agent( + name="Triage Agent", + instructions="You determine which agent to use based on the user's homework question", + handoffs=[history_tutor_agent, math_tutor_agent], + input_guardrails=[ + InputGuardrail(guardrail_function=homework_guardrail), + ], +) + +async def main(): + result = await Runner.run(triage_agent, "who was the first president of the united states?") + print(result.final_output) + + result = await Runner.run(triage_agent, "what is life") + print(result.final_output) + +if __name__ == "__main__": + asyncio.run(main()) +``` + +## トレースの確認 + +エージェントの実行中に何が起きたかを確認するには、[OpenAI ダッシュボードのトレースビューア](https://platform.openai.com/traces) にアクセスして、エージェント実行のトレースを確認してください。 + +## 次のステップ + +より複雑なエージェントフローの構築方法を学びましょう。 + +- [エージェント](agents.md) の設定方法について学ぶ。 +- [エージェントの実行方法](running_agents.md) について学ぶ。 +- [ツール](tools.md)、[ガードレール](guardrails.md)、[モデル](models.md) について学ぶ。 \ No newline at end of file diff --git a/docs/ja/results.md b/docs/ja/results.md new file mode 100644 index 00000000..13ff7cef --- /dev/null +++ b/docs/ja/results.md @@ -0,0 +1,52 @@ +# 実行結果 + +`Runner.run` メソッドを呼び出すと、以下のいずれかが返されます。 + +- `run` または `run_sync` を呼び出した場合は [`RunResult`][agents.result.RunResult] +- `run_streamed` を呼び出した場合は [`RunResultStreaming`][agents.result.RunResultStreaming] + +これらはいずれも [`RunResultBase`][agents.result.RunResultBase] を継承しており、ほとんどの有用な情報はここに含まれています。 + +## 最終出力 + +[`final_output`][agents.result.RunResultBase.final_output] プロパティには、最後に実行されたエージェントの最終出力が格納されています。これは以下のいずれかです。 + +- 最後のエージェントに `output_type` が定義されていない場合は `str` +- エージェントに `output_type` が定義されている場合は、その型(`last_agent.output_type`)のオブジェクト + +!!! note + + `final_output` は型としては `Any` です。これはハンドオフが発生する可能性があるため、静的に型付けできないためです。ハンドオフが発生すると、どのエージェントでも最後のエージェントになり得るため、可能な出力型の集合を静的に特定できません。 + +## 次のターンの入力 + +[`result.to_input_list()`][agents.result.RunResultBase.to_input_list] を使用すると、実行結果を入力リストに変換できます。これは、元々提供した入力とエージェントの実行中に生成された項目を連結したものです。これにより、あるエージェントの実行結果を別の実行に渡したり、ループ内で実行して毎回新しいユーザー入力を追加したりすることが容易になります。 + +## 最後のエージェント + +[`last_agent`][agents.result.RunResultBase.last_agent] プロパティには、最後に実行されたエージェントが格納されています。アプリケーションによっては、次回ユーザーが何かを入力する際に役立つことがあります。例えば、最前線のトリアージエージェントが言語特化型エージェントにハンドオフする場合、最後のエージェントを保存しておき、次回ユーザーがエージェントにメッセージを送る際に再利用できます。 + +## 新規項目 + +[`new_items`][agents.result.RunResultBase.new_items] プロパティには、実行中に生成された新しい項目が格納されています。これらの項目は [`RunItem`][agents.items.RunItem] です。RunItem は LLM によって生成された raw 項目をラップしています。 + +- [`MessageOutputItem`][agents.items.MessageOutputItem] は LLM からのメッセージを示します。raw 項目は生成されたメッセージです。 +- [`HandoffCallItem`][agents.items.HandoffCallItem] は LLM がハンドオフツールを呼び出したことを示します。raw 項目は LLM からのツール呼び出し項目です。 +- [`HandoffOutputItem`][agents.items.HandoffOutputItem] はハンドオフが発生したことを示します。raw 項目はハンドオフツール呼び出しに対するツールの応答です。また、この項目からソース/ターゲットエージェントにアクセスできます。 +- [`ToolCallItem`][agents.items.ToolCallItem] は LLM がツールを呼び出したことを示します。 +- [`ToolCallOutputItem`][agents.items.ToolCallOutputItem] はツールが呼び出されたことを示します。raw 項目はツールの応答です。また、この項目からツールの出力にアクセスできます。 +- [`ReasoningItem`][agents.items.ReasoningItem] は LLM による推論項目を示します。raw 項目は生成された推論内容です。 + +## その他の情報 + +### ガードレールの実行結果 + +[`input_guardrail_results`][agents.result.RunResultBase.input_guardrail_results] および [`output_guardrail_results`][agents.result.RunResultBase.output_guardrail_results] プロパティには、ガードレールの実行結果が格納されています(存在する場合)。ガードレールの実行結果にはログや保存したい有用な情報が含まれることがあるため、これらを利用可能にしています。 + +### raw レスポンス + +[`raw_responses`][agents.result.RunResultBase.raw_responses] プロパティには、LLM によって生成された [`ModelResponse`][agents.items.ModelResponse] が格納されています。 + +### 元の入力 + +[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が格納されています。ほとんどの場合、これは必要ありませんが、必要に応じて利用可能です。 \ No newline at end of file diff --git a/docs/ja/running_agents.md b/docs/ja/running_agents.md new file mode 100644 index 00000000..b02ee393 --- /dev/null +++ b/docs/ja/running_agents.md @@ -0,0 +1,95 @@ +# エージェントの実行 + +エージェントは [`Runner`][agents.run.Runner] クラスを通じて実行できます。以下の 3 つの方法があります。 + +1. [`Runner.run()`][agents.run.Runner.run]:非同期で実行され、[`RunResult`][agents.result.RunResult] を返します。 +2. [`Runner.run_sync()`][agents.run.Runner.run_sync]:同期メソッドで、内部的には `.run()` を呼び出します。 +3. [`Runner.run_streamed()`][agents.run.Runner.run_streamed]:非同期で実行され、[`RunResultStreaming`][agents.result.RunResultStreaming] を返します。LLM をストリーミングモードで呼び出し、受信したイベントを順次ストリームします。 + +```python +from agents import Agent, Runner + +async def main(): + agent = Agent(name="Assistant", instructions="You are a helpful assistant") + + result = await Runner.run(agent, "Write a haiku about recursion in programming.") + print(result.final_output) + # Code within the code, + # Functions calling themselves, + # Infinite loop's dance. +``` + +詳細は [results ガイド](results.md) を参照してください。 + +## エージェントの実行ループ + +`Runner` の run メソッドを使用する際、開始エージェントと入力を渡します。入力は文字列(ユーザーメッセージとして扱われる)または OpenAI Responses API の項目リストのいずれかです。 + +Runner は以下のループを実行します。 + +1. 現在のエージェントと入力を用いて LLM を呼び出します。 +2. LLM が出力を生成します。 + 1. LLM が `final_output` を返した場合、ループを終了し結果を返します。 + 2. LLM がハンドオフを行った場合、現在のエージェントと入力を更新し、再度ループを実行します。 + 3. LLM がツール呼び出しを生成した場合、それらのツール呼び出しを実行し、結果を追加して再度ループを実行します。 +3. 指定された `max_turns` を超えた場合、[`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] 例外を発生させます。 + +!!! note + + LLM の出力が「最終出力(final output)」とみなされる条件は、望ましいタイプのテキスト出力を生成し、かつツール呼び出しがない場合です。 + +## ストリーミング + +ストリーミングを使用すると、LLM の実行中にストリーミングイベントを受け取ることができます。ストリームが完了すると、[`RunResultStreaming`][agents.result.RunResultStreaming] に実行に関する完全な情報(生成されたすべての新しい出力を含む)が格納されます。ストリーミングイベントを取得するには `.stream_events()` を呼び出します。詳細は [streaming ガイド](streaming.md) を参照してください。 + +## 実行設定(Run config) + +`run_config` パラメータを使用すると、エージェント実行時のグローバル設定を構成できます。 + +- [`model`][agents.run.RunConfig.model]:各エージェントの `model` 設定に関係なく、グローバルな LLM モデルを指定します。 +- [`model_provider`][agents.run.RunConfig.model_provider]:モデル名を検索するためのモデルプロバイダーを指定します(デフォルトは OpenAI)。 +- [`model_settings`][agents.run.RunConfig.model_settings]:エージェント固有の設定を上書きします。例えば、グローバルな `temperature` や `top_p` を設定できます。 +- [`input_guardrails`][agents.run.RunConfig.input_guardrails]、[`output_guardrails`][agents.run.RunConfig.output_guardrails]:すべての実行に適用する入力または出力のガードレールのリストです。 +- [`handoff_input_filter`][agents.run.RunConfig.handoff_input_filter]:ハンドオフに既存の入力フィルターがない場合に適用されるグローバルな入力フィルターです。入力フィルターを使用すると、新しいエージェントに送信される入力を編集できます。詳細は [`Handoff.input_filter`][agents.handoffs.Handoff.input_filter] のドキュメントを参照してください。 +- [`tracing_disabled`][agents.run.RunConfig.tracing_disabled]:実行全体の [トレーシング](tracing.md) を無効にします。 +- [`trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data]:トレースに LLM やツール呼び出しの入出力など、機密性の高いデータを含めるかどうかを設定します。 +- [`workflow_name`][agents.run.RunConfig.workflow_name]、[`trace_id`][agents.run.RunConfig.trace_id]、[`group_id`][agents.run.RunConfig.group_id]:トレーシングのワークフロー名、トレース ID、トレースグループ ID を設定します。少なくとも `workflow_name` を設定することを推奨します。グループ ID はオプションで、複数の実行間でトレースを関連付けることができます。 +- [`trace_metadata`][agents.run.RunConfig.trace_metadata]:すべてのトレースに含めるメタデータです。 + +## 会話/チャットスレッド + +いずれかの run メソッドを呼び出すと、1 つ以上のエージェントが実行され(したがって 1 つ以上の LLM 呼び出しが発生)、チャット会話における単一の論理的ターンを表します。例えば: + +1. ユーザーのターン:ユーザーがテキストを入力 +2. Runner の実行:最初のエージェントが LLM を呼び出し、ツールを実行し、2 番目のエージェントにハンドオフし、2 番目のエージェントがさらにツールを実行して出力を生成 + +エージェントの実行終了時に、ユーザーに何を表示するかを選択できます。例えば、エージェントが生成したすべての新しい項目を表示するか、最終出力のみを表示するかを選択できます。いずれの場合も、ユーザーが追加の質問をした場合、再度 run メソッドを呼び出します。 + +次のターンの入力を取得するには、基本クラスの [`RunResultBase.to_input_list()`][agents.result.RunResultBase.to_input_list] メソッドを使用できます。 + +```python +async def main(): + agent = Agent(name="Assistant", instructions="Reply very concisely.") + + with trace(workflow_name="Conversation", group_id=thread_id): + # First turn + result = await Runner.run(agent, "What city is the Golden Gate Bridge in?") + print(result.final_output) + # San Francisco + + # Second turn + new_input = result.to_input_list() + [{"role": "user", "content": "What state is it in?"}] + result = await Runner.run(agent, new_input) + print(result.final_output) + # California +``` + +## 例外 + +SDK は特定の状況で例外を発生させます。完全なリストは [`agents.exceptions`][] にあります。概要は以下の通りです。 + +- [`AgentsException`][agents.exceptions.AgentsException]:SDK 内で発生するすべての例外の基底クラスです。 +- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded]:実行が指定された `max_turns` を超えた場合に発生します。 +- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]:モデルが不正な出力(不正な JSON や存在しないツールの使用など)を生成した場合に発生します。 +- [`UserError`][agents.exceptions.UserError]:SDK を使用するコードに誤りがある場合に発生します。 +- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered]、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]:[ガードレール](guardrails.md) がトリガーされた場合に発生します。 \ No newline at end of file diff --git a/docs/ja/streaming.md b/docs/ja/streaming.md new file mode 100644 index 00000000..60719679 --- /dev/null +++ b/docs/ja/streaming.md @@ -0,0 +1,87 @@ +# ストリーミング + +ストリーミングを使用すると、エージェントの実行中にその進行状況の更新を購読できます。これは、エンドユーザーに進捗状況や部分的な応答を表示する際に役立ちます。 + +ストリーミングを行うには、[`Runner.run_streamed()`][agents.run.Runner.run_streamed] を呼び出します。これにより [`RunResultStreaming`][agents.result.RunResultStreaming] が返されます。`result.stream_events()` を呼び出すと、以下で説明する [`StreamEvent`][agents.stream_events.StreamEvent] オブジェクトの非同期ストリームが得られます。 + +## raw response events + +[`RawResponsesStreamEvent`][agents.stream_events.RawResponsesStreamEvent] は、LLM から直接渡される raw イベントです。これらは OpenAI Responses API の形式であり、各イベントはタイプ(`response.created` や `response.output_text.delta` など)とデータを持ちます。これらのイベントは、生成された応答メッセージを即座にユーザーにストリーミングしたい場合に役立ちます。 + +例えば、以下のコードは LLM が生成したテキストをトークンごとに出力します。 + +```python +import asyncio +from openai.types.responses import ResponseTextDeltaEvent +from agents import Agent, Runner + +async def main(): + agent = Agent( + name="Joker", + instructions="You are a helpful assistant.", + ) + + result = Runner.run_streamed(agent, input="Please tell me 5 jokes.") + async for event in result.stream_events(): + if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent): + print(event.data.delta, end="", flush=True) + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +## Run item events と agent events + +[`RunItemStreamEvent`][agents.stream_events.RunItemStreamEvent] は、より高レベルのイベントです。これらはアイテムが完全に生成された際に通知されます。これにより、トークン単位ではなく、「メッセージが生成された」「ツールが実行された」などのレベルで進捗状況をユーザーに通知できます。同様に、[`AgentUpdatedStreamEvent`][agents.stream_events.AgentUpdatedStreamEvent] は、現在のエージェントが変更された際(例えばハンドオフの結果として)に更新を通知します。 + +例えば、以下のコードは raw イベントを無視し、更新情報のみをユーザーにストリーミングします。 + +```python +import asyncio +import random +from agents import Agent, ItemHelpers, Runner, function_tool + +@function_tool +def how_many_jokes() -> int: + return random.randint(1, 10) + + +async def main(): + agent = Agent( + name="Joker", + instructions="First call the `how_many_jokes` tool, then tell that many jokes.", + tools=[how_many_jokes], + ) + + result = Runner.run_streamed( + agent, + input="Hello", + ) + print("=== Run starting ===") + + async for event in result.stream_events(): + # raw response イベントのデルタは無視します + if event.type == "raw_response_event": + continue + # エージェントが更新された場合、それを表示します + elif event.type == "agent_updated_stream_event": + print(f"Agent updated: {event.new_agent.name}") + continue + # アイテムが生成された場合、それを表示します + elif event.type == "run_item_stream_event": + if event.item.type == "tool_call_item": + print("-- Tool was called") + elif event.item.type == "tool_call_output_item": + print(f"-- Tool output: {event.item.output}") + elif event.item.type == "message_output_item": + print(f"-- Message output:\n {ItemHelpers.text_message_output(event.item)}") + else: + pass # 他のイベントタイプは無視します + + print("=== Run complete ===") + + +if __name__ == "__main__": + asyncio.run(main()) +``` \ No newline at end of file diff --git a/docs/ja/tools.md b/docs/ja/tools.md new file mode 100644 index 00000000..c100885b --- /dev/null +++ b/docs/ja/tools.md @@ -0,0 +1,269 @@ +# ツール + +ツールを使用すると、エージェントがデータ取得、コード実行、外部 API 呼び出し、さらにはコンピュータ操作などのアクションを実行できます。Agents SDK には以下の 3 種類のツールがあります。 + +- ホスト型ツール:AI モデルと共に LLM サーバー上で実行されます。OpenAI は、検索、ウェブ検索、コンピュータ操作をホスト型ツール(OpenAI がホストするツール)として提供しています。 +- 関数呼び出し:任意の Python 関数をツールとして使用できます。 +- エージェントをツールとして使用:エージェントをツールとして使用でき、エージェント間でハンドオフを行わずに他のエージェントを呼び出せます。 + +## ホスト型ツール + +[`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] を使用する場合、OpenAI はいくつかの組み込みツールを提供しています。 + +- [`WebSearchTool`][agents.tool.WebSearchTool] は、エージェントがウェブ検索を行うためのツールです。 +- [`FileSearchTool`][agents.tool.FileSearchTool] は、OpenAI のベクトルストアから情報を取得するためのツールです。 +- [`ComputerTool`][agents.tool.ComputerTool] は、コンピュータ操作タスクを自動化するためのツールです。 + +```python +from agents import Agent, FileSearchTool, Runner, WebSearchTool + +agent = Agent( + name="Assistant", + tools=[ + WebSearchTool(), + FileSearchTool( + max_num_results=3, + vector_store_ids=["VECTOR_STORE_ID"], + ), + ], +) + +async def main(): + result = await Runner.run(agent, "Which coffee shop should I go to, taking into account my preferences and the weather today in SF?") + print(result.final_output) +``` + +## 関数ツール + +任意の Python 関数をツールとして使用できます。Agents SDK は自動的にツールを設定します。 + +- ツール名は Python 関数名が使用されます(または任意の名前を指定可能)。 +- ツールの説明は関数の docstring から取得されます(または任意の説明を指定可能)。 +- 関数の入力スキーマは関数の引数から自動的に作成されます。 +- 各入力の説明は、無効化されていない限り、関数の docstring から取得されます。 + +Python の `inspect` モジュールを使用して関数シグネチャを抽出し、[`griffe`](https://mkdocstrings.github.io/griffe/) を使用して docstring を解析し、`pydantic` を使用してスキーマを作成します。 + +```python +import json + +from typing_extensions import TypedDict, Any + +from agents import Agent, FunctionTool, RunContextWrapper, function_tool + + +class Location(TypedDict): + lat: float + long: float + +@function_tool # (1)! +async def fetch_weather(location: Location) -> str: + # (2)! + """Fetch the weather for a given location. + + Args: + location: The location to fetch the weather for. + """ + # In real life, we'd fetch the weather from a weather API + return "sunny" + + +@function_tool(name_override="fetch_data") # (3)! +def read_file(ctx: RunContextWrapper[Any], path: str, directory: str | None = None) -> str: + """Read the contents of a file. + + Args: + path: The path to the file to read. + directory: The directory to read the file from. + """ + # In real life, we'd read the file from the file system + return "" + + +agent = Agent( + name="Assistant", + tools=[fetch_weather, read_file], # (4)! +) + +for tool in agent.tools: + if isinstance(tool, FunctionTool): + print(tool.name) + print(tool.description) + print(json.dumps(tool.params_json_schema, indent=2)) + print() + +``` + +1. 任意の Python 型を関数の引数として使用可能で、関数は同期または非同期のどちらでも構いません。 +2. docstring が存在する場合、ツールおよび引数の説明として使用されます。 +3. 関数はオプションで `context` を引数として受け取れます(最初の引数である必要があります)。また、ツール名や説明、docstring のスタイルなどを上書き設定できます。 +4. デコレータを付けた関数をツールのリストに渡すことができます。 + +??? note "クリックして出力を表示" + + ``` + fetch_weather + Fetch the weather for a given location. + { + "$defs": { + "Location": { + "properties": { + "lat": { + "title": "Lat", + "type": "number" + }, + "long": { + "title": "Long", + "type": "number" + } + }, + "required": [ + "lat", + "long" + ], + "title": "Location", + "type": "object" + } + }, + "properties": { + "location": { + "$ref": "#/$defs/Location", + "description": "The location to fetch the weather for." + } + }, + "required": [ + "location" + ], + "title": "fetch_weather_args", + "type": "object" + } + + fetch_data + Read the contents of a file. + { + "properties": { + "path": { + "description": "The path to the file to read.", + "title": "Path", + "type": "string" + }, + "directory": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "description": "The directory to read the file from.", + "title": "Directory" + } + }, + "required": [ + "path" + ], + "title": "fetch_data_args", + "type": "object" + } + ``` +### カスタム関数ツール + +Python 関数をツールとして使用したくない場合もあります。その場合は、直接 [`FunctionTool`][agents.tool.FunctionTool] を作成できます。作成時には以下を指定する必要があります: + +- `name` +- `description` +- 引数の JSON スキーマを示す `params_json_schema` +- 非同期関数である `on_invoke_tool`(コンテキストと引数を JSON 文字列として受け取り、ツールの出力を文字列として返す必要があります) + +```python +from typing import Any + +from pydantic import BaseModel + +from agents import RunContextWrapper, FunctionTool + + + +def do_some_work(data: str) -> str: + return "done" + + +class FunctionArgs(BaseModel): + username: str + age: int + + +async def run_function(ctx: RunContextWrapper[Any], args: str) -> str: + parsed = FunctionArgs.model_validate_json(args) + return do_some_work(data=f"{parsed.username} is {parsed.age} years old") + + +tool = FunctionTool( + name="process_user", + description="Processes extracted user data", + params_json_schema=FunctionArgs.model_json_schema(), + on_invoke_tool=run_function, +) +``` + +### 引数とドックストリングの自動解析 + +前述の通り、関数のシグネチャを自動的に解析してツールのスキーマを抽出し、ドックストリングを解析してツールおよび各引数の説明を抽出します。これに関する注意点は以下の通りです: + +1. シグネチャの解析は `inspect` モジュールを使用して行われます。型アノテーションを用いて引数の型を把握し、動的に Pydantic モデルを構築して全体のスキーマを表現します。Python の基本型(basic components)、Pydantic モデル、TypedDict など、ほとんどの型をサポートしています。 +2. ドックストリングの解析には `griffe` を使用します。サポートされるドックストリング形式は `google`、`sphinx`、`numpy` です。ドックストリング形式は自動検出を試みますが、これはベストエフォートであり、`function_tool` 呼び出し時に明示的に指定することも可能です。また、`use_docstring_info` を `False` に設定することでドックストリングの解析を無効化できます。 + +スキーマ抽出のコードは [`agents.function_schema`][] にあります。 + +## ツールとしてのエージェント + +一部のワークフローでは、制御をハンドオフするのではなく、中央のエージェントが専門化されたエージェントのネットワークを調整することが望ましい場合があります。このような場合、エージェントをツールとしてモデル化できます。 + +```python +from agents import Agent, Runner +import asyncio + +spanish_agent = Agent( + name="Spanish agent", + instructions="You translate the user's message to Spanish", +) + +french_agent = Agent( + name="French agent", + instructions="You translate the user's message to French", +) + +orchestrator_agent = Agent( + name="orchestrator_agent", + instructions=( + "You are a translation agent. You use the tools given to you to translate." + "If asked for multiple translations, you call the relevant tools." + ), + tools=[ + spanish_agent.as_tool( + tool_name="translate_to_spanish", + tool_description="Translate the user's message to Spanish", + ), + french_agent.as_tool( + tool_name="translate_to_french", + tool_description="Translate the user's message to French", + ), + ], +) + +async def main(): + result = await Runner.run(orchestrator_agent, input="Say 'Hello, how are you?' in Spanish.") + print(result.final_output) +``` + +## 関数ツールにおけるエラー処理 + +`@function_tool` を使用して関数ツールを作成する際、`failure_error_function` を渡すことができます。これはツール呼び出しがクラッシュした場合に、LLM にエラー応答を提供する関数です。 + +- デフォルト(何も渡さない場合)では、エラーが発生したことを LLM に通知する `default_tool_error_function` が実行されます。 +- 独自のエラー関数を渡した場合は、それが代わりに実行され、その応答が LLM に送信されます。 +- 明示的に `None` を渡した場合、ツール呼び出しのエラーは再度発生(re-raise)し、自分で処理する必要があります。この場合、モデルが無効な JSON を生成した場合は `ModelBehaviorError`、コードがクラッシュした場合は `UserError` などが発生します。 + +手動で `FunctionTool` オブジェクトを作成する場合は、`on_invoke_tool` 関数内でエラーを処理する必要があります。 \ No newline at end of file diff --git a/docs/ja/tracing.md b/docs/ja/tracing.md new file mode 100644 index 00000000..2e0e80da --- /dev/null +++ b/docs/ja/tracing.md @@ -0,0 +1,102 @@ +# トレーシング + +Agents SDK には組み込みのトレーシング機能があり、エージェントの実行中に発生するイベント(LLM の生成、ツール呼び出し、ハンドオフ、ガードレール、さらにはカスタムイベントまで)を包括的に記録します。[Traces ダッシュボード](https://platform.openai.com/traces) を使用して、開発中および本番環境でワークフローのデバッグ、可視化、監視が可能です。 + +!!!note + + トレーシングはデフォルトで有効になっています。トレーシングを無効にする方法は 2 つあります。 + + 1. 環境変数 `OPENAI_AGENTS_DISABLE_TRACING=1` を設定して、グローバルにトレーシングを無効化できます。 + 2. 個別の実行でトレーシングを無効化するには、[`agents.run.RunConfig.tracing_disabled`][] を `True` に設定します。 + +***OpenAI の API を使用してゼロデータ保持(ZDR)ポリシーで運用している組織の場合、トレーシングは利用できません。*** + +## トレースとスパン + +- **トレース(Traces)** は、ワークフローの単一のエンドツーエンド操作を表します。トレースは複数のスパン(Spans)で構成されます。トレースには以下のプロパティがあります。 + - `workflow_name`:論理的なワークフローまたはアプリ名。例:「Code generation」や「Customer service」。 + - `trace_id`:トレースの一意な ID。指定しない場合は自動生成されます。形式は `trace_<32_alphanumeric>` である必要があります。 + - `group_id`:同じ会話からの複数のトレースを関連付けるためのオプションのグループ ID。例えば、チャットスレッド ID を使用できます。 + - `disabled`:True の場合、このトレースは記録されません。 + - `metadata`:トレースに関するオプションのメタデータ。 +- **スパン(Spans)** は、開始時刻と終了時刻を持つ操作を表します。スパンには以下が含まれます。 + - `started_at` と `ended_at` のタイムスタンプ。 + - 所属するトレースを示す `trace_id`。 + - 親スパンを指す `parent_id`(存在する場合)。 + - スパンに関する情報を含む `span_data`。例えば、`AgentSpanData` はエージェントに関する情報を、`GenerationSpanData` は LLM の生成に関する情報を含みます。 + +## デフォルトのトレーシング + +デフォルトでは、SDK は以下をトレースします。 + +- `Runner.{run, run_sync, run_streamed}()` 全体が `trace()` でラップされます。 +- エージェントが実行されるたびに `agent_span()` でラップされます。 +- LLM の生成は `generation_span()` でラップされます。 +- 関数ツールの呼び出しはそれぞれ `function_span()` でラップされます。 +- ガードレールは `guardrail_span()` でラップされます。 +- ハンドオフは `handoff_span()` でラップされます。 +- 音声入力(音声からテキスト)は `transcription_span()` でラップされます。 +- 音声出力(テキストから音声)は `speech_span()` でラップされます。 +- 関連する音声スパンは `speech_group_span()` の下にまとめられる場合があります。 + +デフォルトでは、トレース名は「Agent trace」です。`trace` を使用する場合、この名前を設定できます。また、[`RunConfig`][agents.run.RunConfig] を使用して名前やその他のプロパティを設定できます。 + +さらに、[カスタムトレースプロセッサ](#custom-tracing-processors) を設定して、トレースを他の宛先に送信することも可能です(置き換えまたは追加の宛先として)。 + +## 上位レベルのトレース + +複数回の `run()` 呼び出しを 1 つのトレースにまとめたい場合があります。その場合、コード全体を `trace()` でラップします。 + +```python +from agents import Agent, Runner, trace + +async def main(): + agent = Agent(name="Joke generator", instructions="Tell funny jokes.") + + with trace("Joke workflow"): # (1)! + first_result = await Runner.run(agent, "Tell me a joke") + second_result = await Runner.run(agent, f"Rate this joke: {first_result.final_output}") + print(f"Joke: {first_result.final_output}") + print(f"Rating: {second_result.final_output}") +``` + +1. 2 回の `Runner.run` 呼び出しが `with trace()` でラップされているため、個別の実行はそれぞれ別のトレースを作成するのではなく、全体のトレースの一部になります。 + +## トレースの作成 + +トレースを作成するには [`trace()`][agents.tracing.trace] 関数を使用します。トレースは開始と終了が必要です。以下の 2 つの方法があります。 + +1. **推奨**:コンテキストマネージャとして使用します(例:`with trace(...) as my_trace`)。これによりトレースの開始と終了が自動的に行われます。 +2. 手動で [`trace.start()`][agents.tracing.Trace.start] と [`trace.finish()`][agents.tracing.Trace.finish] を呼び出すこともできます。 + +現在のトレースは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。これにより、並行処理でも自動的に動作します。トレースを手動で開始・終了する場合、`start()` と `finish()` に `mark_as_current` と `reset_current` を渡して現在のトレースを更新する必要があります。 + +## スパンの作成 + +スパンを作成するには、各種の [`*_span()`][agents.tracing.create] メソッドを使用します。通常、スパンを手動で作成する必要はありません。カスタムスパン情報を追跡するために [`custom_span()`][agents.tracing.custom_span] 関数も利用可能です。 + +スパンは自動的に現在のトレースに属し、最も近い現在のスパンの下にネストされます。これは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。 + +## 機密データ + +一部のスパンは機密データを含む可能性があります。 + +`generation_span()` は LLM 生成の入出力を、`function_span()` は関数呼び出しの入出力を保存します。これらには機密データが含まれる可能性があるため、[`RunConfig.trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data] を使用してデータの取得を無効化できます。 + +同様に、音声スパンはデフォルトで音声データを base64 エンコードされた PCM データとして含みます。[`VoicePipelineConfig.trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data] を設定して音声データの取得を無効化できます。 + +## カスタムトレーシングプロセッサ + +トレーシングの高レベルアーキテクチャは以下の通りです。 + +- 初期化時にグローバルな [`TraceProvider`][agents.tracing.setup.TraceProvider] を作成します。 +- `TraceProvider` はトレースを OpenAI バックエンドに送信する [`BatchTraceProcessor`][agents.tracing.processors.BatchTraceProcessor] と [`BackendSpanExporter`][agents.tracing.processors.BackendSpanExporter] で構成されます。 + +このデフォルト設定をカスタマイズするには、以下の 2 つの方法があります。 + +1. [`add_trace_processor()`][agents.tracing.add_trace_processor] で追加のプロセッサを追加できます。 +2. [`set_trace_processors()`][agents.tracing.set_trace_processors] でデフォルトのプロセッサを置き換えることができます。 + +## 外部トレーシングプロセッサ一覧 + +(省略:原文のまま) \ No newline at end of file diff --git a/docs/ja/visualization.md b/docs/ja/visualization.md new file mode 100644 index 00000000..a0e2b9ec --- /dev/null +++ b/docs/ja/visualization.md @@ -0,0 +1,83 @@ +# エージェントの可視化 + +エージェントの可視化を使用すると、**Graphviz** を用いてエージェントとその関係性を構造化したグラフィカルな表現として生成できます。これにより、アプリケーション内でエージェント、ツール、およびハンドオフがどのように相互作用するかを理解できます。 + +## インストール + +オプションの依存関係グループ `viz` をインストールします: + +```bash +pip install "openai-agents[viz]" +``` + +## グラフの生成 + +`draw_graph` 関数を使用してエージェントの可視化を生成できます。この関数は以下のような有向グラフを作成します: + +- **エージェント** は黄色の四角形で表されます。 +- **ツール** は緑色の楕円形で表されます。 +- **ハンドオフ** はあるエージェントから別のエージェントへの有向エッジで表されます。 + +### 使用例 + +```python +from agents import Agent, function_tool +from agents.extensions.visualization import draw_graph + +@function_tool +def get_weather(city: str) -> str: + return f"The weather in {city} is sunny." + +spanish_agent = Agent( + name="Spanish agent", + instructions="You only speak Spanish.", +) + +english_agent = Agent( + name="English agent", + instructions="You only speak English", +) + +triage_agent = Agent( + name="Triage agent", + instructions="Handoff to the appropriate agent based on the language of the request.", + handoffs=[spanish_agent, english_agent], + tools=[get_weather], +) + +draw_graph(triage_agent) +``` + +![Agent Graph](../assets/images/graph.png) + +これにより、**triage agent** とそのサブエージェントおよびツールとの接続構造を視覚的に表現したグラフが生成されます。 + +## 可視化の理解 + +生成されたグラフには以下が含まれます: + +- エントリーポイントを示す **開始ノード** (`__start__`)。 +- 黄色で塗りつぶされた四角形で表されるエージェント。 +- 緑色で塗りつぶされた楕円形で表されるツール。 +- 相互作用を示す有向エッジ: + - エージェント間のハンドオフは **実線矢印**。 + - ツールの呼び出しは **点線矢印**。 +- 実行終了地点を示す **終了ノード** (`__end__`)。 + +## グラフのカスタマイズ + +### グラフの表示 +デフォルトでは、`draw_graph` はグラフをインラインで表示します。グラフを別ウィンドウで表示するには、以下のように記述します: + +```python +draw_graph(triage_agent).view() +``` + +### グラフの保存 +デフォルトでは、`draw_graph` はグラフをインラインで表示します。ファイルとして保存するには、ファイル名を指定します: + +```python +draw_graph(triage_agent, filename="agent_graph.png") +``` + +これにより、作業ディレクトリに `agent_graph.png` が生成されます。 \ No newline at end of file diff --git a/docs/ja/voice/pipeline.md b/docs/ja/voice/pipeline.md new file mode 100644 index 00000000..03e0c54e --- /dev/null +++ b/docs/ja/voice/pipeline.md @@ -0,0 +1,75 @@ +# パイプラインとワークフロー + +[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] クラスを使用すると、エージェントのワークフローを簡単に音声アプリに変換できます。実行するワークフローを渡すと、パイプラインが入力音声の文字起こし、音声終了の検出、適切なタイミングでのワークフロー呼び出し、ワークフロー出力の音声への変換を処理します。 + +```mermaid +graph LR + %% Input + A["🎤 Audio Input"] + + %% Voice Pipeline + subgraph Voice_Pipeline [Voice Pipeline] + direction TB + B["Transcribe (speech-to-text)"] + C["Your Code"]:::highlight + D["Text-to-speech"] + B --> C --> D + end + + %% Output + E["🎧 Audio Output"] + + %% Flow + A --> Voice_Pipeline + Voice_Pipeline --> E + + %% Custom styling + classDef highlight fill:#ffcc66,stroke:#333,stroke-width:1px,font-weight:700; + +``` + +## パイプラインの設定 + +パイプラインを作成する際、以下の項目を設定できます。 + +1. [`workflow`][agents.voice.workflow.VoiceWorkflowBase]:新しい音声が文字起こしされるたびに実行されるコードです。 +2. 使用する [`speech-to-text`][agents.voice.model.STTModel] および [`text-to-speech`][agents.voice.model.TTSModel] モデル +3. [`config`][agents.voice.pipeline_config.VoicePipelineConfig]:以下のような設定が可能です。 + - モデル名をモデルにマッピングするモデルプロバイダー + - トレーシング(トレーシングの無効化、音声ファイルのアップロード有無、ワークフロー名、トレース ID など) + - TTS および STT モデルの設定(プロンプト、言語、使用するデータ型など) + +## パイプラインの実行 + +パイプラインは [`run()`][agents.voice.pipeline.VoicePipeline.run] メソッドを使用して実行できます。このメソッドでは、以下の 2 種類の形式で音声入力を渡すことができます。 + +1. [`AudioInput`][agents.voice.input.AudioInput] は、完全な音声トランスクリプトがあり、それに対する結果を生成したい場合に使用します。これは、話者が話し終えたタイミングを検出する必要がない場合に便利です。例えば、事前録音された音声や、ユーザーが話し終えたタイミングが明確なプッシュトゥトーク型アプリなどです。 +2. [`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] は、ユーザーが話し終えたタイミングを検出する必要がある場合に使用します。音声チャンクを検出時に順次送信でき、音声パイプラインは「アクティビティ検出」と呼ばれるプロセスを通じて、適切なタイミングでエージェントのワークフローを自動的に実行します。 + +## 実行結果 + +音声パイプラインの実行結果は [`StreamedAudioResult`][agents.voice.result.StreamedAudioResult] です。これは、発生したイベントをストリームとして取得できるオブジェクトです。いくつかの種類の [`VoiceStreamEvent`][agents.voice.events.VoiceStreamEvent] があり、以下を含みます。 + +1. [`VoiceStreamEventAudio`][agents.voice.events.VoiceStreamEventAudio]:音声チャンクを含むイベントです。 +2. [`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle]:ターンの開始や終了など、ライフサイクルイベントを通知します。 +3. [`VoiceStreamEventError`][agents.voice.events.VoiceStreamEventError]:エラーイベントです。 + +```python + +result = await pipeline.run(input) + +async for event in result.stream(): + if event.type == "voice_stream_event_audio": + # play audio + elif event.type == "voice_stream_event_lifecycle": + # lifecycle + elif event.type == "voice_stream_event_error" + # error + ... +``` + +## ベストプラクティス + +### 割り込み処理 + +Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの割り込み処理をサポートしていません。その代わり、検出された各ターンごとにワークフローが個別に実行されます。アプリケーション内で割り込みを処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントを監視できます。`turn_started` は新しいターンが文字起こしされ、処理が開始されたことを示します。`turn_ended` は、該当するターンのすべての音声が送信された後にトリガーされます。これらのイベントを利用して、モデルがターンを開始した際に話者のマイクをミュートし、ターンに関連するすべての音声を送信した後にミュートを解除する、といった処理が可能です。 \ No newline at end of file diff --git a/docs/ja/voice/quickstart.md b/docs/ja/voice/quickstart.md new file mode 100644 index 00000000..0602efe6 --- /dev/null +++ b/docs/ja/voice/quickstart.md @@ -0,0 +1,194 @@ +# クイックスタート + +## 前提条件 + +まず、Agents SDK の基本的な[クイックスタート手順](../quickstart.md)に従い、仮想環境をセットアップしてください。その後、SDK のオプションである音声関連の依存関係をインストールします。 + +```bash +pip install 'openai-agents[voice]' +``` + +## コンセプト + +理解すべき主なコンセプトは [`VoicePipeline`][agents.voice.pipeline.VoicePipeline] です。これは以下の 3 ステップで構成されています。 + +1. 音声認識モデルを実行し、音声をテキストに変換します。 +2. 通常はエージェントを用いたワークフローであるコードを実行し、実行結果を生成します。 +3. テキスト読み上げモデルを実行し、実行結果のテキストを再び音声に変換します。 + +```mermaid +graph LR + %% Input + A["🎤 Audio Input"] + + %% Voice Pipeline + subgraph Voice_Pipeline [Voice Pipeline] + direction TB + B["Transcribe (speech-to-text)"] + C["Your Code"]:::highlight + D["Text-to-speech"] + B --> C --> D + end + + %% Output + E["🎧 Audio Output"] + + %% Flow + A --> Voice_Pipeline + Voice_Pipeline --> E + + %% Custom styling + classDef highlight fill:#ffcc66,stroke:#333,stroke-width:1px,font-weight:700; + +``` + +## エージェント + +まず、いくつかのエージェントを設定します。この SDK でエージェントを作成したことがあれば、馴染みのある内容です。ここでは、複数のエージェント、ハンドオフ、およびツールを設定します。 + +```python +import asyncio +import random + +from agents import ( + Agent, + function_tool, +) +from agents.extensions.handoff_prompt import prompt_with_handoff_instructions + + + +@function_tool +def get_weather(city: str) -> str: + """Get the weather for a given city.""" + print(f"[debug] get_weather called with city: {city}") + choices = ["sunny", "cloudy", "rainy", "snowy"] + return f"The weather in {city} is {random.choice(choices)}." + + +spanish_agent = Agent( + name="Spanish", + handoff_description="A spanish speaking agent.", + instructions=prompt_with_handoff_instructions( + "You're speaking to a human, so be polite and concise. Speak in Spanish.", + ), + model="gpt-4o-mini", +) + +agent = Agent( + name="Assistant", + instructions=prompt_with_handoff_instructions( + "You're speaking to a human, so be polite and concise. If the user speaks in Spanish, handoff to the spanish agent.", + ), + model="gpt-4o-mini", + handoffs=[spanish_agent], + tools=[get_weather], +) +``` + +## 音声パイプライン + +ここでは、ワークフローとして [`SingleAgentVoiceWorkflow`][agents.voice.workflow.SingleAgentVoiceWorkflow] を使用し、シンプルな音声パイプラインを設定します。 + +```python +from agents.voice import SingleAgentVoiceWorkflow, VoicePipeline +pipeline = VoicePipeline(workflow=SingleAgentVoiceWorkflow(agent)) +``` + +## パイプラインの実行 + +```python +import numpy as np +import sounddevice as sd +from agents.voice import AudioInput + +# 簡単のため、ここでは 3 秒間の無音を作成します +# 実際にはマイクからの音声データを使用します +buffer = np.zeros(24000 * 3, dtype=np.int16) +audio_input = AudioInput(buffer=buffer) + +result = await pipeline.run(audio_input) + +# `sounddevice` を使ってオーディオプレイヤーを作成します +player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16) +player.start() + +# 音声ストリームをリアルタイムで再生します +async for event in result.stream(): + if event.type == "voice_stream_event_audio": + player.write(event.data) + +``` + +## すべてをまとめる + +```python +import asyncio +import random + +import numpy as np +import sounddevice as sd + +from agents import ( + Agent, + function_tool, + set_tracing_disabled, +) +from agents.voice import ( + AudioInput, + SingleAgentVoiceWorkflow, + VoicePipeline, +) +from agents.extensions.handoff_prompt import prompt_with_handoff_instructions + + +@function_tool +def get_weather(city: str) -> str: + """Get the weather for a given city.""" + print(f"[debug] get_weather called with city: {city}") + choices = ["sunny", "cloudy", "rainy", "snowy"] + return f"The weather in {city} is {random.choice(choices)}." + + +spanish_agent = Agent( + name="Spanish", + handoff_description="A spanish speaking agent.", + instructions=prompt_with_handoff_instructions( + "You're speaking to a human, so be polite and concise. Speak in Spanish.", + ), + model="gpt-4o-mini", +) + +agent = Agent( + name="Assistant", + instructions=prompt_with_handoff_instructions( + "You're speaking to a human, so be polite and concise. If the user speaks in Spanish, handoff to the spanish agent.", + ), + model="gpt-4o-mini", + handoffs=[spanish_agent], + tools=[get_weather], +) + + +async def main(): + pipeline = VoicePipeline(workflow=SingleAgentVoiceWorkflow(agent)) + buffer = np.zeros(24000 * 3, dtype=np.int16) + audio_input = AudioInput(buffer=buffer) + + result = await pipeline.run(audio_input) + + # `sounddevice` を使ってオーディオプレイヤーを作成します + player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16) + player.start() + + # 音声ストリームをリアルタイムで再生します + async for event in result.stream(): + if event.type == "voice_stream_event_audio": + player.write(event.data) + + +if __name__ == "__main__": + asyncio.run(main()) +``` + +このコード例を実行すると、エージェントがあなたに話しかけます。実際にエージェントと会話できるデモについては、[examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) のコード例を参照してください。 \ No newline at end of file diff --git a/docs/ja/voice/tracing.md b/docs/ja/voice/tracing.md new file mode 100644 index 00000000..8432d75d --- /dev/null +++ b/docs/ja/voice/tracing.md @@ -0,0 +1,14 @@ +# トレーシング + +[エージェントのトレーシング](../tracing.md) と同様に、音声パイプラインも自動的にトレーシングされます。 + +基本的なトレーシング情報については、上記のトレーシングドキュメントを参照してください。さらに、[`VoicePipelineConfig`][agents.voice.pipeline_config.VoicePipelineConfig] を使用してパイプラインのトレーシングを設定できます。 + +主なトレーシング関連フィールドは以下のとおりです。 + +- [`tracing_disabled`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレーシングを無効にするかどうかを制御します。デフォルトではトレーシングは有効です。 +- [`trace_include_sensitive_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_data]:音声文字起こしなど、機密性の高いデータをトレースに含めるかどうかを制御します。これは特に音声パイプライン向けであり、ワークフロー内部の処理には影響しません。 +- [`trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data]:トレースに音声データを含めるかどうかを制御します。 +- [`workflow_name`][agents.voice.pipeline_config.VoicePipelineConfig.workflow_name]:トレースするワークフローの名前です。 +- [`group_id`][agents.voice.pipeline_config.VoicePipelineConfig.group_id]:複数のトレースを関連付けるためのトレースの `group_id` です。 +- [`trace_metadata`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレースに含める追加のメタデータです。 \ No newline at end of file diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py new file mode 100644 index 00000000..c907754d --- /dev/null +++ b/docs/scripts/translate_docs.py @@ -0,0 +1,158 @@ +# ruff: noqa +import os +from openai import OpenAI +from concurrent.futures import ThreadPoolExecutor + + +# Define the source and target directories +source_dir = "docs" +languages = { + "ja": "Japanese", + # Add more languages here, e.g., "fr": "French" +} + +# Initialize OpenAI client +openai_client = OpenAI(api_key=os.getenv("OPENAI_API_KEY")) + +# Define dictionaries for translation control +do_not_translate = [ + "OpenAI", + "Agents SDK", + "Hello World", + "Model Context Protocol", + "structured outputs", + # Add more terms here +] + +eng_to_non_eng_mapping = { + "ja": { + "agents": "エージェント", + "computer use": "コンピュータ操作", + "OAI hosted tools": "OpenAI がホストするツール", + "well formed data": "適切な形式のデータ", + "guardrail": "ガードレール", + "handoffs": "ハンドオフ", + "function tools": "関数ツール", + "tracing": "トレーシング", + "code examples": "コード例", + "vector store": "ベクトルストア", + # Add more Japanese mappings here + }, + # Add more languages here +} +eng_to_non_eng_instructions = { + "ja": { + "The term 'result' in the Runner guide context must be translated like 'execution results'", + "The term 'raw' in 'raw response events' must be kept as is", + "The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.", + "The term 'primitives' can be translated as basic components or building blocks.", + "When the terms 'instructions' and 'tools' are mentioned as API parameter names, they must be kept as is.", + # Add more Japanese mappings here + }, + # Add more languages here +} + + +def built_instructions(target_language: str, lang_code: str) -> str: + do_not_translate_terms = "\n".join(do_not_translate) + specific_terms = "\n".join( + [f"{k} -> {v}" for k, v in eng_to_non_eng_mapping.get(lang_code, {}).items()] + ) + specific_instructions = "\n".join(eng_to_non_eng_instructions.get(lang_code, {})) + return f"""You are a professional translator with extensive experience in translating technical documents. +You are assigned to translate markdown text written in English into {target_language}. +The tone and voice must be concise, consistent, and most importantly professional. +You must return only the generated markdown text. Don't include any additional comments. +When you're unable to complete full translation, return an error message indicating the reason instead of returning partial results. + +# Do not translate +{do_not_translate_terms} + +# Specific term mappings +When you convert these terms, do not append whitespaces before/after the terms. +{specific_terms} +{specific_instructions} + +# Other Rules +- When translating into Japanese, ensure there are spaces before and after alphanumeric terms and markdown special characters like italic and bold. +- When translating very uncommon technical terms, include both the translated term and the original term in parentheses. That said, the section titles should be as simple as possible. +- You must skip translating any parts of code snippets and code comments +- "./assets/*" needs to be converted to "../assets/*"; markdown files like ./tracing.md can be kept as is. +""" + + +# Function to translate and save files +def translate_file(file_path: str, target_path: str, lang_code: str) -> None: + print(f"Translating {file_path} into a different language: {lang_code}") + with open(file_path, encoding="utf-8") as f: + content = f.read() + + # Split content into lines + lines: list[str] = content.splitlines() + chunks: list[str] = [] + current_chunk: list[str] = [] + + # Split content into chunks of up to 120 lines, ensuring splits occur before section titles + for line in lines: + if len(current_chunk) >= 120 and line.startswith("#"): + chunks.append("\n".join(current_chunk)) + current_chunk = [] + current_chunk.append(line) + if current_chunk: + chunks.append("\n".join(current_chunk)) + + # Translate each chunk separately and combine results + translated_content: list[str] = [] + for chunk in chunks: + response = openai_client.responses.create( + model="gpt-4.5-preview", + temperature=0.0, + instructions=built_instructions(languages[lang_code], lang_code), + input=chunk, + ) + translated_content.append(response.output_text) + + # Save the combined translated content + with open(target_path, "w", encoding="utf-8") as f: + f.write("\n".join(translated_content)) + + +def translate_single_source_file(file_path: str) -> None: + relative_path = os.path.relpath(file_path, source_dir) + if "ref/" in relative_path or not file_path.endswith(".md"): + return + + for lang_code in languages: + target_dir = os.path.join(source_dir, lang_code) + target_path = os.path.join(target_dir, relative_path) + + # Ensure the target directory exists + os.makedirs(os.path.dirname(target_path), exist_ok=True) + + # Translate and save the file + translate_file(file_path, target_path, lang_code) + + +def main(): + # Traverse the source directory + for root, _, file_names in os.walk(source_dir): + # Skip the target directories + if any(lang in root for lang in languages): + continue + with ThreadPoolExecutor(max_workers=20) as executor: + futures = [ + executor.submit( + translate_single_source_file, + os.path.join(root, file_name), + ) + for file_name in file_names + ] + for future in futures: + future.result() + + print("Translation completed.") + + +if __name__ == "__main__": + # translate_single_source_file("docs/tools.md") + main() diff --git a/mkdocs.yml b/mkdocs.yml index 5e08e321..3eaf0f4b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -18,79 +18,6 @@ theme: primary: black logo: assets/logo.svg favicon: images/favicon-platform.svg -nav: - - Intro: index.md - - Quickstart: quickstart.md - - Examples: examples.md - - Documentation: - - agents.md - - running_agents.md - - results.md - - streaming.md - - tools.md - - mcp.md - - handoffs.md - - tracing.md - - context.md - - guardrails.md - - multi_agent.md - - models.md - - config.md - - visualization.md - - Voice agents: - - voice/quickstart.md - - voice/pipeline.md - - voice/tracing.md - - API Reference: - - Agents: - - ref/index.md - - ref/agent.md - - ref/run.md - - ref/tool.md - - ref/result.md - - ref/stream_events.md - - ref/handoffs.md - - ref/lifecycle.md - - ref/items.md - - ref/run_context.md - - ref/usage.md - - ref/exceptions.md - - ref/guardrail.md - - ref/model_settings.md - - ref/agent_output.md - - ref/function_schema.md - - ref/models/interface.md - - ref/models/openai_chatcompletions.md - - ref/models/openai_responses.md - - ref/mcp/server.md - - ref/mcp/util.md - - Tracing: - - ref/tracing/index.md - - ref/tracing/create.md - - ref/tracing/traces.md - - ref/tracing/spans.md - - ref/tracing/processor_interface.md - - ref/tracing/processors.md - - ref/tracing/scope.md - - ref/tracing/setup.md - - ref/tracing/span_data.md - - ref/tracing/util.md - - Voice: - - ref/voice/pipeline.md - - ref/voice/workflow.md - - ref/voice/input.md - - ref/voice/result.md - - ref/voice/pipeline_config.md - - ref/voice/events.md - - ref/voice/exceptions.md - - ref/voice/model.md - - ref/voice/utils.md - - ref/voice/models/openai_provider.md - - ref/voice/models/openai_stt.md - - ref/voice/models/openai_tts.md - - Extensions: - - ref/extensions/handoff_filters.md - - ref/extensions/handoff_prompt.md plugins: - search @@ -113,10 +40,125 @@ plugins: heading_level: 3 # Show inherited members inherited_members: true + - i18n: + docs_structure: folder + languages: + - locale: en + default: true + name: English + build: true + nav: + - Intro: index.md + - Quickstart: quickstart.md + - Examples: examples.md + - Documentation: + - agents.md + - running_agents.md + - results.md + - streaming.md + - tools.md + - mcp.md + - handoffs.md + - tracing.md + - context.md + - guardrails.md + - multi_agent.md + - models.md + - config.md + - visualization.md + - Voice agents: + - voice/quickstart.md + - voice/pipeline.md + - voice/tracing.md + - API Reference: + - Agents: + - ref/index.md + - ref/agent.md + - ref/run.md + - ref/tool.md + - ref/result.md + - ref/stream_events.md + - ref/handoffs.md + - ref/lifecycle.md + - ref/items.md + - ref/run_context.md + - ref/usage.md + - ref/exceptions.md + - ref/guardrail.md + - ref/model_settings.md + - ref/agent_output.md + - ref/function_schema.md + - ref/models/interface.md + - ref/models/openai_chatcompletions.md + - ref/models/openai_responses.md + - ref/mcp/server.md + - ref/mcp/util.md + - Tracing: + - ref/tracing/index.md + - ref/tracing/create.md + - ref/tracing/traces.md + - ref/tracing/spans.md + - ref/tracing/processor_interface.md + - ref/tracing/processors.md + - ref/tracing/scope.md + - ref/tracing/setup.md + - ref/tracing/span_data.md + - ref/tracing/util.md + - Voice: + - ref/voice/pipeline.md + - ref/voice/workflow.md + - ref/voice/input.md + - ref/voice/result.md + - ref/voice/pipeline_config.md + - ref/voice/events.md + - ref/voice/exceptions.md + - ref/voice/model.md + - ref/voice/utils.md + - ref/voice/models/openai_provider.md + - ref/voice/models/openai_stt.md + - ref/voice/models/openai_tts.md + - Extensions: + - ref/extensions/handoff_filters.md + - ref/extensions/handoff_prompt.md + + - locale: ja + name: 日本語 + build: true + nav: + - はじめに: index.md + - クイックスタート: quickstart.md + - サンプル例: examples.md + - ドキュメント: + - agents.md + - running_agents.md + - results.md + - streaming.md + - tools.md + - mcp.md + - handoffs.md + - tracing.md + - context.md + - guardrails.md + - multi_agent.md + - models.md + - config.md + - visualization.md + - 音声エージェント: + - voice/quickstart.md + - voice/pipeline.md + - voice/tracing.md extra: # Remove material generation message in footer generator: false + language: en + alternate: + - name: English + link: /openai-agents-python/ + lang: en + - name: 日本語 + link: /openai-agents-python/ja/ + lang: ja markdown_extensions: - pymdownx.superfences: diff --git a/pyproject.toml b/pyproject.toml index f850d629..ca398ba2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,6 +14,7 @@ dependencies = [ "requests>=2.0, <3", "types-requests>=2.0, <3", "mcp>=1.6.0, <2; python_version >= '3.10'", + "mkdocs-static-i18n>=1.3.0", ] classifiers = [ "Typing :: Typed", @@ -48,6 +49,7 @@ dev = [ "mkdocs>=1.6.0", "mkdocs-material>=9.6.0", "mkdocstrings[python]>=0.28.0", + "mkdocs-static-i18n", "coverage>=7.6.12", "playwright==1.50.0", "inline-snapshot>=0.20.7", diff --git a/uv.lock b/uv.lock index d1c27225..af7eef7e 100644 --- a/uv.lock +++ b/uv.lock @@ -851,6 +851,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728 }, ] +[[package]] +name = "mkdocs-static-i18n" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/03/2b/59652a2550465fde25ae6a009cb6d74d0f7e724d272fc952685807b29ca1/mkdocs_static_i18n-1.3.0.tar.gz", hash = "sha256:65731e1e4ec6d719693e24fee9340f5516460b2b7244d2a89bed4ce3cfa6a173", size = 1370450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/f7/ef222a7a2f96ecf79c7c00bfc9dde3b22cd2cc1bd2b7472c7b204fc64225/mkdocs_static_i18n-1.3.0-py3-none-any.whl", hash = "sha256:7905d52fff71d2c108b6c344fd223e848ca7e39ddf319b70864dfa47dba85d6b", size = 21660 }, +] + [[package]] name = "mkdocstrings" version = "0.29.0" @@ -1092,6 +1104,7 @@ source = { editable = "." } dependencies = [ { name = "griffe" }, { name = "mcp", marker = "python_full_version >= '3.10'" }, + { name = "mkdocs-static-i18n" }, { name = "openai" }, { name = "pydantic" }, { name = "requests" }, @@ -1115,6 +1128,7 @@ dev = [ { name = "inline-snapshot" }, { name = "mkdocs" }, { name = "mkdocs-material" }, + { name = "mkdocs-static-i18n" }, { name = "mkdocstrings", extra = ["python"] }, { name = "mypy" }, { name = "playwright" }, @@ -1135,6 +1149,7 @@ requires-dist = [ { name = "graphviz", marker = "extra == 'viz'", specifier = ">=0.17" }, { name = "griffe", specifier = ">=1.5.6,<2" }, { name = "mcp", marker = "python_full_version >= '3.10'", specifier = ">=1.6.0,<2" }, + { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, { name = "numpy", marker = "python_full_version >= '3.10' and extra == 'voice'", specifier = ">=2.2.0,<3" }, { name = "openai", specifier = ">=1.66.5" }, { name = "pydantic", specifier = ">=2.10,<3" }, @@ -1152,6 +1167,7 @@ dev = [ { name = "inline-snapshot", specifier = ">=0.20.7" }, { name = "mkdocs", specifier = ">=1.6.0" }, { name = "mkdocs-material", specifier = ">=9.6.0" }, + { name = "mkdocs-static-i18n" }, { name = "mkdocstrings", extras = ["python"], specifier = ">=0.28.0" }, { name = "mypy" }, { name = "playwright", specifier = "==1.50.0" }, From 869c95b012b242ba1333ae01113ba8e1cc54a70b Mon Sep 17 00:00:00 2001 From: kanchi <17161397+KanchiShimono@users.noreply.github.com> Date: Wed, 9 Apr 2025 00:47:15 +0900 Subject: [PATCH 02/21] Update `computer-use` example to support simultaneous key presses (#452) ### Summary Updated the `computer-use` example to support simultaneous key presses. The current implementation presses and releases keys one at a time, which prevents combo inputs like copy (CTRL+C) from working correctly. ### Test plan N/A ### Issue number N/A ### Checks - [ ] I've added new tests (if relevant) - [ ] I've added/updated the relevant documentation - [x] I've run `make lint` and `make format` - [ ] I've made sure tests pass --- examples/tools/computer_use.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/tools/computer_use.py b/examples/tools/computer_use.py index 832255e8..0c17cf95 100644 --- a/examples/tools/computer_use.py +++ b/examples/tools/computer_use.py @@ -148,9 +148,11 @@ async def move(self, x: int, y: int) -> None: await self.page.mouse.move(x, y) async def keypress(self, keys: list[str]) -> None: - for key in keys: - mapped_key = CUA_KEY_TO_PLAYWRIGHT_KEY.get(key.lower(), key) - await self.page.keyboard.press(mapped_key) + mapped_keys = [CUA_KEY_TO_PLAYWRIGHT_KEY.get(key.lower(), key) for key in keys] + for key in mapped_keys: + await self.page.keyboard.down(key) + for key in reversed(mapped_keys): + await self.page.keyboard.up(key) async def drag(self, path: list[tuple[int, int]]) -> None: if not path: From ccff74dcfabb6dd0f323e8489b15e78692ac5960 Mon Sep 17 00:00:00 2001 From: nikkie Date: Wed, 9 Apr 2025 00:47:23 +0900 Subject: [PATCH 03/21] docs: Make default model clear (#457) close https://github.com/openai/openai-agents-python/issues/440 --- src/agents/agent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/agent.py b/src/agents/agent.py index 4c6de245..a24456b0 100644 --- a/src/agents/agent.py +++ b/src/agents/agent.py @@ -108,7 +108,7 @@ class Agent(Generic[TContext]): """The model implementation to use when invoking the LLM. By default, if not set, the agent will use the default model configured in - `model_settings.DEFAULT_MODEL`. + `openai_provider.DEFAULT_MODEL` (currently "gpt-4o"). """ model_settings: ModelSettings = field(default_factory=ModelSettings) From d089886f01d46e3a4cd550d50a68d15a56cbba78 Mon Sep 17 00:00:00 2001 From: nikkie Date: Wed, 9 Apr 2025 03:01:09 +0900 Subject: [PATCH 04/21] examples(research_bot): Add space to INSTRUCTIONS (#439) Thanks to awesome example `research_bot` Fix andproduce and goodgrammar (and so on) ```python >>> from examples.research_bot.agents import search_agent >>> print(search_agent.INSTRUCTIONS) You are a research assistant. Given a search term, you search the web for that term andproduce a concise summary of the results. The summary must 2-3 paragraphs and less than 300words. Capture the main points. Write succinctly, no need to have complete sentences or goodgrammar. This will be consumed by someone synthesizing a report, so its vital you capture theessence and ignore any fluff. Do not include any additional commentary other than the summaryitself. ``` --- examples/research_bot/agents/search_agent.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/research_bot/agents/search_agent.py b/examples/research_bot/agents/search_agent.py index f69cfda8..0212ce5b 100644 --- a/examples/research_bot/agents/search_agent.py +++ b/examples/research_bot/agents/search_agent.py @@ -2,11 +2,11 @@ from agents.model_settings import ModelSettings INSTRUCTIONS = ( - "You are a research assistant. Given a search term, you search the web for that term and" - "produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300" - "words. Capture the main points. Write succinctly, no need to have complete sentences or good" - "grammar. This will be consumed by someone synthesizing a report, so its vital you capture the" - "essence and ignore any fluff. Do not include any additional commentary other than the summary" + "You are a research assistant. Given a search term, you search the web for that term and " + "produce a concise summary of the results. The summary must 2-3 paragraphs and less than 300 " + "words. Capture the main points. Write succinctly, no need to have complete sentences or good " + "grammar. This will be consumed by someone synthesizing a report, so its vital you capture the " + "essence and ignore any fluff. Do not include any additional commentary other than the summary " "itself." ) From 84fb734ba042499d4c080410f6c337ffb50c138a Mon Sep 17 00:00:00 2001 From: Dmitry Pimenov Date: Wed, 9 Apr 2025 11:59:07 -0700 Subject: [PATCH 05/21] Adding scope and span_data doc strings (#463) Built docs and tested outputs locally --- src/agents/tracing/scope.py | 4 +++ src/agents/tracing/span_data.py | 60 +++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+) diff --git a/src/agents/tracing/scope.py b/src/agents/tracing/scope.py index 513ca8c0..1d31c1bd 100644 --- a/src/agents/tracing/scope.py +++ b/src/agents/tracing/scope.py @@ -18,6 +18,10 @@ class Scope: + """ + Manages the current span and trace in the context. + """ + @classmethod def get_current_span(cls) -> "Span[Any] | None": return _current_span.get() diff --git a/src/agents/tracing/span_data.py b/src/agents/tracing/span_data.py index fe2e0618..260e4c45 100644 --- a/src/agents/tracing/span_data.py +++ b/src/agents/tracing/span_data.py @@ -9,17 +9,28 @@ class SpanData(abc.ABC): + """ + Represents span data in the trace. + """ + @abc.abstractmethod def export(self) -> dict[str, Any]: + """Export the span data as a dictionary.""" pass @property @abc.abstractmethod def type(self) -> str: + """Return the type of the span.""" pass class AgentSpanData(SpanData): + """ + Represents an Agent Span in the trace. + Includes name, handoffs, tools, and output type. + """ + __slots__ = ("name", "handoffs", "tools", "output_type") def __init__( @@ -49,6 +60,11 @@ def export(self) -> dict[str, Any]: class FunctionSpanData(SpanData): + """ + Represents a Function Span in the trace. + Includes input, output and MCP data (if applicable). + """ + __slots__ = ("name", "input", "output", "mcp_data") def __init__( @@ -78,6 +94,11 @@ def export(self) -> dict[str, Any]: class GenerationSpanData(SpanData): + """ + Represents a Generation Span in the trace. + Includes input, output, model, model configuration, and usage. + """ + __slots__ = ( "input", "output", @@ -116,6 +137,11 @@ def export(self) -> dict[str, Any]: class ResponseSpanData(SpanData): + """ + Represents a Response Span in the trace. + Includes response and input. + """ + __slots__ = ("response", "input") def __init__( @@ -140,6 +166,11 @@ def export(self) -> dict[str, Any]: class HandoffSpanData(SpanData): + """ + Represents a Handoff Span in the trace. + Includes source and desitnation agents. + """ + __slots__ = ("from_agent", "to_agent") def __init__(self, from_agent: str | None, to_agent: str | None): @@ -159,6 +190,11 @@ def export(self) -> dict[str, Any]: class CustomSpanData(SpanData): + """ + Represents a Custom Span in the trace. + Includes name and data property bag. + """ + __slots__ = ("name", "data") def __init__(self, name: str, data: dict[str, Any]): @@ -178,6 +214,11 @@ def export(self) -> dict[str, Any]: class GuardrailSpanData(SpanData): + """ + Represents a Guardrail Span in the trace. + Includes name and triggered status. + """ + __slots__ = ("name", "triggered") def __init__(self, name: str, triggered: bool = False): @@ -197,6 +238,11 @@ def export(self) -> dict[str, Any]: class TranscriptionSpanData(SpanData): + """ + Represents a Transcription Span in the trace. + Includes input, output, model, and model configuration. + """ + __slots__ = ( "input", "output", @@ -236,6 +282,11 @@ def export(self) -> dict[str, Any]: class SpeechSpanData(SpanData): + """ + Represents a Speech Span in the trace. + Includes input, output, model, model configuration, and first content timestamp. + """ + __slots__ = ("input", "output", "model", "model_config", "first_content_at") def __init__( @@ -273,6 +324,10 @@ def export(self) -> dict[str, Any]: class SpeechGroupSpanData(SpanData): + """ + Represents a Speech Group Span in the trace. + """ + __slots__ = "input" def __init__( @@ -293,6 +348,11 @@ def export(self) -> dict[str, Any]: class MCPListToolsSpanData(SpanData): + """ + Represents an MCP List Tools Span in the trace. + Includes server and result. + """ + __slots__ = ( "server", "result", From 8ded8a9981abf21659ed0c8e0430f98ea0f1f7b4 Mon Sep 17 00:00:00 2001 From: Ddper Date: Fri, 11 Apr 2025 04:54:00 +0800 Subject: [PATCH 06/21] add overwrite mechanism for stream_options (#465) fix issue https://github.com/openai/openai-agents-python/issues/442 below is an example to overwrite include_usage ``` result = Runner.run_streamed( agent, "Write a haiku about recursion in programming.", run_config=RunConfig( model_provider=CUSTOM_MODEL_PROVIDER, model_settings=ModelSettings(include_usage=True) ), ) ``` --- src/agents/model_settings.py | 4 ++++ src/agents/models/openai_chatcompletions.py | 21 +++++++++++++++++++-- tests/test_openai_chatcompletions.py | 2 +- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/src/agents/model_settings.py b/src/agents/model_settings.py index bac71f58..f29cfa4a 100644 --- a/src/agents/model_settings.py +++ b/src/agents/model_settings.py @@ -54,6 +54,10 @@ class ModelSettings: """Whether to store the generated model response for later retrieval. Defaults to True if not provided.""" + include_usage: bool | None = None + """Whether to include usage chunk. + Defaults to True if not provided.""" + def resolve(self, override: ModelSettings | None) -> ModelSettings: """Produce a new ModelSettings by overlaying any non-None values from the override on top of this instance.""" diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index e0aafad0..807c6512 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -521,6 +521,8 @@ async def _fetch_response( reasoning_effort = model_settings.reasoning.effort if model_settings.reasoning else None store = _Converter.get_store_param(self._get_client(), model_settings) + stream_options = _Converter.get_stream_options_param(self._get_client(), model_settings) + ret = await self._get_client().chat.completions.create( model=self.model, messages=converted_messages, @@ -534,7 +536,7 @@ async def _fetch_response( response_format=response_format, parallel_tool_calls=parallel_tool_calls, stream=stream, - stream_options={"include_usage": True} if stream else NOT_GIVEN, + stream_options=self._non_null_or_not_given(stream_options), store=self._non_null_or_not_given(store), reasoning_effort=self._non_null_or_not_given(reasoning_effort), extra_headers=_HEADERS, @@ -568,12 +570,27 @@ def _get_client(self) -> AsyncOpenAI: class _Converter: + + @classmethod + def is_openai(cls, client: AsyncOpenAI): + return str(client.base_url).startswith("https://api.openai.com") + @classmethod def get_store_param(cls, client: AsyncOpenAI, model_settings: ModelSettings) -> bool | None: # Match the behavior of Responses where store is True when not given - default_store = True if str(client.base_url).startswith("https://api.openai.com") else None + default_store = True if cls.is_openai(client) else None return model_settings.store if model_settings.store is not None else default_store + @classmethod + def get_stream_options_param( + cls, client: AsyncOpenAI, model_settings: ModelSettings + ) -> dict[str, bool] | None: + default_include_usage = True if cls.is_openai(client) else None + include_usage = model_settings.include_usage if model_settings.include_usage is not None \ + else default_include_usage + stream_options = {"include_usage": include_usage} if include_usage is not None else None + return stream_options + @classmethod def convert_tool_choice( cls, tool_choice: Literal["auto", "required", "none"] | str | None diff --git a/tests/test_openai_chatcompletions.py b/tests/test_openai_chatcompletions.py index a3198d33..281d7b41 100644 --- a/tests/test_openai_chatcompletions.py +++ b/tests/test_openai_chatcompletions.py @@ -282,7 +282,7 @@ def __init__(self, completions: DummyCompletions) -> None: # Check OpenAI client was called for streaming assert completions.kwargs["stream"] is True assert completions.kwargs["store"] is NOT_GIVEN - assert completions.kwargs["stream_options"] == {"include_usage": True} + assert completions.kwargs["stream_options"] is NOT_GIVEN # Response is a proper openai Response assert isinstance(response, Response) assert response.id == FAKE_RESPONSES_ID From 68c725f9425ab371e8774e50319e18da61ef2e80 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Fri, 11 Apr 2025 05:54:05 +0900 Subject: [PATCH 07/21] Improve translation pipeline details (#475) This pull request improves the translation pipeline, which was introduced by #460. Now the document generation works pretty well with gpt-4o model. --- docs/agents.md | 8 +- docs/config.md | 2 +- docs/ja/agents.md | 52 ++++----- docs/ja/config.md | 32 +++--- docs/ja/context.md | 46 ++++---- docs/ja/examples.md | 42 ++++---- docs/ja/guardrails.md | 54 +++++----- docs/ja/handoffs.md | 40 +++---- docs/ja/index.md | 36 +++---- docs/ja/mcp.md | 37 +++---- docs/ja/models.md | 62 +++++------ docs/ja/multi_agent.md | 46 ++++---- docs/ja/quickstart.md | 47 ++++---- docs/ja/results.md | 48 ++++----- docs/ja/running_agents.md | 76 ++++++------- docs/ja/streaming.md | 24 ++--- docs/ja/tools.md | 73 ++++++------- docs/ja/tracing.md | 98 +++++++++-------- docs/ja/visualization.md | 32 +++--- docs/ja/voice/pipeline.md | 32 +++--- docs/ja/voice/quickstart.md | 30 +++--- docs/ja/voice/tracing.md | 18 ++-- docs/quickstart.md | 2 +- docs/scripts/translate_docs.py | 192 +++++++++++++++++++++++++-------- 24 files changed, 624 insertions(+), 505 deletions(-) diff --git a/docs/agents.md b/docs/agents.md index 23b18b64..39d4afd5 100644 --- a/docs/agents.md +++ b/docs/agents.md @@ -32,11 +32,11 @@ Agents are generic on their `context` type. Context is a dependency-injection to ```python @dataclass class UserContext: - uid: str - is_pro_user: bool + uid: str + is_pro_user: bool - async def fetch_purchases() -> list[Purchase]: - return ... + async def fetch_purchases() -> list[Purchase]: + return ... agent = Agent[UserContext]( ..., diff --git a/docs/config.md b/docs/config.md index 3cf83730..bfaf90e8 100644 --- a/docs/config.md +++ b/docs/config.md @@ -63,7 +63,7 @@ Alternatively, you can customize the logs by adding handlers, filters, formatter ```python import logging -logger = logging.getLogger("openai.agents") # or openai.agents.tracing for the Tracing logger +logger = logging.getLogger("openai.agents") # or openai.agents.tracing for the Tracing logger # To make all logs show up logger.setLevel(logging.DEBUG) diff --git a/docs/ja/agents.md b/docs/ja/agents.md index e9e303bc..5d7a2dfe 100644 --- a/docs/ja/agents.md +++ b/docs/ja/agents.md @@ -1,14 +1,14 @@ # エージェント -エージェント はアプリケーションの基本的な構成要素です。エージェント は、大規模言語モデル(LLM)であり、 instructions と tools を用いて設定されます。 +エージェントはアプリのコア構成要素です。エージェントは、指示とツールで構成された大規模言語モデル (LLM) です。 ## 基本設定 -エージェント の設定でよく使われるプロパティは以下の通りです。 +エージェントで設定する最も一般的なプロパティは次のとおりです: -- `instructions` : 開発者メッセージまたはシステムプロンプトとも呼ばれます。 -- `model` : 使用する LLM を指定します。オプションで `model_settings` を指定し、temperature や top_p などのモデル調整パラメータを設定できます。 -- `tools` : エージェント がタスクを達成するために使用できるツールです。 +- `instructions`: 開発者メッセージまたはシステムプロンプトとも呼ばれます。 +- `model`: 使用する LLM と、temperature や top_p などのモデル調整パラメーターを設定するためのオプションの `model_settings`。 +- `tools`: エージェントがタスクを達成するために使用できるツール。 ```python from agents import Agent, ModelSettings, function_tool @@ -27,16 +27,16 @@ agent = Agent( ## コンテキスト -エージェント は、 `context` 型に対してジェネリックです。コンテキストは依存性注入のためのツールであり、作成したオブジェクトを `Runner.run()` に渡すことで、各エージェント、ツール、ハンドオフなどに渡されます。これはエージェントの実行に必要な依存関係や状態をまとめて保持するためのものです。任意の Python オブジェクトをコンテキストとして提供できます。 +エージェントは `context` タイプに対して汎用的です。コンテキストは依存性注入ツールであり、`Runner.run()` に渡すために作成するオブジェクトです。これはすべてのエージェント、ツール、ハンドオフなどに渡され、エージェントの実行に必要な依存関係や状態をまとめたものとして機能します。任意の Python オブジェクトをコンテキストとして提供できます。 ```python @dataclass class UserContext: - uid: str - is_pro_user: bool + uid: str + is_pro_user: bool - async def fetch_purchases() -> list[Purchase]: - return ... + async def fetch_purchases() -> list[Purchase]: + return ... agent = Agent[UserContext]( ..., @@ -45,7 +45,7 @@ agent = Agent[UserContext]( ## 出力タイプ -デフォルトでは、エージェント はプレーンテキスト(つまり `str` )を出力します。特定の型の出力を生成させたい場合は、 `output_type` パラメータを使用します。一般的には [Pydantic](https://docs.pydantic.dev/) オブジェクトを使用しますが、Pydantic の [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) でラップ可能な型(データクラス、リスト、TypedDict など)であればどのような型でもサポートしています。 +デフォルトでは、エージェントはプレーンテキスト(つまり `str`)の出力を生成します。特定のタイプの出力をエージェントに生成させたい場合は、`output_type` パラメーターを使用できます。一般的な選択肢として [Pydantic](https://docs.pydantic.dev/) オブジェクトを使用しますが、Pydantic の [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) でラップできる任意のタイプをサポートしています - データクラス、リスト、TypedDict など。 ```python from pydantic import BaseModel @@ -66,11 +66,11 @@ agent = Agent( !!! note - `output_type` を指定すると、モデルは通常のプレーンテキストのレスポンスではなく、 [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用します。 + `output_type` を渡すと、モデルに通常のプレーンテキスト応答の代わりに [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用するよう指示します。 ## ハンドオフ -ハンドオフ は、エージェント が処理を委譲できるサブエージェントです。ハンドオフのリストを提供すると、エージェント は必要に応じてそれらに処理を委譲できます。これは、特定のタスクに特化したモジュール型のエージェントを組み合わせて調整するための強力なパターンです。詳細は [ハンドオフ](handoffs.md) のドキュメントを参照してください。 +ハンドオフは、エージェントが委任できるサブエージェントです。ハンドオフのリストを提供し、エージェントは関連する場合にそれらに委任することができます。これは、単一のタスクに優れたモジュール化された専門エージェントを編成する強力なパターンです。[handoffs](handoffs.md) ドキュメントで詳細をお読みください。 ```python from agents import Agent @@ -89,9 +89,9 @@ triage_agent = Agent( ) ``` -## 動的な instructions +## 動的指示 -多くの場合、エージェント 作成時に instructions を指定しますが、関数を通じて動的に instructions を提供することも可能です。この関数はエージェントとコンテキストを受け取り、プロンプトを返します。通常の関数と `async` 関数の両方が使用可能です。 +ほとんどの場合、エージェントを作成する際に指示を提供できますが、関数を介して動的な指示を提供することもできます。この関数はエージェントとコンテキストを受け取り、プロンプトを返す必要があります。通常の関数と `async` 関数の両方が受け入れられます。 ```python def dynamic_instructions( @@ -108,15 +108,15 @@ agent = Agent[UserContext]( ## ライフサイクルイベント(フック) -エージェント のライフサイクルを監視したい場合があります。例えば、イベントをログに記録したり、特定のイベント発生時にデータを事前取得したりできます。エージェント のライフサイクルにフックするには、 `hooks` プロパティを使用します。[`AgentHooks`][agents.lifecycle.AgentHooks] クラスをサブクラス化し、関心のあるメソッドをオーバーライドします。 +時には、エージェントのライフサイクルを観察したいことがあります。たとえば、イベントを記録したり、特定のイベントが発生したときにデータを事前取得したりすることができます。`hooks` プロパティを使用してエージェントのライフサイクルにフックすることができます。[`AgentHooks`][agents.lifecycle.AgentHooks] クラスをサブクラス化し、興味のあるメソッドをオーバーライドします。 ## ガードレール -ガードレール を使用すると、エージェント の実行と並行してユーザー入力に対するチェックや検証を実行できます。例えば、ユーザー入力の関連性を検証できます。詳細は [ガードレール](guardrails.md) のドキュメントを参照してください。 +ガードレールを使用すると、エージェントの実行と並行してユーザー入力のチェック/検証を行うことができます。たとえば、ユーザーの入力を関連性でスクリーニングすることができます。[guardrails](guardrails.md) ドキュメントで詳細をお読みください。 -## エージェント の複製(クローン) +## エージェントのクローン/コピー -エージェント の `clone()` メソッドを使用すると、エージェント を複製し、必要に応じてプロパティを変更できます。 +エージェントの `clone()` メソッドを使用すると、エージェントを複製し、任意のプロパティを変更することができます。 ```python pirate_agent = Agent( @@ -133,15 +133,15 @@ robot_agent = pirate_agent.clone( ## ツール使用の強制 -ツールのリストを提供しても、必ずしも LLM がツールを使用するとは限りません。ツールの使用を強制するには、 [`ModelSettings.tool_choice`][agents.model_settings.ModelSettings.tool_choice] を設定します。有効な値は以下の通りです。 +ツールのリストを提供しても、LLM がツールを使用するとは限りません。[`ModelSettings.tool_choice`][agents.model_settings.ModelSettings.tool_choice] を設定することでツール使用を強制できます。有効な値は次のとおりです: -1. `auto` : LLM がツールを使用するかどうかを決定します。 -2. `required` : LLM にツールの使用を強制します(ただし、どのツールを使用するかは LLM が判断します)。 -3. `none` : LLM にツールを使用しないことを強制します。 -4. 特定の文字列(例: `my_tool` )を設定すると、LLM はその特定のツールを使用することを強制されます。 +1. `auto`:LLM がツールを使用するかどうかを決定します。 +2. `required`:LLM がツールを使用する必要があります(ただし、どのツールを使用するかは賢く決定できます)。 +3. `none`:LLM がツールを使用しないことを要求します。 +4. 特定の文字列を設定する例:`my_tool`、特定のツールを使用することを要求します。 !!! note - 無限ループを防ぐため、フレームワークはツール呼び出し後に自動的に `tool_choice` を "auto" にリセットします。この動作は [`agent.reset_tool_choice`][agents.agent.Agent.reset_tool_choice] で設定可能です。無限ループは、ツールの実行結果が LLM に送信され、再びツール呼び出しが生成されるために発生します。 + 無限ループを防ぐために、フレームワークはツール呼び出し後に `tool_choice` を自動的に "auto" にリセットします。この動作は [`agent.reset_tool_choice`][agents.agent.Agent.reset_tool_choice] で設定可能です。無限ループは、ツールの結果が LLM に送信され、その後 `tool_choice` によって別のツール呼び出しが生成されるために発生します。 - ツール呼び出し後に完全に停止させたい場合(自動モードで続行しない場合)は、 [`Agent.tool_use_behavior="stop_on_first_tool"`] を設定すると、ツールの出力を最終レスポンスとして直接使用し、それ以上の LLM 処理を行いません。 \ No newline at end of file + ツール呼び出し後にエージェントが完全に停止するようにしたい場合(自動モードで続行するのではなく)、[`Agent.tool_use_behavior="stop_on_first_tool"`] を設定することで、ツールの出力を最終応答として直接使用し、さらなる LLM 処理を行わないようにできます。 \ No newline at end of file diff --git a/docs/ja/config.md b/docs/ja/config.md index 6a764eb7..f8586e8a 100644 --- a/docs/ja/config.md +++ b/docs/ja/config.md @@ -2,7 +2,7 @@ ## API キーとクライアント -デフォルトでは、SDK はインポート時に LLM リクエストおよびトレーシング用の環境変数 `OPENAI_API_KEY` を参照します。アプリケーションの起動前にこの環境変数を設定できない場合は、[set_default_openai_key()][agents.set_default_openai_key] 関数を使用してキーを設定できます。 +デフォルトでは、SDK はインポートされるとすぐに LLM リクエストとトレーシングのために `OPENAI_API_KEY` 環境変数を探します。アプリが起動する前にその環境変数を設定できない場合は、[set_default_openai_key()][agents.set_default_openai_key] 関数を使用してキーを設定できます。 ```python from agents import set_default_openai_key @@ -10,7 +10,7 @@ from agents import set_default_openai_key set_default_openai_key("sk-...") ``` -また、使用する OpenAI クライアントを設定することも可能です。デフォルトでは、SDK は環境変数または上記で設定したデフォルトキーを使用して `AsyncOpenAI` インスタンスを作成します。これを変更するには、[set_default_openai_client()][agents.set_default_openai_client] 関数を使用します。 +また、使用する OpenAI クライアントを設定することもできます。デフォルトでは、SDK は環境変数からの API キーまたは上記で設定したデフォルトキーを使用して `AsyncOpenAI` インスタンスを作成します。これを変更するには、[set_default_openai_client()][agents.set_default_openai_client] 関数を使用します。 ```python from openai import AsyncOpenAI @@ -20,7 +20,7 @@ custom_client = AsyncOpenAI(base_url="...", api_key="...") set_default_openai_client(custom_client) ``` -さらに、使用する OpenAI API をカスタマイズすることもできます。デフォルトでは OpenAI Responses API を使用しますが、[set_default_openai_api()][agents.set_default_openai_api] 関数を使用して Chat Completions API に変更できます。 +最後に、使用する OpenAI API をカスタマイズすることもできます。デフォルトでは、OpenAI Responses API を使用します。これを Chat Completions API に変更するには、[set_default_openai_api()][agents.set_default_openai_api] 関数を使用します。 ```python from agents import set_default_openai_api @@ -30,7 +30,7 @@ set_default_openai_api("chat_completions") ## トレーシング -トレーシングはデフォルトで有効になっています。デフォルトでは、前述のセクションで設定した OpenAI API キー(環境変数またはデフォルトキー)を使用します。トレーシング専用の API キーを設定するには、[`set_tracing_export_api_key`][agents.set_tracing_export_api_key] 関数を使用します。 +トレーシングはデフォルトで有効になっています。デフォルトでは、上記のセクションから OpenAI API キー(環境変数または設定したデフォルトキー)を使用します。トレーシングに使用する API キーを特定に設定するには、[`set_tracing_export_api_key`][agents.set_tracing_export_api_key] 関数を使用します。 ```python from agents import set_tracing_export_api_key @@ -38,7 +38,7 @@ from agents import set_tracing_export_api_key set_tracing_export_api_key("sk-...") ``` -また、[`set_tracing_disabled()`][agents.set_tracing_disabled] 関数を使用してトレーシングを完全に無効化することもできます。 +トレーシングを完全に無効にするには、[`set_tracing_disabled()`][agents.set_tracing_disabled] 関数を使用します。 ```python from agents import set_tracing_disabled @@ -48,7 +48,7 @@ set_tracing_disabled(True) ## デバッグログ -SDK はデフォルトでハンドラーが設定されていない 2 つの Python ロガーを持っています。デフォルトでは、警告およびエラーが `stdout` に送信され、それ以外のログは抑制されます。 +SDK にはハンドラーが設定されていない 2 つの Python ロガーがあります。デフォルトでは、警告とエラーが `stdout` に送信されますが、他のログは抑制されます。 詳細なログを有効にするには、[`enable_verbose_stdout_logging()`][agents.enable_verbose_stdout_logging] 関数を使用します。 @@ -58,36 +58,36 @@ from agents import enable_verbose_stdout_logging enable_verbose_stdout_logging() ``` -また、ハンドラー、フィルター、フォーマッターなどを追加してログをカスタマイズすることも可能です。詳細については、[Python logging ガイド](https://docs.python.org/3/howto/logging.html) を参照してください。 +また、ハンドラー、フィルター、フォーマッターなどを追加してログをカスタマイズすることもできます。詳細は [Python ロギングガイド](https://docs.python.org/3/howto/logging.html) を参照してください。 ```python import logging -logger = logging.getLogger("openai.agents") # トレーシング用ロガーの場合は openai.agents.tracing +logger = logging.getLogger("openai.agents") # or openai.agents.tracing for the Tracing logger -# すべてのログを表示する場合 +# To make all logs show up logger.setLevel(logging.DEBUG) -# INFO 以上を表示する場合 +# To make info and above show up logger.setLevel(logging.INFO) -# WARNING 以上を表示する場合 +# To make warning and above show up logger.setLevel(logging.WARNING) -# その他、必要に応じて設定 +# etc -# 必要に応じてカスタマイズ可能ですが、デフォルトでは `stderr` に出力されます +# You can customize this as needed, but this will output to `stderr` by default logger.addHandler(logging.StreamHandler()) ``` ### ログ内の機密データ -一部のログには機密データ(ユーザーデータなど)が含まれる場合があります。このデータのログ記録を無効化したい場合は、以下の環境変数を設定してください。 +特定のログには機密データ(たとえば、ユーザーデータ)が含まれる場合があります。このデータのログ記録を無効にしたい場合は、次の環境変数を設定します。 -LLM の入力および出力のログ記録を無効化する場合: +LLM の入力と出力のログ記録を無効にするには: ```bash export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 ``` -ツールの入力および出力のログ記録を無効化する場合: +ツールの入力と出力のログ記録を無効にするには: ```bash export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 diff --git a/docs/ja/context.md b/docs/ja/context.md index 9ad6dc33..3d3c426e 100644 --- a/docs/ja/context.md +++ b/docs/ja/context.md @@ -1,29 +1,29 @@ # コンテキスト管理 -コンテキストという用語は多義的です。主に次の 2 種類のコンテキストがあります。 +コンテキストは多義的な用語です。考慮すべき主なコンテキストのクラスは2つあります。 -1. コード内でローカルに利用可能なコンテキスト:これは、関数ツールの実行時、`on_handoff` などのコールバック時、ライフサイクルフック時などに必要となるデータや依存関係です。 -2. LLM が利用可能なコンテキスト:これは、LLM が応答を生成する際に参照するデータです。 +1. コードにローカルで利用可能なコンテキスト: これは、ツール関数が実行されるときや、`on_handoff` のようなコールバック、ライフサイクルフックなどで必要になるデータや依存関係です。 +2. LLM に利用可能なコンテキスト: これは、LLM が応答を生成するときに参照するデータです。 ## ローカルコンテキスト -これは [`RunContextWrapper`][agents.run_context.RunContextWrapper] クラスと、その内部の [`context`][agents.run_context.RunContextWrapper.context] プロパティを通じて表現されます。動作の仕組みは以下の通りです。 +これは [`RunContextWrapper`][agents.run_context.RunContextWrapper] クラスとその中の [`context`][agents.run_context.RunContextWrapper.context] プロパティを通じて表現されます。動作の仕組みは次の通りです。 -1. 任意の Python オブジェクトを作成します。一般的にはデータクラスや Pydantic オブジェクトを使用します。 -2. 作成したオブジェクトを各種の実行メソッドに渡します(例:`Runner.run(..., context=whatever)`)。 -3. すべての関数ツール呼び出しやライフサイクルフックなどには、ラッパーオブジェクト `RunContextWrapper[T]` が渡されます。ここで `T` はコンテキストオブジェクトの型を表し、`wrapper.context` を通じてアクセスできます。 +1. 任意の Python オブジェクトを作成します。一般的なパターンは、データクラスや Pydantic オブジェクトを使用することです。 +2. そのオブジェクトを様々な実行メソッドに渡します(例: `Runner.run(..., **context=whatever**)`)。 +3. すべてのツール呼び出し、ライフサイクルフックなどにラッパーオブジェクト `RunContextWrapper[T]` が渡されます。ここで `T` はコンテキストオブジェクトの型を表し、`wrapper.context` を通じてアクセスできます。 -**最も重要な点** は、特定のエージェント実行において、すべてのエージェント、関数ツール、ライフサイクルフックなどが同じコンテキストの _型_ を使用しなければならないということです。 +**最も重要な**点は、特定のエージェント実行において、すべてのエージェント、ツール関数、ライフサイクルなどが同じ _型_ のコンテキストを使用しなければならないことです。 -コンテキストは以下のような用途で使用できます。 +コンテキストは以下のような用途に使用できます。 -- 実行時のコンテキストデータ(ユーザー名や UID など、ユーザーに関する情報) -- 依存関係(ロガーオブジェクト、データ取得用オブジェクトなど) +- 実行のためのコンテキストデータ(例: ユーザー名/uid やその他のユーザー情報) +- 依存関係(例: ロガーオブジェクト、データフェッチャーなど) - ヘルパー関数 !!! danger "注意" - コンテキストオブジェクトは LLM には送信され **ません**。これは純粋にローカルなオブジェクトであり、読み取り、書き込み、メソッド呼び出しが可能です。 + コンテキストオブジェクトは **LLM に送信されません**。これは純粋にローカルなオブジェクトであり、読み書きやメソッドの呼び出しが可能です。 ```python import asyncio @@ -61,17 +61,17 @@ if __name__ == "__main__": asyncio.run(main()) ``` -1. これがコンテキストオブジェクトです。ここではデータクラスを使用していますが、任意の型を使用できます。 -2. これは関数ツールです。`RunContextWrapper[UserInfo]` を引数として受け取り、コンテキストからデータを読み取っています。 -3. エージェントにジェネリック型 `UserInfo` を指定することで、型チェッカーがエラーを検出できるようにしています(例えば、異なるコンテキスト型を取るツールを渡そうとした場合など)。 -4. コンテキストを `run` 関数に渡しています。 -5. エージェントが正しくツールを呼び出し、年齢を取得しています。 +1. これはコンテキストオブジェクトです。ここではデータクラスを使用していますが、任意の型を使用できます。 +2. これはツールです。`RunContextWrapper[UserInfo]` を受け取ることがわかります。ツールの実装はコンテキストから読み取ります。 +3. エージェントをジェネリック `UserInfo` でマークし、型チェッカーがエラーを検出できるようにします(例えば、異なるコンテキスト型を取るツールを渡そうとした場合)。 +4. コンテキストは `run` 関数に渡されます。 +5. エージェントは正しくツールを呼び出し、年齢を取得します。 -## エージェント / LLM コンテキスト +## エージェント/LLM コンテキスト -LLM が呼び出される際、参照できるデータは会話履歴に含まれるもの **のみ** です。そのため、新しいデータを LLM に提供したい場合は、会話履歴に含まれるようにする必要があります。これを実現する方法はいくつかあります。 +LLM が呼び出されるとき、**唯一** 参照できるデータは会話履歴からのものです。新しいデータを LLM に利用可能にしたい場合、それを履歴に含める方法で行う必要があります。これにはいくつかの方法があります。 -1. エージェントの `instructions` に追加する方法です。これは「システムプロンプト」または「開発者メッセージ」とも呼ばれます。システムプロンプトは静的な文字列でもよく、またはコンテキストを受け取って文字列を出力する動的な関数でも構いません。これは常に有用な情報(ユーザー名や現在の日付など)を提供する際によく使われる手法です。 -2. `Runner.run` 関数を呼び出す際の `input` に追加する方法です。これは `instructions` と似ていますが、[指揮系統(chain of command)](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command) の下位に位置するメッセージを設定できます。 -3. 関数ツールを通じて公開する方法です。これは _オンデマンド_ なコンテキストに有効で、LLM が必要なデータを判断し、そのデータを取得するためにツールを呼び出します。 -4. 検索(retrieval)やウェブ検索を使用する方法です。これらはファイルやデータベースから関連データを取得(検索)したり、ウェブからデータを取得(ウェブ検索)したりする特殊なツールです。これは関連するコンテキストデータに基づいて応答を「根拠付ける(grounding)」際に有効です。 \ No newline at end of file +1. エージェントの `instructions` に追加します。これは「システムプロンプト」または「開発者メッセージ」とも呼ばれます。システムプロンプトは静的な文字列でも、コンテキストを受け取って文字列を出力する動的な関数でもかまいません。常に有用な情報(例: ユーザーの名前や現在の日付)に対して一般的な戦術です。 +2. `Runner.run` 関数を呼び出す際に `input` に追加します。これは `instructions` 戦術に似ていますが、[chain of command](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command) の下位にメッセージを持つことができます。 +3. 関数ツールを通じて公開します。これはオンデマンドのコンテキストに有用です。LLM がデータを必要とするときにツールを呼び出してそのデータを取得できます。 +4. リトリーバルや Web 検索を使用します。これらはファイルやデータベース(リトリーバル)、または Web(Web 検索)から関連データを取得できる特別なツールです。関連するコンテキストデータで応答を「グラウンド」するのに有用です。 \ No newline at end of file diff --git a/docs/ja/examples.md b/docs/ja/examples.md index 6d9252aa..21a00f67 100644 --- a/docs/ja/examples.md +++ b/docs/ja/examples.md @@ -1,40 +1,40 @@ -# コード例 +# サンプルコード -SDK のさまざまな実装サンプルについては、[リポジトリ](https://github.com/openai/openai-agents-python/tree/main/examples) のコード例セクションをご覧ください。コード例は、異なるパターンや機能を示す複数のカテゴリに分類されています。 +SDK のさまざまなサンプル実装は、[リポジトリ](https://github.com/openai/openai-agents-python/tree/main/examples)のサンプルコードセクションで確認できます。これらのサンプルコードは、異なるパターンや機能を示すいくつかのカテゴリーに整理されています。 -## カテゴリ +## カテゴリー -- **[agent_patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns):** - このカテゴリのコード例では、一般的なエージェント設計パターンを示しています。例えば、 +- **[agent_patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns):** + このカテゴリーの例は、一般的なエージェント設計パターンを示しています。例えば、 - 決定論的ワークフロー - ツールとしてのエージェント - エージェントの並列実行 -- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):** - SDK の基本的な機能を示すコード例です。例えば、 +- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):** + これらの例は、SDK の基本的な機能を紹介しています。例えば、 - 動的なシステムプロンプト - ストリーミング出力 - ライフサイクルイベント -- **[tool examples](https://github.com/openai/openai-agents-python/tree/main/examples/tools):** - Web 検索やファイル検索などの OpenAI がホストするツールの実装方法と、それらをエージェントに統合する方法を学べます。 +- **[tool examples](https://github.com/openai/openai-agents-python/tree/main/examples/tools):** + Web 検索やファイル検索などの OpenAI がホストするツールを実装し、それらをエージェントに統合する方法を学びます。 -- **[model providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):** - SDK で OpenAI 以外のモデルを使用する方法を確認できます。 +- **[model providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):** + OpenAI 以外のモデルを SDK で使用する方法を探ります。 -- **[handoffs](https://github.com/openai/openai-agents-python/tree/main/examples/handoffs):** - エージェントのハンドオフに関する実践的なコード例を参照できます。 +- **[handoffs](https://github.com/openai/openai-agents-python/tree/main/examples/handoffs):** + エージェントのハンドオフの実用的な例を見てみましょう。 -- **[mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp):** - MCP を使用したエージェントの構築方法を学べます。 +- **[mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp):** + MCP を使用してエージェントを構築する方法を学びます。 -- **[customer_service](https://github.com/openai/openai-agents-python/tree/main/examples/customer_service)** および **[research_bot](https://github.com/openai/openai-agents-python/tree/main/examples/research_bot):** - 実際のアプリケーションを示す、より具体的なコード例です。 +- **[customer_service](https://github.com/openai/openai-agents-python/tree/main/examples/customer_service)** と **[research_bot](https://github.com/openai/openai-agents-python/tree/main/examples/research_bot):** + 実際のアプリケーションを示す、さらに詳細な2つの例 - - **customer_service**:航空会社向けのカスタマーサービスシステムのコード例。 - - **research_bot**:シンプルな詳細調査クローンのコード例。 + - **customer_service**: 航空会社向けのカスタマーサービスシステムの例。 + - **research_bot**: シンプルなディープリサーチクローン。 -- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):** - TTS および STT モデルを使用した音声エージェントのコード例を参照できます。 \ No newline at end of file +- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):** + TTS と STT モデルを使用した音声エージェントの例を見てみましょう。 \ No newline at end of file diff --git a/docs/ja/guardrails.md b/docs/ja/guardrails.md index 1c55b0e0..da38d432 100644 --- a/docs/ja/guardrails.md +++ b/docs/ja/guardrails.md @@ -1,43 +1,43 @@ # ガードレール -ガードレールは、エージェント と _並行して_ 実行され、ユーザー入力のチェックや検証を可能にします。例えば、顧客のリクエストを処理するために非常に高性能(したがって遅く高価)なモデルを使用する エージェント があるとします。悪意のあるユーザーがそのモデルに数学の宿題を解かせるようなことは避けたいでしょう。そのため、高速で安価なモデルを使った ガードレール を実行できます。ガードレール が悪意のある使用を検知すると、即座にエラーを発生させ、高価なモデルの実行を停止し、時間とコストを節約できます。 +ガードレールはエージェントと _並行して_ 実行され、ユーザー入力のチェックと検証を可能にします。例えば、非常に賢い(したがって遅く/高価な)モデルを使用して顧客のリクエストを支援するエージェントがあるとします。悪意のあるユーザーがモデルに数学の宿題を手伝わせるようなことは避けたいでしょう。そこで、速く/安価なモデルでガードレールを実行できます。ガードレールが悪意のある使用を検出した場合、即座にエラーを発生させ、高価なモデルの実行を停止し、時間とお金を節約できます。 -ガードレール には 2 種類あります: +ガードレールには2種類あります: -1. 入力ガードレール:最初のユーザー入力に対して実行されます。 -2. 出力ガードレール:最終的な エージェント の出力に対して実行されます。 +1. 入力ガードレールは初期のユーザー入力に対して実行されます +2. 出力ガードレールは最終的なエージェントの出力に対して実行されます ## 入力ガードレール -入力ガードレール は次の 3 ステップで実行されます: +入力ガードレールは3つのステップで実行されます: -1. 最初に、ガードレール は エージェント に渡されたものと同じ入力を受け取ります。 -2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`InputGuardrailResult`][agents.guardrail.InputGuardrailResult] にラップされます。 -3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な応答や例外処理が可能になります。 +1. まず、ガードレールはエージェントに渡されたのと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を生成し、それが[`InputGuardrailResult`][agents.guardrail.InputGuardrailResult]でラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered]が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered]例外が発生し、ユーザーに適切に応答したり、例外を処理したりできます。 !!! Note - 入力ガードレール はユーザー入力に対して実行されるため、エージェント の ガードレール は、その エージェント が *最初の* エージェント である場合にのみ実行されます。なぜ `guardrails` プロパティが エージェント にあり、`Runner.run` に渡されないのか疑問に思うかもしれませんが、これは ガードレール が実際の エージェント に関連付けられる傾向があるためです。異なる エージェント には異なる ガードレール を実行するため、コードを同じ場所に配置することで可読性が向上します。 + 入力ガードレールはユーザー入力に対して実行されることを意図しているため、エージェントのガードレールはエージェントが*最初の*エージェントである場合にのみ実行されます。なぜ `guardrails` プロパティがエージェントにあり、`Runner.run` に渡されないのか疑問に思うかもしれません。それは、ガードレールが実際のエージェントに関連している傾向があるためです。異なるエージェントには異なるガードレールを実行するので、コードを一緒に配置することは可読性に役立ちます。 ## 出力ガードレール -出力ガードレール は次の 3 ステップで実行されます: +出力ガードレールは3つのステップで実行されます: -1. 最初に、ガードレール は エージェント に渡されたものと同じ入力を受け取ります。 -2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] にラップされます。 -3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な応答や例外処理が可能になります。 +1. まず、ガードレールはエージェントに渡されたのと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を生成し、それが[`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult]でラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered]が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]例外が発生し、ユーザーに適切に応答したり、例外を処理したりできます。 !!! Note - 出力ガードレール は最終的な エージェント の出力に対して実行されるため、エージェント の ガードレール は、その エージェント が *最後の* エージェント である場合にのみ実行されます。入力ガードレール と同様に、これは ガードレール が実際の エージェント に関連付けられる傾向があるためです。異なる エージェント には異なる ガードレール を実行するため、コードを同じ場所に配置することで可読性が向上します。 + 出力ガードレールは最終的なエージェントの出力に対して実行されることを意図しているため、エージェントのガードレールはエージェントが*最後の*エージェントである場合にのみ実行されます。入力ガードレールと同様に、ガードレールが実際のエージェントに関連している傾向があるため、コードを一緒に配置することは可読性に役立ちます。 -## トリップワイヤ(Tripwires) +## トリップワイヤー -入力または出力が ガードレール を通過できない場合、ガードレール はトリップワイヤを使ってこれを通知します。トリップワイヤがトリガーされた ガードレール を検知すると、即座に `{Input,Output}GuardrailTripwireTriggered` 例外を発生させ、エージェント の実行を停止します。 +入力または出力がガードレールに失敗した場合、ガードレールはトリップワイヤーでこれを知らせることができます。トリップワイヤーがトリガーされたガードレールを確認するとすぐに、`{Input,Output}GuardrailTripwireTriggered`例外を即座に発生させ、エージェントの実行を停止します。 -## ガードレール の実装 +## ガードレールの実装 -入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を返す関数を提供する必要があります。この例では、内部で エージェント を実行することでこれを実現します。 +入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を返す関数を提供する必要があります。この例では、エージェントを内部で実行することでこれを行います。 ```python from pydantic import BaseModel @@ -90,12 +90,12 @@ async def main(): print("Math homework guardrail tripped") ``` -1. この エージェント を ガードレール関数 内で使用します。 -2. これは エージェント の入力とコンテキストを受け取り、結果を返す ガードレール関数 です。 -3. ガードレール の結果に追加情報を含めることができます。 -4. これはワークフローを定義する実際の エージェント です。 +1. このエージェントをガードレール関数で使用します。 +2. これはエージェントの入力/コンテキストを受け取り、結果を返すガードレール関数です。 +3. ガードレールの結果に追加情報を含めることができます。 +4. これはワークフローを定義する実際のエージェントです。 -出力ガードレール も同様です。 +出力ガードレールも同様です。 ```python from pydantic import BaseModel @@ -148,7 +148,7 @@ async def main(): print("Math output guardrail tripped") ``` -1. これは実際の エージェント の出力タイプです。 -2. これは ガードレール の出力タイプです。 -3. これは エージェント の出力を受け取り、結果を返す ガードレール関数 です。 -4. これはワークフローを定義する実際の エージェント です。 \ No newline at end of file +1. これは実際のエージェントの出力タイプです。 +2. これはガードレールの出力タイプです。 +3. これはエージェントの出力を受け取り、結果を返すガードレール関数です。 +4. これはワークフローを定義する実際のエージェントです。 \ No newline at end of file diff --git a/docs/ja/handoffs.md b/docs/ja/handoffs.md index 2d5433f4..575195b1 100644 --- a/docs/ja/handoffs.md +++ b/docs/ja/handoffs.md @@ -1,18 +1,18 @@ # ハンドオフ -ハンドオフを使用すると、あるエージェントが別のエージェントにタスクを委任できます。これは、異なるエージェントがそれぞれ特定の分野を専門としている場合に特に役立ちます。例えば、カスタマーサポートアプリでは、注文状況、返金、FAQ などのタスクをそれぞれ専門に処理するエージェントを用意できます。 +ハンドオフは、エージェントがタスクを他のエージェントに委任することを可能にします。これは、異なるエージェントが異なる分野に特化しているシナリオで特に有用です。例えば、カスタマーサポートアプリでは、注文状況、返金、FAQ などのタスクをそれぞれ専門に扱うエージェントがいるかもしれません。 -ハンドオフは、LLM に対してツールとして表現されます。例えば、`Refund Agent` という名前のエージェントへのハンドオフがある場合、そのツールは `transfer_to_refund_agent` と呼ばれます。 +ハンドオフは LLM にとってツールとして表現されます。したがって、`Refund Agent` という名前のエージェントへのハンドオフがある場合、ツールは `transfer_to_refund_agent` と呼ばれます。 ## ハンドオフの作成 -すべてのエージェントは [`handoffs`][agents.agent.Agent.handoffs] パラメータを持ち、これは直接 `Agent` を指定するか、またはカスタマイズされた `Handoff` オブジェクトを指定できます。 +すべてのエージェントには [`handoffs`][agents.agent.Agent.handoffs] パラメーターがあり、これは `Agent` を直接取るか、ハンドオフをカスタマイズする `Handoff` オブジェクトを取ることができます。 Agents SDK が提供する [`handoff()`][agents.handoffs.handoff] 関数を使用してハンドオフを作成できます。この関数を使用すると、ハンドオフ先のエージェントを指定し、オプションでオーバーライドや入力フィルターを設定できます。 -### 基本的な使用方法 +### 基本的な使い方 -シンプルなハンドオフの作成方法は以下の通りです。 +簡単なハンドオフを作成する方法は次のとおりです。 ```python from agents import Agent, handoff @@ -24,18 +24,18 @@ refund_agent = Agent(name="Refund agent") triage_agent = Agent(name="Triage agent", handoffs=[billing_agent, handoff(refund_agent)]) ``` -1. エージェントを直接指定する方法(`billing_agent` のように)と、`handoff()` 関数を使用する方法があります。 +1. エージェントを直接使用することも(`billing_agent` のように)、`handoff()` 関数を使用することもできます。 -### `handoff()` 関数を使用したハンドオフのカスタマイズ +### `handoff()` 関数によるハンドオフのカスタマイズ -[`handoff()`][agents.handoffs.handoff] 関数を使用すると、以下の項目をカスタマイズできます。 +[`handoff()`][agents.handoffs.handoff] 関数を使用すると、さまざまなカスタマイズが可能です。 -- `agent`:ハンドオフ先のエージェントを指定します。 -- `tool_name_override`:デフォルトでは `Handoff.default_tool_name()` 関数が使用され、`transfer_to_` という形式になりますが、これをオーバーライドできます。 -- `tool_description_override`:デフォルトのツール説明(`Handoff.default_tool_description()`)をオーバーライドします。 -- `on_handoff`:ハンドオフが呼び出された際に実行されるコールバック関数です。これは、ハンドオフが呼ばれた時点でデータ取得などの処理を開始する場合に便利です。この関数はエージェントのコンテキストを受け取り、オプションで LLM が生成した入力も受け取れます。入力データは `input_type` パラメータで制御されます。 -- `input_type`:ハンドオフが期待する入力の型を指定します(オプション)。 -- `input_filter`:次のエージェントが受け取る入力をフィルタリングできます。詳細は後述します。 +- `agent`: ハンドオフ先のエージェントです。 +- `tool_name_override`: デフォルトでは `Handoff.default_tool_name()` 関数が使用され、`transfer_to_` に解決されます。これをオーバーライドできます。 +- `tool_description_override`: `Handoff.default_tool_description()` からのデフォルトのツール説明をオーバーライドします。 +- `on_handoff`: ハンドオフが呼び出されたときに実行されるコールバック関数です。ハンドオフが呼び出されるとすぐにデータ取得を開始するなどに役立ちます。この関数はエージェントコンテキストを受け取り、オプションで LLM が生成した入力も受け取ることができます。入力データは `input_type` パラメーターで制御されます。 +- `input_type`: ハンドオフが期待する入力のタイプ(オプション)。 +- `input_filter`: 次のエージェントが受け取る入力をフィルタリングできます。詳細は以下を参照してください。 ```python from agents import Agent, handoff, RunContextWrapper @@ -53,9 +53,9 @@ handoff_obj = handoff( ) ``` -## ハンドオフの入力 +## ハンドオフ入力 -特定の状況では、LLM がハンドオフを呼び出す際に何らかのデータを提供するようにしたい場合があります。例えば、「Escalation agent(エスカレーションエージェント)」へのハンドオフを考えると、ログ記録のために理由を提供してほしい場合があります。 +特定の状況では、LLM がハンドオフを呼び出す際にデータを提供することを望む場合があります。例えば、「エスカレーションエージェント」へのハンドオフを想像してください。理由を提供してログに記録したいかもしれません。 ```python from pydantic import BaseModel @@ -79,9 +79,9 @@ handoff_obj = handoff( ## 入力フィルター -ハンドオフが発生すると、新しいエージェントが会話を引き継ぎ、それまでの会話履歴全体を参照できるようになります。これを変更したい場合は、[`input_filter`][agents.handoffs.Handoff.input_filter] を設定できます。入力フィルターは、既存の入力を [`HandoffInputData`][agents.handoffs.HandoffInputData] として受け取り、新しい `HandoffInputData` を返す関数です。 +ハンドオフが発生すると、新しいエージェントが会話を引き継ぎ、以前の会話履歴全体を見ることができます。これを変更したい場合は、[`input_filter`][agents.handoffs.Handoff.input_filter] を設定できます。入力フィルターは、既存の入力を [`HandoffInputData`][agents.handoffs.HandoffInputData] 経由で受け取り、新しい `HandoffInputData` を返す必要がある関数です。 -よくあるパターン(例えば履歴からすべてのツール呼び出しを削除するなど)は、[`agents.extensions.handoff_filters`][] にあらかじめ実装されています。 +一般的なパターン(例えば、履歴からすべてのツール呼び出しを削除する)が [`agents.extensions.handoff_filters`][] に実装されています。 ```python from agents import Agent, handoff @@ -95,11 +95,11 @@ handoff_obj = handoff( ) ``` -1. これにより、`FAQ agent` が呼び出された際に履歴からすべてのツールが自動的に削除されます。 +1. これにより、`FAQ agent` が呼び出されたときに履歴からすべてのツールが自動的に削除されます。 ## 推奨プロンプト -LLM がハンドオフを適切に理解できるようにするため、エージェントのプロンプトにハンドオフに関する情報を含めることを推奨します。推奨されるプレフィックスは [`agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX`][] に用意されています。または、[`agents.extensions.handoff_prompt.prompt_with_handoff_instructions`][] を呼び出して、推奨データをプロンプトに自動的に追加できます。 +LLM がハンドオフを正しく理解するために、エージェントにハンドオフに関する情報を含めることをお勧めします。[`agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX`][] に推奨されるプレフィックスがあります。または、[`agents.extensions.handoff_prompt.prompt_with_handoff_instructions`][] を呼び出して、プロンプトに推奨データを自動的に追加できます。 ```python from agents import Agent diff --git a/docs/ja/index.md b/docs/ja/index.md index 87b419fd..f36de0ac 100644 --- a/docs/ja/index.md +++ b/docs/ja/index.md @@ -1,28 +1,28 @@ -# OpenAI Agents SDK +# OpenAI エージェント SDK -[OpenAI Agents SDK](https://github.com/openai/openai-agents-python) は、軽量で使いやすく、抽象化を最小限に抑えたエージェントベースの AI アプリケーションを構築できるようにします。これは、以前のエージェント実験である [Swarm](https://github.com/openai/swarm/tree/main) を本番環境向けにアップグレードしたものです。Agents SDK は非常に少数の基本コンポーネント(primitives)で構成されています。 +[OpenAI エージェント SDK](https://github.com/openai/openai-agents-python) は、軽量で使いやすいパッケージでエージェント AI アプリを構築することを可能にします。これは、以前のエージェントの実験である [Swarm](https://github.com/openai/swarm/tree/main) のプロダクション対応のアップグレード版です。エージェント SDK には、非常に少ない基本コンポーネントがあります。 -- **エージェント** : instructions と tools を備えた LLM -- **ハンドオフ** : 特定のタスクを他のエージェントに委任する仕組み -- **ガードレール** : エージェントへの入力を検証する仕組み +- **エージェント**: instructions と tools を備えた LLM +- **ハンドオフ**: エージェントが特定のタスクを他のエージェントに委任することを可能にします +- **ガードレール**: エージェントへの入力を検証することを可能にします -これらの基本コンポーネントを Python と組み合わせることで、ツールとエージェント間の複雑な関係を表現でき、急な学習曲線なしに実世界のアプリケーションを構築できます。さらに SDK には、エージェントのフローを視覚化・デバッグし、評価やモデルのファインチューニングまで可能にする組み込みの **トレーシング** 機能が備わっています。 +これらの基本コンポーネントは Python と組み合わせることで、ツールとエージェント間の複雑な関係を表現するのに十分な強力さを持ち、急な学習曲線なしで実際のアプリケーションを構築することができます。さらに、SDK には組み込みの **トレーシング** があり、エージェントのフローを視覚化してデバッグし、評価し、さらにはアプリケーション用にモデルを微調整することができます。 -## Agents SDK を使う理由 +## なぜエージェント SDK を使うのか -SDK は以下の 2 つの設計原則に基づいています。 +SDK には 2 つの設計原則があります。 -1. 利用価値のある十分な機能を備えつつ、迅速に習得できるよう基本コンポーネントを最小限に抑える。 -2. そのままでも優れた動作をするが、必要に応じて細かくカスタマイズ可能。 +1. 使用する価値があるだけの機能を持ち、学習が迅速になるように基本コンポーネントを少なくする。 +2. すぐに使えるが、何が起こるかを正確にカスタマイズできる。 -SDK の主な機能は以下の通りです。 +SDK の主な機能は次のとおりです。 -- **エージェントループ** : ツールの呼び出し、LLM への実行結果の送信、LLM が完了するまでのループ処理を組み込みで提供。 -- **Python ファースト** : 新しい抽象化を学ぶ必要なく、Python の言語機能を使ってエージェントの連携やチェーンを構築可能。 -- **ハンドオフ** : 複数のエージェント間での調整やタスク委任を可能にする強力な機能。 -- **ガードレール** : エージェントと並行して入力の検証やチェックを実行し、チェックが失敗した場合は早期に処理を中断。 -- **関数ツール** : 任意の Python 関数をツールに変換し、自動的なスキーマ生成と Pydantic による検証を提供。 -- **トレーシング** : ワークフローの視覚化、デバッグ、モニタリングを可能にする組み込みのトレーシング機能。OpenAI が提供する評価、ファインチューニング、蒸留ツールも利用可能。 +- エージェントループ: ツールの呼び出し、LLM への結果の送信、LLM が完了するまでのループを処理する組み込みのエージェントループ。 +- Python ファースト: 新しい抽象化を学ぶ必要なく、組み込みの言語機能を使用してエージェントを編成し、連鎖させる。 +- ハンドオフ: 複数のエージェント間で調整し、委任するための強力な機能。 +- ガードレール: エージェントと並行して入力検証とチェックを実行し、チェックが失敗した場合は早期に中断。 +- 関数ツール: 任意の Python 関数をツールに変換し、自動スキーマ生成と Pydantic による検証を行う。 +- トレーシング: ワークフローを視覚化、デバッグ、監視するための組み込みのトレーシング、および OpenAI の評価、微調整、蒸留ツールを使用。 ## インストール @@ -45,7 +45,7 @@ print(result.final_output) # Infinite loop's dance. ``` -(_実行する場合は、環境変数 `OPENAI_API_KEY` を設定してください。_) +(_これを実行する場合は、`OPENAI_API_KEY` 環境変数を設定してください_) ```bash export OPENAI_API_KEY=sk-... diff --git a/docs/ja/mcp.md b/docs/ja/mcp.md index 52ed1558..057fe188 100644 --- a/docs/ja/mcp.md +++ b/docs/ja/mcp.md @@ -1,21 +1,21 @@ # Model context protocol (MCP) -[Model context protocol](https://modelcontextprotocol.io/introduction)(別名 MCP)は、LLM にツールやコンテキストを提供するための方法です。MCP のドキュメントから引用します: +[Model context protocol](https://modelcontextprotocol.io/introduction) (別名 MCP) は、LLM にツールとコンテキストを提供する方法です。MCP ドキュメントからの引用: -> MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンなプロトコルです。MCP は AI アプリケーションにおける USB-C ポートのようなものです。USB-C がデバイスをさまざまな周辺機器やアクセサリに接続するための標準化された方法を提供するのと同様に、MCP は AI モデルをさまざまなデータソースやツールに接続するための標準化された方法を提供します。 +> MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP を AI アプリケーションのための USB-C ポートのように考えてください。USB-C がデバイスをさまざまな周辺機器やアクセサリーに接続する標準化された方法を提供するのと同様に、MCP は AI モデルをさまざまなデータソースやツールに接続する標準化された方法を提供します。 -Agents SDK は MCP をサポートしています。これにより、さまざまな MCP サーバーを使用して、エージェントにツールを提供できます。 +エージェント SDK は MCP をサポートしています。これにより、エージェントにツールを提供するために幅広い MCP サーバーを使用できます。 ## MCP サーバー -現在、MCP の仕様では、使用するトランスポートメカニズムに基づいて 2 種類のサーバーが定義されています: +現在、MCP 仕様は使用するトランスポートメカニズムに基づいて2種類のサーバーを定義しています: -1. **stdio** サーバーはアプリケーションのサブプロセスとして実行されます。これらは「ローカル」で実行されると考えることができます。 -2. **HTTP over SSE** サーバーはリモートで実行されます。これらには URL を介して接続します。 +1. **stdio** サーバーは、アプリケーションのサブプロセスとして実行されます。これらは「ローカルで」実行されると考えることができます。 +2. **HTTP over SSE** サーバーはリモートで実行されます。URL を介して接続します。 -これらのサーバーに接続するには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] および [`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用できます。 +これらのサーバーに接続するには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用できます。 -例えば、[公式 MCP ファイルシステムサーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem)を使用する場合は以下のようになります: +例えば、[公式 MCP ファイルシステムサーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem) を使用する方法は次のとおりです。 ```python async with MCPServerStdio( @@ -27,11 +27,12 @@ async with MCPServerStdio( tools = await server.list_tools() ``` -## MCP サーバーの使用方法 +## MCP サーバーの使用 -MCP サーバーはエージェントに追加できます。Agents SDK はエージェントが実行されるたびに MCP サーバーの `list_tools()` を呼び出します。これにより、LLM は MCP サーバーのツールを認識します。LLM が MCP サーバーのツールを呼び出すと、SDK はそのサーバーの `call_tool()` を呼び出します。 +MCP サーバーはエージェントに追加できます。エージェント SDK は、エージェントが実行されるたびに MCP サーバーで `list_tools()` を呼び出します。これにより、LLM は MCP サーバーのツールを認識します。LLM が MCP サーバーのツールを呼び出すと、SDK はそのサーバーで `call_tool()` を呼び出します。 ```python + agent=Agent( name="Assistant", instructions="Use the tools to achieve the task", @@ -39,21 +40,21 @@ agent=Agent( ) ``` -## キャッシュ +## キャッシング -エージェントが実行されるたびに、MCP サーバーの `list_tools()` が呼び出されます。特にサーバーがリモートの場合、これはレイテンシの原因となる可能性があります。ツールのリストを自動的にキャッシュするには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] の両方に `cache_tools_list=True` を渡します。これは、ツールのリストが変更されないことが確実な場合にのみ行ってください。 +エージェントが実行されるたびに、MCP サーバーで `list_tools()` を呼び出します。これは、特にサーバーがリモートサーバーの場合、レイテンシーの影響を受ける可能性があります。ツールのリストを自動的にキャッシュするには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] に `cache_tools_list=True` を渡すことができます。ツールリストが変更されないことが確実な場合にのみこれを行うべきです。 -キャッシュを無効化したい場合は、サーバーの `invalidate_tools_cache()` を呼び出します。 +キャッシュを無効にしたい場合は、サーバーで `invalidate_tools_cache()` を呼び出すことができます。 -## エンドツーエンドのコード例 +## エンドツーエンドの例 -完全な動作コード例については、[examples/mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp) を参照してください。 +[examples/mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp) で完全な動作例を確認してください。 ## トレーシング -[トレーシング](./tracing.md) は、以下を含む MCP 操作を自動的にキャプチャします: +[トレーシング](./tracing.md) は、MCP 操作を自動的にキャプチャします。これには以下が含まれます: -1. MCP サーバーへのツール一覧取得の呼び出し +1. ツールをリストするための MCP サーバーへの呼び出し 2. 関数呼び出しに関する MCP 関連情報 -![MCP トレーシングのスクリーンショット](../assets/images/mcp-tracing.jpg) \ No newline at end of file +![MCP Tracing Screenshot](../assets/images/mcp-tracing.jpg) \ No newline at end of file diff --git a/docs/ja/models.md b/docs/ja/models.md index b333666a..a71c9fef 100644 --- a/docs/ja/models.md +++ b/docs/ja/models.md @@ -1,21 +1,21 @@ # モデル -Agents SDK は、OpenAI モデルを以下の 2 種類の形式で標準サポートしています。 +エージェント SDK は、次の 2 種類の OpenAI モデルをサポートしています。 -- **推奨** : 新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使用して OpenAI API を呼び出す [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] -- [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使用して OpenAI API を呼び出す [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] +- **推奨**: 新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使用して OpenAI API を呼び出す [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel]。 +- [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使用して OpenAI API を呼び出す [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel]。 -## モデルの混在と組み合わせ +## モデルの組み合わせ -単一のワークフロー内で、各エージェントごとに異なるモデルを使用したい場合があります。例えば、トリアージには小型で高速なモデルを使用し、複雑なタスクにはより大きく高性能なモデルを使用することができます。[`Agent`][agents.Agent] を設定する際、以下のいずれかの方法で特定のモデルを選択できます。 +1 つのワークフロー内で、各エージェントに異なるモデルを使用したい場合があります。たとえば、トリアージには小さくて高速なモデルを使用し、複雑なタスクにはより大きくて高機能なモデルを使用することができます。[`Agent`][agents.Agent] を設定する際に、次の方法で特定のモデルを選択できます。 -1. OpenAI モデルの名前を直接指定する。 -2. 任意のモデル名と、その名前をモデルインスタンスにマッピングできる [`ModelProvider`][agents.models.interface.ModelProvider] を指定する。 -3. [`Model`][agents.models.interface.Model] 実装を直接指定する。 +1. OpenAI モデルの名前を渡す。 +2. モデル名とその名前をモデルインスタンスにマッピングできる [`ModelProvider`][agents.models.interface.ModelProvider] を渡す。 +3. 直接 [`Model`][agents.models.interface.Model] 実装を提供する。 -!!! note +!!!note - SDK は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] と [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] の両方の形式をサポートしていますが、各ワークフローでは単一のモデル形式を使用することを推奨します。これは、2 つの形式が異なる機能やツールをサポートしているためです。ワークフローで複数のモデル形式を混在させる必要がある場合は、使用するすべての機能が両方の形式で利用可能であることを確認してください。 + SDK は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] と [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] の両方の形状をサポートしていますが、各ワークフローに対して単一のモデル形状を使用することをお勧めします。2 つの形状は異なる機能とツールをサポートしているためです。ワークフローでモデル形状を組み合わせる必要がある場合は、使用しているすべての機能が両方で利用可能であることを確認してください。 ```python from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel @@ -48,46 +48,46 @@ async def main(): print(result.final_output) ``` -1. OpenAI モデルの名前を直接指定しています。 -2. [`Model`][agents.models.interface.Model] 実装を指定しています。 +1. OpenAI モデルの名前を直接設定します。 +2. [`Model`][agents.models.interface.Model] 実装を提供します。 ## 他の LLM プロバイダーの使用 -他の LLM プロバイダーを使用するには、以下の 3 つの方法があります(コード例は [こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/))。 +他の LLM プロバイダーを 3 つの方法で使用できます(例は[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/))。 -1. [`set_default_openai_client`][agents.set_default_openai_client] は、グローバルに `AsyncOpenAI` インスタンスを LLM クライアントとして使用したい場合に便利です。これは、LLM プロバイダーが OpenAI 互換の API エンドポイントを持ち、`base_url` と `api_key` を設定できる場合に使用します。設定可能なコード例は [examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) を参照してください。 -2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで指定します。これにより、「この実行におけるすべてのエージェントにカスタムモデルプロバイダーを使用する」と指定できます。設定可能なコード例は [examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) を参照してください。 -3. [`Agent.model`][agents.agent.Agent.model] は特定のエージェントインスタンスにモデルを指定できます。これにより、異なるエージェントに異なるプロバイダーを組み合わせて使用できます。設定可能なコード例は [examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) を参照してください。 +1. [`set_default_openai_client`][agents.set_default_openai_client] は、`AsyncOpenAI` のインスタンスを LLM クライアントとしてグローバルに使用したい場合に便利です。これは、LLM プロバイダーが OpenAI 互換の API エンドポイントを持っている場合で、`base_url` と `api_key` を設定できます。[examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) に設定可能な例があります。 +2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで使用します。これにより、「この実行のすべてのエージェントにカスタムモデルプロバイダーを使用する」と指定できます。[examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) に設定可能な例があります。 +3. [`Agent.model`][agents.agent.Agent.model] では、特定のエージェントインスタンスにモデルを指定できます。これにより、異なるエージェントに対して異なるプロバイダーを組み合わせて使用することができます。[examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) に設定可能な例があります。 -`platform.openai.com` の API キーを持っていない場合は、`set_tracing_disabled()` を使用してトレーシングを無効化するか、[別のトレーシングプロセッサ](tracing.md) を設定することを推奨します。 +`platform.openai.com` からの API キーがない場合は、`set_tracing_disabled()` を使用してトレーシングを無効にするか、[異なるトレーシングプロセッサー](tracing.md)を設定することをお勧めします。 !!! note - これらのコード例では Chat Completions API / モデルを使用しています。これは、多くの LLM プロバイダーがまだ Responses API をサポートしていないためです。使用する LLM プロバイダーが Responses API をサポートしている場合は、Responses の使用を推奨します。 + これらの例では、Chat Completions API/モデルを使用しています。なぜなら、ほとんどの LLM プロバイダーはまだ Responses API をサポートしていないからです。LLM プロバイダーがそれをサポートしている場合は、Responses を使用することをお勧めします。 -## 他の LLM プロバイダー使用時の一般的な問題 +## 他の LLM プロバイダーを使用する際の一般的な問題 -### トレーシングクライアントのエラー 401 +### トレーシングクライアントエラー 401 -トレーシングに関連するエラーが発生する場合、これはトレースが OpenAI サーバーにアップロードされるためであり、OpenAI API キーを持っていないことが原因です。解決方法は以下の 3 つです。 +トレーシングに関連するエラーが発生した場合、これはトレースが OpenAI サーバーにアップロードされ、OpenAI API キーを持っていないためです。これを解決するには、次の 3 つのオプションがあります。 -1. トレーシングを完全に無効化する : [`set_tracing_disabled(True)`][agents.set_tracing_disabled] -2. トレーシング用に OpenAI キーを設定する : [`set_tracing_export_api_key(...)`][agents.set_tracing_export_api_key]。この API キーはトレースのアップロードのみに使用され、[platform.openai.com](https://platform.openai.com/) から取得する必要があります。 -3. OpenAI 以外のトレースプロセッサを使用する : 詳細は [トレーシングドキュメント](tracing.md#custom-tracing-processors) を参照してください。 +1. トレーシングを完全に無効にする: [`set_tracing_disabled(True)`][agents.set_tracing_disabled]。 +2. トレーシング用の OpenAI キーを設定する: [`set_tracing_export_api_key(...)`][agents.set_tracing_export_api_key]。この API キーはトレースのアップロードにのみ使用され、[platform.openai.com](https://platform.openai.com/) からのものでなければなりません。 +3. 非 OpenAI トレースプロセッサーを使用する。[トレーシングドキュメント](tracing.md#custom-tracing-processors)を参照してください。 -### Responses API のサポート +### Responses API サポート -SDK はデフォルトで Responses API を使用しますが、多くの他の LLM プロバイダーはまだこれをサポートしていません。そのため、404 エラーなどが発生する場合があります。解決方法は以下の 2 つです。 +SDK はデフォルトで Responses API を使用しますが、ほとんどの他の LLM プロバイダーはまだサポートしていません。その結果、404 エラーや類似の問題が発生することがあります。これを解決するには、次の 2 つのオプションがあります。 -1. [`set_default_openai_api("chat_completions")`][agents.set_default_openai_api] を呼び出す。これは環境変数で `OPENAI_API_KEY` と `OPENAI_BASE_URL` を設定している場合に有効です。 -2. [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] を使用する。コード例は [こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/) を参照してください。 +1. [`set_default_openai_api("chat_completions")`][agents.set_default_openai_api] を呼び出します。これは、環境変数を介して `OPENAI_API_KEY` と `OPENAI_BASE_URL` を設定している場合に機能します。 +2. [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] を使用します。例は[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/)にあります。 -### structured outputs のサポート +### 適切な形式のデータのサポート -一部のモデルプロバイダーは [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) をサポートしていません。そのため、以下のようなエラーが発生する場合があります。 +一部のモデルプロバイダーは[適切な形式のデータ](https://platform.openai.com/docs/guides/structured-outputs)をサポートしていません。これにより、次のようなエラーが発生することがあります。 ``` BadRequestError: Error code: 400 - {'error': {'message': "'response_format.type' : value is not one of the allowed values ['text','json_object']", 'type': 'invalid_request_error'}} ``` -これは一部のモデルプロバイダーの制限であり、JSON 出力はサポートしていますが、出力に使用する `json_schema` を指定できないためです。この問題への対応を進めていますが、現時点では JSON スキーマ出力をサポートするプロバイダーを使用することを推奨します。そうでない場合、アプリケーションが不適切な JSON により頻繁に破損する可能性があります。 \ No newline at end of file +これは一部のモデルプロバイダーの欠点で、JSON 出力をサポートしていますが、出力に使用する `json_schema` を指定することはできません。この問題の修正に取り組んでいますが、JSON スキーマ出力をサポートしているプロバイダーに依存することをお勧めします。さもないと、アプリが不正な JSON のために頻繁に壊れることになります。 \ No newline at end of file diff --git a/docs/ja/multi_agent.md b/docs/ja/multi_agent.md index 4c8be96d..af635776 100644 --- a/docs/ja/multi_agent.md +++ b/docs/ja/multi_agent.md @@ -1,37 +1,37 @@ -# 複数のエージェントのオーケストレーション +# 複数エージェントのオーケストレーション -オーケストレーションとは、アプリ内でのエージェントの流れを指します。どのエージェントがどの順序で実行され、次に何を行うかをどのように決定するかを意味します。エージェントをオーケストレーションする主な方法は 2 つあります。 +オーケストレーションとは、アプリ内でのエージェントの流れを指します。どのエージェントが実行され、どの順序で、次に何が起こるかをどのように決定するかです。エージェントをオーケストレーションする主な方法は2つあります。 -1. LLM に判断を任せる方法:LLM の知性を利用して計画、推論を行い、それに基づいて次のステップを決定します。 -2. コードによるオーケストレーション:コードを通じてエージェントの流れを決定します。 +1. LLM に決定を任せる: これは LLM の知能を利用して、計画、推論し、それに基づいてどのステップを取るかを決定します。 +2. コードによるオーケストレーション: コードを通じてエージェントの流れを決定します。 -これらのパターンは組み合わせて使用することも可能です。それぞれのトレードオフについて以下で説明します。 +これらのパターンを組み合わせて使用することができます。それぞれに独自のトレードオフがあり、以下で説明します。 ## LLM によるオーケストレーション -エージェントとは、LLM に instructions、tools、handoffs を与えたものです。これにより、自由度の高いタスクを与えられた場合でも、LLM は自律的にタスクの取り組み方を計画し、tools を使ってアクションを実行したりデータを取得したり、handoffs を使ってサブエージェントにタスクを委任したりできます。例えば、調査エージェントには以下のようなツールを装備できます。 +エージェントは、指示、ツール、ハンドオフを備えた LLM です。これにより、オープンエンドなタスクが与えられた場合、LLM は自律的にタスクに取り組む方法を計画し、ツールを使用してアクションを実行し、データを取得し、ハンドオフを使用してサブエージェントにタスクを委任できます。例えば、リサーチエージェントは次のようなツールを備えることができます。 -- Web 検索:オンラインで情報を検索 -- ファイル検索と取得:独自データや接続先から情報を検索 -- コンピュータ操作:コンピュータ上でアクションを実行 -- コード実行:データ分析を実施 -- ハンドオフ:計画立案やレポート作成などに特化したエージェントにタスクを委任 +- Web 検索でオンライン情報を見つける +- ファイル検索と取得で独自データや接続を検索する +- コンピュータ操作でコンピュータ上でアクションを実行する +- コード実行でデータ分析を行う +- 計画やレポート作成に優れた専門エージェントへのハンドオフ -このパターンは、自由度の高いタスクで LLM の知性に頼りたい場合に適しています。ここで重要な戦術は以下の通りです。 +このパターンは、タスクがオープンエンドであり、LLM の知能に依存したい場合に最適です。ここでの最も重要な戦術は次のとおりです。 -1. 良質なプロンプトに投資する。利用可能なツール、使用方法、動作パラメータを明確にする。 -2. アプリを監視し、繰り返し改善する。問題が発生した箇所を特定し、プロンプトを改善する。 -3. エージェントが自己内省し改善できるようにする。例えばループ内で実行し、自らを批評させたり、エラーメッセージを与えて改善させたりする。 -4. 汎用的なエージェントにあらゆるタスクを任せるのではなく、特定のタスクに秀でた専門エージェントを用意する。 -5. [evals](https://platform.openai.com/docs/guides/evals) に投資する。これによりエージェントを訓練し、タスクの遂行能力を向上させることができる。 +1. 良いプロンプトに投資する。利用可能なツール、使用方法、および操作するパラメーターを明確にします。 +2. アプリを監視し、反復する。問題が発生する箇所を確認し、プロンプトを改善します。 +3. エージェントに内省と改善を許可する。例えば、ループで実行し、自己批評させるか、エラーメッセージを提供して改善させます。 +4. 一つのタスクに優れた専門エージェントを持つこと。何でも得意とされる汎用エージェントを持つのではなく。 +5. [evals](https://platform.openai.com/docs/guides/evals) に投資する。これにより、エージェントを訓練してタスクの改善と向上を図ることができます。 ## コードによるオーケストレーション -LLM によるオーケストレーションは強力ですが、コードによるオーケストレーションは速度、コスト、パフォーマンスの観点でより決定論的で予測可能になります。ここでの一般的なパターンは以下の通りです。 +LLM によるオーケストレーションは強力ですが、コードによるオーケストレーションは、速度、コスト、パフォーマンスの面でタスクをより決定的で予測可能にします。ここでの一般的なパターンは次のとおりです。 -- [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用して、コードで検査可能な適切な形式のデータを生成する。例えば、エージェントにタスクをいくつかのカテゴリに分類させ、そのカテゴリに基づいて次のエージェントを選択することができます。 -- 複数のエージェントを連鎖させ、一つのエージェントの出力を次のエージェントの入力に変換する。例えばブログ記事を書くというタスクを、調査、アウトライン作成、記事執筆、批評、改善という一連のステップに分解できます。 -- タスクを実行するエージェントを、評価とフィードバックを行うエージェントと共に `while` ループ内で実行し、評価エージェントが出力が一定の基準を満たすと判断するまで繰り返します。 -- 複数のエージェントを並列で実行する。例えば Python の基本コンポーネント (`asyncio.gather` など) を使用します。これは、互いに依存しない複数のタスクを高速に処理する場合に有効です。 +- [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用して、コードで検査できる適切な形式のデータを生成します。例えば、エージェントにタスクをいくつかのカテゴリーに分類させ、そのカテゴリーに基づいて次のエージェントを選択することができます。 +- 複数のエージェントをチェーンして、一つの出力を次の入力に変換します。ブログ記事を書くタスクを、リサーチ、アウトライン作成、記事執筆、批評、改善という一連のステップに分解できます。 +- `while` ループでタスクを実行するエージェントと、評価とフィードバックを提供するエージェントを実行し、評価者が出力が特定の基準を満たすと判断するまで続けます。 +- 複数のエージェントを並行して実行します。例えば、Python の基本コンポーネントである `asyncio.gather` を使用します。これは、互いに依存しない複数のタスクがある場合に速度のために役立ちます。 -[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) に多数のコード例があります。 \ No newline at end of file +[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) には多くのコード例があります。 \ No newline at end of file diff --git a/docs/ja/quickstart.md b/docs/ja/quickstart.md index 691761a2..9e4846ef 100644 --- a/docs/ja/quickstart.md +++ b/docs/ja/quickstart.md @@ -2,7 +2,7 @@ ## プロジェクトと仮想環境の作成 -以下の操作は一度だけ行います。 +これは一度だけ行えば大丈夫です。 ```bash mkdir my_project @@ -10,9 +10,9 @@ cd my_project python -m venv .venv ``` -### 仮想環境の有効化 +### 仮想環境をアクティブにする -新しいターミナルセッションを開始するたびに、この操作を行います。 +新しいターミナルセッションを開始するたびに行ってください。 ```bash source .venv/bin/activate @@ -21,20 +21,20 @@ source .venv/bin/activate ### Agents SDK のインストール ```bash -pip install openai-agents # または `uv add openai-agents` など +pip install openai-agents # or `uv add openai-agents`, etc ``` ### OpenAI API キーの設定 -API キーをお持ちでない場合は、[こちらの手順](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)に従って OpenAI API キーを作成してください。 +お持ちでない場合は、[こちらの手順](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)に従って OpenAI API キーを作成してください。 ```bash export OPENAI_API_KEY=sk-... ``` -## 最初のエージェントの作成 +## 最初のエージェントを作成する -エージェント は、 instructions 、名前、およびオプションの設定( `model_config` など)で定義します。 +エージェントは、instructions、名前、オプションの設定(`model_config` など)で定義されます。 ```python from agents import Agent @@ -45,9 +45,9 @@ agent = Agent( ) ``` -## さらに複数のエージェントを追加する +## さらにエージェントを追加する -追加のエージェントも同様に定義できます。 `handoff_description` は、ハンドオフのルーティングを決定するための追加のコンテキストを提供します。 +追加のエージェントも同様に定義できます。`handoff_descriptions` は、ハンドオフルーティングを決定するための追加のコンテキストを提供します。 ```python from agents import Agent @@ -65,9 +65,9 @@ math_tutor_agent = Agent( ) ``` -## ハンドオフの定義 +## ハンドオフを定義する -各エージェントに対して、タスクを進める方法を決定するために選択可能なハンドオフのオプションを定義できます。 +各エージェントで、タスクを進める方法を決定するための送信ハンドオフオプションのインベントリを定義できます。 ```python triage_agent = Agent( @@ -77,9 +77,9 @@ triage_agent = Agent( ) ``` -## エージェントのオーケストレーションを実行する +## エージェントオーケストレーションを実行する -ワークフローが正しく動作し、トリアージエージェントが 2 つの専門エージェント間で適切にルーティングすることを確認しましょう。 +ワークフローが実行され、トリアージエージェントが2つの専門エージェント間を正しくルーティングするか確認しましょう。 ```python from agents import Runner @@ -89,9 +89,9 @@ async def main(): print(result.final_output) ``` -## ガードレールの追加 +## ガードレールを追加する -入力または出力に対して実行するカスタムのガードレールを定義できます。 +入力または出力に対してカスタムガードレールを定義できます。 ```python from agents import GuardrailFunctionOutput, Agent, Runner @@ -116,9 +116,9 @@ async def homework_guardrail(ctx, agent, input_data): ) ``` -## すべてを統合する +## すべてをまとめる -ハンドオフと入力ガードレールを使用して、ワークフロー全体を統合して実行しましょう。 +すべてをまとめて、ハンドオフと入力ガードレールを使用して全体のワークフローを実行しましょう。 ```python from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner @@ -147,6 +147,7 @@ history_tutor_agent = Agent( instructions="You provide assistance with historical queries. Explain important events and context clearly.", ) + async def homework_guardrail(ctx, agent, input_data): result = await Runner.run(guardrail_agent, input_data, context=ctx.context) final_output = result.final_output_as(HomeworkOutput) @@ -175,14 +176,14 @@ if __name__ == "__main__": asyncio.run(main()) ``` -## トレースの確認 +## トレースを表示する -エージェントの実行中に何が起きたかを確認するには、[OpenAI ダッシュボードのトレースビューア](https://platform.openai.com/traces) にアクセスして、エージェント実行のトレースを確認してください。 +エージェントの実行中に何が起こったかを確認するには、[OpenAI ダッシュボードのトレースビューア](https://platform.openai.com/traces)に移動して、エージェント実行のトレースを表示してください。 ## 次のステップ -より複雑なエージェントフローの構築方法を学びましょう。 +より複雑なエージェントフローの構築方法を学びましょう: -- [エージェント](agents.md) の設定方法について学ぶ。 -- [エージェントの実行方法](running_agents.md) について学ぶ。 -- [ツール](tools.md)、[ガードレール](guardrails.md)、[モデル](models.md) について学ぶ。 \ No newline at end of file +- [エージェント](agents.md)の設定方法を学ぶ。 +- [エージェントの実行](running_agents.md)について学ぶ。 +- [ツール](tools.md)、[ガードレール](guardrails.md)、[モデル](models.md)について学ぶ。 \ No newline at end of file diff --git a/docs/ja/results.md b/docs/ja/results.md index 13ff7cef..765bba5c 100644 --- a/docs/ja/results.md +++ b/docs/ja/results.md @@ -1,52 +1,52 @@ -# 実行結果 +# 結果 -`Runner.run` メソッドを呼び出すと、以下のいずれかが返されます。 +`Runner.run` メソッドを呼び出すと、次のいずれかが得られます: -- `run` または `run_sync` を呼び出した場合は [`RunResult`][agents.result.RunResult] -- `run_streamed` を呼び出した場合は [`RunResultStreaming`][agents.result.RunResultStreaming] +- `run` または `run_sync` を呼び出すと [`RunResult`][agents.result.RunResult] +- `run_streamed` を呼び出すと [`RunResultStreaming`][agents.result.RunResultStreaming] -これらはいずれも [`RunResultBase`][agents.result.RunResultBase] を継承しており、ほとんどの有用な情報はここに含まれています。 +これらはどちらも [`RunResultBase`][agents.result.RunResultBase] を継承しており、ほとんどの有用な情報はここにあります。 ## 最終出力 -[`final_output`][agents.result.RunResultBase.final_output] プロパティには、最後に実行されたエージェントの最終出力が格納されています。これは以下のいずれかです。 +[`final_output`][agents.result.RunResultBase.final_output] プロパティには、最後に実行されたエージェントの最終出力が含まれています。これは次のいずれかです: -- 最後のエージェントに `output_type` が定義されていない場合は `str` -- エージェントに `output_type` が定義されている場合は、その型(`last_agent.output_type`)のオブジェクト +- `output_type` が定義されていない場合は `str` +- エージェントに出力タイプが定義されている場合は `last_agent.output_type` のオブジェクト !!! note - `final_output` は型としては `Any` です。これはハンドオフが発生する可能性があるため、静的に型付けできないためです。ハンドオフが発生すると、どのエージェントでも最後のエージェントになり得るため、可能な出力型の集合を静的に特定できません。 + `final_output` は `Any` 型です。ハンドオフのため、静的に型を指定することはできません。ハンドオフが発生すると、どのエージェントが最後になるか分からないため、可能な出力タイプのセットを静的に知ることはできません。 ## 次のターンの入力 -[`result.to_input_list()`][agents.result.RunResultBase.to_input_list] を使用すると、実行結果を入力リストに変換できます。これは、元々提供した入力とエージェントの実行中に生成された項目を連結したものです。これにより、あるエージェントの実行結果を別の実行に渡したり、ループ内で実行して毎回新しいユーザー入力を追加したりすることが容易になります。 +[`result.to_input_list()`][agents.result.RunResultBase.to_input_list] を使用して、結果を入力リストに変換できます。これにより、提供した元の入力をエージェント実行中に生成されたアイテムに連結します。これにより、1つのエージェント実行の出力を別の実行に渡したり、ループで実行して毎回新しいユーザー入力を追加したりするのが便利になります。 ## 最後のエージェント -[`last_agent`][agents.result.RunResultBase.last_agent] プロパティには、最後に実行されたエージェントが格納されています。アプリケーションによっては、次回ユーザーが何かを入力する際に役立つことがあります。例えば、最前線のトリアージエージェントが言語特化型エージェントにハンドオフする場合、最後のエージェントを保存しておき、次回ユーザーがエージェントにメッセージを送る際に再利用できます。 +[`last_agent`][agents.result.RunResultBase.last_agent] プロパティには、最後に実行されたエージェントが含まれています。アプリケーションによっては、次回ユーザーが何かを入力する際に役立つことがよくあります。たとえば、フロントラインのトリアージエージェントが言語特定のエージェントにハンドオフする場合、最後のエージェントを保存し、次回ユーザーがエージェントにメッセージを送信する際に再利用できます。 -## 新規項目 +## 新しいアイテム -[`new_items`][agents.result.RunResultBase.new_items] プロパティには、実行中に生成された新しい項目が格納されています。これらの項目は [`RunItem`][agents.items.RunItem] です。RunItem は LLM によって生成された raw 項目をラップしています。 +[`new_items`][agents.result.RunResultBase.new_items] プロパティには、実行中に生成された新しいアイテムが含まれています。アイテムは [`RunItem`][agents.items.RunItem] です。実行アイテムは LLM によって生成された raw アイテムをラップします。 -- [`MessageOutputItem`][agents.items.MessageOutputItem] は LLM からのメッセージを示します。raw 項目は生成されたメッセージです。 -- [`HandoffCallItem`][agents.items.HandoffCallItem] は LLM がハンドオフツールを呼び出したことを示します。raw 項目は LLM からのツール呼び出し項目です。 -- [`HandoffOutputItem`][agents.items.HandoffOutputItem] はハンドオフが発生したことを示します。raw 項目はハンドオフツール呼び出しに対するツールの応答です。また、この項目からソース/ターゲットエージェントにアクセスできます。 -- [`ToolCallItem`][agents.items.ToolCallItem] は LLM がツールを呼び出したことを示します。 -- [`ToolCallOutputItem`][agents.items.ToolCallOutputItem] はツールが呼び出されたことを示します。raw 項目はツールの応答です。また、この項目からツールの出力にアクセスできます。 -- [`ReasoningItem`][agents.items.ReasoningItem] は LLM による推論項目を示します。raw 項目は生成された推論内容です。 +- [`MessageOutputItem`][agents.items.MessageOutputItem] は LLM からのメッセージを示します。raw アイテムは生成されたメッセージです。 +- [`HandoffCallItem`][agents.items.HandoffCallItem] は LLM がハンドオフツールを呼び出したことを示します。raw アイテムは LLM からのツール呼び出しアイテムです。 +- [`HandoffOutputItem`][agents.items.HandoffOutputItem] はハンドオフが発生したことを示します。raw アイテムはハンドオフツール呼び出しへのツール応答です。アイテムからソース/ターゲットエージェントにもアクセスできます。 +- [`ToolCallItem`][agents.items.ToolCallItem] は LLM がツールを呼び出したことを示します。 +- [`ToolCallOutputItem`][agents.items.ToolCallOutputItem] はツールが呼び出されたことを示します。raw アイテムはツール応答です。アイテムからツール出力にもアクセスできます。 +- [`ReasoningItem`][agents.items.ReasoningItem] は LLM からの推論アイテムを示します。raw アイテムは生成された推論です。 ## その他の情報 -### ガードレールの実行結果 +### ガードレール結果 -[`input_guardrail_results`][agents.result.RunResultBase.input_guardrail_results] および [`output_guardrail_results`][agents.result.RunResultBase.output_guardrail_results] プロパティには、ガードレールの実行結果が格納されています(存在する場合)。ガードレールの実行結果にはログや保存したい有用な情報が含まれることがあるため、これらを利用可能にしています。 +[`input_guardrail_results`][agents.result.RunResultBase.input_guardrail_results] と [`output_guardrail_results`][agents.result.RunResultBase.output_guardrail_results] プロパティには、ガードレールの結果が含まれています。ガードレール結果には、ログや保存に役立つ情報が含まれることがあるため、これらを利用可能にしています。 -### raw レスポンス +### Raw 応答 -[`raw_responses`][agents.result.RunResultBase.raw_responses] プロパティには、LLM によって生成された [`ModelResponse`][agents.items.ModelResponse] が格納されています。 +[`raw_responses`][agents.result.RunResultBase.raw_responses] プロパティには、LLM によって生成された [`ModelResponse`][agents.items.ModelResponse] が含まれています。 ### 元の入力 -[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が格納されています。ほとんどの場合、これは必要ありませんが、必要に応じて利用可能です。 \ No newline at end of file +[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が含まれています。ほとんどの場合、これを必要としませんが、必要な場合に備えて利用可能です。 \ No newline at end of file diff --git a/docs/ja/running_agents.md b/docs/ja/running_agents.md index b02ee393..c2071c65 100644 --- a/docs/ja/running_agents.md +++ b/docs/ja/running_agents.md @@ -1,10 +1,10 @@ # エージェントの実行 -エージェントは [`Runner`][agents.run.Runner] クラスを通じて実行できます。以下の 3 つの方法があります。 +エージェントは [`Runner`][agents.run.Runner] クラスを通じて実行できます。3つのオプションがあります: -1. [`Runner.run()`][agents.run.Runner.run]:非同期で実行され、[`RunResult`][agents.result.RunResult] を返します。 -2. [`Runner.run_sync()`][agents.run.Runner.run_sync]:同期メソッドで、内部的には `.run()` を呼び出します。 -3. [`Runner.run_streamed()`][agents.run.Runner.run_streamed]:非同期で実行され、[`RunResultStreaming`][agents.result.RunResultStreaming] を返します。LLM をストリーミングモードで呼び出し、受信したイベントを順次ストリームします。 +1. 非同期で実行し、[`RunResult`][agents.result.RunResult] を返す [`Runner.run()`][agents.run.Runner.run]。 +2. 同期メソッドで、内部で `.run()` を実行する [`Runner.run_sync()`][agents.run.Runner.run_sync]。 +3. 非同期で実行し、[`RunResultStreaming`][agents.result.RunResultStreaming] を返す [`Runner.run_streamed()`][agents.run.Runner.run_streamed]。ストリーミングモードで LLM を呼び出し、受信したイベントをストリームします。 ```python from agents import Agent, Runner @@ -19,53 +19,53 @@ async def main(): # Infinite loop's dance. ``` -詳細は [results ガイド](results.md) を参照してください。 +詳細は[結果ガイド](results.md)をご覧ください。 -## エージェントの実行ループ +## エージェントループ -`Runner` の run メソッドを使用する際、開始エージェントと入力を渡します。入力は文字列(ユーザーメッセージとして扱われる)または OpenAI Responses API の項目リストのいずれかです。 +`Runner` の実行メソッドを使用する際、開始エージェントと入力を渡します。入力は文字列(ユーザーメッセージと見なされる)または OpenAI Responses API のアイテムリストのいずれかです。 -Runner は以下のループを実行します。 +ランナーは次のループを実行します: -1. 現在のエージェントと入力を用いて LLM を呼び出します。 +1. 現在のエージェントと入力で LLM を呼び出します。 2. LLM が出力を生成します。 - 1. LLM が `final_output` を返した場合、ループを終了し結果を返します。 - 2. LLM がハンドオフを行った場合、現在のエージェントと入力を更新し、再度ループを実行します。 - 3. LLM がツール呼び出しを生成した場合、それらのツール呼び出しを実行し、結果を追加して再度ループを実行します。 -3. 指定された `max_turns` を超えた場合、[`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] 例外を発生させます。 + 1. LLM が `final_output` を返すと、ループは終了し、結果を返します。 + 2. LLM がハンドオフを行う場合、現在のエージェントと入力を更新し、ループを再実行します。 + 3. LLM がツール呼び出しを生成する場合、それらを実行し、結果を追加し、ループを再実行します。 +3. 渡された `max_turns` を超えた場合、[`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] 例外を発生させます。 !!! note - LLM の出力が「最終出力(final output)」とみなされる条件は、望ましいタイプのテキスト出力を生成し、かつツール呼び出しがない場合です。 + LLM の出力が「最終出力」と見なされるかどうかのルールは、望ましいタイプのテキスト出力を生成し、ツール呼び出しがないことです。 ## ストリーミング -ストリーミングを使用すると、LLM の実行中にストリーミングイベントを受け取ることができます。ストリームが完了すると、[`RunResultStreaming`][agents.result.RunResultStreaming] に実行に関する完全な情報(生成されたすべての新しい出力を含む)が格納されます。ストリーミングイベントを取得するには `.stream_events()` を呼び出します。詳細は [streaming ガイド](streaming.md) を参照してください。 +ストリーミングを使用すると、LLM が実行される際にストリーミングイベントを受け取ることができます。ストリームが完了すると、[`RunResultStreaming`][agents.result.RunResultStreaming] は実行に関する完全な情報を含み、生成されたすべての新しい出力を含みます。ストリーミングイベントには `.stream_events()` を呼び出せます。[ストリーミングガイド](streaming.md)で詳細を確認してください。 -## 実行設定(Run config) +## 実行設定 -`run_config` パラメータを使用すると、エージェント実行時のグローバル設定を構成できます。 +`run_config` パラメーターを使用して、エージェント実行のグローバル設定を構成できます: -- [`model`][agents.run.RunConfig.model]:各エージェントの `model` 設定に関係なく、グローバルな LLM モデルを指定します。 -- [`model_provider`][agents.run.RunConfig.model_provider]:モデル名を検索するためのモデルプロバイダーを指定します(デフォルトは OpenAI)。 -- [`model_settings`][agents.run.RunConfig.model_settings]:エージェント固有の設定を上書きします。例えば、グローバルな `temperature` や `top_p` を設定できます。 -- [`input_guardrails`][agents.run.RunConfig.input_guardrails]、[`output_guardrails`][agents.run.RunConfig.output_guardrails]:すべての実行に適用する入力または出力のガードレールのリストです。 -- [`handoff_input_filter`][agents.run.RunConfig.handoff_input_filter]:ハンドオフに既存の入力フィルターがない場合に適用されるグローバルな入力フィルターです。入力フィルターを使用すると、新しいエージェントに送信される入力を編集できます。詳細は [`Handoff.input_filter`][agents.handoffs.Handoff.input_filter] のドキュメントを参照してください。 -- [`tracing_disabled`][agents.run.RunConfig.tracing_disabled]:実行全体の [トレーシング](tracing.md) を無効にします。 -- [`trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data]:トレースに LLM やツール呼び出しの入出力など、機密性の高いデータを含めるかどうかを設定します。 -- [`workflow_name`][agents.run.RunConfig.workflow_name]、[`trace_id`][agents.run.RunConfig.trace_id]、[`group_id`][agents.run.RunConfig.group_id]:トレーシングのワークフロー名、トレース ID、トレースグループ ID を設定します。少なくとも `workflow_name` を設定することを推奨します。グループ ID はオプションで、複数の実行間でトレースを関連付けることができます。 -- [`trace_metadata`][agents.run.RunConfig.trace_metadata]:すべてのトレースに含めるメタデータです。 +- [`model`][agents.run.RunConfig.model]: 各エージェントの `model` に関係なく、使用するグローバル LLM モデルを設定できます。 +- [`model_provider`][agents.run.RunConfig.model_provider]: モデル名を検索するためのモデルプロバイダーで、デフォルトは OpenAI です。 +- [`model_settings`][agents.run.RunConfig.model_settings]: エージェント固有の設定を上書きします。たとえば、グローバルな `temperature` や `top_p` を設定できます。 +- [`input_guardrails`][agents.run.RunConfig.input_guardrails], [`output_guardrails`][agents.run.RunConfig.output_guardrails]: すべての実行に含める入力または出力ガードレールのリスト。 +- [`handoff_input_filter`][agents.run.RunConfig.handoff_input_filter]: すべてのハンドオフに適用するグローバル入力フィルター。ハンドオフに既にフィルターがない場合に適用されます。入力フィルターを使用して、新しいエージェントに送信される入力を編集できます。詳細は [`Handoff.input_filter`][agents.handoffs.Handoff.input_filter] のドキュメントを参照してください。 +- [`tracing_disabled`][agents.run.RunConfig.tracing_disabled]: 実行全体の[トレーシング](tracing.md)を無効にできます。 +- [`trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data]: トレースに LLM やツール呼び出しの入出力など、潜在的に機密性のあるデータを含めるかどうかを設定します。 +- [`workflow_name`][agents.run.RunConfig.workflow_name], [`trace_id`][agents.run.RunConfig.trace_id], [`group_id`][agents.run.RunConfig.group_id]: 実行のトレーシングワークフロー名、トレース ID、トレースグループ ID を設定します。少なくとも `workflow_name` を設定することをお勧めします。グループ ID は、複数の実行にわたってトレースをリンクするためのオプションフィールドです。 +- [`trace_metadata`][agents.run.RunConfig.trace_metadata]: すべてのトレースに含めるメタデータ。 -## 会話/チャットスレッド +## 会話/チャットスレッド -いずれかの run メソッドを呼び出すと、1 つ以上のエージェントが実行され(したがって 1 つ以上の LLM 呼び出しが発生)、チャット会話における単一の論理的ターンを表します。例えば: +いずれかの実行メソッドを呼び出すと、1つ以上のエージェントが実行される可能性があります(したがって、1つ以上の LLM 呼び出しが行われます)が、チャット会話の単一の論理ターンを表します。例えば: -1. ユーザーのターン:ユーザーがテキストを入力 -2. Runner の実行:最初のエージェントが LLM を呼び出し、ツールを実行し、2 番目のエージェントにハンドオフし、2 番目のエージェントがさらにツールを実行して出力を生成 +1. ユーザーターン:ユーザーがテキストを入力 +2. ランナー実行:最初のエージェントが LLM を呼び出し、ツールを実行し、2番目のエージェントにハンドオフし、2番目のエージェントがさらにツールを実行し、出力を生成します。 -エージェントの実行終了時に、ユーザーに何を表示するかを選択できます。例えば、エージェントが生成したすべての新しい項目を表示するか、最終出力のみを表示するかを選択できます。いずれの場合も、ユーザーが追加の質問をした場合、再度 run メソッドを呼び出します。 +エージェント実行の終了時に、ユーザーに何を表示するかを選択できます。例えば、エージェントによって生成されたすべての新しいアイテムをユーザーに表示するか、最終出力のみを表示するかです。いずれにせよ、ユーザーがフォローアップの質問をする可能性があり、その場合は再度実行メソッドを呼び出すことができます。 -次のターンの入力を取得するには、基本クラスの [`RunResultBase.to_input_list()`][agents.result.RunResultBase.to_input_list] メソッドを使用できます。 +次のターンの入力を取得するには、基本の [`RunResultBase.to_input_list()`][agents.result.RunResultBase.to_input_list] メソッドを使用できます。 ```python async def main(): @@ -86,10 +86,10 @@ async def main(): ## 例外 -SDK は特定の状況で例外を発生させます。完全なリストは [`agents.exceptions`][] にあります。概要は以下の通りです。 +SDK は特定のケースで例外を発生させます。完全なリストは [`agents.exceptions`][] にあります。概要は以下の通りです: -- [`AgentsException`][agents.exceptions.AgentsException]:SDK 内で発生するすべての例外の基底クラスです。 -- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded]:実行が指定された `max_turns` を超えた場合に発生します。 -- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]:モデルが不正な出力(不正な JSON や存在しないツールの使用など)を生成した場合に発生します。 -- [`UserError`][agents.exceptions.UserError]:SDK を使用するコードに誤りがある場合に発生します。 -- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered]、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]:[ガードレール](guardrails.md) がトリガーされた場合に発生します。 \ No newline at end of file +- [`AgentsException`][agents.exceptions.AgentsException] は、SDK で発生するすべての例外の基本クラスです。 +- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] は、実行が渡された `max_turns` を超えた場合に発生します。 +- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError] は、モデルが無効な出力を生成した場合に発生します。例:不正な形式の JSON や存在しないツールの使用。 +- [`UserError`][agents.exceptions.UserError] は、SDK を使用する際にエラーを犯した場合に発生します。 +- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered], [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] は、[ガードレール](guardrails.md)が作動した場合に発生します。 \ No newline at end of file diff --git a/docs/ja/streaming.md b/docs/ja/streaming.md index 60719679..2f7a8dd2 100644 --- a/docs/ja/streaming.md +++ b/docs/ja/streaming.md @@ -1,14 +1,14 @@ # ストリーミング -ストリーミングを使用すると、エージェントの実行中にその進行状況の更新を購読できます。これは、エンドユーザーに進捗状況や部分的な応答を表示する際に役立ちます。 +ストリーミングを使用すると、エージェントの実行が進行する際の更新を購読できます。これは、エンドユーザーに進捗状況の更新や部分的な応答を表示するのに役立ちます。 -ストリーミングを行うには、[`Runner.run_streamed()`][agents.run.Runner.run_streamed] を呼び出します。これにより [`RunResultStreaming`][agents.result.RunResultStreaming] が返されます。`result.stream_events()` を呼び出すと、以下で説明する [`StreamEvent`][agents.stream_events.StreamEvent] オブジェクトの非同期ストリームが得られます。 +ストリーミングを行うには、[`Runner.run_streamed()`][agents.run.Runner.run_streamed] を呼び出します。これにより、[`RunResultStreaming`][agents.result.RunResultStreaming] が得られます。`result.stream_events()` を呼び出すと、以下で説明する [`StreamEvent`][agents.stream_events.StreamEvent] オブジェクトの非同期ストリームが得られます。 -## raw response events +## Raw response events -[`RawResponsesStreamEvent`][agents.stream_events.RawResponsesStreamEvent] は、LLM から直接渡される raw イベントです。これらは OpenAI Responses API の形式であり、各イベントはタイプ(`response.created` や `response.output_text.delta` など)とデータを持ちます。これらのイベントは、生成された応答メッセージを即座にユーザーにストリーミングしたい場合に役立ちます。 +[`RawResponsesStreamEvent`][agents.stream_events.RawResponsesStreamEvent] は、LLM から直接渡される raw イベントです。これらは OpenAI Responses API フォーマットであり、各イベントにはタイプ(`response.created`、`response.output_text.delta` など)とデータがあります。これらのイベントは、生成され次第、ユーザーに応答メッセージをストリーミングしたい場合に便利です。 -例えば、以下のコードは LLM が生成したテキストをトークンごとに出力します。 +例えば、これは LLM によってトークンごとに生成されたテキストを出力します。 ```python import asyncio @@ -31,11 +31,11 @@ if __name__ == "__main__": asyncio.run(main()) ``` -## Run item events と agent events +## 実行アイテムイベントとエージェントイベント -[`RunItemStreamEvent`][agents.stream_events.RunItemStreamEvent] は、より高レベルのイベントです。これらはアイテムが完全に生成された際に通知されます。これにより、トークン単位ではなく、「メッセージが生成された」「ツールが実行された」などのレベルで進捗状況をユーザーに通知できます。同様に、[`AgentUpdatedStreamEvent`][agents.stream_events.AgentUpdatedStreamEvent] は、現在のエージェントが変更された際(例えばハンドオフの結果として)に更新を通知します。 +[`RunItemStreamEvent`][agents.stream_events.RunItemStreamEvent] は、より高レベルのイベントです。アイテムが完全に生成されたときに通知します。これにより、「メッセージが生成された」、「ツールが実行された」などのレベルで進捗状況を更新することができます。同様に、[`AgentUpdatedStreamEvent`][agents.stream_events.AgentUpdatedStreamEvent] は、現在のエージェントが変更されたとき(例えば、ハンドオフの結果として)に更新を提供します。 -例えば、以下のコードは raw イベントを無視し、更新情報のみをユーザーにストリーミングします。 +例えば、これは raw イベントを無視し、ユーザーに更新をストリーミングします。 ```python import asyncio @@ -61,14 +61,14 @@ async def main(): print("=== Run starting ===") async for event in result.stream_events(): - # raw response イベントのデルタは無視します + # We'll ignore the raw responses event deltas if event.type == "raw_response_event": continue - # エージェントが更新された場合、それを表示します + # When the agent updates, print that elif event.type == "agent_updated_stream_event": print(f"Agent updated: {event.new_agent.name}") continue - # アイテムが生成された場合、それを表示します + # When items are generated, print them elif event.type == "run_item_stream_event": if event.item.type == "tool_call_item": print("-- Tool was called") @@ -77,7 +77,7 @@ async def main(): elif event.item.type == "message_output_item": print(f"-- Message output:\n {ItemHelpers.text_message_output(event.item)}") else: - pass # 他のイベントタイプは無視します + pass # Ignore other event types print("=== Run complete ===") diff --git a/docs/ja/tools.md b/docs/ja/tools.md index c100885b..cd747663 100644 --- a/docs/ja/tools.md +++ b/docs/ja/tools.md @@ -1,18 +1,18 @@ # ツール -ツールを使用すると、エージェントがデータ取得、コード実行、外部 API 呼び出し、さらにはコンピュータ操作などのアクションを実行できます。Agents SDK には以下の 3 種類のツールがあります。 +ツールはエージェントがアクションを実行するためのものです。データの取得、コードの実行、外部 API の呼び出し、さらにはコンピュータの使用などが含まれます。Agent SDK には3つのクラスのツールがあります。 -- ホスト型ツール:AI モデルと共に LLM サーバー上で実行されます。OpenAI は、検索、ウェブ検索、コンピュータ操作をホスト型ツール(OpenAI がホストするツール)として提供しています。 -- 関数呼び出し:任意の Python 関数をツールとして使用できます。 -- エージェントをツールとして使用:エージェントをツールとして使用でき、エージェント間でハンドオフを行わずに他のエージェントを呼び出せます。 +- ホストされたツール: これらは LLM サーバー上で AI モデルと一緒に実行されます。OpenAI は、リトリーバル、Web 検索、コンピュータ操作をホストされたツールとして提供しています。 +- 関数呼び出し: 任意の Python 関数をツールとして使用できます。 +- エージェントをツールとして使用: エージェントをツールとして使用し、エージェントが他のエージェントをハンドオフせずに呼び出すことができます。 -## ホスト型ツール +## ホストされたツール -[`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] を使用する場合、OpenAI はいくつかの組み込みツールを提供しています。 +OpenAI は、[`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] を使用する際にいくつかの組み込みツールを提供しています。 -- [`WebSearchTool`][agents.tool.WebSearchTool] は、エージェントがウェブ検索を行うためのツールです。 -- [`FileSearchTool`][agents.tool.FileSearchTool] は、OpenAI のベクトルストアから情報を取得するためのツールです。 -- [`ComputerTool`][agents.tool.ComputerTool] は、コンピュータ操作タスクを自動化するためのツールです。 +- [`WebSearchTool`][agents.tool.WebSearchTool] はエージェントが Web 検索を行うことを可能にします。 +- [`FileSearchTool`][agents.tool.FileSearchTool] は OpenAI ベクトルストアから情報を取得することを可能にします。 +- [`ComputerTool`][agents.tool.ComputerTool] はコンピュータ操作タスクを自動化することを可能にします。 ```python from agents import Agent, FileSearchTool, Runner, WebSearchTool @@ -35,12 +35,12 @@ async def main(): ## 関数ツール -任意の Python 関数をツールとして使用できます。Agents SDK は自動的にツールを設定します。 +任意の Python 関数をツールとして使用できます。Agents SDK はツールを自動的にセットアップします。 -- ツール名は Python 関数名が使用されます(または任意の名前を指定可能)。 -- ツールの説明は関数の docstring から取得されます(または任意の説明を指定可能)。 -- 関数の入力スキーマは関数の引数から自動的に作成されます。 -- 各入力の説明は、無効化されていない限り、関数の docstring から取得されます。 +- ツールの名前は Python 関数の名前になります(または名前を指定できます) +- ツールの説明は関数の docstring から取得されます(または説明を指定できます) +- 関数入力のスキーマは関数の引数から自動的に作成されます +- 各入力の説明は、無効にしない限り、関数の docstring から取得されます Python の `inspect` モジュールを使用して関数シグネチャを抽出し、[`griffe`](https://mkdocstrings.github.io/griffe/) を使用して docstring を解析し、`pydantic` を使用してスキーマを作成します。 @@ -94,12 +94,12 @@ for tool in agent.tools: ``` -1. 任意の Python 型を関数の引数として使用可能で、関数は同期または非同期のどちらでも構いません。 -2. docstring が存在する場合、ツールおよび引数の説明として使用されます。 -3. 関数はオプションで `context` を引数として受け取れます(最初の引数である必要があります)。また、ツール名や説明、docstring のスタイルなどを上書き設定できます。 -4. デコレータを付けた関数をツールのリストに渡すことができます。 +1. 任意の Python 型を関数の引数として使用でき、関数は同期または非同期であることができます。 +2. Docstring が存在する場合、説明や引数の説明を取得するために使用されます。 +3. 関数はオプションで `context` を取ることができ(最初の引数である必要があります)、ツールの名前、説明、使用する docstring スタイルなどのオーバーライドを設定できます。 +4. デコレートされた関数をツールのリストに渡すことができます。 -??? note "クリックして出力を表示" +??? note "出力を表示するには展開してください" ``` fetch_weather @@ -168,14 +168,15 @@ for tool in agent.tools: "type": "object" } ``` + ### カスタム関数ツール -Python 関数をツールとして使用したくない場合もあります。その場合は、直接 [`FunctionTool`][agents.tool.FunctionTool] を作成できます。作成時には以下を指定する必要があります: +時には、Python 関数をツールとして使用したくない場合もあります。その場合、直接 [`FunctionTool`][agents.tool.FunctionTool] を作成できます。以下を提供する必要があります。 -- `name` -- `description` -- 引数の JSON スキーマを示す `params_json_schema` -- 非同期関数である `on_invoke_tool`(コンテキストと引数を JSON 文字列として受け取り、ツールの出力を文字列として返す必要があります) +- `name` +- `description` +- `params_json_schema`(引数の JSON スキーマ) +- `on_invoke_tool`(コンテキストと引数を JSON 文字列として受け取り、ツールの出力を文字列として返す非同期関数) ```python from typing import Any @@ -208,18 +209,18 @@ tool = FunctionTool( ) ``` -### 引数とドックストリングの自動解析 +### 引数と docstring の自動解析 -前述の通り、関数のシグネチャを自動的に解析してツールのスキーマを抽出し、ドックストリングを解析してツールおよび各引数の説明を抽出します。これに関する注意点は以下の通りです: +前述のように、ツールのスキーマを抽出するために関数シグネチャを自動的に解析し、ツールおよび個々の引数の説明を抽出するために docstring を解析します。以下の点に注意してください。 -1. シグネチャの解析は `inspect` モジュールを使用して行われます。型アノテーションを用いて引数の型を把握し、動的に Pydantic モデルを構築して全体のスキーマを表現します。Python の基本型(basic components)、Pydantic モデル、TypedDict など、ほとんどの型をサポートしています。 -2. ドックストリングの解析には `griffe` を使用します。サポートされるドックストリング形式は `google`、`sphinx`、`numpy` です。ドックストリング形式は自動検出を試みますが、これはベストエフォートであり、`function_tool` 呼び出し時に明示的に指定することも可能です。また、`use_docstring_info` を `False` に設定することでドックストリングの解析を無効化できます。 +1. シグネチャの解析は `inspect` モジュールを通じて行われます。引数の型を理解するために型注釈を使用し、全体のスキーマを表す Pydantic モデルを動的に構築します。Python の基本コンポーネント、Pydantic モデル、TypedDict など、ほとんどの型をサポートしています。 +2. `griffe` を使用して docstring を解析します。サポートされている docstring フォーマットは `google`、`sphinx`、`numpy` です。docstring フォーマットを自動的に検出しようとしますが、これはベストエフォートであり、`function_tool` を呼び出す際に明示的に設定できます。`use_docstring_info` を `False` に設定することで docstring 解析を無効にすることもできます。 スキーマ抽出のコードは [`agents.function_schema`][] にあります。 -## ツールとしてのエージェント +## エージェントをツールとして使用 -一部のワークフローでは、制御をハンドオフするのではなく、中央のエージェントが専門化されたエージェントのネットワークを調整することが望ましい場合があります。このような場合、エージェントをツールとしてモデル化できます。 +一部のワークフローでは、中央のエージェントが専門エージェントのネットワークをオーケストレーションすることを望むかもしれません。これを行うには、エージェントをツールとしてモデル化します。 ```python from agents import Agent, Runner @@ -258,12 +259,12 @@ async def main(): print(result.final_output) ``` -## 関数ツールにおけるエラー処理 +## 関数ツールでのエラー処理 -`@function_tool` を使用して関数ツールを作成する際、`failure_error_function` を渡すことができます。これはツール呼び出しがクラッシュした場合に、LLM にエラー応答を提供する関数です。 +`@function_tool` を使用して関数ツールを作成する際、`failure_error_function` を渡すことができます。これは、ツール呼び出しがクラッシュした場合に LLM にエラーレスポンスを提供する関数です。 -- デフォルト(何も渡さない場合)では、エラーが発生したことを LLM に通知する `default_tool_error_function` が実行されます。 -- 独自のエラー関数を渡した場合は、それが代わりに実行され、その応答が LLM に送信されます。 -- 明示的に `None` を渡した場合、ツール呼び出しのエラーは再度発生(re-raise)し、自分で処理する必要があります。この場合、モデルが無効な JSON を生成した場合は `ModelBehaviorError`、コードがクラッシュした場合は `UserError` などが発生します。 +- デフォルトでは(何も渡さない場合)、`default_tool_error_function` が実行され、LLM にエラーが発生したことを伝えます。 +- 独自のエラー関数を渡した場合、それが実行され、LLM にレスポンスが送信されます。 +- 明示的に `None` を渡した場合、ツール呼び出しエラーは再度発生し、処理する必要があります。モデルが無効な JSON を生成した場合は `ModelBehaviorError`、コードがクラッシュした場合は `UserError` などが考えられます。 -手動で `FunctionTool` オブジェクトを作成する場合は、`on_invoke_tool` 関数内でエラーを処理する必要があります。 \ No newline at end of file +`FunctionTool` オブジェクトを手動で作成する場合、`on_invoke_tool` 関数内でエラーを処理する必要があります。 \ No newline at end of file diff --git a/docs/ja/tracing.md b/docs/ja/tracing.md index 2e0e80da..0f573eb8 100644 --- a/docs/ja/tracing.md +++ b/docs/ja/tracing.md @@ -1,51 +1,51 @@ # トレーシング -Agents SDK には組み込みのトレーシング機能があり、エージェントの実行中に発生するイベント(LLM の生成、ツール呼び出し、ハンドオフ、ガードレール、さらにはカスタムイベントまで)を包括的に記録します。[Traces ダッシュボード](https://platform.openai.com/traces) を使用して、開発中および本番環境でワークフローのデバッグ、可視化、監視が可能です。 +Agents SDK には組み込みのトレーシング機能があり、エージェント実行中のイベント(LLM の生成、ツール呼び出し、ハンドオフ、ガードレール、カスタムイベントなど)の包括的な記録を収集します。[Traces ダッシュボード](https://platform.openai.com/traces)を使用して、開発中および本番環境でワークフローをデバッグ、可視化、監視できます。 !!!note - トレーシングはデフォルトで有効になっています。トレーシングを無効にする方法は 2 つあります。 + トレーシングはデフォルトで有効です。トレーシングを無効にする方法は2つあります: - 1. 環境変数 `OPENAI_AGENTS_DISABLE_TRACING=1` を設定して、グローバルにトレーシングを無効化できます。 - 2. 個別の実行でトレーシングを無効化するには、[`agents.run.RunConfig.tracing_disabled`][] を `True` に設定します。 + 1. 環境変数 `OPENAI_AGENTS_DISABLE_TRACING=1` を設定して、グローバルにトレーシングを無効にすることができます。 + 2. [`agents.run.RunConfig.tracing_disabled`][] を `True` に設定して、単一の実行でトレーシングを無効にすることができます。 -***OpenAI の API を使用してゼロデータ保持(ZDR)ポリシーで運用している組織の場合、トレーシングは利用できません。*** +***OpenAI の API を使用している Zero Data Retention (ZDR) ポリシーの下で運営されている組織では、トレーシングは利用できません。*** ## トレースとスパン -- **トレース(Traces)** は、ワークフローの単一のエンドツーエンド操作を表します。トレースは複数のスパン(Spans)で構成されます。トレースには以下のプロパティがあります。 - - `workflow_name`:論理的なワークフローまたはアプリ名。例:「Code generation」や「Customer service」。 - - `trace_id`:トレースの一意な ID。指定しない場合は自動生成されます。形式は `trace_<32_alphanumeric>` である必要があります。 - - `group_id`:同じ会話からの複数のトレースを関連付けるためのオプションのグループ ID。例えば、チャットスレッド ID を使用できます。 - - `disabled`:True の場合、このトレースは記録されません。 - - `metadata`:トレースに関するオプションのメタデータ。 -- **スパン(Spans)** は、開始時刻と終了時刻を持つ操作を表します。スパンには以下が含まれます。 - - `started_at` と `ended_at` のタイムスタンプ。 - - 所属するトレースを示す `trace_id`。 - - 親スパンを指す `parent_id`(存在する場合)。 - - スパンに関する情報を含む `span_data`。例えば、`AgentSpanData` はエージェントに関する情報を、`GenerationSpanData` は LLM の生成に関する情報を含みます。 +- **トレース** は「ワークフロー」の単一のエンドツーエンドの操作を表します。スパンで構成されています。トレースには以下のプロパティがあります: + - `workflow_name`: 論理的なワークフローまたはアプリです。例: "Code generation" や "Customer service"。 + - `trace_id`: トレースの一意の ID。指定しない場合は自動生成されます。形式は `trace_<32_alphanumeric>` でなければなりません。 + - `group_id`: 同じ会話からの複数のトレースをリンクするためのオプションのグループ ID。例: チャットスレッド ID。 + - `disabled`: True の場合、トレースは記録されません。 + - `metadata`: トレースのオプションのメタデータ。 +- **スパン** は開始時間と終了時間を持つ操作を表します。スパンには以下があります: + - `started_at` と `ended_at` のタイムスタンプ。 + - 所属するトレースを表す `trace_id` + - 親スパンを指す `parent_id`(ある場合) + - スパンに関する情報を含む `span_data`。例: `AgentSpanData` はエージェントに関する情報を含み、`GenerationSpanData` は LLM の生成に関する情報を含みます。 ## デフォルトのトレーシング -デフォルトでは、SDK は以下をトレースします。 +デフォルトで、SDK は以下をトレースします: - `Runner.{run, run_sync, run_streamed}()` 全体が `trace()` でラップされます。 -- エージェントが実行されるたびに `agent_span()` でラップされます。 +- エージェントが実行されるたびに、`agent_span()` でラップされます。 - LLM の生成は `generation_span()` でラップされます。 - 関数ツールの呼び出しはそれぞれ `function_span()` でラップされます。 - ガードレールは `guardrail_span()` でラップされます。 - ハンドオフは `handoff_span()` でラップされます。 - 音声入力(音声からテキスト)は `transcription_span()` でラップされます。 - 音声出力(テキストから音声)は `speech_span()` でラップされます。 -- 関連する音声スパンは `speech_group_span()` の下にまとめられる場合があります。 +- 関連する音声スパンは `speech_group_span()` の下に配置されることがあります。 -デフォルトでは、トレース名は「Agent trace」です。`trace` を使用する場合、この名前を設定できます。また、[`RunConfig`][agents.run.RunConfig] を使用して名前やその他のプロパティを設定できます。 +デフォルトでは、トレースは "Agent trace" と名付けられています。`trace` を使用する場合、この名前を設定することができ、[`RunConfig`][agents.run.RunConfig] で名前やその他のプロパティを設定できます。 -さらに、[カスタムトレースプロセッサ](#custom-tracing-processors) を設定して、トレースを他の宛先に送信することも可能です(置き換えまたは追加の宛先として)。 +さらに、[カスタムトレースプロセッサー](#custom-tracing-processors)を設定して、トレースを他の宛先に送信することもできます(置き換えまたは二次的な宛先として)。 -## 上位レベルのトレース +## 高レベルのトレース -複数回の `run()` 呼び出しを 1 つのトレースにまとめたい場合があります。その場合、コード全体を `trace()` でラップします。 +時には、複数の `run()` 呼び出しを単一のトレースの一部にしたいことがあります。これを行うには、コード全体を `trace()` でラップします。 ```python from agents import Agent, Runner, trace @@ -60,43 +60,57 @@ async def main(): print(f"Rating: {second_result.final_output}") ``` -1. 2 回の `Runner.run` 呼び出しが `with trace()` でラップされているため、個別の実行はそれぞれ別のトレースを作成するのではなく、全体のトレースの一部になります。 +1. `Runner.run` への2つの呼び出しが `with trace()` でラップされているため、個々の実行は2つのトレースを作成するのではなく、全体のトレースの一部になります。 ## トレースの作成 -トレースを作成するには [`trace()`][agents.tracing.trace] 関数を使用します。トレースは開始と終了が必要です。以下の 2 つの方法があります。 +[`trace()`][agents.tracing.trace] 関数を使用してトレースを作成できます。トレースは開始と終了が必要です。以下の2つの方法があります: -1. **推奨**:コンテキストマネージャとして使用します(例:`with trace(...) as my_trace`)。これによりトレースの開始と終了が自動的に行われます。 +1. **推奨**: トレースをコンテキストマネージャーとして使用します。つまり、`with trace(...) as my_trace` とします。これにより、トレースが自動的に適切なタイミングで開始および終了します。 2. 手動で [`trace.start()`][agents.tracing.Trace.start] と [`trace.finish()`][agents.tracing.Trace.finish] を呼び出すこともできます。 -現在のトレースは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。これにより、並行処理でも自動的に動作します。トレースを手動で開始・終了する場合、`start()` と `finish()` に `mark_as_current` と `reset_current` を渡して現在のトレースを更新する必要があります。 +現在のトレースは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。これにより、並行処理でも自動的に機能します。トレースを手動で開始/終了する場合は、`start()`/`finish()` に `mark_as_current` と `reset_current` を渡して現在のトレースを更新する必要があります。 ## スパンの作成 -スパンを作成するには、各種の [`*_span()`][agents.tracing.create] メソッドを使用します。通常、スパンを手動で作成する必要はありません。カスタムスパン情報を追跡するために [`custom_span()`][agents.tracing.custom_span] 関数も利用可能です。 +さまざまな [`*_span()`][agents.tracing.create] メソッドを使用してスパンを作成できます。一般的に、スパンを手動で作成する必要はありません。カスタムスパン情報を追跡するための [`custom_span()`][agents.tracing.custom_span] 関数が利用可能です。 -スパンは自動的に現在のトレースに属し、最も近い現在のスパンの下にネストされます。これは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。 +スパンは自動的に現在のトレースの一部となり、Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡される最も近い現在のスパンの下にネストされます。 -## 機密データ +## センシティブデータ -一部のスパンは機密データを含む可能性があります。 +特定のスパンは潜在的にセンシティブなデータをキャプチャすることがあります。 -`generation_span()` は LLM 生成の入出力を、`function_span()` は関数呼び出しの入出力を保存します。これらには機密データが含まれる可能性があるため、[`RunConfig.trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data] を使用してデータの取得を無効化できます。 +`generation_span()` は LLM 生成の入力/出力を保存し、`function_span()` は関数呼び出しの入力/出力を保存します。これらにはセンシティブなデータが含まれる可能性があるため、[`RunConfig.trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data] を使用してそのデータのキャプチャを無効にすることができます。 -同様に、音声スパンはデフォルトで音声データを base64 エンコードされた PCM データとして含みます。[`VoicePipelineConfig.trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data] を設定して音声データの取得を無効化できます。 +同様に、音声スパンにはデフォルトで入力および出力音声の base64 エンコードされた PCM データが含まれます。この音声データのキャプチャを無効にするには、[`VoicePipelineConfig.trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data] を設定します。 -## カスタムトレーシングプロセッサ +## カスタムトレーシングプロセッサー -トレーシングの高レベルアーキテクチャは以下の通りです。 +トレーシングの高レベルアーキテクチャは次のとおりです: -- 初期化時にグローバルな [`TraceProvider`][agents.tracing.setup.TraceProvider] を作成します。 -- `TraceProvider` はトレースを OpenAI バックエンドに送信する [`BatchTraceProcessor`][agents.tracing.processors.BatchTraceProcessor] と [`BackendSpanExporter`][agents.tracing.processors.BackendSpanExporter] で構成されます。 +- 初期化時に、トレースを作成する責任を持つグローバルな [`TraceProvider`][agents.tracing.setup.TraceProvider] を作成します。 +- `TraceProvider` を [`BatchTraceProcessor`][agents.tracing.processors.BatchTraceProcessor] で構成し、トレース/スパンをバッチで [`BackendSpanExporter`][agents.tracing.processors.BackendSpanExporter] に送信し、OpenAI バックエンドにバッチでスパンとトレースをエクスポートします。 -このデフォルト設定をカスタマイズするには、以下の 2 つの方法があります。 +このデフォルトのセットアップをカスタマイズして、トレースを代替または追加のバックエンドに送信したり、エクスポーターの動作を変更したりするには、次の2つのオプションがあります: -1. [`add_trace_processor()`][agents.tracing.add_trace_processor] で追加のプロセッサを追加できます。 -2. [`set_trace_processors()`][agents.tracing.set_trace_processors] でデフォルトのプロセッサを置き換えることができます。 +1. [`add_trace_processor()`][agents.tracing.add_trace_processor] を使用して、トレースとスパンが準備できたときに受け取る**追加の**トレースプロセッサーを追加できます。これにより、OpenAI のバックエンドにトレースを送信することに加えて、独自の処理を行うことができます。 +2. [`set_trace_processors()`][agents.tracing.set_trace_processors] を使用して、デフォルトのプロセッサーを独自のトレースプロセッサーに**置き換える**ことができます。これにより、`TracingProcessor` を含めない限り、トレースは OpenAI バックエンドに送信されません。 -## 外部トレーシングプロセッサ一覧 +## 外部トレーシングプロセッサーリスト -(省略:原文のまま) \ No newline at end of file +- [Weights & Biases](https://weave-docs.wandb.ai/guides/integrations/openai_agents) +- [Arize-Phoenix](https://docs.arize.com/phoenix/tracing/integrations-tracing/openai-agents-sdk) +- [MLflow (self-hosted/OSS](https://mlflow.org/docs/latest/tracing/integrations/openai-agent) +- [MLflow (Databricks hosted](https://docs.databricks.com/aws/en/mlflow/mlflow-tracing#-automatic-tracing) +- [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk) +- [Pydantic Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents) +- [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk) +- [Scorecard](https://docs.scorecard.io/docs/documentation/features/tracing#openai-agents-sdk-integration) +- [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent) +- [LangSmith](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_openai_agents_sdk) +- [Maxim AI](https://www.getmaxim.ai/docs/observe/integrations/openai-agents-sdk) +- [Comet Opik](https://www.comet.com/docs/opik/tracing/integrations/openai_agents) +- [Langfuse](https://langfuse.com/docs/integrations/openaiagentssdk/openai-agents) +- [Langtrace](https://docs.langtrace.ai/supported-integrations/llm-frameworks/openai-agents-sdk) +- [Okahu-Monocle](https://github.com/monocle2ai/monocle) \ No newline at end of file diff --git a/docs/ja/visualization.md b/docs/ja/visualization.md index a0e2b9ec..1054dd12 100644 --- a/docs/ja/visualization.md +++ b/docs/ja/visualization.md @@ -1,10 +1,10 @@ # エージェントの可視化 -エージェントの可視化を使用すると、**Graphviz** を用いてエージェントとその関係性を構造化したグラフィカルな表現として生成できます。これにより、アプリケーション内でエージェント、ツール、およびハンドオフがどのように相互作用するかを理解できます。 +エージェントの可視化では、**Graphviz** を使用してエージェントとその関係の構造化されたグラフィカル表現を生成できます。これは、アプリケーション内でエージェント、ツール、ハンドオフがどのように相互作用するかを理解するのに役立ちます。 ## インストール -オプションの依存関係グループ `viz` をインストールします: +オプションの `viz` 依存関係グループをインストールします: ```bash pip install "openai-agents[viz]" @@ -12,11 +12,11 @@ pip install "openai-agents[viz]" ## グラフの生成 -`draw_graph` 関数を使用してエージェントの可視化を生成できます。この関数は以下のような有向グラフを作成します: +`draw_graph` 関数を使用してエージェントの可視化を生成できます。この関数は、以下のような有向グラフを作成します: -- **エージェント** は黄色の四角形で表されます。 -- **ツール** は緑色の楕円形で表されます。 -- **ハンドオフ** はあるエージェントから別のエージェントへの有向エッジで表されます。 +- **エージェント** は黄色のボックスで表されます。 +- **ツール** は緑色の楕円で表されます。 +- **ハンドオフ** はあるエージェントから別のエージェントへの有向エッジです。 ### 使用例 @@ -50,31 +50,31 @@ draw_graph(triage_agent) ![Agent Graph](../assets/images/graph.png) -これにより、**triage agent** とそのサブエージェントおよびツールとの接続構造を視覚的に表現したグラフが生成されます。 +これにより、**トリアージエージェント** の構造とサブエージェントおよびツールへの接続を視覚的に表現するグラフが生成されます。 ## 可視化の理解 -生成されたグラフには以下が含まれます: +生成されたグラフには以下が含まれます: - エントリーポイントを示す **開始ノード** (`__start__`)。 -- 黄色で塗りつぶされた四角形で表されるエージェント。 -- 緑色で塗りつぶされた楕円形で表されるツール。 -- 相互作用を示す有向エッジ: - - エージェント間のハンドオフは **実線矢印**。 - - ツールの呼び出しは **点線矢印**。 -- 実行終了地点を示す **終了ノード** (`__end__`)。 +- 黄色で塗りつぶされた **長方形** で表されるエージェント。 +- 緑色で塗りつぶされた **楕円** で表されるツール。 +- 相互作用を示す有向エッジ: + - エージェント間のハンドオフには **実線の矢印**。 + - ツール呼び出しには **点線の矢印**。 +- 実行が終了する場所を示す **終了ノード** (`__end__`)。 ## グラフのカスタマイズ ### グラフの表示 -デフォルトでは、`draw_graph` はグラフをインラインで表示します。グラフを別ウィンドウで表示するには、以下のように記述します: +デフォルトでは、`draw_graph` はグラフをインラインで表示します。別ウィンドウでグラフを表示するには、次のように記述します: ```python draw_graph(triage_agent).view() ``` ### グラフの保存 -デフォルトでは、`draw_graph` はグラフをインラインで表示します。ファイルとして保存するには、ファイル名を指定します: +デフォルトでは、`draw_graph` はグラフをインラインで表示します。ファイルとして保存するには、ファイル名を指定します: ```python draw_graph(triage_agent, filename="agent_graph.png") diff --git a/docs/ja/voice/pipeline.md b/docs/ja/voice/pipeline.md index 03e0c54e..6df7dd04 100644 --- a/docs/ja/voice/pipeline.md +++ b/docs/ja/voice/pipeline.md @@ -1,6 +1,6 @@ # パイプラインとワークフロー -[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] クラスを使用すると、エージェントのワークフローを簡単に音声アプリに変換できます。実行するワークフローを渡すと、パイプラインが入力音声の文字起こし、音声終了の検出、適切なタイミングでのワークフロー呼び出し、ワークフロー出力の音声への変換を処理します。 +[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] は、エージェントのワークフローを音声アプリに変換するのを簡単にするクラスです。実行するワークフローを渡すと、パイプラインが入力音声の文字起こし、音声の終了検出、適切なタイミングでのワークフロー呼び出し、ワークフロー出力の音声化を行います。 ```mermaid graph LR @@ -30,28 +30,28 @@ graph LR ## パイプラインの設定 -パイプラインを作成する際、以下の項目を設定できます。 +パイプラインを作成する際に、以下のことを設定できます: -1. [`workflow`][agents.voice.workflow.VoiceWorkflowBase]:新しい音声が文字起こしされるたびに実行されるコードです。 -2. 使用する [`speech-to-text`][agents.voice.model.STTModel] および [`text-to-speech`][agents.voice.model.TTSModel] モデル +1. [`workflow`][agents.voice.workflow.VoiceWorkflowBase]:新しい音声が文字起こしされるたびに実行されるコード。 +2. 使用する [`speech-to-text`][agents.voice.model.STTModel] および [`text-to-speech`][agents.voice.model.TTSModel] モデル。 3. [`config`][agents.voice.pipeline_config.VoicePipelineConfig]:以下のような設定が可能です。 - - モデル名をモデルにマッピングするモデルプロバイダー - - トレーシング(トレーシングの無効化、音声ファイルのアップロード有無、ワークフロー名、トレース ID など) - - TTS および STT モデルの設定(プロンプト、言語、使用するデータ型など) + - モデルプロバイダー:モデル名をモデルにマッピングできます。 + - トレーシング:トレーシングを無効にするかどうか、音声ファイルのアップロード、ワークフロー名、トレース ID など。 + - TTS および STT モデルの設定:プロンプト、言語、使用するデータ型など。 ## パイプラインの実行 -パイプラインは [`run()`][agents.voice.pipeline.VoicePipeline.run] メソッドを使用して実行できます。このメソッドでは、以下の 2 種類の形式で音声入力を渡すことができます。 +パイプラインは [`run()`][agents.voice.pipeline.VoicePipeline.run] メソッドを通じて実行できます。これにより、2 つの形式で音声入力を渡すことができます: -1. [`AudioInput`][agents.voice.input.AudioInput] は、完全な音声トランスクリプトがあり、それに対する結果を生成したい場合に使用します。これは、話者が話し終えたタイミングを検出する必要がない場合に便利です。例えば、事前録音された音声や、ユーザーが話し終えたタイミングが明確なプッシュトゥトーク型アプリなどです。 -2. [`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] は、ユーザーが話し終えたタイミングを検出する必要がある場合に使用します。音声チャンクを検出時に順次送信でき、音声パイプラインは「アクティビティ検出」と呼ばれるプロセスを通じて、適切なタイミングでエージェントのワークフローを自動的に実行します。 +1. [`AudioInput`][agents.voice.input.AudioInput]:完全な音声トランスクリプトがある場合に使用し、その結果を生成するだけです。これは、話者が話し終わったときの検出が不要な場合に便利です。例えば、事前録音された音声や、ユーザーが話し終わったことが明確なプッシュ・トゥ・トークアプリで使用します。 +2. [`StreamedAudioInput`][agents.voice.input.StreamedAudioInput]:ユーザーが話し終わったときの検出が必要な場合に使用します。音声チャンクを検出時にプッシュでき、音声パイプラインが自動的にエージェントワークフローを適切なタイミングで実行します。これは「アクティビティ検出」と呼ばれるプロセスを通じて行われます。 -## 実行結果 +## 結果 -音声パイプラインの実行結果は [`StreamedAudioResult`][agents.voice.result.StreamedAudioResult] です。これは、発生したイベントをストリームとして取得できるオブジェクトです。いくつかの種類の [`VoiceStreamEvent`][agents.voice.events.VoiceStreamEvent] があり、以下を含みます。 +音声パイプライン実行の結果は [`StreamedAudioResult`][agents.voice.result.StreamedAudioResult] です。これは、イベントが発生するたびにストリーミングできるオブジェクトです。いくつかの種類の [`VoiceStreamEvent`][agents.voice.events.VoiceStreamEvent] があります: -1. [`VoiceStreamEventAudio`][agents.voice.events.VoiceStreamEventAudio]:音声チャンクを含むイベントです。 -2. [`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle]:ターンの開始や終了など、ライフサイクルイベントを通知します。 +1. [`VoiceStreamEventAudio`][agents.voice.events.VoiceStreamEventAudio]:音声チャンクを含むイベント。 +2. [`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle]:ターンの開始や終了などのライフサイクルイベントを通知します。 3. [`VoiceStreamEventError`][agents.voice.events.VoiceStreamEventError]:エラーイベントです。 ```python @@ -70,6 +70,6 @@ async for event in result.stream(): ## ベストプラクティス -### 割り込み処理 +### 中断 -Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの割り込み処理をサポートしていません。その代わり、検出された各ターンごとにワークフローが個別に実行されます。アプリケーション内で割り込みを処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントを監視できます。`turn_started` は新しいターンが文字起こしされ、処理が開始されたことを示します。`turn_ended` は、該当するターンのすべての音声が送信された後にトリガーされます。これらのイベントを利用して、モデルがターンを開始した際に話者のマイクをミュートし、ターンに関連するすべての音声を送信した後にミュートを解除する、といった処理が可能です。 \ No newline at end of file +Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの中断サポートを提供していません。代わりに、検出されたターンごとにワークフローの別の実行をトリガーします。アプリケーション内で中断を処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントを監視できます。`turn_started` は新しいターンが文字起こしされ、処理が始まったことを示します。`turn_ended` は、関連するすべての音声が送信された後にトリガーされます。これらのイベントを使用して、モデルがターンを開始したときにスピーカーのマイクをミュートし、関連する音声をすべてフラッシュした後にアンミュートすることができます。 \ No newline at end of file diff --git a/docs/ja/voice/quickstart.md b/docs/ja/voice/quickstart.md index 0602efe6..77e5ef27 100644 --- a/docs/ja/voice/quickstart.md +++ b/docs/ja/voice/quickstart.md @@ -2,7 +2,7 @@ ## 前提条件 -まず、Agents SDK の基本的な[クイックスタート手順](../quickstart.md)に従い、仮想環境をセットアップしてください。その後、SDK のオプションである音声関連の依存関係をインストールします。 +Agents SDK の基本的な[クイックスタート手順](../quickstart.md)に従い、仮想環境を設定してください。その後、SDK からオプションの音声依存関係をインストールします。 ```bash pip install 'openai-agents[voice]' @@ -10,11 +10,11 @@ pip install 'openai-agents[voice]' ## コンセプト -理解すべき主なコンセプトは [`VoicePipeline`][agents.voice.pipeline.VoicePipeline] です。これは以下の 3 ステップで構成されています。 +知っておくべき主なコンセプトは、[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] です。これは3ステップのプロセスです。 -1. 音声認識モデルを実行し、音声をテキストに変換します。 -2. 通常はエージェントを用いたワークフローであるコードを実行し、実行結果を生成します。 -3. テキスト読み上げモデルを実行し、実行結果のテキストを再び音声に変換します。 +1. 音声をテキストに変換する音声認識モデルを実行します。 +2. 通常はエージェントワークフローであるコードを実行して、結果を生成します。 +3. 結果のテキストを音声に戻すテキスト読み上げモデルを実行します。 ```mermaid graph LR @@ -44,7 +44,7 @@ graph LR ## エージェント -まず、いくつかのエージェントを設定します。この SDK でエージェントを作成したことがあれば、馴染みのある内容です。ここでは、複数のエージェント、ハンドオフ、およびツールを設定します。 +まず、いくつかのエージェントを設定しましょう。この SDK でエージェントを構築したことがある場合、これは馴染みがあるはずです。エージェント、ハンドオフ、ツールを用意します。 ```python import asyncio @@ -88,32 +88,32 @@ agent = Agent( ## 音声パイプライン -ここでは、ワークフローとして [`SingleAgentVoiceWorkflow`][agents.voice.workflow.SingleAgentVoiceWorkflow] を使用し、シンプルな音声パイプラインを設定します。 +[`SingleAgentVoiceWorkflow`][agents.voice.workflow.SingleAgentVoiceWorkflow] をワークフローとして使用して、シンプルな音声パイプラインを設定します。 ```python from agents.voice import SingleAgentVoiceWorkflow, VoicePipeline pipeline = VoicePipeline(workflow=SingleAgentVoiceWorkflow(agent)) ``` -## パイプラインの実行 +## パイプラインを実行する ```python import numpy as np import sounddevice as sd from agents.voice import AudioInput -# 簡単のため、ここでは 3 秒間の無音を作成します -# 実際にはマイクからの音声データを使用します +# For simplicity, we'll just create 3 seconds of silence +# In reality, you'd get microphone data buffer = np.zeros(24000 * 3, dtype=np.int16) audio_input = AudioInput(buffer=buffer) result = await pipeline.run(audio_input) -# `sounddevice` を使ってオーディオプレイヤーを作成します +# Create an audio player using `sounddevice` player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16) player.start() -# 音声ストリームをリアルタイムで再生します +# Play the audio stream as it comes in async for event in result.stream(): if event.type == "voice_stream_event_audio": player.write(event.data) @@ -177,11 +177,11 @@ async def main(): result = await pipeline.run(audio_input) - # `sounddevice` を使ってオーディオプレイヤーを作成します + # Create an audio player using `sounddevice` player = sd.OutputStream(samplerate=24000, channels=1, dtype=np.int16) player.start() - # 音声ストリームをリアルタイムで再生します + # Play the audio stream as it comes in async for event in result.stream(): if event.type == "voice_stream_event_audio": player.write(event.data) @@ -191,4 +191,4 @@ if __name__ == "__main__": asyncio.run(main()) ``` -このコード例を実行すると、エージェントがあなたに話しかけます。実際にエージェントと会話できるデモについては、[examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) のコード例を参照してください。 \ No newline at end of file +この例を実行すると、エージェントがあなたに話しかけます! [examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) の例をチェックして、自分でエージェントと話すデモを見てください。 \ No newline at end of file diff --git a/docs/ja/voice/tracing.md b/docs/ja/voice/tracing.md index 8432d75d..1a1df278 100644 --- a/docs/ja/voice/tracing.md +++ b/docs/ja/voice/tracing.md @@ -1,14 +1,14 @@ # トレーシング -[エージェントのトレーシング](../tracing.md) と同様に、音声パイプラインも自動的にトレーシングされます。 +[エージェントがトレースされる](../tracing.md)のと同様に、音声パイプラインも自動的にトレースされます。 -基本的なトレーシング情報については、上記のトレーシングドキュメントを参照してください。さらに、[`VoicePipelineConfig`][agents.voice.pipeline_config.VoicePipelineConfig] を使用してパイプラインのトレーシングを設定できます。 +基本的なトレーシング情報については上記のトレーシングドキュメントを参照できますが、パイプラインのトレーシングは [`VoicePipelineConfig`][agents.voice.pipeline_config.VoicePipelineConfig] を通じて追加で設定できます。 -主なトレーシング関連フィールドは以下のとおりです。 +トレーシングに関連する主なフィールドは次のとおりです: -- [`tracing_disabled`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレーシングを無効にするかどうかを制御します。デフォルトではトレーシングは有効です。 -- [`trace_include_sensitive_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_data]:音声文字起こしなど、機密性の高いデータをトレースに含めるかどうかを制御します。これは特に音声パイプライン向けであり、ワークフロー内部の処理には影響しません。 -- [`trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data]:トレースに音声データを含めるかどうかを制御します。 -- [`workflow_name`][agents.voice.pipeline_config.VoicePipelineConfig.workflow_name]:トレースするワークフローの名前です。 -- [`group_id`][agents.voice.pipeline_config.VoicePipelineConfig.group_id]:複数のトレースを関連付けるためのトレースの `group_id` です。 -- [`trace_metadata`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレースに含める追加のメタデータです。 \ No newline at end of file +- [`tracing_disabled`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]: トレーシングを無効にするかどうかを制御します。デフォルトでは、トレーシングは有効です。 +- [`trace_include_sensitive_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_data]: トレースに音声トランスクリプトのような潜在的に機密性のあるデータを含めるかどうかを制御します。これは特に音声パイプライン用であり、ワークフロー内で行われることには関係ありません。 +- [`trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data]: トレースに音声データを含めるかどうかを制御します。 +- [`workflow_name`][agents.voice.pipeline_config.VoicePipelineConfig.workflow_name]: トレースワークフローの名前です。 +- [`group_id`][agents.voice.pipeline_config.VoicePipelineConfig.group_id]: 複数のトレースをリンクするための `group_id` です。 +- [`trace_metadata`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]: トレースに含める追加のメタデータです。 \ No newline at end of file diff --git a/docs/quickstart.md b/docs/quickstart.md index f8eca5ca..9513fdb8 100644 --- a/docs/quickstart.md +++ b/docs/quickstart.md @@ -121,7 +121,7 @@ async def homework_guardrail(ctx, agent, input_data): Let's put it all together and run the entire workflow, using handoffs and the input guardrail. ```python -from agents import Agent, InputGuardrail,GuardrailFunctionOutput, Runner +from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner from pydantic import BaseModel import asyncio diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index c907754d..7294e6a9 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -3,6 +3,11 @@ from openai import OpenAI from concurrent.futures import ThreadPoolExecutor +# import logging +# logging.basicConfig(level=logging.INFO) +# logging.getLogger("openai").setLevel(logging.DEBUG) + +OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "gpt-4o") # Define the source and target directories source_dir = "docs" @@ -19,8 +24,18 @@ "OpenAI", "Agents SDK", "Hello World", - "Model Context Protocol", + "Model context protocol", "structured outputs", + "Chain-of-Thought", + "Chat Completions", + "Computer-Using Agent", + "Code Interpreter", + "Function Calling", + "LLM", + "Operator", + "Playground", + "Realtime API", + "Sora", # Add more terms here ] @@ -36,19 +51,34 @@ "tracing": "トレーシング", "code examples": "コード例", "vector store": "ベクトルストア", + "deep research": "ディープリサーチ", + "category": "カテゴリー", + "user": "ユーザー", + "parameter": "パラメーター", + "processor": "プロセッサー", + "server": "サーバー", + "web search": "Web 検索", + "file search": "ファイル検索", + "streaming": "ストリーミング", + "system prompt": "システムプロンプト", + "Python first": "Python ファースト", # Add more Japanese mappings here }, # Add more languages here } eng_to_non_eng_instructions = { - "ja": { - "The term 'result' in the Runner guide context must be translated like 'execution results'", - "The term 'raw' in 'raw response events' must be kept as is", - "The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.", - "The term 'primitives' can be translated as basic components or building blocks.", - "When the terms 'instructions' and 'tools' are mentioned as API parameter names, they must be kept as is.", + "common": [ + "* The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.", + "* The term 'primitives' can be translated as basic components.", + "* When the terms 'instructions' and 'tools' are mentioned as API parameter names, they must be kept as is.", + "* The terms 'temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty' as parameter names must be kept as is.", + ], + "ja": [ + "* The term 'result' in the Runner guide context must be translated like 'execution results'", + "* The term 'raw' in 'raw response events' must be kept as is", + "* You must consistently use polite wording such as です/ます rather than である/なのだ.", # Add more Japanese mappings here - }, + ], # Add more languages here } @@ -56,28 +86,72 @@ def built_instructions(target_language: str, lang_code: str) -> str: do_not_translate_terms = "\n".join(do_not_translate) specific_terms = "\n".join( - [f"{k} -> {v}" for k, v in eng_to_non_eng_mapping.get(lang_code, {}).items()] + [f"* {k} -> {v}" for k, v in eng_to_non_eng_mapping.get(lang_code, {}).items()] + ) + specific_instructions = "\n".join( + eng_to_non_eng_instructions.get("common", []) + + eng_to_non_eng_instructions.get(lang_code, []) ) - specific_instructions = "\n".join(eng_to_non_eng_instructions.get(lang_code, {})) - return f"""You are a professional translator with extensive experience in translating technical documents. -You are assigned to translate markdown text written in English into {target_language}. -The tone and voice must be concise, consistent, and most importantly professional. -You must return only the generated markdown text. Don't include any additional comments. -When you're unable to complete full translation, return an error message indicating the reason instead of returning partial results. - -# Do not translate + return f"""You are an expert technical translator. + +Your task: translate the markdown passed as a user input from English into {target_language}. + +############################ +## OUTPUT REQUIREMENTS ## +############################ +- Return **only** the translated markdown, with the original markdown structure preserved. +- Do **not** add explanations, comments, or metadata. + +######################### +## GENERAL RULES ## +######################### +- The output quality must be great enough to be used for public documentation. +- Be professional and polite. +- Keep the tone **natural** and concise. +- Do not omit any content. If a segment should stay in English, copy it verbatim. +- Do not change the markdown data structure, including the indentations. +- Keep all placeholders such as `CODE_BLOCK_*` and `CODE_LINE_PREFIX` unchanged. +- Convert asset paths: `./assets/…` → `../assets/…`. + *Example:* `![img](./assets/pic.png)` → `![img](../assets/pic.png)` +- Treat the **Do‑Not‑Translate list** and **Term‑Specific list** as case‑insensitive; preserve the original casing you see. +- Skip translation for: + - Inline code surrounded by single back‑ticks ( `like_this` ). + - Fenced code blocks delimited by ``` or ~~~, including all comments inside them. + - Link URLs inside `[label](URL)` – translate the label, never the URL. + +######################### +## LANGUAGE‑SPECIFIC ## +######################### +*(applies only when {target_language} = Japanese)* +- Insert a half‑width space before and after all alphanumeric terms. +- Add a half‑width space just outside markdown emphasis markers: ` **太字** ` (good) vs `** 太字 **` (bad). + +######################### +## DO NOT TRANSLATE ## +######################### +When replacing the following terms, do not have extra spaces before/after them: {do_not_translate_terms} -# Specific term mappings -When you convert these terms, do not append whitespaces before/after the terms. +######################### +## TERM‑SPECIFIC ## +######################### +Translate these terms exactly as provided (no extra spaces): {specific_terms} + +######################### +## EXTRA GUIDELINES ## +######################### {specific_instructions} -# Other Rules -- When translating into Japanese, ensure there are spaces before and after alphanumeric terms and markdown special characters like italic and bold. -- When translating very uncommon technical terms, include both the translated term and the original term in parentheses. That said, the section titles should be as simple as possible. -- You must skip translating any parts of code snippets and code comments -- "./assets/*" needs to be converted to "../assets/*"; markdown files like ./tracing.md can be kept as is. +######################### +## IF UNSURE ## +######################### +If you are uncertain about a term, leave the original English term in parentheses after your translation. + +######################### +## FINAL REMINDER ## +######################### +Return **only** the translated markdown text. No extra commentary. """ @@ -93,28 +167,55 @@ def translate_file(file_path: str, target_path: str, lang_code: str) -> None: current_chunk: list[str] = [] # Split content into chunks of up to 120 lines, ensuring splits occur before section titles + in_code_block = False + code_blocks: list[str] = [] + code_block_chunks: list[str] = [] for line in lines: - if len(current_chunk) >= 120 and line.startswith("#"): + if len(current_chunk) >= 120 and not in_code_block and line.startswith("#"): chunks.append("\n".join(current_chunk)) current_chunk = [] - current_chunk.append(line) + if line.strip().startswith("```"): + code_block_chunks.append(line) + if in_code_block is True: + code_blocks.append("\n".join(code_block_chunks)) + current_chunk.append(f"CODE_BLOCK_{(len(code_blocks) - 1):02}") + code_block_chunks.clear() + in_code_block = not in_code_block + continue + if in_code_block is True: + code_block_chunks.append(line) + else: + current_chunk.append(line) if current_chunk: chunks.append("\n".join(current_chunk)) # Translate each chunk separately and combine results translated_content: list[str] = [] for chunk in chunks: - response = openai_client.responses.create( - model="gpt-4.5-preview", - temperature=0.0, - instructions=built_instructions(languages[lang_code], lang_code), - input=chunk, - ) - translated_content.append(response.output_text) + instructions = built_instructions(languages[lang_code], lang_code) + if OPENAI_MODEL.startswith("o"): + response = openai_client.responses.create( + model=OPENAI_MODEL, + instructions=instructions, + input=chunk, + ) + translated_content.append(response.output_text) + else: + response = openai_client.responses.create( + model=OPENAI_MODEL, + instructions=instructions, + input=chunk, + temperature=0.0, + ) + translated_content.append(response.output_text) + + translated_text = "\n".join(translated_content) + for idx, code_block in enumerate(code_blocks): + translated_text = translated_text.replace(f"CODE_BLOCK_{idx:02}", code_block) # Save the combined translated content with open(target_path, "w", encoding="utf-8") as f: - f.write("\n".join(translated_content)) + f.write(translated_text) def translate_single_source_file(file_path: str) -> None: @@ -139,20 +240,21 @@ def main(): # Skip the target directories if any(lang in root for lang in languages): continue - with ThreadPoolExecutor(max_workers=20) as executor: - futures = [ - executor.submit( - translate_single_source_file, - os.path.join(root, file_name), - ) - for file_name in file_names - ] - for future in futures: - future.result() + # Increasing this will make the translation faster; you can decide considering the model's capacity + concurrency = 6 + with ThreadPoolExecutor(max_workers=concurrency) as executor: + futures = [] + for file_name in file_names: + filepath = os.path.join(root, file_name) + futures.append(executor.submit(translate_single_source_file, filepath)) + if len(futures) >= concurrency: + for future in futures: + future.result() + futures.clear() print("Translation completed.") if __name__ == "__main__": - # translate_single_source_file("docs/tools.md") + # translate_single_source_file("docs/index.md") main() From e115d5a4599a4421dbca694b85d95bcc47602839 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Sat, 12 Apr 2025 02:27:01 +0900 Subject: [PATCH 08/21] Add model_settings guide to models document page (#484) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a pretty minor improvement to the docs: `model_settings` parameter is only mentioned on the agent doc page, but first-time visitors may want to know it’s also available on the models page. --- docs/ja/models.md | 21 +++++++++++++++++---- docs/models.md | 13 +++++++++++++ 2 files changed, 30 insertions(+), 4 deletions(-) diff --git a/docs/ja/models.md b/docs/ja/models.md index a71c9fef..3d216ac3 100644 --- a/docs/ja/models.md +++ b/docs/ja/models.md @@ -1,6 +1,6 @@ # モデル -エージェント SDK は、次の 2 種類の OpenAI モデルをサポートしています。 +Agents SDK は、OpenAI モデルを次の 2 つの形式でサポートしています。 - **推奨**: 新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使用して OpenAI API を呼び出す [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel]。 - [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使用して OpenAI API を呼び出す [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel]。 @@ -51,11 +51,24 @@ async def main(): 1. OpenAI モデルの名前を直接設定します。 2. [`Model`][agents.models.interface.Model] 実装を提供します。 +エージェントに使用するモデルをさらに設定したい場合は、`temperature` などのオプションのモデル設定パラメーターを提供する [`ModelSettings`][agents.models.interface.ModelSettings] を渡すことができます。 + +```python +from agents import Agent, ModelSettings + +english_agent = Agent( + name="English agent", + instructions="You only speak English", + model="gpt-4o", + model_settings=ModelSettings(temperature=0.1), +) +``` + ## 他の LLM プロバイダーの使用 他の LLM プロバイダーを 3 つの方法で使用できます(例は[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/))。 -1. [`set_default_openai_client`][agents.set_default_openai_client] は、`AsyncOpenAI` のインスタンスを LLM クライアントとしてグローバルに使用したい場合に便利です。これは、LLM プロバイダーが OpenAI 互換の API エンドポイントを持っている場合で、`base_url` と `api_key` を設定できます。[examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) に設定可能な例があります。 +1. [`set_default_openai_client`][agents.set_default_openai_client] は、`AsyncOpenAI` のインスタンスを LLM クライアントとしてグローバルに使用したい場合に便利です。LLM プロバイダーが OpenAI 互換の API エンドポイントを持っている場合に、`base_url` と `api_key` を設定できます。[examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) に設定可能な例があります。 2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで使用します。これにより、「この実行のすべてのエージェントにカスタムモデルプロバイダーを使用する」と指定できます。[examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) に設定可能な例があります。 3. [`Agent.model`][agents.agent.Agent.model] では、特定のエージェントインスタンスにモデルを指定できます。これにより、異なるエージェントに対して異なるプロバイダーを組み合わせて使用することができます。[examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) に設定可能な例があります。 @@ -84,10 +97,10 @@ SDK はデフォルトで Responses API を使用しますが、ほとんどの ### 適切な形式のデータのサポート -一部のモデルプロバイダーは[適切な形式のデータ](https://platform.openai.com/docs/guides/structured-outputs)をサポートしていません。これにより、次のようなエラーが発生することがあります。 +一部のモデルプロバイダーは、[適切な形式のデータ](https://platform.openai.com/docs/guides/structured-outputs)をサポートしていません。これにより、次のようなエラーが発生することがあります。 ``` BadRequestError: Error code: 400 - {'error': {'message': "'response_format.type' : value is not one of the allowed values ['text','json_object']", 'type': 'invalid_request_error'}} ``` -これは一部のモデルプロバイダーの欠点で、JSON 出力をサポートしていますが、出力に使用する `json_schema` を指定することはできません。この問題の修正に取り組んでいますが、JSON スキーマ出力をサポートしているプロバイダーに依存することをお勧めします。さもないと、アプリが不正な JSON のために頻繁に壊れることになります。 \ No newline at end of file +これは一部のモデルプロバイダーの欠点であり、JSON 出力をサポートしていますが、出力に使用する `json_schema` を指定することはできません。これに対する修正に取り組んでいますが、JSON スキーマ出力をサポートしているプロバイダーに依存することをお勧めします。さもないと、アプリが不正な JSON のために頻繁に壊れることになります。 \ No newline at end of file diff --git a/docs/models.md b/docs/models.md index ab4cefb8..1ce6e8f2 100644 --- a/docs/models.md +++ b/docs/models.md @@ -51,6 +51,19 @@ async def main(): 1. Sets the name of an OpenAI model directly. 2. Provides a [`Model`][agents.models.interface.Model] implementation. +When you want to further configure the model used for an agent, you can pass [`ModelSettings`][agents.models.interface.ModelSettings], which provides optional model configuration parameters such as temperature. + +```python +from agents import Agent, ModelSettings + +english_agent = Agent( + name="English agent", + instructions="You only speak English", + model="gpt-4o", + model_settings=ModelSettings(temperature=0.1), +) +``` + ## Using other LLM providers You can use other LLM providers in 3 ways (examples [here](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/)): From d0693a192e92057bfae7cc9d621a6a68e76a111b Mon Sep 17 00:00:00 2001 From: LouisShark Date: Sat, 12 Apr 2025 06:20:59 +0800 Subject: [PATCH 09/21] fix: ensure metadata is non-null in response handling (#483) ensure metadata is non-null in response handling --- src/agents/models/openai_responses.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index 6fda4bb3..06828884 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -248,7 +248,7 @@ async def _fetch_response( text=response_format, store=self._non_null_or_not_given(model_settings.store), reasoning=self._non_null_or_not_given(model_settings.reasoning), - metadata=model_settings.metadata, + metadata=self._non_null_or_not_given(model_settings.metadata) ) def _get_client(self) -> AsyncOpenAI: From e04d87cb1fbd72f8d8c48ba18730408cdd321766 Mon Sep 17 00:00:00 2001 From: Daniele Morotti <58258368+DanieleMorotti@users.noreply.github.com> Date: Mon, 14 Apr 2025 16:37:00 +0200 Subject: [PATCH 10/21] Add extra request parameters `extra_query` and `extra_body` (#500) Added the possibility to pass `extra_query` and `extra_body` parameters when sending a request. In this implementation I added the attributes to `ModelSettings` as suggested by @rm-openai in #487 . I'll be happy to add some tests if you have any suggestions. --- src/agents/model_settings.py | 9 +++++++++ src/agents/models/openai_chatcompletions.py | 2 ++ src/agents/models/openai_responses.py | 2 ++ 3 files changed, 13 insertions(+) diff --git a/src/agents/model_settings.py b/src/agents/model_settings.py index f29cfa4a..ed9a0131 100644 --- a/src/agents/model_settings.py +++ b/src/agents/model_settings.py @@ -3,6 +3,7 @@ from dataclasses import dataclass, fields, replace from typing import Literal +from openai._types import Body, Query from openai.types.shared import Reasoning @@ -58,6 +59,14 @@ class ModelSettings: """Whether to include usage chunk. Defaults to True if not provided.""" + extra_query: Query | None = None + """Additional query fields to provide with the request. + Defaults to None if not provided.""" + + extra_body: Body | None = None + """Additional body fields to provide with the request. + Defaults to None if not provided.""" + def resolve(self, override: ModelSettings | None) -> ModelSettings: """Produce a new ModelSettings by overlaying any non-None values from the override on top of this instance.""" diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index 807c6512..267efcaf 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -540,6 +540,8 @@ async def _fetch_response( store=self._non_null_or_not_given(store), reasoning_effort=self._non_null_or_not_given(reasoning_effort), extra_headers=_HEADERS, + extra_query=model_settings.extra_query, + extra_body=model_settings.extra_body, metadata=self._non_null_or_not_given(model_settings.metadata), ) diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index 06828884..cb5a603f 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -245,6 +245,8 @@ async def _fetch_response( parallel_tool_calls=parallel_tool_calls, stream=stream, extra_headers=_HEADERS, + extra_query=model_settings.extra_query, + extra_body=model_settings.extra_body, text=response_format, store=self._non_null_or_not_given(model_settings.store), reasoning=self._non_null_or_not_given(model_settings.reasoning), From 25f97f979b32810eb9b455d2809f5ef5f14bdb54 Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Mon, 14 Apr 2025 23:37:13 +0900 Subject: [PATCH 11/21] Fix typos and misspellings (#486) Detected typos using typos-cli (https://crates.io/crates/typos-cli). It detected "occured" in a string constant "handoff_occured" too, but I didn't change the part this time because it could be a minor breaking change. Full outputs: ``` % typos . error: `Supresses` should be `Suppresses` --> ./src/agents/function_schema.py:134:7 | 134 | # Supresses warnings about missing annotations for params | ^^^^^^^^^ | error: `typ` should be `typo`, `type` --> ./src/agents/strict_schema.py:51:5 | 51 | typ = json_schema.get("type") | ^^^ | error: `typ` should be `typo`, `type` --> ./src/agents/strict_schema.py:52:8 | 52 | if typ == "object" and "additionalProperties" not in json_schema: | ^^^ | error: `typ` should be `typo`, `type` --> ./src/agents/strict_schema.py:55:9 | 55 | typ == "object" | ^^^ | error: `occured` should be `occurred` --> ./src/agents/stream_events.py:34:18 | 34 | "handoff_occured", | ^^^^^^^ | error: `occured` should be `occurred` --> ./src/agents/_run_impl.py:723:69 | 723 | event = RunItemStreamEvent(item=item, name="handoff_occured") | ^^^^^^^ | error: `desitnation` should be `destination` --> ./src/agents/tracing/span_data.py:171:25 | 171 | Includes source and desitnation agents. | ^^^^^^^^^^^ | error: `exmaples` should be `examples` --> ./docs/scripts/translate_docs.py:71:145 | 71 | "* The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.", | ^^^^^^^^ | error: `structed` should be `structured` --> ./tests/test_agent_hooks.py:227:16 | 227 | async def test_structed_output_non_streamed_agent_hooks(): | ^^^^^^^^ | error: `structed` should be `structured` --> ./tests/test_agent_hooks.py:298:16 | 298 | async def test_structed_output_streamed_agent_hooks(): | ^^^^^^^^ | ``` --- docs/scripts/translate_docs.py | 2 +- src/agents/function_schema.py | 2 +- src/agents/tracing/span_data.py | 2 +- tests/test_agent_hooks.py | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index 7294e6a9..e62a2c09 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -68,7 +68,7 @@ } eng_to_non_eng_instructions = { "common": [ - "* The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code exmaples' or 'sample code'.", + "* The term 'examples' must be code examples when the page mentions the code examples in the repo, it can be translated as either 'code examples' or 'sample code'.", "* The term 'primitives' can be translated as basic components.", "* When the terms 'instructions' and 'tools' are mentioned as API parameter names, they must be kept as is.", "* The terms 'temperature', 'top_p', 'max_tokens', 'presence_penalty', 'frequency_penalty' as parameter names must be kept as is.", diff --git a/src/agents/function_schema.py b/src/agents/function_schema.py index 681affce..0e586896 100644 --- a/src/agents/function_schema.py +++ b/src/agents/function_schema.py @@ -131,7 +131,7 @@ def _detect_docstring_style(doc: str) -> DocstringStyle: @contextlib.contextmanager def _suppress_griffe_logging(): - # Supresses warnings about missing annotations for params + # Suppresses warnings about missing annotations for params logger = logging.getLogger("griffe") previous_level = logger.getEffectiveLevel() logger.setLevel(logging.ERROR) diff --git a/src/agents/tracing/span_data.py b/src/agents/tracing/span_data.py index 260e4c45..1a450280 100644 --- a/src/agents/tracing/span_data.py +++ b/src/agents/tracing/span_data.py @@ -168,7 +168,7 @@ def export(self) -> dict[str, Any]: class HandoffSpanData(SpanData): """ Represents a Handoff Span in the trace. - Includes source and desitnation agents. + Includes source and destination agents. """ __slots__ = ("from_agent", "to_agent") diff --git a/tests/test_agent_hooks.py b/tests/test_agent_hooks.py index 33107cba..a6c302dc 100644 --- a/tests/test_agent_hooks.py +++ b/tests/test_agent_hooks.py @@ -224,7 +224,7 @@ class Foo(TypedDict): @pytest.mark.asyncio -async def test_structed_output_non_streamed_agent_hooks(): +async def test_structured_output_non_streamed_agent_hooks(): hooks = AgentHooksForTests() model = FakeModel() agent_1 = Agent(name="test_1", model=model) @@ -295,7 +295,7 @@ async def test_structed_output_non_streamed_agent_hooks(): @pytest.mark.asyncio -async def test_structed_output_streamed_agent_hooks(): +async def test_structured_output_streamed_agent_hooks(): hooks = AgentHooksForTests() model = FakeModel() agent_1 = Agent(name="test_1", model=model) From 5183f528f441cadcb55599c654192a31c390723f Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 12:40:32 -0400 Subject: [PATCH 12/21] Add docs for customizng agent-as-tool (#504) Co-authored-by: pakrym-oai --- docs/tools.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/tools.md b/docs/tools.md index f7a88691..5fe2eced 100644 --- a/docs/tools.md +++ b/docs/tools.md @@ -259,6 +259,27 @@ async def main(): print(result.final_output) ``` +### Customizing tool-agents + +The `agent.as_tool` function is a convenience method to make it easy to turn an agent into a tool. It doesn't support all configuration though; for example, you can't set `max_turns`. For advanced use cases, use `Runner.run` directly in your tool implementation: + +```python +@function_tool +async def run_my_agent() -> str: + """A tool that runs the agent with custom configs". + + agent = Agent(name="My agent", instructions="...") + + result = await Runner.run( + agent, + input="...", + max_turns=5, + run_config=... + ) + + return str(result.final_output) +``` + ## Handling errors in function tools When you create a function tool via `@function_tool`, you can pass a `failure_error_function`. This is a function that provides an error response to the LLM in case the tool call crashes. From 5727a1c73a45a7e2681f90b6cdc0cd372434bd3f Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 12:40:41 -0400 Subject: [PATCH 13/21] Example for streaming guardrails (#505) An example for the question in the issue attached - how to run guardrails during streaming. Towards #495. --- .../agent_patterns/streaming_guardrails.py | 93 +++++++++++++++++++ src/agents/models/openai_chatcompletions.py | 8 +- src/agents/models/openai_responses.py | 2 +- 3 files changed, 99 insertions(+), 4 deletions(-) create mode 100644 examples/agent_patterns/streaming_guardrails.py diff --git a/examples/agent_patterns/streaming_guardrails.py b/examples/agent_patterns/streaming_guardrails.py new file mode 100644 index 00000000..f4db2869 --- /dev/null +++ b/examples/agent_patterns/streaming_guardrails.py @@ -0,0 +1,93 @@ +from __future__ import annotations + +import asyncio + +from openai.types.responses import ResponseTextDeltaEvent +from pydantic import BaseModel, Field + +from agents import Agent, Runner + +""" +This example shows how to use guardrails as the model is streaming. Output guardrails run after the +final output has been generated; this example runs guardails every N tokens, allowing for early +termination if bad output is detected. + +The expected output is that you'll see a bunch of tokens stream in, then the guardrail will trigger +and stop the streaming. +""" + + +agent = Agent( + name="Assistant", + instructions=( + "You are a helpful assistant. You ALWAYS write long responses, making sure to be verbose " + "and detailed." + ), +) + + +class GuardrailOutput(BaseModel): + reasoning: str = Field( + description="Reasoning about whether the response could be understood by a ten year old." + ) + is_readable_by_ten_year_old: bool = Field( + description="Whether the response is understandable by a ten year old." + ) + + +guardrail_agent = Agent( + name="Checker", + instructions=( + "You will be given a question and a response. Your goal is to judge whether the response " + "is simple enough to be understood by a ten year old." + ), + output_type=GuardrailOutput, + model="gpt-4o-mini", +) + + +async def check_guardrail(text: str) -> GuardrailOutput: + result = await Runner.run(guardrail_agent, text) + return result.final_output_as(GuardrailOutput) + + +async def main(): + question = "What is a black hole, and how does it behave?" + result = Runner.run_streamed(agent, question) + current_text = "" + + # We will check the guardrail every N characters + next_guardrail_check_len = 300 + guardrail_task = None + + async for event in result.stream_events(): + if event.type == "raw_response_event" and isinstance(event.data, ResponseTextDeltaEvent): + print(event.data.delta, end="", flush=True) + current_text += event.data.delta + + # Check if it's time to run the guardrail check + # Note that we don't run the guardrail check if there's already a task running. An + # alternate implementation is to have N guardrails running, or cancel the previous + # one. + if len(current_text) >= next_guardrail_check_len and not guardrail_task: + print("Running guardrail check") + guardrail_task = asyncio.create_task(check_guardrail(current_text)) + next_guardrail_check_len += 300 + + # Every iteration of the loop, check if the guardrail has been triggered + if guardrail_task and guardrail_task.done(): + guardrail_result = guardrail_task.result() + if not guardrail_result.is_readable_by_ten_year_old: + print("\n\n================\n\n") + print(f"Guardrail triggered. Reasoning:\n{guardrail_result.reasoning}") + break + + # Do one final check on the final output + guardrail_result = await check_guardrail(current_text) + if not guardrail_result.is_readable_by_ten_year_old: + print("\n\n================\n\n") + print(f"Guardrail triggered. Reasoning:\n{guardrail_result.reasoning}") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index 267efcaf..6978ee30 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -572,7 +572,6 @@ def _get_client(self) -> AsyncOpenAI: class _Converter: - @classmethod def is_openai(cls, client: AsyncOpenAI): return str(client.base_url).startswith("https://api.openai.com") @@ -585,11 +584,14 @@ def get_store_param(cls, client: AsyncOpenAI, model_settings: ModelSettings) -> @classmethod def get_stream_options_param( - cls, client: AsyncOpenAI, model_settings: ModelSettings + cls, client: AsyncOpenAI, model_settings: ModelSettings ) -> dict[str, bool] | None: default_include_usage = True if cls.is_openai(client) else None - include_usage = model_settings.include_usage if model_settings.include_usage is not None \ + include_usage = ( + model_settings.include_usage + if model_settings.include_usage is not None else default_include_usage + ) stream_options = {"include_usage": include_usage} if include_usage is not None else None return stream_options diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index cb5a603f..055ab79b 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -250,7 +250,7 @@ async def _fetch_response( text=response_format, store=self._non_null_or_not_given(model_settings.store), reasoning=self._non_null_or_not_given(model_settings.reasoning), - metadata=self._non_null_or_not_given(model_settings.metadata) + metadata=self._non_null_or_not_given(model_settings.metadata), ) def _get_client(self) -> AsyncOpenAI: From 36f5b72449cb1bb20b0b464a671a24af11df8013 Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 12:46:00 -0400 Subject: [PATCH 14/21] Don't run tracing shutdown behavior if disabled (#503) Towards #502 --- src/agents/tracing/setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/agents/tracing/setup.py b/src/agents/tracing/setup.py index 3a7c6ade..9e27d210 100644 --- a/src/agents/tracing/setup.py +++ b/src/agents/tracing/setup.py @@ -201,6 +201,9 @@ def create_span( ) def shutdown(self) -> None: + if self._disabled: + return + try: logger.debug("Shutting down trace provider") self._multi_processor.shutdown() From e8f14da473775ca6a5f3d5208e21759bdeaf5040 Mon Sep 17 00:00:00 2001 From: Daniele Morotti <58258368+DanieleMorotti@users.noreply.github.com> Date: Mon, 14 Apr 2025 19:28:43 +0200 Subject: [PATCH 15/21] Fix type annotations examples (#496) I fixed the type annotations errors for pydantic objects in some examples as noted in #490 . When running `make lint` the following error occurs "UP007 Use `X | Y` for type annotations". If you know how to ignore it I will be happy to edit the pull request, thanks. --- pyproject.toml | 1 + uv.lock | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index ca398ba2..fa3da072 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "types-requests>=2.0, <3", "mcp>=1.6.0, <2; python_version >= '3.10'", "mkdocs-static-i18n>=1.3.0", + "eval-type-backport>=0.2.2", ] classifiers = [ "Typing :: Typed", diff --git a/uv.lock b/uv.lock index af7eef7e..a762c723 100644 --- a/uv.lock +++ b/uv.lock @@ -313,6 +313,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277 }, ] +[[package]] +name = "eval-type-backport" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/ea/8b0ac4469d4c347c6a385ff09dc3c048c2d021696664e26c7ee6791631b5/eval_type_backport-0.2.2.tar.gz", hash = "sha256:f0576b4cf01ebb5bd358d02314d31846af5e07678387486e2c798af0e7d849c1", size = 9079 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/31/55cd413eaccd39125368be33c46de24a1f639f2e12349b0361b4678f3915/eval_type_backport-0.2.2-py3-none-any.whl", hash = "sha256:cb6ad7c393517f476f96d456d0412ea80f0a8cf96f6892834cd9340149111b0a", size = 5830 }, +] + [[package]] name = "evdev" version = "1.9.1" @@ -1102,6 +1111,7 @@ name = "openai-agents" version = "0.0.9" source = { editable = "." } dependencies = [ + { name = "eval-type-backport" }, { name = "griffe" }, { name = "mcp", marker = "python_full_version >= '3.10'" }, { name = "mkdocs-static-i18n" }, @@ -1146,6 +1156,7 @@ dev = [ [package.metadata] requires-dist = [ + { name = "eval-type-backport", specifier = ">=0.2.2" }, { name = "graphviz", marker = "extra == 'viz'", specifier = ">=0.17" }, { name = "griffe", specifier = ">=1.5.6,<2" }, { name = "mcp", marker = "python_full_version >= '3.10'", specifier = ">=1.6.0,<2" }, From d6f5190d53dd1923f380356abd21848b53059e7f Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 21:37:18 -0400 Subject: [PATCH 16/21] Replace referencable_id with response_id (#508) Minor change - naming. So that it doesn't pollute the next PR. --- [//]: # (BEGIN SAPLING FOOTER) * #509 * __->__ #508 --- src/agents/items.py | 2 +- src/agents/models/openai_chatcompletions.py | 2 +- src/agents/models/openai_responses.py | 2 +- src/agents/run.py | 2 +- tests/fake_model.py | 2 +- tests/test_items_helpers.py | 12 ++++---- tests/test_openai_chatcompletions.py | 2 +- tests/test_run_step_execution.py | 20 ++++++------- tests/test_run_step_processing.py | 32 ++++++++++----------- 9 files changed, 38 insertions(+), 38 deletions(-) diff --git a/src/agents/items.py b/src/agents/items.py index c2af0dfc..d72701ab 100644 --- a/src/agents/items.py +++ b/src/agents/items.py @@ -166,7 +166,7 @@ class ModelResponse: usage: Usage """The usage information for the response.""" - referenceable_id: str | None + response_id: str | None """An ID for the response which can be used to refer to the response in subsequent calls to the model. Not supported by all model providers. """ diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index 6978ee30..b60d5d6a 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -156,7 +156,7 @@ async def get_response( return ModelResponse( output=items, usage=usage, - referenceable_id=None, + response_id=None, ) async def stream_response( diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index 055ab79b..e509d6f8 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -120,7 +120,7 @@ async def get_response( return ModelResponse( output=response.output, usage=usage, - referenceable_id=response.id, + response_id=response.id, ) async def stream_response( diff --git a/src/agents/run.py b/src/agents/run.py index 0159822a..93e6490c 100644 --- a/src/agents/run.py +++ b/src/agents/run.py @@ -677,7 +677,7 @@ async def _run_single_turn_streamed( final_response = ModelResponse( output=event.response.output, usage=usage, - referenceable_id=event.response.id, + response_id=event.response.id, ) streamed_result._event_queue.put_nowait(RawResponsesStreamEvent(data=event)) diff --git a/tests/fake_model.py b/tests/fake_model.py index ecbb7583..61fb5951 100644 --- a/tests/fake_model.py +++ b/tests/fake_model.py @@ -81,7 +81,7 @@ async def get_response( return ModelResponse( output=output, usage=Usage(), - referenceable_id=None, + response_id=None, ) async def stream_response( diff --git a/tests/test_items_helpers.py b/tests/test_items_helpers.py index 90fe6475..5dba21d8 100644 --- a/tests/test_items_helpers.py +++ b/tests/test_items_helpers.py @@ -168,7 +168,7 @@ def test_to_input_items_for_message() -> None: message = ResponseOutputMessage( id="m1", content=[content], role="assistant", status="completed", type="message" ) - resp = ModelResponse(output=[message], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[message], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 # The dict should contain exactly the primitive values of the message @@ -193,7 +193,7 @@ def test_to_input_items_for_function_call() -> None: tool_call = ResponseFunctionToolCall( id="f1", arguments="{}", call_id="c1", name="func", type="function_call" ) - resp = ModelResponse(output=[tool_call], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[tool_call], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 expected: ResponseFunctionToolCallParam = { @@ -211,7 +211,7 @@ def test_to_input_items_for_file_search_call() -> None: fs_call = ResponseFileSearchToolCall( id="fs1", queries=["query"], status="completed", type="file_search_call" ) - resp = ModelResponse(output=[fs_call], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[fs_call], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 expected: ResponseFileSearchToolCallParam = { @@ -226,7 +226,7 @@ def test_to_input_items_for_file_search_call() -> None: def test_to_input_items_for_web_search_call() -> None: """A web search tool call output should produce the same dict as a web search input.""" ws_call = ResponseFunctionWebSearch(id="w1", status="completed", type="web_search_call") - resp = ModelResponse(output=[ws_call], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[ws_call], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 expected: ResponseFunctionWebSearchParam = { @@ -248,7 +248,7 @@ def test_to_input_items_for_computer_call_click() -> None: pending_safety_checks=[], status="completed", ) - resp = ModelResponse(output=[comp_call], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[comp_call], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 converted_dict = input_items[0] @@ -268,7 +268,7 @@ def test_to_input_items_for_reasoning() -> None: """A reasoning output should produce the same dict as a reasoning input item.""" rc = Summary(text="why", type="summary_text") reasoning = ResponseReasoningItem(id="rid1", summary=[rc], type="reasoning") - resp = ModelResponse(output=[reasoning], usage=Usage(), referenceable_id=None) + resp = ModelResponse(output=[reasoning], usage=Usage(), response_id=None) input_items = resp.to_input_items() assert isinstance(input_items, list) and len(input_items) == 1 converted_dict = input_items[0] diff --git a/tests/test_openai_chatcompletions.py b/tests/test_openai_chatcompletions.py index 281d7b41..3608fc57 100644 --- a/tests/test_openai_chatcompletions.py +++ b/tests/test_openai_chatcompletions.py @@ -80,7 +80,7 @@ async def patched_fetch_response(self, *args, **kwargs): assert resp.usage.input_tokens == 7 assert resp.usage.output_tokens == 5 assert resp.usage.total_tokens == 12 - assert resp.referenceable_id is None + assert resp.response_id is None @pytest.mark.allow_call_model_methods diff --git a/tests/test_run_step_execution.py b/tests/test_run_step_execution.py index 16c62c84..6ae25fbd 100644 --- a/tests/test_run_step_execution.py +++ b/tests/test_run_step_execution.py @@ -43,7 +43,7 @@ async def test_empty_response_is_final_output(): response = ModelResponse( output=[], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -59,7 +59,7 @@ async def test_plaintext_agent_no_tool_calls_is_final_output(): response = ModelResponse( output=[get_text_message("hello_world")], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -79,7 +79,7 @@ async def test_plaintext_agent_no_tool_calls_multiple_messages_is_final_output() get_text_message("bye"), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result( agent, @@ -105,7 +105,7 @@ async def test_plaintext_agent_with_tool_call_is_run_again(): response = ModelResponse( output=[get_text_message("hello_world"), get_function_tool_call("test", "")], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -140,7 +140,7 @@ async def test_multiple_tool_calls(): get_function_tool_call("test_2"), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -166,7 +166,7 @@ async def test_handoff_output_leads_to_handoff_next_step(): response = ModelResponse( output=[get_text_message("Hello, world!"), get_handoff_tool_call(agent_1)], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent_3, response) @@ -186,7 +186,7 @@ async def test_final_output_without_tool_runs_again(): response = ModelResponse( output=[get_function_tool_call("tool_1")], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -203,7 +203,7 @@ async def test_final_output_leads_to_final_output_next_step(): get_final_output_message(Foo(bar="123").model_dump_json()), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent, response) @@ -222,7 +222,7 @@ async def test_handoff_and_final_output_leads_to_handoff_next_step(): get_handoff_tool_call(agent_1), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent_3, response) @@ -241,7 +241,7 @@ async def test_multiple_final_output_leads_to_final_output_next_step(): get_final_output_message(Foo(bar="456").model_dump_json()), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = await get_execute_result(agent_3, response) diff --git a/tests/test_run_step_processing.py b/tests/test_run_step_processing.py index 2a6634ac..2ea98f06 100644 --- a/tests/test_run_step_processing.py +++ b/tests/test_run_step_processing.py @@ -39,7 +39,7 @@ def test_empty_response(): response = ModelResponse( output=[], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( @@ -58,7 +58,7 @@ def test_no_tool_calls(): response = ModelResponse( output=[get_text_message("Hello, world!")], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent, response=response, output_schema=None, handoffs=[], all_tools=[] @@ -76,7 +76,7 @@ async def test_single_tool_call(): get_function_tool_call("test", ""), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent, @@ -102,7 +102,7 @@ async def test_missing_tool_call_raises_error(): get_function_tool_call("missing", ""), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) with pytest.raises(ModelBehaviorError): @@ -132,7 +132,7 @@ async def test_multiple_tool_calls(): get_function_tool_call("test_2", "xyz"), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( @@ -162,7 +162,7 @@ async def test_handoffs_parsed_correctly(): response = ModelResponse( output=[get_text_message("Hello, world!")], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent_3, @@ -176,7 +176,7 @@ async def test_handoffs_parsed_correctly(): response = ModelResponse( output=[get_text_message("Hello, world!"), get_handoff_tool_call(agent_1)], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent_3, @@ -205,7 +205,7 @@ async def test_missing_handoff_fails(): response = ModelResponse( output=[get_text_message("Hello, world!"), get_handoff_tool_call(agent_2)], usage=Usage(), - referenceable_id=None, + response_id=None, ) with pytest.raises(ModelBehaviorError): RunImpl.process_model_response( @@ -229,7 +229,7 @@ async def test_multiple_handoffs_doesnt_error(): get_handoff_tool_call(agent_2), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent_3, @@ -254,7 +254,7 @@ async def test_final_output_parsed_correctly(): get_final_output_message(Foo(bar="123").model_dump_json()), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) RunImpl.process_model_response( @@ -281,7 +281,7 @@ async def test_file_search_tool_call_parsed_correctly(): response = ModelResponse( output=[get_text_message("hello"), file_search_call], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent, @@ -306,7 +306,7 @@ async def test_function_web_search_tool_call_parsed_correctly(): response = ModelResponse( output=[get_text_message("hello"), web_search_call], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent, @@ -333,7 +333,7 @@ async def test_reasoning_item_parsed_correctly(): response = ModelResponse( output=[reasoning], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=Agent(name="test"), @@ -401,7 +401,7 @@ async def test_computer_tool_call_without_computer_tool_raises_error(): response = ModelResponse( output=[computer_call], usage=Usage(), - referenceable_id=None, + response_id=None, ) with pytest.raises(ModelBehaviorError): RunImpl.process_model_response( @@ -430,7 +430,7 @@ async def test_computer_tool_call_with_computer_tool_parsed_correctly(): response = ModelResponse( output=[computer_call], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( agent=agent, @@ -460,7 +460,7 @@ async def test_tool_and_handoff_parsed_correctly(): get_handoff_tool_call(agent_1), ], usage=Usage(), - referenceable_id=None, + response_id=None, ) result = RunImpl.process_model_response( From 86ad99d7982ebe92259d656e2929d300290d96ae Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 21:59:41 -0400 Subject: [PATCH 17/21] Move dev-only deps to dev section (#506) These two deps are only used in development/examples --- pyproject.toml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index fa3da072..251a6ab5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,8 +14,6 @@ dependencies = [ "requests>=2.0, <3", "types-requests>=2.0, <3", "mcp>=1.6.0, <2; python_version >= '3.10'", - "mkdocs-static-i18n>=1.3.0", - "eval-type-backport>=0.2.2", ] classifiers = [ "Typing :: Typed", @@ -60,6 +58,8 @@ dev = [ "textual", "websockets", "graphviz", + "mkdocs-static-i18n>=1.3.0", + "eval-type-backport>=0.2.2", ] [tool.uv.workspace] From 92d6e3e66cc9672895dac15c3ebbb3f4ee6475c4 Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 22:02:47 -0400 Subject: [PATCH 18/21] Previous response id (#509) Allows passing in the previous_response_id to reduce sending the same data again and again. Test plan: Examples. Adding tests in next PR shortly. --- [//]: # (BEGIN SAPLING FOOTER) * __->__ #509 * #508 --- src/agents/items.py | 2 + src/agents/models/interface.py | 8 ++ src/agents/models/openai_chatcompletions.py | 3 + src/agents/models/openai_responses.py | 9 ++ src/agents/result.py | 8 ++ src/agents/run.py | 22 +++- tests/fake_model.py | 4 + tests/test_openai_chatcompletions.py | 3 + tests/test_openai_chatcompletions_stream.py | 3 + tests/test_responses_tracing.py | 108 +++++++++++++++++--- tests/voice/test_workflow.py | 4 + 11 files changed, 161 insertions(+), 13 deletions(-) diff --git a/src/agents/items.py b/src/agents/items.py index d72701ab..8fb2b52a 100644 --- a/src/agents/items.py +++ b/src/agents/items.py @@ -169,6 +169,8 @@ class ModelResponse: response_id: str | None """An ID for the response which can be used to refer to the response in subsequent calls to the model. Not supported by all model providers. + If using OpenAI models via the Responses API, this is the `response_id` parameter, and it can + be passed to `Runner.run`. """ def to_input_items(self) -> list[TResponseInputItem]: diff --git a/src/agents/models/interface.py b/src/agents/models/interface.py index e9a8700c..bcf2c1a6 100644 --- a/src/agents/models/interface.py +++ b/src/agents/models/interface.py @@ -44,6 +44,8 @@ async def get_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> ModelResponse: """Get a response from the model. @@ -55,6 +57,8 @@ async def get_response( output_schema: The output schema to use. handoffs: The handoffs available to the model. tracing: Tracing configuration. + previous_response_id: the ID of the previous response. Generally not used by the model, + except for the OpenAI Responses API. Returns: The full model response. @@ -71,6 +75,8 @@ def stream_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> AsyncIterator[TResponseStreamEvent]: """Stream a response from the model. @@ -82,6 +88,8 @@ def stream_response( output_schema: The output schema to use. handoffs: The handoffs available to the model. tracing: Tracing configuration. + previous_response_id: the ID of the previous response. Generally not used by the model, + except for the OpenAI Responses API. Returns: An iterator of response stream events, in OpenAI Responses format. diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index b60d5d6a..c12fe68a 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -108,6 +108,7 @@ async def get_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + previous_response_id: str | None, ) -> ModelResponse: with generation_span( model=str(self.model), @@ -168,6 +169,8 @@ async def stream_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> AsyncIterator[TResponseStreamEvent]: """ Yields a partial message as it is generated, as well as the usage information. diff --git a/src/agents/models/openai_responses.py b/src/agents/models/openai_responses.py index e509d6f8..ab4617d4 100644 --- a/src/agents/models/openai_responses.py +++ b/src/agents/models/openai_responses.py @@ -69,6 +69,7 @@ async def get_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + previous_response_id: str | None, ) -> ModelResponse: with response_span(disabled=tracing.is_disabled()) as span_response: try: @@ -79,6 +80,7 @@ async def get_response( tools, output_schema, handoffs, + previous_response_id, stream=False, ) @@ -132,6 +134,7 @@ async def stream_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + previous_response_id: str | None, ) -> AsyncIterator[ResponseStreamEvent]: """ Yields a partial message as it is generated, as well as the usage information. @@ -145,6 +148,7 @@ async def stream_response( tools, output_schema, handoffs, + previous_response_id, stream=True, ) @@ -180,6 +184,7 @@ async def _fetch_response( tools: list[Tool], output_schema: AgentOutputSchema | None, handoffs: list[Handoff], + previous_response_id: str | None, stream: Literal[True], ) -> AsyncStream[ResponseStreamEvent]: ... @@ -192,6 +197,7 @@ async def _fetch_response( tools: list[Tool], output_schema: AgentOutputSchema | None, handoffs: list[Handoff], + previous_response_id: str | None, stream: Literal[False], ) -> Response: ... @@ -203,6 +209,7 @@ async def _fetch_response( tools: list[Tool], output_schema: AgentOutputSchema | None, handoffs: list[Handoff], + previous_response_id: str | None, stream: Literal[True] | Literal[False] = False, ) -> Response | AsyncStream[ResponseStreamEvent]: list_input = ItemHelpers.input_to_new_input_list(input) @@ -229,9 +236,11 @@ async def _fetch_response( f"Stream: {stream}\n" f"Tool choice: {tool_choice}\n" f"Response format: {response_format}\n" + f"Previous response id: {previous_response_id}\n" ) return await self._client.responses.create( + previous_response_id=self._non_null_or_not_given(previous_response_id), instructions=self._non_null_or_not_given(system_instructions), model=self.model, input=list_input, diff --git a/src/agents/result.py b/src/agents/result.py index 40a64806..a2a6cc4a 100644 --- a/src/agents/result.py +++ b/src/agents/result.py @@ -80,6 +80,14 @@ def to_input_list(self) -> list[TResponseInputItem]: return original_items + new_items + @property + def last_response_id(self) -> str | None: + """Convenience method to get the response ID of the last model response.""" + if not self.raw_responses: + return None + + return self.raw_responses[-1].response_id + @dataclass class RunResult(RunResultBase): diff --git a/src/agents/run.py b/src/agents/run.py index 93e6490c..e2b0dbce 100644 --- a/src/agents/run.py +++ b/src/agents/run.py @@ -117,6 +117,7 @@ async def run( max_turns: int = DEFAULT_MAX_TURNS, hooks: RunHooks[TContext] | None = None, run_config: RunConfig | None = None, + previous_response_id: str | None = None, ) -> RunResult: """Run a workflow starting at the given agent. The agent will run in a loop until a final output is generated. The loop runs like so: @@ -141,6 +142,8 @@ async def run( AI invocation (including any tool calls that might occur). hooks: An object that receives callbacks on various lifecycle events. run_config: Global settings for the entire agent run. + previous_response_id: The ID of the previous response, if using OpenAI models via the + Responses API, this allows you to skip passing in input from the previous turn. Returns: A run result containing all the inputs, guardrail results and the output of the last @@ -230,6 +233,7 @@ async def run( run_config=run_config, should_run_agent_start_hooks=should_run_agent_start_hooks, tool_use_tracker=tool_use_tracker, + previous_response_id=previous_response_id, ), ) else: @@ -243,6 +247,7 @@ async def run( run_config=run_config, should_run_agent_start_hooks=should_run_agent_start_hooks, tool_use_tracker=tool_use_tracker, + previous_response_id=previous_response_id, ) should_run_agent_start_hooks = False @@ -291,6 +296,7 @@ def run_sync( max_turns: int = DEFAULT_MAX_TURNS, hooks: RunHooks[TContext] | None = None, run_config: RunConfig | None = None, + previous_response_id: str | None = None, ) -> RunResult: """Run a workflow synchronously, starting at the given agent. Note that this just wraps the `run` method, so it will not work if there's already an event loop (e.g. inside an async @@ -319,6 +325,8 @@ def run_sync( AI invocation (including any tool calls that might occur). hooks: An object that receives callbacks on various lifecycle events. run_config: Global settings for the entire agent run. + previous_response_id: The ID of the previous response, if using OpenAI models via the + Responses API, this allows you to skip passing in input from the previous turn. Returns: A run result containing all the inputs, guardrail results and the output of the last @@ -332,6 +340,7 @@ def run_sync( max_turns=max_turns, hooks=hooks, run_config=run_config, + previous_response_id=previous_response_id, ) ) @@ -344,6 +353,7 @@ def run_streamed( max_turns: int = DEFAULT_MAX_TURNS, hooks: RunHooks[TContext] | None = None, run_config: RunConfig | None = None, + previous_response_id: str | None = None, ) -> RunResultStreaming: """Run a workflow starting at the given agent in streaming mode. The returned result object contains a method you can use to stream semantic events as they are generated. @@ -370,7 +380,8 @@ def run_streamed( AI invocation (including any tool calls that might occur). hooks: An object that receives callbacks on various lifecycle events. run_config: Global settings for the entire agent run. - + previous_response_id: The ID of the previous response, if using OpenAI models via the + Responses API, this allows you to skip passing in input from the previous turn. Returns: A result object that contains data about the run, as well as a method to stream events. """ @@ -428,6 +439,7 @@ def run_streamed( hooks=hooks, context_wrapper=context_wrapper, run_config=run_config, + previous_response_id=previous_response_id, ) ) return streamed_result @@ -485,6 +497,7 @@ async def _run_streamed_impl( hooks: RunHooks[TContext], context_wrapper: RunContextWrapper[TContext], run_config: RunConfig, + previous_response_id: str | None, ): current_span: Span[AgentSpanData] | None = None current_agent = starting_agent @@ -554,6 +567,7 @@ async def _run_streamed_impl( should_run_agent_start_hooks, tool_use_tracker, all_tools, + previous_response_id, ) should_run_agent_start_hooks = False @@ -623,6 +637,7 @@ async def _run_single_turn_streamed( should_run_agent_start_hooks: bool, tool_use_tracker: AgentToolUseTracker, all_tools: list[Tool], + previous_response_id: str | None, ) -> SingleStepResult: if should_run_agent_start_hooks: await asyncio.gather( @@ -662,6 +677,7 @@ async def _run_single_turn_streamed( get_model_tracing_impl( run_config.tracing_disabled, run_config.trace_include_sensitive_data ), + previous_response_id=previous_response_id, ): if isinstance(event, ResponseCompletedEvent): usage = ( @@ -717,6 +733,7 @@ async def _run_single_turn( run_config: RunConfig, should_run_agent_start_hooks: bool, tool_use_tracker: AgentToolUseTracker, + previous_response_id: str | None, ) -> SingleStepResult: # Ensure we run the hooks before anything else if should_run_agent_start_hooks: @@ -746,6 +763,7 @@ async def _run_single_turn( context_wrapper, run_config, tool_use_tracker, + previous_response_id, ) return await cls._get_single_step_result_from_response( @@ -888,6 +906,7 @@ async def _get_new_response( context_wrapper: RunContextWrapper[TContext], run_config: RunConfig, tool_use_tracker: AgentToolUseTracker, + previous_response_id: str | None, ) -> ModelResponse: model = cls._get_model(agent, run_config) model_settings = agent.model_settings.resolve(run_config.model_settings) @@ -903,6 +922,7 @@ async def _get_new_response( tracing=get_model_tracing_impl( run_config.tracing_disabled, run_config.trace_include_sensitive_data ), + previous_response_id=previous_response_id, ) context_wrapper.usage.add(new_response.usage) diff --git a/tests/fake_model.py b/tests/fake_model.py index 61fb5951..203479d0 100644 --- a/tests/fake_model.py +++ b/tests/fake_model.py @@ -54,6 +54,8 @@ async def get_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> ModelResponse: self.last_turn_args = { "system_instructions": system_instructions, @@ -93,6 +95,8 @@ async def stream_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> AsyncIterator[TResponseStreamEvent]: with generation_span(disabled=not self.tracing_enabled) as span: output = self.get_next_output() diff --git a/tests/test_openai_chatcompletions.py b/tests/test_openai_chatcompletions.py index 3608fc57..92d65fda 100644 --- a/tests/test_openai_chatcompletions.py +++ b/tests/test_openai_chatcompletions.py @@ -67,6 +67,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ) # Should have produced exactly one output message with one text part assert isinstance(resp, ModelResponse) @@ -115,6 +116,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ) assert len(resp.output) == 1 assert isinstance(resp.output[0], ResponseOutputMessage) @@ -164,6 +166,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ) # Expect a message item followed by a function tool call item. assert len(resp.output) == 2 diff --git a/tests/test_openai_chatcompletions_stream.py b/tests/test_openai_chatcompletions_stream.py index 7add92a6..b82f2430 100644 --- a/tests/test_openai_chatcompletions_stream.py +++ b/tests/test_openai_chatcompletions_stream.py @@ -79,6 +79,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ): output_events.append(event) # We expect a response.created, then a response.output_item.added, content part added, @@ -168,6 +169,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ): output_events.append(event) # Expect sequence similar to text: created, output_item.added, content part added, @@ -255,6 +257,7 @@ async def patched_fetch_response(self, *args, **kwargs): output_schema=None, handoffs=[], tracing=ModelTracing.DISABLED, + previous_response_id=None, ): output_events.append(event) # Sequence should be: response.created, then after loop we expect function call-related events: diff --git a/tests/test_responses_tracing.py b/tests/test_responses_tracing.py index 40bdfafb..0bc97a95 100644 --- a/tests/test_responses_tracing.py +++ b/tests/test_responses_tracing.py @@ -44,7 +44,14 @@ async def test_get_response_creates_trace(monkeypatch): # Mock _fetch_response to return a dummy response with a known id async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): return DummyResponse() @@ -52,7 +59,14 @@ async def dummy_fetch_response( # Call get_response await model.get_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.ENABLED + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.ENABLED, + previous_response_id=None, ) assert fetch_normalized_spans() == snapshot( @@ -74,7 +88,14 @@ async def test_non_data_tracing_doesnt_set_response_id(monkeypatch): # Mock _fetch_response to return a dummy response with a known id async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): return DummyResponse() @@ -82,7 +103,14 @@ async def dummy_fetch_response( # Call get_response await model.get_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.ENABLED_WITHOUT_DATA + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.ENABLED_WITHOUT_DATA, + previous_response_id=None, ) assert fetch_normalized_spans() == snapshot( @@ -102,7 +130,14 @@ async def test_disable_tracing_does_not_create_span(monkeypatch): # Mock _fetch_response to return a dummy response with a known id async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): return DummyResponse() @@ -110,7 +145,14 @@ async def dummy_fetch_response( # Call get_response await model.get_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.DISABLED + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.DISABLED, + previous_response_id=None, ) assert fetch_normalized_spans() == snapshot([{"workflow_name": "test"}]) @@ -127,7 +169,14 @@ async def test_stream_response_creates_trace(monkeypatch): # Define a dummy fetch function that returns an async stream with a dummy response async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): class DummyStream: async def __aiter__(self): @@ -142,7 +191,14 @@ async def __aiter__(self): # Consume the stream to trigger processing of the final response async for _ in model.stream_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.ENABLED + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.ENABLED, + previous_response_id=None, ): pass @@ -165,7 +221,14 @@ async def test_stream_non_data_tracing_doesnt_set_response_id(monkeypatch): # Define a dummy fetch function that returns an async stream with a dummy response async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): class DummyStream: async def __aiter__(self): @@ -180,7 +243,14 @@ async def __aiter__(self): # Consume the stream to trigger processing of the final response async for _ in model.stream_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.ENABLED_WITHOUT_DATA + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.ENABLED_WITHOUT_DATA, + previous_response_id=None, ): pass @@ -202,7 +272,14 @@ async def test_stream_disabled_tracing_doesnt_create_span(monkeypatch): # Define a dummy fetch function that returns an async stream with a dummy response async def dummy_fetch_response( - system_instructions, input, model_settings, tools, output_schema, handoffs, stream + system_instructions, + input, + model_settings, + tools, + output_schema, + handoffs, + prev_response_id, + stream, ): class DummyStream: async def __aiter__(self): @@ -217,7 +294,14 @@ async def __aiter__(self): # Consume the stream to trigger processing of the final response async for _ in model.stream_response( - "instr", "input", ModelSettings(), [], None, [], ModelTracing.DISABLED + "instr", + "input", + ModelSettings(), + [], + None, + [], + ModelTracing.DISABLED, + previous_response_id=None, ): pass diff --git a/tests/voice/test_workflow.py b/tests/voice/test_workflow.py index 3f18c049..72a3370d 100644 --- a/tests/voice/test_workflow.py +++ b/tests/voice/test_workflow.py @@ -51,6 +51,8 @@ async def get_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> ModelResponse: raise NotImplementedError("Not implemented") @@ -63,6 +65,8 @@ async def stream_response( output_schema: AgentOutputSchema | None, handoffs: list[Handoff], tracing: ModelTracing, + *, + previous_response_id: str | None, ) -> AsyncIterator[TResponseStreamEvent]: output = self.get_next_output() for item in output: From 360f173b73233bbe82ceb6586809c016d8584f0b Mon Sep 17 00:00:00 2001 From: Kazuhiro Sera Date: Tue, 15 Apr 2025 11:04:07 +0900 Subject: [PATCH 19/21] Evolve the doc translation workflow by using gpt-4.1 (#507) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This pull request enhances the document translation workflow by switching to the new GPT-4.1 model. The generator script’s prompt now includes a “workflow” section that guides the model to iterate self-reviews on its outputs to autonomously achieve the highest quality. This addition has noticeably improved the naturalness and consistency of the wording in the translated outputs. --- docs/ja/agents.md | 44 ++++++------ docs/ja/config.md | 24 +++---- docs/ja/context.md | 44 ++++++------ docs/ja/examples.md | 40 +++++------ docs/ja/guardrails.md | 40 +++++------ docs/ja/handoffs.md | 32 ++++----- docs/ja/index.md | 36 +++++----- docs/ja/mcp.md | 34 ++++----- docs/ja/models.md | 60 ++++++++-------- docs/ja/multi_agent.md | 44 ++++++------ docs/ja/quickstart.md | 32 ++++----- docs/ja/results.md | 38 +++++----- docs/ja/running_agents.md | 70 +++++++++--------- docs/ja/streaming.md | 16 ++--- docs/ja/tools.md | 70 +++++++++--------- docs/ja/tracing.md | 128 ++++++++++++++++----------------- docs/ja/visualization.md | 27 +++---- docs/ja/voice/pipeline.md | 30 ++++---- docs/ja/voice/quickstart.md | 18 ++--- docs/ja/voice/tracing.md | 18 ++--- docs/scripts/translate_docs.py | 21 ++++-- mkdocs.yml | 2 +- 22 files changed, 438 insertions(+), 430 deletions(-) diff --git a/docs/ja/agents.md b/docs/ja/agents.md index 5d7a2dfe..f4b108e8 100644 --- a/docs/ja/agents.md +++ b/docs/ja/agents.md @@ -1,14 +1,14 @@ # エージェント -エージェントはアプリのコア構成要素です。エージェントは、指示とツールで構成された大規模言語モデル (LLM) です。 +エージェントは、アプリケーションの中核となる基本コンポーネントです。エージェントとは、instructions とツールで構成された大規模言語モデル(LLM)のことです。 ## 基本設定 -エージェントで設定する最も一般的なプロパティは次のとおりです: +エージェントで最も一般的に設定するプロパティは以下の通りです。 -- `instructions`: 開発者メッセージまたはシステムプロンプトとも呼ばれます。 -- `model`: 使用する LLM と、temperature や top_p などのモデル調整パラメーターを設定するためのオプションの `model_settings`。 -- `tools`: エージェントがタスクを達成するために使用できるツール。 +- `instructions`:developer message や システムプロンプト(system prompt)とも呼ばれます。 +- `model`:どの LLM を使用するか、また `model_settings` で temperature や top_p などのモデル調整パラメーターを設定できます。 +- `tools`:エージェントがタスクを達成するために使用できるツールです。 ```python from agents import Agent, ModelSettings, function_tool @@ -27,7 +27,7 @@ agent = Agent( ## コンテキスト -エージェントは `context` タイプに対して汎用的です。コンテキストは依存性注入ツールであり、`Runner.run()` に渡すために作成するオブジェクトです。これはすべてのエージェント、ツール、ハンドオフなどに渡され、エージェントの実行に必要な依存関係や状態をまとめたものとして機能します。任意の Python オブジェクトをコンテキストとして提供できます。 +エージェントは `context` 型に対して汎用的です。コンテキストは依存性注入ツールであり、`Runner.run()` に渡すオブジェクトです。これはすべてのエージェント、ツール、ハンドオフなどに渡され、エージェント実行時の依存関係や状態をまとめて管理します。任意の Python オブジェクトを context として指定できます。 ```python @dataclass @@ -45,7 +45,7 @@ agent = Agent[UserContext]( ## 出力タイプ -デフォルトでは、エージェントはプレーンテキスト(つまり `str`)の出力を生成します。特定のタイプの出力をエージェントに生成させたい場合は、`output_type` パラメーターを使用できます。一般的な選択肢として [Pydantic](https://docs.pydantic.dev/) オブジェクトを使用しますが、Pydantic の [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) でラップできる任意のタイプをサポートしています - データクラス、リスト、TypedDict など。 +デフォルトでは、エージェントはプレーンテキスト(つまり `str`)出力を生成します。特定の型の出力をエージェントに生成させたい場合は、`output_type` パラメーターを使用できます。一般的な選択肢として [Pydantic](https://docs.pydantic.dev/) オブジェクトがありますが、Pydantic の [TypeAdapter](https://docs.pydantic.dev/latest/api/type_adapter/) でラップできる型(dataclasses、リスト、TypedDict など)であればサポートしています。 ```python from pydantic import BaseModel @@ -66,11 +66,11 @@ agent = Agent( !!! note - `output_type` を渡すと、モデルに通常のプレーンテキスト応答の代わりに [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用するよう指示します。 + `output_type` を指定すると、モデルは通常のプレーンテキスト応答の代わりに [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用するよう指示されます。 ## ハンドオフ -ハンドオフは、エージェントが委任できるサブエージェントです。ハンドオフのリストを提供し、エージェントは関連する場合にそれらに委任することができます。これは、単一のタスクに優れたモジュール化された専門エージェントを編成する強力なパターンです。[handoffs](handoffs.md) ドキュメントで詳細をお読みください。 +ハンドオフは、エージェントが委任できるサブエージェントです。ハンドオフのリストを指定すると、エージェントは必要に応じてそれらに処理を委任できます。これは、単一タスクに特化したモジュール型のエージェントをオーケストレーションする強力なパターンです。詳細は [handoffs](handoffs.md) ドキュメントをご覧ください。 ```python from agents import Agent @@ -89,9 +89,9 @@ triage_agent = Agent( ) ``` -## 動的指示 +## 動的 instructions -ほとんどの場合、エージェントを作成する際に指示を提供できますが、関数を介して動的な指示を提供することもできます。この関数はエージェントとコンテキストを受け取り、プロンプトを返す必要があります。通常の関数と `async` 関数の両方が受け入れられます。 +多くの場合、エージェント作成時に instructions を指定できますが、関数を使って動的に instructions を提供することも可能です。この関数はエージェントと context を受け取り、プロンプトを返す必要があります。通常の関数と `async` 関数の両方が利用可能です。 ```python def dynamic_instructions( @@ -108,15 +108,15 @@ agent = Agent[UserContext]( ## ライフサイクルイベント(フック) -時には、エージェントのライフサイクルを観察したいことがあります。たとえば、イベントを記録したり、特定のイベントが発生したときにデータを事前取得したりすることができます。`hooks` プロパティを使用してエージェントのライフサイクルにフックすることができます。[`AgentHooks`][agents.lifecycle.AgentHooks] クラスをサブクラス化し、興味のあるメソッドをオーバーライドします。 +エージェントのライフサイクルを監視したい場合があります。たとえば、イベントを記録したり、特定のイベント発生時にデータを事前取得したりしたい場合です。`hooks` プロパティを使ってエージェントのライフサイクルにフックできます。[`AgentHooks`][agents.lifecycle.AgentHooks] クラスをサブクラス化し、関心のあるメソッドをオーバーライドしてください。 ## ガードレール -ガードレールを使用すると、エージェントの実行と並行してユーザー入力のチェック/検証を行うことができます。たとえば、ユーザーの入力を関連性でスクリーニングすることができます。[guardrails](guardrails.md) ドキュメントで詳細をお読みください。 +ガードレールを使うと、エージェントの実行と並行して user 入力のチェックやバリデーションを行えます。たとえば、user の入力が関連性のある内容かどうかをスクリーニングできます。詳細は [guardrails](guardrails.md) ドキュメントをご覧ください。 -## エージェントのクローン/コピー +## エージェントのクローン/コピー -エージェントの `clone()` メソッドを使用すると、エージェントを複製し、任意のプロパティを変更することができます。 +エージェントの `clone()` メソッドを使うことで、エージェントを複製し、任意のプロパティを変更できます。 ```python pirate_agent = Agent( @@ -133,15 +133,15 @@ robot_agent = pirate_agent.clone( ## ツール使用の強制 -ツールのリストを提供しても、LLM がツールを使用するとは限りません。[`ModelSettings.tool_choice`][agents.model_settings.ModelSettings.tool_choice] を設定することでツール使用を強制できます。有効な値は次のとおりです: +ツールのリストを指定しても、必ずしも LLM がツールを使用するとは限りません。[`ModelSettings.tool_choice`][agents.model_settings.ModelSettings.tool_choice] を設定することでツールの使用を強制できます。有効な値は以下の通りです。 -1. `auto`:LLM がツールを使用するかどうかを決定します。 -2. `required`:LLM がツールを使用する必要があります(ただし、どのツールを使用するかは賢く決定できます)。 -3. `none`:LLM がツールを使用しないことを要求します。 -4. 特定の文字列を設定する例:`my_tool`、特定のツールを使用することを要求します。 +1. `auto`:LLM がツールを使うかどうかを自動で判断します。 +2. `required`:LLM にツールの使用を必須とします(どのツールを使うかは賢く選択されます)。 +3. `none`:LLM にツールを _使わない_ ことを要求します。 +4. 特定の文字列(例:`my_tool`)を指定すると、その特定のツールの使用を必須とします。 !!! note - 無限ループを防ぐために、フレームワークはツール呼び出し後に `tool_choice` を自動的に "auto" にリセットします。この動作は [`agent.reset_tool_choice`][agents.agent.Agent.reset_tool_choice] で設定可能です。無限ループは、ツールの結果が LLM に送信され、その後 `tool_choice` によって別のツール呼び出しが生成されるために発生します。 + 無限ループを防ぐため、フレームワークはツール呼び出し後に自動的に `tool_choice` を "auto" にリセットします。この挙動は [`agent.reset_tool_choice`][agents.agent.Agent.reset_tool_choice] で設定可能です。無限ループは、ツールの execution results が LLM に送信され、`tool_choice` のために再度ツール呼び出しが発生し、これが繰り返されることで発生します。 - ツール呼び出し後にエージェントが完全に停止するようにしたい場合(自動モードで続行するのではなく)、[`Agent.tool_use_behavior="stop_on_first_tool"`] を設定することで、ツールの出力を最終応答として直接使用し、さらなる LLM 処理を行わないようにできます。 \ No newline at end of file + ツール呼び出し後にエージェントを完全に停止させたい場合(auto モードで継続させたくない場合)は、[`Agent.tool_use_behavior="stop_on_first_tool"`] を設定できます。これにより、ツールの出力がそのまま最終応答として使用され、以降の LLM 処理は行われません。 \ No newline at end of file diff --git a/docs/ja/config.md b/docs/ja/config.md index f8586e8a..c547a793 100644 --- a/docs/ja/config.md +++ b/docs/ja/config.md @@ -2,7 +2,7 @@ ## API キーとクライアント -デフォルトでは、SDK はインポートされるとすぐに LLM リクエストとトレーシングのために `OPENAI_API_KEY` 環境変数を探します。アプリが起動する前にその環境変数を設定できない場合は、[set_default_openai_key()][agents.set_default_openai_key] 関数を使用してキーを設定できます。 +デフォルトでは、SDK はインポート時に LLM リクエストやトレーシングのために `OPENAI_API_KEY` 環境変数を探します。アプリの起動前にこの環境変数を設定できない場合は、[set_default_openai_key()][agents.set_default_openai_key] 関数を使ってキーを設定できます。 ```python from agents import set_default_openai_key @@ -10,7 +10,7 @@ from agents import set_default_openai_key set_default_openai_key("sk-...") ``` -また、使用する OpenAI クライアントを設定することもできます。デフォルトでは、SDK は環境変数からの API キーまたは上記で設定したデフォルトキーを使用して `AsyncOpenAI` インスタンスを作成します。これを変更するには、[set_default_openai_client()][agents.set_default_openai_client] 関数を使用します。 +また、使用する OpenAI クライアントを設定することも可能です。デフォルトでは、SDK は環境変数または上記で設定したデフォルトキーを使って `AsyncOpenAI` インスタンスを作成します。これを変更したい場合は、[set_default_openai_client()][agents.set_default_openai_client] 関数を利用してください。 ```python from openai import AsyncOpenAI @@ -20,7 +20,7 @@ custom_client = AsyncOpenAI(base_url="...", api_key="...") set_default_openai_client(custom_client) ``` -最後に、使用する OpenAI API をカスタマイズすることもできます。デフォルトでは、OpenAI Responses API を使用します。これを Chat Completions API に変更するには、[set_default_openai_api()][agents.set_default_openai_api] 関数を使用します。 +さらに、使用する OpenAI API をカスタマイズすることもできます。デフォルトでは OpenAI Responses API を使用していますが、[set_default_openai_api()][agents.set_default_openai_api] 関数を使って Chat Completions API を利用するように上書きできます。 ```python from agents import set_default_openai_api @@ -30,7 +30,7 @@ set_default_openai_api("chat_completions") ## トレーシング -トレーシングはデフォルトで有効になっています。デフォルトでは、上記のセクションから OpenAI API キー(環境変数または設定したデフォルトキー)を使用します。トレーシングに使用する API キーを特定に設定するには、[`set_tracing_export_api_key`][agents.set_tracing_export_api_key] 関数を使用します。 +トレーシングはデフォルトで有効になっています。デフォルトでは、上記のセクションで説明した OpenAI API キー(環境変数または設定したデフォルトキー)を使用します。トレーシング専用の API キーを設定したい場合は、[`set_tracing_export_api_key`][agents.set_tracing_export_api_key] 関数を利用してください。 ```python from agents import set_tracing_export_api_key @@ -38,7 +38,7 @@ from agents import set_tracing_export_api_key set_tracing_export_api_key("sk-...") ``` -トレーシングを完全に無効にするには、[`set_tracing_disabled()`][agents.set_tracing_disabled] 関数を使用します。 +また、[`set_tracing_disabled()`][agents.set_tracing_disabled] 関数を使ってトレーシングを完全に無効化することもできます。 ```python from agents import set_tracing_disabled @@ -48,9 +48,9 @@ set_tracing_disabled(True) ## デバッグログ -SDK にはハンドラーが設定されていない 2 つの Python ロガーがあります。デフォルトでは、警告とエラーが `stdout` に送信されますが、他のログは抑制されます。 +SDK には、ハンドラーが設定されていない 2 つの Python ロガーがあります。デフォルトでは、警告やエラーは `stdout` に送信されますが、それ以外のログは抑制されます。 -詳細なログを有効にするには、[`enable_verbose_stdout_logging()`][agents.enable_verbose_stdout_logging] 関数を使用します。 +詳細なログ出力を有効にするには、[`enable_verbose_stdout_logging()`][agents.enable_verbose_stdout_logging] 関数を使用してください。 ```python from agents import enable_verbose_stdout_logging @@ -58,7 +58,7 @@ from agents import enable_verbose_stdout_logging enable_verbose_stdout_logging() ``` -また、ハンドラー、フィルター、フォーマッターなどを追加してログをカスタマイズすることもできます。詳細は [Python ロギングガイド](https://docs.python.org/3/howto/logging.html) を参照してください。 +また、ハンドラーやフィルター、フォーマッターなどを追加してログをカスタマイズすることも可能です。詳細は [Python ロギングガイド](https://docs.python.org/3/howto/logging.html) をご覧ください。 ```python import logging @@ -77,17 +77,17 @@ logger.setLevel(logging.WARNING) logger.addHandler(logging.StreamHandler()) ``` -### ログ内の機密データ +### ログ内の機微なデータ -特定のログには機密データ(たとえば、ユーザーデータ)が含まれる場合があります。このデータのログ記録を無効にしたい場合は、次の環境変数を設定します。 +一部のログには機微なデータ(たとえば ユーザー データ)が含まれる場合があります。これらのデータのログ出力を無効にしたい場合は、以下の環境変数を設定してください。 -LLM の入力と出力のログ記録を無効にするには: +LLM の入力および出力のログ出力を無効にするには: ```bash export OPENAI_AGENTS_DONT_LOG_MODEL_DATA=1 ``` -ツールの入力と出力のログ記録を無効にするには: +ツールの入力および出力のログ出力を無効にするには: ```bash export OPENAI_AGENTS_DONT_LOG_TOOL_DATA=1 diff --git a/docs/ja/context.md b/docs/ja/context.md index 3d3c426e..4240ceee 100644 --- a/docs/ja/context.md +++ b/docs/ja/context.md @@ -1,29 +1,29 @@ # コンテキスト管理 -コンテキストは多義的な用語です。考慮すべき主なコンテキストのクラスは2つあります。 +コンテキストは多義的な用語です。主に関心を持つべきコンテキストには、次の 2 つの大きなクラスがあります。 -1. コードにローカルで利用可能なコンテキスト: これは、ツール関数が実行されるときや、`on_handoff` のようなコールバック、ライフサイクルフックなどで必要になるデータや依存関係です。 -2. LLM に利用可能なコンテキスト: これは、LLM が応答を生成するときに参照するデータです。 +1. コード内でローカルに利用可能なコンテキスト:これは、ツール関数の実行時や `on_handoff` のようなコールバック、ライフサイクルフックなどで必要となるデータや依存関係です。 +2. LLM に利用可能なコンテキスト:これは、LLM がレスポンスを生成する際に参照できるデータです。 ## ローカルコンテキスト -これは [`RunContextWrapper`][agents.run_context.RunContextWrapper] クラスとその中の [`context`][agents.run_context.RunContextWrapper.context] プロパティを通じて表現されます。動作の仕組みは次の通りです。 +これは [`RunContextWrapper`][agents.run_context.RunContextWrapper] クラスおよびその中の [`context`][agents.run_context.RunContextWrapper.context] プロパティによって表現されます。仕組みは以下の通りです。 -1. 任意の Python オブジェクトを作成します。一般的なパターンは、データクラスや Pydantic オブジェクトを使用することです。 -2. そのオブジェクトを様々な実行メソッドに渡します(例: `Runner.run(..., **context=whatever**)`)。 -3. すべてのツール呼び出し、ライフサイクルフックなどにラッパーオブジェクト `RunContextWrapper[T]` が渡されます。ここで `T` はコンテキストオブジェクトの型を表し、`wrapper.context` を通じてアクセスできます。 +1. 任意の Python オブジェクトを作成します。一般的なパターンとしては、dataclass や Pydantic オブジェクトを使います。 +2. そのオブジェクトを各種 run メソッド(例:`Runner.run(..., **context=whatever**))`)に渡します。 +3. すべてのツール呼び出しやライフサイクルフックなどには、ラッパーオブジェクト `RunContextWrapper[T]` が渡されます。ここで `T` はコンテキストオブジェクトの型を表し、`wrapper.context` からアクセスできます。 -**最も重要な**点は、特定のエージェント実行において、すべてのエージェント、ツール関数、ライフサイクルなどが同じ _型_ のコンテキストを使用しなければならないことです。 +**最も重要**な注意点:特定のエージェント実行において、すべてのエージェント、ツール関数、ライフサイクルなどは、同じ _型_ のコンテキストを使用する必要があります。 -コンテキストは以下のような用途に使用できます。 +コンテキストは以下のような用途で利用できます。 -- 実行のためのコンテキストデータ(例: ユーザー名/uid やその他のユーザー情報) -- 依存関係(例: ロガーオブジェクト、データフェッチャーなど) -- ヘルパー関数 +- 実行時のコンテキストデータ(例:ユーザー名/uid やユーザーに関するその他の情報など) +- 依存関係(例:ロガーオブジェクト、データフェッチャーなど) +- ヘルパー関数 !!! danger "注意" - コンテキストオブジェクトは **LLM に送信されません**。これは純粋にローカルなオブジェクトであり、読み書きやメソッドの呼び出しが可能です。 + コンテキストオブジェクトは **LLM には送信されません**。これは純粋にローカルなオブジェクトであり、読み書きやメソッド呼び出しが可能です。 ```python import asyncio @@ -61,17 +61,17 @@ if __name__ == "__main__": asyncio.run(main()) ``` -1. これはコンテキストオブジェクトです。ここではデータクラスを使用していますが、任意の型を使用できます。 -2. これはツールです。`RunContextWrapper[UserInfo]` を受け取ることがわかります。ツールの実装はコンテキストから読み取ります。 -3. エージェントをジェネリック `UserInfo` でマークし、型チェッカーがエラーを検出できるようにします(例えば、異なるコンテキスト型を取るツールを渡そうとした場合)。 +1. これはコンテキストオブジェクトです。ここでは dataclass を使用していますが、任意の型を利用できます。 +2. これはツールです。`RunContextWrapper[UserInfo]` を受け取っていることが分かります。ツールの実装はコンテキストから値を読み取ります。 +3. エージェントにはジェネリック型 `UserInfo` を指定しています。これにより、型チェッカーがエラーを検出できます(例えば、異なるコンテキスト型を受け取るツールを渡そうとした場合など)。 4. コンテキストは `run` 関数に渡されます。 5. エージェントは正しくツールを呼び出し、年齢を取得します。 -## エージェント/LLM コンテキスト +## エージェント/LLM コンテキスト -LLM が呼び出されるとき、**唯一** 参照できるデータは会話履歴からのものです。新しいデータを LLM に利用可能にしたい場合、それを履歴に含める方法で行う必要があります。これにはいくつかの方法があります。 +LLM が呼び出される際、**唯一** 参照できるデータは会話履歴からのものです。つまり、LLM に新しいデータを利用させたい場合は、そのデータを履歴に含める必要があります。これを実現する方法はいくつかあります。 -1. エージェントの `instructions` に追加します。これは「システムプロンプト」または「開発者メッセージ」とも呼ばれます。システムプロンプトは静的な文字列でも、コンテキストを受け取って文字列を出力する動的な関数でもかまいません。常に有用な情報(例: ユーザーの名前や現在の日付)に対して一般的な戦術です。 -2. `Runner.run` 関数を呼び出す際に `input` に追加します。これは `instructions` 戦術に似ていますが、[chain of command](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command) の下位にメッセージを持つことができます。 -3. 関数ツールを通じて公開します。これはオンデマンドのコンテキストに有用です。LLM がデータを必要とするときにツールを呼び出してそのデータを取得できます。 -4. リトリーバルや Web 検索を使用します。これらはファイルやデータベース(リトリーバル)、または Web(Web 検索)から関連データを取得できる特別なツールです。関連するコンテキストデータで応答を「グラウンド」するのに有用です。 \ No newline at end of file +1. エージェントの `instructions` に追加する。この方法は「システムプロンプト」や「開発者メッセージ」とも呼ばれます。システムプロンプトは静的な文字列でも、コンテキストを受け取って文字列を出力する動的な関数でも構いません。たとえば、ユーザー名や現在の日付など、常に有用な情報に適しています。 +2. `Runner.run` 関数を呼び出す際に `input` に追加する。この方法は `instructions` と似ていますが、[chain of command](https://cdn.openai.com/spec/model-spec-2024-05-08.html#follow-the-chain-of-command) の下位メッセージとして追加できます。 +3. 関数ツールを通じて公開する。この方法は _オンデマンド_ のコンテキストに適しています。LLM が必要なタイミングでツールを呼び出し、データを取得できます。 +4. リトリーバルや Web 検索を利用する。これらはファイルやデータベース(リトリーバル)、または Web(Web 検索)から関連データを取得できる特別なツールです。関連するコンテキストデータに基づいたレスポンスを「グラウンディング」するのに役立ちます。 \ No newline at end of file diff --git a/docs/ja/examples.md b/docs/ja/examples.md index 21a00f67..c2393c8e 100644 --- a/docs/ja/examples.md +++ b/docs/ja/examples.md @@ -1,40 +1,40 @@ -# サンプルコード +# コード例 -SDK のさまざまなサンプル実装は、[リポジトリ](https://github.com/openai/openai-agents-python/tree/main/examples)のサンプルコードセクションで確認できます。これらのサンプルコードは、異なるパターンや機能を示すいくつかのカテゴリーに整理されています。 +SDK のさまざまなサンプル実装については、[リポジトリ](https://github.com/openai/openai-agents-python/tree/main/examples) のコード例セクションをご覧ください。これらのコード例は、異なるパターンや機能を示すいくつかのカテゴリーに整理されています。 ## カテゴリー -- **[agent_patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns):** - このカテゴリーの例は、一般的なエージェント設計パターンを示しています。例えば、 +- **[agent_patterns](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns):** + このカテゴリーのコード例では、よく使われるエージェント設計パターンを紹介しています。 - - 決定論的ワークフロー + - 決定論的なワークフロー - ツールとしてのエージェント - エージェントの並列実行 -- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):** - これらの例は、SDK の基本的な機能を紹介しています。例えば、 +- **[basic](https://github.com/openai/openai-agents-python/tree/main/examples/basic):** + これらのコード例では、SDK の基本的な機能を紹介しています。 - 動的なシステムプロンプト - ストリーミング出力 - ライフサイクルイベント -- **[tool examples](https://github.com/openai/openai-agents-python/tree/main/examples/tools):** - Web 検索やファイル検索などの OpenAI がホストするツールを実装し、それらをエージェントに統合する方法を学びます。 +- **[tool examples](https://github.com/openai/openai-agents-python/tree/main/examples/tools):** + OpenAI がホストするツール(Web 検索やファイル検索など)の実装方法や、それらをエージェントに統合する方法を学べます。 -- **[model providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):** - OpenAI 以外のモデルを SDK で使用する方法を探ります。 +- **[model providers](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers):** + OpenAI 以外のモデルを SDK で利用する方法を紹介しています。 -- **[handoffs](https://github.com/openai/openai-agents-python/tree/main/examples/handoffs):** - エージェントのハンドオフの実用的な例を見てみましょう。 +- **[handoffs](https://github.com/openai/openai-agents-python/tree/main/examples/handoffs):** + エージェントのハンドオフの実践的なコード例をご覧いただけます。 -- **[mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp):** - MCP を使用してエージェントを構築する方法を学びます。 +- **[mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp):** + Model context protocol (MCP) を使ったエージェントの構築方法を学べます。 -- **[customer_service](https://github.com/openai/openai-agents-python/tree/main/examples/customer_service)** と **[research_bot](https://github.com/openai/openai-agents-python/tree/main/examples/research_bot):** - 実際のアプリケーションを示す、さらに詳細な2つの例 +- **[customer_service](https://github.com/openai/openai-agents-python/tree/main/examples/customer_service)** および **[research_bot](https://github.com/openai/openai-agents-python/tree/main/examples/research_bot):** + 実際のユースケースを示す、より発展的な 2 つのコード例です。 - - **customer_service**: 航空会社向けのカスタマーサービスシステムの例。 + - **customer_service**: 航空会社向けカスタマーサービスシステムの例。 - **research_bot**: シンプルなディープリサーチクローン。 -- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):** - TTS と STT モデルを使用した音声エージェントの例を見てみましょう。 \ No newline at end of file +- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):** + TTS および STT モデルを利用した音声エージェントのコード例をご覧いただけます。 \ No newline at end of file diff --git a/docs/ja/guardrails.md b/docs/ja/guardrails.md index da38d432..2525f8c2 100644 --- a/docs/ja/guardrails.md +++ b/docs/ja/guardrails.md @@ -1,43 +1,43 @@ # ガードレール -ガードレールはエージェントと _並行して_ 実行され、ユーザー入力のチェックと検証を可能にします。例えば、非常に賢い(したがって遅く/高価な)モデルを使用して顧客のリクエストを支援するエージェントがあるとします。悪意のあるユーザーがモデルに数学の宿題を手伝わせるようなことは避けたいでしょう。そこで、速く/安価なモデルでガードレールを実行できます。ガードレールが悪意のある使用を検出した場合、即座にエラーを発生させ、高価なモデルの実行を停止し、時間とお金を節約できます。 +ガードレールは、エージェントと _並行して_ 実行され、ユーザー入力のチェックやバリデーションを行うことができます。例えば、非常に賢い(そのため遅くて高価な)モデルを使ってカスタマーリクエストに対応するエージェントがあるとします。悪意のあるユーザーがモデルに数学の宿題を手伝わせるようなリクエストを送ることは避けたいでしょう。そこで、ガードレールを高速かつ安価なモデルで実行できます。ガードレールが悪意のある利用を検知した場合、即座にエラーを発生させ、高価なモデルの実行を止めて時間やコストを節約できます。 -ガードレールには2種類あります: +ガードレールには 2 種類あります: -1. 入力ガードレールは初期のユーザー入力に対して実行されます -2. 出力ガードレールは最終的なエージェントの出力に対して実行されます +1. 入力ガードレール:最初のユーザー入力に対して実行されます +2. 出力ガードレール:最終的なエージェント出力に対して実行されます ## 入力ガードレール -入力ガードレールは3つのステップで実行されます: +入力ガードレールは 3 ステップで実行されます: -1. まず、ガードレールはエージェントに渡されたのと同じ入力を受け取ります。 -2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を生成し、それが[`InputGuardrailResult`][agents.guardrail.InputGuardrailResult]でラップされます。 -3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered]が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered]例外が発生し、ユーザーに適切に応答したり、例外を処理したりできます。 +1. まず、ガードレールはエージェントに渡されたものと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`InputGuardrailResult`][agents.guardrail.InputGuardrailResult] でラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な対応や例外処理が可能です。 !!! Note - 入力ガードレールはユーザー入力に対して実行されることを意図しているため、エージェントのガードレールはエージェントが*最初の*エージェントである場合にのみ実行されます。なぜ `guardrails` プロパティがエージェントにあり、`Runner.run` に渡されないのか疑問に思うかもしれません。それは、ガードレールが実際のエージェントに関連している傾向があるためです。異なるエージェントには異なるガードレールを実行するので、コードを一緒に配置することは可読性に役立ちます。 + 入力ガードレールはユーザー入力に対して実行されることを想定しているため、エージェントのガードレールは *最初* のエージェントでのみ実行されます。「なぜ `guardrails` プロパティがエージェントにあり、`Runner.run` に渡さないのか?」と疑問に思うかもしれません。これは、ガードレールが実際のエージェントに関連することが多いためです。異なるエージェントごとに異なるガードレールを実行するため、コードを同じ場所にまとめておくと可読性が向上します。 ## 出力ガードレール -出力ガードレールは3つのステップで実行されます: +出力ガードレールも 3 ステップで実行されます: -1. まず、ガードレールはエージェントに渡されたのと同じ入力を受け取ります。 -2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を生成し、それが[`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult]でラップされます。 -3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered]が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]例外が発生し、ユーザーに適切に応答したり、例外を処理したりできます。 +1. まず、ガードレールはエージェントに渡されたものと同じ入力を受け取ります。 +2. 次に、ガードレール関数が実行され、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を生成し、それが [`OutputGuardrailResult`][agents.guardrail.OutputGuardrailResult] でラップされます。 +3. 最後に、[`.tripwire_triggered`][agents.guardrail.GuardrailFunctionOutput.tripwire_triggered] が true かどうかを確認します。true の場合、[`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] 例外が発生し、ユーザーへの適切な対応や例外処理が可能です。 !!! Note - 出力ガードレールは最終的なエージェントの出力に対して実行されることを意図しているため、エージェントのガードレールはエージェントが*最後の*エージェントである場合にのみ実行されます。入力ガードレールと同様に、ガードレールが実際のエージェントに関連している傾向があるため、コードを一緒に配置することは可読性に役立ちます。 + 出力ガードレールは最終的なエージェント出力に対して実行されることを想定しているため、エージェントのガードレールは *最後* のエージェントでのみ実行されます。入力ガードレールと同様に、ガードレールが実際のエージェントに関連することが多いため、コードを同じ場所にまとめておくと可読性が向上します。 ## トリップワイヤー -入力または出力がガードレールに失敗した場合、ガードレールはトリップワイヤーでこれを知らせることができます。トリップワイヤーがトリガーされたガードレールを確認するとすぐに、`{Input,Output}GuardrailTripwireTriggered`例外を即座に発生させ、エージェントの実行を停止します。 +入力または出力がガードレールに失敗した場合、ガードレールはトリップワイヤーでこれを通知できます。トリップワイヤーが発動したガードレールを検知した時点で、即座に `{Input,Output}GuardrailTripwireTriggered` 例外を発生させ、エージェントの実行を停止します。 ## ガードレールの実装 -入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput]を返す関数を提供する必要があります。この例では、エージェントを内部で実行することでこれを行います。 +入力を受け取り、[`GuardrailFunctionOutput`][agents.guardrail.GuardrailFunctionOutput] を返す関数を用意する必要があります。この例では、内部でエージェントを実行することでこれを実現します。 ```python from pydantic import BaseModel @@ -90,8 +90,8 @@ async def main(): print("Math homework guardrail tripped") ``` -1. このエージェントをガードレール関数で使用します。 -2. これはエージェントの入力/コンテキストを受け取り、結果を返すガードレール関数です。 +1. このエージェントをガードレール関数内で使用します。 +2. これはエージェントの入力やコンテキストを受け取り、結果を返すガードレール関数です。 3. ガードレールの結果に追加情報を含めることができます。 4. これはワークフローを定義する実際のエージェントです。 @@ -148,7 +148,7 @@ async def main(): print("Math output guardrail tripped") ``` -1. これは実際のエージェントの出力タイプです。 -2. これはガードレールの出力タイプです。 +1. これは実際のエージェントの出力型です。 +2. これはガードレールの出力型です。 3. これはエージェントの出力を受け取り、結果を返すガードレール関数です。 4. これはワークフローを定義する実際のエージェントです。 \ No newline at end of file diff --git a/docs/ja/handoffs.md b/docs/ja/handoffs.md index 575195b1..ae3b8b12 100644 --- a/docs/ja/handoffs.md +++ b/docs/ja/handoffs.md @@ -1,18 +1,18 @@ # ハンドオフ -ハンドオフは、エージェントがタスクを他のエージェントに委任することを可能にします。これは、異なるエージェントが異なる分野に特化しているシナリオで特に有用です。例えば、カスタマーサポートアプリでは、注文状況、返金、FAQ などのタスクをそれぞれ専門に扱うエージェントがいるかもしれません。 +ハンドオフは、エージェントが他のエージェントにタスクを委任できる仕組みです。これは、異なるエージェントがそれぞれ異なる分野に特化しているシナリオで特に有用です。たとえば、カスタマーサポートアプリでは、注文状況、返金、FAQ などのタスクをそれぞれ専門に扱うエージェントが存在する場合があります。 -ハンドオフは LLM にとってツールとして表現されます。したがって、`Refund Agent` という名前のエージェントへのハンドオフがある場合、ツールは `transfer_to_refund_agent` と呼ばれます。 +ハンドオフは LLM からはツールとして認識されます。たとえば、`Refund Agent` という名前のエージェントへのハンドオフがある場合、そのツール名は `transfer_to_refund_agent` となります。 ## ハンドオフの作成 -すべてのエージェントには [`handoffs`][agents.agent.Agent.handoffs] パラメーターがあり、これは `Agent` を直接取るか、ハンドオフをカスタマイズする `Handoff` オブジェクトを取ることができます。 +すべてのエージェントは [`handoffs`][agents.agent.Agent.handoffs] パラメーターを持っており、これは直接 `Agent` を指定することも、ハンドオフをカスタマイズする `Handoff` オブジェクトを指定することもできます。 -Agents SDK が提供する [`handoff()`][agents.handoffs.handoff] 関数を使用してハンドオフを作成できます。この関数を使用すると、ハンドオフ先のエージェントを指定し、オプションでオーバーライドや入力フィルターを設定できます。 +Agents SDK で提供されている [`handoff()`][agents.handoffs.handoff] 関数を使ってハンドオフを作成できます。この関数では、ハンドオフ先のエージェントや、オプションのオーバーライドや入力フィルターを指定できます。 ### 基本的な使い方 -簡単なハンドオフを作成する方法は次のとおりです。 +シンプルなハンドオフの作成方法は以下の通りです。 ```python from agents import Agent, handoff @@ -24,18 +24,18 @@ refund_agent = Agent(name="Refund agent") triage_agent = Agent(name="Triage agent", handoffs=[billing_agent, handoff(refund_agent)]) ``` -1. エージェントを直接使用することも(`billing_agent` のように)、`handoff()` 関数を使用することもできます。 +1. エージェントを直接指定する(例:`billing_agent`)ことも、`handoff()` 関数を使うこともできます。 ### `handoff()` 関数によるハンドオフのカスタマイズ -[`handoff()`][agents.handoffs.handoff] 関数を使用すると、さまざまなカスタマイズが可能です。 +[`handoff()`][agents.handoffs.handoff] 関数では、さまざまなカスタマイズが可能です。 - `agent`: ハンドオフ先のエージェントです。 -- `tool_name_override`: デフォルトでは `Handoff.default_tool_name()` 関数が使用され、`transfer_to_` に解決されます。これをオーバーライドできます。 -- `tool_description_override`: `Handoff.default_tool_description()` からのデフォルトのツール説明をオーバーライドします。 -- `on_handoff`: ハンドオフが呼び出されたときに実行されるコールバック関数です。ハンドオフが呼び出されるとすぐにデータ取得を開始するなどに役立ちます。この関数はエージェントコンテキストを受け取り、オプションで LLM が生成した入力も受け取ることができます。入力データは `input_type` パラメーターで制御されます。 -- `input_type`: ハンドオフが期待する入力のタイプ(オプション)。 -- `input_filter`: 次のエージェントが受け取る入力をフィルタリングできます。詳細は以下を参照してください。 +- `tool_name_override`: デフォルトでは `Handoff.default_tool_name()` 関数が使われ、`transfer_to_` となります。これを上書きできます。 +- `tool_description_override`: デフォルトのツール説明(`Handoff.default_tool_description()`)を上書きできます。 +- `on_handoff`: ハンドオフが呼び出されたときに実行されるコールバック関数です。たとえば、ハンドオフが呼び出されたタイミングでデータ取得を開始するなどに便利です。この関数はエージェントコンテキストを受け取り、オプションで LLM が生成した入力も受け取れます。入力データは `input_type` パラメーターで制御します。 +- `input_type`: ハンドオフで期待される入力の型(オプション)です。 +- `input_filter`: 次のエージェントが受け取る入力をフィルタリングできます。詳細は下記をご覧ください。 ```python from agents import Agent, handoff, RunContextWrapper @@ -55,7 +55,7 @@ handoff_obj = handoff( ## ハンドオフ入力 -特定の状況では、LLM がハンドオフを呼び出す際にデータを提供することを望む場合があります。例えば、「エスカレーションエージェント」へのハンドオフを想像してください。理由を提供してログに記録したいかもしれません。 +状況によっては、LLM にハンドオフ時に何らかのデータを提供してほしい場合があります。たとえば、「エスカレーションエージェント」へのハンドオフを考えてみましょう。この場合、理由を提供して記録できるようにしたいことがあります。 ```python from pydantic import BaseModel @@ -79,9 +79,9 @@ handoff_obj = handoff( ## 入力フィルター -ハンドオフが発生すると、新しいエージェントが会話を引き継ぎ、以前の会話履歴全体を見ることができます。これを変更したい場合は、[`input_filter`][agents.handoffs.Handoff.input_filter] を設定できます。入力フィルターは、既存の入力を [`HandoffInputData`][agents.handoffs.HandoffInputData] 経由で受け取り、新しい `HandoffInputData` を返す必要がある関数です。 +ハンドオフが発生すると、新しいエージェントが会話を引き継ぎ、これまでの会話履歴全体を見ることができます。これを変更したい場合は、[`input_filter`][agents.handoffs.Handoff.input_filter] を設定できます。入力フィルターは、[`HandoffInputData`][agents.handoffs.HandoffInputData] を受け取り、新しい `HandoffInputData` を返す関数です。 -一般的なパターン(例えば、履歴からすべてのツール呼び出しを削除する)が [`agents.extensions.handoff_filters`][] に実装されています。 +よくあるパターン(たとえば履歴からすべてのツール呼び出しを削除するなど)は、[`agents.extensions.handoff_filters`][] で実装されています。 ```python from agents import Agent, handoff @@ -99,7 +99,7 @@ handoff_obj = handoff( ## 推奨プロンプト -LLM がハンドオフを正しく理解するために、エージェントにハンドオフに関する情報を含めることをお勧めします。[`agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX`][] に推奨されるプレフィックスがあります。または、[`agents.extensions.handoff_prompt.prompt_with_handoff_instructions`][] を呼び出して、プロンプトに推奨データを自動的に追加できます。 +LLM がハンドオフを正しく理解できるようにするため、エージェントにハンドオフに関する情報を含めることを推奨します。[`agents.extensions.handoff_prompt.RECOMMENDED_PROMPT_PREFIX`][] で推奨されるプレフィックスを利用するか、[`agents.extensions.handoff_prompt.prompt_with_handoff_instructions`][] を呼び出して、推奨データをプロンプトに自動追加できます。 ```python from agents import Agent diff --git a/docs/ja/index.md b/docs/ja/index.md index f36de0ac..3b306464 100644 --- a/docs/ja/index.md +++ b/docs/ja/index.md @@ -1,28 +1,28 @@ -# OpenAI エージェント SDK +# OpenAI Agents SDK -[OpenAI エージェント SDK](https://github.com/openai/openai-agents-python) は、軽量で使いやすいパッケージでエージェント AI アプリを構築することを可能にします。これは、以前のエージェントの実験である [Swarm](https://github.com/openai/swarm/tree/main) のプロダクション対応のアップグレード版です。エージェント SDK には、非常に少ない基本コンポーネントがあります。 +[OpenAI Agents SDK](https://github.com/openai/openai-agents-python) は、非常に少ない抽象化で、軽量かつ使いやすいパッケージで エージェント 型 AI アプリを構築できる SDK です。これは、以前のエージェント向け実験プロジェクト [Swarm](https://github.com/openai/swarm/tree/main) の本番運用向けアップグレード版です。Agents SDK には、非常に少数の基本コンポーネントが含まれています。 -- **エージェント**: instructions と tools を備えた LLM -- **ハンドオフ**: エージェントが特定のタスクを他のエージェントに委任することを可能にします -- **ガードレール**: エージェントへの入力を検証することを可能にします +- **エージェント**: instructions と tools を備えた LLM +- **ハンドオフ**:特定のタスクを他のエージェントに委任できる仕組み +- **ガードレール**:エージェントへの入力を検証できる仕組み -これらの基本コンポーネントは Python と組み合わせることで、ツールとエージェント間の複雑な関係を表現するのに十分な強力さを持ち、急な学習曲線なしで実際のアプリケーションを構築することができます。さらに、SDK には組み込みの **トレーシング** があり、エージェントのフローを視覚化してデバッグし、評価し、さらにはアプリケーション用にモデルを微調整することができます。 +Python と組み合わせることで、これらの基本コンポーネントは tools と エージェント 間の複雑な関係を表現でき、急な学習コストなしに実用的なアプリケーションを構築できます。さらに、SDK には組み込みの **トレーシング** 機能があり、エージェント フローの可視化やデバッグ、評価、さらにはアプリケーション向けモデルのファインチューニングも可能です。 -## なぜエージェント SDK を使うのか +## なぜ Agents SDK を使うのか SDK には 2 つの設計原則があります。 -1. 使用する価値があるだけの機能を持ち、学習が迅速になるように基本コンポーネントを少なくする。 -2. すぐに使えるが、何が起こるかを正確にカスタマイズできる。 +1. 使う価値のある十分な機能を持ちつつ、学習が容易なほど少ない基本コンポーネントで構成されていること。 +2. すぐに使い始められるが、動作を細かくカスタマイズできること。 -SDK の主な機能は次のとおりです。 +SDK の主な特徴は以下の通りです。 -- エージェントループ: ツールの呼び出し、LLM への結果の送信、LLM が完了するまでのループを処理する組み込みのエージェントループ。 -- Python ファースト: 新しい抽象化を学ぶ必要なく、組み込みの言語機能を使用してエージェントを編成し、連鎖させる。 -- ハンドオフ: 複数のエージェント間で調整し、委任するための強力な機能。 -- ガードレール: エージェントと並行して入力検証とチェックを実行し、チェックが失敗した場合は早期に中断。 -- 関数ツール: 任意の Python 関数をツールに変換し、自動スキーマ生成と Pydantic による検証を行う。 -- トレーシング: ワークフローを視覚化、デバッグ、監視するための組み込みのトレーシング、および OpenAI の評価、微調整、蒸留ツールを使用。 +- エージェントループ: tools の呼び出し、LLM への実行結果の送信、LLM が完了するまでのループ処理を自動で行います。 +- Python ファースト:新しい抽象化を学ぶ必要なく、Python の言語機能でエージェントのオーケストレーションや連携が可能です。 +- ハンドオフ:複数のエージェント間での調整や委任を実現する強力な機能です。 +- ガードレール:エージェントと並行して入力検証やチェックを実行し、チェックに失敗した場合は早期に処理を中断します。 +- 関数ツール:任意の Python 関数を自動でスキーマ生成・Pydantic ベースのバリデーション付きツールに変換できます。 +- トレーシング:組み込みのトレーシングでワークフローの可視化・デバッグ・モニタリングができ、OpenAI の評価・ファインチューニング・蒸留ツールも利用可能です。 ## インストール @@ -30,7 +30,7 @@ SDK の主な機能は次のとおりです。 pip install openai-agents ``` -## Hello World の例 +## Hello World サンプル ```python from agents import Agent, Runner @@ -45,7 +45,7 @@ print(result.final_output) # Infinite loop's dance. ``` -(_これを実行する場合は、`OPENAI_API_KEY` 環境変数を設定してください_) +(_実行する場合は、`OPENAI_API_KEY` 環境変数を設定してください_) ```bash export OPENAI_API_KEY=sk-... diff --git a/docs/ja/mcp.md b/docs/ja/mcp.md index 057fe188..d93252fb 100644 --- a/docs/ja/mcp.md +++ b/docs/ja/mcp.md @@ -1,21 +1,21 @@ # Model context protocol (MCP) -[Model context protocol](https://modelcontextprotocol.io/introduction) (別名 MCP) は、LLM にツールとコンテキストを提供する方法です。MCP ドキュメントからの引用: +[Model context protocol](https://modelcontextprotocol.io/introduction)(通称 MCP)は、 LLM にツールやコンテキストを提供するための方法です。MCP ドキュメントからの引用です: -> MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP を AI アプリケーションのための USB-C ポートのように考えてください。USB-C がデバイスをさまざまな周辺機器やアクセサリーに接続する標準化された方法を提供するのと同様に、MCP は AI モデルをさまざまなデータソースやツールに接続する標準化された方法を提供します。 +> MCP は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープンプロトコルです。MCP を AI アプリケーションのための USB-C ポートのようなものと考えてください。USB-C がさまざまな周辺機器やアクセサリにデバイスを接続する標準的な方法を提供するのと同様に、MCP は AI モデルをさまざまなデータソースやツールに接続する標準的な方法を提供します。 -エージェント SDK は MCP をサポートしています。これにより、エージェントにツールを提供するために幅広い MCP サーバーを使用できます。 +Agents SDK は MCP をサポートしています。これにより、幅広い MCP サーバーを利用して、エージェントにツールを提供することができます。 ## MCP サーバー -現在、MCP 仕様は使用するトランスポートメカニズムに基づいて2種類のサーバーを定義しています: +現在、MCP 仕様では、使用するトランスポートメカニズムに基づいて 2 種類のサーバーが定義されています: -1. **stdio** サーバーは、アプリケーションのサブプロセスとして実行されます。これらは「ローカルで」実行されると考えることができます。 +1. **stdio** サーバーは、アプリケーションのサブプロセスとして実行されます。ローカルで実行されるものと考えることができます。 2. **HTTP over SSE** サーバーはリモートで実行されます。URL を介して接続します。 -これらのサーバーに接続するには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用できます。 +これらのサーバーに接続するには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] および [`MCPServerSse`][agents.mcp.server.MCPServerSse] クラスを使用できます。 -例えば、[公式 MCP ファイルシステムサーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem) を使用する方法は次のとおりです。 +例えば、[公式 MCP ファイルシステムサーバー](https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem) を使用する場合は、次のようになります。 ```python async with MCPServerStdio( @@ -27,9 +27,9 @@ async with MCPServerStdio( tools = await server.list_tools() ``` -## MCP サーバーの使用 +## MCP サーバーの利用 -MCP サーバーはエージェントに追加できます。エージェント SDK は、エージェントが実行されるたびに MCP サーバーで `list_tools()` を呼び出します。これにより、LLM は MCP サーバーのツールを認識します。LLM が MCP サーバーのツールを呼び出すと、SDK はそのサーバーで `call_tool()` を呼び出します。 +MCP サーバーはエージェントに追加できます。Agents SDK は、エージェントが実行されるたびに MCP サーバーの `list_tools()` を呼び出します。これにより、LLM は MCP サーバーのツールを認識できるようになります。LLM が MCP サーバーのツールを呼び出すと、SDK はそのサーバーの `call_tool()` を呼び出します。 ```python @@ -40,21 +40,21 @@ agent=Agent( ) ``` -## キャッシング +## キャッシュ -エージェントが実行されるたびに、MCP サーバーで `list_tools()` を呼び出します。これは、特にサーバーがリモートサーバーの場合、レイテンシーの影響を受ける可能性があります。ツールのリストを自動的にキャッシュするには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] と [`MCPServerSse`][agents.mcp.server.MCPServerSse] に `cache_tools_list=True` を渡すことができます。ツールリストが変更されないことが確実な場合にのみこれを行うべきです。 +エージェントが実行されるたびに、MCP サーバーの `list_tools()` が呼び出されます。特にサーバーがリモートの場合、これはレイテンシの原因となることがあります。ツールリストを自動的にキャッシュするには、[`MCPServerStdio`][agents.mcp.server.MCPServerStdio] および [`MCPServerSse`][agents.mcp.server.MCPServerSse] の両方に `cache_tools_list=True` を渡すことができます。ツールリストが変更されないことが確実な場合のみ、この設定を行ってください。 -キャッシュを無効にしたい場合は、サーバーで `invalidate_tools_cache()` を呼び出すことができます。 +キャッシュを無効化したい場合は、サーバーで `invalidate_tools_cache()` を呼び出すことができます。 -## エンドツーエンドの例 +## エンドツーエンドの code examples -[examples/mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp) で完全な動作例を確認してください。 +[examples/mcp](https://github.com/openai/openai-agents-python/tree/main/examples/mcp) で、完全な動作 code examples をご覧いただけます。 ## トレーシング -[トレーシング](./tracing.md) は、MCP 操作を自動的にキャプチャします。これには以下が含まれます: +[トレーシング](../tracing.md) は、以下を含む MCP の操作を自動的に記録します: -1. ツールをリストするための MCP サーバーへの呼び出し +1. MCP サーバーへのツールリスト取得の呼び出し 2. 関数呼び出しに関する MCP 関連情報 -![MCP Tracing Screenshot](../assets/images/mcp-tracing.jpg) \ No newline at end of file +![MCP トレーシングのスクリーンショット](../assets/images/mcp-tracing.jpg) \ No newline at end of file diff --git a/docs/ja/models.md b/docs/ja/models.md index 3d216ac3..5a76d60e 100644 --- a/docs/ja/models.md +++ b/docs/ja/models.md @@ -1,21 +1,21 @@ # モデル -Agents SDK は、OpenAI モデルを次の 2 つの形式でサポートしています。 +Agents SDK には、OpenAI モデルの 2 種類のサポートが標準で用意されています。 -- **推奨**: 新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使用して OpenAI API を呼び出す [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel]。 -- [Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使用して OpenAI API を呼び出す [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel]。 +- **推奨**: [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] は、新しい [Responses API](https://platform.openai.com/docs/api-reference/responses) を使って OpenAI API を呼び出します。 +- [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] は、[Chat Completions API](https://platform.openai.com/docs/api-reference/chat) を使って OpenAI API を呼び出します。 ## モデルの組み合わせ -1 つのワークフロー内で、各エージェントに異なるモデルを使用したい場合があります。たとえば、トリアージには小さくて高速なモデルを使用し、複雑なタスクにはより大きくて高機能なモデルを使用することができます。[`Agent`][agents.Agent] を設定する際に、次の方法で特定のモデルを選択できます。 +1 つのワークフロー内で、各エージェントごとに異なるモデルを使いたい場合があります。たとえば、トリアージには小型で高速なモデルを使い、複雑なタスクにはより大きく高性能なモデルを使うことができます。[`Agent`][agents.Agent] を設定する際、以下のいずれかの方法で特定のモデルを選択できます。 -1. OpenAI モデルの名前を渡す。 -2. モデル名とその名前をモデルインスタンスにマッピングできる [`ModelProvider`][agents.models.interface.ModelProvider] を渡す。 -3. 直接 [`Model`][agents.models.interface.Model] 実装を提供する。 +1. OpenAI モデル名を直接渡す。 +2. 任意のモデル名と、その名前を Model インスタンスにマッピングできる [`ModelProvider`][agents.models.interface.ModelProvider] を渡す。 +3. [`Model`][agents.models.interface.Model] 実装を直接指定する。 !!!note - SDK は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] と [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] の両方の形状をサポートしていますが、各ワークフローに対して単一のモデル形状を使用することをお勧めします。2 つの形状は異なる機能とツールをサポートしているためです。ワークフローでモデル形状を組み合わせる必要がある場合は、使用しているすべての機能が両方で利用可能であることを確認してください。 + SDK は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] と [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] の両方の形状をサポートしていますが、各ワークフローで 1 つのモデル形状のみを使うことを推奨します。なぜなら、2 つの形状はサポートする機能やツールが異なるためです。ワークフローでモデル形状を組み合わせて使う場合は、利用するすべての機能が両方で利用可能かご確認ください。 ```python from agents import Agent, Runner, AsyncOpenAI, OpenAIChatCompletionsModel @@ -48,10 +48,10 @@ async def main(): print(result.final_output) ``` -1. OpenAI モデルの名前を直接設定します。 -2. [`Model`][agents.models.interface.Model] 実装を提供します。 +1. OpenAI モデル名を直接設定します。 +2. [`Model`][agents.models.interface.Model] 実装を指定します。 -エージェントに使用するモデルをさらに設定したい場合は、`temperature` などのオプションのモデル設定パラメーターを提供する [`ModelSettings`][agents.models.interface.ModelSettings] を渡すことができます。 +エージェントで使用するモデルをさらに細かく設定したい場合は、[`ModelSettings`][agents.models.interface.ModelSettings] を渡すことができます。これにより、temperature などのオプションのモデル設定パラメーターを指定できます。 ```python from agents import Agent, ModelSettings @@ -64,43 +64,43 @@ english_agent = Agent( ) ``` -## 他の LLM プロバイダーの使用 +## 他の LLM プロバイダーの利用 -他の LLM プロバイダーを 3 つの方法で使用できます(例は[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/))。 +他の LLM プロバイダーは、3 つの方法で利用できます([こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/) に code examples があります)。 -1. [`set_default_openai_client`][agents.set_default_openai_client] は、`AsyncOpenAI` のインスタンスを LLM クライアントとしてグローバルに使用したい場合に便利です。LLM プロバイダーが OpenAI 互換の API エンドポイントを持っている場合に、`base_url` と `api_key` を設定できます。[examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) に設定可能な例があります。 -2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで使用します。これにより、「この実行のすべてのエージェントにカスタムモデルプロバイダーを使用する」と指定できます。[examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) に設定可能な例があります。 -3. [`Agent.model`][agents.agent.Agent.model] では、特定のエージェントインスタンスにモデルを指定できます。これにより、異なるエージェントに対して異なるプロバイダーを組み合わせて使用することができます。[examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) に設定可能な例があります。 +1. [`set_default_openai_client`][agents.set_default_openai_client] は、`AsyncOpenAI` のインスタンスを LLM クライアントとしてグローバルに利用したい場合に便利です。これは、LLM プロバイダーが OpenAI 互換の API エンドポイントを持ち、`base_url` と `api_key` を設定できる場合に使います。[examples/model_providers/custom_example_global.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_global.py) に設定例があります。 +2. [`ModelProvider`][agents.models.interface.ModelProvider] は `Runner.run` レベルで利用します。これにより、「この実行のすべてのエージェントでカスタムモデルプロバイダーを使う」と指定できます。[examples/model_providers/custom_example_provider.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_provider.py) に設定例があります。 +3. [`Agent.model`][agents.agent.Agent.model] で、特定のエージェントインスタンスにモデルを指定できます。これにより、エージェントごとに異なるプロバイダーを組み合わせて使うことができます。[examples/model_providers/custom_example_agent.py](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/custom_example_agent.py) に設定例があります。 -`platform.openai.com` からの API キーがない場合は、`set_tracing_disabled()` を使用してトレーシングを無効にするか、[異なるトレーシングプロセッサー](tracing.md)を設定することをお勧めします。 +`platform.openai.com` の API キーがない場合は、`set_tracing_disabled()` でトレーシングを無効にするか、[別のトレーシングプロセッサー](tracing.md) を設定することを推奨します。 !!! note - これらの例では、Chat Completions API/モデルを使用しています。なぜなら、ほとんどの LLM プロバイダーはまだ Responses API をサポートしていないからです。LLM プロバイダーがそれをサポートしている場合は、Responses を使用することをお勧めします。 + これらの code examples では Chat Completions API/モデルを使っています。なぜなら、ほとんどの LLM プロバイダーはまだ Responses API をサポートしていないためです。もし LLM プロバイダーが Responses API をサポートしている場合は、Responses の利用を推奨します。 -## 他の LLM プロバイダーを使用する際の一般的な問題 +## 他の LLM プロバイダー利用時のよくある問題 -### トレーシングクライアントエラー 401 +### Tracing クライアントの 401 エラー -トレーシングに関連するエラーが発生した場合、これはトレースが OpenAI サーバーにアップロードされ、OpenAI API キーを持っていないためです。これを解決するには、次の 3 つのオプションがあります。 +トレーシングに関連するエラーが発生した場合、これはトレースが OpenAI サーバーにアップロードされるため、OpenAI API キーがないことが原因です。解決方法は 3 つあります。 -1. トレーシングを完全に無効にする: [`set_tracing_disabled(True)`][agents.set_tracing_disabled]。 -2. トレーシング用の OpenAI キーを設定する: [`set_tracing_export_api_key(...)`][agents.set_tracing_export_api_key]。この API キーはトレースのアップロードにのみ使用され、[platform.openai.com](https://platform.openai.com/) からのものでなければなりません。 -3. 非 OpenAI トレースプロセッサーを使用する。[トレーシングドキュメント](tracing.md#custom-tracing-processors)を参照してください。 +1. トレーシングを完全に無効化する: [`set_tracing_disabled(True)`][agents.set_tracing_disabled]。 +2. トレーシング用の OpenAI キーを設定する: [`set_tracing_export_api_key(...)`][agents.set_tracing_export_api_key]。この API キーはトレースのアップロードのみに使われ、[platform.openai.com](https://platform.openai.com/) のものが必要です。 +3. OpenAI 以外のトレースプロセッサーを使う。[トレーシングのドキュメント](tracing.md#custom-tracing-processors) をご覧ください。 ### Responses API サポート -SDK はデフォルトで Responses API を使用しますが、ほとんどの他の LLM プロバイダーはまだサポートしていません。その結果、404 エラーや類似の問題が発生することがあります。これを解決するには、次の 2 つのオプションがあります。 +SDK はデフォルトで Responses API を使いますが、ほとんどの他の LLM プロバイダーはまだ対応していません。そのため、404 エラーなどが発生する場合があります。解決方法は 2 つあります。 -1. [`set_default_openai_api("chat_completions")`][agents.set_default_openai_api] を呼び出します。これは、環境変数を介して `OPENAI_API_KEY` と `OPENAI_BASE_URL` を設定している場合に機能します。 -2. [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] を使用します。例は[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/)にあります。 +1. [`set_default_openai_api("chat_completions")`][agents.set_default_openai_api] を呼び出します。これは、環境変数で `OPENAI_API_KEY` と `OPENAI_BASE_URL` を設定している場合に有効です。 +2. [`OpenAIChatCompletionsModel`][agents.models.openai_chatcompletions.OpenAIChatCompletionsModel] を使います。[こちら](https://github.com/openai/openai-agents-python/tree/main/examples/model_providers/) に code examples があります。 -### 適切な形式のデータのサポート +### structured outputs サポート -一部のモデルプロバイダーは、[適切な形式のデータ](https://platform.openai.com/docs/guides/structured-outputs)をサポートしていません。これにより、次のようなエラーが発生することがあります。 +一部のモデルプロバイダーは [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) をサポートしていません。その場合、次のようなエラーが発生することがあります。 ``` BadRequestError: Error code: 400 - {'error': {'message': "'response_format.type' : value is not one of the allowed values ['text','json_object']", 'type': 'invalid_request_error'}} ``` -これは一部のモデルプロバイダーの欠点であり、JSON 出力をサポートしていますが、出力に使用する `json_schema` を指定することはできません。これに対する修正に取り組んでいますが、JSON スキーマ出力をサポートしているプロバイダーに依存することをお勧めします。さもないと、アプリが不正な JSON のために頻繁に壊れることになります。 \ No newline at end of file +これは一部のモデルプロバイダーの制限で、JSON 出力には対応していても、出力に使う `json_schema` を指定できない場合があります。現在この問題の修正に取り組んでいますが、JSON schema 出力をサポートしているプロバイダーの利用を推奨します。そうでない場合、不正な JSON によりアプリが頻繁に動作しなくなる可能性があります。 \ No newline at end of file diff --git a/docs/ja/multi_agent.md b/docs/ja/multi_agent.md index af635776..e5604f6f 100644 --- a/docs/ja/multi_agent.md +++ b/docs/ja/multi_agent.md @@ -1,37 +1,37 @@ -# 複数エージェントのオーケストレーション +# 複数のエージェントのオーケストレーション -オーケストレーションとは、アプリ内でのエージェントの流れを指します。どのエージェントが実行され、どの順序で、次に何が起こるかをどのように決定するかです。エージェントをオーケストレーションする主な方法は2つあります。 +オーケストレーションとは、アプリ内でのエージェントの流れを指します。どのエージェントが、どの順番で実行され、次に何が起こるかをどのように決定するかということです。エージェントをオーケストレーションする主な方法は 2 つあります。 -1. LLM に決定を任せる: これは LLM の知能を利用して、計画、推論し、それに基づいてどのステップを取るかを決定します。 -2. コードによるオーケストレーション: コードを通じてエージェントの流れを決定します。 +1. LLM に意思決定を任せる方法:これは LLM の知能を活用し、計画・推論・意思決定を行わせるものです。 +2. コードによるオーケストレーション:コードでエージェントの流れを制御する方法です。 -これらのパターンを組み合わせて使用することができます。それぞれに独自のトレードオフがあり、以下で説明します。 +これらのパターンは組み合わせて使うこともできます。それぞれにメリット・デメリットがあり、以下で説明します。 ## LLM によるオーケストレーション -エージェントは、指示、ツール、ハンドオフを備えた LLM です。これにより、オープンエンドなタスクが与えられた場合、LLM は自律的にタスクに取り組む方法を計画し、ツールを使用してアクションを実行し、データを取得し、ハンドオフを使用してサブエージェントにタスクを委任できます。例えば、リサーチエージェントは次のようなツールを備えることができます。 +エージェントとは、instructions、tools、handoffs を備えた LLM です。つまり、オープンエンドなタスクが与えられた場合、LLM は自律的にタスクへの取り組み方を計画し、tools を使ってアクションを実行・データを取得し、handoffs を使ってサブエージェントにタスクを委任できます。たとえば、リサーチエージェントには以下のような tools を持たせることができます。 -- Web 検索でオンライン情報を見つける -- ファイル検索と取得で独自データや接続を検索する -- コンピュータ操作でコンピュータ上でアクションを実行する +- Web 検索でオンライン情報を探す +- ファイル検索やリトリーバルで独自データや接続先を検索する +- コンピュータ操作でコンピュータ上のアクションを実行する - コード実行でデータ分析を行う -- 計画やレポート作成に優れた専門エージェントへのハンドオフ +- 計画やレポート作成などに特化したエージェントへの handoffs -このパターンは、タスクがオープンエンドであり、LLM の知能に依存したい場合に最適です。ここでの最も重要な戦術は次のとおりです。 +このパターンは、タスクがオープンエンドで LLM の知能に頼りたい場合に最適です。ここで重要なポイントは次のとおりです。 -1. 良いプロンプトに投資する。利用可能なツール、使用方法、および操作するパラメーターを明確にします。 -2. アプリを監視し、反復する。問題が発生する箇所を確認し、プロンプトを改善します。 -3. エージェントに内省と改善を許可する。例えば、ループで実行し、自己批評させるか、エラーメッセージを提供して改善させます。 -4. 一つのタスクに優れた専門エージェントを持つこと。何でも得意とされる汎用エージェントを持つのではなく。 -5. [evals](https://platform.openai.com/docs/guides/evals) に投資する。これにより、エージェントを訓練してタスクの改善と向上を図ることができます。 +1. 良いプロンプトに投資しましょう。利用可能な tools、使い方、守るべきパラメーターを明確に伝えます。 +2. アプリをモニタリングし、改善を繰り返しましょう。問題が発生した箇所を確認し、プロンプトを改善します。 +3. エージェントに内省と改善を促しましょう。たとえばループで実行し、自己批評させたり、エラーメッセージを与えて改善させたりします。 +4. 何でもできる汎用エージェントではなく、1 つのタスクに特化したエージェントを用意しましょう。 +5. [evals](https://platform.openai.com/docs/guides/evals) に投資しましょう。これによりエージェントを訓練し、タスクの精度を向上させることができます。 ## コードによるオーケストレーション -LLM によるオーケストレーションは強力ですが、コードによるオーケストレーションは、速度、コスト、パフォーマンスの面でタスクをより決定的で予測可能にします。ここでの一般的なパターンは次のとおりです。 +LLM によるオーケストレーションは強力ですが、コードによるオーケストレーションは、速度・コスト・パフォーマンスの面でより決定的かつ予測可能になります。よく使われるパターンは次のとおりです。 -- [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使用して、コードで検査できる適切な形式のデータを生成します。例えば、エージェントにタスクをいくつかのカテゴリーに分類させ、そのカテゴリーに基づいて次のエージェントを選択することができます。 -- 複数のエージェントをチェーンして、一つの出力を次の入力に変換します。ブログ記事を書くタスクを、リサーチ、アウトライン作成、記事執筆、批評、改善という一連のステップに分解できます。 -- `while` ループでタスクを実行するエージェントと、評価とフィードバックを提供するエージェントを実行し、評価者が出力が特定の基準を満たすと判断するまで続けます。 -- 複数のエージェントを並行して実行します。例えば、Python の基本コンポーネントである `asyncio.gather` を使用します。これは、互いに依存しない複数のタスクがある場合に速度のために役立ちます。 +- [structured outputs](https://platform.openai.com/docs/guides/structured-outputs) を使い、コードで検査できる適切な形式のデータを生成する。たとえば、エージェントにタスクをいくつかのカテゴリーに分類させ、そのカテゴリーに応じて次のエージェントを選択することができます。 +- 複数のエージェントを連鎖させ、一方の出力を次の入力に変換する。たとえば、ブログ記事の作成タスクを「リサーチ→アウトライン作成→記事執筆→批評→改善」といった一連のステップに分解できます。 +- タスクを実行するエージェントと、評価・フィードバックを行うエージェントを `while` ループで回し、評価者が基準を満たしたと判断するまで繰り返します。 +- 複数のエージェントを並列で実行する(例:Python の基本コンポーネントである `asyncio.gather` を利用)。これは、互いに依存しない複数のタスクを高速に処理したい場合に有効です。 -[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) には多くのコード例があります。 \ No newline at end of file +[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) には、さまざまな code examples をご用意しています。 \ No newline at end of file diff --git a/docs/ja/quickstart.md b/docs/ja/quickstart.md index 9e4846ef..1a4913c7 100644 --- a/docs/ja/quickstart.md +++ b/docs/ja/quickstart.md @@ -2,7 +2,7 @@ ## プロジェクトと仮想環境の作成 -これは一度だけ行えば大丈夫です。 +この作業は一度だけ行えば十分です。 ```bash mkdir my_project @@ -10,9 +10,9 @@ cd my_project python -m venv .venv ``` -### 仮想環境をアクティブにする +### 仮想環境の有効化 -新しいターミナルセッションを開始するたびに行ってください。 +新しいターミナルセッションを開始するたびに、これを実行してください。 ```bash source .venv/bin/activate @@ -26,7 +26,7 @@ pip install openai-agents # or `uv add openai-agents`, etc ### OpenAI API キーの設定 -お持ちでない場合は、[こちらの手順](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)に従って OpenAI API キーを作成してください。 +まだお持ちでない場合は、[こちらの手順](https://platform.openai.com/docs/quickstart#create-and-export-an-api-key)に従って OpenAI API キーを作成してください。 ```bash export OPENAI_API_KEY=sk-... @@ -34,7 +34,7 @@ export OPENAI_API_KEY=sk-... ## 最初のエージェントを作成する -エージェントは、instructions、名前、オプションの設定(`model_config` など)で定義されます。 +エージェントは instructions、名前、およびオプションの設定(例: `model_config` )で定義します。 ```python from agents import Agent @@ -47,7 +47,7 @@ agent = Agent( ## さらにエージェントを追加する -追加のエージェントも同様に定義できます。`handoff_descriptions` は、ハンドオフルーティングを決定するための追加のコンテキストを提供します。 +追加のエージェントも同様の方法で定義できます。 `handoff_descriptions` は、ハンドオフのルーティングを判断するための追加コンテキストを提供します。 ```python from agents import Agent @@ -67,7 +67,7 @@ math_tutor_agent = Agent( ## ハンドオフを定義する -各エージェントで、タスクを進める方法を決定するための送信ハンドオフオプションのインベントリを定義できます。 +各エージェントで、タスクを進めるために選択できる送信先ハンドオフオプションのインベントリを定義できます。 ```python triage_agent = Agent( @@ -77,9 +77,9 @@ triage_agent = Agent( ) ``` -## エージェントオーケストレーションを実行する +## エージェントのオーケストレーションを実行する -ワークフローが実行され、トリアージエージェントが2つの専門エージェント間を正しくルーティングするか確認しましょう。 +ワークフローが正しく動作し、トリアージエージェントが 2 つの専門エージェント間で正しくルーティングするか確認しましょう。 ```python from agents import Runner @@ -91,7 +91,7 @@ async def main(): ## ガードレールを追加する -入力または出力に対してカスタムガードレールを定義できます。 +入力または出力に対して実行するカスタムガードレールを定義できます。 ```python from agents import GuardrailFunctionOutput, Agent, Runner @@ -118,7 +118,7 @@ async def homework_guardrail(ctx, agent, input_data): ## すべてをまとめる -すべてをまとめて、ハンドオフと入力ガードレールを使用して全体のワークフローを実行しましょう。 +すべてを組み合わせて、ハンドオフと入力ガードレールを使ったワークフロー全体を実行してみましょう。 ```python from agents import Agent, InputGuardrail, GuardrailFunctionOutput, Runner @@ -176,14 +176,14 @@ if __name__ == "__main__": asyncio.run(main()) ``` -## トレースを表示する +## トレースを確認する -エージェントの実行中に何が起こったかを確認するには、[OpenAI ダッシュボードのトレースビューア](https://platform.openai.com/traces)に移動して、エージェント実行のトレースを表示してください。 +エージェントの実行中に何が起こったかを確認するには、[OpenAI ダッシュボードの Trace viewer](https://platform.openai.com/traces) にアクセスして、エージェント実行のトレースを表示してください。 ## 次のステップ より複雑なエージェントフローの構築方法を学びましょう: -- [エージェント](agents.md)の設定方法を学ぶ。 -- [エージェントの実行](running_agents.md)について学ぶ。 -- [ツール](tools.md)、[ガードレール](guardrails.md)、[モデル](models.md)について学ぶ。 \ No newline at end of file +- [エージェント](agents.md) の設定方法について学ぶ +- [エージェントの実行](running_agents.md) について学ぶ +- [tools](tools.md)、[guardrails](guardrails.md)、[models](models.md) について学ぶ \ No newline at end of file diff --git a/docs/ja/results.md b/docs/ja/results.md index 765bba5c..6b2c0ccc 100644 --- a/docs/ja/results.md +++ b/docs/ja/results.md @@ -1,52 +1,52 @@ # 結果 -`Runner.run` メソッドを呼び出すと、次のいずれかが得られます: +`Runner.run` メソッドを呼び出すと、以下のいずれかが返されます: -- `run` または `run_sync` を呼び出すと [`RunResult`][agents.result.RunResult] -- `run_streamed` を呼び出すと [`RunResultStreaming`][agents.result.RunResultStreaming] +- `run` または `run_sync` を呼び出した場合は、[`RunResult`][agents.result.RunResult] +- `run_streamed` を呼び出した場合は、[`RunResultStreaming`][agents.result.RunResultStreaming] -これらはどちらも [`RunResultBase`][agents.result.RunResultBase] を継承しており、ほとんどの有用な情報はここにあります。 +これらはどちらも [`RunResultBase`][agents.result.RunResultBase] を継承しており、ほとんどの有用な情報はここに含まれています。 ## 最終出力 -[`final_output`][agents.result.RunResultBase.final_output] プロパティには、最後に実行されたエージェントの最終出力が含まれています。これは次のいずれかです: +[`final_output`][agents.result.RunResultBase.final_output] プロパティには、最後に実行されたエージェントの最終出力が格納されます。これは以下のいずれかです: -- `output_type` が定義されていない場合は `str` -- エージェントに出力タイプが定義されている場合は `last_agent.output_type` のオブジェクト +- 最後のエージェントに `output_type` が定義されていない場合は `str` +- エージェントに `output_type` が定義されている場合は、`last_agent.output_type` 型のオブジェクト !!! note - `final_output` は `Any` 型です。ハンドオフのため、静的に型を指定することはできません。ハンドオフが発生すると、どのエージェントが最後になるか分からないため、可能な出力タイプのセットを静的に知ることはできません。 + `final_output` の型は `Any` です。ハンドオフのため、静的に型を決定することはできません。ハンドオフが発生した場合、どのエージェントが最後になるか分からないため、出力型の集合を静的に知ることができません。 -## 次のターンの入力 +## 次のターンへの入力 -[`result.to_input_list()`][agents.result.RunResultBase.to_input_list] を使用して、結果を入力リストに変換できます。これにより、提供した元の入力をエージェント実行中に生成されたアイテムに連結します。これにより、1つのエージェント実行の出力を別の実行に渡したり、ループで実行して毎回新しいユーザー入力を追加したりするのが便利になります。 +[`result.to_input_list()`][agents.result.RunResultBase.to_input_list] を使うことで、実行結果を入力リストに変換できます。これは、あなたが提供した元の入力と、エージェント実行中に生成されたアイテムを連結したものです。これにより、あるエージェント実行の出力を別の実行に渡したり、ループで実行して毎回新しいユーザー入力を追加したりするのが簡単になります。 ## 最後のエージェント -[`last_agent`][agents.result.RunResultBase.last_agent] プロパティには、最後に実行されたエージェントが含まれています。アプリケーションによっては、次回ユーザーが何かを入力する際に役立つことがよくあります。たとえば、フロントラインのトリアージエージェントが言語特定のエージェントにハンドオフする場合、最後のエージェントを保存し、次回ユーザーがエージェントにメッセージを送信する際に再利用できます。 +[`last_agent`][agents.result.RunResultBase.last_agent] プロパティには、最後に実行されたエージェントが格納されます。アプリケーションによっては、次回ユーザーが何か入力した際にこれが役立つことがよくあります。たとえば、フロントラインのトリアージエージェントが言語特化エージェントにハンドオフする場合、最後のエージェントを保存しておき、次回ユーザーがエージェントにメッセージを送る際に再利用できます。 ## 新しいアイテム -[`new_items`][agents.result.RunResultBase.new_items] プロパティには、実行中に生成された新しいアイテムが含まれています。アイテムは [`RunItem`][agents.items.RunItem] です。実行アイテムは LLM によって生成された raw アイテムをラップします。 +[`new_items`][agents.result.RunResultBase.new_items] プロパティには、実行中に生成された新しいアイテムが格納されます。これらのアイテムは [`RunItem`][agents.items.RunItem] です。RunItem は LLM によって生成された raw アイテムをラップします。 - [`MessageOutputItem`][agents.items.MessageOutputItem] は LLM からのメッセージを示します。raw アイテムは生成されたメッセージです。 -- [`HandoffCallItem`][agents.items.HandoffCallItem] は LLM がハンドオフツールを呼び出したことを示します。raw アイテムは LLM からのツール呼び出しアイテムです。 -- [`HandoffOutputItem`][agents.items.HandoffOutputItem] はハンドオフが発生したことを示します。raw アイテムはハンドオフツール呼び出しへのツール応答です。アイテムからソース/ターゲットエージェントにもアクセスできます。 +- [`HandoffCallItem`][agents.items.HandoffCallItem] は LLM がハンドオフツールを呼び出したことを示します。raw アイテムは LLM からのツールコールアイテムです。 +- [`HandoffOutputItem`][agents.items.HandoffOutputItem] はハンドオフが発生したことを示します。raw アイテムはハンドオフツールコールへのツールレスポンスです。また、アイテムからソース/ターゲットエージェントにもアクセスできます。 - [`ToolCallItem`][agents.items.ToolCallItem] は LLM がツールを呼び出したことを示します。 -- [`ToolCallOutputItem`][agents.items.ToolCallOutputItem] はツールが呼び出されたことを示します。raw アイテムはツール応答です。アイテムからツール出力にもアクセスできます。 +- [`ToolCallOutputItem`][agents.items.ToolCallOutputItem] はツールが呼び出されたことを示します。raw アイテムはツールレスポンスです。また、アイテムからツール出力にもアクセスできます。 - [`ReasoningItem`][agents.items.ReasoningItem] は LLM からの推論アイテムを示します。raw アイテムは生成された推論です。 ## その他の情報 ### ガードレール結果 -[`input_guardrail_results`][agents.result.RunResultBase.input_guardrail_results] と [`output_guardrail_results`][agents.result.RunResultBase.output_guardrail_results] プロパティには、ガードレールの結果が含まれています。ガードレール結果には、ログや保存に役立つ情報が含まれることがあるため、これらを利用可能にしています。 +[`input_guardrail_results`][agents.result.RunResultBase.input_guardrail_results] および [`output_guardrail_results`][agents.result.RunResultBase.output_guardrail_results] プロパティには、ガードレールの結果(存在する場合)が格納されます。ガードレール結果には、ログや保存に役立つ有用な情報が含まれることがあるため、これらを利用できるようにしています。 -### Raw 応答 +### raw レスポンス -[`raw_responses`][agents.result.RunResultBase.raw_responses] プロパティには、LLM によって生成された [`ModelResponse`][agents.items.ModelResponse] が含まれています。 +[`raw_responses`][agents.result.RunResultBase.raw_responses] プロパティには、LLM によって生成された [`ModelResponse`][agents.items.ModelResponse] が格納されます。 ### 元の入力 -[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が含まれています。ほとんどの場合、これを必要としませんが、必要な場合に備えて利用可能です。 \ No newline at end of file +[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が格納されます。ほとんどの場合これは必要ありませんが、必要な場合のために利用可能です。 \ No newline at end of file diff --git a/docs/ja/running_agents.md b/docs/ja/running_agents.md index c2071c65..1a56fcc7 100644 --- a/docs/ja/running_agents.md +++ b/docs/ja/running_agents.md @@ -1,10 +1,10 @@ # エージェントの実行 -エージェントは [`Runner`][agents.run.Runner] クラスを通じて実行できます。3つのオプションがあります: +エージェントは [`Runner`][agents.run.Runner] クラスを使って実行できます。3 つのオプションがあります。 -1. 非同期で実行し、[`RunResult`][agents.result.RunResult] を返す [`Runner.run()`][agents.run.Runner.run]。 -2. 同期メソッドで、内部で `.run()` を実行する [`Runner.run_sync()`][agents.run.Runner.run_sync]。 -3. 非同期で実行し、[`RunResultStreaming`][agents.result.RunResultStreaming] を返す [`Runner.run_streamed()`][agents.run.Runner.run_streamed]。ストリーミングモードで LLM を呼び出し、受信したイベントをストリームします。 +1. [`Runner.run()`][agents.run.Runner.run]:非同期で実行され、[`RunResult`][agents.result.RunResult] を返します。 +2. [`Runner.run_sync()`][agents.run.Runner.run_sync]:同期メソッドで、内部的には `.run()` を実行します。 +3. [`Runner.run_streamed()`][agents.run.Runner.run_streamed]:非同期で実行され、[`RunResultStreaming`][agents.result.RunResultStreaming] を返します。LLM をストリーミングモードで呼び出し、受信したイベントをリアルタイムでストリームします。 ```python from agents import Agent, Runner @@ -19,53 +19,53 @@ async def main(): # Infinite loop's dance. ``` -詳細は[結果ガイド](results.md)をご覧ください。 +詳細は [results guide](results.md) をご覧ください。 ## エージェントループ -`Runner` の実行メソッドを使用する際、開始エージェントと入力を渡します。入力は文字列(ユーザーメッセージと見なされる)または OpenAI Responses API のアイテムリストのいずれかです。 +`Runner` の run メソッドを使用する際、開始するエージェントと入力を渡します。入力は文字列(ユーザーメッセージと見なされます)または入力アイテムのリスト(OpenAI Responses API のアイテム)を指定できます。 -ランナーは次のループを実行します: +runner は次のようなループを実行します。 1. 現在のエージェントと入力で LLM を呼び出します。 2. LLM が出力を生成します。 - 1. LLM が `final_output` を返すと、ループは終了し、結果を返します。 - 2. LLM がハンドオフを行う場合、現在のエージェントと入力を更新し、ループを再実行します。 - 3. LLM がツール呼び出しを生成する場合、それらを実行し、結果を追加し、ループを再実行します。 + 1. LLM が `final_output` を返した場合、ループは終了し、結果を返します。 + 2. LLM がハンドオフを行った場合、現在のエージェントと入力を更新し、ループを再実行します。 + 3. LLM がツール呼び出しを生成した場合、それらのツール呼び出しを実行し、結果を追加してループを再実行します。 3. 渡された `max_turns` を超えた場合、[`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] 例外を発生させます。 !!! note - LLM の出力が「最終出力」と見なされるかどうかのルールは、望ましいタイプのテキスト出力を生成し、ツール呼び出しがないことです。 + LLM の出力が「final output」と見なされるルールは、希望する型のテキスト出力が生成され、ツール呼び出しがない場合です。 ## ストリーミング -ストリーミングを使用すると、LLM が実行される際にストリーミングイベントを受け取ることができます。ストリームが完了すると、[`RunResultStreaming`][agents.result.RunResultStreaming] は実行に関する完全な情報を含み、生成されたすべての新しい出力を含みます。ストリーミングイベントには `.stream_events()` を呼び出せます。[ストリーミングガイド](streaming.md)で詳細を確認してください。 +ストリーミングを利用すると、LLM の実行中にストリーミングイベントを受け取ることができます。ストリームが完了すると、[`RunResultStreaming`][agents.result.RunResultStreaming] に実行に関するすべての情報(新たに生成されたすべての出力を含む)が格納されます。ストリーミングイベントは `.stream_events()` で取得できます。詳細は [streaming guide](streaming.md) をご覧ください。 -## 実行設定 +## Run config -`run_config` パラメーターを使用して、エージェント実行のグローバル設定を構成できます: +`run_config` パラメーターでは、エージェント実行のグローバル設定をいくつか構成できます。 -- [`model`][agents.run.RunConfig.model]: 各エージェントの `model` に関係なく、使用するグローバル LLM モデルを設定できます。 -- [`model_provider`][agents.run.RunConfig.model_provider]: モデル名を検索するためのモデルプロバイダーで、デフォルトは OpenAI です。 -- [`model_settings`][agents.run.RunConfig.model_settings]: エージェント固有の設定を上書きします。たとえば、グローバルな `temperature` や `top_p` を設定できます。 -- [`input_guardrails`][agents.run.RunConfig.input_guardrails], [`output_guardrails`][agents.run.RunConfig.output_guardrails]: すべての実行に含める入力または出力ガードレールのリスト。 -- [`handoff_input_filter`][agents.run.RunConfig.handoff_input_filter]: すべてのハンドオフに適用するグローバル入力フィルター。ハンドオフに既にフィルターがない場合に適用されます。入力フィルターを使用して、新しいエージェントに送信される入力を編集できます。詳細は [`Handoff.input_filter`][agents.handoffs.Handoff.input_filter] のドキュメントを参照してください。 -- [`tracing_disabled`][agents.run.RunConfig.tracing_disabled]: 実行全体の[トレーシング](tracing.md)を無効にできます。 -- [`trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data]: トレースに LLM やツール呼び出しの入出力など、潜在的に機密性のあるデータを含めるかどうかを設定します。 -- [`workflow_name`][agents.run.RunConfig.workflow_name], [`trace_id`][agents.run.RunConfig.trace_id], [`group_id`][agents.run.RunConfig.group_id]: 実行のトレーシングワークフロー名、トレース ID、トレースグループ ID を設定します。少なくとも `workflow_name` を設定することをお勧めします。グループ ID は、複数の実行にわたってトレースをリンクするためのオプションフィールドです。 -- [`trace_metadata`][agents.run.RunConfig.trace_metadata]: すべてのトレースに含めるメタデータ。 +- [`model`][agents.run.RunConfig.model]:各エージェントの `model` 設定に関わらず、グローバルで使用する LLM モデルを指定できます。 +- [`model_provider`][agents.run.RunConfig.model_provider]:モデル名を検索するためのモデルプロバイダーで、デフォルトは OpenAI です。 +- [`model_settings`][agents.run.RunConfig.model_settings]:エージェント固有の設定を上書きします。たとえば、グローバルな `temperature` や `top_p` を設定できます。 +- [`input_guardrails`][agents.run.RunConfig.input_guardrails], [`output_guardrails`][agents.run.RunConfig.output_guardrails]:すべての実行に含める入力または出力ガードレールのリストです。 +- [`handoff_input_filter`][agents.run.RunConfig.handoff_input_filter]:すべてのハンドオフに適用するグローバルな入力フィルターです(ハンドオフに既にフィルターがない場合)。入力フィルターを使うと、新しいエージェントに送信する入力を編集できます。詳細は [`Handoff.input_filter`][agents.handoffs.Handoff.input_filter] のドキュメントをご覧ください。 +- [`tracing_disabled`][agents.run.RunConfig.tracing_disabled]:実行全体の [トレーシング](tracing.md) を無効にできます。 +- [`trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data]:トレースに LLM やツール呼び出しの入出力など、機密性のあるデータを含めるかどうかを設定します。 +- [`workflow_name`][agents.run.RunConfig.workflow_name], [`trace_id`][agents.run.RunConfig.trace_id], [`group_id`][agents.run.RunConfig.group_id]:実行のトレーシングワークフロー名、トレース ID、トレースグループ ID を設定します。少なくとも `workflow_name` の設定を推奨します。グループ ID は複数の実行にまたがるトレースをリンクするためのオプション項目です。 +- [`trace_metadata`][agents.run.RunConfig.trace_metadata]:すべてのトレースに含めるメタデータです。 -## 会話/チャットスレッド +## 会話・チャットスレッド -いずれかの実行メソッドを呼び出すと、1つ以上のエージェントが実行される可能性があります(したがって、1つ以上の LLM 呼び出しが行われます)が、チャット会話の単一の論理ターンを表します。例えば: +いずれかの run メソッドを呼び出すと、1 つまたは複数のエージェント(および 1 つまたは複数の LLM 呼び出し)が実行されますが、チャット会話における 1 回の論理的なターンを表します。例: -1. ユーザーターン:ユーザーがテキストを入力 -2. ランナー実行:最初のエージェントが LLM を呼び出し、ツールを実行し、2番目のエージェントにハンドオフし、2番目のエージェントがさらにツールを実行し、出力を生成します。 +1. ユーザーのターン:ユーザーがテキストを入力 +2. Runner の実行:最初のエージェントが LLM を呼び出し、ツールを実行し、2 番目のエージェントにハンドオフ、2 番目のエージェントがさらにツールを実行し、出力を生成 -エージェント実行の終了時に、ユーザーに何を表示するかを選択できます。例えば、エージェントによって生成されたすべての新しいアイテムをユーザーに表示するか、最終出力のみを表示するかです。いずれにせよ、ユーザーがフォローアップの質問をする可能性があり、その場合は再度実行メソッドを呼び出すことができます。 +エージェントの実行が終わったら、ユーザーに何を表示するか選択できます。たとえば、エージェントが生成したすべての新しいアイテムをユーザーに見せることも、最終出力だけを見せることもできます。いずれの場合も、ユーザーが追加の質問をした場合は、再度 run メソッドを呼び出せます。 -次のターンの入力を取得するには、基本の [`RunResultBase.to_input_list()`][agents.result.RunResultBase.to_input_list] メソッドを使用できます。 +次のターンの入力を取得するには、ベースの [`RunResultBase.to_input_list()`][agents.result.RunResultBase.to_input_list] メソッドを使用できます。 ```python async def main(): @@ -86,10 +86,10 @@ async def main(): ## 例外 -SDK は特定のケースで例外を発生させます。完全なリストは [`agents.exceptions`][] にあります。概要は以下の通りです: +SDK は特定のケースで例外を発生させます。全リストは [`agents.exceptions`][] にあります。概要は以下の通りです。 -- [`AgentsException`][agents.exceptions.AgentsException] は、SDK で発生するすべての例外の基本クラスです。 -- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded] は、実行が渡された `max_turns` を超えた場合に発生します。 -- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError] は、モデルが無効な出力を生成した場合に発生します。例:不正な形式の JSON や存在しないツールの使用。 -- [`UserError`][agents.exceptions.UserError] は、SDK を使用する際にエラーを犯した場合に発生します。 -- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered], [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered] は、[ガードレール](guardrails.md)が作動した場合に発生します。 \ No newline at end of file +- [`AgentsException`][agents.exceptions.AgentsException]:SDK で発生するすべての例外の基底クラスです。 +- [`MaxTurnsExceeded`][agents.exceptions.MaxTurnsExceeded]:run メソッドに渡した `max_turns` を超えた場合に発生します。 +- [`ModelBehaviorError`][agents.exceptions.ModelBehaviorError]:モデルが不正な出力(例:不正な JSON や存在しないツールの使用)を生成した場合に発生します。 +- [`UserError`][agents.exceptions.UserError]:SDK を使用する際に、あなた(SDK を使ってコードを書く人)がエラーを起こした場合に発生します。 +- [`InputGuardrailTripwireTriggered`][agents.exceptions.InputGuardrailTripwireTriggered], [`OutputGuardrailTripwireTriggered`][agents.exceptions.OutputGuardrailTripwireTriggered]:[ガードレール](guardrails.md) が作動した場合に発生します。 \ No newline at end of file diff --git a/docs/ja/streaming.md b/docs/ja/streaming.md index 2f7a8dd2..b820bae5 100644 --- a/docs/ja/streaming.md +++ b/docs/ja/streaming.md @@ -1,14 +1,14 @@ # ストリーミング -ストリーミングを使用すると、エージェントの実行が進行する際の更新を購読できます。これは、エンドユーザーに進捗状況の更新や部分的な応答を表示するのに役立ちます。 +ストリーミングを利用すると、エージェントの実行が進行するにつれて、その更新情報を購読できます。これは、エンドユーザーに進捗状況や部分的な応答を表示するのに役立ちます。 -ストリーミングを行うには、[`Runner.run_streamed()`][agents.run.Runner.run_streamed] を呼び出します。これにより、[`RunResultStreaming`][agents.result.RunResultStreaming] が得られます。`result.stream_events()` を呼び出すと、以下で説明する [`StreamEvent`][agents.stream_events.StreamEvent] オブジェクトの非同期ストリームが得られます。 +ストリーミングを行うには、[`Runner.run_streamed()`][agents.run.Runner.run_streamed] を呼び出します。これにより、[`RunResultStreaming`][agents.result.RunResultStreaming] が返されます。`result.stream_events()` を呼び出すと、下記で説明する [`StreamEvent`][agents.stream_events.StreamEvent] オブジェクトの非同期ストリームが得られます。 -## Raw response events +## raw response events -[`RawResponsesStreamEvent`][agents.stream_events.RawResponsesStreamEvent] は、LLM から直接渡される raw イベントです。これらは OpenAI Responses API フォーマットであり、各イベントにはタイプ(`response.created`、`response.output_text.delta` など)とデータがあります。これらのイベントは、生成され次第、ユーザーに応答メッセージをストリーミングしたい場合に便利です。 +[`RawResponsesStreamEvent`][agents.stream_events.RawResponsesStreamEvent] は、LLM から直接渡される raw イベントです。これらは OpenAI Responses API フォーマットであり、各イベントには type(例:`response.created`、`response.output_text.delta` など)とデータが含まれます。これらのイベントは、応答メッセージが生成され次第、ユーザーにストリーミングしたい場合に便利です。 -例えば、これは LLM によってトークンごとに生成されたテキストを出力します。 +例えば、以下の例では LLM が生成したテキストをトークンごとに出力します。 ```python import asyncio @@ -31,11 +31,11 @@ if __name__ == "__main__": asyncio.run(main()) ``` -## 実行アイテムイベントとエージェントイベント +## Run item イベントとエージェントイベント -[`RunItemStreamEvent`][agents.stream_events.RunItemStreamEvent] は、より高レベルのイベントです。アイテムが完全に生成されたときに通知します。これにより、「メッセージが生成された」、「ツールが実行された」などのレベルで進捗状況を更新することができます。同様に、[`AgentUpdatedStreamEvent`][agents.stream_events.AgentUpdatedStreamEvent] は、現在のエージェントが変更されたとき(例えば、ハンドオフの結果として)に更新を提供します。 +[`RunItemStreamEvent`][agents.stream_events.RunItemStreamEvent] は、より高レベルなイベントです。アイテムが完全に生成されたタイミングを通知します。これにより、「メッセージが生成された」「ツールが実行された」など、各トークン単位ではなく、進捗状況をまとめてユーザーに伝えることができます。同様に、[`AgentUpdatedStreamEvent`][agents.stream_events.AgentUpdatedStreamEvent] は、現在のエージェントが変更されたとき(例:ハンドオフの結果として)に更新情報を提供します。 -例えば、これは raw イベントを無視し、ユーザーに更新をストリーミングします。 +例えば、以下の例では raw イベントを無視し、ユーザーに更新情報のみをストリーミングします。 ```python import asyncio diff --git a/docs/ja/tools.md b/docs/ja/tools.md index cd747663..2444891c 100644 --- a/docs/ja/tools.md +++ b/docs/ja/tools.md @@ -1,18 +1,18 @@ # ツール -ツールはエージェントがアクションを実行するためのものです。データの取得、コードの実行、外部 API の呼び出し、さらにはコンピュータの使用などが含まれます。Agent SDK には3つのクラスのツールがあります。 +ツールは エージェント がアクションを実行するためのものです。たとえば、データの取得、コードの実行、外部 API の呼び出し、さらにはコンピュータ操作などが含まれます。Agents SDK には 3 種類のツールクラスがあります。 -- ホストされたツール: これらは LLM サーバー上で AI モデルと一緒に実行されます。OpenAI は、リトリーバル、Web 検索、コンピュータ操作をホストされたツールとして提供しています。 -- 関数呼び出し: 任意の Python 関数をツールとして使用できます。 -- エージェントをツールとして使用: エージェントをツールとして使用し、エージェントが他のエージェントをハンドオフせずに呼び出すことができます。 +- Hosted tools: これらは LLM サーバー上で AI モデルとともに実行されます。OpenAI は retrieval、Web 検索、コンピュータ操作を Hosted tools として提供しています。 +- Function calling: 任意の Python 関数をツールとして利用できます。 +- Agents as tools: エージェントをツールとして利用でき、エージェントが他のエージェントをハンドオフせずに呼び出すことができます。 -## ホストされたツール +## Hosted tools -OpenAI は、[`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] を使用する際にいくつかの組み込みツールを提供しています。 +OpenAI は [`OpenAIResponsesModel`][agents.models.openai_responses.OpenAIResponsesModel] を使用する際に、いくつかの組み込みツールを提供しています。 -- [`WebSearchTool`][agents.tool.WebSearchTool] はエージェントが Web 検索を行うことを可能にします。 -- [`FileSearchTool`][agents.tool.FileSearchTool] は OpenAI ベクトルストアから情報を取得することを可能にします。 -- [`ComputerTool`][agents.tool.ComputerTool] はコンピュータ操作タスクを自動化することを可能にします。 +- [`WebSearchTool`][agents.tool.WebSearchTool] は、エージェントが Web 検索を行うことを可能にします。 +- [`FileSearchTool`][agents.tool.FileSearchTool] は、OpenAI ベクトルストアから情報を取得できます。 +- [`ComputerTool`][agents.tool.ComputerTool] は、コンピュータ操作タスクの自動化を可能にします。 ```python from agents import Agent, FileSearchTool, Runner, WebSearchTool @@ -33,16 +33,16 @@ async def main(): print(result.final_output) ``` -## 関数ツール +## Function tools -任意の Python 関数をツールとして使用できます。Agents SDK はツールを自動的にセットアップします。 +任意の Python 関数をツールとして利用できます。Agents SDK が自動的にツールをセットアップします。 -- ツールの名前は Python 関数の名前になります(または名前を指定できます) -- ツールの説明は関数の docstring から取得されます(または説明を指定できます) -- 関数入力のスキーマは関数の引数から自動的に作成されます -- 各入力の説明は、無効にしない限り、関数の docstring から取得されます +- ツール名は Python 関数名になります(または任意の名前を指定できます) +- ツールの説明は関数の docstring から取得されます(または任意の説明を指定できます) +- 関数の引数から自動的に入力スキーマが作成されます +- 各入力の説明は、関数の docstring から取得されます(無効化も可能です) -Python の `inspect` モジュールを使用して関数シグネチャを抽出し、[`griffe`](https://mkdocstrings.github.io/griffe/) を使用して docstring を解析し、`pydantic` を使用してスキーマを作成します。 +Python の `inspect` モジュールを使って関数シグネチャを抽出し、[`griffe`](https://mkdocstrings.github.io/griffe/) で docstring を解析し、`pydantic` でスキーマを作成します。 ```python import json @@ -94,12 +94,12 @@ for tool in agent.tools: ``` -1. 任意の Python 型を関数の引数として使用でき、関数は同期または非同期であることができます。 -2. Docstring が存在する場合、説明や引数の説明を取得するために使用されます。 -3. 関数はオプションで `context` を取ることができ(最初の引数である必要があります)、ツールの名前、説明、使用する docstring スタイルなどのオーバーライドを設定できます。 -4. デコレートされた関数をツールのリストに渡すことができます。 +1. 関数の引数には任意の Python 型を利用でき、同期・非同期どちらの関数も利用可能です。 +2. docstring があれば、説明や引数の説明として利用されます。 +3. 関数はオプションで `context` を最初の引数として受け取れます。また、ツール名や説明、docstring スタイルの指定などのオーバーライドも可能です。 +4. デコレートした関数をツールのリストに渡すことができます。 -??? note "出力を表示するには展開してください" +??? note "出力を展開して表示" ``` fetch_weather @@ -169,14 +169,14 @@ for tool in agent.tools: } ``` -### カスタム関数ツール +### カスタム function tools -時には、Python 関数をツールとして使用したくない場合もあります。その場合、直接 [`FunctionTool`][agents.tool.FunctionTool] を作成できます。以下を提供する必要があります。 +場合によっては、Python 関数をツールとして使いたくないこともあります。その場合は、[`FunctionTool`][agents.tool.FunctionTool] を直接作成できます。必要な情報は以下の通りです。 - `name` - `description` - `params_json_schema`(引数の JSON スキーマ) -- `on_invoke_tool`(コンテキストと引数を JSON 文字列として受け取り、ツールの出力を文字列として返す非同期関数) +- `on_invoke_tool`(context と引数(JSON 文字列)を受け取り、ツールの出力を文字列で返す async 関数) ```python from typing import Any @@ -211,16 +211,16 @@ tool = FunctionTool( ### 引数と docstring の自動解析 -前述のように、ツールのスキーマを抽出するために関数シグネチャを自動的に解析し、ツールおよび個々の引数の説明を抽出するために docstring を解析します。以下の点に注意してください。 +前述の通り、関数シグネチャを自動解析してツールのスキーマを抽出し、docstring からツールや各引数の説明を抽出します。主なポイントは以下の通りです。 -1. シグネチャの解析は `inspect` モジュールを通じて行われます。引数の型を理解するために型注釈を使用し、全体のスキーマを表す Pydantic モデルを動的に構築します。Python の基本コンポーネント、Pydantic モデル、TypedDict など、ほとんどの型をサポートしています。 -2. `griffe` を使用して docstring を解析します。サポートされている docstring フォーマットは `google`、`sphinx`、`numpy` です。docstring フォーマットを自動的に検出しようとしますが、これはベストエフォートであり、`function_tool` を呼び出す際に明示的に設定できます。`use_docstring_info` を `False` に設定することで docstring 解析を無効にすることもできます。 +1. シグネチャの解析は `inspect` モジュールで行います。型アノテーションを利用して引数の型を把握し、Pydantic モデルを動的に構築して全体のスキーマを表現します。Python の基本コンポーネント、Pydantic モデル、TypedDict など、ほとんどの型をサポートしています。 +2. docstring の解析には `griffe` を使用します。サポートされている docstring フォーマットは `google`、`sphinx`、`numpy` です。docstring フォーマットは自動検出を試みますが、`function_tool` 呼び出し時に明示的に指定することもできます。`use_docstring_info` を `False` に設定することで docstring 解析を無効化できます。 スキーマ抽出のコードは [`agents.function_schema`][] にあります。 -## エージェントをツールとして使用 +## Agents as tools -一部のワークフローでは、中央のエージェントが専門エージェントのネットワークをオーケストレーションすることを望むかもしれません。これを行うには、エージェントをツールとしてモデル化します。 +一部のワークフローでは、ハンドオフせずに中央のエージェントが専門エージェントのネットワークをオーケストレーションしたい場合があります。その場合、エージェントをツールとしてモデル化することで実現できます。 ```python from agents import Agent, Runner @@ -259,12 +259,12 @@ async def main(): print(result.final_output) ``` -## 関数ツールでのエラー処理 +## Function tools でのエラー処理 -`@function_tool` を使用して関数ツールを作成する際、`failure_error_function` を渡すことができます。これは、ツール呼び出しがクラッシュした場合に LLM にエラーレスポンスを提供する関数です。 +`@function_tool` で function tool を作成する際、`failure_error_function` を渡すことができます。これは、ツール呼び出しがクラッシュした場合に LLM へエラー応答を提供する関数です。 -- デフォルトでは(何も渡さない場合)、`default_tool_error_function` が実行され、LLM にエラーが発生したことを伝えます。 -- 独自のエラー関数を渡した場合、それが実行され、LLM にレスポンスが送信されます。 -- 明示的に `None` を渡した場合、ツール呼び出しエラーは再度発生し、処理する必要があります。モデルが無効な JSON を生成した場合は `ModelBehaviorError`、コードがクラッシュした場合は `UserError` などが考えられます。 +- デフォルト(何も渡さない場合)では、`default_tool_error_function` が実行され、LLM にエラーが発生したことを伝えます。 +- 独自のエラー関数を渡した場合は、それが実行され、その応答が LLM に送信されます。 +- 明示的に `None` を渡した場合、ツール呼び出し時のエラーは再スローされ、ユーザー側で処理できます。たとえば、モデルが無効な JSON を生成した場合は `ModelBehaviorError`、コードがクラッシュした場合は `UserError` などです。 -`FunctionTool` オブジェクトを手動で作成する場合、`on_invoke_tool` 関数内でエラーを処理する必要があります。 \ No newline at end of file +`FunctionTool` オブジェクトを手動で作成する場合は、`on_invoke_tool` 関数内でエラー処理を行う必要があります。 \ No newline at end of file diff --git a/docs/ja/tracing.md b/docs/ja/tracing.md index 0f573eb8..b7cb18dc 100644 --- a/docs/ja/tracing.md +++ b/docs/ja/tracing.md @@ -1,51 +1,51 @@ # トレーシング -Agents SDK には組み込みのトレーシング機能があり、エージェント実行中のイベント(LLM の生成、ツール呼び出し、ハンドオフ、ガードレール、カスタムイベントなど)の包括的な記録を収集します。[Traces ダッシュボード](https://platform.openai.com/traces)を使用して、開発中および本番環境でワークフローをデバッグ、可視化、監視できます。 +Agents SDK にはトレーシング機能が組み込まれており、エージェントの実行中に発生するイベント( LLM 生成、ツール呼び出し、ハンドオフ、ガードレール、カスタムイベントなど)の包括的な記録を収集します。[Traces ダッシュボード](https://platform.openai.com/traces) を使用することで、開発中や本番環境でワークフローのデバッグ、可視化、監視が可能です。 !!!note - トレーシングはデフォルトで有効です。トレーシングを無効にする方法は2つあります: + トレーシングはデフォルトで有効になっています。トレーシングを無効にする方法は 2 つあります: - 1. 環境変数 `OPENAI_AGENTS_DISABLE_TRACING=1` を設定して、グローバルにトレーシングを無効にすることができます。 - 2. [`agents.run.RunConfig.tracing_disabled`][] を `True` に設定して、単一の実行でトレーシングを無効にすることができます。 + 1. 環境変数 `OPENAI_AGENTS_DISABLE_TRACING=1` を設定することで、グローバルにトレーシングを無効化できます。 + 2. 単一の実行に対しては [`agents.run.RunConfig.tracing_disabled`][] を `True` に設定することで無効化できます。 -***OpenAI の API を使用している Zero Data Retention (ZDR) ポリシーの下で運営されている組織では、トレーシングは利用できません。*** +***OpenAI の API を使用し、Zero Data Retention (ZDR) ポリシーの下で運用している組織では、トレーシングは利用できません。*** ## トレースとスパン -- **トレース** は「ワークフロー」の単一のエンドツーエンドの操作を表します。スパンで構成されています。トレースには以下のプロパティがあります: - - `workflow_name`: 論理的なワークフローまたはアプリです。例: "Code generation" や "Customer service"。 - - `trace_id`: トレースの一意の ID。指定しない場合は自動生成されます。形式は `trace_<32_alphanumeric>` でなければなりません。 - - `group_id`: 同じ会話からの複数のトレースをリンクするためのオプションのグループ ID。例: チャットスレッド ID。 - - `disabled`: True の場合、トレースは記録されません。 - - `metadata`: トレースのオプションのメタデータ。 -- **スパン** は開始時間と終了時間を持つ操作を表します。スパンには以下があります: - - `started_at` と `ended_at` のタイムスタンプ。 - - 所属するトレースを表す `trace_id` - - 親スパンを指す `parent_id`(ある場合) - - スパンに関する情報を含む `span_data`。例: `AgentSpanData` はエージェントに関する情報を含み、`GenerationSpanData` は LLM の生成に関する情報を含みます。 +- **トレース** は 1 つの「ワークフロー」のエンドツーエンドの操作を表します。トレースはスパンで構成されます。トレースには以下のプロパティがあります: + - `workflow_name`: 論理的なワークフローやアプリ名です。例: "Code generation" や "Customer service" など。 + - `trace_id`: トレースの一意な ID です。指定しない場合は自動生成されます。フォーマットは `trace_<32_alphanumeric>` である必要があります。 + - `group_id`: オプションのグループ ID で、同じ会話からの複数のトレースをリンクするために使用します。例: チャットスレッド ID など。 + - `disabled`: True の場合、このトレースは記録されません。 + - `metadata`: トレースに付加するオプションのメタデータです。 +- **スパン** は開始時刻と終了時刻を持つ操作を表します。スパンには以下があります: + - `started_at` および `ended_at` タイムスタンプ + - 所属するトレースを示す `trace_id` + - このスパンの親スパンを指す `parent_id`(存在する場合) + - スパンに関する情報を含む `span_data`。例: `AgentSpanData` はエージェントに関する情報、`GenerationSpanData` は LLM 生成に関する情報など。 ## デフォルトのトレーシング -デフォルトで、SDK は以下をトレースします: +デフォルトでは、 SDK は以下をトレースします: -- `Runner.{run, run_sync, run_streamed}()` 全体が `trace()` でラップされます。 -- エージェントが実行されるたびに、`agent_span()` でラップされます。 -- LLM の生成は `generation_span()` でラップされます。 -- 関数ツールの呼び出しはそれぞれ `function_span()` でラップされます。 -- ガードレールは `guardrail_span()` でラップされます。 -- ハンドオフは `handoff_span()` でラップされます。 -- 音声入力(音声からテキスト)は `transcription_span()` でラップされます。 -- 音声出力(テキストから音声)は `speech_span()` でラップされます。 -- 関連する音声スパンは `speech_group_span()` の下に配置されることがあります。 +- `Runner.{run, run_sync, run_streamed}()` 全体が `trace()` でラップされます。 +- エージェントが実行されるたびに `agent_span()` でラップされます。 +- LLM 生成は `generation_span()` でラップされます。 +- 関数ツール呼び出しはそれぞれ `function_span()` でラップされます。 +- ガードレールは `guardrail_span()` でラップされます。 +- ハンドオフは `handoff_span()` でラップされます。 +- 音声入力(音声からテキスト)は `transcription_span()` でラップされます。 +- 音声出力(テキストから音声)は `speech_span()` でラップされます。 +- 関連する音声スパンは `speech_group_span()` の下にまとめられる場合があります。 -デフォルトでは、トレースは "Agent trace" と名付けられています。`trace` を使用する場合、この名前を設定することができ、[`RunConfig`][agents.run.RunConfig] で名前やその他のプロパティを設定できます。 +デフォルトでは、トレース名は "Agent trace" です。`trace` を使用する場合、この名前を設定できます。また、[`RunConfig`][agents.run.RunConfig] で名前やその他のプロパティを設定することも可能です。 -さらに、[カスタムトレースプロセッサー](#custom-tracing-processors)を設定して、トレースを他の宛先に送信することもできます(置き換えまたは二次的な宛先として)。 +さらに、[カスタムトレースプロセッサー](#custom-tracing-processors) を設定して、トレースを他の宛先に送信することもできます(置き換えや追加の宛先として)。 -## 高レベルのトレース +## より高レベルのトレース -時には、複数の `run()` 呼び出しを単一のトレースの一部にしたいことがあります。これを行うには、コード全体を `trace()` でラップします。 +複数回の `run()` 呼び出しを 1 つのトレースにまとめたい場合があります。その場合、コード全体を `trace()` でラップしてください。 ```python from agents import Agent, Runner, trace @@ -60,57 +60,57 @@ async def main(): print(f"Rating: {second_result.final_output}") ``` -1. `Runner.run` への2つの呼び出しが `with trace()` でラップされているため、個々の実行は2つのトレースを作成するのではなく、全体のトレースの一部になります。 +1. 2 回の `Runner.run` 呼び出しが `with trace()` でラップされているため、個々の実行は 2 つのトレースを作成するのではなく、全体のトレースの一部となります。 ## トレースの作成 -[`trace()`][agents.tracing.trace] 関数を使用してトレースを作成できます。トレースは開始と終了が必要です。以下の2つの方法があります: +[`trace()`][agents.tracing.trace] 関数を使ってトレースを作成できます。トレースは開始と終了が必要です。方法は 2 つあります: -1. **推奨**: トレースをコンテキストマネージャーとして使用します。つまり、`with trace(...) as my_trace` とします。これにより、トレースが自動的に適切なタイミングで開始および終了します。 -2. 手動で [`trace.start()`][agents.tracing.Trace.start] と [`trace.finish()`][agents.tracing.Trace.finish] を呼び出すこともできます。 +1. **推奨**: トレースをコンテキストマネージャーとして使用します。例: `with trace(...) as my_trace`。これにより、トレースの開始と終了が自動的に行われます。 +2. [`trace.start()`][agents.tracing.Trace.start] および [`trace.finish()`][agents.tracing.Trace.finish] を手動で呼び出すこともできます。 -現在のトレースは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡されます。これにより、並行処理でも自動的に機能します。トレースを手動で開始/終了する場合は、`start()`/`finish()` に `mark_as_current` と `reset_current` を渡して現在のトレースを更新する必要があります。 +現在のトレースは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) で管理されています。これにより、自動的に並行処理にも対応します。トレースを手動で開始・終了する場合は、`start()`/`finish()` に `mark_as_current` および `reset_current` を渡して現在のトレースを更新する必要があります。 ## スパンの作成 -さまざまな [`*_span()`][agents.tracing.create] メソッドを使用してスパンを作成できます。一般的に、スパンを手動で作成する必要はありません。カスタムスパン情報を追跡するための [`custom_span()`][agents.tracing.custom_span] 関数が利用可能です。 +さまざまな [`*_span()`][agents.tracing.create] メソッドを使ってスパンを作成できます。通常、スパンを手動で作成する必要はありません。カスタムスパン情報を追跡するための [`custom_span()`][agents.tracing.custom_span] 関数も用意されています。 -スパンは自動的に現在のトレースの一部となり、Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) を介して追跡される最も近い現在のスパンの下にネストされます。 +スパンは自動的に現在のトレースの一部となり、最も近い現在のスパンの下にネストされます。これは Python の [`contextvar`](https://docs.python.org/3/library/contextvars.html) で管理されています。 -## センシティブデータ +## 機微なデータ -特定のスパンは潜在的にセンシティブなデータをキャプチャすることがあります。 +一部のスパンは、機微なデータを記録する場合があります。 -`generation_span()` は LLM 生成の入力/出力を保存し、`function_span()` は関数呼び出しの入力/出力を保存します。これらにはセンシティブなデータが含まれる可能性があるため、[`RunConfig.trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data] を使用してそのデータのキャプチャを無効にすることができます。 +`generation_span()` は LLM 生成の入力・出力を保存し、`function_span()` は関数呼び出しの入力・出力を保存します。これらには機微なデータが含まれる場合があるため、[`RunConfig.trace_include_sensitive_data`][agents.run.RunConfig.trace_include_sensitive_data] でそのデータの記録を無効化できます。 -同様に、音声スパンにはデフォルトで入力および出力音声の base64 エンコードされた PCM データが含まれます。この音声データのキャプチャを無効にするには、[`VoicePipelineConfig.trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data] を設定します。 +同様に、音声スパンはデフォルトで入力・出力音声の base64 エンコード PCM データを含みます。[`VoicePipelineConfig.trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data] を設定することで、この音声データの記録を無効化できます。 -## カスタムトレーシングプロセッサー +## カスタムトレースプロセッサー -トレーシングの高レベルアーキテクチャは次のとおりです: +トレーシングの高レベルなアーキテクチャは以下の通りです: -- 初期化時に、トレースを作成する責任を持つグローバルな [`TraceProvider`][agents.tracing.setup.TraceProvider] を作成します。 -- `TraceProvider` を [`BatchTraceProcessor`][agents.tracing.processors.BatchTraceProcessor] で構成し、トレース/スパンをバッチで [`BackendSpanExporter`][agents.tracing.processors.BackendSpanExporter] に送信し、OpenAI バックエンドにバッチでスパンとトレースをエクスポートします。 +- 初期化時にグローバルな [`TraceProvider`][agents.tracing.setup.TraceProvider] を作成し、トレースの生成を担当します。 +- `TraceProvider` は [`BatchTraceProcessor`][agents.tracing.processors.BatchTraceProcessor] で構成されており、トレースやスパンをバッチで [`BackendSpanExporter`][agents.tracing.processors.BackendSpanExporter] に送信します。これにより、スパンやトレースが OpenAI バックエンドにバッチでエクスポートされます。 -このデフォルトのセットアップをカスタマイズして、トレースを代替または追加のバックエンドに送信したり、エクスポーターの動作を変更したりするには、次の2つのオプションがあります: +このデフォルト設定をカスタマイズし、トレースを別のバックエンドや追加のバックエンドに送信したり、エクスポーターの動作を変更したりするには、2 つの方法があります: -1. [`add_trace_processor()`][agents.tracing.add_trace_processor] を使用して、トレースとスパンが準備できたときに受け取る**追加の**トレースプロセッサーを追加できます。これにより、OpenAI のバックエンドにトレースを送信することに加えて、独自の処理を行うことができます。 -2. [`set_trace_processors()`][agents.tracing.set_trace_processors] を使用して、デフォルトのプロセッサーを独自のトレースプロセッサーに**置き換える**ことができます。これにより、`TracingProcessor` を含めない限り、トレースは OpenAI バックエンドに送信されません。 +1. [`add_trace_processor()`][agents.tracing.add_trace_processor] を使うと、**追加の** トレースプロセッサーを追加できます。これにより、トレースやスパンが準備できた時点で独自の処理を行うことができ、OpenAI バックエンドへの送信に加えて独自の処理が可能です。 +2. [`set_trace_processors()`][agents.tracing.set_trace_processors] を使うと、デフォルトのプロセッサーを独自のトレースプロセッサーに**置き換える**ことができます。この場合、OpenAI バックエンドにトレースが送信されるのは、`TracingProcessor` を含めた場合のみです。 -## 外部トレーシングプロセッサーリスト +## 外部トレースプロセッサー一覧 -- [Weights & Biases](https://weave-docs.wandb.ai/guides/integrations/openai_agents) -- [Arize-Phoenix](https://docs.arize.com/phoenix/tracing/integrations-tracing/openai-agents-sdk) -- [MLflow (self-hosted/OSS](https://mlflow.org/docs/latest/tracing/integrations/openai-agent) -- [MLflow (Databricks hosted](https://docs.databricks.com/aws/en/mlflow/mlflow-tracing#-automatic-tracing) -- [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk) -- [Pydantic Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents) -- [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk) -- [Scorecard](https://docs.scorecard.io/docs/documentation/features/tracing#openai-agents-sdk-integration) -- [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent) -- [LangSmith](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_openai_agents_sdk) -- [Maxim AI](https://www.getmaxim.ai/docs/observe/integrations/openai-agents-sdk) -- [Comet Opik](https://www.comet.com/docs/opik/tracing/integrations/openai_agents) -- [Langfuse](https://langfuse.com/docs/integrations/openaiagentssdk/openai-agents) -- [Langtrace](https://docs.langtrace.ai/supported-integrations/llm-frameworks/openai-agents-sdk) -- [Okahu-Monocle](https://github.com/monocle2ai/monocle) \ No newline at end of file +- [Weights & Biases](https://weave-docs.wandb.ai/guides/integrations/openai_agents) +- [Arize-Phoenix](https://docs.arize.com/phoenix/tracing/integrations-tracing/openai-agents-sdk) +- [MLflow (self-hosted/OSS](https://mlflow.org/docs/latest/tracing/integrations/openai-agent) +- [MLflow (Databricks hosted](https://docs.databricks.com/aws/en/mlflow/mlflow-tracing#-automatic-tracing) +- [Braintrust](https://braintrust.dev/docs/guides/traces/integrations#openai-agents-sdk) +- [Pydantic Logfire](https://logfire.pydantic.dev/docs/integrations/llms/openai/#openai-agents) +- [AgentOps](https://docs.agentops.ai/v1/integrations/agentssdk) +- [Scorecard](https://docs.scorecard.io/docs/documentation/features/tracing#openai-agents-sdk-integration) +- [Keywords AI](https://docs.keywordsai.co/integration/development-frameworks/openai-agent) +- [LangSmith](https://docs.smith.langchain.com/observability/how_to_guides/trace_with_openai_agents_sdk) +- [Maxim AI](https://www.getmaxim.ai/docs/observe/integrations/openai-agents-sdk) +- [Comet Opik](https://www.comet.com/docs/opik/tracing/integrations/openai_agents) +- [Langfuse](https://langfuse.com/docs/integrations/openaiagentssdk/openai-agents) +- [Langtrace](https://docs.langtrace.ai/supported-integrations/llm-frameworks/openai-agents-sdk) +- [Okahu-Monocle](https://github.com/monocle2ai/monocle) \ No newline at end of file diff --git a/docs/ja/visualization.md b/docs/ja/visualization.md index 1054dd12..c93b3836 100644 --- a/docs/ja/visualization.md +++ b/docs/ja/visualization.md @@ -1,10 +1,10 @@ # エージェントの可視化 -エージェントの可視化では、**Graphviz** を使用してエージェントとその関係の構造化されたグラフィカル表現を生成できます。これは、アプリケーション内でエージェント、ツール、ハンドオフがどのように相互作用するかを理解するのに役立ちます。 +エージェントの可視化では、 **Graphviz** を使用してエージェントとその関係性を構造的にグラフィカルに表現できます。これは、アプリケーション内でエージェント、ツール、ハンドオフがどのように相互作用しているかを理解するのに役立ちます。 ## インストール -オプションの `viz` 依存関係グループをインストールします: +オプションの `viz` 依存グループをインストールします: ```bash pip install "openai-agents[viz]" @@ -12,11 +12,11 @@ pip install "openai-agents[viz]" ## グラフの生成 -`draw_graph` 関数を使用してエージェントの可視化を生成できます。この関数は、以下のような有向グラフを作成します: +`draw_graph` 関数を使ってエージェントの可視化を生成できます。この関数は、以下のような有向グラフを作成します: - **エージェント** は黄色のボックスで表されます。 - **ツール** は緑色の楕円で表されます。 -- **ハンドオフ** はあるエージェントから別のエージェントへの有向エッジです。 +- **ハンドオフ** は、あるエージェントから別のエージェントへの有向エッジで表されます。 ### 使用例 @@ -50,31 +50,32 @@ draw_graph(triage_agent) ![Agent Graph](../assets/images/graph.png) -これにより、**トリアージエージェント** の構造とサブエージェントおよびツールへの接続を視覚的に表現するグラフが生成されます。 +これにより、 **triage agent** の構造とサブエージェントやツールとの接続が視覚的に表現されたグラフが生成されます。 + ## 可視化の理解 生成されたグラフには以下が含まれます: -- エントリーポイントを示す **開始ノード** (`__start__`)。 -- 黄色で塗りつぶされた **長方形** で表されるエージェント。 -- 緑色で塗りつぶされた **楕円** で表されるツール。 +- エントリーポイントを示す **start node** (`__start__`) +- 黄色で塗りつぶされた **長方形** で表されるエージェント +- 緑色で塗りつぶされた **楕円** で表されるツール - 相互作用を示す有向エッジ: - - エージェント間のハンドオフには **実線の矢印**。 - - ツール呼び出しには **点線の矢印**。 -- 実行が終了する場所を示す **終了ノード** (`__end__`)。 + - エージェント間のハンドオフには **実線の矢印** + - ツール呼び出しには **点線の矢印** +- 実行が終了する場所を示す **end node** (`__end__`) ## グラフのカスタマイズ ### グラフの表示 -デフォルトでは、`draw_graph` はグラフをインラインで表示します。別ウィンドウでグラフを表示するには、次のように記述します: +デフォルトでは、`draw_graph` はグラフをインラインで表示します。グラフを別ウィンドウで表示したい場合は、次のように記述します: ```python draw_graph(triage_agent).view() ``` ### グラフの保存 -デフォルトでは、`draw_graph` はグラフをインラインで表示します。ファイルとして保存するには、ファイル名を指定します: +デフォルトでは、`draw_graph` はグラフをインラインで表示します。ファイルとして保存したい場合は、ファイル名を指定します: ```python draw_graph(triage_agent, filename="agent_graph.png") diff --git a/docs/ja/voice/pipeline.md b/docs/ja/voice/pipeline.md index 6df7dd04..50661076 100644 --- a/docs/ja/voice/pipeline.md +++ b/docs/ja/voice/pipeline.md @@ -1,6 +1,6 @@ # パイプラインとワークフロー -[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] は、エージェントのワークフローを音声アプリに変換するのを簡単にするクラスです。実行するワークフローを渡すと、パイプラインが入力音声の文字起こし、音声の終了検出、適切なタイミングでのワークフロー呼び出し、ワークフロー出力の音声化を行います。 +[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] は、エージェントワークフローを音声アプリに簡単に変換できるクラスです。実行したいワークフローを渡すと、パイプラインが入力音声の文字起こし、音声終了の検出、適切なタイミングでのワークフロー呼び出し、ワークフロー出力の音声化までを自動で処理します。 ```mermaid graph LR @@ -30,28 +30,28 @@ graph LR ## パイプラインの設定 -パイプラインを作成する際に、以下のことを設定できます: +パイプラインを作成する際、以下の項目を設定できます。 -1. [`workflow`][agents.voice.workflow.VoiceWorkflowBase]:新しい音声が文字起こしされるたびに実行されるコード。 -2. 使用する [`speech-to-text`][agents.voice.model.STTModel] および [`text-to-speech`][agents.voice.model.TTSModel] モデル。 +1. [`workflow`][agents.voice.workflow.VoiceWorkflowBase]:新しい音声が文字起こしされるたびに実行されるコードです。 +2. 使用する [`speech-to-text`][agents.voice.model.STTModel] および [`text-to-speech`][agents.voice.model.TTSModel] モデル 3. [`config`][agents.voice.pipeline_config.VoicePipelineConfig]:以下のような設定が可能です。 - - モデルプロバイダー:モデル名をモデルにマッピングできます。 - - トレーシング:トレーシングを無効にするかどうか、音声ファイルのアップロード、ワークフロー名、トレース ID など。 - - TTS および STT モデルの設定:プロンプト、言語、使用するデータ型など。 + - モデルプロバイダー:モデル名をモデルにマッピングできます + - トレーシング:トレーシングの有効/無効、音声ファイルのアップロード有無、ワークフロー名、トレース ID など + - TTS および STT モデルの設定:プロンプト、言語、使用するデータ型など ## パイプラインの実行 -パイプラインは [`run()`][agents.voice.pipeline.VoicePipeline.run] メソッドを通じて実行できます。これにより、2 つの形式で音声入力を渡すことができます: +パイプラインは [`run()`][agents.voice.pipeline.VoicePipeline.run] メソッドで実行できます。音声入力は 2 つの形式で渡せます。 -1. [`AudioInput`][agents.voice.input.AudioInput]:完全な音声トランスクリプトがある場合に使用し、その結果を生成するだけです。これは、話者が話し終わったときの検出が不要な場合に便利です。例えば、事前録音された音声や、ユーザーが話し終わったことが明確なプッシュ・トゥ・トークアプリで使用します。 -2. [`StreamedAudioInput`][agents.voice.input.StreamedAudioInput]:ユーザーが話し終わったときの検出が必要な場合に使用します。音声チャンクを検出時にプッシュでき、音声パイプラインが自動的にエージェントワークフローを適切なタイミングで実行します。これは「アクティビティ検出」と呼ばれるプロセスを通じて行われます。 +1. [`AudioInput`][agents.voice.input.AudioInput]:完全な音声トランスクリプトがある場合に使用し、その内容に対する結果のみを生成します。話者が話し終えたタイミングを検出する必要がない場合(例:事前録音音声や push-to-talk アプリなど、ユーザーが話し終えたことが明確な場合)に便利です。 +2. [`StreamedAudioInput`][agents.voice.input.StreamedAudioInput]:ユーザーが話し終えたタイミングを検出する必要がある場合に使用します。音声チャンクを検出ごとにプッシュでき、VoicePipeline が「アクティビティ検出」と呼ばれるプロセスを通じて、適切なタイミングでエージェントワークフローを自動実行します。 ## 結果 -音声パイプライン実行の結果は [`StreamedAudioResult`][agents.voice.result.StreamedAudioResult] です。これは、イベントが発生するたびにストリーミングできるオブジェクトです。いくつかの種類の [`VoiceStreamEvent`][agents.voice.events.VoiceStreamEvent] があります: +VoicePipeline 実行の結果は [`StreamedAudioResult`][agents.voice.result.StreamedAudioResult] です。これは、イベントが発生するたびにストリーミングで受け取れるオブジェクトです。いくつかの種類の [`VoiceStreamEvent`][agents.voice.events.VoiceStreamEvent] があります。 -1. [`VoiceStreamEventAudio`][agents.voice.events.VoiceStreamEventAudio]:音声チャンクを含むイベント。 -2. [`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle]:ターンの開始や終了などのライフサイクルイベントを通知します。 +1. [`VoiceStreamEventAudio`][agents.voice.events.VoiceStreamEventAudio]:音声チャンクを含みます。 +2. [`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle]:ターンの開始や終了など、ライフサイクルイベントを通知します。 3. [`VoiceStreamEventError`][agents.voice.events.VoiceStreamEventError]:エラーイベントです。 ```python @@ -70,6 +70,6 @@ async for event in result.stream(): ## ベストプラクティス -### 中断 +### 割り込み -Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの中断サポートを提供していません。代わりに、検出されたターンごとにワークフローの別の実行をトリガーします。アプリケーション内で中断を処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントを監視できます。`turn_started` は新しいターンが文字起こしされ、処理が始まったことを示します。`turn_ended` は、関連するすべての音声が送信された後にトリガーされます。これらのイベントを使用して、モデルがターンを開始したときにスピーカーのマイクをミュートし、関連する音声をすべてフラッシュした後にアンミュートすることができます。 \ No newline at end of file +Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの割り込みサポートを提供していません。そのため、検出された各ターンごとにワークフローの個別実行がトリガーされます。アプリケーション内で割り込みを処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントをリッスンできます。`turn_started` は新しいターンが文字起こしされ、処理が開始されたことを示します。`turn_ended` は該当ターンのすべての音声が送信された後にトリガーされます。これらのイベントを利用して、モデルがターンを開始した際に話者のマイクをミュートし、ターンに関連するすべての音声を送信し終えた後にアンミュートする、といった制御が可能です。 \ No newline at end of file diff --git a/docs/ja/voice/quickstart.md b/docs/ja/voice/quickstart.md index 77e5ef27..9c874020 100644 --- a/docs/ja/voice/quickstart.md +++ b/docs/ja/voice/quickstart.md @@ -2,7 +2,7 @@ ## 前提条件 -Agents SDK の基本的な[クイックスタート手順](../quickstart.md)に従い、仮想環境を設定してください。その後、SDK からオプションの音声依存関係をインストールします。 +Agents SDK の[クイックスタート手順](../quickstart.md)に従い、仮想環境をセットアップしてください。その後、SDK からオプションの音声依存関係をインストールします。 ```bash pip install 'openai-agents[voice]' @@ -10,11 +10,11 @@ pip install 'openai-agents[voice]' ## コンセプト -知っておくべき主なコンセプトは、[`VoicePipeline`][agents.voice.pipeline.VoicePipeline] です。これは3ステップのプロセスです。 +主なコンセプトは [`VoicePipeline`][agents.voice.pipeline.VoicePipeline] です。これは 3 ステップのプロセスです: -1. 音声をテキストに変換する音声認識モデルを実行します。 -2. 通常はエージェントワークフローであるコードを実行して、結果を生成します。 -3. 結果のテキストを音声に戻すテキスト読み上げモデルを実行します。 +1. 音声をテキストに変換する音声認識モデル(speech-to-text)を実行します。 +2. 通常はエージェント的なワークフローであるあなたのコードを実行し、結果を生成します。 +3. 結果のテキストを音声に戻す音声合成モデル(text-to-speech)を実行します。 ```mermaid graph LR @@ -44,7 +44,7 @@ graph LR ## エージェント -まず、いくつかのエージェントを設定しましょう。この SDK でエージェントを構築したことがある場合、これは馴染みがあるはずです。エージェント、ハンドオフ、ツールを用意します。 +まず、いくつかのエージェントをセットアップしましょう。この SDK でエージェントを作成したことがあれば、馴染みがあるはずです。ここでは、複数のエージェント、ハンドオフ、ツールを用意します。 ```python import asyncio @@ -88,14 +88,14 @@ agent = Agent( ## 音声パイプライン -[`SingleAgentVoiceWorkflow`][agents.voice.workflow.SingleAgentVoiceWorkflow] をワークフローとして使用して、シンプルな音声パイプラインを設定します。 +[`SingleAgentVoiceWorkflow`][agents.voice.workflow.SingleAgentVoiceWorkflow] をワークフローとして使い、シンプルな音声パイプラインをセットアップします。 ```python from agents.voice import SingleAgentVoiceWorkflow, VoicePipeline pipeline = VoicePipeline(workflow=SingleAgentVoiceWorkflow(agent)) ``` -## パイプラインを実行する +## パイプラインの実行 ```python import numpy as np @@ -191,4 +191,4 @@ if __name__ == "__main__": asyncio.run(main()) ``` -この例を実行すると、エージェントがあなたに話しかけます! [examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) の例をチェックして、自分でエージェントと話すデモを見てください。 \ No newline at end of file +この例を実行すると、エージェントがあなたに話しかけます![examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) のコード例をチェックして、実際にエージェントと会話できるデモをご覧ください。 \ No newline at end of file diff --git a/docs/ja/voice/tracing.md b/docs/ja/voice/tracing.md index 1a1df278..639a95f2 100644 --- a/docs/ja/voice/tracing.md +++ b/docs/ja/voice/tracing.md @@ -1,14 +1,14 @@ # トレーシング -[エージェントがトレースされる](../tracing.md)のと同様に、音声パイプラインも自動的にトレースされます。 +[エージェントのトレーシング](../tracing.md)と同様に、音声パイプラインも自動的にトレーシングされます。 -基本的なトレーシング情報については上記のトレーシングドキュメントを参照できますが、パイプラインのトレーシングは [`VoicePipelineConfig`][agents.voice.pipeline_config.VoicePipelineConfig] を通じて追加で設定できます。 +基本的なトレーシング情報については上記のトレーシングドキュメントをご参照いただけますが、さらに [`VoicePipelineConfig`][agents.voice.pipeline_config.VoicePipelineConfig] を使ってパイプラインのトレーシングを設定することも可能です。 -トレーシングに関連する主なフィールドは次のとおりです: +主なトレーシング関連フィールドは以下の通りです: -- [`tracing_disabled`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]: トレーシングを無効にするかどうかを制御します。デフォルトでは、トレーシングは有効です。 -- [`trace_include_sensitive_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_data]: トレースに音声トランスクリプトのような潜在的に機密性のあるデータを含めるかどうかを制御します。これは特に音声パイプライン用であり、ワークフロー内で行われることには関係ありません。 -- [`trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data]: トレースに音声データを含めるかどうかを制御します。 -- [`workflow_name`][agents.voice.pipeline_config.VoicePipelineConfig.workflow_name]: トレースワークフローの名前です。 -- [`group_id`][agents.voice.pipeline_config.VoicePipelineConfig.group_id]: 複数のトレースをリンクするための `group_id` です。 -- [`trace_metadata`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]: トレースに含める追加のメタデータです。 \ No newline at end of file +- [`tracing_disabled`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレーシングを無効にするかどうかを制御します。デフォルトではトレーシングは有効です。 +- [`trace_include_sensitive_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_data]:トレースに音声の書き起こしなど、機密性の高いデータを含めるかどうかを制御します。これは特に音声パイプライン用であり、Workflow 内部で発生する内容には適用されません。 +- [`trace_include_sensitive_audio_data`][agents.voice.pipeline_config.VoicePipelineConfig.trace_include_sensitive_audio_data]:トレースに音声データを含めるかどうかを制御します。 +- [`workflow_name`][agents.voice.pipeline_config.VoicePipelineConfig.workflow_name]:トレースワークフローの名前です。 +- [`group_id`][agents.voice.pipeline_config.VoicePipelineConfig.group_id]:トレースの `group_id` で、複数のトレースをリンクすることができます。 +- [`trace_metadata`][agents.voice.pipeline_config.VoicePipelineConfig.tracing_disabled]:トレースに追加するメタデータです。 \ No newline at end of file diff --git a/docs/scripts/translate_docs.py b/docs/scripts/translate_docs.py index e62a2c09..f261daa0 100644 --- a/docs/scripts/translate_docs.py +++ b/docs/scripts/translate_docs.py @@ -7,7 +7,7 @@ # logging.basicConfig(level=logging.INFO) # logging.getLogger("openai").setLevel(logging.DEBUG) -OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "gpt-4o") +OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "gpt-4.1") # Define the source and target directories source_dir = "docs" @@ -94,18 +94,17 @@ def built_instructions(target_language: str, lang_code: str) -> str: ) return f"""You are an expert technical translator. -Your task: translate the markdown passed as a user input from English into {target_language}. +Your task: translate the markdown passed as a user input from English into {target_language}. +The inputs are the official OpenAI Agents SDK framework documentation, and your translation outputs'll be used for serving the official {target_language} version of them. Thus, accuracy, clarity, and fidelity to the original are critical. ############################ ## OUTPUT REQUIREMENTS ## ############################ -- Return **only** the translated markdown, with the original markdown structure preserved. -- Do **not** add explanations, comments, or metadata. +You must return **only** the translated markdown. Do not include any commentary, metadata, or explanations. The original markdown structure must be strictly preserved. ######################### ## GENERAL RULES ## ######################### -- The output quality must be great enough to be used for public documentation. - Be professional and polite. - Keep the tone **natural** and concise. - Do not omit any content. If a segment should stay in English, copy it verbatim. @@ -149,9 +148,17 @@ def built_instructions(target_language: str, lang_code: str) -> str: If you are uncertain about a term, leave the original English term in parentheses after your translation. ######################### -## FINAL REMINDER ## +## WORKFLOW ## ######################### -Return **only** the translated markdown text. No extra commentary. + +Follow the following workflow to translate the given markdown text data: + +1. Read the input markdown text given by the user. +2. Translate the markdown file into {target_language}, carefully following the requirements above. +3. Perform a self-review to evaluate the quality of the translation, focusing on naturalness, accuracy, and consistency in detail. +4. If improvements are necessary, refine the content without changing the original meaning. +5. Continue improving the translation until you are fully satisfied with the result. +6. Once the final output is ready, return **only** the translated markdown text. No extra commentary. """ diff --git a/mkdocs.yml b/mkdocs.yml index 3eaf0f4b..51d65e69 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -127,7 +127,7 @@ plugins: nav: - はじめに: index.md - クイックスタート: quickstart.md - - サンプル例: examples.md + - コード例: examples.md - ドキュメント: - agents.md - running_agents.md From 96a97af9be9a30c6ca0c2e811425043d53a5ee3f Mon Sep 17 00:00:00 2001 From: Rohan Mehta Date: Mon, 14 Apr 2025 22:45:30 -0400 Subject: [PATCH 20/21] v0.0.10 (#514) --- pyproject.toml | 2 +- uv.lock | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index 251a6ab5..c3e46a66 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "openai-agents" -version = "0.0.9" +version = "0.0.10" description = "OpenAI Agents SDK" readme = "README.md" requires-python = ">=3.9" diff --git a/uv.lock b/uv.lock index a762c723..1212f790 100644 --- a/uv.lock +++ b/uv.lock @@ -1108,13 +1108,11 @@ wheels = [ [[package]] name = "openai-agents" -version = "0.0.9" +version = "0.0.10" source = { editable = "." } dependencies = [ - { name = "eval-type-backport" }, { name = "griffe" }, { name = "mcp", marker = "python_full_version >= '3.10'" }, - { name = "mkdocs-static-i18n" }, { name = "openai" }, { name = "pydantic" }, { name = "requests" }, @@ -1134,6 +1132,7 @@ voice = [ [package.dev-dependencies] dev = [ { name = "coverage" }, + { name = "eval-type-backport" }, { name = "graphviz" }, { name = "inline-snapshot" }, { name = "mkdocs" }, @@ -1156,11 +1155,9 @@ dev = [ [package.metadata] requires-dist = [ - { name = "eval-type-backport", specifier = ">=0.2.2" }, { name = "graphviz", marker = "extra == 'viz'", specifier = ">=0.17" }, { name = "griffe", specifier = ">=1.5.6,<2" }, { name = "mcp", marker = "python_full_version >= '3.10'", specifier = ">=1.6.0,<2" }, - { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, { name = "numpy", marker = "python_full_version >= '3.10' and extra == 'voice'", specifier = ">=2.2.0,<3" }, { name = "openai", specifier = ">=1.66.5" }, { name = "pydantic", specifier = ">=2.10,<3" }, @@ -1174,11 +1171,13 @@ provides-extras = ["voice", "viz"] [package.metadata.requires-dev] dev = [ { name = "coverage", specifier = ">=7.6.12" }, + { name = "eval-type-backport", specifier = ">=0.2.2" }, { name = "graphviz" }, { name = "inline-snapshot", specifier = ">=0.20.7" }, { name = "mkdocs", specifier = ">=1.6.0" }, { name = "mkdocs-material", specifier = ">=9.6.0" }, { name = "mkdocs-static-i18n" }, + { name = "mkdocs-static-i18n", specifier = ">=1.3.0" }, { name = "mkdocstrings", extras = ["python"], specifier = ">=0.28.0" }, { name = "mypy" }, { name = "playwright", specifier = "==1.50.0" }, From b978b4382ef7e6b7f78982e0d0a9c3c758ec886c Mon Sep 17 00:00:00 2001 From: RonaldChungHueyWu <10584547+ronaldchwu@users.noreply.github.com> Date: Tue, 15 Apr 2025 12:48:01 +1000 Subject: [PATCH 21/21] Support parallel_tool_calls=False for ChatCompletion API (#513) The current ChatCompletion API supports only `parallel_tool_calls=True` or `parallel_tool_calls=NOT_GIVEN` This PR is to support setting `parallel_tool_calls=False`, a common requirement in controlling agent tool use patterns (e.g. ensuring one tool call at the time, to facilitate desired tool calling sequence). I followed the merged [PR#333](https://github.com/openai/openai-agents-python/pull/333) for consistency. --- src/agents/models/openai_chatcompletions.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/agents/models/openai_chatcompletions.py b/src/agents/models/openai_chatcompletions.py index c12fe68a..712a7998 100644 --- a/src/agents/models/openai_chatcompletions.py +++ b/src/agents/models/openai_chatcompletions.py @@ -500,7 +500,11 @@ async def _fetch_response( span.span_data.input = converted_messages parallel_tool_calls = ( - True if model_settings.parallel_tool_calls and tools and len(tools) > 0 else NOT_GIVEN + True + if model_settings.parallel_tool_calls and tools and len(tools) > 0 + else False + if model_settings.parallel_tool_calls is False + else NOT_GIVEN ) tool_choice = _Converter.convert_tool_choice(model_settings.tool_choice) response_format = _Converter.convert_response_format(output_schema)