# OpenAI SDK > Python、TypeScript、Go の公式 OpenAI クライアントから Kiln を呼び出す方法です。インストール、検証済みのリクエスト例、ツール呼び出しの往復に加え、OpenAI のスキーマにない cost フィールドと、max_tokens に含まれる reasoning の上限といった違いをまとめます。 Source: https://kiln.bricksum.com/docs/ja/sdks/openai Kiln は OpenAI Chat Completions API を提供しているため、公式の OpenAI クライアントは間に何も挟まずに接続できます。変更する値は base URL、キー、モデル ID の 3 つです。 ## インストール **Python** ```bash pip install openai ``` **TypeScript** ```bash npm install openai ``` **Go** ```bash go get github.com/openai/openai-go/v3 ``` ## 接続 **Python** ```python import os from openai import OpenAI client = OpenAI( base_url="https://api.bricksum.com/v1", api_key=os.environ["KILN_API_KEY"], # sk-bk-... ) resp = client.chat.completions.create( model="qwen3-32b", messages=[{"role": "user", "content": "Write a haiku about kilns."}], max_tokens=800, ) print(resp.choices[0].message.content) ``` **TypeScript** ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.bricksum.com/v1", apiKey: process.env.KILN_API_KEY, // sk-bk-... }); const resp = await client.chat.completions.create({ model: "qwen3-32b", messages: [{ role: "user", content: "Write a haiku about kilns." }], max_tokens: 800, }); console.log(resp.choices[0].message.content); ``` **Go** ```go package main import ( "context" "fmt" "os" "github.com/openai/openai-go/v3" "github.com/openai/openai-go/v3/option" ) func main() { client := openai.NewClient( option.WithBaseURL("https://api.bricksum.com/v1"), option.WithAPIKey(os.Getenv("KILN_API_KEY")), ) resp, err := client.Chat.Completions.New(context.Background(), openai.ChatCompletionNewParams{ Model: "qwen3-32b", MaxTokens: openai.Int(800), Messages: []openai.ChatCompletionMessageParamUnion{ openai.UserMessage("Write a haiku about kilns."), }, }) if err != nil { panic(err) } fmt.Println(resp.Choices[0].Message.Content) } ``` ## ツール呼び出し tool_choice を "auto" にした往復 1 回の例です。モデルがツールを要求したらコードが実行し、その結果を tool メッセージとして返します。すべてのツールに description が必要で、description のないツールはモデルサーバーが 400 で拒否します。 **Python** ```python import json, os from openai import OpenAI client = OpenAI(base_url="https://api.bricksum.com/v1", api_key=os.environ["KILN_API_KEY"]) tools = [{"type": "function", "function": { "name": "get_weather", "description": "Current weather for a city", # required "parameters": {"type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"]}, }}] messages = [{"role": "user", "content": "What's the weather in Seoul?"}] first = client.chat.completions.create(model="qwen3-32b", messages=messages, tools=tools, tool_choice="auto", max_tokens=800) reply = first.choices[0].message # The model may answer without a tool call, and one reply can carry several. if reply.tool_calls: messages.append(reply) for call in reply.tool_calls: messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps({"temp_c": 27})}) final = client.chat.completions.create(model="qwen3-32b", messages=messages, max_tokens=800) print(final.choices[0].message.content) else: print(reply.content) ``` **TypeScript** ```javascript import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.bricksum.com/v1", apiKey: process.env.KILN_API_KEY }); const tools: OpenAI.ChatCompletionTool[] = [{ type: "function", function: { name: "get_weather", description: "Current weather for a city", // required parameters: { type: "object", properties: { city: { type: "string" } }, required: ["city"] }, }}]; const messages: OpenAI.ChatCompletionMessageParam[] = [ { role: "user", content: "What's the weather in Seoul?" }, ]; const first = await client.chat.completions.create({ model: "qwen3-32b", messages, tools, tool_choice: "auto", max_tokens: 800 }); // The model may answer without a tool call, and one reply can carry several. const calls = first.choices[0].message.tool_calls ?? []; if (calls.length > 0) { messages.push(first.choices[0].message); for (const call of calls) { if (call.type !== "function") continue; messages.push({ role: "tool", tool_call_id: call.id, content: JSON.stringify({ temp_c: 27 }) }); } const final = await client.chat.completions.create({ model: "qwen3-32b", messages, max_tokens: 800 }); console.log(final.choices[0].message.content); } else { console.log(first.choices[0].message.content); } ``` ## Kiln での違い - **usage.cost は OpenAI のスキーマにない** Kiln はすべてのレスポンスの usage オブジェクトに USD 建ての cost を追加します。OpenAI クライアントは usage を OpenAI のスキーマどおりに型付けしており、そのスキーマにこのフィールドはないため、型を広げるまで TypeScript は resp.usage.cost を受け付けません。値そのものはどちらの場合でもレスポンスに含まれます。 - **reasoning トークンも max_tokens に含まれる** モデルは回答の前に reasoning を行い、そのトークンも課金され max_tokens に含まれます。上限が小さいと message が空のまま finish_reason が "length" で返るため、両方が収まる余裕を確保してください。例の 800 はこのモデルで測定していない初期値のため、content が空で finish_reason が "length" なら増やしてください。 base URL、認証、すべてのエンドポイントが共通で受け取るリクエストパラメータ、レスポンスの形式、ストリーミング、エラーコードは、どの SDK を使っても同じです。これらは [API リファレンス](https://kiln.bricksum.com/docs/ja/api-reference)に一度だけまとめています。 上の呼び出しが到達するエンドポイントは [Chat completions](https://kiln.bricksum.com/docs/ja/api-reference/chat-completions)です。 モデル ID は API が現在提供しているものである必要があります。一覧の取得方法と、目的の ID が一覧にない場合の対処は [モデル](https://kiln.bricksum.com/docs/ja/models) のページにあります。 SDK に関係なくこのモデルが対応していない機能は [OpenAI からの移行](https://kiln.bricksum.com/docs/ja/migrating-from-openai) のページにまとめています。 メモ このページのスニペットは 2026-09-21 に openai 3.16.2 (Python), openai 7.20.0 (Node), openai-go v3.64.0 の環境で Kiln API に対して実行し、動作を確認しています。 未確認の項目: その実行は gpt-oss-120b で行いました。ページは現在 qwen3-32b を使っており、このモデルではまだ再実行していません。ツール呼び出しタブのすべての呼び出しに応答するループはその実行の後に追加されたもので、API に対して実行していません。