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.
This commit is contained in:
parent
8ded8a9981
commit
68c725f942
24 changed files with 623 additions and 504 deletions
|
|
@ -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](
|
||||
...,
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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 処理を行いません。
|
||||
ツール呼び出し後にエージェントが完全に停止するようにしたい場合(自動モードで続行するのではなく)、[`Agent.tool_use_behavior="stop_on_first_tool"`] を設定することで、ツールの出力を最終応答として直接使用し、さらなる LLM 処理を行わないようにできます。
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)」際に有効です。
|
||||
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 検索)から関連データを取得できる特別なツールです。関連するコンテキストデータで応答を「グラウンド」するのに有用です。
|
||||
|
|
@ -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 モデルを使用した音声エージェントのコード例を参照できます。
|
||||
- **[voice](https://github.com/openai/openai-agents-python/tree/main/examples/voice):**
|
||||
TTS と STT モデルを使用した音声エージェントの例を見てみましょう。
|
||||
|
|
@ -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. これはワークフローを定義する実際の エージェント です。
|
||||
1. これは実際のエージェントの出力タイプです。
|
||||
2. これはガードレールの出力タイプです。
|
||||
3. これはエージェントの出力を受け取り、結果を返すガードレール関数です。
|
||||
4. これはワークフローを定義する実際のエージェントです。
|
||||
|
|
@ -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_<agent_name>` という形式になりますが、これをオーバーライドできます。
|
||||
- `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_<agent_name>` に解決されます。これをオーバーライドできます。
|
||||
- `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
|
||||
|
|
|
|||
|
|
@ -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-...
|
||||
|
|
|
|||
|
|
@ -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 関連情報
|
||||
|
||||

|
||||

|
||||
|
|
@ -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 により頻繁に破損する可能性があります。
|
||||
これは一部のモデルプロバイダーの欠点で、JSON 出力をサポートしていますが、出力に使用する `json_schema` を指定することはできません。この問題の修正に取り組んでいますが、JSON スキーマ出力をサポートしているプロバイダーに依存することをお勧めします。さもないと、アプリが不正な JSON のために頻繁に壊れることになります。
|
||||
|
|
@ -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) に多数のコード例があります。
|
||||
[`examples/agent_patterns`](https://github.com/openai/openai-agents-python/tree/main/examples/agent_patterns) には多くのコード例があります。
|
||||
|
|
@ -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) について学ぶ。
|
||||
- [エージェント](agents.md)の設定方法を学ぶ。
|
||||
- [エージェントの実行](running_agents.md)について学ぶ。
|
||||
- [ツール](tools.md)、[ガードレール](guardrails.md)、[モデル](models.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` メソッドに提供した元の入力が格納されています。ほとんどの場合、これは必要ありませんが、必要に応じて利用可能です。
|
||||
[`input`][agents.result.RunResultBase.input] プロパティには、`run` メソッドに提供した元の入力が含まれています。ほとんどの場合、これを必要としませんが、必要な場合に備えて利用可能です。
|
||||
|
|
@ -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) がトリガーされた場合に発生します。
|
||||
- [`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)が作動した場合に発生します。
|
||||
|
|
@ -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 ===")
|
||||
|
||||
|
|
|
|||
|
|
@ -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` 関数内でエラーを処理する必要があります。
|
||||
`FunctionTool` オブジェクトを手動で作成する場合、`on_invoke_tool` 関数内でエラーを処理する必要があります。
|
||||
|
|
@ -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 バックエンドに送信されません。
|
||||
|
||||
## 外部トレーシングプロセッサ一覧
|
||||
## 外部トレーシングプロセッサーリスト
|
||||
|
||||
(省略:原文のまま)
|
||||
- [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)
|
||||
|
|
@ -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)
|
|||
|
||||

|
||||
|
||||
これにより、**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")
|
||||
|
|
|
|||
|
|
@ -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` は、該当するターンのすべての音声が送信された後にトリガーされます。これらのイベントを利用して、モデルがターンを開始した際に話者のマイクをミュートし、ターンに関連するすべての音声を送信した後にミュートを解除する、といった処理が可能です。
|
||||
Agents SDK は現在、[`StreamedAudioInput`][agents.voice.input.StreamedAudioInput] に対する組み込みの中断サポートを提供していません。代わりに、検出されたターンごとにワークフローの別の実行をトリガーします。アプリケーション内で中断を処理したい場合は、[`VoiceStreamEventLifecycle`][agents.voice.events.VoiceStreamEventLifecycle] イベントを監視できます。`turn_started` は新しいターンが文字起こしされ、処理が始まったことを示します。`turn_ended` は、関連するすべての音声が送信された後にトリガーされます。これらのイベントを使用して、モデルがターンを開始したときにスピーカーのマイクをミュートし、関連する音声をすべてフラッシュした後にアンミュートすることができます。
|
||||
|
|
@ -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) のコード例を参照してください。
|
||||
この例を実行すると、エージェントがあなたに話しかけます! [examples/voice/static](https://github.com/openai/openai-agents-python/tree/main/examples/voice/static) の例をチェックして、自分でエージェントと話すデモを見てください。
|
||||
|
|
@ -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]:トレースに含める追加のメタデータです。
|
||||
- [`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]: トレースに含める追加のメタデータです。
|
||||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,11 @@ import os
|
|||
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 @@ do_not_translate = [
|
|||
"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 @@ eng_to_non_eng_mapping = {
|
|||
"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 @@ eng_to_non_eng_instructions = {
|
|||
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(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.
|
||||
specific_instructions = "\n".join(
|
||||
eng_to_non_eng_instructions.get("common", [])
|
||||
+ eng_to_non_eng_instructions.get(lang_code, [])
|
||||
)
|
||||
return f"""You are an expert technical translator.
|
||||
|
||||
# Do not translate
|
||||
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:* `` → ``
|
||||
- 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()
|
||||
|
|
|
|||
Loading…
Reference in a new issue