> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aireiter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# OpenAI チャット補完API

> - OpenAI Chat Completions API フォーマットと完全互換
- 複数ターンの対話、ツール呼び出し、構造化出力、ストリーミングレスポンスに対応
- OpenAI SDK の `baseURL` を直接置き換え可能で、他のコードの修正は不要


export const apiKeyUrl = 'https://aireiter.com/keys';

## Authorizations

<ParamField header="Authorization" type="string" required>
  APIキー、Bearerトークン形式

  APIキーの取得：

  <a href={apiKeyUrl} target="_blank">APIキー管理ページ</a>にアクセスしてAPIキーを取得してください

  ```
  Authorization: Bearer YOUR_API_KEY
  ```
</ParamField>

## Body

<ParamField body="model" type="string" required>
  モデル名

  **OpenAI 互換モデル（ツール呼び出しに推奨）：**

  * `gpt-4o-mini` — 軽量で高速、頻繁かつ単純なタスクに最適
  * `gpt-4o` — バランスの取れた性能とコストで総合推奨
  * `gpt-5.2` — 高性能版、**ツール呼び出しを完全にサポート**
  * その他のモデルは `GET /api/v1/models` を参照してください

  **Claude モデル（Anthropic プロトコル経由）：**

  * `claude-haiku-4-5-20251001` — 軽量で高速
  * `claude-sonnet-4-5-20250929` — 総合推奨
  * `claude-sonnet-4-6` — Sonnet 新バージョン
  * `claude-opus-4-5-20251101` — フラグシップ推論モデル
  * `claude-opus-4-6` — Opus 新バージョン、最高性能

  完全なモデルリストは `GET /api/v1/models` をご覧ください
</ParamField>

<ParamField body="messages" type="array" required>
  メッセージリスト

  モデルはメッセージ履歴に基づいて次の応答を生成します。各メッセージに `role` と `content` を含みます。

  <Expandable title="フィールド説明">
    <ParamField body="role" type="string" required>
      役割タイプ

      * `system` — システムプロンプト（メッセージリストから抽出して個別に処理）
      * `user` — ユーザーメッセージ
      * `assistant` — AIの応答（マルチターン対話用）
    </ParamField>

    <ParamField body="content" type="string" required>
      メッセージ内容、プレーンテキスト文字列
    </ParamField>
  </Expandable>

  **プレーンテキストメッセージ：**

  ```json theme={null} theme={null}
  [{"role": "user", "content": "こんにちは"}]
  ```

  **マルチターン対話：**

  ```json theme={null} theme={null}
  [
    {"role": "system",    "content": "あなたは専門のコードレビュアーです。"},
    {"role": "user",      "content": "このコードをチェックしてください"},
    {"role": "assistant", "content": "分析します..."},
    {"role": "user",      "content": "パフォーマンスの問題はありますか？"}
  ]
  ```

  **マルチターンツール呼び出し：**

  ```json theme={null} theme={null}
  [
    {"role": "user", "content": "今日の北京の天気は？"},
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "id": "call_001",
          "type": "function",
          "function": {"name": "get_weather", "arguments": "{\"city\": \"北京\"}"}
        }
      ]
    },
    {
      "role": "tool",
      "tool_call_id": "call_001",
      "content": "北京：25°C、晴れ"
    }
  ]
  ```
</ParamField>

<ParamField body="max_tokens" type="integer">
  最大出力トークン数

  最大生成トークン数を制御します。モデルは上限に達する前に自然に終了する可能性があります。最小値：`1`。
  デフォルトは無制限（モデルのコンテキストウィンドウ制限を受けます）。
</ParamField>

<ParamField body="max_completion_tokens" type="integer">
  最大出力トークン数（`max_tokens` の新名称）

  `max_tokens` と完全に同等で、どちらか一方を指定すればよく、`max_tokens` が優先されます。
</ParamField>

<ParamField body="stream" type="boolean">
  ストリーム出力の有効化

  `true` に設定すると、SSE（Server-Sent Events）を通じてリアルタイムにストリーミングで返されます。**デフォルトは `true`**。非ストリーミング応答が必要な場合は明示的に `"stream": false` を指定してください。

  `false` の場合は、生成完了後に一括で完全な応答を返します。
</ParamField>

<ParamField body="temperature" type="number">
  温度、範囲 `0–2`

  * 低い値（例：`0.2`） — 出力がより確定的で保守的
  * 高い値（例：`0.8`） — 出力がよりランダムでクリエイティブ

  デフォルトは `1.0`。`top_p` と併用は推奨されません。
</ParamField>

<ParamField body="top_p" type="number">
  nucleusサンプリングパラメータ、範囲 `0–1`

  累積確率が `top_p` に達するまでのトークン集合からサンプリングします。デフォルトは `1.0`。
  `temperature` と同時使用は推奨されません。
</ParamField>

<ParamField body="frequency_penalty" type="number">
  頻度ペナルティ、範囲 `-2.0–2.0`

  正の値は既生成テキスト内のトークンの頻度に応じてペナルティをかけ、繰り返し表現の確率を減少させます。デフォルトは `0`。
</ParamField>

<ParamField body="presence_penalty" type="number">
  存在ペナルティ、範囲 `-2.0–2.0`

  正の値は既に出現したトークンにペナルティをかけ、モデルに新しいトピックを探索させます。デフォルトは `0`。
</ParamField>

<ParamField body="seed" type="integer">
  ランダムシード

  設定すると、同じシードと同じリクエストパラメータで可能な限り決定的な出力を生成し、結果の再現性を高めます。
</ParamField>

<ParamField body="stop" type="string | array">
  停止シーケンス

  これらの文字列（もしくは配列内のいずれか）に遭遇すると直ちに生成を停止します。最大4つまで設定可能。

  ```json theme={null} theme={null}
  {"stop": ["\n\nUser:", "###END###"]}
  ```
</ParamField>

<ParamField body="tools" type="array">
  ツール定義リスト

  モデルが呼び出せる関数ツールを定義します。各ツールは名前、説明、パラメータのJSON Schemaを含みます。

  ```json theme={null} theme={null}
  {
    "tools": [
      {
        "type": "function",
        "function": {
          "name": "get_weather",
          "description": "指定都市の現在の天気を取得する",
          "parameters": {
            "type": "object",
            "properties": {
              "city": {
                "type": "string",
                "description": "都市名、例：北京"
              },
              "unit": {
                "type": "string",
                "enum": ["celsius", "fahrenheit"]
              }
            },
            "required": ["city"]
          }
        }
      }
    ]
  }
  ```
</ParamField>

<ParamField body="tool_choice" type="string | object">
  ツール選択ポリシー

  * `"auto"` — モデルがツール呼び出しの可否を自動判断（デフォルト）
  * `"required"` — モデルが必ず特定ツールを呼び出す
  * `"none"` — ツールの呼び出しを禁止
  * `{"type": "function", "function": {"name": "get_weather"}}` — 特定ツールを強制呼び出し

  ```json theme={null} theme={null}
  {"tool_choice": "required"}
  ```
</ParamField>

<ParamField body="parallel_tool_calls" type="boolean">
  並列ツール呼び出しの許可

  `false` の場合は1回に1つのツールのみ呼び出します。デフォルトは `true` （並列呼び出し許可）。
</ParamField>

<ParamField body="response_format" type="object">
  応答フォーマット

  モデルの出力フォーマットを制御します。

  <Expandable title="フィールド説明">
    <ParamField body="type" type="string" required>
      フォーマットタイプ

      * `"text"` — 通常テキスト（デフォルト）
      * `"json_object"` — JSONオブジェクト、モデルの出力は有効なJSON
      * `"json_schema"` — 指定のJSON Schemaに厳密に従う
    </ParamField>

    <ParamField body="json_schema" type="object">
      `type` が `"json_schema"` の場合は必須

      <Expandable title="フィールド説明">
        <ParamField body="name" type="string" required>
          スキーマ名
        </ParamField>

        <ParamField body="schema" type="object" required>
          JSON Schema定義。モデルはこの構造に厳密に従います
        </ParamField>

        <ParamField body="strict" type="boolean">
          厳密モードの有効化。デフォルトは `true`
        </ParamField>
      </Expandable>
    </ParamField>
  </Expandable>

  **JSONオブジェクトモード：**

  ```json theme={null} theme={null}
  {"response_format": {"type": "json_object"}}
  ```

  **JSON Schemaモード：**

  ```json theme={null} theme={null}
  {
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "analysis_result",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "summary":    {"type": "string"},
            "score":      {"type": "number"},
            "tags":       {"type": "array", "items": {"type": "string"}}
          },
          "required": ["summary", "score", "tags"]
        }
      }
    }
  }
  ```
</ParamField>

<ParamField body="reasoning_effort" type="string">
  推論強度

  推論対応モデル（例：`gpt-5.2` 以上）向けに推論の深さを制御します。

  * `"low"` — 高速推論でトークン節約
  * `"medium"` — バランスの取れた推論
  * `"high"` — 深い推論で精度向上、トークン消費は多め
</ParamField>

## Response

<ResponseField name="id" type="string">
  補完の一意識別子

  例：`"chatcmpl-9vKqnMf3Ax8ZpRdTw2LsYe7b"`
</ResponseField>

<ResponseField name="object" type="string">
  オブジェクトタイプで、固定値は `"chat.completion"`（非ストリーミング）または `"chat.completion.chunk"`（ストリーミング）
</ResponseField>

<ResponseField name="created" type="integer">
  作成日時、Unixタイムスタンプ（秒）
</ResponseField>

<ResponseField name="model" type="string">
  リクエスト時に指定したモデル名
</ResponseField>

<ResponseField name="task_id" type="string">
  請求タスクID（プロジェクトの拡張フィールド）、今回の呼び出しにおけるポイント消費記録の追跡に使用
</ResponseField>

<ResponseField name="choices" type="array">
  生成結果の配列（常に1件のみ）

  <Expandable title="フィールド説明">
    <ResponseField name="index" type="integer">
      結果のインデックス、固定値 `0`
    </ResponseField>

    <ResponseField name="message" type="object">
      **非ストリーミングレスポンス**における完全なメッセージオブジェクト

      * `role` — 固定値 `"assistant"`
      * `content` — テキスト内容（ツール呼び出し時は `null`）
      * `tool_calls` — ツール呼び出しのリスト（ツール呼び出しがある場合に存在）
    </ResponseField>

    <ResponseField name="delta" type="object">
      **ストリーミングレスポンス**における増分内容

      * 最初のフレーム：`{"role": "assistant"}`
      * テキストフレーム：`{"content": "..."}`
      * ツール呼び出しフレーム：`{"tool_calls": [{"index": 0, "id": "...", "type": "function", "function": {"name": "...", "arguments": ""}}]}`
      * 終了フレーム：`{}`
    </ResponseField>

    <ResponseField name="finish_reason" type="string">
      停止理由

      * `"stop"` — 自然終了
      * `"length"` — `max_tokens` 上限に達した
      * `"tool_calls"` — モデルがツール呼び出しを要求
      * `"content_filter"` — コンテンツフィルタ
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="usage" type="object">
  Token使用統計（非ストリーミングではレスポンスボディトップレベル、ストリーミングでは最終フレームに含む）

  <Expandable title="フィールド説明">
    <ResponseField name="prompt_tokens" type="integer">
      入力トークン数（システムプロンプト含む）
    </ResponseField>

    <ResponseField name="completion_tokens" type="integer">
      出力トークン数
    </ResponseField>

    <ResponseField name="total_tokens" type="integer">
      総トークン数
    </ResponseField>
  </Expandable>
</ResponseField>

<RequestExample>
  ```bash cURL theme={null} theme={null}
  curl https://aireiter.com/api/v1/chat/completions \
    -H "Authorization: Bearer $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "claude-sonnet-4-5-20250929",
      "messages": [
        {"role": "user", "content": "こんにちは、世界"}
      ]
    }'
  ```

  ```python Python theme={null} theme={null}
  from openai import OpenAI

  client = OpenAI(
      api_key="YOUR_API_KEY",
      base_url="https://aireiter.com/api/v1"
  )

  response = client.chat.completions.create(
      model="claude-sonnet-4-5-20250929",
      messages=[
          {"role": "user", "content": "こんにちは、世界"}
      ]
  )

  print(response.choices[0].message.content)
  ```

  ```javascript JavaScript theme={null} theme={null}
  import OpenAI from 'openai';

  const client = new OpenAI({
    apiKey: process.env.API_KEY,
    baseURL: 'https://aireiter.com/api/v1'
  });

  const response = await client.chat.completions.create({
    model: 'claude-sonnet-4-5-20250929',
    messages: [
      { role: 'user', content: 'こんにちは、世界' }
    ]
  });

  console.log(response.choices[0].message.content);
  ```

  ```go Go theme={null} theme={null}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io/ioutil"
      "net/http"
      "os"
  )

  func main() {
      url := "https://aireiter.com/api/v1/chat/completions"

      payload := map[string]interface{}{
          "model": "claude-sonnet-4-5-20250929",
          "messages": []map[string]string{
              {"role": "user", "content": "こんにちは、世界"},
          },
      }

      jsonData, _ := json.Marshal(payload)

      req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonData))
      req.Header.Set("Authorization", "Bearer "+os.Getenv("API_KEY"))
      req.Header.Set("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := ioutil.ReadAll(resp.Body)
      fmt.Println(string(body))
  }
  ```

  ```java Java theme={null} theme={null}
  import java.net.http.HttpClient;
  import java.net.http.HttpRequest;
  import java.net.http.HttpResponse;
  import java.net.URI;

  public class Main {
      public static void main(String[] args) throws Exception {
          String url    = "https://aireiter.com/api/v1/chat/completions";
          String apiKey = System.getenv("API_KEY");

          String payload = """
          {
            "model": "claude-sonnet-4-5-20250929",
            "messages": [
              {"role": "user", "content": "こんにちは、世界"}
            ]
          }
          """;

          HttpClient client = HttpClient.newHttpClient();
          HttpRequest request = HttpRequest.newBuilder()
              .uri(URI.create(url))
              .header("Authorization", "Bearer " + apiKey)
              .header("Content-Type", "application/json")
              .POST(HttpRequest.BodyPublishers.ofString(payload))
              .build();

          HttpResponse<String> response = client.send(request,
              HttpResponse.BodyHandlers.ofString());
          System.out.println(response.body());
      }
  }
  ```

  ```php PHP theme={null} theme={null}
  <?php

  $url    = "https://aireiter.com/api/v1/chat/completions";
  $apiKey = getenv('API_KEY');

  $payload = [
      "model"    => "claude-sonnet-4-5-20250929",
      "messages" => [
          ["role" => "user", "content" => "こんにちは、世界"]
      ]
  ];

  $ch = curl_init($url);
  curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  curl_setopt($ch, CURLOPT_POST, true);
  curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload));
  curl_setopt($ch, CURLOPT_HTTPHEADER, [
      "Authorization: Bearer " . $apiKey,
      "Content-Type: application/json"
  ]);

  $response = curl_exec($ch);
  curl_close($ch);
  echo $response;
  ?>
  ```

  ```ruby Ruby theme={null} theme={null}
  require 'net/http'
  require 'json'
  require 'uri'

  url     = URI("https://aireiter.com/api/v1/chat/completions")
  api_key = ENV['API_KEY']

  payload = {
    model:    "claude-sonnet-4-5-20250929",
    messages: [{ role: "user", content: "こんにちは、世界" }]
  }

  http         = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true

  request                   = Net::HTTP::Post.new(url)
  request["Authorization"]  = "Bearer #{api_key}"
  request["Content-Type"]   = "application/json"
  request.body              = payload.to_json

  puts http.request(request).body
  ```

  ```swift Swift theme={null} theme={null}
  import Foundation

  let url    = URL(string: "https://aireiter.com/api/v1/chat/completions")!
  let apiKey = ProcessInfo.processInfo.environment["API_KEY"] ?? ""

  let payload: [String: Any] = [
      "model":    "claude-sonnet-4-5-20250929",
      "messages": [["role": "user", "content": "こんにちは、世界"]]
  ]

  var request = URLRequest(url: url)
  request.httpMethod = "POST"
  request.setValue("Bearer \(apiKey)", forHTTPHeaderField: "Authorization")
  request.setValue("application/json",  forHTTPHeaderField: "Content-Type")
  request.httpBody = try? JSONSerialization.data(withJSONObject: payload)

  URLSession.shared.dataTask(with: request) { data, _, _ in
      if let data = data {
          print(String(data: data, encoding: .utf8) ?? "")
      }
  }.resume()
  ```

  ```csharp C# theme={null} theme={null}
  using System;
  using System.Net.Http;
  using System.Text;
  using System.Threading.Tasks;

  class Program
  {
      static async Task Main(string[] args)
      {
          var url    = "https://aireiter.com/api/v1/chat/completions";
          var apiKey = Environment.GetEnvironmentVariable("API_KEY");

          var payload = @"{
              ""model"": ""claude-sonnet-4-5-20250929"",
              ""messages"": [
                  {""role"": ""user"", ""content"": ""こんにちは、世界""}
              ]
          }";

          using var client = new HttpClient();
          client.DefaultRequestHeaders.Add("Authorization", $"Bearer {apiKey}");

          var content  = new StringContent(payload, Encoding.UTF8, "application/json");
          var response = await client.PostAsync(url, content);
          Console.WriteLine(await response.Content.ReadAsStringAsync());
      }
  }
  ```

  ```c C theme={null} theme={null}
  #include <stdio.h>
  #include <curl/curl.h>
  #include <stdlib.h>
  #include <string.h>

  int main(void) {
      CURL *curl;
      const char *api_key = getenv("API_KEY");

      curl_global_init(CURL_GLOBAL_DEFAULT);
      curl = curl_easy_init();

      if (curl) {
          const char *payload =
              "{\"model\":\"claude-sonnet-4-5-20250929\","
              "\"messages\":[{\"role\":\"user\",\"content\":\"こんにちは、世界\"}]}";

          char auth_header[256];
          snprintf(auth_header, sizeof(auth_header), "Authorization: Bearer %s", api_key);

          struct curl_slist *headers = NULL;
          headers = curl_slist_append(headers, auth_header);
          headers = curl_slist_append(headers, "Content-Type: application/json");

          curl_easy_setopt(curl, CURLOPT_URL, "https://aireiter.com/api/v1/chat/completions");
          curl_easy_setopt(curl, CURLOPT_POSTFIELDS, payload);
          curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);

          curl_easy_perform(curl);
          curl_slist_free_all(headers);
          curl_easy_cleanup(curl);
      }

      curl_global_cleanup();
      return 0;
  }
  ```

  ```dart Dart theme={null} theme={null}
  import 'dart:convert';
  import 'dart:io';
  import 'package:http/http.dart' as http;

  void main() async {
    final url    = Uri.parse('https://aireiter.com/api/v1/chat/completions');
    final apiKey = Platform.environment['API_KEY']!;

    final response = await http.post(
      url,
      headers: {
        'Authorization': 'Bearer $apiKey',
        'Content-Type':  'application/json',
      },
      body: jsonEncode({
        'model':    'claude-sonnet-4-5-20250929',
        'messages': [{'role': 'user', 'content': 'こんにちは、世界'}],
      }),
    );

    print(response.body);
  }
  ```

  ```r R theme={null} theme={null}
  library(httr)
  library(jsonlite)

  url     <- "https://aireiter.com/api/v1/chat/completions"
  api_key <- Sys.getenv("API_KEY")

  response <- POST(
    url,
    add_headers(
      `Authorization` = paste("Bearer", api_key),
      `Content-Type`  = "application/json"
    ),
    body = toJSON(list(
      model    = "claude-sonnet-4-5-20250929",
      messages = list(list(role = "user", content = "こんにちは、世界"))
    ), auto_unbox = TRUE),
    encode = "raw"
  )

  cat(content(response, "text"))
  ```
</RequestExample>

<ResponseExample>
  ```json 200 非ストリーミング theme={null} theme={null}
  {
    "id": "chatcmpl-9vKqnMf3Ax8ZpRdTw2LsYe7b",
    "object": "chat.completion",
    "created": 1741680000,
    "model": "claude-sonnet-4-5-20250929",
    "task_id": "task_abc123",
    "choices": [
      {
        "index": 0,
        "message": {
          "role": "assistant",
          "content": "こんにちは！何かお手伝いできることはありますか？"
        },
        "finish_reason": "stop"
      }
    ],
    "usage": {
      "prompt_tokens": 12,
      "completion_tokens": 15,
      "total_tokens": 27
    }
  }
  ```

  ```json 200 ツール呼び出し theme={null} theme={null}
  {
    "id": "chatcmpl-9vKqnMf3Ax8ZpRdTw2LsYe7b",
    "object": "chat.completion",
    "created": 1741680000,
    "model": "claude-sonnet-4-5-20250929",
    "task_id": "task_abc123",
    "choices": [
      {
        "index": 0,
        "message": {
          "role": "assistant",
          "content": null,
          "tool_calls": [
            {
              "id": "call_01A09q90qw90lq917835lq9",
              "type": "function",
              "function": {
                "name": "get_weather",
                "arguments": "{\"city\": \"北京\"}"
              }
            }
          ]
        },
        "finish_reason": "tool_calls"
      }
    ],
    "usage": {
      "prompt_tokens": 85,
      "completion_tokens": 22,
      "total_tokens": 107
    }
  }
  ```

  ```json 400 theme={null} theme={null}
  {
    "error": {
      "message": "messages は必須で空ではいけません",
      "type": "invalid_request_error",
      "param": null,
      "code": null
    }
  }
  ```

  ```json 401 theme={null} theme={null}
  {
    "error": {
      "message": "無効なAPIキーです",
      "type": "invalid_request_error",
      "param": null,
      "code": null
    }
  }
  ```

  ```json 402 theme={null} theme={null}
  {
    "error": {
      "message": "クレジットが不足しています",
      "type": "invalid_request_error",
      "param": null,
      "code": null
    }
  }
  ```

  ```json 404 theme={null} theme={null}
  {
    "error": {
      "message": "モデル 'xxx' が見つかりません",
      "type": "invalid_request_error",
      "param": null,
      "code": null
    }
  }
  ```

  ```json 502 theme={null} theme={null}
  {
    "error": {
      "message": "すべてのプロバイダーが失敗しました",
      "type": "invalid_request_error",
      "param": null,
      "code": null
    }
  }
  ```
</ResponseExample>

## 使用例

### 基本的な対話

```python theme={null} theme={null}
from openai import OpenAI

client = OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://aireiter.com/api/v1"
)

response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "user", "content": "Pythonでクイックソートを実装する"}
    ]
)

print(response.choices[0].message.content)
```

### システムプロンプト + 複数ターンの対話

```python theme={null} theme={null}
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "system",    "content": "あなたは経験豊富なPython開発者で、コードレビューとパフォーマンス最適化に長けています。"},
        {"role": "user",      "content": "GILとは何ですか？"},
        {"role": "assistant", "content": "GIL（グローバルインタプリタロック）は..."},
        {"role": "user",      "content": "どうすればGILを回避して真の並列処理が可能ですか？"}
    ],
    temperature=0.3
)
```

### ストリーミングレスポンス

```python theme={null} theme={null}
stream = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "量子計算に関する技術ブログを書いてください"}],
    stream=True
)

for chunk in stream:
    delta = chunk.choices[0].delta
    if delta.content:
        print(delta.content, end="", flush=True)
```

### ツール呼び出し（完全な複数ターンプロセス）

```python theme={null} theme={null}
import json

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "株式のリアルタイム価格を取得する",
            "parameters": {
                "type": "object",
                "properties": {
                    "ticker": {"type": "string", "description": "銘柄コード、例：AAPL"}
                },
                "required": ["ticker"]
            }
        }
    }
]

messages = [{"role": "user", "content": "テスラの株価はいくらですか？"}]

# 第1ラウンド：モデルがツール呼び出しを決定
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=messages,
    tools=tools
)

# ツール呼び出しの処理
if response.choices[0].finish_reason == "tool_calls":
    tool_call = response.choices[0].message.tool_calls[0]

    # ツール実行（ビジネスロジック）
    tool_result = {"price": 245.80, "currency": "USD"}

    # 第2ラウンド：結果をモデルに返す
    messages += [
        response.choices[0].message,
        {
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(tool_result)
        }
    ]

    final = client.chat.completions.create(
        model="claude-sonnet-4-5-20250929",
        messages=messages,
        tools=tools
    )
    print(final.choices[0].message.content)
```

### 構造化出力（JSON Schema）

```python theme={null} theme={null}
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[
        {"role": "user", "content": "以下の製品レビューの感情分析をしてください：'このヘッドフォンは音質が優れているが、バッテリー持ちは普通だ'"}
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "sentiment_analysis",
            "strict": True,
            "schema": {
                "type": "object",
                "properties": {
                    "sentiment":   {"type": "string", "enum": ["positive", "negative", "mixed"]},
                    "score":       {"type": "number", "description": "感情スコア -1.0 から 1.0"},
                    "highlights":  {"type": "array", "items": {"type": "string"}}
                },
                "required": ["sentiment", "score", "highlights"]
            }
        }
    }
)

result = json.loads(response.choices[0].message.content)
print(result)
# {"sentiment": "mixed", "score": 0.2, "highlights": ["音質が優れている", "バッテリー持ちは普通"]}
```

### サンプリングパラメータの制御

```python theme={null} theme={null}
# 創造的な文章作成：高温度 + 頻度ペナルティ
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "秋についての現代詩を書いてください"}],
    temperature=0.9,
    frequency_penalty=0.5,
    presence_penalty=0.3
)

# 正確な出力：低温度 + 固定シード
response = client.chat.completions.create(
    model="claude-sonnet-4-5-20250929",
    messages=[{"role": "user", "content": "1234 × 5678 の計算結果"}],
    temperature=0.0,
    seed=42
)
```

## ストリーミングレスポンスイベントフォーマット

```text theme={null} theme={null}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","task_id":"task_abc123","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{"content":"こんにちは"},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{"content":"！"},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{},"finish_reason":"stop"}],"usage":{"prompt_tokens":12,"completion_tokens":5,"total_tokens":17}}

data: [DONE]
```

ツール呼び出しストリーミングイベント：

```text theme={null} theme={null}
data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"id":"call_abc","type":"function","function":{"name":"get_weather","arguments":""}}]},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"city\""}}]},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{"tool_calls":[{"index":0,"function":{"arguments":": \"北京\"}"}}]},"finish_reason":null}]}

data: {"id":"chatcmpl-xxx","object":"chat.completion.chunk","created":1741680000,"model":"claude-sonnet-4-5-20250929","choices":[{"index":0,"delta":{},"finish_reason":"tool_calls"}],"usage":{"prompt_tokens":85,"completion_tokens":22,"total_tokens":107}}

data: [DONE]
```

## 注意事項

1. **認証方法**：`Authorization: Bearer <api_key>` 形式のみサポートしており、OpenAI SDKを使用する場合は直接 `api_key` を設定してください。

2. **デフォルトはストリーミング**：`stream` パラメータはデフォルトで `true` です。非ストリーミングレスポンスが必要な場合は、明示的に `"stream": false` を渡してください。

3. **ポイント不足**：残高が足りない場合は HTTP `402` を返し、チャージ後に再試行してください。

4. **stop と停止シーケンス**：`stop` パラメータは現時点で有効ではなく、バックエンドのプロバイダがこの機能をサポートしていません。パラメータを渡してもエラーにならず、指定されたシーケンスで生成が停止することもありません。

5. **response\_format 注意点**：現行のバックエンドプロバイダによる `response_format` のサポートは限定的です——`json_object` モードではモデルが純粋な JSON ではなく Markdown のコードブロックを出力する可能性があり、`json_schema` モードではスキーマの制約が守られない場合があります。構造化出力が必要な場合は、プロンプト内で明確にフォーマットを指定することを推奨します。

6. **ツールパラメータ**：`parameters` フィールドは有効な JSON Schema である必要があり、`required` 配列が必須のパラメータを決定します。

7. **モデル選択のおすすめ**：
   * Haiku — 高頻度の簡単な質問応答、最もコストが低い
   * Sonnet — コード生成やドキュメント処理、総合的におすすめ
   * Opus — 複雑な推論や長文分析、最も高い性能
   * `-thinking` シリーズ — 数学的証明や論理的導出など深い思考が必要なシナリオ
