意思決定
OpenAI Decisions API
GPT-6 Luna Decisions に、テキスト・画像・JSON についての分類やスコアリングの質問を投げると、コードでそのまま扱える型付きの回答が返ります。ある文がどの程度正しいか、どの値が当てはまるか、スケール上のどこに位置するかを、それぞれ確率付きで取得できます。1回のリクエストで多数の質問を処理でき、通常は1秒未満で完了します。OpenAI 独自の Decisions API と SDK を利用できます。
/v1/decisionsGPT-6 Luna Decisions は OpenAI の判断モデルです。入力を読み取り、それについて設定した質問に答えます。テキストは生成しないため、チャットモデルではありません。送信先は /v1/chat/completions ではなく /v1/decisions です。このエンドポイントでは、OpenAI 自身の SDK ドキュメントと同様に gpt-6-luna もモデル ID として使えるので、OpenAI のサンプルコードがそのまま動作します。レスポンスの model は gpt-6-luna-decisions になります。TypeSafe の判断モデル Jev については、意思決定 (Jev) をご覧ください。
質問する
# pip install --upgrade openaiimport osfrom openai import OpenAIclient = OpenAI( base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"],)decision = client.decisions.create( model="gpt-6-luna-decisions", input="My headphones stopped charging two days after they arrived. I want a refund.", questions=[ { "type": "predicate", "name": "refund", "instructions": "Is the customer asking for a refund?", }, { "type": "choice", "name": "topic", "instructions": "What is the ticket about?", "choices": [ {"value": "billing", "description": "Charges and invoices"}, {"value": "hardware", "description": "A device that is broken or faulty"}, {"value": "shipping", "description": "Delivery and tracking"}, ], }, { "type": "score", "name": "sentiment", "instructions": "How does the customer feel?", "levels": [ {"label": "very negative"}, {"label": "negative"}, {"label": "neutral"}, ], }, ],)# One answer per question, in the order askedfor answer in decision.answers: if answer.type == "refusal": print(answer.name, "refused") elif answer.type == "predicate": print(answer.name, answer.probability) elif answer.type == "choice": print(answer.name, answer.choice, answer.confidence) else: print(answer.name, answer.score, answer.confidence)print(decision.usage.input_tokens, "input tokens")OpenAI の SDK の接続先を https://api.zurelay.com/v1 にし、/v1 は Zurelay 上のほかの OpenAI モデルと同じ設定にして、Zurelay のキーで client.decisions.create を呼び出してください。Node.js では openai 7.30.0 以降が必要です。Python では client.decisions に対応している新しさの openai パッケージが必要です(3.41 なら対応しています)。HTTP クライアントでも同様で、キーを Bearer トークンとして付けて JSON を POST してください。
回答
{ "id": "req_3Fh8sLq0vW2nTc7yRb5kZp1M", "model": "gpt-6-luna-decisions", "answers": [ { "type": "predicate", "name": "refund", "probability": 1 }, { "type": "choice", "name": "topic", "choice": "hardware", "confidence": 1, "probabilities": [ { "value": "billing", "probability": 0 }, { "value": "hardware", "probability": 1 }, { "value": "shipping", "probability": 0 } ] }, { "type": "score", "name": "sentiment", "score": 0.18, "confidence": 0.85, "probabilities": [ { "value": 0, "label": "very negative", "probability": 0.82 }, { "value": 1, "label": "negative", "probability": 0.18 }, { "value": 2, "label": "neutral", "probability": 0 } ] } ], "usage": { "input_tokens": 325, "input_tokens_details": { "cached_tokens": 0, "cache_write_tokens": 0 }, "output_tokens": 0, "output_tokens_details": { "reasoning_tokens": 0 }, "total_tokens": 325, "cost": 0.000013 }}answers には、質問した順に質問ごとの回答が入り、それぞれに type が、指定した場合は name も含まれます。usage はリクエストの課金対象で、input_tokens の形式です。output_tokens は常に 0 で、cost は米ドルでの費用です。レスポンスの x-request-id ヘッダーを使えばリクエストログからこのリクエストを見つけられ、x-zurelay-input-tokens には課金対象が同じ内容で記載されます。
パラメータ
modelstring必須gpt-6-luna-decisions、またはこのエンドポイントではgpt-6-luna。input文字列または配列必須- 判定の対象:空でないテキスト、またはユーザーメッセージの配列
{ "role": "user", "content": ... }("type": "message"は省略可)。メッセージのcontentはテキストまたはパーツの配列で、詳細は以下のとおりです。 questionsarray必須- 1〜64個の質問を指定でき、記載した順に回答されます。
safety_identifierstring- 任意:リクエストの対象となるエンドユーザーを識別する不透明な ID です(自社のユーザー ID のハッシュなど)。
prompt_cache_keystring- 受け付けますが無視されます(
prompt_cache_optionsも同様です)。キャッシュは自動で行われ、入力トークンの料金はすべて同じです。
typestring必須predicate、choice、またはscore。instructionsstring必須- 質問をテキストで入力してください。画像は、ここではなく入力(input)に含めます。
namestring- 任意項目です。リクエスト内で一意にしてください。質問の回答に含まれて返されるため、名前で回答を読み取れます。
choicesarraychoice(必須)の場合:2〜255個の値を指定します。各値は{ "value": ..., "description": ... }。値はテキストまたはtrue/falseで、それぞれ一意である必要があります。説明は省略可能です。levelsarrayscore(必須)の場合:2〜10段階のレベルを低い順に指定します。各レベルは{ "label": ..., "description": ... }、説明は任意です。
input_text{ text }- テキスト。
input_image{ image_url, detail }- PNG、JPEG、WebP、GIF形式の画像。base64のデータURL、またはZurelayがダウンロードする公開
httpsリンクを指定できます。detailは省略可能です。指定できる値はlow、high、auto、originalです。 input_json{ data }- レコードやアプリの状態などのオブジェクトまたは配列です。モデルはこれをコンパクトな JSON テキストとして読み取り、そのテキストとしてカウントされます。
質問の種類
1回のリクエストで3つすべてを組み合わせられます。入力はまとめて1回だけ読み込まれるため、複数の質問を1つのリクエストで送るほうが、質問ごとに別々のリクエストを送るよりもコストを抑えられます。
プレディケート
入力に関する文、またははい/いいえで答えられる質問です。回答のprobabilityは、その内容が真である可能性の高さを表します。「はい」なら1に近く、「いいえ」なら0に近く、入力から明確に判断できない場合はその中間の値になります。
{ "type": "predicate", "name": "refund", "instructions": "Is the customer asking for a refund?" }{ "type": "predicate", "name": "refund", "probability": 1 }選択
指定した値の中から1つを選び、それぞれの確率を返します。説明を付けると値の意味を伝えられるため、値がコードだけの場合に役立ちます。値には true や false も使えます。文字列の "true" と真偽値の true は、別の値として扱われます。
{ "type": "choice", "name": "language", "instructions": "Which language is the message written in?", "choices": [ { "value": "en", "description": "English" }, { "value": "es", "description": "Spanish" }, { "value": "other", "description": "Any other language" } ]}スコア
入力をあなたが定義したレベルに、低いほうから順に割り当てます。score は期待レベルで、各レベルのインデックス(0から数えます)を、その確率で重み付けした値です。そのため、2つのレベルの間の値になることがあります。上の例のレスポンスでは、0.18 は大部分が最初のレベルで、2番目のレベルがわずかに混ざっています。probabilities の各エントリーには、レベルのインデックスを示す value と、その label が含まれます。
{ "type": "score", "name": "relevance", "instructions": "How well does the passage answer the search query?", "levels": [ { "label": "irrelevant" }, { "label": "related", "description": "On the topic, but doesn't answer it" }, { "label": "answers it" } ]}画像
入力に画像を含めるには、ユーザーメッセージのパートとしてテキストと並べて指定します。base64 のデータ URL、または公開されている https リンクを指定できます。リンクの場合は Zurelay が画像をダウンロードして転送します。対応形式は PNG、JPEG、WebP、GIF です。大きな画像はリンクで送信してください。
import base64, osfrom openai import OpenAIclient = OpenAI(base_url="https://api.zurelay.com/v1", api_key=os.environ["ZURELAY_API_KEY"])with open("return-photo.jpg", "rb") as file: photo = "data:image/jpeg;base64," + base64.b64encode(file.read()).decode()decision = client.decisions.create( model="gpt-6-luna-decisions", input=[ { "role": "user", "content": [ {"type": "input_text", "text": "Photo sent with a return request for a blender."}, {"type": "input_image", "image_url": photo, "detail": "low"}, ], } ], questions=[ { "type": "predicate", "name": "damaged", "instructions": "Does the photo show visible damage to the product?", }, { "type": "choice", "name": "product", "instructions": "What product is in the photo?", "choices": [ {"value": "blender"}, {"value": "kettle"}, {"value": "other", "description": "Anything else, or no product"}, ], }, ],)print(decision.answers)画像は、サイズとdetailに応じてトークンが加算されます。1200 × 630 の画像は、highまたはautoで約750トークン、lowでは約150トークンです。細かい文字ではなく画像全体について尋ねる場合は、lowを使います。画像を渡せるのは入力のみで、質問の指示にはテキストを使います。
JSON入力
構造化データは、テキストや画像と並べて input_json パートにそのまま入れられます。モデルはコンパクトな JSON テキストとして読み取り、そのテキストとして課金されます。
"input": [ { "role": "user", "content": [ { "type": "input_text", "text": "A sign-up from our app:" }, { "type": "input_json", "data": { "name": "Free Gift Card Giveaway", "email": "win-now@example.net", "bio": "Click my link" } } ] }]拒否
どの質問も、回答ではなく拒否として返される場合があります。その場合でも、リクエスト内の他の質問には通常どおり回答が返されます。各回答のフィールドを読む前に、まず type を確認してください。テストでは、入力 “Refund requested 38 hours ago.” に対して述語 “Page on-call?” を指定したところ、拒否として返されました。
{ "type": "refusal", "name": "page_on_call" }拒否は通常のレスポンスとして返され、そのusageにはリクエストの課金対象が示されます。質問をより明確にしてもう一度送信するか、担当者に引き継いでください。
制限
- 1リクエストあたり最大 1.05M トークンです(入力とすべての質問の合計)。テストでは、918K トークンの入力でも問題なく動作しました。
- 質問は1〜64件です。
choiceには2〜255個の一意の値、scoreには2〜10段階のレベルを指定できます。 - ユーザーメッセージのみ受け付けます。system、developer、assistant のメッセージと、関数呼び出しやツール呼び出しの項目は拒否されます。コンテキストはユーザーメッセージか、質問の instructions に入れてください。
- ストリーミングは使えません。
streamは拒否され、回答は一括で返されます。 - 形式が不正なリクエストや、API が受け付けないフィールドを含むリクエストは、モデルに届く前に、そのフィールド名(
questions[2].choicesなど)を示す400で拒否されます。料金はかかりません。 - 一部のモデルに限定したキーでは、リストに
gpt-6-luna-decisionsを含める必要があります。リクエストでgpt-6-lunaと指定した場合も同様です。詳しくはキーの制限とルールをご覧ください。
速度
当社のテストでは、回答は通常 0.3〜1 秒で返り、画像付きの場合は約 1 秒です。900K トークンの入力では約 10 秒かかりました。
意思決定の料金
GPT-6 Luna Decisions の料金は、入力 1M トークンあたり $0.04 です。回答は無料です。 トークンは、入力(1 回だけ数えます)に、質問ごとにモデル自身の約 110〜160 トークンを加えた数です。短いテキストに対する短い predicate 1 つで合計約 160 トークン、2 つで約 320 トークン、2,600 トークンの入力に 4 つの質問で約 3,200 トークンになります。画像は上記のとおり、そのトークン数が加算されます。 そのため、短いテキストに対する 1 問のチェックは約 $0.0000064、100 万件で約 $6.40 になります。
各レスポンスの usage ヘッダーと x-zurelay-input-tokens ヘッダーに課金の基準が示されます。すべてのリクエストはリクエストログで確認でき、失敗したリクエストには料金がかかりません。
エラー
キー、クレジット、予算、レート制限に関するエラーは、ほかのエンドポイントと同じです。詳しくはエラーをご覧ください。OpenAI の SDK は、再試行する価値のあるエラーを自動で再試行します。
まず試してみる
ご質問や不足している情報はありますか? サポートチームにお問い合わせください。通常1分以内にメールで回答します。