# リクエストログ Source: https://aiand-docs-staging.pages.dev/ja/analytics/logs/ ```http GET /logs?range=&after=&after_id=&errors=&limit= ``` 組織のリクエストログを新しい順に取得します。 同じログは [Console](https://console.aiand.com/analytics?tab=logs) の **Analytics → Logs** からも取得・確認できます。対話的なトラブルシューティングには Console、プログラムによる取得やエクスポートには API を利用してください。 ターミナルからは [ai& CLI](/ja/cli/) で同じログを確認できます。`aiand logs --range 1h --errors` で最近失敗したリクエストを、`aiand logs --follow` で新しいリクエストを追跡して表示します。 ## クエリパラメータ | パラメータ | 型 | 必須 | 説明 | | ---------------- | ------- | ---- | ----------------------------------------------------------------------------------------------- | | `range` | string | 任意 | `15m`、`1h`、`6h`、`24h`、`7days`、`30days`。デフォルト `24h`。 | | `after` | string | 任意 | ページングカーソル — 前ページの `next_after`。`after_id` と併せて指定します。 | | `after_id` | string | 任意 | ページングカーソル — 前ページの `next_after_id`。`after` と併せて指定します。 | | `errors` | boolean | 任意 | `true` で非 2xx のみ。 | | `endpoint` | string | 任意 | この `/v1` パスへのリクエストのみ(例: `/v1/responses`)。 | | `content_logged` | boolean | 任意 | `true` の場合、取得が試みられたリクエストのみ(下記参照)。ページは `request_at` 順になります。 | | `limit` | integer | 任意 | ページサイズ。最大 100。デフォルト 50。 | ## レスポンス ```json { "data": [ { "id": "...", "model": "...", "api_key": "sk-...abcd", "status_code": 200, "ttft_ms": 210, "latency_ms": 420, "input_tokens": 123, "output_tokens": 45, "cached_tokens": 64, "cost": "0.00420000", "currency": "usd", "created_at": "2026-05-18 12:34:56.123456+00", "request_at": "2026-05-18 12:34:55.901234+00", "endpoint": "/v1/chat/completions", "content_logged": true } ], "has_more": true, "next_after": "2026-05-18T12:34:55.654321Z", "next_after_id": "..." } ``` `cost` は `currency`(組織の請求通貨、`usd` または `jpy`)建てで、USD 固定値ではありません。`has_more` が `false` の場合、指定範囲の終端に到達しています。 `ttft_ms` は最初のトークンまでの時間です。ストリーミングのリクエストを受信してから、最初に受信する生成出力(テキスト、推論、ツール呼び出しのいずれか)までのミリ秒数を表します。冒頭のロール通知のようにメタデータだけを含むチャンクは数えません。エンドポイントが送信しない出力も数えません。たとえば `thinking` を指定しない `/v1/messages` の推論です。ストリーミングでないリクエストと、出力の前に終了したストリームでは `null` になります。 `cached_tokens` は `input_tokens` のうち、割引された[キャッシュ入力単価](/ja/models/pricing/#プロンプトキャッシュ)で課金された部分です。キャッシュヒットがない場合は `0`、キャッシュ単価を持たないモデルでは `null` になります。 `request_at` はリクエストを受信した時刻、`created_at` はその少し後に行が確定した時刻です。一覧の並び順とページングは `created_at` 基準ですが、`content_logged=true` の場合は `request_at` 基準になります。`next_after` には常に対応する値が入るため、そのまま渡してください。`endpoint` は `/v1` のパス、`content_logged` は本文の取得が試みられたかどうかを示すもので、保存が必ず成功したことを保証するものではありません。まれに欠落する場合は詳細レスポンスで `unavailable` として現れ、`content_logged: false` にはなりません([内容ログ](#内容ログ)を参照)。 ## ページング 前ページの `next_after` と `next_after_id` を `after` と `after_id` として渡し、`has_more` が `false` になったら終了します。両方送ってください。`after_id` は同じタイムスタンプの行の同点を解消するので、どちらか一方のみの場合は、不足しているパラメータを示す `400 invalid_request_error` が返ります。 `next_after` は不透明なカーソルであり、RFC 3339 のタイムスタンプではありません。値は解析せず、そのまま渡してください。 ## 認証 API キー、または JWT + `X-Org-ID`。[認証](/ja/authentication/) を参照。 ## 単一リクエストの取得(内容付き) ```http GET /logs/{id} ``` 組織で内容ログが有効な場合、1 件のリクエストのメタデータに加えて、取得された**内容**(リクエスト本文とレスポンス)を返します([内容ログ](#内容ログ)を参照)。`id` は一覧から、または全 `/v1` レスポンスで返る `X-Request-ID` ヘッダーから取得できます。 ```json { "id": "...", "state": "ready", "metadata": { "model": "...", "endpoint": "/v1/chat/completions", "api_key": "sk-...abcd", "status_code": 200, "input_tokens": 123, "output_tokens": 45, "cost": "0.00420000", "currency": "usd", "request_at": "2026-05-18 12:34:56.123456+00", "created_at": "2026-05-18 12:34:58.000000+00" }, "content": { "endpoint": "/v1/chat/completions", "streamed": false, "capturedAt": "2026-05-18T12:34:56.123Z", "responseId": "chatcmpl_...", "request": "{ ...送信したリクエスト... }", "response": "{ ...レスポンス... }", "error": null, "truncated": false } } ``` `request` と `response` は**テキスト**として保存されます(非ストリームは JSON 文字列、ストリームは取得された SSE イベントストリーム)。クライアント側でパースしてください。保存値はエンドポイント固有の形式(たとえば `/v1/messages` では Anthropic 形式)を維持しますが、安全に保存するための処理が加わるため、元の通信内容とバイト単位で完全に同一であるとは限りません。インラインメディアのプレースホルダ化とサイズ超過時の切り詰めについては、以下で説明します。 ストリーミングレスポンスでは、保存用コピーの `data:` イベントに含まれる JSON ペイロードだけがインラインメディア置換の対象になります。SSE のフレーミングとメディアを含まないイベントは元の形式のまま解析可能であり、クライアントへ配信されるライブストリームがリクエストログ機能によって変更されることはありません。 原則として、保存されるログ 1 件あたり、リクエスト、レスポンス、付随するメタデータを合わせて **10 MiB(約 10 MB)** が上限です。上限を超える内容は拒否されるのではなく切り詰められ、`truncated` が `true` になり、保存されたテキストには切り詰めを示すマーカーが含まれます。インラインの base64 メディアは、サイズ上限を適用する前に `omitted:;bytes=` プレースホルダへ置き換えられます。 失敗したリクエストでは、`response` は返却されたエラー本文、`error` にはその `message` と `status`(上流のステータスがあればそれ、なければ返却されたステータス)が入ります。上流の本文そのものは保存されません。 クライアント指定のリクエスト ID は `[A-Za-z0-9._:@=+-]{1,36}` に一致する必要があります。独自の `X-Request-ID` がこの形式に合わない場合、サービスは生成した ID に置き換えます。メタデータと内容の取得には、レスポンスで返された `X-Request-ID` を使用してください。 ### `state` `content` は存在しない場合があります。`state` がその理由を示すため、id が不明な場合を除きエラーにはなりません。 | State | 意味 | | ------------- | ------------------------------------------ | | `ready` | メタデータと内容の両方が存在。 | | `processing` | リクエスト完了直後で、メタデータが確定中。 | | `not_logged` | このリクエストでは内容ログがオフだった。 | | `expired` | 30 日を超過し、内容は削除済み。 | | `unavailable` | 内容が想定されるが見つからない。 | メタデータと内容のどちらも存在しない場合のみ `404` を返します。 ## 保存された内容のエクスポート ```http GET /logs/export ``` 組織管理者のみ。指定した期間に内容ログが取得されたリクエストの本文を、gzip 圧縮した [JSON Lines](https://jsonlines.org/) ファイル `request-logs.jsonl.gz` 1 つとして新しい順にダウンロードします。1 行が 1 件のリクエストで、各行は[単一リクエストの取得](#単一リクエストの取得内容付き)の `content` と同じ形です。一覧と同じ `range`・`errors`・`endpoint` パラメータを受け付け、既定値も同じ `24h` です。 1 ファイルに含まれるのは、期間内の新しいものから最大 5,000 件です。それより古いリクエストは、`content_logged=true` を付けて一覧を[ページング](#ページング)し、1 件ずつ取得してください。内容がすでに削除されたリクエストはファイルに含まれません。 管理者が組織を[ゼロデータリテンション](/ja/organizations/zero-data-retention/)に切り替えるとき、Console からこのエクスポートを利用できます。 ## 保存された内容の削除 ```http DELETE /logs ``` 組織管理者のみ。組織のすべてのリクエスト/レスポンス本文の削除を開始し、`202 { "accepted": true }` を返します。削除は数分以内にバックグラウンドで完了します。メタデータ行は残り、対象のリクエストは以後 `unavailable` として開きます。削除はログ取得のスイッチを変更しません。スイッチが ON のままなら、削除後のリクエストは再び保存されます。先にスイッチを OFF にしても、切り替え後最長 1 分ほど取得が続くことがあるため、完全な区切りにはなりません([内容ログ](#内容ログ)を参照)。 ## 内容ログ リクエスト/レスポンス本文の取得は**オプトイン(既定オフ)**です。メタデータ(上記の一覧)は常に記録されますが、リクエストログに**内容**(実際のプロンプトとレスポンス)が保存されるのは内容ログがオンの間のみです。インライン PDF や動画ジョブなど、内容ログの設定にかかわらず内容を保存する機能もあります。一覧は[ゼロデータリテンション](/ja/organizations/zero-data-retention/)を参照してください。 ```http GET /logs/settings PATCH /logs/settings { "log_content_enabled": true } ``` `GET` は `{ "log_content_enabled": , "available": , "data_retention": "standard" | "zero" }` を返し、`PATCH` の結果を即時に反映します。`available` が `false` の場合、内容取得のコントロールを非表示にしてください。削除機能は引き続き利用できます。`PATCH`(組織管理者のみ)は、利用可能な場合にログ取得を切り替えます。[ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織は `"data_retention": "zero"` を返し、ログ取得が利用可能な環境では、ログ取得をオンにする `PATCH` は `403 zero_data_retention` を返します。 組織管理者は、[Console](https://console.aiand.com/settings/organizations) の **Settings → Organizations → Request Logging** からも内容ログをオン/オフできます。このスイッチは、現在の環境で内容保存が利用可能な場合にのみ表示されます。利用できない場合でも、Console から保存済みの内容を削除できます。 --- # メトリクス Source: https://aiand-docs-staging.pages.dev/ja/analytics/metrics/ ```http GET /analytics/metrics?range= ``` 呼び出し元組織の時間バケット集計メトリクスを返します。チャート、ダッシュボード、容量計画に便利です。 ## クエリパラメータ | パラメータ | 型 | 必須 | 説明 | |-----------|------|------|------| | `range` | string | 必須 | `1h`、`24h`、`7days`、`30days`、`3months` のいずれか。サーバ側で適切なバケット幅を選択。 | ## レスポンス ```json { "range": "24h", "buckets": [ { "ts": "2026-05-18T00:00:00Z", "requests": 1234, "input_tokens": 567890, "output_tokens": 12345, "cost_usd": 1.23, "errors": 5, "p50_latency_ms": 420, "p95_latency_ms": 1850 } ] } ``` ## キャッシュ レスポンスは singleflight 重複排除付きで **120 秒** キャッシュされます — その間の繰り返し呼び出しはキャッシュからレスポンスされ、分析バックエンドへの再クエリは発生しません。 ## 認証 API キー、または JWT + `X-Org-ID`。[認証](/ja/authentication/) を参照。 --- # サマリー Source: https://aiand-docs-staging.pages.dev/ja/analytics/summary/ ```http GET /analytics/summary?range= ``` 指定した期間のリクエスト件数と入力・出力トークンの合計、それより前の期間の合計、および現在の期間のトークン時系列を返します。"代表値" を表示する用途に向いています。 ## クエリパラメータ | パラメータ | 型 | 必須 | 説明 | |-----------|------|------|------| | `range` | string | 必須 | `1h`、`24h`、`7days`、`30days`、`3months` のいずれか。 | ## レスポンス ```json { "current": { "requests": 87432, "input_tokens": 12345678, "output_tokens": 234567 }, "previous": { "requests": 80110, "input_tokens": 11023456, "output_tokens": 198765 }, "timeseries": [ { "timestamp": "2026-05-11T00:00:00", "tokens": 1804321 }, { "timestamp": "2026-05-11T01:00:00", "tokens": 1756789 } ] } ``` ## キャッシュ レスポンスは singleflight 重複排除付きで **120 秒** キャッシュされます。 ## 認証 API キー、または JWT + `X-Org-ID`。[認証](/ja/authentication/) を参照。 --- # チャット補完 Source: https://aiand-docs-staging.pages.dev/ja/api/chat-completions/ ```http POST /v1/chat/completions ``` 指定した会話に対してモデル応答を生成します。[OpenAI Chat Completions API](https://platform.openai.com/docs/api-reference/chat/create) と完全互換です。 ## リクエストボディ | パラメータ | 型 | 必須 | 説明 | | ----------------------- | ------------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------- | | `model` | string | はい | モデル ID ([モデル](/ja/api/models/) を参照) | | `messages` | array | はい | 会話メッセージ ([メッセージタイプ](#メッセージタイプ) を参照) | | `stream` | boolean | いいえ | SSE で部分デルタをストリーミング。デフォルト: `false` | | `stream_options` | object | いいえ | `{ "include_usage": true }` で最終ストリームイベントにトークン数を含める | | `temperature` | number | いいえ | サンプリング温度 (0〜2)。デフォルトはモデル依存 | | `top_p` | number | いいえ | Nucleus サンプリングの閾値 (0より大きく1以下) | | `n` | integer | いいえ | 生成する選択肢の数 (1〜128) | | `max_tokens` | integer | いいえ | 生成する最大トークン数 (非推奨 — `max_completion_tokens` を使用) | | `max_completion_tokens` | integer | いいえ | 推論トークンを含む生成トークン数の上限 | | `stop` | string \| string[] | いいえ | 最大 4 つの停止シーケンス | | `frequency_penalty` | number | いいえ | 頻度ペナルティ (-2〜2) | | `presence_penalty` | number | いいえ | 出現ペナルティ (-2〜2) | | `logprobs` | boolean | いいえ | 出力トークンの対数確率を返す | | `top_logprobs` | integer | いいえ | 位置ごとに最も可能性の高いトークン数 (0〜20) | | `response_format` | object | いいえ | `{ "type": "text" }`、`{ "type": "json_object" }`、または `{ "type": "json_schema", "json_schema": {...} }` | | `seed` | integer | いいえ | 決定論的サンプリングのためのシード | | `tools` | array | いいえ | モデルが呼び出し可能な関数ツール | | `tool_choice` | string \| object | いいえ | `"none"`、`"auto"`、`"required"`、または特定のツール | | `parallel_tool_calls` | boolean | いいえ | 並列関数呼び出しを許可 | | `reasoning_effort` | string | いいえ | モデルごとに異なります。[`GET /v1/models`](/ja/models/catalog/) の `reasoning_efforts` を参照してください。モデルの一覧にないレベルは一つ上のレベル(なければ最も高いレベル)で実行され、送信したレベルより高コストになる場合があります。適用されたレベルは `X-Reasoning-Effort` で返されます。effort の語彙にない値は拒否されます | | `top_k` | integer | いいえ | Top-k サンプリング (プロバイダ依存) | | `repetition_penalty` | number | いいえ | 繰り返しペナルティ (プロバイダ依存) | | `user` | string | いいえ | 不正利用追跡用のエンドユーザー識別子 | モデルが reasoning をオフにできるのは、その levels に `none` が含まれる場合だけです。`none` を公開していないモデルへ `reasoning_effort` に `none` を送ると 400 になります。エラー文は [エラー](/ja/errors/#reasoning-をオフにする) にあります。 ### メッセージタイプ #### システムメッセージ ```json { "role": "system", "content": "You are a helpful assistant." } ``` #### ユーザーメッセージ ```json { "role": "user", "content": "What is the capital of France?" } ``` ユーザーメッセージはマルチモーダルなコンテンツ配列も受け付けます: ```json { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://...", "detail": "auto" } } ] } ``` 対応するコンテンツタイプ: `text`、`image_url`、`video_url`、`audio_url`、`input_audio`、`file`。 `image_url`、`video_url`、`audio_url`、`file.file_url` の URL は [URL の要件](/ja/capabilities/vision/#url-の要件) を満たす必要があります。 画像については、インラインの base64 ではなく [Files API](/ja/api/files/) でアップロードして `file_id` で参照することを推奨します。マルチターンの会話やリトライ時に、クライアントからバイト列を再送する必要がなくなります: ```json { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "file", "file": { "file_id": "file-abc123" } } ] } ``` モデルは対応する capability (例: `vision`) を持つ必要があります。持たない場合、リクエストは `400 model_capability_mismatch` で拒否されます。 PDF は、OpenAI SDK や Vercel AI SDK と同じ形でインライン送信することもできます (OpenCode は PDF 添付をこの形で送ります): ```json { "type": "file", "file": { "filename": "report.pdf", "file_data": "data:application/pdf;base64,JVBERi0x..." } } ``` インライン PDF は、[Files API](/ja/api/files/) にアップロードした場合と同じく `purpose: "document"` のファイルとして保存されます。ファイル一覧に表示され、30 日後に期限切れになります。同じ PDF を含む以降のリクエストはそのファイルを再利用するため、ページ画像への変換を待つのは最初のリクエストだけです。モデルには `vision` capability が必要で、PDF は 100 ページまで、以前のリクエストで保存されていない PDF はリクエストあたり 16 MiB までです(以前のリクエストで保存済みの PDF は数えません)。これを超える場合は、PDF を `purpose: "document"` で Files API にアップロードし、`file_id` で参照してください。[ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織はファイルをアップロードできないため、インライン PDF は保存されずメモリ上で描画され、制限は[インライン PDF](/ja/organizations/zero-data-retention/#インライン-pdf)のとおりです。モデルに `vision` capability が必要な点は変わりません。 #### アシスタントメッセージ ```json { "role": "assistant", "content": "The capital of France is Paris." } ``` #### ツールメッセージ ```json { "role": "tool", "tool_call_id": "call_abc123", "content": "{\"result\": 42}" } ``` ## レスポンス ```json { "id": "chatcmpl-abc123", "object": "chat.completion", "created": 1700000000, "model": "google/gemma-4-31b-it", "choices": [ { "index": 0, "message": { "role": "assistant", "content": "Hello! How can I help you today?" }, "finish_reason": "stop" } ], "usage": { "prompt_tokens": 10, "completion_tokens": 9, "total_tokens": 19 } } ``` ### 使用量 (usage) | フィールド | 型 | 説明 | | --------------------------- | ------- | ------------------------------------------ | | `prompt_tokens` | integer | 入力で消費したトークン数 | | `completion_tokens` | integer | 生成された出力トークン数 | | `total_tokens` | integer | 入力と出力の合計 | | `prompt_tokens_details` | object | 任意。`{ cached_tokens, audio_tokens }` | | `completion_tokens_details` | object | 任意。`{ reasoning_tokens, audio_tokens }` | ### 推論 推論モデルは、推論を `message.reasoning_content` と `message.reasoning` (ストリーミングでは `delta.reasoning_content` と `delta.reasoning`) にも返します。両者には同じテキストが入ります。詳しくは [推論](/ja/capabilities/reasoning/) を参照してください。 ## ストリーミング `stream: true` を指定すると、Server-Sent Events として部分的な応答を受け取れます。 ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemma-4-31b-it", "stream": true, "messages": [{"role": "user", "content": "Count to 5"}] }' ``` 各イベントは JSON チャンクを含む `data:` 行で構成されます。ストリームは `data: [DONE]` で終了します。 最終イベントにトークン使用量を含めるには: ```json { "stream": true, "stream_options": { "include_usage": true } } ``` ## ツール呼び出し リクエストでツールを定義すると、モデルがそれらを呼び出すかを選択できます: ```json { "model": "google/gemma-4-31b-it", "messages": [{ "role": "user", "content": "What's the weather in Tokyo?" }], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Get current weather for a location", "parameters": { "type": "object", "properties": { "location": { "type": "string" } }, "required": ["location"] } } } ] } ``` モデルがツールを呼び出すと、レスポンスには `tool_calls` が含まれます: ```json { "choices": [ { "message": { "role": "assistant", "tool_calls": [ { "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"location\": \"Tokyo\"}" } } ] }, "finish_reason": "tool_calls" } ] } ``` 実行結果は `tool` メッセージとして返送し、会話を継続します。 --- # 補完 (廃止) Source: https://aiand-docs-staging.pages.dev/ja/api/completions/ レガシーのテキスト補完エンドポイントで、OpenAI も [Completions API リファレンス](https://platform.openai.com/docs/api-reference/completions) でレガシーとしています。代わりに、プロンプトを user メッセージとして [チャット補完](/ja/api/chat-completions/) に送信してください。 ```diff - POST /v1/completions {"model": "...", "prompt": "Say hello"} + POST /v1/chat/completions {"model": "...", "messages": [{"role": "user", "content": "Say hello"}]} ``` クライアントが対応していれば、[レスポンス](/ja/api/responses/) と [メッセージ](/ja/api/messages/) でも同じモデルを利用できます。 --- # ライフサイクルと有効期限 Source: https://aiand-docs-staging.pages.dev/ja/api/file-lifecycle/ アップロードされたファイルには有効期限があります。ai& は期限切れファイルを自動でクリーンアップし、任意のタイミングでの削除にも対応しています。 ## デフォルトの保持期間 ファイルはアップロードから **30 日間** 保持されます。SDK が対応している場合は個別アップロードに短い有効期限を指定できるほか、明示的に削除することも可能です。 ## 手動削除 ```bash curl -X DELETE https://api.aiand.com/v1/files/file-abc123 \ -H "Authorization: Bearer sk-..." ``` 削除されたファイルは即座にアクセス不能となり、以降の `GET` は `404` を返します。 ## 自動クリーンアップ `expires_at` を過ぎたファイルは自動的に削除されます — バイト列とメタデータの両方が対象です。以降の読み取りは `404` を返します。 ## 参照への影響 ファイル削除後、その `file_id` を参照するチャットリクエストはエラーを返します。削除は取り消せないため、再利用するには再アップロードが必要です。 --- # ファイルの用途 (purpose) Source: https://aiand-docs-staging.pages.dev/ja/api/file-purposes/ アップロードされた各ファイルには `purpose` (用途) が付与されます。これはファイルがどのように使われるか、参照に必要なモデル capability は何かを表すラベルです。 ## サポートする purpose | Purpose | MIME | シングルショット上限 | 使えるモデル | |---------|------|----------------------|--------------| | `vision` | `image/png`、`image/jpeg`、`image/webp`、`image/gif` | 100 MiB | ビジョン対応モデル — [ビジョン](/ja/capabilities/vision/) | | `video` | `video/mp4`、`video/webm`、`video/quicktime` | [Uploads API](/ja/api/uploads/) を利用 (8 GiB) | 動画対応モデル — [動画理解](/ja/capabilities/video/) | 動画生成は GIF を受け付けません。[`/v1/videos`](/ja/api/videos/) のフレームと参照画像は PNG、JPEG、WebP のいずれかである必要があります(`vision` はチャット用に `image/gif` も受け付けます)。 ## MIME からの推論 アップロード時、`purpose` フィールドは **省略可能** です。省略するとファイルの MIME から ai& が自動推論します。これにより purpose フィールドを持たない公式 `anthropic` SDK でもそのまま動作します。 ```bash curl https://api.aiand.com/v1/files \ -H "Authorization: Bearer sk-..." \ -F "file=@cat.png" # 推論結果の purpose: "vision" ``` ## リクエスト時の capability ゲート チャットメッセージ中で `file_id` を参照する場合、ファイルの purpose は対象モデルが宣言する capability と一致する必要があります: - `purpose: "vision"` → モデルに `vision` capability が必要。 - `purpose: "video"` → モデルに `video` capability が必要。 一致しないリクエストは、モデルを呼び出すことなく `400 invalid_request_error` を返します。 --- # OpenAI と Anthropic の形式 Source: https://aiand-docs-staging.pages.dev/ja/api/file-shapes/ ai& の Files API は単一エンドポイントで 2 種類の形式のレスポンスを返します — `anthropic-version` ヘッダの有無で切り替わります。 これにより、公式 `openai` SDK と `anthropic` SDK の両方が同じ URL、同じ API キーで、コード変更なしに動作します。 ## ヘッダによる形式選択 | ヘッダ | レスポンス形式 | |--------|----------------| | `anthropic-version: <任意>` | Anthropic Files API 形式 | | (ヘッダなし) | OpenAI Files API 形式 | ## 例: 同じファイルを 2 形式で取得 ```bash curl https://api.aiand.com/v1/files/file-abc123 \ -H "Authorization: Bearer sk-..." ``` ```json { "id": "file-abc123", "object": "file", "bytes": 12345, "created_at": 1716960000, "filename": "cat.png", "purpose": "vision" } ``` ```bash curl https://api.aiand.com/v1/files/file-abc123 \ -H "Authorization: Bearer sk-..." \ -H "anthropic-version: 2023-06-01" ``` ```json { "id": "file-abc123", "type": "file", "size_bytes": 12345, "created_at": "2026-05-18T12:00:00Z", "filename": "cat.png", "mime_type": "image/png" } ``` ## できること - OpenAI Python SDK の `client.files.create(...)` がそのまま動作。 - Anthropic Python SDK の `client.beta.files.upload(...)` がそのまま動作。 - 一方の SDK でアップロードし、もう一方で取得することも可能 — `file_id` は同一。 --- # ファイル Source: https://aiand-docs-staging.pages.dev/ja/api/files/ Files API を使うと、アセットを一度アップロードして `file_id` で推論リクエストから参照できます。ターンごとにバイト列 (または base64) を再送する必要がありません。[OpenAI Files API](https://platform.openai.com/docs/api-reference/files) のシェイプと完全互換で、`anthropic-version` ヘッダ付きのリクエストには [Anthropic Files API](https://docs.claude.com/en/docs/build-with-claude/files) のシェイプを返します。これにより、公式の `openai` SDK と `anthropic` SDK のどちらも拡張なしで動作します。 ```http POST /v1/files GET /v1/files GET /v1/files/{file_id} GET /v1/files/{file_id}/content DELETE /v1/files/{file_id} ``` ## 制限 | Purpose | 単発の `/v1/files` | [`/v1/uploads`](/ja/api/uploads/) 経由の合計 | 許可される MIME タイプ | |------------|--------------------|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------| | `vision` | 100 MiB | 100 MiB | `image/png`, `image/jpeg`, `image/webp`, `image/gif` | | `video` | 100 MiB | 8 GiB | `video/mp4`, `video/webm`, `video/quicktime` | | `audio` | 100 MiB | 1 GiB | `audio/wav`, `audio/x-wav`, `audio/mpeg`, `audio/mp3`, `audio/flac`, `audio/ogg`, `audio/webm`, `audio/mp4`, `audio/x-m4a` | | `document` | 100 MiB | 1 GiB | `application/pdf` | 動画生成は GIF を受け付けません。[`/v1/videos`](/ja/api/videos/) のフレームと参照画像は PNG、JPEG、WebP のいずれかである必要があります(`vision` はチャット用に `image/gif` も受け付けます)。 アップロードのデフォルト有効期限は 30 日で、ファイルオブジェクトには常に `expires_at` が含まれます。期限切れ後の参照は `410 file_expired` で失敗します。ファイルは `DELETE` によるソフト削除の対象でもあります。 ## ファイルをアップロードする ```http POST /v1/files ``` multipart フォームアップロードです。 | フィールド | 型 | 必須 | 説明 | |-------|------|----------|-------------| | `file` | file | はい | アセットのバイト列 | | `purpose` | string | いいえ | `vision`、`video`、`audio`、`document` のいずれか。制限値と参照可能なモデルを決定します。省略時はファイルの MIME タイプから推測されます — `purpose` を送信しない Anthropic SDK のアップロードでもそのまま動作します | ### 使用例 ```python from openai import OpenAI client = OpenAI( api_key="sk-your-api-key", base_url="https://api.aiand.com/v1", ) with open("photo.png", "rb") as f: file = client.files.create(file=f, purpose="vision") print(file.id) # → file-abc123... ``` ```javascript import OpenAI, { toFile } from "openai"; import fs from "node:fs"; const client = new OpenAI({ apiKey: "sk-your-api-key", baseURL: "https://api.aiand.com/v1", }); const file = await client.files.create({ file: await toFile(fs.createReadStream("photo.png"), "photo.png", { type: "image/png", }), purpose: "vision", }); console.log(file.id); // → file-abc123... ``` ```bash curl https://api.aiand.com/v1/files \ -H "Authorization: Bearer sk-your-api-key" \ -F "file=@photo.png" \ -F "purpose=vision" ``` MIME タイプは multipart パートの `Content-Type` から判定されます。openai-node は `fs.ReadStream` をそのまま渡すと `application/octet-stream` として送信し、どの purpose でも拒否されるため、`toFile` で明示的に `type` を指定してください。 ### レスポンス ```json { "id": "file-abc123def456", "object": "file", "bytes": 482301, "purpose": "vision", "filename": "photo.png", "created_at": 1719450000, "expires_at": 1722042000 } ``` | フィールド | 型 | 説明 | |-------|------|-------------| | `id` | string | `file-` プレフィックス付きの安定 ID。チャット補完のコンテンツパートで使用します | | `object` | string | 常に `"file"` | | `bytes` | integer | ファイルサイズ (バイト) | | `purpose` | string | アップロード時に指定した purpose | | `filename` | string \| null | 提供された場合は元のファイル名 | | `created_at` | integer | Unix タイムスタンプ | | `expires_at` | integer \| null | Unix タイムスタンプ。デフォルトはアップロードから 30 日後 | | `page_count` | integer | `document` アップロードでのみ存在 — PDF のページ数 | ## チャット補完でファイルを参照する ユーザーメッセージ内で `type: "file"` のコンテンツパートを使用します。クライアントが送信するのは ID のみで、バイト列が再度送信されることはありません。 ```json { "model": "", "messages": [{ "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "file", "file": { "file_id": "file-abc123def456" } } ] }] } ``` ```python completion = client.chat.completions.create( model="", messages=[{ "role": "user", "content": [ {"type": "text", "text": "What's in this image?"}, {"type": "file", "file": {"file_id": file.id}}, ], }], ) print(completion.choices[0].message.content) ``` ```javascript const completion = await client.chat.completions.create({ model: "", messages: [{ role: "user", content: [ { type: "text", text: "What's in this image?" }, { type: "file", file: { file_id: file.id } }, ], }], }); console.log(completion.choices[0].message.content); ``` ### 動画の例 ```json { "model": "", "messages": [{ "role": "user", "content": [ { "type": "text", "text": "Describe what happens in this clip." }, { "type": "file", "file": { "file_id": "file-vid789..." } } ] }] } ``` ワイヤーフォーマットは画像と同じです — 送信するのは常に `type: "file"` で、ファイルの `purpose` がモデルへの受け渡し方を決定します。 ### 音声の例 ```json { "model": "", "messages": [{ "role": "user", "content": [ { "type": "text", "text": "Transcribe and summarize this clip." }, { "type": "file", "file": { "file_id": "file-aud456..." } } ] }] } ``` シェイプは同じです。音声をアップロードせずインラインで送る場合は、OpenAI シェイプの `{ "type": "input_audio", "input_audio": { "data": "", "format": "wav" } }` パートを直接送信することもできます。 ### ドキュメント (PDF) の例 ```json { "model": "", "messages": [{ "role": "user", "content": [ { "type": "text", "text": "Summarize this paper." }, { "type": "file", "file": { "file_id": "file-doc456..." } } ] }] } ``` ワイヤーフォーマットは同じ `type: "file"` 参照です。モデルは 1 ページにつき 1 枚の画像を受け取るため、`vision` capability が必要です。ページ数は `GET /v1/files/{file_id}` のレスポンスの `page_count` で確認できます。 PDF の処理はアップロード時に行われるため、アップロード済みのドキュメントであれば、推論レイテンシはそのサイズの影響を受けません。リクエストにインラインで含めた PDF は、それを含む最初のリクエストで同じように処理・保存され、この一覧に表示されます([ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織を除く)。[Chat Completions](/ja/api/chat-completions/) を参照してください。 ## ファイル一覧 ```http GET /v1/files ``` | クエリパラメータ | 型 | 説明 | |-------------|------|-------------| | `purpose` | string | purpose で絞り込み | | `limit` | integer | ページサイズ (1〜100、デフォルト 20) | | `after` | string | カーソル: 前ページの最後のアイテムの `id` を指定 | ファイルは新しい順 (逆時系列) で返されます。 ### 使用例 ```bash curl "https://api.aiand.com/v1/files?purpose=vision&limit=50" \ -H "Authorization: Bearer sk-your-api-key" ``` ### レスポンス ```json { "object": "list", "data": [ { "id": "file-abc...", "object": "file", "bytes": 482301, "purpose": "vision", "filename": "photo.png", "created_at": 1719450000, "expires_at": 1722042000 } ], "has_more": false, "first_id": "file-abc...", "last_id": "file-abc..." } ``` `has_more: true` のときは、次のリクエストの `after` に `last_id` を指定します。SDK のページネーション (`client.files.list().auto_paging_iter()`) は自動的に動作します。 ## ファイルメタデータを取得する ```http GET /v1/files/{file_id} ``` アップロードレスポンスと同じシェイプを返します。 ```bash curl https://api.aiand.com/v1/files/file-abc123 \ -H "Authorization: Bearer sk-your-api-key" ``` ## ファイルコンテンツをダウンロードする ```http GET /v1/files/{file_id}/content ``` 生のバイト列を返します。`Content-Type` と `Content-Disposition` ヘッダはアップロード時のメタデータから設定されます。 ```python content = client.files.content("file-abc123") with open("downloaded.png", "wb") as f: f.write(content.read()) ``` ```bash curl https://api.aiand.com/v1/files/file-abc123/content \ -H "Authorization: Bearer sk-your-api-key" \ -o downloaded.png ``` ## ファイルを削除する ```http DELETE /v1/files/{file_id} ``` ファイルを削除します。以降、その ID を参照する推論リクエストは失敗します。 ```bash curl -X DELETE https://api.aiand.com/v1/files/file-abc123 \ -H "Authorization: Bearer sk-your-api-key" ``` ### レスポンス ```json { "id": "file-abc123", "object": "file", "deleted": true } ``` ファイルが存在しない、または既に削除されている場合は `404` を返します (冪等な動作)。 ## エラー | ステータス | `error.code` | 発生条件 | |--------|--------------|------| | `400` | `invalid_request_error` | `file`/`purpose` の欠落、未知の `purpose`、許可外の mime、ファイルサイズの上限超過 | | `400` | `model_capability_mismatch` | チャット補完が、モデルに無い capability を必要とする purpose のファイルを参照 | | `401` | `invalid_api_key` | `Authorization` ヘッダが欠落または無効 | | `403` | `zero_data_retention` | 組織が[ゼロデータリテンション](/ja/organizations/zero-data-retention/)のため、アップロードできない | | `404` | `file_not_found` | 未知の ID、または別の組織に属する ID | | `410` | `file_expired` | ファイルが `expires_at` を過ぎている | | `500` | `server_error` | 内部エラー | ## 注意事項 - ファイル ID はアップロード元の **組織** にスコープされます。組織をまたいだ参照は `404` を返します。 - 単発の小さな画像であれば、標準の `{type: "image_url", image_url: {url: "data:..."}}` コンテンツパートで base64 をインラインで送ることも可能です。ただしマルチターン会話や大きなアセットでは「一度アップロードしてから参照する」方式の方が効率的です。 --- # メッセージ (Anthropic) Source: https://aiand-docs-staging.pages.dev/ja/api/messages/ ```http POST /v1/messages ``` [Anthropic Messages API](https://docs.anthropic.com/en/api/messages) 形式のリクエストを受け付けます。リクエストは内部の OpenAI 互換形式に変換されて処理され、レスポンスは Anthropic 形式に戻してから返却されます。 これにより、コードを変更することなく Anthropic SDK を ai& と組み合わせて使えます。 ## 使い方 ```python from anthropic import Anthropic client = Anthropic( api_key="sk-your-api-key", base_url="https://api.aiand.com", ) message = client.messages.create( model="google/gemma-4-31b-it", max_tokens=1024, messages=[{"role": "user", "content": "Hello!"}], ) print(message.content[0].text) ``` ```javascript import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ apiKey: "sk-your-api-key", baseURL: "https://api.aiand.com", }); const message = await client.messages.create({ model: "google/gemma-4-31b-it", max_tokens: 1024, messages: [{ role: "user", content: "Hello!" }], }); console.log(message.content[0].text); ``` ## 仕組み 1. リクエストが Anthropic Messages 形式で到着 2. ai& がそれを OpenAI 形式に変換して推論を実行 3. レスポンスを Anthropic 形式に戻して返却 ストリーミングにも対応しています。認証は他のエンドポイントと同じく `Authorization: Bearer` ヘッダを使用します。 ## サポートされるパラメータ Anthropic Messages API の標準パラメータを受け付けます。基となるモデルに対応する機能がないパラメータは、以下の例外を除き無視されます。 - **`tools`** — クライアントツール(type が `custom`、または type なし)は function tool に変換されます。Anthropic のサーバーサイドツール(`web_search_*`、`web_fetch_*`、`code_execution_*`、`tool_search_*` など)は Anthropic の API 内部で実行されるため提供できません。Anthropic 定義のクライアントツール(`bash_*`、`text_editor_*`、`computer_*` など)には Anthropic 以外のモデルが従える `input_schema` がないため、カスタムツールとして送信してください。Anthropic 定義のツール type を含むリクエストは、ツール名を示す `400 invalid_request_error` で拒否されます。 - **`tool_choice`** — `auto`、`any`、`none`、`tool` が対応付けられ、`disable_parallel_tool_use: true` は `parallel_tool_calls: false` になります。 - **`output_config.effort` と `thinking`** — `output_config.effort` は reasoning のレベルを指定し、`thinking: { "type": "disabled" }` は `none` を公開している名前付きの推論モデルで reasoning を無効にします。例外は [reasoning](#reasoning) を参照してください。 - **`tool_result` 内の画像** — vision 対応モデルでは、ツール結果内の画像はそのターンのツール結果の後に続く user メッセージとしてモデルに渡され、それぞれ `tool_use_id` でラベル付けされます。テキストのみのモデルでは、ツールのテキストに `[Image omitted…]` のプレースホルダーが入ります。 ## エラー このエンドポイントのエラーは Anthropic のエンベロープ `{"type":"error","error":{"type":"…","message":"…"},"request_id":"…"}` を使用し、型名も Anthropic のもの(`invalid_request_error`、`authentication_error`、`permission_error`、`not_found_error`、`rate_limit_error`、`api_error` など)です。モデルのコンテキストウィンドウを超えるリクエストは、メッセージが `prompt is too long` で始まり `capability_rejected: prompt_too_long` トークンを含む `400` となります。これは Claude Code の自動圧縮が検出する文言です。 ## キープアライブ ストリーミング応答が 15 秒間アイドルになると、キープアライブが送られます。`message_start` の前は SSE のコメント行、その後は `ping` イベントです。バイト数でストールを検出するクライアント(Claude Code は 300 秒の無通信で中断します)でも、長い推論の間、接続が維持されます。 ## reasoning `thinking` ブロックは reasoning のレベルを指定するものではありません (`budget_tokens` も `enabled` も当社の effort スケールには対応しません)。そのため、深さは原則モデル自身のデフォルトに委ねられます。レベルを指定するには、モデルが公開している [`reasoning_efforts`](/ja/models/catalog/) のいずれかを `reasoning_effort` として送信するか、Claude Code が `/effort` で送信する Anthropic 本来の `output_config: { "effort": "…" }` を使用してください。両方がある場合は明示的な `reasoning_effort` が優先されます。扱いはどちらも `/v1/chat/completions` と同一で、モデルの一覧にないレベルは一つ上のレベル(なければ最も高いレベル)で実行され(送信したレベルより高コストになる場合があります)、effort の語彙にない値は送信したフィールド名を示す `400` となり、適用されたレベルは [`X-Reasoning-Effort`](/ja/reference/response-headers/) で返されます。 例外は `thinking: { "type": "disabled" }` です。これは「reasoning を一切行わない」という、当社のスケールで表現できる唯一の指定であるため、`reasoning_effort: "none"` として適用し、その確認として `X-Reasoning-Effort: none` を返します。`output_config.effort` より優先されるので、thinking を無効にしたリクエストが、そのフィールドの effort で課金されることはありません。`none` を公開していない推論モデルでは、明示的な `reasoning_effort` `none` と同じ文で、`thinking` を指す `400` になります。エラー文は [エラー](/ja/errors/#reasoning-をオフにする) にあります。`reasoning_effort` を併せて送信した場合はそちらが適用され、ブロックはレスポンス形式の制御のみに使われます。`reasoning` 機能を持たないモデルでは、抑制する対象がないため無視されます。 予約名 [`auto`](/ja/models/auto/) では、このブロックはいずれの場合もレベルを指定しません。`auto` は effort を一切受け付けないため、reasoning を無効化したい場合はモデルを直接指定してください。`auto` では Claude Code の `output_config.effort` は拒否せず無視されます。 `thinking` が制御するのは、その reasoning を返すかどうかです。`thinking: { "type": "enabled" }` (`"adaptive"` も同様に受け付けます) を送信すると、reasoning は text ブロックの前に `thinking` コンテンツブロックとして返され、ストリーミングでは `thinking_delta` イベントとして流れます。指定しない場合は回答のみが返ります。 当社が返す `thinking` ブロックに `signature` は含まれません。署名する上流が存在しないため、Anthropic 本家の API にそのまま送り返すと拒否されます。ai& に送り返す場合は問題ありません。リクエストに含まれる `thinking` ブロックはモデルに到達する前に破棄されます。 reasoning モデルの中には、回答全体を reasoning の中に書き、メッセージ本文を空のまま返すものがあります。そうしたレスポンスは `thinking` を要求したかどうかに関わらず通常の `text` ブロックとして返されるため、成功レスポンスには必ず 1 つ以上のコンテンツブロックが含まれます。 ## 画像入力 画像コンテンツブロックは vision 対応モデルでサポートされます。Anthropic の 3 つのソースタイプすべて (`base64`、`url`、および [`POST /v1/files`](/ja/api/files/) で取得した `file_id` を参照する `file`) が動作します。ワイヤーフォーマットの詳細は [Anthropic のコンテンツブロックドキュメント](https://docs.anthropic.com/en/api/messages#content-blocks) を参照してください。`vision` capability を持たないモデルへのリクエストは、推論実行前に `400 invalid_request_error` で拒否されます。`url` ソースは [URL の要件](/ja/capabilities/vision/#url-の要件) を満たす必要があります。 ## ドキュメント入力 PDF の `document` ブロックは vision 対応モデルでサポートされます。ソースは `base64` (`media_type: "application/pdf"`) と、`purpose: "document"` でアップロードしたファイルを参照する `file` です。各ページは画像としてモデルに渡され、`tool_result` 内の PDF はツール結果内の画像と同じように扱われます。`base64` の PDF は `document` ファイルとして保存されて再利用され、制限は [Chat Completions](/ja/api/chat-completions/) のインライン PDF と同じです。ただし[ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織では、保存されずメモリ上で描画され、[専用の制限](/ja/organizations/zero-data-retention/#インライン-pdf)が適用されます。`text` と `content` ソースはテキストとしてモデルに渡されます。`url` ソースは取得されませんが、[URL の要件](/ja/capabilities/vision/#url-の要件) を満たさない場合はリクエストが拒否されます。 --- # モデル Source: https://aiand-docs-staging.pages.dev/ja/api/models/ ```http GET /v1/models ``` モデルを価格とメタデータとともに一覧表示します。 認証は任意です。API キーを付けると、組織が利用権限を持つモデルだけが組織の請求通貨の価格で一覧に含まれます。付けない場合は、ai& が提供するすべてのモデルが USD の価格で一覧に含まれます。キーなしのリクエストは IP ごとに毎分 600 回までに制限されます。この上限は [`GET /v1/videos/models`](/ja/api/videos/#動画モデルの一覧) を含む、キーなしで呼べるすべてのカタログエンドポイントで共有されます。 ## 使用例 ```bash curl https://api.aiand.com/v1/models ``` API キーを使う場合: ```bash curl https://api.aiand.com/v1/models \ -H "Authorization: Bearer sk-your-api-key" ``` ## レスポンス ```json { "object": "list", "data": [ { "id": "google/gemma-4-31b-it", "name": "google/gemma-4-31b-it", "object": "model", "created": 1775474514, "owned_by": "ai&", "provider": "google", "context_window": 262144, "max_output_tokens": 32768, "capabilities": [ "reasoning", "tool_calling", "vision", "video", "document" ], "reasoning_efforts": [ "none", "high" ], "reasoning_effort_default": "none", "description": "Largest Gemma 4 instruction model for open, self-hosted chat and reasoning", "currency": "usd", "input_per_1m": "0.200000", "output_per_1m": "0.500000", "cached_input_per_1m": "0.050000", "deprecation_date": null } ] } ``` ### モデルオブジェクト | フィールド | 型 | 説明 | |-------|------|-------------| | `id` | string | モデル識別子 — リクエストの `model` パラメータにこの値を指定します | | `object` | string | 常に `"model"` | | `created` | integer | Unix タイムスタンプ | | `owned_by` | string | 常に `"ai&"` | | `provider` | string | 上流プロバイダ名 | | `context_window` | integer | 最大コンテキスト長 (トークン数) | | `max_output_tokens` | integer \| null | 記録済みの最大生成トークン数。上限が記録されていないときは `null` | | `description` | string | モデルの簡単な説明 | | `currency` | string | 組織の請求通貨(`usd` または `jpy`) | | `input_per_1m` | string | 入力 100 万トークンあたりのコスト(請求通貨建て)。精度保持のため数値を文字列で返します(例: `"0.150000"`) | | `output_per_1m` | string | 出力 100 万トークンあたりのコスト(請求通貨建て) | | `deprecation_date` | string \| null | モデルがリクエストの受付を終了する日時 (ISO 8601)。終了予定がないときは `null` | ## 使用例 ```bash curl https://api.aiand.com/v1/models \ -H "Authorization: Bearer sk-your-api-key" ``` ## モデル名の解決 推論リクエスト (`/v1/chat/completions`、`/v1/responses`、`/v1/messages`) で指定する `model` パラメータは、`GET /v1/models` のモデル `id` と**完全に一致**している必要があります。大文字と小文字は区別しませんが、部分的な名前は受け付けません。バージョンを省略したモデルファミリー名を指定すると、バージョンを推測せずに `404` (エラーコード `model_not_found`) を返します。有効な名前は `GET /v1/models` で確認してください。 モデルは存在するものの組織に利用権限がない場合は、`404` (エラーコード `model_access_denied`) を返します。このモデルは組織の `GET /v1/models` の一覧にも含まれません。 使用量は、送信した大文字・小文字の表記にかかわらず、常にモデルの正規の `id` で記録・課金されます。 ## コストの計算 ``` cost = (input_tokens / 1_000_000 * input_per_1m) + (output_tokens / 1_000_000 * output_per_1m) ``` クレジットはリクエストが成功するたびに差し引かれます。失敗したリクエスト (4xx / 5xx) は課金されません。 --- # Responses Source: https://aiand-docs-staging.pages.dev/ja/api/responses/ ```http POST /v1/responses ``` 指定した入力に対してモデル応答を生成します。[OpenAI Responses API](https://platform.openai.com/docs/api-reference/responses/create) と互換です。 ## リクエストボディ | パラメータ | 型 | 必須 | 説明 | |-----------|------|----------|-------------| | `model` | string | はい | モデル ID | | `input` | string \| array | はい | テキスト文字列 (ユーザーメッセージとして扱われる) または入力アイテムの配列 | | `instructions` | string | いいえ | コンテキストの先頭に追加されるシステム / デベロッパーメッセージ | | `stream` | boolean | いいえ | SSE でストリーミング。デフォルト: `false` | | `temperature` | number | いいえ | サンプリング温度 (0〜2) | | `top_p` | number | いいえ | Nucleus サンプリング (0より大きく1以下) | | `max_output_tokens` | integer | いいえ | 生成トークン数の上限 | | `tools` | array | いいえ | モデルが呼び出し可能な関数ツール | | `tool_choice` | string \| object | いいえ | `"none"`、`"auto"`、`"required"`、または特定のツール | | `parallel_tool_calls` | boolean | いいえ | 並列ツール呼び出しを許可 | | `reasoning` | object | いいえ | `{ "effort": …, "summary": "auto"\|"concise"\|"detailed" }`。`effort` はモデルごとにその [`reasoning_efforts`](/ja/models/catalog/) と照合されます。一覧にないレベルは一つ上のレベル(なければ最も高いレベル)で実行され、送信したレベルより高コストになる場合があります。適用されたレベルは `X-Reasoning-Effort` で返されます。effort の語彙にない値は 400 になります。 | | `truncation` | string | いいえ | `"auto"` (コンテキストに収まるよう切り詰め) または `"disabled"` | | `metadata` | object | いいえ | トラッキング用のキーバリューペア | | `text` | object | いいえ | テキストレスポンスフォーマットの設定 | | `seed` | integer | いいえ | 決定論的サンプリングのシード | | `stop` | string \| string[] | いいえ | 最大 4 つの停止シーケンス | | `top_k` | integer | いいえ | Top-k サンプリング (プロバイダ依存) | | `repetition_penalty` | number | いいえ | 繰り返しペナルティ (プロバイダ依存) | モデルが reasoning をオフにできるのは、その levels に `none` が含まれる場合だけです。`none` を公開していないモデルへ `reasoning.effort` に `none` を送ると 400 になります。エラー文は [エラー](/ja/errors/#reasoning-をオフにする) にあります。 ### 入力タイプ **単純な文字列:** ```json { "model": "google/gemma-4-31b-it", "input": "Explain quantum computing in one paragraph." } ``` **構造化された入力アイテム:** ```json { "model": "google/gemma-4-31b-it", "input": [ { "role": "user", "content": [ { "type": "input_text", "text": "Describe this image" }, { "type": "input_image", "image_url": "https://..." } ] } ] } ``` **入力アイテムのタイプ:** | タイプ | 説明 | |------|-------------| | メッセージ | `{ "role": "user"\|"assistant"\|"developer"\|"system", "content": string \| content[] }` | | 関数呼び出し | `{ "type": "function_call", "call_id": "...", "name": "...", "arguments": "..." }` | | 関数呼び出しの出力 | `{ "type": "function_call_output", "call_id": "...", "output": "..." }` | **コンテンツタイプ:** `input_text`、`input_image`、`input_file` `input_image` の `image_url`、`input_file` の `file_url`、MCP ツールの `server_url` は [URL の要件](/ja/capabilities/vision/#url-の要件) を満たす必要があります。 PDF は、`input_file` にドキュメントの `file_id` を指定するか、`file_data` (`data:application/pdf;base64,...`) としてインラインで送信します。インラインの PDF は `document` ファイルとして保存され、制限は [Chat Completions](/ja/api/chat-completions/) と同じです([ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織では保存されずメモリ上で描画され、[専用の制限](/ja/organizations/zero-data-retention/#インライン-pdf)が適用されます)。サーバーが各ページを画像に変換し、1 ページにつき 1 つの `input_image` パートとしてモデルに渡します。 ## レスポンス ```json { "id": "resp_abc123", "object": "response", "status": "completed", "created_at": 1700000000, "model": "google/gemma-4-31b-it", "output": [ { "type": "message", "role": "assistant", "content": [ { "type": "output_text", "text": "Quantum computing uses quantum bits (qubits)..." } ] } ], "usage": { "input_tokens": 15, "output_tokens": 80, "total_tokens": 95 } } ``` ### レスポンスのステータス | ステータス | 説明 | |--------|-------------| | `completed` | 生成完了 | | `failed` | 生成失敗 (`error` フィールドを参照) | | `in_progress` | 生成中 (ストリーミング) | | `incomplete` | 途中で停止 (`incomplete_details.reason` を参照) | | `cancelled` | リクエストがキャンセルされた | | `queued` | 処理待ち | ### 使用量 (usage) | フィールド | 型 | 説明 | |-------|------|-------------| | `input_tokens` | integer | 入力で消費したトークン数 | | `output_tokens` | integer | 生成された出力トークン数 | | `total_tokens` | integer | 入力と出力の合計 | | `input_tokens_details` | object | `{ cached_tokens }` | | `output_tokens_details` | object | `{ reasoning_tokens }` | ## マルチターン会話 レスポンスオブジェクトは保存されないため、毎回のリクエストでそれまでのターンを `input` に含めて送信してください。モデルが行った `function_call` も、対応する `function_call_output` と合わせて含めます。空でない `previous_response_id` または `item_reference` 入力アイテム(`{ "id": "..." }` だけで送ったものも含む)を含むリクエストは `400 unsupported_value` で拒否されます。`store` 自体は受け付けますが、無視されます。ただし、Vercel AI SDK など `store: true` がデフォルトのクライアントはそれまでのターンを `item_reference` として送るため、`store: false` を指定してください。ただし、インライン PDF や記録されたリクエスト本文など、リクエストに含まれる内容が保存される場合はあります。何がどれだけの期間保存されるかは[ゼロデータリテンション](/ja/organizations/zero-data-retention/)に記載しています。 ```json { "model": "google/gemma-4-31b-it", "input": [ { "role": "user", "content": "Explain quantum computing in one paragraph." }, { "role": "assistant", "content": "Quantum computing uses quantum bits (qubits)..." }, { "role": "user", "content": "Now explain it to a 5-year-old." } ] } ``` --- # アップロード Source: https://aiand-docs-staging.pages.dev/ja/api/uploads/ Uploads API を使うと、大きなファイル (数百 MB の動画や複数 GB のクリップ) を 5 MiB 以上 64 MiB 以下のパートに分割してアップロードできます。各パートはアップロードセッションに対して送信され、`complete` を呼ぶと通常の [File オブジェクト](/ja/api/files/) に組み立てられ、推論リクエストから `file_id` で参照できるようになります。 [OpenAI Uploads API](https://platform.openai.com/docs/api-reference/uploads) とワイヤ互換です。公式 Python `openai` SDK の `client.uploads.upload_file_chunked(...)` ヘルパーが、一連のシーケンスを 1 回の呼び出しで実行します。相違点は 1 つ: パートは到着順に組み立てられるため、順番に 1 つずつアップロードし、同じ順序で complete してください ([パートのサイズと順序](#パートのサイズと順序) を参照)。 ```http POST /v1/uploads POST /v1/uploads/{upload_id}/parts POST /v1/uploads/{upload_id}/complete POST /v1/uploads/{upload_id}/cancel ``` ## 制限 | 制約 | 値 | | -------------------- | ------------------------------------------------------------------------- | | 合計ファイルサイズ | 8 GiB | | パートあたりのサイズ | 5 MiB 以上 64 MiB 以下。5 MiB 未満にできるのは最後のパートだけです | | セッションの有効期限 | 作成から 1 時間 | | 許可される purpose | `video` (推奨)。`vision` も動作しますが、このサイズで使うケースはまれです | 1 時間以内に完了されなかったセッションは自動的にキャンセルされます。完了したファイルは Files API の標準的な 30 日有効期限を引き継ぎます。 ### パートのサイズと順序 ファイルを 5 MiB 以上のパートに分割してください (SDK ヘルパーは 64 MiB を使います)。最後のパートだけは小さくてもかまいません。 パートは API に到着した順に番号が付けられ、その順序で組み立てられます。パートは順番に 1 つずつアップロードし、`complete` には同じ順序で `part_ids` を渡してください。他のどのパートよりも先に到着した 5 MiB 未満のパートは、それがファイル全体でない限り `400` で拒否されます。順序が入れ替わって到着した場合、`complete` は誤った順序でファイルを組み立てる代わりに `400` で拒否します。指定したパートのサイズの合計は、セッション作成時に申告した `bytes` と正確に一致する必要があります。 ## クイックスタート 最も簡単なのは、Python SDK の高レベルヘルパーを使う方法です。チャンク分割はヘルパーが処理します。Node SDK には同等のヘルパーがないため、JavaScript タブでは生のエンドポイントを直接呼び出します。同じシーケンスを数行多く書くだけです。 ```python from pathlib import Path from openai import OpenAI client = OpenAI( api_key="sk-your-api-key", base_url="https://api.aiand.com/v1", ) upload = client.uploads.upload_file_chunked( file=Path("clip.mp4"), purpose="video", mime_type="video/mp4", ) print(upload.file.id) # → file-vid789... ``` ```javascript import OpenAI, { toFile } from "openai"; import fs from "node:fs/promises"; const client = new OpenAI({ apiKey: "sk-your-api-key", baseURL: "https://api.aiand.com/v1", }); const PART = 64 * 1024 * 1024; const data = await fs.readFile("clip.mp4"); const session = await client.uploads.create({ filename: "clip.mp4", purpose: "video", bytes: data.byteLength, mime_type: "video/mp4", }); const partIds = []; for (let offset = 0; offset < data.byteLength; offset += PART) { const chunk = data.subarray(offset, Math.min(offset + PART, data.byteLength)); const part = await client.uploads.parts.create(session.id, { data: await toFile(chunk, "part"), }); partIds.push(part.id); } const upload = await client.uploads.complete(session.id, { part_ids: partIds }); console.log(upload.file.id); // → file-vid789... ``` どちらの方法も、ファイルを均一なパートに分割し、セッションを開き、パートを順番に 1 つずつアップロードし、アップロード順の part id で `complete` を呼び出します。返される `upload.file.id` は通常の `file-...` ID で、他のファイルと同様にチャット補完で使用できます。 ## マニュアルフロー SDK を使わない場合は、生の HTTP エンドポイントに対して同じフローを実行できます。 ### 1. セッションを作成する ```http POST /v1/uploads ``` | フィールド | 型 | 必須 | 説明 | | ----------- | ------- | ---- | ----------------------------------------------------- | | `filename` | string | はい | 元のファイル名 | | `purpose` | string | はい | `vision` または `video` | | `bytes` | integer | はい | 申告されたファイルの合計サイズ | | `mime_type` | string | はい | MIME タイプ。purpose の許可リストに対して検証されます | ```bash curl https://api.aiand.com/v1/uploads \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "filename": "clip.mp4", "purpose": "video", "bytes": 524288000, "mime_type": "video/mp4" }' ``` #### レスポンス ```json { "id": "upload-abc123", "object": "upload", "bytes": 524288000, "purpose": "video", "filename": "clip.mp4", "status": "pending", "created_at": 1719450000, "expires_at": 1719453600, "file": null } ``` ### 2. パートをアップロードする ```http POST /v1/uploads/{upload_id}/parts ``` `data` フィールドを 1 つだけ含む multipart フォームでアップロードします。最後のパートを除くすべてのパートは 5 MiB 以上である必要があります。いずれのパートも 64 MiB を超えることはできません。パートは順番に 1 つずつアップロードしてください。到着順に番号が付けられ、`complete` にはその順序で指定する必要があります。申告 `bytes` を超えるパートと、ファイル全体ではないのに 5 MiB 未満の最初のパートは、`400` で拒否されます。 ```bash curl https://api.aiand.com/v1/uploads/upload-abc123/parts \ -H "Authorization: Bearer sk-your-api-key" \ -F "data=@clip.part1.bin" ``` #### レスポンス ```json { "id": "part-xyz789", "object": "upload.part", "upload_id": "upload-abc123", "created_at": 1719450010 } ``` ソースファイルのすべてのチャンクを送信し終わるまで繰り返し、各 `part.id` を順序付きで記録しておきます。 ### 3. アップロードを完了する ```http POST /v1/uploads/{upload_id}/complete ``` | フィールド | 型 | 必須 | 説明 | | ---------- | -------- | ------ | ------------------------------------------------------------------------------------------------------------------------------- | | `part_ids` | string[] | はい | ステップ 2 で取得した `part.id` を、アップロードした順序で並べたリスト。サイズの合計は申告した `bytes` と一致する必要があります | | `md5` | string | いいえ | 組み立て後のファイルの MD5 (任意) | ```bash curl https://api.aiand.com/v1/uploads/upload-abc123/complete \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "part_ids": ["part-xyz789", "part-uvw456", "part-rst123"] }' ``` #### レスポンス ```json { "id": "upload-abc123", "object": "upload", "bytes": 524288000, "purpose": "video", "filename": "clip.mp4", "status": "completed", "created_at": 1719450000, "expires_at": 1719453600, "file": { "id": "file-vid789", "object": "file", "bytes": 524288000, "purpose": "video", "filename": "clip.mp4", "created_at": 1719450090, "expires_at": 1722042090 } } ``` `file.id` はチャット補完で参照可能な通常のファイル ID です。ドキュメントの場合、`file` には `GET /v1/files/{file_id}` と同様に `page_count` も含まれます。 complete は冪等です。成功した `complete` のレスポンスが失われた場合、同じセッションに対して再度呼び出すと同じ `file` が返ります。 ### 4. キャンセル (任意) ```http POST /v1/uploads/{upload_id}/cancel ``` ペンディングのセッションを中止します。冪等です — 既に完了済みまたはキャンセル済みのセッションは `404` を返します。 ```bash curl -X POST https://api.aiand.com/v1/uploads/upload-abc123/cancel \ -H "Authorization: Bearer sk-your-api-key" ``` ## チャット補完でファイルを参照する `complete` が `file.id` を返したら、他のファイルと同じように使えます: ```json { "model": "", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe what happens in this clip." }, { "type": "file", "file": { "file_id": "file-vid789" } } ] } ] } ``` 完全な例については [Files → チャット補完でファイルを参照する](/ja/api/files/#チャット補完でファイルを参照する) を参照してください。 ## エラー | ステータス | `error.code` | 発生条件 | | ---------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `400` | `invalid_request_error` | フィールド欠落、未知の `purpose`、許可外の mime、申告 `bytes` が purpose ごとの上限を超過、パート本文が 64 MiB 超、`part_ids` が空または他のアップロードに属する ID を含む | | `400` | `invalid_request_error` | セッションに合わないパート: ファイル全体ではないのに 5 MiB 未満の最初のパート、または申告 `bytes` を超過 | | `400` | `invalid_request_error` | `part_ids` がアップロード順でない、同じパートを 2 回含む、最後以外に 5 MiB 未満のパートを含む、またはサイズの合計が申告 `bytes` と一致しない | | `400` | `invalid_request_error` | `pending` でないアップロード、または有効期限が切れたセッションへのパート追加や完了 | | `401` | `invalid_api_key` | `Authorization` ヘッダが欠落または無効 | | `403` | `zero_data_retention` | 組織が[ゼロデータリテンション](/ja/organizations/zero-data-retention/)のため、アップロードできない | | `404` | `not_found` | 未知の `upload_id`、または別の組織に属する ID | | `500` | `server_error` | 内部エラー。メッセージが新しいアップロードセッションの開始を求めている場合、そのセッションは `failed` になっており再試行できません | ## 注意事項 - アップロードセッションおよび結果として生成されるファイルは、作成した **組織** にスコープされます。 - 各パートは受理された時点で永続的に保存されます。クライアントがアップロード中にクラッシュした場合は、既存の `part_ids` を一覧 (セッション有効期限まで保持) して続きから再開できます。 - レスポンスが失われた後に再送されたパート (OpenAI SDK は接続エラーや 5xx で自動的に再送します) は、使われない 2 つ目のパートになります。組み立てたい ID だけを渡してください。重複分はセッションとともに破棄されます。 - モデルはファイルの purpose に対応する capability を持つ必要があります。`purpose: "video"` には `video` 対応モデルが必要です — [`GET /v1/models`](/ja/api/models/) を参照してください。 --- # 動画 Source: https://aiand-docs-staging.pages.dev/ja/api/videos/ Videos API はテキストプロンプトから動画クリップを生成し、必要に応じてアップロード済みのメディア(first/last フレームとしての 1〜2 枚の画像、または参照画像・動画クリップ・音声クリップ)を条件に指定できます。レンダリングには数秒ではなく数分かかるため、**非同期のジョブリソース**として提供されます。ジョブを作成し、終了ステータスになるまでポーリングし、出力をダウンロードします。 ```http POST /v1/videos GET /v1/videos GET /v1/videos/models GET /v1/videos/acceptance POST /v1/videos/acceptance GET /v1/videos/{video_id} GET /v1/videos/{video_id}/content GET /v1/videos/{video_id}/thumbnail ``` 出力は音声付き MP4、768p です。すべてのリクエストで `aspect_ratio` の指定が必要です。 MiniMax H3 による動画生成は日本国内のハードウェアで実行されます。 日本語のシーン説明は、生成前に英語へ翻訳されます。翻訳時、`…` 内のセリフとシーン内に表示されるテキストはそのまま保持するよう翻訳モデルに指示しています。 ## 利用規約への同意 動画ジョブを開始するには、その人がコンソールのプレイグラウンドで Video Service Terms に同意している必要があります。同意した本人が使う API キーはその後使えます。同じ組織でも、同意していない同僚はジョブを開始できません。 ジョブの作成は同意の記録にはなりません。記録できるのは、コンソールログインからの `POST /v1/videos/acceptance` だけです。API キーでは同意できません。 `GET /v1/videos/acceptance` は、現行の規約バージョンと、この組織でその人が同意済みかを返します。 同意がない場合は `403`、コード `agreement_required` です。ジョブ一覧・取得・モデル一覧は開いたままです。 ## ジョブを作成する ```bash curl https://api.aiand.com/v1/videos \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "minimaxai/minimax-h3", "prompt": "A paper boat drifting down a rain-soaked gutter at dusk", "seconds": 8, "aspect_ratio": "16:9" }' ``` | フィールド | 必須 | 説明 | | ----------------- | ------ | --------------------------------------------------------------------------------------------------------- | | `model` | はい | [`GET /v1/videos/models`](#動画モデルの一覧) が返すモデル ID | | `prompt` | はい | 最大 7000 文字 | | `seconds` | はい | クリップの長さ、4〜30 秒。**16〜30 秒は試験提供中のため、品質が安定しない場合があります。** | | `aspect_ratio` | はい | `Auto`, `21:9`, `16:9`, `4:3`, `1:1`, `3:4`, `9:16` のいずれか | | `image_reference` | いいえ | 一意の `first_frame`/`last_frame` ロールを持つ画像を 1〜2 個(`purpose: "vision"`、image-to-video) | | `references` | いいえ | 条件にする参照メディア(reference-to-video): `images`, `videos`, `audio`。`image_reference` とは併用不可 | ### 最初と最後のフレーム(image-to-video) 最初に各画像をアップロードし、返された `file_id` を使用します。各画像は `purpose: "vision"` の PNG、JPEG、WebP ファイルで、**30 MiB 以下**である必要があります。動画生成では、100 MiB までアップロードできる Files API よりも低い入力上限があります。 ```bash curl https://api.aiand.com/v1/files \ -H "Authorization: Bearer $AIAND_API_KEY" \ -F "purpose=vision" \ -F "file=@first.jpg" ``` 次に、ユーザーが決めた順序で 1〜2 個のファイル参照を送信します。 ```bash curl https://api.aiand.com/v1/videos \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "minimaxai/minimax-h3", "prompt": "A cinematic scene inspired by the references, natural motion", "seconds": 5, "aspect_ratio": "16:9", "image_reference": [ { "file_id": "file-first", "role": "first_frame" }, { "file_id": "file-last", "role": "last_frame" } ] }' ``` API は各ファイルが同じ組織に属し、`purpose: "vision"` であることを検証します。保存済みのファイルは、動画を生成する直前に短時間だけ有効な署名付き URL に変換されるため、公開 URL は不要です。どちらのロールも単独で使用できるため、`first_frame` だけを指定しても `last_frame` は必要ありません。両方を指定する場合、ロールは重複できません。 ### 参照画像・動画・音声(reference-to-video) フレームではなく参照メディアを条件にする場合は、各ファイルを対応する purpose でアップロードし(画像は `vision`、動画は `video`、音声は `audio`)、`file_id` を `references` オブジェクトに入れて渡します。 ```bash curl https://api.aiand.com/v1/videos \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "minimaxai/minimax-h3", "prompt": "A cinematic scene inspired by the references, natural motion", "seconds": 5, "aspect_ratio": "16:9", "references": { "images": [{ "file_id": "file-img1" }], "videos": [{ "file_id": "file-clip1" }], "audio": [{ "file_id": "file-aud1" }] } }' ``` 個数、ファイルごとのサイズ、合計サイズはリクエスト時に検証されます。リクエストした動画より長い動画・音声の参照はカットされ、先頭から `seconds` の長さ分だけが使われます。たとえば 8 秒の動画なら、各クリップの最初の 8 秒です。最良の結果を得るには、2〜15 秒のクリップを使ってください。 | 参照 | purpose | 最大個数 | 最大サイズ | 推奨の長さ | | ---- | -------- | -------- | ---------- | ---------- | | 画像 | `vision` | 9 | 30 MiB | — | | 動画 | `video` | 3 | 50 MiB | 2〜15 秒 | | 音声 | `audio` | 3 | 15 MiB | 2〜15 秒 | 次のルールがあります。 - **フレームと参照は混在できません。** リクエストは `image_reference` か `references` のどちらか一方のみを使い、両方は使えません(別々のリクエスト形式です)。 - **音声にはアンカーが必要です。** `references` には画像または動画が少なくとも 1 つ必要で、音声単独は拒否されます。 - **参照は合計 12 個までです。** 上記の種類ごとの上限に加えて、`references` 全体で 12 個を超えるファイルは指定できません。 - **入力ファイルは合計 256 MiB までです。** 上記のファイルごとの上限に加えて、1 回のリクエストの入力ファイルの合計は 256 MiB を超えられません。同じファイルを 2 つの枠で使う場合は 2 回分として数えます。 - **入力ファイルには 1 時間以上の有効期限が必要です。** 1 時間以内に期限切れになるフレームや参照ファイルは拒否されます。再度アップロードしてください。 - **枠ごとに受け付ける形式が決まっています。** 最初と最後のフレームおよび参照画像は PNG、JPEG、WebP。参照動画は MP4、MOV、WebM。参照音声は WAV、MP3、FLAC、OGG、M4A、または MP4・WebM ファイルに入った音声です。GIF や HEIC など、その他の形式は拒否されます。 - **入力ファイルは空であってはなりません。** 0 バイトのフレームや参照ファイルは拒否されます。 - **画像の縦横比は 1:4〜4:1 の範囲である必要があります。** 長辺が短辺の 4 倍を超えるフレーム画像や参照画像は拒否されます。 - **画像には標準的で読み取り可能なヘッダーが必要です。** JPEG は 8 ビットのベースラインまたはプログレッシブ形式に限られ、マルチピクチャ JPEG(一部の iPhone 写真など)や CMYK の JPEG は拒否されます。Ultra HDR 写真は使用できます。画像ヘッダーはファイルの先頭 64 KiB 以内にある必要があり、メタデータが非常に大きいとそれより後ろにずれることがあります。標準的な PNG または JPEG に変換してください。 - **画像は静止画である必要があります。** アニメーション PNG やアニメーション WebP は拒否されます。 これらのルールに違反したリクエストは `400 invalid_value` で拒否されます。可能な場合、`param` が原因の入力を示します。 レスポンスは `status: "moderating"` のジョブオブジェクトです。 ```json { "id": "video_9f2c1b7e4a3d4e8fa1b0c9d8e7f6a5b4", "object": "video", "model": "minimaxai/minimax-h3", "prompt": "A paper boat drifting down a rain-soaked gutter at dusk", "seconds": 8, "status": "moderating", "error": null, "cost": "0.64000000", "currency": "usd", "created_at": 1755302400, "completed_at": null, "thumbnail": false } ``` `status` は `moderating`、`translating`、`queued`、`in_progress`、`completed`、`failed`、`canceled` のいずれかです。現在 `canceled` で終わるジョブはありません。認識できないステータスは「実行中」として扱ってください — 中間ステージは今後追加される可能性があります。`error` はジョブが失敗した場合のみ設定されます。 ## 入力モデレーション すべてのジョブは `moderating` から始まり、プロンプトと参照メディアがコンテンツポリシーに照らして検査されます。通常は数秒(参照がある場合は最大 1 分程度)で完了し、許可されたジョブはプロンプトを英語へ翻訳する `translating` を経て `queued` に進み、通常どおりレンダリングされます。ポリシーに違反するリクエストはエラーコード `moderation_blocked` で失敗し、課金は発生しません。 ```json { "status": "failed", "error": { "code": "moderation_blocked", "message": "Your request was rejected by our content moderation system." } } ``` モデレーションシステム自体が利用できない場合、ジョブはエラーコード `moderation_unavailable` でフェイルクローズします。何も判定されず課金もされないため、後で再送信してください。同様に、日本語プロンプトの翻訳ができない場合、ジョブはエラーコード `translation_unavailable` でフェイルクローズします。課金はされないため、後で再送信してください。 ## 完了をポーリングする ```bash curl https://api.aiand.com/v1/videos/video_9f2c1b7e4a3d4e8fa1b0c9d8e7f6a5b4 \ -H "Authorization: Bearer $AIAND_API_KEY" ``` 通常のクリップで数分かかります。終了ステータスになるまで 10〜30 秒間隔でポーリングしてください。より短い間隔でポーリングしてもレンダリングは早く終わりません。 ## 出力をダウンロードする `status` が `completed` になったらバイト列を取得します。レスポンスは JSON ではなく MP4 そのものです。 ```bash curl https://api.aiand.com/v1/videos/video_9f2c1b7e4a3d4e8fa1b0c9d8e7f6a5b4/content \ -H "Authorization: Bearer $AIAND_API_KEY" \ -o clip.mp4 ``` `completed` でないジョブのコンテンツを要求すると `400` が返ります。 ### サムネイル 完了したジョブには通常、クリップの冒頭付近から切り出した幅 480 ピクセルの JPEG 静止画もあります。ダウンロードできるサムネイルがある場合、ジョブの `thumbnail` は `true` になります。ない場合は `404` を、ジョブが `completed` でない場合は `400` を返します。 ```bash curl https://api.aiand.com/v1/videos/video_9f2c1b7e4a3d4e8fa1b0c9d8e7f6a5b4/thumbnail \ -H "Authorization: Bearer $AIAND_API_KEY" \ -o clip.jpg ``` サムネイルは無料で、動画と一緒に削除されます。 ## ジョブの一覧 ```bash curl "https://api.aiand.com/v1/videos?limit=20" \ -H "Authorization: Bearer $AIAND_API_KEY" ``` 新しい順に返ります。`limit` の既定値は 20、上限は 100 です。ページングには `after=` を指定します。組織内の全員のジョブが返ります。自分(または API キーの所有者)が作成したジョブだけに絞るには `mine=true` を指定します。 ## 動画モデルの一覧 認証は任意です。API キーを付けると組織の請求通貨で価格が表示され、付けない場合は USD で表示されます。キーなしのリクエストは IP ごとに毎分 600 回までに制限されます。この上限は [`GET /v1/models`](/ja/api/models/) を含む、キーなしで呼べるすべてのカタログエンドポイントで共有されます。 ```bash curl https://api.aiand.com/v1/videos/models ``` API キーを使う場合: ```bash curl https://api.aiand.com/v1/videos/models \ -H "Authorization: Bearer $AIAND_API_KEY" ``` 各エントリには秒単価が、出力解像度ごとに 1 行ずつ含まれます。 ```json { "object": "list", "data": [ { "id": "minimaxai/minimax-h3", "object": "video_model", "name": "MiniMaxAI/MiniMax-H3", "description": null, "pricing": [ { "resolution": "768p", "per_second": "0.055000", "currency": "usd" } ] } ] } ``` ## 課金 レンダリングの料金は `秒単価 × 秒数` で、**完了時にのみ課金されます**。失敗またはタイムアウトしたジョブが課金されることはありません。送信後のジョブはキャンセルできません。 1 回のレンダリングは数ドル規模で途中で中断できないため、料金は送信時に `秒単価 × リクエストした秒数` で確定します。その確定料金と実行中のレンダリング料金の合計を残高がカバーできない場合、ジョブは拒否されます。残高がゼロを超えていればリクエストを受け付けるチャットエンドポイントより厳格です。 ジョブオブジェクトの `cost` と `currency` は最初のレスポンスからこの確定料金を示します。残高からの差し引きは、レンダリングが正常に完了した後にのみ行われます。 ## エラー | ステータス | コード | 意味 | | ---------- | ---------------------------- | ------------------------------------------------------------------------------------ | | `400` | `invalid_value` | 不正なボディ、範囲外の `seconds`、不正またはサイズ超過の参照、完了前のコンテンツ要求 | | `403` | `agreement_required` | この人がコンソールのプレイグラウンドで現行の Video Service Terms に同意していない | | `403` | `zero_data_retention` | 組織が[ゼロデータリテンション](/ja/organizations/zero-data-retention/)のため、動画を生成できない | | `402` | `insufficient_credits` | 残高がこのレンダリングの確定料金に満たない | | `402` | `monthly_budget_reached` | 組織の月間予算の残りが、このレンダリングと実行中のレンダリングの確定料金に満たない | | `404` | `model_not_found` | 不明なモデル | | `404` | `model_access_denied` | 組織にこのモデルの利用権限がない | | `429` | `concurrency_limit_exceeded` | プランで許可された同時レンダリング数に達している | | `429` | `rate_limit_exceeded` | 組織からの送信が 1 分あたり 10 回を超えた。`Retry-After` の秒数後に再試行 | | `409` | `conflict` | ジョブが実行中、または審査中のため削除できない | | `503` | `provider_unavailable` | このモデルの動画生成は一時的に利用できません | 受け付け済みのジョブも失敗することがあります。たとえば次のエラーコードです。失敗したジョブは課金されません。 - `engine_unavailable`:動画生成を利用できませんでした。後で再送信してください。 - `engine_timeout`:制限時間内に動画生成が完了しませんでした。再送信してください。解決しない場合はサポートまでお問い合わせください。 - `engine_rejected`:動画を生成できませんでした。同じ入力で再試行しても同じ結果になります。解決しない場合はサポートまでお問い合わせください。 ## 保持期間と削除 完了したジョブ(生成された動画と、プロンプトを含むジョブ記録)は、完了から **30 日後** に自動的に削除されます。残しておきたいものは、それまでにダウンロードしてください。 `DELETE /v1/videos/{video_id}` で即時に削除できます。 ```bash curl -X DELETE https://api.aiand.com/v1/videos/video_abc123 \ -H "Authorization: Bearer $AIAND_API_KEY" ``` ```json { "id": "video_abc123", "object": "video", "deleted": true } ``` 削除は完全で、取り消せません。実行中のジョブは先に完了させる必要があります。ステータスが終了状態 になるまでポーリングしてから削除してください。 --- # 認証 Source: https://aiand-docs-staging.pages.dev/ja/authentication/ すべての API エンドポイントには認証が必要です。ai& は次の 2 つの方式に対応しています。 ## API キー (推奨) `Authorization` ヘッダに API キーを指定します: ```http Authorization: Bearer sk-your-api-key ``` API キーは組織に紐づきます。各キーから対応する課金アカウントが自動的に解決されます。 ### キーの形式 すべての API キーは `sk-` で始まります。 ### キーの管理 API キーは [コンソール](https://console.aiand.com) または管理 API から作成、一覧、更新、無効化できます: | 操作 | エンドポイント | | -------- | ------------------------------ | | キー一覧 | `GET /api/v1/keys` | | キー作成 | `POST /api/v1/keys` | | キー更新 | `PATCH /api/v1/keys/{key_id}` | | キー削除 | `DELETE /api/v1/keys/{key_id}` | キー管理 API を呼び出す際は、`X-Org-ID` ヘッダに組織 ID を指定してください。 ターミナルからは、[ai& CLI](/ja/cli/) の `aiand login` でブラウザからサインインすると、キーの作成・保存・ローテーションを CLI が代行します。 ## JWT (セッション認証) ブラウザベースのクライアントは、`httpOnly` クッキーに保存された JWT トークンで認証します。コンソール Web アプリで使用される方式であり、プログラムからの API アクセスには推奨しません。 - **アクセストークン**: TTL 15 分、`__Host-access_token` クッキーに設定(API ホストのみ) - **リフレッシュトークン**: TTL 30 日、`__Host-refresh_token` クッキーに設定(API ホストのみ) JWT は OAuth (Google / GitHub)、マジックリンク、または SAML SSO のサインインフローで発行されます。 ### SAML SSO エンタープライズテナントは、Google / マジックリンクでのサインインの代わりに SAML SSO(Okta、Entra ID などの IdP)を有効化できます。SAML の終端は WorkOS が担い、ai& 側は OAuth 風のリダイレクトとして扱います: 1. コンソールが `GET /auth/login/workos` にリダイレクトし、WorkOS AuthKit のサインイン画面へ移動します。組織やドメインは渡しません。 2. ユーザーがその画面で勤務先のメールアドレスを入力すると、WorkOS がメールドメインから SSO 接続を判定し、IdP へ移動します。 3. IdP からのリダイレクト後、`GET /auth/callback/workos` が結果をセッションに交換し、他のサインイン方式と同じ Cookie ベースのフローに合流します。 受け付けるのは、実際に SSO 接続を通ったサインインだけです。AuthKit 自身のパスワードやソーシャルログインで入った場合は、組織に登録済みのメールドメインであっても拒否します。また、メールアドレスが貴社の検証済みドメインのものであるときだけ受け付けます。そのため、SSO で統合されるのは、会社の検証済みドメインのアドレスを持つ既存アカウントだけです。 貴社から最初にサインインした人が ai& 上の組織を作成し、その組織の Admin になります。2 人目以降は同じ組織に Member として参加します。ai& 上でメンバーを除名しても、再サインインは止まりません。IdP 側でアカウントが有効なままだと、次の SSO サインインで再び追加されます。退職者などを確実に外すときは、IdP 側でもアカウントを無効化してください。 SSO を必須にしたメールドメインでは、Google と GitHub のサインインはコンソールの `sso_required` エラーに戻り、マジックリンクの送信は `403` を返します。いずれも SSO でのサインインを案内します。組織で SSO を有効化するには、担当営業にお問い合わせください。 ## 組織コンテキスト API キーは組織に紐づいているため、API キーで認証する場合は組織が自動的に解決されます。 JWT 認証を使う場合は、`X-Org-ID` ヘッダで組織コンテキストを指定してください。 ## エラーレスポンス | ステータス | 意味 | | ---------- | ------------------------------------ | | `401` | 認証情報が欠落しているか無効 | | `402` | 課金アカウントのクレジット残高が不足 | | `403` | 認証情報は有効だが権限が不足 | エラーレスポンスの完全な形式は [エラーコード](/ja/errors/) を参照してください。 --- # 残高 API Source: https://aiand-docs-staging.pages.dev/ja/billing/balance/ ```http GET /billing/balance ``` 組織のプリペイドクレジット残高 — コンソールの請求ページに表示されているのと同じ値 — を返します。残高が減ってきたら、リクエストが `402 Payment Required` で失敗し始める前に通知する、といったスクリプトから利用してください。 ## レスポンス ```json { "balance": "42.75000000", "currency": "usd" } ``` | フィールド | 型 | 説明 | | ---------- | ------ | ---------------------------------------- | | `balance` | string | 請求通貨建ての残高。10 進数の文字列。 | | `currency` | string | `usd` または `jpy`。組織の請求通貨です。 | `balance` は精度を落とさないよう文字列で返します。float ではなく decimal ライブラリで解釈してください。 ## この値の意味 残高は **確定済み** の台帳の値です。そのため、実際に使える額より一時的に大きく見えることがあります: - チャットや補完のリクエストは完了後、非同期の精算キューを経由して差し引かれます。通常は数秒の遅延です。精算が滞留・リトライしている場合はさらに遅れます。 - 動画生成は受け付け時にクレジットを予約しますが、差し引かれるのはレンダリング完了時です。待機中・実行中のレンダリングはまだ反映されていません。 - 処理中のリクエストによって残高が一時的にわずかにマイナスになることがあります。次のチャージでまず相殺されます。 監視用途なら 1 分に 1 回のポーリングで十分です。閾値は上記の遅延を見込んで余裕を持たせてください。 ## 認証 API キー、または JWT + `X-Org-ID`。[認証](/ja/authentication/) を参照。 API キーで呼び出した場合、返されるのは常にそのキーが属する組織の残高です。`X-Org-ID` は無視されます。 ## 例 ```bash curl https://api.aiand.com/billing/balance \ -H "Authorization: Bearer $AIAND_API_KEY" ``` --- # クーポン Source: https://aiand-docs-staging.pages.dev/ja/billing/coupons/ ai& はチェックアウト時のプロモーション割引コードに対応しています。クーポンコードをお持ちの場合は、購入時に入力するとクレジットチャージが割引されます。受け取るクレジットの額は選択した金額そのままで変わりません。 ## 仕組み クーポンを適用すると: - **支払い額が減少** — クーポンによりカードへの請求額が減ります - **クレジットは満額付与** — 残高には、最初に選択した金額がそのまま追加されます - **クレジットに有効期限なし** — 購入方法に関わらず、クレジットは期限切れになりません 例: $100 のクレジットを選択し、`WELCOME10` (10% オフ) を適用した場合。Stripe はカードに $90 を請求し、アカウント残高は $100 増えます。 ## クーポンを適用する 1. **請求ページを開く** — [console.aiand.com/settings/billing](https://console.aiand.com/settings/billing) にアクセスします。 2. **「Purchase Credits」をクリック** — 購入したい金額 (例: $100) を入力します。 3. **「Purchase」をクリック** — Stripe の安全なチェックアウトページにリダイレクトされます。 4. **「Add promotion code」をクリック** — Stripe のチェックアウトページでクーポンコードを入力します。 Stripe チェックアウト画面の「Add promotion code」ボタン 5. **割引を確認** — Stripe が元の金額、割引、最終合計を表示します。 WELCOME10 を適用した Stripe チェックアウト画面 (10% オフ表示) 6. **支払いを完了** — 処理が完了すると、選択した金額が満額でクレジットに加算されます。 ## 適用済みクーポンの確認 [請求ページ](https://console.aiand.com/settings/billing) の支払い履歴では以下が確認できます: - **Credits** — 残高に追加された金額 - **Amount** — カードに実際に請求された金額 - **Coupon** — 適用されたクーポンコード (あれば) ## トラブルシューティング **「The code you entered is invalid (入力されたコードは無効です)」** — クーポンには利用回数の上限や有効期限があります。コードを再確認するか、コードを送ってくれた相手に有効性を確認してください。 **「This code has expired (このコードは有効期限が切れています)」** — クーポンの有効期間が終了しています。発行元に新しいコードを依頼してください。 **「You've already used this code (このコードはすでに使用されています)」** — 顧客ごとに 1 回限りのクーポンがあります。 ## 質問 うまく動作しないクーポンや、サポートが必要な場合は [support@aiand.com](mailto:support@aiand.com) までご連絡ください。 --- # クレジットとチャージ Source: https://aiand-docs-staging.pages.dev/ja/billing/credits/ ai& はプリペイドのクレジットモデルです。組織にクレジットを追加すると、推論リクエストの完了時に残高から自動的に差し引かれます。 ## クレジットの購入 1. [console.aiand.com/settings/billing](https://console.aiand.com/settings/billing) を開きます。 2. **Purchase Credits** をクリックし、金額を選択します。 3. (任意) [クーポン](/ja/billing/coupons/) を適用します。 4. Stripe Checkout で支払い。 決済が成功すると残高が即時に反映されます。Stripe の Webhook で支払いを確認しており、後から決済が失敗した場合は該当クレジットが取り消されます。 ## 課金の仕組み - 各リクエストの課金は完了時に行われ、入力 + 出力トークンから計算されます。 - 差し引きはアトミックに行われるため、並行リクエストでも残高の超過引き落としは起こりません。 - 単価は [料金](/ja/models/pricing/) を参照。 ## 残高 0 のとき 残高がゼロに達すると、新規推論リクエストは `402 Payment Required` を返し、エラーメッセージで通知します。実行中のリクエストは完走するため残高が一時的にわずかにマイナスになる場合がありますが、次回チャージ時に相殺されてから新しいクレジットが追加されます。 --- # 請求書と領収書 Source: https://aiand-docs-staging.pages.dev/ja/billing/invoices/ クレジット購入ごとに請求書と領収書が発行されます。コンソールの課金ページから取得できるほか、課金連絡先にもメール送付されます。 ## 請求書の場所 [console.aiand.com/settings/billing](https://console.aiand.com/settings/billing) → **Payment History** に進みます。各行から以下にアクセスできます: - **領収書** — Stripe ホストの軽量フォーマット。個人記録に。 - **請求書 PDF** — 明細付きのフォーマット。経費精算・経理向け。 ## 請求書の記載内容 - 組織名と請求先住所 (設定済みの場合)。 - 購入日、支払い方法 (末尾 4 桁)。 - 購入クレジット額と請求額 (クーポン適用後)。 - 照合用の Stripe トランザクション ID。 ## 請求先住所の設定 会社名や住所が必要な (経費精算用などの) 請求書は、**Settings → Billing → Billing Details** から登録してください。以降の請求書に反映されます。過去の請求書も依頼ベースで再発行できます。 --- # 支払い方法 Source: https://aiand-docs-staging.pages.dev/ja/billing/payment-methods/ ai& はカード決済に Stripe を使用します。支払い方法は組織の課金アカウントに紐づけられ、複数回のチャージで再利用されます。 ## カードの追加 最初の Checkout 完了時に支払い方法が自動で保存されます。追加のカードを登録したり、デフォルトを変更するには: 1. [console.aiand.com/settings/billing](https://console.aiand.com/settings/billing) を開きます。 2. **Payment Methods** をクリック。 3. Stripe のフォームから新規カードを追加するか、既存のカードをデフォルトに設定。 ## デフォルト支払い方法 デフォルトカードは、将来の自動課金 (オート チャージ機能、近日提供) で使用されます。単発のチャージでは常に支払い方法を選択できます。 ## 対応する支払い方法 - 主要なクレジット / デビットカード (Visa、Mastercard、AmEx、JCB、Discover)。 - 国によっては他の Stripe 対応決済手段が Checkout に表示される場合があります。 ## カードの削除 非デフォルトカードは課金ページから直接削除できます。デフォルトカードを削除するには、まず別のカードをデフォルトに設定してください。 --- # リデンプションコード Source: https://aiand-docs-staging.pages.dev/ja/billing/redemption-codes/ リデンプションコードは、イベント・ハッカソン・ワークショップなどで配布されるコードです。入力すると組織の残高にクレジットが直接追加されます。カード登録も決済も不要で、支払いは発生しません。 [クーポン](/ja/billing/coupons)とは異なります。クーポンは購入時の金額を割引するものですが、リデンプションコードはそれ自体でクレジットを付与します。 ## コードを引き換える 1. **請求ページを開きます** — [console.aiand.com/settings/billing](https://console.aiand.com/settings/billing) 2. **「Redeem a Code」パネル**にコードを入力します。大文字・小文字や空白の違いは問いません。 3. **「Apply Code」をクリックします。** クレジットは即座に残高へ反映され、請求履歴には **Code Redemption** として表示されます。 ## 条件 コードごとに、作成時に設定された次の制限があります。 - **1人につき1回のみ。** 同じアドレスのエイリアスは同一人物として扱われます。`you+anything@gmail.com` と `y.o.u@gmail.com` はこの判定では同じアカウントです。 - **1組織につき1回のみ。** - **引き換え回数の上限。** 上限に達したコードは使用できません。 - **有効期限。** イベント用のコードは当日のみ有効な場合が多くあります。 - **メールドメインの制限(任意、複数指定可)。** 企業や大学のイベント用コードでは、指定されたドメインのアドレスに限定されることがあります。照合は完全一致のため、職員と学生の両方を対象にする場合は両方のドメインを登録します(`u-tokyo.ac.jp` だけでは `s.u-tokyo.ac.jp` は対象になりません)。 - **引き換えられるのは組織の管理者のみです。** クレジットは組織共有の残高に入るため、請求通貨の設定と同じ権限が必要です。 1つのコードで請求通貨ごとに異なる金額を設定できます(例:同じイベントで ¥3,000 と $20)。組織には**その組織の請求通貨**に対応する金額が付与されます。請求通貨は登録時に一度選択し、以降は変更できません。 コードにその通貨の金額が設定されていない場合は、任意の為替レートで換算することはせずエラーになります。2つの金額はそれぞれ独立して設定されるため、一方が他方の換算値というわけではありません。 ## エラーメッセージ | メッセージ | 意味 | | ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------ | | This code wasn't recognised. Please check for errors and try again. | 入力を確認してください。生成されたコードに `0`/`O` や `1`/`I` は使われません。 | | This code has expired and can no longer be redeemed. | 引き換え期間が終了しています。 | | That code has been fully claimed | 引き換え回数の上限に達しています。 | | That code does not grant … credits | 組織の請求通貨に対応する金額がコードに設定されていません。 | | This code has already been redeemed. | 1人・1組織につき1回のみです。 | | That code is restricted to a different email domain | 指定されたドメインのアドレスでのみ使用できます。サブドメインのアドレスをお使いの場合は、主催者に追加を依頼してください。 | | Only organization admins can redeem a code | 組織の管理者に引き換えを依頼してください。 | | Rate limit exceeded. Try again in 3600 seconds. | 失敗した試行には回数制限があります。1時間ほど待ってから再度お試しください。 | | This account is not eligible to redeem codes | アカウント・組織・メールドメインのいずれかがブロックされています。サポートまでお問い合わせください。 | コードで付与されたクレジットに有効期限はなく、リクエスト時の挙動は購入したクレジットと同じです。ただし現金への返金はできません。 --- # 返金ポリシー Source: https://aiand-docs-staging.pages.dev/ja/billing/refunds/ ## 返金可能なケース ai& のクレジットは原則として返金不可です — 推論のための前払いであり、保証金ではありません。例外: - **決済エラー** — 金額誤り、重複請求、不正利用など。Stripe トランザクション ID を添えてサポートにご連絡ください。 - **サービス側の問題** — 大規模障害により直前に購入したクレジットを利用できなかった場合は、ケースバイケースで部分返金を検討します。 - **14 日以内のキャンセル** — 該当チャージのクレジットを一切使用していない場合、購入後 14 日以内に返金を申請できます。 ## クレジットの有効期限 クレジットは **失効しません**。アクティブな組織には残高が永続的に保持されます。 残高が残ったまま組織を削除すると、残高は失われます — 大きな残高がある場合は削除前にサポートまでご連絡ください。 ## チャージバック カード発行会社経由でチャージバックを申請すると、対応額分のクレジットが残高から差し戻されます。残高が不足する場合は、紛争が解決するまで組織が一時停止されます。 --- # 使用量の確認 Source: https://aiand-docs-staging.pages.dev/ja/billing/usage/ 使用量データは 2 か所から確認できます: **コンソールのダッシュボード** (人間向け) と **Analytics API** (プログラム向け)。 ## コンソールのダッシュボード [console.aiand.com](https://console.aiand.com) のダッシュボードでは以下が見られます: - 現在のクレジット残高。 - 24 時間、7 日、30 日の使用量。 - リクエスト数とコストの上位モデル。 - 最近のリクエスト一覧 (ステータス、レイテンシ、コスト)。 ## Analytics API 自動レポート用には [Analytics](/ja/analytics/metrics/) エンドポイントを利用します: - `GET /analytics/metrics` — リクエスト・トークンの時系列。 - `GET /analytics/summary` — 期間集計サマリー。 - `GET /logs` — カーソルページネーション付きのリクエスト単位ログ。 各エンドポイントのページに、そのエンドポイントが受け付ける `range` の値が記載されています。 ターミナルからは、[ai& CLI](/ja/cli/) の `aiand usage --range 30days` で指定期間のリクエスト数とトークン数を、前の期間と比較して確認できます。 `GET /analytics/metrics` と `GET /analytics/summary` は期間内のリクエスト数とトークンを返します。`GET /analytics/metrics` は 1 秒あたりのトークン、レイテンシ、最初のトークンまでの時間も返します。`GET /logs` の各行にはそのリクエストのコストと通貨が含まれます。残っている額は [残高 API](/ja/billing/balance/) で取得できます。 ## リクエスト単位のコスト リクエストに `X-Aiand-Metrics: true` ヘッダを付けると、レスポンスの `X-Cost` と `X-Cost-Currency` ヘッダでそのリクエストの正確なコスト(請求通貨建て)を受け取れます。ストリーミングレスポンスでは末尾の trailer イベントに同じ値が含まれます。[レスポンスヘッダ](/ja/reference/response-headers/) と [ストリーミングイベント](/ja/reference/streaming-events/) を参照。 --- # 推論 Source: https://aiand-docs-staging.pages.dev/ja/capabilities/reasoning/ 推論モデルは、回答の前に推論を書き出します。これらのモデルは [`GET /v1/models`](/ja/models/catalog/) の `capabilities` に `reasoning` を含みます。推論トークンは出力トークンとして課金され、usage では `reasoning_tokens` として別に集計されます。 ## Chat Completions 推論は `content` と並んで、`reasoning_content` と `reasoning` の 2 つの名前で返ります。両者には常に同じテキストが入ります。フィールド名はエンジンやクライアントライブラリによって異なるため、すべてのモデルが両方を返します。クライアントが想定する方を読んでください。 ```json "message": { "role": "assistant", "content": "391", "reasoning_content": "17 × 23 = 17 × 20 + 17 × 3 = 340 + 51 = 391.", "reasoning": "17 × 23 = 17 × 20 + 17 × 3 = 340 + 51 = 391." } ``` ストリーミングでは、まず両方のフィールドを持つ delta で推論が届き、その後に回答が `delta.content` で届きます。 ```text data: {"choices":[{"index":0,"delta":{"reasoning_content":"17 × 23","reasoning":"17 × 23"},"finish_reason":null}],...} data: {"choices":[{"index":0,"delta":{"content":"391"},"finish_reason":null}],...} ``` ```python stream = client.chat.completions.create( model="moonshotai/kimi-k3", messages=[{"role": "user", "content": "17 × 23 は?"}], stream=True, ) for chunk in stream: if not chunk.choices: continue delta = chunk.choices[0].delta reasoning = getattr(delta, "reasoning_content", None) if reasoning: print(reasoning, end="") if delta.content: print(delta.content, end="") ``` 以降のターンで推論を送り返す必要はありません。送信した assistant ターンに両方のフィールドが値を持つ場合は、`reasoning_content` が使われます。 ## Responses 推論は、メッセージより前に `reasoning` タイプの出力アイテムとして返ります。モデルが推論テキストを返す場合は `content[].text`(タイプ `reasoning_text`)に入り、要約が生成される場合は代わりに `summary[].text` に入ります。usage では `output_tokens_details.reasoning_tokens` に集計されます。 ## Messages `thinking: { "type": "enabled" }`(または同じく扱われる `"adaptive"`)を指定すると推論を受け取れます。推論はテキストより前の `thinking` コンテンツブロックとして返ります。ストリーミングでは、`delta.type` が `thinking_delta` の `content_block_delta` イベントで届きます。指定しない場合は回答のみが返ります。ただし、モデルが応答全体を推論の中に書いた場合、そのターンは通常の `text` ブロックとして返ります。詳しくは [Messages](/ja/api/messages/) を参照してください。 ## 推論レベル 推論レベルは、Chat Completions では `reasoning_effort`、Responses では `reasoning.effort`、Messages では `reasoning_effort` または `output_config.effort` で指定します。各モデルが受け付けるレベルは [`GET /v1/models`](/ja/models/catalog/) の `reasoning_efforts` に記載されています。適用されたレベルは [`X-Reasoning-Effort`](/ja/reference/response-headers/) で返ります。レベルの検証方法は、各エンドポイントのページを参照してください。 --- # ストリーミング Source: https://aiand-docs-staging.pages.dev/ja/capabilities/streaming/ すべての生成系エンドポイントはストリーミングに対応しています。リクエストに `stream: true` を指定すると、レスポンスは Server-Sent Events (SSE) として配信されます。 ## ストリーミングを有効化する ```python stream = client.chat.completions.create( model="...", messages=[{"role": "user", "content": "Hello"}], stream=True, stream_options={"include_usage": True}, ) for chunk in stream: if chunk.choices: print(chunk.choices[0].delta.content or "", end="") ``` ```python with client.messages.stream( model="...", max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], ) as stream: for text in stream.text_stream: print(text, end="") ``` ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-..." \ -d '{"model":"...","stream":true,"messages":[{"role":"user","content":"Hello"}]}' ``` ## 受信内容 - **OpenAI 形式**: `data: {...}` イベント (`choices[].delta` のチャンク) と最終の `data: [DONE]`。 - **Anthropic 形式**: 型付きイベント — `message_start`、`content_block_delta`、`message_delta`、`message_stop`。 - **ai& の trailer** (OpenAI 形式、オプトイン): リクエストヘッダ `X-Aiand-Metrics: true` を付与すると、モデルの終端イベントの後ろにトークン数・コスト・通貨を含む `metrics` イベントを ai& が追記します。[ストリーミングイベント](/ja/reference/streaming-events/) を参照。 ## ストリーム中の usage / コスト OpenAI 形式では `stream_options.include_usage = true` を指定すると、trailer イベントの直前の最終 SSE イベントに `usage` が含まれます。Anthropic 形式は常に `message_delta` に usage を含みます。 --- # 構造化出力 Source: https://aiand-docs-staging.pages.dev/ja/capabilities/structured-outputs/ 構造化出力を使うと、指定したスキーマに従う JSON をモデルに出力させられます。パース失敗や項目の欠落が発生しません。 ## JSON モード 最もシンプルな方式。`response_format` に `json_object` を指定します: ```json { "model": "...", "messages": [...], "response_format": { "type": "json_object" } } ``` モデルは構文的に正しい JSON を必ず返します。具体的な形はプロンプト次第です。 ## strict な JSON Schema 形まで保証したい場合は、スキーマを渡します: ```python response = client.chat.completions.create( model="...", messages=[{"role": "user", "content": "Extract: Jane Doe, jane@example.com"}], response_format={ "type": "json_schema", "json_schema": { "name": "contact", "strict": True, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "email": {"type": "string"}, }, "required": ["name", "email"], "additionalProperties": False, }, }, }, ) ``` `strict: true` を指定すると、出力はスキーマに厳密に従います — 余分なフィールドや必須フィールドの欠落はありません。 ## OpenAI Python SDK との組み合わせ SDK は Pydantic モデルからスキーマを自動生成できます (`client.chat.completions.parse()` または `responses.parse()`)。 --- # ツール呼び出し Source: https://aiand-docs-staging.pages.dev/ja/capabilities/tool-calling/ ツール呼び出し (function calling) は、提供した JSON ツール定義に基づいてモデルが構造化された関数呼び出しを生成する機能です。ai& は OpenAI Chat Completions と Anthropic Messages の両方の API でツール呼び出しに対応しています。 ## ツールの定義 ```python tools = [{ "type": "function", "function": { "name": "get_weather", "description": "Get current weather for a city.", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, }, }] response = client.chat.completions.create( model="...", messages=[{"role": "user", "content": "Weather in Tokyo?"}], tools=tools, tool_choice="auto", ) ``` ```python tools = [{ "name": "get_weather", "description": "Get current weather for a city.", "input_schema": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, }] response = client.messages.create( model="...", max_tokens=1024, tools=tools, messages=[{"role": "user", "content": "Weather in Tokyo?"}], ) ``` ## 並列ツール呼び出し OpenAI 形式のリクエストでは `parallel_tool_calls: true` (デフォルト) を指定して、1 ターンで複数のツール呼び出しを生成できます。 ## tool_choice の制御 - `"auto"` — モデルがツールを使うかどうかを判断 (`tools` を指定した場合のデフォルト)。 - `"none"` — このリクエストではツール利用を無効化。 - `"required"` — 必ずツールを呼び出させる。 - `{ "type": "function", "function": { "name": "..." } }` — 特定のツールに限定。 --- # 動画理解 Source: https://aiand-docs-staging.pages.dev/ja/capabilities/video/ 動画対応モデルはテキストと一緒に動画クリップを受け付けます。動画は 2 通りの方法で渡せます: アップロードを `file_id` で参照するか、インライン URL を指定するかのいずれかです。 ## オプション 1: 先にアップロードして `file_id` で参照する (推奨) 複数のリクエストで同じクリップを使う場合や、どこにも公開ホスティングしていないファイルを使う場合は、こちらを使ってください。 1. [Uploads API](/ja/api/uploads/) (最大 8 GiB のチャンクアップロード) に `purpose: "video"` でアップロード、または `purpose` を省略して MIME から推論。 2. 返却された `file-...` ID をチャットメッセージで参照: ```json { "role": "user", "content": [ { "type": "text", "text": "Summarize this clip." }, { "type": "file", "file": { "file_id": "file-abc123" } } ] } ``` 推論時にストレージからバイト列が取得されるため、クライアント側で再アップロードは不要です。 ## オプション 2: インライン `video_url` 動画がすでに公開 URL にある場合は、URL を直接参照できます: ```json { "role": "user", "content": [ { "type": "text", "text": "Summarize this clip." }, { "type": "video_url", "video_url": { "url": "https://example.com/clip.mp4" } } ] } ``` URL は ai& から到達可能で、対応している `Content-Type` でバイト列を返す必要があります。また、[URL の要件](/ja/capabilities/vision/#url-の要件) (ポート 443 の `https`、公開ホスト名) を満たす必要があります。 ## 上限 - 対応 MIME: `video/mp4`、`video/webm`、`video/quicktime`。 - アップロードファイル: チャンク [Uploads API](/ja/api/uploads/) 経由で最大 8 GiB。シングルショットの `/v1/files` は 100 MiB が上限です。 ## Capability ゲート どちらの方法でも、対象モデルが `video` capability を宣言している必要があります — そうでない場合は `400 invalid_request_error` が返ります。モデルと capability の一覧は [Models](/ja/api/models/) を参照。 --- # ビジョン Source: https://aiand-docs-staging.pages.dev/ja/capabilities/vision/ ビジョン対応モデルはテキストと一緒に画像入力を受け付けます。ai& は 3 種類の入力方式に対応しているため、用途に合わせて選択してください。 ## 画像を渡す 3 つの方法 ```json { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "https://example.com/cat.png" } } ] } ``` ```json { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "image_url", "image_url": { "url": "data:image/png;base64,iVBORw0KG..." } } ] } ``` ```json { "role": "user", "content": [ { "type": "text", "text": "What's in this image?" }, { "type": "file", "file": { "file_id": "file-abc123" } } ] } ``` ## URL の要件 ai& はリクエストがモデルに届く前にメディア URL を検査します。対象は `image_url`、`video_url`、`audio_url` パート、Responses の `input_image` の `image_url`、チャットの `file` パートと Responses の `input_file` の `file_url`、`type: "url"` の Anthropic ソース、Responses の MCP ツールの `server_url` です。URL は次の条件をすべて満たす場合のみ受け付けられます: - 絶対 URL で、スキームが `https` であること。`http` などほかのスキームは拒否されます。 - デフォルトのポート 443 を使うこと。 - ユーザー名やパスワードを含まないこと。 - IP アドレスではなくホスト名を指定すること。IPv4 と IPv6 のどの表記も対象です。 - `.com` や `.jp` などの公開トップレベルドメインで終わること。`localhost`、ドットを含まない単一ラベルの名前、`.local` や `.internal` 配下の名前は拒否されます。 `data:` URL や `file_id` で送るメディアは検査の対象外です。 条件を満たさない URL には、`type: "invalid_request_error"`、`code: "invalid_media_url"` の `400` が返ります。`param` には該当フィールドが入ります (例: `messages.0.content.1.image_url.url`)。`/v1/messages` では [Anthropic のエンベロープ](/ja/errors/#エラー形式) で返ります。リクエストはモデルに届かず、課金もされません。 メディア URL の場合は、ファイルを公開 `https` URL でホストするか、[Files API](/ja/api/files/) でアップロードして `file_id` を渡すか、base64 の `data:` URL としてインラインで送信してください。MCP の `server_url` は、それ自体が公開 `https` URL である必要があります。 ## file_id 方式の仕組み `{type: "file", file: {file_id}}` を送ると、アップロード済みのバイト列がモデルに渡されます — 公開ホスティングは不要です。クライアント側のワイヤーフォーマットはどの方式でも変わりません。 画像は [Files](/ja/api/files/) から `purpose: "vision"` でアップロード、または `purpose` を省略すると MIME から推論されます。 対応 MIME: `image/png`、`image/jpeg`、`image/webp`、`image/gif`。最大サイズ: 100 MiB。 ## Capability ゲート ビジョンリクエストは、対象モデルが `vision` capability を持たない場合は拒否されます — インラインの `image_url` パートでも、purpose がビジョンに対応する `file_id` 参照でも同様です。モデルと capability の一覧は [Models](/ja/api/models/) を参照。 --- # ai& CLI Source: https://aiand-docs-staging.pages.dev/ja/cli/ ai& CLI (`aiand`) は、ブラウザ経由でサインインし、API キーの管理を代行するコマンドラインツールです。コーディングエージェントを ai& で動かすための設定、プロンプトの送信、さらにモデルカタログ・リクエストログ・使用量の確認といったコンソールでの日常的な作業をターミナルから行えます。ソースコードは [github.com/aiandlabs/aiand-cli](https://github.com/aiandlabs/aiand-cli) で公開しています。 ```bash npm install -g @aiand/cli aiand code # サインインし、OpenCode を設定して ai& 上で起動 aiand run "hello" # またはプロンプトを 1 つだけ送信 ``` ## インストール Node.js 22 以降が必要です。 ```bash npm install -g @aiand/cli ``` ```bash curl -fsSL https://raw.githubusercontent.com/aiandlabs/aiand-cli/main/install.sh | bash ``` ```powershell irm https://raw.githubusercontent.com/aiandlabs/aiand-cli/main/install.ps1 | iex ``` インストールスクリプトはシェルのプロファイルを編集して `aiand` を `PATH` に追加します。この変更を行わない場合は `AIAND_NO_MODIFY_PATH=1` を設定してください。 ### アップデートとアンインストール アップデートするには、インストールコマンドをもう一度実行します。 アンインストール時、インストールスクリプトはまず aiand が設定したすべてのコーディングエージェントを無効化してから CLI を削除します。`~/.config/aiand` 以下のプロファイルと認証情報は残ります。 ```bash aiand init --off npm uninstall -g @aiand/cli ``` ```bash bash ~/.aiand/cli/install.sh uninstall ``` ```powershell & "$env:USERPROFILE\.aiand\cli\install.ps1" uninstall ``` ## サインイン ```bash aiand login ``` `aiand login` を実行するとブラウザが開きます。サインインを承認すると組織の [API キー](/ja/organizations/api-keys/) が作成されます。キー名は `aiand@` となるため、コンソールでマシンごとに見分けられます。ブラウザでのサインインが完了できない場合 (ブラウザがない、タイムアウトした、ターミナルがない等) は、任意のデバイスで承認するコードによるサインインに切り替わります: ``` Your code BCDF-GHJK Approve at https://api.aiand.com/auth/device?user_code=BCDF-GHJK ``` コンソールで作成済みのキーを使う場合: ```bash aiand login --paste # 入力を伏せ字で表示するプロンプト aiand login --with-token < key.txt # 標準入力からキーを読み込む ``` `aiand whoami` はサインイン中のユーザー、組織、キーの有効期限を表示します。`aiand status` はこれに加えて、キーの保存先と設定済みのコーディングエージェントを表示します。 `aiand logout` は、`aiand login` で作成したキーを無効化するか確認します。貼り付けたキーはこのマシンから削除されるだけなので、コンソールで無効化してください。 ### キーの保存先 キーは OS のキーチェーンが利用できる場合はそこに、利用できない場合は `~/.config/aiand/` 以下の暗号化ファイルに保存されます。このファイルの暗号鍵は同じ場所に置かれるため、ちょっと覗かれる程度は防げますが、ディレクトリを読める人からは保護できません。`AIAND_KEY_STORAGE=plaintext` を設定すると、所有者のみが読める平文ファイルに保存します。 `aiand login` で作成したキーの有効期間は 30 日です。CLI は有効期限の 3 日前から、または API がキーを拒否した時点で、キーを自動的にローテーションします。貼り付けたキーを CLI がローテーションや無効化することはありません。 ## コマンド | コマンド | 内容 | | ------------------------------------- | --------------------------------------------------------------------- | | `aiand login` / `aiand logout` | このマシンのセッションを開始・終了 | | `aiand whoami` | ユーザー、組織、キーの有効期限 | | `aiand status` | サインイン状態と各コーディングエージェントの設定 | | `aiand code` | OpenCode を ai& 上で起動 (必要なら先に設定) | | `aiand ` | 同様にコーディングエージェントを ai& 上で起動 | | `aiand on` / `off` / `status` | コーディングエージェントを ai& を使うよう設定・設定を解除・確認 | | `aiand init` | インストール済みのコーディングエージェントを検出してまとめて設定 | | `aiand run-agent ` | 設定を変更せず、1 セッションだけコーディングエージェントを ai& で実行 | | `aiand restore --force` | エージェントの設定を aiand が変更する前の状態に戻す | | `aiand run ` | プロンプトを 1 つ送信し、回答を stdout にストリーミング | | `aiand chat` | 対話形式の会話 | | `aiand models` | モデルカタログ (請求通貨建ての料金付き) | | `aiand logs` | 最近のリクエスト (`--follow` で新しいリクエストを追跡) | | `aiand usage` | リクエスト数とトークン数 (前の期間との比較付き) | | `aiand orgs` | 所属している組織 | | `aiand config` | プロファイルと既定値 | | `aiand key export` | アクティブなキーを出力 (他のツールへのパイプ用) | ほとんどのコマンドは `--json` に対応し、すべてのコマンドで `--help` を使えます。 ## コーディングエージェント CLI は 3 つのコーディングエージェントに対応しています。`` には次のいずれかを指定します: | エージェント | コマンド | ガイド | | ------------ | -------------------------------------- | -------------------------------------------- | | OpenCode | `aiand opencode` (または `aiand code`) | [OpenCode](/ja/integrations/opencode/) | | Claude Code | `aiand claude` | [Claude Code](/ja/integrations/claude-code/) | | Codex | `aiand codex` | [Codex](/ja/integrations/codex/) | `aiand ` はエージェントを ai& 上で起動します。サインインしていなければサインインを行い、エージェントがインストールされていなければインストールを提案します。エージェントがまだ ai& 向けに設定されていなければ先に `on` を実行するため、以後はエージェント本来のコマンドでも ai& が使われます。 ```bash aiand claude # Claude Code を ai& 上で起動 (必要なら先に設定) aiand claude on # Claude Code が ai& を使うよう設定 aiand claude status # Claude Code の現在の設定を確認 aiand claude off # aiand が追加した設定だけを削除 aiand run-agent claude # このセッションだけ ai& を使い、設定は変更しない aiand init --all # インストール済みのすべてのエージェントを設定 ``` エージェント名より後の引数は、`aiand claude -p "explain this repo"` のようにそのままエージェントに渡されます。aiand 自身のフラグはエージェント名より前に置き (`aiand --profile work codex`)、aiand がサブコマンドとして解釈してしまう引数の前には `--` を付けてください (`aiand opencode -- status`)。モデルを指定するには `on` に `--model ` を渡します。 `on` は最初に変更する前にエージェントの設定のスナップショットを取り、`off` は aiand が追加した設定だけを削除します。aiand が変更する前の設定をそのまま復元するには `aiand restore --force` を実行します。`on` が各エージェントに書き込む内容は、それぞれのガイドを参照してください。 ## プロンプトの実行 ```bash aiand run "why is the sky blue?" cat main.ts | aiand run "review this file" aiand run -m google/gemma-4-31b-it --system "be terse" "summarize CAP theorem" aiand run --no-stream --json "hello" | jq .usage aiand chat ``` パイプで渡した入力はプロンプトの後ろに追加されます。回答は stdout に、それ以外は stderr に出力されるため、`aiand run "..." > out.md` で回答だけを保存できます。回答の後にはモデル、トークン数、コスト、所要時間、リクエスト ID を示すフッターが表示されます。`-q` で非表示にできます。 `-m` を省略すると、プロファイルのモデル、またはカタログの推奨デフォルトモデルが使われます。`-m auto` を指定すると、アカウントが対応していればリクエストごとに ai& がモデルを選びます。[自動選択](/ja/models/auto/) を参照。既定のモデルは `aiand config set model ` で設定できます。 `aiand chat` では `/help` と入力するとセッション内コマンドが一覧表示されます。たとえば `/model ` でモデルを切り替えられます。 ## モデル・ログ・使用量 ```bash aiand models --capability vision # カタログを絞り込む aiand logs --range 1h --errors # 失敗したリクエストのみ aiand logs --follow # 新しいリクエストを追跡 aiand usage --range 30days aiand usage --metrics # 詳細な内訳 ``` - `aiand models` は [カタログ](/ja/models/catalog/) を、100 万トークンあたりの請求通貨建て料金とともに一覧表示します。サインインしていなくても使え、その場合は USD 建てになります。`--search`、`--capability`、`--sort` で絞り込みや並べ替えができます。 - `aiand logs` は [リクエストログ](/ja/analytics/logs/) を表示します。`--range` には `15m`、`1h`、`6h`、`24h` (デフォルト)、`7days`、`30days` を指定できます。 - `aiand usage` は [使用量](/ja/billing/usage/) を前の期間と比較して要約します。`--range` には `1h`、`24h`、`7days` (デフォルト)、`30days`、`3months` を指定できます。 ログと使用量は、このマシンだけでなく組織全体が対象です。 ## 組織とプロファイル CLI のキーはサインイン時に選んだ 1 つの組織にスコープされます。`aiand orgs` で所属している組織を一覧できます。別の組織で作業するには、コンソールでデフォルトの組織を変更してから `aiand login --force` を実行してください。 プロファイルごとにサインインは独立しているため、プロファイルごとに別の組織のキーを持てます: ```bash aiand login --profile work aiand --profile work usage aiand config use work # デフォルトのプロファイルにする ``` 組織が API リクエストにどう適用されるかは [組織の切り替え](/ja/organizations/switching/) を参照してください。 ## 設定 ```bash aiand config # 現在の設定 aiand config set model google/gemma-4-31b-it aiand config profiles # プロファイル一覧 aiand config path # ファイルの場所 ``` 設定は `~/.config/aiand/config.json` (または `$XDG_CONFIG_HOME` 以下) に保存されます。認証情報は別のファイルに保存されるため、設定ファイルは共有しても安全です。優先順位はフラグ、環境変数、保存済みプロファイルの順です。 | 変数 | 効果 | | ---------------------- | ------------------------------------------------------------------------------------ | | `AIAND_API_KEY` | このキーを使用 (サインイン不要、何も保存しない) | | `AIAND_PROFILE` | 使用するプロファイル | | `AIAND_BASE_URL` | API エンドポイント (デフォルト `https://api.aiand.com`) | | `AIAND_AUTH_URL` | サインイン用エンドポイント (API と異なる場合) | | `AIAND_CONFIG_DIR` | 設定と認証情報の保存場所 | | `AIAND_HOME` | エージェントの設定を探すホームディレクトリ (WSL から Windows のホームを使う場合など) | | `AIAND_KEY_STORAGE` | `keychain`、`file`、`plaintext` のいずれか | | `AIAND_NO_BROWSER=1` | ブラウザを開かず、サインイン用のリンクを表示 | | `AIAND_UPDATE_CHECK=0` | 1 日 1 回のアップデート通知を無効化 | | `NO_COLOR` | 色付き表示を無効化 | ## 終了コード | コード | 意味 | | ------ | ------------------------------------------------------------------- | | `0` | 成功 | | `1` | リクエストエラーまたは使い方の誤り (メッセージでどちらか分かります) | | `2` | サインインしていない、またはセッションを更新できなかった | | `3` | サインインが拒否された、またはコードの有効期限が切れた | | `70` | CLI のバグ (スタックトレースが表示されます) | | `127` | 不明なコマンド、またはコーディングエージェントが未インストール | | `130` | 中断された (Ctrl-C) | `aiand status` はサインイン済みなら、ai& に接続できずキーを確認できない場合でも `0` を返し、サインインしていない場合のみ `1` を返します。そのため、これを判定に使うスクリプトは障害時も動作し続けます。 不具合の報告や機能のリクエストは [GitHub](https://github.com/aiandlabs/aiand-cli/issues) で受け付けています。 --- # 構造化抽出 Source: https://aiand-docs-staging.pages.dev/ja/cookbook/extraction/ 請求書、メール、議事録、スクレイピングしたページなどの自由形式テキストから構造化レコードを取り出します。strict な JSON Schema を使えば、出力は毎回クリーンにパースできます。 ## 例: 連絡先情報の抽出 ```python from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") text = """ From: Jane Doe Re: Coffee next week Phone: +1 555-123-4567 """ response = client.chat.completions.create( model="google/gemma-4-31b-it", messages=[ {"role": "system", "content": "Extract contact info from the user's text."}, {"role": "user", "content": text}, ], response_format={ "type": "json_schema", "json_schema": { "name": "contact", "strict": True, "schema": { "type": "object", "properties": { "name": {"type": "string"}, "email": {"type": "string"}, "phone": {"type": ["string", "null"]}, }, "required": ["name", "email", "phone"], "additionalProperties": False, }, }, }, ) import json contact = json.loads(response.choices[0].message.content) print(contact) # {'name': 'Jane Doe', 'email': 'jane@example.com', 'phone': '+1 555-123-4567'} ``` ## Pydantic と併用 (Python) OpenAI Python SDK は Pydantic モデルからスキーマを自動生成できます: ```python from pydantic import BaseModel from typing import Optional class Contact(BaseModel): name: str email: str phone: Optional[str] response = client.chat.completions.parse( model="google/gemma-4-31b-it", messages=[ {"role": "system", "content": "Extract contact info."}, {"role": "user", "content": text}, ], response_format=Contact, ) contact = response.choices[0].message.parsed print(contact.name, contact.email) ``` ## Tips - すべてのフィールドを `required` にし、任意項目は `["string", "null"]` で表現 — strict モードは欠落を拒否しますが nullable は許可します。 - `additionalProperties: false` を指定して余計なフィールドを防ぐ。 - 複数件 (例: 複数の連絡先) は `{"type": "array", "items": {...}}` で外側オブジェクトにラップ。 --- # ドキュメント上のチャット (RAG) Source: https://aiand-docs-staging.pages.dev/ja/cookbook/rag/ ## 方式 A: コーパスをすべてコンテキストに入れる 社内ハンドブック、製品 FAQ、数本の PDF など中小規模のコーパスであれば、最もシンプルな方法は全文を system プロンプトに入れることです。検索もベクトルストアも埋め込みモデルも不要です。 ```python from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") with open("handbook.md") as f: handbook = f.read() def answer(question: str) -> str: response = client.chat.completions.create( model="deepseek-ai/deepseek-v4.1-flash", messages=[ { "role": "system", "content": ( "Answer based only on the handbook below. " "If the answer isn't in it, say so.\n\n" f"---\n{handbook}\n---" ), }, {"role": "user", "content": question}, ], ) return response.choices[0].message.content print(answer("リモートワークの規定は?")) ``` ハンドブック全体が `context_window` に収まるモデルを [カタログ](/ja/models/catalog/) から選んでください — `deepseek-ai/deepseek-v4.1-flash` は最大のウィンドウを最も安く使えるモデルです。 ## 方式 B: ローカル埋め込みでの検索 コーパスが大きすぎてコンテキストに収まらない場合は、自前で埋め込みを計算し、クエリ時に上位 K 件のチャンクを取得します。下記の例ではローカルの `sentence-transformers` を使用しています: ```bash pip install openai sentence-transformers numpy ``` ```python import numpy as np from openai import OpenAI from sentence_transformers import SentenceTransformer client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") embedder = SentenceTransformer("BAAI/bge-small-en-v1.5") CHUNKS = [ "Refunds are processed within 5 business days of approval.", "All employees are entitled to 20 days of paid annual leave.", "Expense reports must be submitted within 30 days of the expense.", "Remote work is supported for engineering and design roles.", # ... 実際にはチャンクが数千件 ] embeds = embedder.encode(CHUNKS, normalize_embeddings=True) def retrieve(query: str, k: int = 3) -> list[str]: q = embedder.encode([query], normalize_embeddings=True)[0] scores = embeds @ q return [CHUNKS[i] for i in np.argsort(-scores)[:k]] def answer(question: str) -> str: context = "\n\n".join(retrieve(question)) response = client.chat.completions.create( model="deepseek-ai/deepseek-v4.1-flash", messages=[ { "role": "system", "content": ( "Answer based only on the snippets below. " "If the answer isn't in them, say so.\n\n" f"{context}" ), }, {"role": "user", "content": question}, ], ) return response.choices[0].message.content print(answer("リモートワークの規定は?")) ``` ## スケーリングのポイント numpy 配列で足りなくなったら: - **ベクトルストア**: pgvector / Pinecone / Qdrant / Weaviate などに置き換え。 - **チャンキング**: 1 チャンクあたり 200–500 トークン、若干のオーバーラップを付けて分割。ページ全体を埋め込まないこと。 - **リランキング**: dense 検索で上位 K 件を取得した後、cross-encoder か LLM で再ランクする。精度向上に有効。 - **引用**: 回答とともにチャンク ID を引用させる。[構造化出力](/ja/capabilities/structured-outputs/) と組み合わせると確実です。 - **埋め込みサービス**: ローカル埋め込みが合わない場合は、外部の埋め込み API を同じスクリプトから呼び出すこともできます。 --- # ストリーミングチャット UI Source: https://aiand-docs-staging.pages.dev/ja/cookbook/streaming-ui/ ストリーミング UI は、トークンが到着するたびに表示されるため即時感があります。パターンは共通: サーバルートが ai& にストリームを開き、SSE のボディをそのままブラウザに流し、クライアントが delta を描画します。 ## サーバルート (Next.js App Router) ```ts // app/api/chat/route.ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: process.env.AIAND_API_KEY!, }); export async function POST(req: Request) { const { messages } = await req.json(); const stream = await client.chat.completions.create({ model: "google/gemma-4-31b-it", messages, stream: true, stream_options: { include_usage: true }, }); const encoder = new TextEncoder(); const body = new ReadableStream({ async start(controller) { for await (const chunk of stream) { const delta = chunk.choices[0]?.delta?.content ?? ""; if (delta) controller.enqueue(encoder.encode(delta)); } controller.close(); }, }); return new Response(body, { headers: { "Content-Type": "text/plain; charset=utf-8" }, }); } ``` ## クライアントコンポーネント ```tsx "use client"; import { useState } from "react"; export default function Chat() { const [input, setInput] = useState(""); const [output, setOutput] = useState(""); async function send() { setOutput(""); const res = await fetch("/api/chat", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ messages: [{ role: "user", content: input }] }), }); const reader = res.body!.getReader(); const decoder = new TextDecoder(); while (true) { const { value, done } = await reader.read(); if (done) break; setOutput((prev) => prev + decoder.decode(value)); } } return (
setInput(e.target.value)} />
{output}
); } ``` ## コストとリクエスト ID の取得 Node SDK の `for await` ループはコンテンツチャンクのみを iterate し、`metrics` trailer イベントを直接公開しません。コストとリクエスト ID を取得するには: - リクエスト ID はレスポンスヘッダ `X-Request-ID` から読む。 - コストはリクエストヘッダ `X-Aiand-Metrics: true` を付与した上で、`fetch` + SSE パーサで `data: [DONE]` の後の `event: metrics` を読む — ペイロードにはトークン数・`cost`・`currency` が含まれます。[ストリーミングイベント](/ja/reference/streaming-events/) を参照。 ## ポイント - アップストリームのレスポンスボディは OpenAI の形式と完全に一致するため、ベース URL を切り替えるだけで既存パーサがそのまま動作します。 - API キーをクライアントコードに埋め込まず、必ずサーバ経由で呼び出します。 - Vercel AI SDK の `useChat` 連携については [Vercel AI SDK](/ja/integrations/vercel-ai/) を参照。 --- # ツール呼び出しエージェント Source: https://aiand-docs-staging.pages.dev/ja/cookbook/tool-agent/ モデルがツールを呼び出し、その結果を見て、タスクが終わるまで続けるループを作ります。 ## ループの流れ 1. ツールを JSON Schema リストとして定義。 2. messages とツールを送信。 3. `tool_calls` が返ってきたら、ローカルで実行して結果を追加。 4. 通常のメッセージが返るまで繰り返す。 ## サンプル ```python import json from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") def get_weather(city: str) -> str: return json.dumps({"city": city, "temp_c": 22, "conditions": "sunny"}) def search_web(query: str) -> str: return json.dumps({"results": [{"title": "Tokyo", "url": "https://en.wikipedia.org/wiki/Tokyo"}]}) TOOLS = [ { "type": "function", "function": { "name": "get_weather", "description": "Get current weather for a city.", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, }, }, { "type": "function", "function": { "name": "search_web", "description": "Search the web.", "parameters": { "type": "object", "properties": {"query": {"type": "string"}}, "required": ["query"], }, }, }, ] HANDLERS = {"get_weather": get_weather, "search_web": search_web} def run(question: str) -> str: messages = [{"role": "user", "content": question}] for _ in range(10): response = client.chat.completions.create( model="google/gemma-4-31b-it", messages=messages, tools=TOOLS, ) msg = response.choices[0].message messages.append(msg.model_dump(exclude_none=True)) if not msg.tool_calls: return msg.content for call in msg.tool_calls: args = json.loads(call.function.arguments) result = HANDLERS[call.function.name](**args) messages.append({ "role": "tool", "tool_call_id": call.id, "content": result, }) raise RuntimeError("Agent exceeded max iterations") print(run("What's the weather in Tokyo, and is it famous for anything?")) ``` ## ポイント - 反復回数の上限 (上記では 10 回) を必ず設定 — 暴走を防ぎます。 - `tool_choice="auto"` がデフォルト。特定ツールを強制するなら `tool_choice={"type": "function", "function": {"name": "..."}}`。 - 並列ツール呼び出し (1 ターンで複数) は `parallel_tool_calls: true` がデフォルト。上記ループは複数の `tool_calls` を 1 イテレーション内で処理します。 --- # 画像からの抽出 Source: https://aiand-docs-staging.pages.dev/ja/cookbook/vision-extraction/ レシート、請求書、身分証、名刺などの画像から構造化データを取り出すレシピ。3 ステップ: 1. [Files](/ja/api/files/) で画像をアップロード。 2. チャットメッセージで `file_id` を参照。 3. JSON Schema で出力を制約。 ## サンプル ```python from openai import OpenAI from pydantic import BaseModel from typing import List client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") class LineItem(BaseModel): description: str quantity: int unit_price_jpy: float class Receipt(BaseModel): merchant: str date: str items: List[LineItem] total_jpy: float uploaded = client.files.create( file=open("receipt.jpg", "rb"), purpose="vision", ) response = client.chat.completions.parse( model="zai-org/glm-5.3-flash", messages=[ {"role": "system", "content": "Extract structured data from receipts."}, { "role": "user", "content": [ {"type": "text", "text": "Parse this receipt into JSON."}, {"type": "file", "file": {"file_id": uploaded.id}}, ], }, ], response_format=Receipt, ) receipt = response.choices[0].message.parsed for item in receipt.items: print(f"{item.description}: ¥{item.unit_price_jpy}") print(f"Total: ¥{receipt.total_jpy}") ``` ## 仕組み - `client.files.create(..., purpose="vision")` で画像を ai& のストレージにアップロード。`purpose` 省略時は MIME から推論されます。 - `file` コンテンツパート — `{type: "file", file: {file_id}}` — を指定すると、ai& がファイルを参照し、短時間有効な署名付き URL を生成して `image_url` パートに書き換えた上でモデルに転送します。詳細は [ビジョン](/ja/capabilities/vision/) を参照。 - `response_format=Receipt` で Pydantic スキーマを strict な JSON Schema として送信。 ## クリーンアップ ファイルはストレージコストを消費するため、使い終わったら削除します: ```python client.files.delete(uploaded.id) ``` [30 日間の有効期限](/ja/api/file-lifecycle/) に任せることもできます。 --- # エラーコード Source: https://aiand-docs-staging.pages.dev/ja/errors/ ## エラー形式 すべてのエラーは OpenAI 互換の形式で返ります: ```json { "error": { "message": "A human-readable description of the error", "type": "error_type", "param": "field_name", "code": "error_code" } } ``` `param` と `code` フィールドは任意で、`null` になることがあります。 唯一の例外は [`POST /v1/messages`](/ja/api/messages/#エラー) で、Anthropic の SDK や Claude Code がそのまま解釈できるよう、Anthropic のエンベロープで応答します: ```json { "type": "error", "error": { "type": "invalid_request_error", "message": "A human-readable description of the error" }, "request_id": "…" } ``` `code` と `param` は設定されている場合に `error` 内に含まれます。モデルのコンテキストウィンドウを超えるリクエストは、メッセージが `prompt is too long` で始まり `capability_rejected: prompt_too_long` トークンを含む `400` となります。これは Claude Code の自動圧縮が検出する文言です。以下のステータスコードはどちらの形式にも適用されます。 ## ステータスコード | ステータス | タイプ | 説明 | |--------|------|-------------| | `400` | `invalid_request_error` | リクエスト検証に失敗 — JSON が不正、必須フィールドの欠落、パラメータ値が無効など。 | | `401` | `authentication_error` | API キーや JWT トークンが欠落しているか無効。 | | `402` | `billing_error` | 課金アカウントの残高が不足しています。クレジットを追加してから再試行してください。 | | `403` | `authorization_error` | 認証情報は有効ですが、対象リソースへの権限が不足しています。 | | `404` | `invalid_request_error` | リソースが見つかりません — 未知のルート、組織が利用できないモデル、または参照先のリソース (例: `file_id`) が存在しないか別の組織のものです。 | | `410` | `invalid_request_error` | リソースが消滅 — 参照されたファイルが `expires_at` を過ぎているか、エンドポイントが廃止されたケース。 | | `429` | `rate_limit_error` | レート制限を超過。再試行の方法はバケットによって異なります — [レート制限](/ja/reference/rate-limits/#429-レスポンス) を参照。 | | `499` | `client_closed_request` | レスポンス完了前にクライアントが切断しました。中断されたストリームで返されます。 | | `500` | `server_error` | リクエスト処理中に予期せぬエラーが発生しました。 | | `502` | `server_error` | モデル推論レイヤへの到達に失敗。 | | `504` | `server_error` | モデルがリクエストタイムアウト内に応答しませんでした。 | `500`、`502`、`504` はいずれも `type` が `"server_error"` です。区別するには `code` を参照してください。`500` には `code` がありません。 ## 主なエラーコード `code` フィールドは `type` よりも具体的な原因を示します。代表的なもの: | コード | ステータス | 発生条件 | |------|--------|------| | `invalid_value` | 400 | リクエストフィールドの値が不正 — mime タイプや purpose が不正、`image_url` / `video_url` / `file_id` に必要な capability を選択したモデルが持たない、モデルが対応していないコンテンツパートの種類、対応するツール呼び出しのないツール結果、`tools` にないツールを指定する `tool_choice`、またはモデルのコンテキスト長以上の `max_tokens`(チャットリクエストで `max_completion_tokens` を指定した場合はそのフィールド、`/v1/responses` では `max_output_tokens`)。`param` に該当フィールド名が入ります | | `invalid_media_url` | 400 | メディア URL が [URL の要件](/ja/capabilities/vision/#url-の要件) を満たしていない。例: `http` の URL、IP アドレス、内部ホスト名。公開 `https` URL、`file_id`、base64 の `data:` URL のいずれかを使ってください。`param` に該当フィールド名が入ります | | `context_length_exceeded` | 400 | リクエストがモデルの最大コンテキスト長を超過。プロンプトを短くするか、出力トークン数の指定を減らしてください | | `unsupported_value` | 400 | 利用できない機能をリクエストが使っている。`/v1/responses` での `previous_response_id` や `item_reference` 入力アイテム(レスポンスオブジェクトは保存されません)、またはモデルがサポートしていない入力アイテムの種類やツールの種類。`param` に該当フィールド名が入り、標準的な種類であればメッセージにその名前が含まれます | | `file_not_found` | 404 | 指定された `file_id` が存在しないか、組織に紐づいていない | | `file_expired` | 410 | 指定された `file_id` が `expires_at` を過ぎている | | `endpoint_removed` | 410 | `/v1/completions` など、廃止されたエンドポイントへのリクエスト。メッセージに代わりのエンドポイントが示されます | | `model_not_found` | 404 | `model` が正確なモデル `id` ではない、またはモデルに組織の請求通貨での価格が設定されていない。チャットモデルは `GET /v1/models`、動画モデルは `GET /v1/videos/models` で確認できます | | `model_deprecated` | 404 | モデルは提供を終了した。代わりに使うモデルをメッセージで案内する | | `model_access_denied` | 404 | モデルは存在するが、組織にそのモデルの利用権限がない。利用を希望する場合は support@aiand.com までお問い合わせください | | `invalid_api_key` | 401 | API キーが欠落、形式不正、または未知 | | `rate_limit_exceeded` | 429 | レート制限を超過。モデルバケットによる拒否では `X-RateLimit-Policy`、認証スロットルでは `Retry-After` のみが付く | | `insufficient_credits` | 402 | 残高不足 | | `upstream_error` | 502 | モデル推論レイヤに到達できない、または応答を読み取れない | | `timeout` | 504 | モデルがリクエストタイムアウト内に応答しなかった | | `client_closed_request` | 499 | レスポンス完了前にクライアントが切断した | ## reasoning をオフにする モデルが reasoning をオフにできるのは、公開しているレベルに `none` が含まれる場合だけです。`none` を公開していない推論モデルへ `reasoning_effort` の `none`、`reasoning.effort` の `none`、または `/v1/messages` の `thinking` ブロックで `type` `disabled` を送ると、`400` `invalid_request_error` になります。 ```text Model '' cannot disable reasoning: suppressing it needs reasoning_effort 'none', which this model does not publish. Supported values: . Use '' for the least reasoning. ``` `` は、そのモデルが公開しているレベルのうち最も低いものです。`reasoning` 機能を持たないモデルは、これらのフィールドを無視します。 ## その他の reasoning レベルのエラー `none` 以外でモデルの一覧にないレベルは、失敗せず一つ上のレベル(なければ最も高いレベル)で実行されます。一覧にない `none` は上記の 400 になります。`ultra` のように effort の語彙にない値は `Model '' does not support ''. Supported values: .` になります。レベルを一つも持たない推論モデルは、どのレベルにも `Model '' lists no reasoning levels, so it cannot apply .` を返します。 ## エラーハンドリング ```python from openai import OpenAI, APIError client = OpenAI( api_key="sk-your-api-key", base_url="https://api.aiand.com/v1", ) try: response = client.chat.completions.create( model="google/gemma-4-31b-it", messages=[{"role": "user", "content": "Hello!"}], ) except APIError as e: print(f"Status: {e.status_code}") print(f"Message: {e.message}") ``` OpenAI SDK はエラーレスポンスを自動的にパースし、型付きの例外を送出します。`X-RateLimit-Policy` が付く `429` エラーでは、バケットに応じて対処してください — 時間ベースの拒否では (`Retry-After` に従って) バックオフし、concurrency の拒否では再試行せず実行中リクエストを消化させます。認証スロットルには policy が付かないため、`Retry-After` に従ってください。[レート制限](/ja/reference/rate-limits/#429-レスポンス) を参照。 --- # クイックスタート Source: https://aiand-docs-staging.pages.dev/ja/getting-started/ このページでは、API キーの取得から初回呼び出しまでを順に解説します。最後まで進めると、レスポンスのストリーミングを体験でき、ツール呼び出し・ビジョン・構造化出力への次のステップも分かります。 ## 1. API キーとクレジットを準備 1. [console.aiand.com](https://console.aiand.com) にサインイン — Google、GitHub、またはマジックリンクで。 2. API キーを発行。キーは `sk-` で始まり、表示は **一度きり** — シークレットマネージャーに保存してください。 3. 課金ページでクレジットをチャージ。最低金額は $1。 ## 2. 初回リクエスト ```bash pip install openai ``` ```python from openai import OpenAI client = OpenAI( base_url="https://api.aiand.com/v1", api_key="sk-your-api-key", ) response = client.chat.completions.create( model="google/gemma-4-31b-it", messages=[{"role": "user", "content": "Hello!"}], ) print(response.choices[0].message.content) ``` ```bash npm install openai ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-your-api-key", }); const response = await client.chat.completions.create({ model: "google/gemma-4-31b-it", messages: [{ role: "user", content: "Hello!" }], }); console.log(response.choices[0].message.content); ``` ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemma-4-31b-it", "messages": [{"role": "user", "content": "Hello!"}] }' ``` ## 3. レスポンスをストリーミング `stream=True` を指定してイテレートします。生成されたトークンが逐次届き、最後にコストとリクエスト ID を含む trailer イベントが配信されます。 ```python stream = client.chat.completions.create( model="google/gemma-4-31b-it", messages=[{"role": "user", "content": "Tell me a haiku about Tokyo."}], stream=True, stream_options={"include_usage": True}, ) for chunk in stream: if chunk.choices: print(chunk.choices[0].delta.content or "", end="", flush=True) ``` ストリーミングの詳細 (オプトインの `metrics` trailer 等) は [ストリーミング](/ja/capabilities/streaming/) を参照。 ## 4. 次のステップを選ぶ | やりたいこと | 進む先 | |--------------|--------| | モデルから関数を呼び出させる | [ツール呼び出し](/ja/capabilities/tool-calling/) | | スキーマに沿った JSON を得る | [構造化出力](/ja/capabilities/structured-outputs/) | | 画像を渡す | [ビジョン](/ja/capabilities/vision/) | | 動くアプリを作る (RAG・エージェント・抽出 等) | [クックブック](/ja/cookbook/rag/) | | LangChain / LlamaIndex / Vercel AI SDK と統合 | [インテグレーション](/ja/integrations/langchain/) | | 既存の OpenAI / Anthropic プロジェクトを移行 | [OpenAI からの移行](/ja/migrating-openai/) · [Anthropic からの移行](/ja/migrating-anthropic/) | ## API キー以外の認証 ブラウザアプリやコンソールでは `X-Org-ID` ヘッダ付きの JWT 認証もサポートしています。[認証](/ja/authentication/) と [組織の切り替え](/ja/organizations/switching/) を参照。 --- # ai& API ドキュメント Source: https://aiand-docs-staging.pages.dev/ja/ ## 概要 ai& はオープンウェイトの LLM を自社インフラ上でホストし、OpenAI / Anthropic 互換 API でアクセスできるサービスです。既存の SDK のベース URL を ai& に向けるだけで、コードを変更せずに当社がホストするオープンソースモデルを利用できます。課金はトークン単位のクレジット制です。 ## ベース URL ``` https://api.aiand.com ``` すべての API エンドポイントはこのベース URL から提供されます。すべてのリクエストには認証が必要です。 ## 最初のリクエスト ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "model": "google/gemma-4-31b-it", "messages": [{"role": "user", "content": "Hello!"}] }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") response = client.chat.completions.create( model="google/gemma-4-31b-it", messages=[{"role": "user", "content": "Hello!"}], ) print(response.choices[0].message.content) ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-...", }); const response = await client.chat.completions.create({ model: "google/gemma-4-31b-it", messages: [{ role: "user", content: "Hello!" }], }); console.log(response.choices[0].message.content); ``` ## 提供する機能 `/v1/chat/completions` のドロップイン代替として利用できます。 OpenAI SDK、LangChain、LlamaIndex など、OpenAI 形式に対応するあらゆるツールで動作します。 1 つの API キーでオープンソースモデルにアクセスできます。 どのモデルでも同じ OpenAI 互換のリクエスト形式が使えます。 画像や動画を [Files API](/ja/api/files/) で一度アップロードし、チャット補完では `file_id` で参照できます。 OpenAI 標準のワイヤーフォーマットなので、純正の SDK がそのまま動作します。 トークン単位の従量課金で、クレジットから自動的に消費されます。 モデルごとの価格設定 — 使った分だけお支払いいただきます。失敗したリクエストには課金されません。 ## 次のステップ ## AI エージェント向け このドキュメントは [llms.txt 規約](https://llmstxt.org/)に沿ったプレーンテキストのコーパスとして公開しています。 エージェントはクロールせずに全体を読み込めます。 --- # Claude Code Source: https://aiand-docs-staging.pages.dev/ja/integrations/claude-code/ [Claude Code](https://claude.com/claude-code) は Anthropic の Messages API と通信します。ai& は Anthropic 互換の `/v1/messages` エンドポイントを公開しているため、[カタログ](/ja/models/catalog/) 内の `tool_calling` 対応モデルであればエージェントループを駆動できます。 設定方法は 2 つあります: - **[セッション](#セッションこのターミナルのみ)** — 現在のシェルに環境変数を `export` します。ターミナルを閉じると失われます。お試し用。 - **[永続化](#永続化-settingsjson)** — 同じ内容を `settings.json` に書き込みます。セッションをまたいで有効になり、プロジェクト単位または全体に適用できます。 ## セッション(このターミナルのみ) **1. Claude Code をインストール** 前提: [Node.js 22 以上](https://nodejs.org/) ```bash npm install -g @anthropic-ai/claude-code ``` インストール確認 — `claude --version` がバージョン番号を表示すれば成功です: ```bash claude --version ``` **2. このターミナルで環境変数を設定** ```bash export ANTHROPIC_BASE_URL="https://api.aiand.com" export ANTHROPIC_AUTH_TOKEN="sk-your-aiand-api-key" export ANTHROPIC_API_KEY="" export ANTHROPIC_DEFAULT_OPUS_MODEL="moonshotai/kimi-k3" export ANTHROPIC_DEFAULT_SONNET_MODEL="moonshotai/kimi-k3" export ANTHROPIC_DEFAULT_HAIKU_MODEL="google/gemma-4-31b-it" export CLAUDE_CODE_SUBAGENT_MODEL="moonshotai/kimi-k3" ``` **3. Claude Code を起動** ```bash claude ``` **1. Claude Code をインストール** 前提: - [Node.js 22 以上](https://nodejs.org/) - [Git for Windows](https://git-scm.com/download/win) ```powershell npm install -g @anthropic-ai/claude-code ``` インストール確認 — `claude --version` がバージョン番号を表示すれば成功です: ```powershell claude --version ``` **2. このターミナルで環境変数を設定** ```powershell $env:ANTHROPIC_BASE_URL = "https://api.aiand.com" $env:ANTHROPIC_AUTH_TOKEN = "sk-your-aiand-api-key" $env:ANTHROPIC_API_KEY = "" $env:ANTHROPIC_DEFAULT_OPUS_MODEL = "moonshotai/kimi-k3" $env:ANTHROPIC_DEFAULT_SONNET_MODEL = "moonshotai/kimi-k3" $env:ANTHROPIC_DEFAULT_HAIKU_MODEL = "google/gemma-4-31b-it" $env:CLAUDE_CODE_SUBAGENT_MODEL = "moonshotai/kimi-k3" ``` **3. Claude Code を起動** ```powershell claude ``` ## 永続化 (settings.json) Claude Code は起動時に `settings.json` の設定を読み込みます。同じ `env` ブロックを記述しておけば、以降 export し直す必要はありません: ```json { "env": { "ANTHROPIC_BASE_URL": "https://api.aiand.com", "ANTHROPIC_AUTH_TOKEN": "sk-your-aiand-api-key", "ANTHROPIC_API_KEY": "", "ANTHROPIC_DEFAULT_OPUS_MODEL": "moonshotai/kimi-k3", "ANTHROPIC_DEFAULT_SONNET_MODEL": "moonshotai/kimi-k3", "ANTHROPIC_DEFAULT_HAIKU_MODEL": "google/gemma-4-31b-it", "CLAUDE_CODE_SUBAGENT_MODEL": "moonshotai/kimi-k3" } } ``` スコープは 2 つ — どちらか一方を選びます: - **プロジェクト単位 (`.claude/settings.local.json`)** — そのリポジトリで `claude` を起動したときだけ適用されます。このファイルには API キーが平文で保存されるため、下のコマンドはリポジトリの `.gitignore` にもこのファイルを追加します (同じ行がすでにあれば追加しません)。`.gitignore` の変更はコミットしてください。最初に ai& を試すならこちらがおすすめ。 - **全体 (`~/.claude/settings.json`)** — マシン全体に適用されます。Claude Code のすべての利用面が同じ ai& バックエンドを参照するようになります — 任意のターミナルセッションで起動する `claude` CLI、[Claude Code VS Code 拡張](https://code.claude.com/docs/en/vs-code)(拡張と CLI は[このファイルを共有する](https://code.claude.com/docs/en/vs-code#configure-settings)設計です)、**および** Claude Desktop アプリ。ai& をマシン全体のデフォルトにしたい場合はこちら。 以下のコマンドは `env` ブロックを**安全にマージ**します — 既存のキー(`permissions`、`hooks` など)はそのまま保持されます。ステップ 1 で Claude Code を npm からインストールしているため、Node はすでにマシンにあります。実行前に `sk-your-aiand-api-key` を実際のキーに置き換えてください。 ### プロジェクト単位 (お試しに最適) プロジェクトのルートで実行します: ```bash mkdir -p .claude && node -e ' const fs = require("fs"), p = ".claude/settings.local.json"; const d = fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, "utf8")) : {}; d.env = Object.assign(d.env || {}, { ANTHROPIC_BASE_URL: "https://api.aiand.com", ANTHROPIC_AUTH_TOKEN: "sk-your-aiand-api-key", ANTHROPIC_API_KEY: "", ANTHROPIC_DEFAULT_OPUS_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_SONNET_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_HAIKU_MODEL: "google/gemma-4-31b-it", CLAUDE_CODE_SUBAGENT_MODEL: "moonshotai/kimi-k3" }); fs.writeFileSync(p, JSON.stringify(d, null, 2)); const g = ".gitignore", gi = fs.existsSync(g) ? fs.readFileSync(g, "utf8") : ""; if (!gi.split(/\r?\n/).includes(p)) fs.appendFileSync(g, (gi && !gi.endsWith("\n") ? "\n" : "") + p + "\n"); ' ``` プロジェクトのルートで実行します: ```powershell New-Item -ItemType Directory -Force -Path .claude | Out-Null $script = @' const fs = require("fs"), p = ".claude/settings.local.json"; const d = fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, "utf8")) : {}; d.env = Object.assign(d.env || {}, { ANTHROPIC_BASE_URL: "https://api.aiand.com", ANTHROPIC_AUTH_TOKEN: "sk-your-aiand-api-key", ANTHROPIC_API_KEY: "", ANTHROPIC_DEFAULT_OPUS_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_SONNET_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_HAIKU_MODEL: "google/gemma-4-31b-it", CLAUDE_CODE_SUBAGENT_MODEL: "moonshotai/kimi-k3" }); fs.writeFileSync(p, JSON.stringify(d, null, 2)); const g = ".gitignore", gi = fs.existsSync(g) ? fs.readFileSync(g, "utf8") : ""; if (!gi.split(/\r?\n/).includes(p)) fs.appendFileSync(g, (gi && !gi.endsWith("\n") ? "\n" : "") + p + "\n"); '@ node -e $script ``` ### 全体スコープ (すべてのプロジェクト) ```bash mkdir -p ~/.claude && node -e ' const fs = require("fs"), os = require("os"), path = require("path"); const p = path.join(os.homedir(), ".claude", "settings.json"); const d = fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, "utf8")) : {}; d.env = Object.assign(d.env || {}, { ANTHROPIC_BASE_URL: "https://api.aiand.com", ANTHROPIC_AUTH_TOKEN: "sk-your-aiand-api-key", ANTHROPIC_API_KEY: "", ANTHROPIC_DEFAULT_OPUS_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_SONNET_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_HAIKU_MODEL: "google/gemma-4-31b-it", CLAUDE_CODE_SUBAGENT_MODEL: "moonshotai/kimi-k3" }); fs.writeFileSync(p, JSON.stringify(d, null, 2)); ' ``` ```powershell New-Item -ItemType Directory -Force -Path $HOME\.claude | Out-Null $script = @' const fs = require("fs"), os = require("os"), path = require("path"); const p = path.join(os.homedir(), ".claude", "settings.json"); const d = fs.existsSync(p) ? JSON.parse(fs.readFileSync(p, "utf8")) : {}; d.env = Object.assign(d.env || {}, { ANTHROPIC_BASE_URL: "https://api.aiand.com", ANTHROPIC_AUTH_TOKEN: "sk-your-aiand-api-key", ANTHROPIC_API_KEY: "", ANTHROPIC_DEFAULT_OPUS_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_SONNET_MODEL: "moonshotai/kimi-k3", ANTHROPIC_DEFAULT_HAIKU_MODEL: "google/gemma-4-31b-it", CLAUDE_CODE_SUBAGENT_MODEL: "moonshotai/kimi-k3" }); fs.writeFileSync(p, JSON.stringify(d, null, 2)); '@ node -e $script ``` ## 動作確認 Claude Code 内で以下を実行します: ```text /status ``` 現在のベース URL とモデルがパネルに表示されます。`https://api.aiand.com` と `moonshotai/kimi-k3` が見えれば成功です。 シェルから直接エンドポイントを叩いて確認することもできます: ```bash curl -sS https://api.aiand.com/v1/models \ -H "Authorization: Bearer sk-your-aiand-api-key" \ | grep -o 'moonshotai/kimi-k3' ``` ```powershell (Invoke-RestMethod https://api.aiand.com/v1/models ` -Headers @{ Authorization = "Bearer sk-your-aiand-api-key" }).data.id ` | Select-String "moonshotai/kimi-k3" ``` 一致すればキーの認証が通り、モデルが組織で利用可能であることを確認できます。 ## 動作上の注意 - **Effort。** `/effort` と `CLAUDE_CODE_EFFORT_LEVEL` は反映されます。Claude Code はレベルを `output_config.effort` として送信し、ai& はそれをモデルの [`reasoning_effort`](/ja/models/catalog/) として適用します。`none` 以外でモデルの一覧にないレベルは一つ上のレベル(なければ最も高いレベル)で実行されるため(一覧にない `none` は 400)、最上位が `max` のモデルで `/effort xhigh` を指定すると `max` で実行され、コストが上がる場合があります。適用されたレベルは `X-Reasoning-Effort` で返され、各モデルのレベルは `reasoning_efforts` に記載されています。レベルが送信されない場合、ai& は何も指定せずに転送し、モデルは自身のデフォルト(最も高コストなレベルの場合もあります)で動作するため、明示的に設定してください。 - **コンテキスト上限。** 会話がモデルのウィンドウを超えると、ai& は Anthropic 本家と同じ「prompt is too long」の文言で応答するため、Claude Code は自動で圧縮(compact)して再試行します。Claude Code は認識しないモデル名に対して 200K のウィンドウを仮定するため、`context_window` がそれより小さいモデルでは上限に早く達し、この圧縮と再試行に頼ることになります。 - **Thinking。** Claude Code はメインのチャットリクエストで adaptive thinking を要求し、バックグラウンドの呼び出しでは `thinking` を送りません。ai& はモデルの推論を `thinking` ブロックとしてストリーミングで返します。thinking ブロックはレベルを指定しませんが、`thinking: { "type": "disabled" }` は、`none` を公開している名前付きの推論モデルでは推論を無効にし、公開していないモデルでは 400 になります([詳細](/ja/api/messages/#reasoning)、[エラー文](/ja/errors/#reasoning-をオフにする))。それ以外の場合、推論の深さは effort で決まります。 - **WebSearch などのサーバーサイドツール。** Anthropic のサーバーサイドツール(ウェブ検索、ウェブ取得、コード実行)は Anthropic の API 内部で実行されるため、ai& 経由では利用できません。これらを含むリクエストはツール名を示す 400 で拒否されるため、Claude Code の `WebSearch` ツールは捏造された結果ではなくエラーを報告します。代わりに MCP のウェブ検索サーバーを利用してください。 - **スクリーンショット。** ツール結果内の画像(PNG に対する `Read` ツールなど)は、vision 対応モデルではモデルに渡され、テキストのみのモデルでは短いプレースホルダーに置き換えられます。 --- # Cline Source: https://aiand-docs-staging.pages.dev/ja/integrations/cline/ [Cline](https://github.com/cline/cline) は、ターミナルで動作する AI コーディングエージェントです。ai& は組み込み provider として含まれ、id は `aiand`、base URL は `https://api.aiand.com/v1` です。 ## 1. CLI をインストール ```bash npm install -g cline ``` ## 2. API キーを設定 [ai& console](https://console.aiand.com/api-keys) でキーを作成し、shell に設定します: ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ```powershell $env:AIAND_API_KEY = "sk-your-aiand-api-key" ``` ## 3. ai& を選ぶ provider とモデルを保存します。API キーは Cline のローカル設定に書き込まれます: ```bash cline auth --provider aiand --apikey "$AIAND_API_KEY" --modelid moonshotai/kimi-k3 ``` モデル id はカタログの id です。例: `moonshotai/kimi-k3`。`aiand/` は付けません。 保存するモデルを変える場合: ```bash cline auth --provider aiand --apikey "$AIAND_API_KEY" --modelid google/gemma-4-31b-it ``` ## 4. Cline を実行 保存した provider でタスクを始めます: ```bash cline "inspect this repository and fix the failing test" ``` prompt を渡すと act mode で起動し、ツールは自動承認されます。1 回だけモデルを変える場合: ```bash cline -P aiand -m moonshotai/kimi-k3 "reply with only: ok" ``` `AIAND_API_KEY` が設定されていれば、この one-shot の前に `cline auth` は不要です。 ## 動作確認 ```bash cline "reply with only: ok" ``` Cline はそのターンのトークン数を表示します。モデルが prompt cache に対応している場合は、キャッシュされた入力トークンも含まれます。 ## トラブルシューティング - **Unauthorized request** — 同じ shell に `AIAND_API_KEY` を設定するか、[ai& console](https://console.aiand.com/api-keys) のキーで `cline auth` をやり直してください。 - **Model not found** — [モデルカタログ](/ja/models/catalog/)の id を使ってください。`aiand/` は付けません。 - **返答はあるがファイルを編集しない** — `moonshotai/kimi-k3` や `google/gemma-4-31b-it` のように、ツール呼び出しに対応したモデルを選んでください。 --- # Cloudflare AI Gateway Source: https://aiand-docs-staging.pages.dev/ja/integrations/cloudflare-ai-gateway/ [Cloudflare AI Gateway](https://developers.cloudflare.com/ai-gateway/) は、[カスタムプロバイダ](https://developers.cloudflare.com/ai-gateway/configuration/custom-providers/) として `https://api.aiand.com` をプロキシできます。Gateway のログ・分析・キャッシュ・レート制限が使え、課金はこれまで通り ai& の `sk-` キーです。 ai& は Gateway のネイティブプロバイダではありません。URL は `/openai` や `/aiand` ではなく `custom-{slug}` です。 ## セットアップ 先に [API キー](https://console.aiand.com) を発行します。 1. Cloudflare ダッシュボードの **AI → AI Gateway → Custom Providers** でプロバイダを追加します。 - Slug: `aiand` - Base URL: `https://api.aiand.com`(末尾スラッシュも `/v1` も付けない) - 有効化する 2. ゲートウェイを作成します(名前は任意。以下では `aiand-gateway`)。 3. ai& のキーは `Authorization: Bearer sk-…` に載せます。この経路では **Authenticated Gateway** は任意です。オンなら **AI Gateway Run** 権限の Cloudflare トークンを `cf-aig-authorization` にも付けます。 4. キーを **Provider Keys**(BYOK)に保存して `Authorization` を省略する場合は、Authenticated Gateway をオンにし、毎回 `cf-aig-authorization` を付けます。この Cloudflare トークンは `sk-` ではありません。 カスタムプロバイダの作成画面にキー欄はありません。それが正しいです。 ## ゲートウェイ経由の呼び出し `ACCOUNT_ID` は Cloudflare のアカウント ID に置き換えてください。 ```bash curl https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/custom-aiand/v1/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "cf-aig-authorization: Bearer $CF_AIG_TOKEN" \ -d '{ "model": "google/gemma-4-31b-it", "messages": [{"role": "user", "content": "Hello"}] }' ``` 例には両方のヘッダがあります。`cf-aig-authorization` を外してよいのは、自分で `sk-` を送り、かつ Authenticated Gateway がオフのときだけです。`Authorization` を外してよいのは BYOK のときだけで、その場合は `cf-aig-authorization` を残します。 ```ts import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.AIAND_API_KEY, baseURL: "https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/custom-aiand/v1", defaultHeaders: { "cf-aig-authorization": `Bearer ${process.env.CF_AIG_TOKEN}`, }, }); const response = await client.chat.completions.create({ model: "google/gemma-4-31b-it", messages: [{ role: "user", content: "Hello" }], }); ``` SDK が `/chat/completions` を付け、Gateway が `https://api.aiand.com/v1/chat/completions` を呼びます。同じ `baseURL` で `/v1/responses`、`/v1/messages`、`/v1/models` も使えます。 ## Unified `/compat`(任意) ```bash curl https://gateway.ai.cloudflare.com/v1/ACCOUNT_ID/aiand-gateway/compat/chat/completions \ -H "Content-Type: application/json" \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "cf-aig-authorization: Bearer $CF_AIG_TOKEN" \ -d '{ "model": "custom-aiand/google/gemma-4-31b-it", "messages": [{"role": "user", "content": "Hello"}] }' ``` `/compat` は chat completions だけです。Responses、Messages、カタログは `/custom-aiand/v1` を使ってください。 ## キャッシュ ゲートウェイ設定で **Cache Responses** をオンにします。同一リクエストは `cf-aig-cache-status: HIT` になり、ai& には届かず課金されません。ミスは `MISS` です。 デフォルトのキャッシュキーはプロバイダ・パス・モデル・認証・JSON ボディ全体の完全一致です。バイパスは `cf-aig-skip-cache: true` です。 ストリーミングはデフォルトではキャッシュされません。**Cache Responses** の対象は同一の非ストリーミングのテキストと画像だけです。`stream: true` は ai& に届き、課金されます。 ## エラー - `cf-aig-authorization` の欠落や誤り(認証オン時): Cloudflare の `401`(`AiGatewayError`)。OpenAI 形式ではありません。 - 誤ったカスタム slug: Cloudflare の `502`(`The provider did not return a valid response`)。ai& の `404` ではありません。 - 未知のモデル、壊れた JSON、空の `messages`、不正な `reasoning_effort`、テキスト専用モデルへの画像: いつもどおりの OpenAI 形式エラーがそのまま返ります。 ## これではないもの `env.AI.run("@cf/…")` は別製品の [Workers AI](https://developers.cloudflare.com/workers-ai/) です。Worker から AI Gateway なしで ai& を呼ぶなら、OpenAI SDK の `baseURL` を `https://api.aiand.com/v1` にしてください。 --- # Codex Source: https://aiand-docs-staging.pages.dev/ja/integrations/codex/ [Codex](https://developers.openai.com/codex) は OpenAI の Responses API と通信します。ai& は OpenAI 互換の `/v1/responses` エンドポイントを公開しているため、[カタログ](/ja/models/catalog/) 内の `tool_calling` 対応モデルであればエージェントループを駆動できます。 ## 1. Codex をインストール 前提: [Node.js 18 以降](https://nodejs.org/)。 ```bash npm install -g @openai/codex ``` インストールを確認 — `codex --version` がバージョン番号を表示するはずです: ```bash codex --version ``` ```powershell npm install -g @openai/codex ``` インストールを確認 — `codex --version` がバージョン番号を表示するはずです: ```powershell codex --version ``` ## 2. API キーを設定 以下の設定はキーを環境変数 `AIAND_API_KEY` から読み取るため、Codex がキーをディスクに保存することはありません。 ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ターミナルをまたいで有効にするには、この行を `~/.zshrc` または `~/.bashrc` に追記してください。 ```powershell $env:AIAND_API_KEY = "sk-your-aiand-api-key" ``` セッションをまたいで永続化するには: `setx AIAND_API_KEY "sk-your-aiand-api-key"`(その後ターミナルを開き直してください)。 ## 3. ai& プロファイルを追加 Codex 0.141 以降は、各プロファイルを専用ファイル `~/.codex/.config.toml` に保存します。`~/.codex/aiand.config.toml` を作成してください: ```toml model = "moonshotai/kimi-k3" model_reasoning_effort = "high" model_provider = "aiand" web_search = "disabled" [model_providers.aiand] name = "ai&" base_url = "https://api.aiand.com/v1" wire_api = "responses" [model_providers.aiand.auth] command = "sh" args = ["-c", "echo $AIAND_API_KEY"] [tools] view_image = false [features] unified_exec = false apps = false browser_use = false browser_use_external = false computer_use = false image_generation = false multi_agent = false in_app_browser = false ``` `model_reasoning_effort` の行は重要です。Codex の組み込みデフォルトは `medium` ですが、サポートされる推論レベルはモデルごとに異なり、モデルの `reasoning_efforts` にないレベルはエラーになります。`moonshotai/kimi-k3` は `high` を受け付けるため、ここでは `high` を明示的に指定するのが安全な選択です。モデルを切り替える前に [`GET /v1/models`](/ja/api/models/) の `reasoning_efforts` を確認してください。 `[model_providers.aiand.auth]` ブロックは、Codex に ai& のモデルカタログを取得させるためのものです。Codex 0.157 以降は、コマンドで認証するプロバイダーに対してのみカスタムプロバイダーのモデル一覧を取得します。単に `env_key = "AIAND_API_KEY"` とした場合もリクエスト自体は動作しますが、Codex は同梱のメタデータにフォールバックし、`/model` に「Unknown model」の警告が表示され、各 ai& モデルがサポートする推論レベルも提示されません。このコマンドは、手順 2 で設定した環境変数からキーを出力するだけです。 `[features]` ブロックも重要です。ai& は標準的な **関数ツール(function tools)** を提供しており、コーディングのエージェントループに必要なのはこれだけです。一方で Codex のホスト型・組み込みツール(ウェブ検索、画像生成、ブラウザ・コンピューター操作)やツールをまとめるラッパーには対応していません。有効のままだと Codex は API に拒否されうるツール種別を送信し(`tool type … not supported`)てしまうため、プロファイルでこれらを無効化します。 1 ステップで保存できます: ```bash mkdir -p ~/.codex && cat > ~/.codex/aiand.config.toml <<'EOF' model = "moonshotai/kimi-k3" model_reasoning_effort = "high" model_provider = "aiand" web_search = "disabled" [model_providers.aiand] name = "ai&" base_url = "https://api.aiand.com/v1" wire_api = "responses" [model_providers.aiand.auth] command = "sh" args = ["-c", "echo $AIAND_API_KEY"] [tools] view_image = false [features] unified_exec = false apps = false browser_use = false browser_use_external = false computer_use = false image_generation = false multi_agent = false in_app_browser = false EOF ``` ```powershell New-Item -ItemType Directory -Force -Path $HOME\.codex | Out-Null @' model = "moonshotai/kimi-k3" model_reasoning_effort = "high" model_provider = "aiand" web_search = "disabled" [model_providers.aiand] name = "ai&" base_url = "https://api.aiand.com/v1" wire_api = "responses" [model_providers.aiand.auth] command = "cmd" args = ["/c", "echo %AIAND_API_KEY%"] [tools] view_image = false [features] unified_exec = false apps = false browser_use = false browser_use_external = false computer_use = false image_generation = false multi_agent = false in_app_browser = false '@ | Set-Content -Encoding utf8 $HOME\.codex\aiand.config.toml ``` ## 4. Codex を実行 ```bash codex --profile aiand ``` または非対話モードで実行 — `--sandbox workspace-write` を付けるとエージェントがワークスペース内のファイルを編集できます: ```bash codex exec --profile aiand --sandbox workspace-write "src/math.js の失敗しているテストを修正して" ``` ## 動作確認 シェルからワイヤレベルの経路を確認します — 一致すればキーが認証され、そのモデルが組織で利用可能なことを意味します: ```bash curl -sS https://api.aiand.com/v1/models \ -H "Authorization: Bearer $AIAND_API_KEY" \ | grep -o 'moonshotai/kimi-k3' ``` ```powershell (Invoke-RestMethod https://api.aiand.com/v1/models ` -Headers @{ Authorization = "Bearer $env:AIAND_API_KEY" }).data.id ` | Select-String "moonshotai/kimi-k3" ``` --- # CrewAI Source: https://aiand-docs-staging.pages.dev/ja/integrations/crewai/ [CrewAI](https://docs.crewai.com/) は役割ベースのマルチエージェントシステムを構築するフレームワークです。OpenAI 互換プロバイダへの接続には LiteLLM(`litellm` extra でインストール)を使用しており、環境変数を 2 つ設定するだけで ai& と接続できます。 ## セットアップ ```bash pip install 'crewai[litellm]' ``` ```bash export OPENAI_API_KEY="sk-your-aiand-api-key" export OPENAI_API_BASE="https://api.aiand.com/v1" ``` ## 2 エージェントの crew ```python from crewai import Agent, Task, Crew, LLM llm = LLM(model="openai/google/gemma-4-31b-it") researcher = Agent( role="Researcher", goal="Find accurate information", backstory="An experienced research analyst.", llm=llm, ) writer = Agent( role="Writer", goal="Write a clear summary", backstory="A concise technical writer.", llm=llm, ) research_task = Task( description="Research the city of Tokyo — population, history, notable features.", expected_output="Bullet points covering the key facts.", agent=researcher, ) write_task = Task( description="Write a 100-word summary based on the research.", expected_output="A 100-word paragraph.", agent=writer, ) crew = Crew(agents=[researcher, writer], tasks=[research_task, write_task]) print(crew.kickoff()) ``` ## ツール付き ```python from crewai.tools import tool @tool("get_weather") def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny in {city}, 22°C" researcher = Agent( role="Weather Reporter", goal="Answer weather questions", backstory="A meteorologist.", llm=llm, tools=[get_weather], ) ``` --- # Cursor Source: https://aiand-docs-staging.pages.dev/ja/integrations/cursor/ [Cursor](https://cursor.com) は OpenAI ベース URL を独自の API キーで上書きする機能(BYOK: Bring Your Own Key)をサポートしています。ai& は OpenAI 互換の `/v1/chat/completions` エンドポイントを公開しているため、[カタログ](/ja/models/catalog/) 内の `tool_calling` 対応モデルで Cursor の Agent モードを駆動できます。 ## 前提条件 - [Cursor](https://cursor.com) がインストール済み - ツール呼び出し対応モデルにアクセスできる [ai& API キー](https://console.aiand.com/settings/api-keys) ## セットアップ 1. Cursor の設定を開く(`Cmd+,` / `Ctrl+,`) 2. **Models** → **OpenAI API Key** までスクロール 3. **OpenAI API Key** フィールドに ai& API キーを貼り付け 4. **Override OpenAI Base URL** を有効にして、以下を設定: ``` https://api.aiand.com/v1 ``` `/v1` サフィックスは必須です — Cursor は指定された URL に `/chat/completions` を追加します。 5. モデルリストで **+ Add Model** をクリックし、[カタログ](/ja/models/catalog/) からツール呼び出し対応のモデル ID を入力。例: ``` moonshotai/kimi-k3 ``` モデルを有効にしてから **Verify** をクリック — Cursor がテストリクエストを送信し、キーとモデルが機能することを確認します ## Agent モードの使用 認証が完了したら、Agent モードに切り替えます(サイドバーのロボットアイコン、または `Cmd+.` / `Ctrl+.`)。エージェントは以下を実行できます: - ワークスペース内のファイルの読み取りと編集 - ターミナルコマンドの実行 - マルチターンのツール呼び出しでタスクを完了 ## 接続の確認 シェルからキーが認証され、モデルが利用可能か確認します: ```bash curl -sS https://api.aiand.com/v1/models \ -H "Authorization: Bearer $AIAND_API_KEY" \ | grep -o 'moonshotai/kimi-k3' ``` ```powershell (Invoke-RestMethod https://api.aiand.com/v1/models ` -Headers @{ Authorization = "Bearer $env:AIAND_API_KEY" }).data.id ` | Select-String "moonshotai/kimi-k3" ``` 一致すればキーが機能し、そのモデルが組織で利用可能であることを意味します。 ## トラブルシューティング - **「Invalid API key」** — ai& ダッシュボードから完全なキーをコピーしたか、キーが取り消されていないか確認してください。 - **「Model not found」** — モデル ID は [カタログ](/ja/models/catalog/) と完全一致する必要があります。プロバイダープレフィックス(`zai-org/`、`moonshotai/` など)も含めてください。 - **Agent モードがツールを使わない** — 選択したモデルがツール呼び出しに対応しているか確認してください。カタログのすべてのモデルが対応しているわけではありません。 - **キーとモデルが正しいのに Verify が失敗する** — Cursor が検証リクエストを `model: "default"` で送信することがあります。回避策: まずリスト内の他のモデルをすべて無効にしてから検証してください。 - **リクエストがブロックされる、または 403** — 企業プロキシや VPN が干渉している可能性があります。まず直接接続で試してください。 ## Cursor ホスト型モデルに戻す 1. 設定 → Models に移動 2. **Override OpenAI Base URL** を無効化(またはフィールドをクリア) 3. Cursor ホスト型モデル(GPT-4o、Claude など)が再び利用可能になります BYOK キーは Cursor によってローカルに保存され、上書き先のエンドポイント以外には送信されません。 --- # Kilo Code Source: https://aiand-docs-staging.pages.dev/ja/integrations/kilo-code/ [Kilo Code](https://kilo.ai) は、VS Code、JetBrains、ターミナルで利用できるオープンソースのコーディングエージェントです。ai& を custom OpenAI-compatible provider として登録すると、すべての環境で同じモデルと設定を使えます。 ## 前提条件 - [VS Code](https://marketplace.visualstudio.com/items?itemName=kilocode.Kilo-Code)、[JetBrains](https://plugins.jetbrains.com/plugin/28350-kilo-code)、または CLI 版の Kilo Code - [ai& API キー](https://console.aiand.com/api-keys) ## VS Code と JetBrains 1. Kilo Code の設定を開きます: - **VS Code:** Kilo Code sidebar の gear icon をクリックする。 - **JetBrains:** **Settings → Tools → Kilo Code** を開く。 2. **Providers** を開き、一番下の **Custom provider** を選びます。 3. 次の値を入力します: | 設定 | 値 | | ------------ | -------------------------- | | Provider ID | `aiand` | | Display name | `ai&` | | Provider API | **OpenAI Compatible** | | Base URL | `https://api.aiand.com/v1` | | API key | ai& API キー | 4. 取得された一覧からモデルを選ぶか、[モデルカタログ](/ja/models/catalog/) の ID を入力します。 5. provider を保存し、Kilo の model picker で `aiand/` を選びます。 ## CLI Kilo をインストールします: ```bash npm install -g @kilocode/cli ``` API キーを設定します: ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ```powershell $env:AIAND_API_KEY = "sk-your-aiand-api-key" ``` global config `~/.config/kilo/kilo.jsonc` を作成します: ```jsonc { "$schema": "https://app.kilo.ai/config.json", "model": "openai-compatible/moonshotai/kimi-k3", "provider": { "openai-compatible": { "options": { "apiKey": "{env:AIAND_API_KEY}", "baseURL": "https://api.aiand.com/v1", }, "models": { "moonshotai/kimi-k3": { "name": "moonshotai/kimi-k3", "tool_call": true, "reasoning": true, "limit": { "context": 1048576, "output": 131072, }, }, "google/gemma-4-31b-it": { "name": "google/gemma-4-31b-it", "tool_call": true, "reasoning": true, "limit": { "context": 262144, "output": 32768, }, }, }, }, }, } ``` 対話型の terminal UI を起動します: ```bash kilo ``` one-shot task も実行できます: ```bash kilo run --auto -m openai-compatible/moonshotai/kimi-k3 "このリポジトリを確認して、失敗しているテストを修正してください" ``` ## 動作確認 設定した provider とモデルが Kilo から見えるか確認します: ```bash kilo models openai-compatible kilo run --auto -m openai-compatible/moonshotai/kimi-k3 "reply with only: ok" ``` ## トラブルシューティング - **モデルが読み込まれない** — Base URL が `https://api.aiand.com/v1` と完全に一致しているか確認し、API キーを再入力してください。 - **Unauthorized request** — [ai& console](https://console.aiand.com/api-keys) で新しいキーを作成し、provider または `AIAND_API_KEY` を更新してください。 - **CLI が `AIAND_API_KEY` を認識しない** — `{env:AIAND_API_KEY}` は project config ではなく global config に記述してください。 - **応答は返るが file を編集できない** — [カタログ](/ja/models/catalog/) で `tool_calling` 対応モデルを選び、Kilo の確認画面で file tool を許可してください。 - **context usage が表示されない、または compaction が動かない** — [カタログ](/ja/models/catalog/) の `limit.context` と `limit.output` を `kilo.jsonc` のモデル設定に追加してください。 --- # LangChain Source: https://aiand-docs-staging.pages.dev/ja/integrations/langchain/ LangChain は `ChatOpenAI` を介して ai& と接続できます — ai& のベース URL を指定するだけで、既存のチェーン・エージェント・グラフがそのまま動作します。 ## セットアップ ```bash pip install langchain langchain-openai ``` ```python from langchain_openai import ChatOpenAI llm = ChatOpenAI( model="google/gemma-4-31b-it", base_url="https://api.aiand.com/v1", api_key="sk-your-api-key", ) print(llm.invoke("Hello").content) ``` ## チェーン内での利用 ```python from langchain_core.prompts import ChatPromptTemplate prompt = ChatPromptTemplate.from_messages([ ("system", "Translate the user's input to {language}."), ("user", "{text}"), ]) chain = prompt | llm print(chain.invoke({"language": "Japanese", "text": "Hello, world!"}).content) ``` ## ツール付き ```python from langchain_core.tools import tool @tool def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny in {city}, 22°C" llm_with_tools = llm.bind_tools([get_weather]) response = llm_with_tools.invoke("What's the weather in Tokyo?") print(response.tool_calls) ``` ## LangGraph `ChatOpenAI` をラップした LangGraph ノードは同じ要領で動作します — ai& 固有の設定はありません。詳細は [LangGraph ドキュメント](https://langchain-ai.github.io/langgraph/) を参照。 --- # LlamaIndex Source: https://aiand-docs-staging.pages.dev/ja/integrations/llamaindex/ LlamaIndex は `OpenAILike` LLM を介して ai& と接続できます — OpenAI のワイヤ形式に対応し、ベース URL のみカスタマイズします。 ## セットアップ ```bash pip install llama-index llama-index-llms-openai-like ``` ```python from llama_index.llms.openai_like import OpenAILike llm = OpenAILike( model="google/gemma-4-31b-it", api_base="https://api.aiand.com/v1", api_key="sk-your-api-key", is_chat_model=True, ) print(llm.complete("Hello").text) ``` ## ドキュメントのインデックス化と検索 ```python from llama_index.core import VectorStoreIndex, SimpleDirectoryReader, Settings Settings.llm = llm # ai& は埋め込みエンドポイントを提供しないため、埋め込みは別途用意: from llama_index.embeddings.huggingface import HuggingFaceEmbedding Settings.embed_model = HuggingFaceEmbedding(model_name="BAAI/bge-small-en-v1.5") docs = SimpleDirectoryReader("./data").load_data() index = VectorStoreIndex.from_documents(docs) query_engine = index.as_query_engine() print(query_engine.query("What is this corpus about?")) ``` ## ツール付きエージェント ```python from llama_index.core.agent.workflow import FunctionAgent from llama_index.core.tools import FunctionTool def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny in {city}, 22°C" agent = FunctionAgent( tools=[FunctionTool.from_defaults(fn=get_weather)], llm=llm, ) print(await agent.run("What's the weather in Tokyo?")) ``` --- # OMP Source: https://aiand-docs-staging.pages.dev/ja/integrations/omp/ [OMP](https://github.com/can1357/oh-my-pi) は、ターミナルで動作する AI コーディングエージェントです。ai& は組み込み provider として含まれています。 ## 1. OMP をインストール ```bash curl -fsSL https://omp.sh/install | sh ``` ```powershell irm https://omp.sh/install.ps1 | iex ``` Bun 1.3.14 以降でもインストールできます: ```bash bun install -g @oh-my-pi/pi-coding-agent ``` ## 2. API キーを設定 [ai& console](https://console.aiand.com/api-keys) でキーを作成し、shell に設定します: ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ```powershell $env:AIAND_API_KEY = "sk-your-aiand-api-key" ``` ## 3. OMP を実行 ai& のモデルを指定して OMP を起動します: ```bash omp --model aiand/ ``` モデル名は `aiand/` 形式で指定してください。 ## 動作確認 one-shot prompt を実行します: ```bash omp --print --model aiand/ "reply with only: ok" ``` Unauthorized request が表示された場合は、同じ shell に `AIAND_API_KEY` が設定されているか確認してください。 --- # OpenAI Agents SDK Source: https://aiand-docs-staging.pages.dev/ja/integrations/openai-agents/ [OpenAI Agents SDK](https://github.com/openai/openai-agents-python) (Python) と JS 版は、`OpenAI` クライアントをカスタム設定するだけで ai& と接続できます。 ## セットアップ ```bash pip install openai-agents ``` ```python from agents import Agent, Runner, ModelSettings from agents.models.openai_chatcompletions import OpenAIChatCompletionsModel from openai import AsyncOpenAI client = AsyncOpenAI( base_url="https://api.aiand.com/v1", api_key="sk-your-api-key", ) model = OpenAIChatCompletionsModel( model="google/gemma-4-31b-it", openai_client=client, ) ``` ## シンプルなエージェント ```python agent = Agent( name="Assistant", instructions="You are a helpful assistant. Always reply concisely.", model=model, ) result = await Runner.run(agent, "What is the capital of France?") print(result.final_output) ``` ## ツール付きエージェント ```python from agents import function_tool @function_tool def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny in {city}, 22°C" agent = Agent( name="WeatherBot", instructions="Help the user with weather questions.", model=model, tools=[get_weather], ) result = await Runner.run(agent, "What's the weather in Tokyo?") print(result.final_output) ``` ## ハンドオフとマルチエージェント Agents SDK のハンドオフパターンも同じ要領で動きます — `Agent(...)` に `handoffs=[other_agent]` を渡します。ai& 固有の設定は不要です。 --- # OpenCode Source: https://aiand-docs-staging.pages.dev/ja/integrations/opencode/ [OpenCode](https://opencode.ai) は、ターミナル UI、CLI、IDE 拡張、デスクトップアプリとして利用できるオープンソースの AI コーディングエージェントです。ai& は OpenCode に組み込みの provider として含まれているため、API キーで接続すれば ai& のモデルが model picker に表示されます。 ## 1. OpenCode をインストール ターミナルまたは one-shot CLI で使う場合: ```bash curl -fsSL https://opencode.ai/install | bash ``` npm や Homebrew でもインストールできます: ```bash npm install -g opencode-ai brew install anomalyco/tap/opencode ``` ターミナルで使う場合、OpenCode は WSL を推奨しています。Windows パッケージも利用できます: ```powershell choco install opencode ``` または: ```powershell scoop install opencode ``` デスクトップアプリは、[opencode.ai/download](https://opencode.ai/download) から **OpenCode Desktop** をダウンロードするか、パッケージマネージャーでインストールします: ```bash brew install --cask opencode-desktop ``` ```powershell scoop bucket add extras scoop install extras/opencode-desktop ``` ## 2. ai& に接続 [ai& console](https://console.aiand.com/api-keys) で API キーを作成し、使用する環境に合わせて OpenCode に追加します。 ### ターミナル OpenCode TUI で以下を実行します: ```text /connect ``` provider 一覧から **ai&** を選び、`sk-...` キーを貼り付けます。OpenCode が認証情報を保存し、以降のセッションで再利用します。 TUI の外では、shell から `opencode auth login` を実行すると同じ provider 一覧から選べます。 ### Desktop app **Settings → Providers → View all providers** を開き、**ai&** を検索して `sk-...` キーを貼り付けます。Providers 画面には既定で接続済みと人気の provider しか表示されないため、全一覧を開くまで ai& は表示されません。 ### 環境変数 CI、script、非対話実行では環境変数も使えます: ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ```powershell $env:AIAND_API_KEY = "sk-your-aiand-api-key" ``` ## 3. モデルを選ぶ model picker を開き、**ai&** セクションからモデルを選びます: ```text /models ``` モデル名は `aiand/` 形式です(例: `aiand/moonshotai/kimi-k3`)。OpenCode は provider catalog を自動で取得するため、ai& に新しいモデルが追加されると、再インストールなしで再起動後に表示されます。 ## 4. OpenCode を実行 対話型の terminal UI: ```bash opencode ``` One-shot CLI: ```bash opencode run "say hi in one word" ``` ## Desktop App Desktop app もターミナルと同じ組み込みの ai& provider を使います: 1. [opencode.ai/download](https://opencode.ai/download) から **OpenCode Desktop** をインストールする。 2. **Settings → Providers → View all providers** を開き、**ai&** を検索して API キーを貼り付ける。 3. project folder を開く。 4. `/models` で `aiand/...` モデルを選ぶ。 ## 動作確認 OpenCode が ai& に接続できるか確認します: ```bash opencode run -m aiand/moonshotai/kimi-k3 "reply with only: ok" ``` キーを ai& に直接送って確認することもできます: ```bash curl -sS https://api.aiand.com/v1/models \ -H "Authorization: Bearer $AIAND_API_KEY" ``` ```powershell Invoke-RestMethod https://api.aiand.com/v1/models ` -Headers @{ Authorization = "Bearer $env:AIAND_API_KEY" } ``` ## トラブルシューティング - **provider 一覧に ai& が表示されない** — OpenCode を最新版に更新して再起動し、provider catalog を再取得してください。 - **ai& カタログにあるモデルが `/models` に表示されない** — models.dev の掲載は [ai& カタログ](/ja/models/catalog/) より遅れることがあります。OpenCode を再起動し、それでも表示されない場合は `opencode run -m aiand/` でモデル ID を直接指定してください。 - **Unauthorized request** — `/connect` または `opencode auth login`(ターミナル)、あるいは **Settings → Providers → View all providers → ai&**(Desktop)でキーを再入力するか、OpenCode を起動している process に `AIAND_API_KEY` が設定されているか確認してください。 - **Desktop app がキーを認識しない** — **Settings → Providers → View all providers → ai&** からキーを追加するか、`AIAND_API_KEY` を export した shell から Desktop を起動してください。 --- # PydanticAI Source: https://aiand-docs-staging.pages.dev/ja/integrations/pydantic-ai/ [PydanticAI](https://ai.pydantic.dev/) は LLM を型付き関数として扱うフレームワークです。OpenAI 互換プロバイダ経由で ai& と接続できます。 ## セットアップ ```bash pip install pydantic-ai ``` ```python from pydantic_ai import Agent from pydantic_ai.models.openai import OpenAIChatModel from pydantic_ai.providers.openai import OpenAIProvider model = OpenAIChatModel( "google/gemma-4-31b-it", provider=OpenAIProvider( base_url="https://api.aiand.com/v1", api_key="sk-your-api-key", ), ) ``` ## 型付きエージェント ```python agent = Agent(model, system_prompt="Be concise.") result = await agent.run("What is the capital of France?") print(result.output) ``` ## 構造化出力 ```python from pydantic import BaseModel class Contact(BaseModel): name: str email: str agent = Agent(model, output_type=Contact) result = await agent.run("From: Jane Doe ") print(result.output.name, result.output.email) ``` スキーマは strict な `final_result` ツールのパラメータとして ai& に送信され、ツール呼び出しの引数が Pydantic モデルに復元されます。 ## ツール ```python agent = Agent(model) @agent.tool_plain def get_weather(city: str) -> str: """Get current weather for a city.""" return f"Sunny in {city}, 22°C" result = await agent.run("What's the weather in Tokyo?") print(result.output) ``` --- # Vercel AI SDK Source: https://aiand-docs-staging.pages.dev/ja/integrations/vercel-ai/ Vercel AI SDK は `@ai-sdk/openai-compatible` で ai& に接続します。 ## セットアップ ```bash npm install ai @ai-sdk/openai-compatible ``` ```ts import { createOpenAICompatible } from "@ai-sdk/openai-compatible"; export const aiand = createOpenAICompatible({ name: "aiand", baseURL: "https://api.aiand.com/v1", apiKey: process.env.AIAND_API_KEY, includeUsage: true, }); ``` API キーは [ai& コンソール](https://console.aiand.com) で発行し、`AIAND_API_KEY` に設定します。 ## テキスト生成 ```ts import { generateText } from "ai"; import { aiand } from "./client"; const { text } = await generateText({ model: aiand("google/gemma-4-31b-it"), prompt: "Tell me a haiku about Tokyo.", }); console.log(text); ``` システムプロンプトは `{ role: "system" }` メッセージではなく `instructions` に置きます。 ## ブラウザにストリーム (Next.js App Router) ```bash npm install @ai-sdk/react ``` ```ts // app/api/chat/route.ts import { convertToModelMessages, createUIMessageStreamResponse, streamText, toUIMessageStream, type UIMessage } from "ai"; import { aiand } from "@/lib/aiand"; export async function POST(req: Request) { const { messages }: { messages: UIMessage[] } = await req.json(); const result = streamText({ model: aiand("google/gemma-4-31b-it"), messages: await convertToModelMessages(messages), }); return createUIMessageStreamResponse({ stream: toUIMessageStream({ stream: result.stream }), }); } ``` ```tsx // app/page.tsx "use client"; import { useChat } from "@ai-sdk/react"; import { useState } from "react"; export default function Page() { const { messages, sendMessage } = useChat(); const [input, setInput] = useState(""); return (
{ e.preventDefault(); sendMessage({ text: input }); setInput(""); }} > {messages.map((m) => (
{m.role}:{" "} {m.parts.map((part, i) => (part.type === "text" ? {part.text} : null))}
))} setInput(e.target.value)} />
); } ``` ## ツール ```ts import { generateText, tool } from "ai"; import { z } from "zod"; import { aiand } from "./client"; const result = await generateText({ model: aiand("google/gemma-4-31b-it"), tools: { getWeather: tool({ description: "Get current weather", inputSchema: z.object({ city: z.string() }), execute: async ({ city }) => `Sunny in ${city}, 22°C`, }), }, prompt: "What's the weather in Tokyo?", }); ``` ## 推論 (reasoning) 推論モデルは `providerOptions` でレベルを受け取ります。モデルごとの対応レベルは [モデルカタログ](https://api.aiand.com/v1/models) の `reasoning_efforts` にあります。 ```ts const { text } = await generateText({ model: aiand("moonshotai/kimi-k3"), prompt: "Solve this step by step: What is 15 * 23?", providerOptions: { aiand: { reasoningEffort: "high", }, }, }); ``` --- # Anthropic からの移行 Source: https://aiand-docs-staging.pages.dev/ja/migrating-anthropic/ ai& Inference API は OpenAI に加えて Anthropic 互換のエンドポイントも提供しています。`anthropic` SDK を利用している場合、**ベース URL** と **API キー** を変更するだけで移行できます。 ## 2 箇所の変更 ```python from anthropic import Anthropic client = Anthropic( base_url="https://api.aiand.com", api_key="sk-your-aiand-api-key", ) ``` ```ts import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: "https://api.aiand.com", apiKey: "sk-your-aiand-api-key", }); ``` SDK が自動で送信する `anthropic-version` ヘッダにより、Files のような共通エンドポイントでも Anthropic 形式のペイロードを返します。 ## 対応エンドポイント | Anthropic エンドポイント | ai& のパス | 備考 | |--------------------------|------------|------| | `/v1/messages` | [Messages](/ja/api/messages/) | ストリーミング + ツール使用 + ビジョン | | `/v1/files` | [Files](/ja/api/files/) | `anthropic-version` ヘッダで Anthropic 形式を選択 | ## 異なる点 - **API キー** は `sk-ant-` ではなく `sk-` で始まります — [認証](/ja/authentication/) を参照。 - **モデル ID** は Anthropic とは異なります。OpenAI 互換面の `client.models.list()` か [カタログ](/ja/models/catalog/) で確認できます。 --- # OpenAI からの移行 Source: https://aiand-docs-staging.pages.dev/ja/migrating-openai/ ai& Inference API は OpenAI の Chat Completions / Responses / Models API とワイヤ互換です。既存の OpenAI 統合がある場合、通常は **ベース URL** と **API キー** を変更するだけで移行できます。 ## 2 箇所の変更 ```python from openai import OpenAI client = OpenAI( base_url="https://api.aiand.com/v1", api_key="sk-your-aiand-api-key", ) ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-your-aiand-api-key", }); ``` これ以外 — `chat.completions.create`、ストリーミング、ツール呼び出し、構造化出力 — はそのまま動作します。 ## 対応エンドポイント | OpenAI エンドポイント | ai& のパス | 備考 | |----------------------|------------|------| | `/v1/chat/completions` | [Chat Completions](/ja/api/chat-completions/) | 完全互換 | | `/v1/models` | [Models](/ja/api/models/) | 公開。API キーありは組織通貨、なしは USD 建て | | `/v1/files` | [Files](/ja/api/files/) | 同じ multipart アップロード形式 | | `/v1/uploads` | [Uploads](/ja/api/uploads/) | 大容量ファイル向けのチャンクアップロード | OpenAI のレガシーな `/v1/completions` は利用できません。プロンプトを user メッセージとして `/v1/chat/completions` に送信してください。`/v1/completions` へのリクエストには、エラーコード [`endpoint_removed`](/ja/errors/#主なエラーコード) 付きの `410` が返ります。 ## 異なる点 - **API キー** は OpenAI と同様に `sk-` から始まりますが ai& が発行します — [認証](/ja/authentication/) を参照。 - **モデル ID** が異なります。`client.models.list()` または [カタログ](/ja/models/catalog/) で確認できます。 - **組織のスコープ** — JWT 認証時は `X-Org-ID` を指定。API キー認証ではキーから自動的に組織が解決されます。 --- # モデルの自動選択 Source: https://aiand-docs-staging.pages.dev/ja/models/auto/ `auto` は予約されたモデル名です。`model` に指定すると、ai& がそのリクエストに対して具体的なモデルを選択し、通常どおり処理します。リクエスト / レスポンスの形式、ストリーミングの挙動、課金ルールは、モデル名を直接指定した場合と同じです。 用途の異なるリクエストが混在するワークロードで、すべてを最も高価なモデルに送らずに済ませるための機能です。短い検索的な質問は安価なモデルに、推論を要する処理はそれが可能なモデルに解決されます。 ## 使い方 ```bash curl -i https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-your-api-key" \ -H "Content-Type: application/json" \ -d '{ "model": "auto", "messages": [{"role": "user", "content": "日本の首都は?"}] }' ``` ```python from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") response = client.chat.completions.with_raw_response.create( model="auto", messages=[{"role": "user", "content": "日本の首都は?"}], ) print(response.headers["x-model"]) print(response.parse().choices[0].message.content) ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-..." }); const { data, response } = await client.chat.completions .create({ model: "auto", messages: [{ role: "user", content: "日本の首都は?" }], }) .withResponse(); console.log(response.headers.get("x-model")); console.log(data.choices[0].message.content); ``` `auto` は `/v1/chat/completions`、`/v1/responses`、`/v1/messages` で利用できます。 ## 実行されたモデルの確認 解決されたモデルのカタログ名(小文字化)は、レスポンスヘッダ `X-Model` で返されます。比較は大文字小文字を区別せずに行ってください。ストリーミングでも同様に取得できます — レスポンスヘッダはボディの最初のチャンクより先に到達するため、ストリームが開いた時点で読み取れます。 ``` X-Model: google/gemma-4-31b-it ``` このヘッダは CORS で公開しているため、ブラウザのクライアントからも読み取れます。[リクエストログ](/ja/analytics/logs/) と利用実績にも解決後のモデル名が記録されます (`auto` は記録されません)。そのため、自動選択を使っているかどうかに関わらず、コストの按分や分析はそのまま機能します。[レスポンスヘッダ](/ja/reference/response-headers/) も参照してください。 ## モデルの選択方法 以下の 3 ステップで決定します。 1. **絞り込み** — **そのリクエスト**に対して組織が呼び出せるモデルに限定します。自動選択のプールに追加されていること、プラン上の利用権があること、プロンプトがコンテキストウィンドウに収まること、リクエストに含まれるすべての入力モダリティ (画像・動画・音声) に対応していること、が条件です。 2. **並べ替え** — 残ったモデルを能力の低い順に並べます。能力が同等のモデル同士では、価格の安い方が先になります。 3. **選択** — リクエストの複雑さを 4 段階のティアに分類し、ティアがそのリストの中の位置を決めます。 | ティア | 解決先の傾向 | 典型的なリクエスト | | ----------- | -------------------- | ---------------------------------------------------- | | `simple` | 最も能力の低いモデル | 挨拶、相槌、短い答えが決まっている事実の確認 | | `medium` | リストの下寄り中間 | ある程度の説明を要する日常的なリクエスト | | `complex` | リストの上寄り中間 | 平易でないコード、多段階の分析、専門知識を要するもの | | `reasoning` | 最も能力の高いモデル | 証明、導出、症状からのデバッグ、設計上のトレードオフ | 能力の順位は価格ではなく、公開されているベンチマーク結果に基づきます。価格と能力は必ずしも一致せず、高価であることは性能が高い根拠にはならないためです。まだ順位付けされていないモデルは `auto` の選択対象になりません。利用する場合はモデルを直接指定してください。 **プールは、能力と価格が揃って上がるように選定しています。** 上の説明で「安価なモデル」と「最も能力の低いモデル」が同じ選択を指しているのはこのためで、両者は競合する基準ではありません。あるモデルがプールに入るのは、それより安価で同等以上に能力の高いモデルが存在しない場合に限られるため、能力順に並べることは価格順に並べることでもあります。価格ではなくベンチマークで順位付けしているのは、カタログが変化してもこの前提を保つためです。能力が変わらないまま価格だけが上がったモデルは、リストの上位へずれていくのではなく、プールから外れます。 `reasoning` ティアでは、組織が `reasoning` capability を持つモデルを利用できる場合、まずそれらに絞り込みます。 **難易度の判定には通常、別のモデルが介在します。** 挨拶や相槌はローカルで判別し、プール内で最も能力の低いモデルに解決します。それ以外はすべて当社が選定した小規模モデルが判定し、これが唯一の難易度判定です。難しいリクエストをローカルでスコアリングすることはありません。キーワードの一覧では、あらゆる言語で難易度を確実に判定できないためです。 この問い合わせが行われる場合、リクエストのテキスト (一定の長さに切り詰め、システム指示は別のラベルを付与したもの) が、回答するモデルの実行前にその判定用モデルへ送信されます。判定用モデルは当社のカタログから選ばれ、お客様の組織が通常利用しているモデルとは限らないため、別のプロバイダになることもあります。[ゼロデータリテンション](/ja/organizations/zero-data-retention/)の組織では、リクエストのテキストは ai& が提供する判定用モデルにのみ送信されます。当社が選定している判定用モデルがそうでない場合は判定を行わず、プールの中間に解決します。この判定分が課金されることはなく、使用量にも表示されません。なお、較正のため、それ以外のリクエストのごく一部も背後で判定しています。指定したモデル以外にリクエストが渡らないことがデータ取り扱い上の要件である場合は、モデルを直接指定してください。 **`auto` は `reasoning_effort` を受け付けません。** 指定した場合は 400 になります。effort を自分で選びたい場合は、モデル名を直接指定してください。上記の並び順は各モデルの公開指標に基づいており、この指標はモデルごとに 1 つの構成で計測された値です。そのため、呼び出し側が effort を指定すると、並び順が前提としているその計測点からモデルがずれてしまいます。`auto` はモデルのみを選び、effort はそのモデル本来の既定値 — つまり指標が計測された設定 — のままにします。 `reasoning_effort: "none"` も同様に拒否します。理由はより明確で、推論モデルの思考を抑制した状態は、そのモデルが順位付けされた計測点から最も遠い状態だからです。 `/v1/responses` の `reasoning.effort` も同じ扱いです。エンドポイントごとのフィールド名の違いに関わらず、規則は変わりません。 [`/v1/messages`](/ja/api/messages/) の `thinking: { "type": "disabled" }` は、拒否ではなく無視されます。呼び出し側が effort を指定したわけではないので、リクエストは通常どおりルーティングされ、選ばれたモデルは本来の既定 effort のまま動きます。reasoning を無効化したい場合は、`none` を公開しているモデルを直接指定してください。 **クレジット残高がない場合は、ティアに関わらず無料モデルへ優先的に絞り込みます。** 有料モデルを選んでも、指定していないモデルに対してクレジット不足のエラーが返るだけだからです。プール内に無料モデルがない場合は、通常どおりそのエラーが返ります。 プールは組織ごとに異なるため、同じプロンプトでも組織が違えば別のモデルに解決されることがあります。 ## 課金 解決されたモデルの通常の入力 / 出力単価で課金されます。`auto` の利用に対する追加料金はなく、明細も分かれません。実行されたモデルに対する課金として計上されます。 つまり、プールが変われば**同一のリクエストでも呼び出しごとにコストが変わり得ます**。単一モデルの単価ではなく、[利用状況](/ja/billing/usage/) の合計値を基準に予算を見積もってください。 ## 会話 `auto` はリクエストごとに判定するため、複数ターンの会話は毎ターン再判定されます。前のターンより難しいと判定された追加質問は別のモデルに解決されることがあり、`X-Model` はスレッドの途中で変わり得ます。 これには把握しておくべきコストがあります。[プロンプトプレフィックス割引](/ja/models/pricing/)は会話が同じモデルに続く間だけ適用されるため、モデルが切り替わったターンではその割引を失います。会話全体で 1 つのモデルを使う必要がある場合は、モデルを直接指定してください。指定したモデルが再ルーティングされることはありません。 ## その他の制約 - **判定用モデルが利用できない場合、リクエストはプールの中間に解決されます。** タイムアウトや障害時には難易度を判定する材料がないため、挨拶と判別されなかったリクエストは推測に頼らず、中位の能力のモデルに解決します。これは意図的に最も能力の低いモデルではありません — 難しいリクエストが黙って格下げされることはない、という意味です — が、`X-Model` が同じリクエストの通常の解決先と異なり得ることは意味します。固定する必要がある場合は、モデルを直接指定してください。 - **`auto` は `GET /v1/models` に含まれません。** モデルではなくルーティングの指示であり、固有の capability・コンテキストウィンドウ・価格を持ちません。 - **プールは変化します。** カタログの更新に伴い、モデルは追加も削除もされます。特定のプロンプトが常に特定のモデルに解決されることを前提としたロジックは避けてください。 - **capability の要件は絞り込むだけで、上書きはしません。** 画像を含むリクエストは画像に対応したモデルのみを対象とします。プール内に該当するモデルがなければ、画像を黙って無視するのではなくリクエストを拒否します。 ## エラー | ステータス | メッセージ | 原因 | | ---------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------ | | 400 | `Model 'auto' is not supported.` | 自動選択が有効化されていません。モデル名を直接指定してください。 | | 400 | `No model available to 'auto' can serve this request.` | プール内にリクエストを処理できるモデルがありません。多くはモダリティまたはコンテキスト長の不一致です。 | | 400 | `Model 'auto' does not accept reasoning_effort.` | `auto` は effort もモデルと併せて決定します。自分で指定する場合はモデル名を直接指定してください。 | いずれも [エラー](/ja/errors/) に記載の `invalid_request_error` の形式です。`param` は `model`、最後の 1 件のみ送信した effort のフィールド名になります。 --- # モデルカタログ Source: https://aiand-docs-staging.pages.dev/ja/models/catalog/ ai& は現在、以下のオープンウェイトモデルを提供しています。カタログは動的で、組織ごとにアクセス可能なモデルが異なるため、正確な一覧は常に `GET /v1/models` で取得してください。 ## クイックピック このページではピックをライブで算出します (出力単価が最安のモデル、画像・動画・ドキュメント入力に対応するモデル、最大コンテキストのモデル)。元のデータは `GET /v1/models` で取得できます。 ## 利用可能なモデル このページでは表をライブで描画します。各モデルの capability・コンテキストウィンドウ・価格は `GET /v1/models` で取得できます。 出力単価の安い順。価格は 100 万トークンあたりの USD です — リクエスト単位のコスト計算は [料金](/ja/models/pricing/) を参照。 自分で選ばず、リクエストごとに ai& に選択させることもできます — [モデルの自動選択](/ja/models/auto/) を参照。 ## Capability の値 | Capability | 意味 | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `reasoning` | 内部の reasoning トークンを出力 (出力として課金) し、`reasoning_effort` を受け付けます。受け付ける値は共通ではないため、各モデルの `reasoning_efforts` を参照してください。reasoning をオフにできるのは、そのレベルに `none` が含まれる場合だけです。 | | `tool_calling` | `tools` / `tool_choice` を受け付け。[ツール呼び出し](/ja/capabilities/tool-calling/) を参照。 | | `vision` | 画像入力 (`image_url` または `file_id`) を受け付け。[ビジョン](/ja/capabilities/vision/) を参照。 | | `video` | `file_id` 経由で動画入力を受け付け。[動画理解](/ja/capabilities/video/) を参照。 | | `document` | PDF / ドキュメント入力を受け付け。 | このリストに含まれない capability を使うリクエストはバリデーション時に拒否されます。 ## モデル一覧をプログラムから取得 ```bash curl https://api.aiand.com/v1/models ``` ```python from openai import OpenAI client = OpenAI(base_url="https://api.aiand.com/v1", api_key="sk-...") for m in client.models.list().data: print(m.id, m.context_window, m.capabilities) ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-..." }); const { data } = await client.models.list(); for (const m of data) console.log(m.id, m.context_window, m.capabilities); ``` ```bash aiand models aiand models --capability vision --sort output ``` 料金は 100 万トークンあたりの請求通貨建てで表示されます。[ai& CLI](/ja/cli/) を参照。 ## レスポンス形式 (OpenAI 互換) ```json { "object": "list", "data": [ { "id": "google/gemma-4-31b-it", "name": "google/gemma-4-31b-it", "object": "model", "created": 1775474514, "owned_by": "ai&", "provider": "google", "context_window": 262144, "max_output_tokens": 32768, "capabilities": [ "reasoning", "tool_calling", "vision", "video", "document" ], "reasoning_efforts": [ "none", "high" ], "reasoning_effort_default": "none", "description": "Largest Gemma 4 instruction model for open, self-hosted chat and reasoning", "currency": "usd", "input_per_1m": "0.200000", "output_per_1m": "0.500000", "cached_input_per_1m": "0.050000", "deprecation_date": null } ] } ``` | フィールド | 型 | 意味 | | -------------------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | `id` | string | chat / responses / messages の `"model"` に渡す値。 | | `provider` | string | オープンウェイトを公開した研究所 (`openai`、`google`、`qwen` 等)。`provider` に関わらず、すべてのモデルは ai& のインフラ上でホストされます。 | | `context_window` | int | 入力 + 出力の最大合計トークン数。 | | `max_output_tokens` | int \| null | 記録済みの最大生成トークン数。上限が記録されていないときは `null`。一覧は推測値を埋めません。 | | `capabilities` | string[] | 対応機能 — 上の表を参照。 | | `reasoning_efforts` | string[] \| null | このモデルが実行する `reasoning_effort` の値。それ以外の既知のレベルは、一覧にある一つ上のレベル(なければ最も高いレベル)で実行され、送信したレベルより高コストになる場合があります。適用されたレベルは [`X-Reasoning-Effort`](/ja/reference/response-headers/) で返されます。モデルが reasoning をオフにできるのは、その levels に `none` が含まれる場合だけで、effort の語彙にない値は 400 になります。`null` は `reasoning` 機能を持たないモデルだけです。 | | `reasoning_effort_default` | string \| null | UI の初期値として推奨されるレベル。サーバー側では適用されません — `reasoning_effort` を省略した場合は上流のデフォルトがそのまま使われます。 | | `currency` | string | 組織の請求通貨(`usd` または `jpy`)。組織作成時に決まります。API キーなしの場合は `usd`。 | | `input_per_1m` | string | **100 万トークンあたり** の入力単価(請求通貨建て)。精度保持のため文字列形式。 | | `output_per_1m` | string | **100 万トークンあたり** の出力単価(請求通貨建て)。 | | `deprecation_date` | string \| null | モデルがリクエストの受付を終了する日時 (ISO 8601)。終了予定がないときは `null`。 | ## Anthropic 互換 `anthropic-version` ヘッダを付与すると Anthropic 互換形式が返却されます — `data[].display_name`、`created_at`、`has_more`、`first_id`、`last_id`。価格と capability は OpenAI 互換形式にのみ含まれます。 --- # 料金 Source: https://aiand-docs-staging.pages.dev/ja/models/pricing/ ai& は推論をトークン単位で課金し、リクエスト完了時にプリペイドのクレジット残高から差し引きます。チャージは [クレジットとチャージ](/ja/billing/credits/) から。 ## 計算式 ``` cost = (input_tokens / 1_000_000) × input_per_1m + (output_tokens / 1_000_000) × output_per_1m ``` `input_per_1m` と `output_per_1m` はいずれも **組織の請求通貨(USD または JPY、組織作成時に固定)建ての 100 万トークンあたり単価** で、`currency` フィールドとともに `GET /v1/models` の各モデル行に含まれます。API キーなしで呼び出した場合は USD 建てで返されます。請求通貨の価格が設定されていないモデルは一覧に表示されず、呼び出すこともできません。 ## プロンプトキャッシュ キャッシュ入力単価を持つモデルでは、リクエストのメッセージが同じ組織から同じモデルへ同じ `tools` で送られた以前のリクエストのメッセージ全体で始まる場合に、その単価が適用されます。単一文字列の `prompt` や `input` は、完全に同一の繰り返しのときだけ対象になり、テキストを追加しても対象になりません。会話では各ターンのメッセージが直前のターンのメッセージで始まるため、その部分が割引されます。`cache_control` マーカーやコード変更は不要です。 モデルがキャッシュ単価を持つ場合、コストは次のようになります: ``` cost = (cached_tokens / 1_000_000) × cached_input_per_1m + (input_tokens − cached_tokens) / 1_000_000 × input_per_1m + (output_tokens / 1_000_000) × output_per_1m ``` キャッシュされたトークン数は、各 SDK が想定するフィールドでレスポンスの `usage` に返されます: | API | フィールド | |-----|-----------| | OpenAI Chat Completions | `usage.prompt_tokens_details.cached_tokens` | | OpenAI Responses | `usage.input_tokens_details.cached_tokens` | | Anthropic Messages | `usage.cache_read_input_tokens` | ストリーミングレスポンスでは、同じ値が `event: metrics` trailer の `tokens.cached` として返されます(`X-Aiand-Metrics: true` 付与時)。 - キャッシュは **1024 トークン以上** のプロンプトに適用され、**128 トークン単位** で計上されます。 - 再利用は組織ごとにスコープされ、無操作からおよそ **10 分** 持続します。 - キャッシュ入力単価を持つモデルのみが `cached_tokens` を返します。それ以外のモデルでは入力はすべて標準単価で課金され、このフィールドは省略されます。 ## リクエスト単位のコスト表示 リクエストヘッダ `X-Aiand-Metrics: true` を付与すると、レスポンスごとに正確な計算済みコストを受け取れます: - **非ストリーミング**: `X-Cost` + `X-Cost-Currency` ヘッダ。[レスポンスヘッダ](/ja/reference/response-headers/) を参照。 - **ストリーミング**: モデルの終端メッセージ後の `event: metrics` trailer イベント。ペイロードにはトークン数・`cost` に加えて、コストの通貨を示す `currency` フィールドが含まれます。[ストリーミングイベント](/ja/reference/streaming-events/) を参照。 過去分の利用状況・コストは [Analytics](/ja/analytics/metrics/) と [リクエストログ](/ja/analytics/logs/) からも参照できます。 ## 課金されるケース | 結果 | 課金 | |------|------| | 出力ありの 2xx | あり — `(入力 × 単価) + (出力 × 単価)` | | モデル呼び出し前の 4xx (バリデーション・認証・レート制限・残高不足) | なし | | 一部ストリーミング後の 5xx | 生成済み分は課金 | | ストリーム中断 | 生成済み分は課金 | リクエスト確定時にアトミックに引き落とされるため、並行リクエストでも残高超過は発生しません。 ## ティア トークン単価はティアによらず共通です。ティアで異なるのはスループット — RPM / TPM の上限は [レート制限](/ja/reference/rate-limits/) を参照。 --- # 組織の API キー Source: https://aiand-docs-staging.pages.dev/ja/organizations/api-keys/ API キーはサーバー間通信で推奨される認証方式です。各キーは単一の組織にスコープされ、リクエストごとに組織の課金アカウントを自動解決します — `X-Org-ID` ヘッダは不要です。 ## キーの形式 すべてのキーは `sk-` で始まり、作成時に **一度だけ** 表示されます。シークレットマネージャーに保存してください — 後から再取得することはできません。 ## キーの作成 ```bash curl -X POST https://api.aiand.com/api/v1/keys \ -H "Authorization: Bearer " \ -H "X-Org-ID: " \ -H "Content-Type: application/json" \ -d '{"name": "production-server"}' ``` またはコンソールから: Settings → API Keys → Create。 手元のマシンでは、[ai& CLI](/ja/cli/) の `aiand login` を実行してブラウザでサインインを承認すると、`aiand@` という名前のキーが作成・保存されます。 ## キーの管理 | 操作 | エンドポイント | |------|----------------| | 一覧 | `GET /api/v1/keys` | | 作成 | `POST /api/v1/keys` | | 更新 (名前・状態) | `PATCH /api/v1/keys/{key_id}` | | 無効化 | `DELETE /api/v1/keys/{key_id}` | すべての管理エンドポイントは JWT 認証 + `X-Org-ID` を必要とします。 ## ローテーション キーは自動で失効しません。ただし `aiand login` で作成したキーは例外で、有効期間は 30 日、[ai& CLI](/ja/cli/) が自動でローテーションします。それ以外のキーは以下のタイミングでローテーションしてください: - キーへアクセス権を持つメンバーが退職した。 - キーが漏洩した (ログ、誤コミット等)。 - コンプライアンスポリシーで定期的なローテーションが必要。 新しいキーを先に作成・デプロイしてから古いキーを失効させると、ダウンタイムを回避できます。 --- # 組織 Source: https://aiand-docs-staging.pages.dev/ja/organizations/concepts/ ai& はマルチテナント設計です。すべてのリクエストは **組織** のコンテキスト内で実行され、課金、API キー、レート制限、リクエスト履歴はすべて組織単位でスコープされます。 ## データモデル - **ユーザー** — メールアドレスで識別される個人アカウント。初回 OAuth またはマジックリンクサインインで作成。 - **組織** — 課金とアクセスの境界。クレジット、API キー、ファイル、リクエストログを保有。 - **メンバーシップ** — ユーザーと組織を **ロール** (`owner`、`admin`、`member`) で結びつけます。1 ユーザーが複数組織に所属可能。 - **API キー** — 組織レベルで発行。組織コンテキストを自動で保持するため、API キー認証時には `X-Org-ID` は不要。 - **課金アカウント** — 組織ごとに 1 つ。クレジット残高、支払い方法、請求履歴を保持。 ## 組織の選択 - **API キー認証** — キー自体に組織が紐づくため、すべての操作がそのキーの組織で行われます。 - **JWT (ブラウザ) 認証** — 各リクエストで `X-Org-ID` を指定して組織を選択します。[組織の切り替え](/ja/organizations/switching/) を参照。 ## 組織ごとのスコープ 以下はすべて組織間で独立しています: - クレジット残高と支払い方法 - API キー - アップロード済みファイル - リクエストログと分析データ - レート制限のバケット ([レート制限](/ja/reference/rate-limits/)) --- # メンバーとロール Source: https://aiand-docs-staging.pages.dev/ja/organizations/members/ 組織には複数のメンバーが所属できます。各メンバーには **ロール** が付与され、できることが決まります。 ## ロール | ロール | 推論 | API キー | 課金 | メンバー | 組織設定 | |--------|------|----------|------|----------|----------| | `owner` | ✓ | 管理 | 管理 | 管理 | 管理 | | `admin` | ✓ | 管理 | 閲覧 | 管理 | 閲覧 | | `member` | ✓ | 自分のキーのみ | 閲覧 | 閲覧 | 閲覧 | - **Owner** は所有権の移譲や組織の削除が可能。最低 1 名は必須です。 - **Admin** はメンバーの招待・削除、キーのローテーションができますが、課金所有者の変更はできません。 - **Member** は API を呼び出したり、自分用の API キーを作成したりできます。 ## メンバーの招待 招待は [コンソール](https://console.aiand.com) から行います — Settings → Members → Invite。招待メールを受け取った相手が承諾すると、選択したロールでメンバーシップが作成されます。 ## メンバーの削除 メンバーを削除するとアクセスは即時失効します。ただし、そのメンバーが作成した API キーは **明示的にローテーションされるまで有効** です — [組織の API キー](/ja/organizations/api-keys/) を参照。 --- # 組織の切り替え Source: https://aiand-docs-staging.pages.dev/ja/organizations/switching/ 1 ユーザーが複数組織に所属できます。リクエストで使用される組織が、課金アカウント、レート制限、モデルアクセス、表示されるファイルを決定します。 ## API キーの場合 API キーは作成時に単一組織にスコープされます。**キー自体が組織を決定する** ため、追加ヘッダは不要です。 ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer sk-..." \ -d '{...}' ``` 別の組織で操作するには、その組織の API キーを使用します。 [ai& CLI](/ja/cli/) も同じ仕組みで、キーはサインイン時に選んだ組織に紐づきます。組織ごとに [プロファイル](/ja/cli/#組織とプロファイル) を用意し、`aiand --profile work usage` のように `--profile` で切り替えてください。 ## JWT (ブラウザ / コンソール) の場合 JWT はユーザーを識別しますが、組織は識別しません。リクエストごとに `X-Org-ID` でアクティブな組織を指定します: ```bash curl https://api.aiand.com/api/v1/keys \ -H "Authorization: Bearer " \ -H "X-Org-ID: " ``` JWT 認証エンドポイントで `X-Org-ID` を指定しないと `400` が返されます。 ## 所属組織の一覧 ```bash curl https://api.aiand.com/api/v1/me \ -H "Authorization: Bearer " ``` レスポンスの `memberships` 配列に各組織の `id`、`name`、自分の `role` が含まれます。ターミナルからは `aiand orgs` で同じ組織の一覧を確認できます。 --- # ゼロデータリテンション Source: https://aiand-docs-staging.pages.dev/ja/organizations/zero-data-retention/ ゼロデータリテンションは組織単位の設定です。この設定の下では、ai& はプロンプト、レスポンス、ファイルを各リクエストに応答する間だけメモリ上に保持し、ストレージには一切書き込みません。 この設定がオフの場合、ai& が内容を保存するのは機能上必要な場合だけです。[内容ログ](/ja/analytics/logs/#内容ログ)がオンの間のリクエスト本文、[ファイル](/ja/api/file-lifecycle/)として保存されるインライン PDF とアップロードしたファイル、プロンプトと動画を含む動画ジョブがこれに当たり、いずれも 30 日以内に削除されます。 オンにするまではオフです。アカウントの初期設定でオンにでき、その後は組織の管理者が [Console](https://console.aiand.com/settings/organizations) の **Settings → Organizations** でオン・オフを切り替えられます。変更は約 1 分以内に組織のすべての API キーと Console セッションに適用されます。 エンタープライズ契約で求められる場合は ai& が設定をロックし、その場合は担当チームだけが変更できます。 ## 変わること | 機能 | ゼロデータリテンションの下で | | --- | --- | | Chat Completions、Responses、Messages | 通常どおり利用できます。`/v1/responses` はどの組織でもレスポンスオブジェクトを保存しません。 | | インライン画像 | 通常どおり利用できます。モデルに渡されるだけで保存されません。 | | インライン PDF | 利用できますが、ファイルとして保存せずメモリ上で描画します。[インライン PDF](#インライン-pdf) を参照。 | | リクエストログ | オフになり、オンにできません。`GET /logs/settings` は `"data_retention": "zero"` を返し、オンにする `PATCH` は `403` を返します。 | | Files API と Uploads API | アップロードは `403` で拒否されます。設定前に保存されたファイルは[後述](#既存の組織で有効にする場合)のとおり削除されます。 | | 動画生成 | `403` で拒否されます。動画ジョブはプロンプトと生成した動画を保存するためです。 | | 外部プロバイダーが提供するモデル | `403` で拒否されます。そのプロバイダー自身の保持ポリシーが適用されるためです。[`auto`](/ja/models/auto/) は ai& が提供するモデルにのみ振り分け、分類のためにリクエストを外部プロバイダーへ送ることもありません。 | 拒否されたリクエストは次を返します: ```json { "error": { "message": "File upload stores content, so it is unavailable to an organization on zero data retention.", "type": "authorization_error", "param": null, "code": "zero_data_retention" } } ``` ## インライン PDF インラインで送られた PDF(Chat Completions または Responses の `file_data`、Messages の `base64` の `document` ブロック)は、メモリ上でページごとに描画され、画像としてモデルに渡されます。ファイルは作成されず、リクエスト間で再利用もされないため、同じ PDF を再送すると再度描画されます。 ページはリクエストの間メモリ上に保持されるため、他の組織より上限が厳しくなっています: - 1 つの PDF は最大 100 ページ - 1 リクエストあたりの PDF は最大 16 MiB - 1 リクエストあたりの描画済みページ画像は最大 10 MiB それより前のメッセージの PDF によって 1 リクエストあたりの上限を超えた場合は、モデルのコンテキストウィンドウを超えた場合と同じく、コード `context_length_exceeded`(Messages では `prompt is too long`)の `400` で拒否されるため、エージェントは履歴を圧縮できます。最新のメッセージの PDF だけで上限を超える場合は、コード `invalid_value` の `400` で拒否されます。 ## 引き続き保持されるもの ゼロデータリテンションの対象はリクエストの内容です。以下は課金と運用に必要なため保持されますが、いずれもプロンプトやレスポンスの本文は含みません: - **リクエストのメタデータ**: リクエストごとのモデル、トークン数、コスト、ステータス、時刻。[リクエストログ](/ja/analytics/logs/) に表示されるものと同じ行で、365 日間保持されます。 - **プロンプトキャッシュ**: キャッシュ済み入力トークンの料金計算のため、各プロンプトの先頭部分の一方向ハッシュとトークン数を 10 分間保持します。ハッシュは本文ではありません。 - **モデルの作業メモリ**: 生成中、モデルはプロンプトの中間状態(KV キャッシュ)を GPU とサーバーのメモリに保持します。ストレージには書き込まれず、1 日以内に破棄されます。 - **運用ログ**: リクエスト ID、ステータスコード、処理時間。プロンプトやレスポンスは一切含みません。 ## 既存の組織で有効にする場合 オンにすると、組織がすでに保存している内容は削除され、後でオフにしても元に戻りません。確定する前に、削除されるファイルと動画の件数が Console に表示され、保存済みのリクエストログをダウンロードできます([`GET /logs/export`](/ja/analytics/logs/#保存された内容のエクスポート))。 - ファイルは 15 分以内に削除され、進行中のアップロードは取り消されます。 - 保存済みのリクエストログと完了した動画は 1 日以内に削除されます。生成中の動画は完了まで処理され、完了から 1 日以内に削除されます。 法的保全などで保存が義務付けられている内容は、保全が解除されるまで保持されます。過去の動画リクエストのモデレーション記録(プロンプトを含む)は、不正利用の証拠として 30 日間保持された後に削除されます。 ## オフにする場合 リクエストログは、管理者が **Settings → Organizations** で再度オンにするまでオフのままです。設定がオンの間に削除されたものは戻りません。 --- # レート制限 Source: https://aiand-docs-staging.pages.dev/ja/reference/rate-limits/ ai& は共有負荷下でプラットフォームを健全に保つため、組織単位でレート制限を適用します。上限はティアによって決まり、推論エンドポイントに適用されます — 管理 API には別途 (緩めの) 制限があります。 ## ティア | ティア | 説明 | |--------|------| | **Tier 0** | 評価用ティア。分あたり上限が低め。開発や小規模プロジェクト向け。新規組織はこのティアから始まります。 | | **Tier 1** | 本番用ティア。上限が高く、高スループットモデルへもアクセス可能。初回の決済成功時に自動昇格します。 | ## 計測対象 各リクエストは 6 つのバケットで判定されます — モデル単位の 4 つと、組織単位の 2 つ (global): - **Per-model RPM** — 特定モデルに対する 1 分間のリクエスト数。 - **Per-model Input TPM** — 特定モデルに対する 1 分間の入力トークン数 (リクエストボディから事前に見積もり)。 - **Per-model Output TPM** — 特定モデルに対する 1 分間の出力トークン数 (レスポンス完了後に計上)。 - **Per-model Concurrency** — 特定モデルに対する同時実行中リクエスト数の上限。 - **Global RPM** — **すべてのモデル**を合わせた 1 分間のリクエスト数。 - **Global Concurrency** — すべてのモデルを合わせた同時実行中リクエスト数の上限。 いずれかのバケットが先に埋まった時点でスロットルされます。 ## ヘッダ 認証を通過してモデルの受付判定に到達したすべての推論リクエスト — `200`、ストリーミング、およびこれら 6 つのバケットによる `429` を含む — に、適用される各バケットの状態が付与されます。最初の 2 行は OpenAI のヘッダ名と形式をそのまま使っているため、既にこれらを読み取るツールはそのまま動作します。残りは同じパターンを拡張したものです。 | バケット | ヘッダ | |----------|--------| | Per-model RPM | `x-ratelimit-limit-requests`, `x-ratelimit-remaining-requests`, `x-ratelimit-reset-requests` | | Per-model Input TPM | `x-ratelimit-limit-tokens`, `x-ratelimit-remaining-tokens`, `x-ratelimit-reset-tokens` | | Per-model Output TPM | `x-ratelimit-limit-output-tokens`, `x-ratelimit-remaining-output-tokens`, `x-ratelimit-reset-output-tokens` | | Per-model Concurrency | `x-ratelimit-limit-concurrency`, `x-ratelimit-remaining-concurrency` | | Global RPM | `x-ratelimit-limit-global-requests`, `x-ratelimit-remaining-global-requests`, `x-ratelimit-reset-global-requests` | | Global Concurrency | `x-ratelimit-limit-global-concurrency`, `x-ratelimit-remaining-global-concurrency` | - `limit-*` はバケットの上限、`remaining-*` は現時点の残量です。`remaining-tokens` は入力トークンのみを数えます — 出力トークンはレスポンス完了後に計上されます。 - `reset-*` はそのバケットが再び満杯になるまでの時間で、`45s` や `6m0s` のような duration 形式です。concurrency バケットには reset がありません: 実行中リクエストの完了とともに空きます。 - ティアに上限がないバケット (Input/Output TPM や global の上限が `0`) は省略されます。`limit-requests` または `limit-concurrency` が `0` の場合は逆で、そのモデルはあなたのティアには閉じており、待っても開きません。 これら 6 つのモデルバケットによる `429 Too Many Requests` では、さらに以下が追加されます: | ヘッダ | 意味 | |--------|------| | `X-RateLimit-Policy` | 拒否したバケット: `rpm` / `global_rpm` / `input_tpm` / `output_tpm` / `concurrency` / `global_concurrency`。 | | `Retry-After` | このリクエストが通るようになるまでの秒数 — バケット全体の回復を待つ `reset-*` より短くなります。`concurrency` と `global_concurrency` の拒否では付かない — 実行中リクエストの完了/キャンセルで解消する。 | 以前の `X-RateLimit-Limit` と `X-RateLimit-Remaining` は、非推奨の互換エイリアスとして引き続き返されます。新規の実装では上記の明示的なヘッダを使用してください。認証スロットルはモデルの受付判定より前に行われるため、`Retry-After` のみが付き、`X-RateLimit-Policy` とバケットヘッダは付きません。`GET /v1/models` のような公開カタログエンドポイントはこの方式では計測されず、これらのヘッダは付きません。 レート制限以外のヘッダは [レスポンスヘッダ](/ja/reference/response-headers/) を参照。 ## 429 レスポンス スロットルされると `429 Too Many Requests` が返されます。2 種類のバケットは解消の仕方が異なるため、`X-RateLimit-Policy` を確認して拒否の種類に応じて対処してください — 同じ「バックオフして再試行」は concurrency の拒否には当てはまりません。 **時間ベースの拒否** — `rpm` / `global_rpm` / `input_tpm` / `output_tpm`。ウィンドウの経過とともに回復します。`Retry-After` が最小の安全な待機時間を示すので、少なくともその時間だけ待ってから、ジッタ付きの指数バックオフで再試行してください。 **concurrency の拒否** — `concurrency` / `global_concurrency`。時間では解消せず、実行中のリクエストが完了またはキャンセルされたときにのみ空くため、`Retry-After` は付きません。新たに送信する前に、実行中のリクエストを消化させる (または同時実行数を下げる) 必要があります。 --- # レスポンスヘッダ Source: https://aiand-docs-staging.pages.dev/ja/reference/response-headers/ ai& は OpenAI / Anthropic 形式のレスポンスボディに変更を加えず、リクエストのメタデータは HTTP ヘッダで提供します。これにより公式 SDK とのワイヤ形式互換性が保たれます。 ## 識別 / トレース | ヘッダ | 説明 | | -------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-Request-ID` | トレース対象の API ルート(推論、認証、課金、Files)におけるこのリクエストの一意 ID。サポート問い合わせ時に添付してください。 | | `traceparent` | [OpenTelemetry のコンテキスト伝播](https://opentelemetry.io/docs/concepts/context-propagation/)で使用するヘッダ。トレース対象の推論ルートと auth/files/billing の HTTP リクエストでは、受信値を受け入れるか新しいトレースを開始し、可能な場合は下流へ伝播して、サーバーのトレースコンテキストをレスポンスで返します。これにより分散トレースを関連付けられます。 | | `X-Model` | 実際にリクエストを処理したモデルのカタログ名(小文字化)。解決後の名前を返すため、送信した値と大文字小文字が異なる場合があります。予約名 `auto` を使用した場合、選択されたモデルが報告される唯一の場所です。比較は大文字小文字を区別せずに行ってください。 | ## コストメトリクス(オプトイン) コスト・計測系のヘッダはデフォルトでは送出され**ません**。リクエストヘッダ `X-Aiand-Metrics: true` を付与した場合のみ、非ストリーミングのレスポンスに付与されます: | ヘッダ | 説明 | | ----------------- | -------------------------------------------------- | | `X-Cost` | リクエストのコスト(請求通貨建て)。 | | `X-Cost-Currency` | `X-Cost` の通貨(`usd` または `jpy`)。 | | `X-Inference-Ms` | 上流モデルがレスポンス生成に要した時間(ミリ秒)。 | トークン数はヘッダでは提供されません — レスポンスボディの `usage` ブロックを参照してください。 ## reasoning effort | ヘッダ | 説明 | | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `X-Reasoning-Effort` | effort を要求したリクエストにおいて、実際に適用されたレベル (`/v1/chat/completions` と `/v1/messages` では `reasoning_effort`、`/v1/responses` では `reasoning.effort`)。[`/v1/messages`](/ja/api/messages/) では、名前付きの推論モデルに対する `thinking: { "type": "disabled" }` も要求として扱われ、`none` が返ります。予約名 [`auto`](/ja/models/auto/) ではこのブロックは無視されるため、ヘッダは付きません。常にそのモデルの公開レベルのいずれかです。要求しなかった場合は付与されません — その場合はモデル自身のデフォルトが適用され、当社が値を補うことはありません。 | モデルの一覧にないレベル([`reasoning_efforts`](/ja/models/catalog/) を参照)は、一つ上のレベル、それがなければそのモデルの最も高いレベルで実行されます。その場合このヘッダは送信した値と異なり、課金対象の reasoning トークンは適用されたレベルのもので、要求したレベルより高コストになる場合があります。`none` は繰り上げられません。`none` を一覧に含まないモデルでは 400 になり、effort の語彙にない値も同様です。 ## レート制限 レート制限ヘッダの一覧は [レート制限](/ja/reference/rate-limits/) を参照。 ## ストリーミング ストリーミングレスポンスでは `X-Request-ID` とレート制限ヘッダは即時送出されますが、コストヘッダは付与されません。`X-Aiand-Metrics: true` を付与すると、chat completions のストリームではモデルの終端メッセージの後にトークン数・コスト・通貨を含む `event: metrics` の trailer イベントが追加されます。[ストリーミングイベント](/ja/reference/streaming-events/) を参照。 --- # ストリーミングイベント 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` | 上流モデルがレスポンス生成に要した時間(ミリ秒)。 | ## 送出されるエンドポイント 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 が変更なしで動作します。 --- # ai& SDK Source: https://aiand-docs-staging.pages.dev/ja/sdks/aiand/ ai& 公式 SDK は公開 OpenAPI スペックから生成され、完全な型定義を同梱しています。プラットフォーム全体と同じ OpenAI 互換のエンドポイントをカバーします。 ## セットアップ ```bash pip install aiand ``` ```python import aiand configuration = aiand.Configuration(access_token="sk-your-aiand-api-key") client = aiand.OpenaiApi(aiand.ApiClient(configuration)) models = client.list_models() print(models.data[0].id) ``` ```bash npm install @aiand/sdk ``` ```ts import { Configuration, OpenaiApi } from "@aiand/sdk"; const client = new OpenaiApi( new Configuration({ accessToken: "sk-your-aiand-api-key" }), ); const models = await client.listModels(); console.log(models.data[0].id); ``` ## Chat completion ```python response = client.create_chat_completion( aiand.CreateChatCompletionRequest.from_dict({ "model": "google/gemma-4-31b-it", "messages": [{"role": "user", "content": "Hello"}], }) ) print(response.choices[0].message.content) ``` ```ts const response = await client.createChatCompletion({ createChatCompletionRequest: { model: "google/gemma-4-31b-it", messages: [{ role: "user", content: "Hello" }], }, }); console.log(response.choices[0].message.content); ``` ## Responses ```python response = client.create_response( aiand.CreateResponseRequest( model="google/gemma-4-31b-it", input=aiand.ResponseInput("Hello"), ) ) # output[0] は reasoning アイテムであることが多い message = next((item for item in response.to_dict()["output"] if item["type"] == "message"), None) if message: print(message["content"][0]["text"]) else: print(f"No message in the output (status: {response.status})") ``` ```ts const response = await client.createResponse({ createResponseRequest: { model: "google/gemma-4-31b-it", input: "Hello", }, }); console.log(response.output); ``` ## その他のエンドポイント - `list_models()` / `listModels()` — [Models](/ja/api/models/) - ファイルやアップロードなども同じクライアントで利用できます([Files](/ja/api/files/) を参照) --- # Anthropic SDK Source: https://aiand-docs-staging.pages.dev/ja/sdks/anthropic/ ai& は OpenAI 互換に加え、Anthropic 互換エンドポイントも提供します。ベース URL を上書きすれば公式 `anthropic` SDK をそのまま利用できます。 ## セットアップ ```bash pip install anthropic ``` ```python from anthropic import Anthropic client = Anthropic( base_url="https://api.aiand.com", api_key="sk-your-aiand-api-key", ) ``` ```bash npm install @anthropic-ai/sdk ``` ```ts import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ baseURL: "https://api.aiand.com", apiKey: "sk-your-aiand-api-key", }); ``` ## Messages ```python response = client.messages.create( model="...", max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], ) print(response.content[0].text) ``` ## ストリーミング ```python with client.messages.stream( model="...", max_tokens=1024, messages=[{"role": "user", "content": "Hello"}], ) as stream: for text in stream.text_stream: print(text, end="") ``` ## Files Anthropic Files API も利用可能です — SDK が送信する `anthropic-version` ヘッダで選択されます: ```python file = client.beta.files.upload(file=open("cat.png", "rb")) ``` 仕組みは [OpenAI と Anthropic の形式](/ja/api/file-shapes/) を参照。 --- # curl Source: https://aiand-docs-staging.pages.dev/ja/sdks/curl/ ai& のエンドポイントはすべて HTTP + JSON です。`curl` を使ってシェルからテスト、CI からの自動化、SDK を導入する前のサニティチェックなどに利用できます。 ## 認証 ```bash export AIAND_API_KEY="sk-your-aiand-api-key" ``` ## Chat completion ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "...", "messages": [{"role": "user", "content": "Hello"}] }' ``` ## ストリーミング `"stream": true` を指定し、バッファリングを無効化する `curl -N` を使います: ```bash curl -N https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "...", "stream": true, "messages": [{"role": "user", "content": "Hello"}] }' ``` ## ビジョン (file_id) ```bash curl https://api.aiand.com/v1/chat/completions \ -H "Authorization: Bearer $AIAND_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "...", "messages": [{ "role": "user", "content": [ {"type": "text", "text": "What is this?"}, {"type": "file", "file": {"file_id": "file-abc123"}} ] }] }' ``` ## ファイルアップロード ```bash curl https://api.aiand.com/v1/files \ -H "Authorization: Bearer $AIAND_API_KEY" \ -F "file=@cat.png" \ -F "purpose=vision" ``` ## Anthropic 形式 `-H "anthropic-version: 2023-06-01"` を付与し、`/v1/messages` を呼び出します。[Messages](/ja/api/messages/) を参照。 --- # OpenAI SDK Source: https://aiand-docs-staging.pages.dev/ja/sdks/openai/ ai& Inference API は OpenAI とワイヤ互換です。ベース URL を上書きすれば公式 `openai` SDK をそのまま利用できます。 ## セットアップ ```bash pip install openai ``` ```python from openai import OpenAI client = OpenAI( base_url="https://api.aiand.com/v1", api_key="sk-your-aiand-api-key", ) ``` ```bash npm install openai ``` ```ts import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.aiand.com/v1", apiKey: "sk-your-aiand-api-key", }); ``` ## Chat completion ```python response = client.chat.completions.create( model="...", messages=[{"role": "user", "content": "Hello"}], ) print(response.choices[0].message.content) ``` ## ストリーミング ```python stream = client.chat.completions.create( model="...", messages=[{"role": "user", "content": "Hello"}], stream=True, stream_options={"include_usage": True}, ) for chunk in stream: if chunk.choices: print(chunk.choices[0].delta.content or "", end="") ``` ## その他のエンドポイント - `client.files.create(...)` — [Files](/ja/api/files/) - `client.models.list()` — [Models](/ja/api/models/)