エージェントの動作をリアルタイムで追跡し、完了した作業やターンの詳細なトレースを確認できます。
Platform ダッシュボードでセッションログを確認できます。
イベントや保存された履歴を通じてセッションを追跡できます。
ターンを確認し、委任されたコマンドの実行を特定できます。
ルートエージェントとサブエージェントの各ターンについて、記録されたトークン使用量を確認できます。
platform.openai.com/logs?api=agents にアクセスし、 エージェント タブを開きます。
ID でセッションを検索すると、そのターン、ツール呼び出し、サブエージェントを確認できます。
トレーシングガイド を参照して、記録されたモデルの応答、ツール呼び出し、サブエージェントのアクティビティをダッシュボードで確認できます。また、公開 API を通じて OTLP JSON 形式でセッショントレースをエクスポート することもできます。
イベントの追跡とセッション履歴の確認
各セッションは、エージェントの動作をリアルタイムで示すイベントストリームを公開します。OPENAI_API_KEY を設定し、以下の例にあるサンプルのセッション ID を、保存しておいたセッション ID に置き換えてください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 // Replace the illustrative IDs and URLs below with your own resource values.
import OpenAI from "openai" ;
const client = new OpenAI ();
const events = await client.beta.agents.sessions.events. stream ( "sess_123" );
try {
for await ( const event of events) {
if (
[
"agent.session.turn.failed" ,
"agent.session.turn.cancelled" ,
"agent.session.failed" ,
"agent.session.environment.failed" ,
"error" ,
]. includes (event.type)
) {
throw new Error ( `Agent lifecycle failure: ${ event . type }` );
}
console. log ( JSON . stringify (event));
}
} finally {
events.controller. abort ();
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 # Replace the illustrative IDs and URLs below with your own resource values.
from openai import OpenAI
client = OpenAI()
session_id = "sess_123"
with client.beta.agents.sessions.events.stream(session_id) as events:
for event in events:
if event.type in {
"agent.session.turn.failed",
"agent.session.turn.cancelled",
"agent.session.failed",
"agent.session.environment.failed",
"error",
}:
raise RuntimeError(f"Agent lifecycle failure: {event.type}")
print(event.to_json(indent=None)) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 // Replace the illustrative IDs and URLs below with your own resource values.
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
ctx := context.Background()
client := openai.NewClient()
events := client.Beta.Agents.Sessions.Events.StreamStreaming(ctx, "sess_123")
defer events.Close()
if events.Err() != nil {
panic(events.Err())
}
for events.Next() {
event := events.Current()
switch event.Type {
case "agent.session.turn.failed", "agent.session.turn.cancelled", "agent.session.failed", "agent.session.environment.failed", "error":
panic(event.RawJSON())
}
fmt.Println(event.RawJSON())
}
if err := events.Err(); err != nil {
panic(err)
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 // Replace the illustrative IDs and URLs below with your own resource values.
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.core.http.StreamResponse;
import com.openai.models.beta.agents.AgentSessionEvent;
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
var json = new JsonMapper();
try (StreamResponse<AgentSessionEvent> events =
client.beta().agents().sessions().events().streamStreaming("sess_123")) {
var iterator = events.stream().iterator();
while (iterator.hasNext()) {
var event = iterator.next();
if (event.turnFailed().isPresent()
|| event.turnCancelled().isPresent()
|| event.failed().isPresent()
|| event.environmentFailed().isPresent()
|| event.error().isPresent()) {
throw new IllegalStateException("Agent failed: " + event);
}
System.out.println(json.writeValueAsString(event));
}
} 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 # Replace the illustrative IDs and URLs below with your own resource values.
require "openai"
require "json"
client = OpenAI::Client.new
events = client.beta.agents.sessions.events.stream_streaming("sess_123")
begin
events.each do |event|
case event.type.to_s
when "agent.session.turn.failed", "agent.session.turn.cancelled", "agent.session.failed", "agent.session.environment.failed", "error"
raise "Agent failed: #{event.to_h}"
end
puts JSON.generate(event.to_h)
end
ensure
events.close
end 1
2
3
4
5 curl -N \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Accept: text/event-stream" \
"https://api.openai.com/v1/agents/sessions/sess_123/events?stream=true"
キューに入った作業を見逃さないよう、アイドルイベントが発生してもストリームは開いたままになります。監視を停止するには Ctrl+C を押します。
セッションの実行中は、次のようなイベントが表示されます。
agent.session.environment.connected
agent.session.turn.created
agent.session.turn.in_progress
agent.session.turn.item.added
agent.session.turn.output_text.delta
agent.session.turn.completed
agent.session.idle
すでに行われた作業を確認するには、セッションに保存された項目を取得します。
1
2
3
4
5
6
7
8
9
10 // Replace the illustrative IDs and URLs below with your own resource values.
import OpenAI from "openai" ;
const client = new OpenAI ();
const sessionId = "sess_123" ;
const items = await client.beta.agents.sessions.items. list (sessionId, {
order: "asc" ,
limit: 100 ,
});
console. log (items.data); 1
2
3
4
5
6
7
8 # Replace the illustrative IDs and URLs below with your own resource values.
from openai import OpenAI
client = OpenAI()
session_id = "sess_123"
items = client.beta.agents.sessions.items.list(session_id, order="asc", limit=100)
print(items.to_json()) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 // Replace the illustrative IDs and URLs below with your own resource values.
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
ctx := context.Background()
client := openai.NewClient()
result, err := client.Beta.Agents.Sessions.Items.List(ctx,
"sess_123",
openai.BetaAgentSessionItemListParams{
Order: "asc",
Limit: openai.Int(100),
})
if err != nil {
panic(err)
}
fmt.Println(result.Data) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 // Replace the illustrative IDs and URLs below with your own resource values.
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.beta.agents.sessions.items.ItemListParams;
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
var result =
client
.beta()
.agents()
.sessions()
.items()
.list(
ItemListParams.builder()
.sessionId("sess_123")
.order(ItemListParams.Order.of("asc"))
.limit(100L)
.build());
System.out.println(result.items()); 1
2
3
4
5
6
7
8
9
10 # Replace the illustrative IDs and URLs below with your own resource values.
require "openai"
client = OpenAI::Client.new
result = client.beta.agents.sessions.items.list(
"sess_123",
order: "asc",
limit: 100
)
puts result.data 1
2
3
4 curl \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
"https://api.openai.com/v1/agents/sessions/sess_123/items?order=asc&limit=100"
セッションのターンは公開 API で取得できます。コマンド項目の turn_id と、保存しておいたセッション ID を使用します。cURL の例には jq が必要です。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 // Replace the illustrative IDs and URLs below with your own resource values.
import OpenAI from "openai" ;
const client = new OpenAI ();
const sessionId = "sess_123" ;
const turns = await client.beta.agents.sessions.turns. list (sessionId, {
limit: 20 ,
order: "desc" ,
});
console. log (turns.data);
const turnId = "turn_123" ;
const turn = await client.beta.agents.sessions.turns. retrieve (turnId, {
session_id: sessionId,
});
console. log (turn.subagent_id); 1
2
3
4
5
6
7
8
9
10
11 # Replace the illustrative IDs and URLs below with your own resource values.
from openai import OpenAI
client = OpenAI()
session_id = "sess_123"
turns = client.beta.agents.sessions.turns.list(session_id, limit=20, order="desc")
print(turns.to_json())
turn_id = "turn_123"
turn = client.beta.agents.sessions.turns.retrieve(turn_id, session_id=session_id)
print(turn.subagent_id) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27 // Replace the illustrative IDs and URLs below with your own resource values.
import (
"context"
"fmt"
"github.com/openai/openai-go/v3"
)
ctx := context.Background()
client := openai.NewClient()
result, err := client.Beta.Agents.Sessions.Turns.List(ctx,
"sess_123",
openai.BetaAgentSessionTurnListParams{
Limit: openai.Int(20),
Order: "desc",
})
if err != nil {
panic(err)
}
fmt.Println(result.Data)
turn, err := client.Beta.Agents.Sessions.Turns.Get(ctx,
"sess_123",
"turn_123")
if err != nil {
panic(err)
}
fmt.Println(turn.SubagentID) 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29 // Replace the illustrative IDs and URLs below with your own resource values.
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.beta.agents.sessions.turns.TurnListParams;
import com.openai.models.beta.agents.sessions.turns.TurnRetrieveParams;
OpenAIClient client = OpenAIOkHttpClient.fromEnv();
var result =
client
.beta()
.agents()
.sessions()
.turns()
.list(
TurnListParams.builder()
.sessionId("sess_123")
.limit(20L)
.order(TurnListParams.Order.of("desc"))
.build());
System.out.println(result.items());
var turn =
client
.beta()
.agents()
.sessions()
.turns()
.retrieve(
TurnRetrieveParams.builder().turnId("turn_123").sessionId("sess_123").build());
System.out.println(turn.subagentId()); 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 # Replace the illustrative IDs and URLs below with your own resource values.
require "openai"
client = OpenAI::Client.new
result = client.beta.agents.sessions.turns.list(
"sess_123",
limit: 20,
order: "desc"
)
puts result.data
turn = client.beta.agents.sessions.turns.retrieve(
"turn_123",
session_id: "sess_123"
)
puts turn.subagent_id 1
2
3
4
5
6
7 curl "https://api.openai.com/v1/agents/sessions/sess_123/turns?limit=20&order=desc" \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY"
curl "https://api.openai.com/v1/agents/sessions/sess_123/turns/turn_123" \
-H "OpenAI-Beta: agents=v1" \
-H "Authorization: Bearer $OPENAI_API_KEY" | jq '.subagent_id'
has_more が true の場合は、返された last_id を次のページの after の値として使用します。
コマンド項目には turn_id が含まれます。そのターンを取得して subagent_id を確認すると、委任を受けてコマンドを実行したエージェントを特定できます。サブエージェント ID が null の場合は、ルートエージェントの作業を示します。コマンド出力の切り詰めは報告されません。
完了したターンとそのエージェントのアクティビティを確認するには、Platform ダッシュボードを使用します。
公開 API を通じて記録済みのトレースを取得するには、プロジェクトの API キーを使ってセッショントレースのエクスポート用エンドポイント を利用します。ダッシュボードのトレース用エンドポイントは、サポート対象の顧客向け API とは別のものです。
ターンリソースには、ベストエフォートで提供される usage と、委任された作業を識別する subagent_id が含まれます。使用量が不明な場合は null になることがあり、値が変わる場合もあります。サブエージェントのトークン使用量の確認 を参照してください。
シェルコマンドの実行元を特定するには、コマンド項目の turn_id が示すターンを取得し、
turn.subagent_id を確認します。
顧客向け API では、コマンド出力が切り詰められたかどうかは示されません。
エージェントは、タスクを完了するまでにモデルを複数回呼び出すことがあります。各呼び出しには、Responses API と同様に、モデルのトークン料金 とプロンプトキャッシュのルール が適用されます。タスクの完了に必要なすべての呼び出しを含めてコストを見積もってください。
モデルの各呼び出しでは、次のトークンが消費される可能性があります。
入力トークン: エージェントへの指示、ツール定義、会話履歴、ユーザー入力、ファイルや画像、ツールの結果
キャッシュされた入力トークン: 一致するプロンプトのプレフィックスから再利用される入力。モデルのキャッシュ入力料金が適用されます
出力トークン: 生成されたテキスト、ツール呼び出しの引数、推論
推論トークンは出力トークンとして課金されます。
サブエージェントもモデルを呼び出すことがあります。モデルのコストを調べる際は、ルートエージェントの作業に加えて、サブエージェントに記録されたターンごとの使用量 も確認してください。
再試行を含むルートエージェントとサブエージェントの作業に加え、該当するツール、サンドボックスのコンピューティング、サードパーティサービスの料金も考慮してください。キャッシュ書き込み料金が設定されているモデルでは、入力をキャッシュに書き込む際にもコストが発生します。以下の Agents API の使用量フィールドにはキャッシュ書き込み分のカウントが個別に含まれないため、この料金が適用される場合、これらのフィールドだけではモデルの正確な料金を算出できません。
エージェントはセッション内でコンテキストを引き継ぎます。連続するモデル呼び出しで同じプロンプトのプレフィックスを共有する場合、プロンプトキャッシュにより、以前の処理を再利用できます。モデルは新しいレスポンスを生成し、キャッシュから過去の回答をそのまま返すわけではありません。セッションを維持しても、キャッシュヒットは保証されません。再利用できるかどうかは、プレフィックスの一致と、モデルのキャッシュ適用条件および有効期間のルールによって決まります。
可能な限り、最初の指示とツール定義は変更せず、新しいタスクの詳細は後続のメッセージに追加してください。ツール検索 では、見つかった定義が会話の末尾に追加されるため、それ以前の内容が維持され、キャッシュを再利用できます。モデルごとのルールについては、プロンプトキャッシュ を参照してください。
キャッシュされた入力の割合が高くても、タスク全体のコスト削減率を示すものではありません。キャッシュされた入力にも料金がかかり、呼び出しを繰り返すと大量の履歴を処理することがあります。アプリケーションに必要な品質とレイテンシーを満たしながら、同じタスクを完了するためのコストを比較してください。
セッションリソースとターンリソースは、ベストエフォートで usage を提供します。使用量が不明な場合は null になることがあり、集計データが届くにつれて記録されたカウントが変わる場合もあります。使用量の記録がないことは、使用量がゼロであることを意味しません。これらのカウントは最終的な請求額を示すものではありません。
記録された使用量オブジェクトには、次のトークンカテゴリが含まれます。
1 2 3 4 5 6 7 8 9 10 11 {
"input_tokens" : 5000 ,
"input_tokens_details" : {
"cached_tokens" : 1500
},
"output_tokens" : 900 ,
"output_tokens_details" : {
"reasoning_tokens" : 200
},
"total_tokens" : 5900
}
この例では、エージェントは 5,000 入力トークンを処理し、900 出力トークンを生成しました。入力トークンのうち 1,500 トークンがキャッシュされており、出力トークンのうち 200 トークンが推論トークンでした。
キャッシュされたトークンは input_tokens に含まれ、推論トークンは output_tokens に含まれます。
セッションのターン を一覧表示または個別に取得し、各ターンの usage を確認します。subagent_id はサブエージェントを識別する値で、ルートエージェントのターンでは null です。has_more が true の場合は、order を同じ値に保ち、last_id を after として渡して残りのターンを取得します。
使用量はベストエフォートで提供されます。不明な場合は null になることがあり、記録された値が変わる場合もあります。各エージェントに記録された使用量は、トレーシングダッシュボード でも確認できます。