ガイド:ChatGPT APIのトークンとコスト計算
ChatGPT APIは、文字単位でレスポンスを返すServer-Sent Events:サーバー送信イベント(SSE)をサポートしています。SSEはHTTPプロトコルに基づくリアルタイム通信技術で、大規模言語モデル(LLM) APIのテストシナリオで一般的に使用されています。
開発者はしばしば、SSEイベントを連結し、トークン数と推定コストを計算する必要があります。この記事では、特定のAIアプリケーションのテストを例に取り、入力と出力の文字数を自動的にトークン値に変換し、1回のAPIテストセッション中にリアルタイムでコストの推定額を計算する方法を示します。
前提条件
テストプロセス中に消費するトークンを計算する前に、大規模モデルプロバイダの課金条件を理解する必要があります。プロセスに使用されたトークン数を記録し、OpenAIの料金表によって相応の通貨に変換する必要があります。
この記事では、日本円(JPY)を例として使用しています。
したがって、APIテスト中の質問応答のコストを計算するには、次の2つのステップが含まれます:
1. 入力と出力のトークン数を計算する。
2. リアルタイム為替レートを使用して、消費トークンの料金を日本円に変換する。
トークン数変換ライブラリ
コンテンツを正確にトークン値に変換するには、サードパーティのトークン変換ライブラリが必要です。次の例では、APIテストプロセス中に入力/出力データをトークン数に変換するために、OpenAI GPT Token Counterライブラリを使用しています。
まず、JSファイルを作成して、次のコードを入れます:
Node.js コード:
const openaiTokenCounter = require('openai-gpt-token-counter');
const text = process.argv[2]; // コマンドライン引数からテストコンテンツを取得
const model = "gpt-4"; // 使用したいOpenAIモデルに置き換える
const tokenCount = openaiTokenCounter.text(text, model);
const characterCount = text.length; // 文字数を計算
console.log(`${tokenCount}`);
Node.jsスクリプトの名前をgpt-tokens-counter.js
に変更し、他のプログラミング言語の呼び出しセクションで説明されているように、Apidogの外部プログラムディレクトリに保存します。
そして、OpenAI GPT Token Counterをパソコンにインストールする必要があります。このパッケージを次のコマンドでインストールできます。
npm install openai-gpt-token-counter
リアルタイム為替レートAPI
入力と出力のトークン値を取得した後、リアルタイム為替レートAPIを使用して、消費したトークンの料金を日本円(JPY)に変換する必要があります。この記事では、リアルタイム為替レートを取得するために Currencylayer APIを呼び出します。ここからアカウント登録してAPIキーを取得できます。
入力のコスト
入力値をトークンに変換
入力値は、ユーザーがAIアプリケーションにリクエストを発行するときに入力する質問やプロンプトと理解できます。 そのため、リクエストのbody
からmessages
パラメータのcontent
内容を抽出し、カスタムスクリプトを前処理に追加すると、それをトークン値に変換できます。
前処理セクションで、入力値をトークンに変換するため、カスタムScriptを追加する必要があります:
try {
var jsonData = JSON.parse(pm.request.body.raw);
var content = jsonData.messages[0].content; // メッセージのコンテンツを取得
var result_input_tokens_js = pm.execute('gpt-tokens-counter.js',[content])
console.log(content);
pm.environment.set("RESULT_INPUT_TOKENS", result_input_tokens_js);
console.log("入力トークン値: " + pm.environment.get("RESULT_INPUT_TOKENS"));
} catch (e) {
console.log(e);
}
「送信」ボタンをクリックすると、入力値から変換されたトークンの推定値がコンソールに表示されます。
トークンを実際の消費額(JPY)への変換
入力から消費されたトークンの値を取得した後、リアルタイム為替レートAPIを使用して、USDからJPYへの為替レーどを取得する必要があります。前処理に次のスクリプトを追加します:
pm.sendRequest("http://apilayer.net/api/live?access_key=YOUR-API-KEY¤cies=JPY&source=USD&format=1", (err, res) => {
if (err) {
console.log(err);
} else {
const quotes = res.json().quotes;
const rate = parseFloat(quotes.USDJPY).toFixed(3);
pm.environment.set("USDJPY_RATE", rate);
var USDJPY_RATE = pm.environment.get("USDJPY_RATE");
// 前のスクリプトからRESULT_INPUT_TOKENS変数を取得
var RESULT_INPUT_TOKENS = pm.environment.get("RESULT_INPUT_TOKENS");
// トークンの為替レート値を計算
const tokensExchangeRate = 0.03; // 1000トークンのUSD価格(GPT-4-8kコンテキスト入力価格を参照)
// 推定JPY価格を計算
const JPYPrice = ((RESULT_INPUT_TOKENS / 1000) * tokensExchangeRate * USDJPY_RATE).toFixed(2);
pm.environment.set("INPUT_PRICE", JPYPrice);
console.log("推定コスト: " + "¥" + JPYPrice);
}
});
レスポンスのコスト
レスポンスの連結
APIから返されたレスポンスのContent-Typeパラメータにtext/event-stream
が含まれる場合、Apidogは自動的に返されたデータをSSEイベントとして解析します。通常、SSEイベントの各返り値には断片的な文字(通常1文字)しか含まれていません。この場合、返されたすべてのコンテンツを完全な文に連結する必要があります。
API定義の後処理に移動し、レスポンスコンテンツを抽出し連結を完了するカスタムスクリプトを追加します。
レスポンスの連結用の後処理のスクリプト
// レスポンステキストを取得
const text = pm.response.text()
// テキストを行に分割
var lines = text.split('\n');
// "content"パラメータを格納する空の配列を作成
var contents = [];
// 各行を反復処理
for (var i = 0; i < lines.length; i++) {
const line = lines[i];
// "data:"で始まらない行はスキップ
if (!line.startsWith('data:')) {
continue;
}
// JSONデータの解析を試みる
try {
var data = JSON.parse(line.substring(5).trim()); // 先頭の"data: "を削除
// "choices"配列から"content"パラメータを取得し、配列に追加
contents.push(data.choices[0].delta.content);
} catch (e) {
// 有効なJSONデータでない場合は現在の行を無視
}
}
// join()メソッドを使用して"content"パラメータを連結
var result = contents.join('');
// 本文の"Visualize"タブに結果を表示
pm.visualizer.set(result);
// 結果をコンソールに出力
console.log(result);
リクエスト後、コンソールで完全なレスポンスコンテンツを取得できます。
レスポンス内容をトークン値への変換
完全なレスポンス内容を取得した後、サードパーティのライブラリを使用してそれをトークン値に変換する必要があります。後処理に次のカスタムScriptを追加すると、Apidogが外部のgpt-tokens-counter.js
スクリプト(具体的なスクリプトは「前提条件」の「トークン数変換ライブラリ」部分までご参照)を呼び出してトークン値を取得できます。
// レスポンステキストを取得
const text = pm.response.text()
// テキストを行に分割
var lines = text.split('\n');
// "content"パラメータを格納する空の配列を作成
var contents = [];
// 各行を反復処理
for (var i = 0; i < lines.length; i++) {
const line = lines[i];
// "data:"で始まらない行はスキップ
if (!line.startsWith('data:')) {
continue;
}
// JSONデータの解析を試みる
try {
var data = JSON.parse(line.substring(5).trim()); // 先頭の"data: "を削除
// "choices"配列から"content"パラメータを取得し、配列に追加
contents.push(data.choices[0].delta.content);
} catch (e) {
// 有効なJSONデータでない場合は現在の行を無視
}
}
// join()メソッドを使用して"content"パラメータを連結
var result = contents.join('');
// 本文の"Visualize"タブに結果を表示
pm.visualizer.set(result);
// 結果をコンソールに出力
console.log(result);
// 出力トークン数を計算
var RESULT_OUTPUT_TOKENS = pm.execute('./gpt-tokens/gpt-tokens-output-counter.js', [result])
pm.environment.set("RESULT_OUTPUT_TOKENS", RESULT_OUTPUT_TOKENS);
console.log("出力トークン値: " + pm.environment.get("RESULT_OUTPUT_TOKENS"));
レスポンスの実際コスト(JPY)
入力値に消費したトークン値のコストと同様に、レスポンスの実際コスト(JPY)はトークン値に為替レートを乗算することで取得できます。
後処理に次のスクリプトを追加します:
pm.sendRequest("http://apilayer.net/api/live?access_key=YOUR-API-KEY¤cies=JPY&source=USD&format=1", (err, res) => {
if (err) {
console.log(err);
} else {
const quotes = res.json().quotes;
const rate = parseFloat(quotes.USDJPY).toFixed(3);
pm.environment.set("USDJPY_RATE", rate);
var USDJPY_RATE = pm.environment.get("USDJPY_RATE");
// 前のPostmanスクリプトからRESULT_OUTPUT_TOKENS変数を取得
var RESULT_OUTPUT_TOKENS = pm.environment.get("RESULT_OUTPUT_TOKENS");
// トークンの為替レートを計算
const tokensExchangeRate = 0.06; // 1000トークンのUSD価格(GPT-4-8kコンテキスト入力価格に基づく)
// 推定JPY価格を計算
const JPYPrice = ((RESULT_OUTPUT_TOKENS / 1000) * tokensExchangeRate * USDJPY_RATE).toFixed(2);
pm.environment.set("OUTPUT_PRICE", JPYPrice);
console.log("コスト(JPY): " + JPYPrice + "円");
}
});
合計コストの推定値
最後に、入力とレスポンスのコストを足すと、合計コストの推定値が取得されます。加算用のカスタムスクリプトを後処理に追加しましょう。
// 入力コストとレスポンスコストの合計
const INPUTPrice = Number(pm.environment.get("INPUT_PRICE"));
const OUTPUTPrice = Number(pm.environment.get("OUTPUT_PRICE"));
console.log("合計コスト: " + "¥" + (INPUTPrice + OUTPUTPrice));
// 合計コストを出力: 入力価格とレスポンス価格の合計
これにより、APIのテストプロセス中に現在のリクエストの実際コストの推定値を知ることができるようになります。