# ストリーミングイベント

Source: https://aiand-docs-staging.pages.dev/ja/reference/streaming-events/

ストリーミングレスポンスを要求すると、ai& はモデルの SSE イベントをそのまま中継します(`/v1/responses` での 2 つの小さな修復を除きます。詳しくは後述)。リクエストにオプトインヘッダ `X-Aiand-Metrics: true` を付与した場合、トークン数・コスト・計測時間を含む `metrics` という名前の **trailer イベント** を 1 つだけ追記します。

## OpenAI 形式

```
data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"delta":{"content":"Hel"}}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"delta":{"content":"lo"}}]}

data: {"id":"chatcmpl-...","object":"chat.completion.chunk","choices":[{"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":7,"completion_tokens":2,"total_tokens":9}}

data: [DONE]

event: metrics
data: {"tokens":{"input":7,"output":2,"total":9,"cached":0},"cost":0.000018,"currency":"usd","ttft_ms":120,"inference_ms":850}
```

`metrics` イベントは `[DONE]` の **後** に送出されます。堅牢なクライアントは自然にストリームが閉じるまで接続を保つようにしてください。

## Trailer イベント

| フィールド | 説明 |
|------------|------|
| `tokens.input` | 課金対象の入力トークン数。 |
| `tokens.output` | 課金対象の出力トークン数。 |
| `tokens.total` | 入力 + 出力の合計トークン数。 |
| `tokens.cached` | モデルの割引キャッシュ単価で課金された入力トークン数。キャッシュヒットがない場合は `0`。[プロンプトキャッシュ](/ja/models/pricing/#プロンプトキャッシュ) を参照。 |
| `cost` | リクエストの最終コスト（請求通貨建て）。 |
| `currency` | `cost` の通貨（`usd` または `jpy`）。 |
| `ttft_ms` | 最初のトークンまでの時間（ミリ秒）。モデルへリクエストを送ってから、最初に生成されたテキスト、推論、ツール呼び出しまでを測ります。メタデータだけのチャンクは数えません。出力が生成されなかった場合は `null`。 |
| `inference_ms` | 上流モデルがレスポンス生成に要した時間（ミリ秒）。 |

<Aside type="caution">
  `metrics` をチャット補完チャンクとしてパースしないでください — `event:` 行を付与しているため、未知のイベント名を無視するクライアントは安全にスキップできます。
</Aside>

## 送出されるエンドポイント

trailer は `/v1/chat/completions` と `/v1/responses` のストリームで送出されます。Anthropic 形式の `/v1/messages` のストリームには付与されません — native の `usage` ブロックを読むか、コストは [リクエストログ](/ja/analytics/logs/) を参照してください。


## `/v1/responses` での修復

一部のモデルは、Codex のような厳格なクライアントで問題になる 2 つの小さな不具合を出力するため、ai& は `/v1/responses` でこれらを修復します。

- `response.output_item.added` で `content` なしで通知されたメッセージには `"content": []` を追加します。
- ツール呼び出しの最終的な引数で、浮動小数点数として書かれた整数を整数にします。`{"yield_time_ms":10000.0}` は `{"yield_time_ms":10000}` になります。対象は `response.output_item.done`、`response.function_call_arguments.done`、`response.completed` と `response.incomplete` の `output`、および非ストリーミングの応答です。ストリーミング中の引数のデルタはそのままで、文字列内の数値には手を触れません。

どちらも JSON としての意味は変わらないため、JSON を解析するクライアントには違いはありません。

## なぜ trailer イベントなのか?

これらの修復を除き、ai& はモデルが返すレスポンスボディを一切変更しません。トークン数・コスト・計測時間は終端メッセージの後ろに名前付き SSE イベントとして送出されるため、trailer 以前のバイト列は本家 API の出力と一致し、公式の OpenAI / Anthropic SDK が変更なしで動作します。
