エージェントは、重要な操作ごとに構造化イベントを 診断チャネル へ発行します。RPC 呼び出し、状態変更、スケジュール実行、Workflow の遷移、MCP 接続などです。購読者がいなければ、発行のオーバーヘッドはありません。
各イベントには次のフィールドがあります。
{
type: "rpc", // what happened
agent: "MyAgent", // which agent class emitted it
name: "user-123", // which agent instance (Durable Object name)
payload: { method: "getWeather" }, // details
timestamp: 1758005142787 // when (ms since epoch)
}agent と name は発行元のエージェントを示します。agent はクラス名、name は Durable Object インスタンス名です。
イベントは種類に応じて、名前付きチャネルへ振り分けられます。
| チャネル | イベント種類 | 説明 |
|---|---|---|
agents:state |
state:update |
状態同期イベント |
agents:rpc |
rpc, rpc:error |
RPC メソッドの呼び出しと失敗 |
agents:message |
message:request, message:response, message:clear, message:cancel, message:error, tool:result, tool:approval, submission:create, submission:status, submission:error |
チャットメッセージ、ツール、Think の送信のライフサイクル |
agents:chat |
chat:request:failed, chat:recovery:*, chat:stream:stalled, chat:context:compacted |
チャットリクエスト、復旧、ストール、コンテキスト圧縮のライフサイクル |
agents:transcript |
chat:transcript:repaired |
トランスクリプト修復イベント |
agents:fiber |
fiber:run:*, fiber:recovery:* |
耐久 fiber のライフサイクル |
agents:agent_tool |
agent_tool:recovery:* |
親 / 子のエージェントツール復旧 |
agents:schedule |
schedule:create, schedule:execute, schedule:cancel, schedule:retry, schedule:error, schedule:duplicate_warning, queue:create, queue:retry, queue:error |
スケジュール済みおよびキュー済みタスクのライフサイクル |
agents:lifecycle |
connect, disconnect, destroy |
エージェントの接続と破棄 |
agents:workflow |
workflow:start, workflow:event, workflow:approved, workflow:rejected, workflow:terminated, workflow:paused, workflow:resumed, workflow:restarted |
Workflow の状態遷移 |
agents:mcp |
mcp:client:preconnect, mcp:client:connect, mcp:client:authorize, mcp:client:discover |
MCP クライアント操作 |
agents:email |
email:receive, email:reply, email:send |
メール処理 |
agents/observability の subscribe() は、特定チャネルのイベントへ型安全にアクセスできます。
import { subscribe } from "agents/observability";
const unsub = subscribe("rpc", (event) => {
if (event.type === "rpc") {
console.log(`RPC call: ${event.payload.method}`);
}
if (event.type === "rpc:error") {
console.error(
`RPC failed: ${event.payload.method} — ${event.payload.error}`,
);
}
});
// Clean up when done
unsub();import { subscribe } from "agents/observability";
const unsub = subscribe("rpc", (event) => {
if (event.type === "rpc") {
console.log(`RPC call: ${event.payload.method}`);
}
if (event.type === "rpc:error") {
console.error(
`RPC failed: ${event.payload.method} — ${event.payload.error}`,
);
}
});
// Clean up when done
unsub();コールバックは完全に型付けされます。event は、そのチャネルを流れるイベント型だけに絞り込まれます。
型付きヘルパーは camelCase キーを使います。エージェントツールの復旧は subscribe("agentTool", ...) です。生の診断チャネルを購読する場合は、発行されるチャネル名 agents:agent_tool を使います。
Node.js API で直接購読することもできます。
import { subscribe } from "node:diagnostics_channel";
subscribe("agents:schedule", (event) => {
console.log(event);
});import { subscribe } from "node:diagnostics_channel";
subscribe("agents:schedule", (event) => {
console.log(event);
});本番では、診断チャネルのメッセージはすべて Tail Workers へ自動転送されます。エージェント側に購読コードは不要です。Tail Worker を付け、event.diagnosticsChannelEvents でイベントにアクセスします。
export default {
async tail(events) {
for (const event of events) {
for (const msg of event.diagnosticsChannelEvents) {
// msg.channel is "agents:rpc", "agents:workflow", etc.
// msg.message is the typed event payload
console.log(msg.timestamp, msg.channel, msg.message);
}
}
},
};export default {
async tail(events) {
for (const event of events) {
for (const msg of event.diagnosticsChannelEvents) {
// msg.channel is "agents:rpc", "agents:workflow", etc.
// msg.message is the typed event payload
console.log(msg.timestamp, msg.channel, msg.message);
}
}
},
};本番で構造化され、絞り込めるオブザーバビリティが得られます。エージェントの高頻度実行経路にオーバーヘッドはありません。
独自の Observability インターフェイスを渡すと、デフォルト実装を上書きできます。
import { Agent } from "agents";
const myObservability = {
emit(event) {
// Send to your logging service, filter events, etc.
if (event.type === "rpc:error") {
console.error(event.payload.method, event.payload.error);
}
},
};
class MyAgent extends Agent {
observability = myObservability;
}import { Agent } from "agents";
import type { Observability } from "agents/observability";
const myObservability: Observability = {
emit(event) {
// Send to your logging service, filter events, etc.
if (event.type === "rpc:error") {
console.error(event.payload.method, event.payload.error);
}
},
};
class MyAgent extends Agent {
override observability = myObservability;
}イベント発行をすべて無効にするには、observability を undefined にします。
import { Agent } from "agents";
class MyAgent extends Agent {
observability = undefined;
}import { Agent } from "agents";
class MyAgent extends Agent {
override observability = undefined;
}| 種類 | ペイロード | タイミング |
|---|---|---|
rpc |
{ method, streaming? } |
@callable メソッドが呼ばれたとき |
rpc:error |
{ method, error } |
@callable メソッドが例外を投げたとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
state:update |
{} |
setState() が呼ばれたとき |
これらのイベントは、チャットメッセージのライフサイクル、クライアント側のツール操作、Think の耐久送信を追跡します。
| 種類 | ペイロード | タイミング |
|---|---|---|
message:request |
{} |
チャットメッセージを受信したとき |
message:response |
{} |
チャット応答ストリームが完了したとき |
message:clear |
{} |
チャット履歴がクリアされたとき |
message:cancel |
{ requestId } |
ストリーミングリクエストがキャンセルされたとき |
message:error |
{ error } |
チャットストリームが失敗したとき |
tool:result |
{ toolCallId, toolName } |
クライアントツールの結果を受信したとき |
tool:approval |
{ toolCallId, approved } |
ツール呼び出しが承認または拒否されたとき |
submission:create |
{ submissionId } |
Think の送信が受け付けられたとき |
submission:status |
{ submissionId, status } |
Think の送信ステータスが変わったとき |
submission:error |
{ submissionId, error } |
Think の送信が失敗したとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
chat:request:failed |
{ requestId?, stage, messagesPersisted?, error } |
Think のチャットリクエストが、解析、永続化、実行、またはストリーミング中に失敗したとき |
chat:recovery:detected |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind } |
中断されたチャット fiber を初めて検出したとき |
chat:recovery:attempt |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind } |
フレームワークが復旧を開始したとき |
chat:recovery:scheduled |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind } |
再試行または継続のコールバックがスケジュールされたとき |
chat:recovery:completed |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind } |
復旧が成功したとき |
chat:recovery:skipped |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind, reason? } |
会話が変わった、または復旧不能になったため、復旧をスキップしたとき |
chat:recovery:failed |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind, reason? } |
復旧を実行したが失敗したとき |
chat:recovery:exhausted |
{ incidentId, requestId, attempt, maxAttempts, recoveryKind, reason } |
復旧が設定した試行回数を超えたとき |
chat:stream:stalled |
{ requestId, timeoutMs } |
chatStreamStallTimeoutMs 以内にストリームチャンクが来ず、非アクティブ監視が発火したとき。ターンは耐久復旧へ進みます |
recoveryKind は、未応答のユーザーターンを再生する復旧では "retry"、途中のアシスタントターンを続ける復旧では "continue" です。
| 種類 | ペイロード | タイミング |
|---|---|---|
chat:context:compacted |
{ reason, shortened, requestId?, attempt? } |
Think がコンテキストウィンドウのオーバーフローに対処するため、セッションを圧縮したとき。reason は "proactive"(ステップ前に contextOverflow.proactive ガードが発火)または "reactive"(オーバーフロー後に contextOverflow.reactive が発火)です。shortened は圧縮で履歴が実際に短くなったかどうかです。false は再試行しても再びオーバーフローすることを意味します。コンテキストウィンドウのオーバーフロー復旧 を参照してください。 |
| 種類 | ペイロード | タイミング |
|---|---|---|
chat:transcript:repaired |
{ requestId?, removedToolCalls, normalizedInputs, toolCallIds? } |
Think が永続化したトランスクリプトをプロバイダーへ送る前に修復したとき。removedToolCalls は修復した孤立ツール呼び出しの数、normalizedInputs は文字列化または欠損したツール入力を修復した数です |
| 種類 | ペイロード | タイミング |
|---|---|---|
fiber:run:started |
{ fiberId, fiberName, managed? } |
耐久 fiber が開始したとき |
fiber:run:completed |
{ fiberId, fiberName, managed?, elapsedMs? } |
耐久 fiber が完了したとき |
fiber:run:failed |
{ fiberId, fiberName, managed?, error, elapsedMs? } |
耐久 fiber が例外を投げたとき |
fiber:run:interrupted |
{ fiberId, fiberName, managed?, recoveryReason, elapsedMs? } |
起動時に中断された fiber を見つけたとき |
fiber:recovery:detected |
{ fiberId, fiberName, managed?, recoveryReason, elapsedMs? } |
復旧が中断された fiber を検出したとき |
fiber:recovery:attempt |
{ fiberId, fiberName, managed?, recoveryReason } |
復旧フックが開始したとき |
fiber:recovery:handled |
{ fiberId, fiberName, managed?, recoveryReason, status, elapsedMs? } |
復旧処理が完了したとき |
fiber:recovery:skipped |
{ fiberId, fiberName, managed?, reason, elapsedMs? } |
復旧スキャンが残りの作業をスキップしたとき |
fiber:recovery:failed |
{ fiberId, fiberName, managed?, error, reason?, elapsedMs? } |
復旧フックが失敗したとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
agent_tool:recovery:begin |
{ runCount, totalTimeoutMs? } |
親の復旧が古いエージェントツール実行のスキャンを始めたとき |
agent_tool:recovery:row |
{ runId, agentType, status, reason?, elapsedMs? } |
1 件の古い実行を突き合わせたとき |
agent_tool:recovery:deadline |
{ runId, agentType, elapsedMs? } |
行を検査する前に復旧の期限が尽きたとき |
agent_tool:recovery:complete |
{ runCount, elapsedMs? } |
親の復旧が行のスキャンを終えたとき |
agent_tool:recovery:failed |
{ error } |
親の復旧が予期せず失敗したとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
schedule:create |
{ callback, id } |
スケジュールが作成されたとき |
schedule:execute |
{ callback, id } |
スケジュール済みコールバックが開始したとき |
schedule:cancel |
{ callback, id } |
スケジュールがキャンセルされたとき |
schedule:retry |
{ callback, id, attempt, maxAttempts } |
スケジュール済みコールバックが再試行されたとき |
schedule:error |
{ callback, id, error, attempts } |
すべての再試行のあと、スケジュール済みコールバックが失敗したとき |
schedule:duplicate_warning |
{ callback } |
非冪等なスケジュールが作業を重複する可能性があるとき |
queue:create |
{ callback, id } |
タスクがキューに入ったとき |
queue:retry |
{ callback, id, attempt, maxAttempts } |
キュー済みコールバックが再試行されたとき |
queue:error |
{ callback, id, error, attempts } |
すべての再試行のあと、キュー済みコールバックが失敗したとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
connect |
{ connectionId } |
WebSocket 接続が確立されたとき |
disconnect |
{ connectionId, code, reason } |
WebSocket 接続が閉じられたとき |
destroy |
{} |
エージェントが破棄されたとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
workflow:start |
{ workflowId, workflowName? } |
Workflow インスタンスが開始されたとき |
workflow:event |
{ workflowId, eventType? } |
Workflow へイベントが送られたとき |
workflow:approved |
{ workflowId, reason? } |
Workflow が承認されたとき |
workflow:rejected |
{ workflowId, reason? } |
Workflow が拒否されたとき |
workflow:terminated |
{ workflowId, workflowName? } |
Workflow が終了されたとき |
workflow:paused |
{ workflowId, workflowName? } |
Workflow が一時停止されたとき |
workflow:resumed |
{ workflowId, workflowName? } |
Workflow が再開されたとき |
workflow:restarted |
{ workflowId, workflowName? } |
Workflow が再起動されたとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
mcp:client:preconnect |
{ serverId } |
MCP サーバーへ接続する前 |
mcp:client:connect |
{ url, transport, state, error? } |
MCP 接続の試行が完了または失敗したとき |
mcp:client:authorize |
{ serverId, authUrl, clientId? } |
MCP の OAuth フローが始まったとき |
mcp:client:discover |
{ url?, state?, error?, capability? } |
MCP の能力検出が成功または失敗したとき |
| 種類 | ペイロード | タイミング |
|---|---|---|
email:receive |
{ from, to, subject? } |
メールを受信したとき |
email:reply |
{ from, to, subject? } |
返信メールを送ったとき |
email:send |
{ from, to, subject? } |
メールを送ったとき |