27
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Azure Open AIのトークン取得方法

Last updated at Posted at 2025-12-03

LLM APIの料金算出方法

現場にてLLMを利用した際、
どのように料金を算出するかの簡単なコードを備忘のため作成することにしました
他にもtiktokenというライブラリを使うこともできるようです

ソースコード

レスポンスのusageにそれぞれのトークンが入っています


import os
import sys
import base64
from dotenv import load_dotenv

from azure.ai.openai import OpenAIClient
from azure.core.credentials import AzureKeyCredential


def load_env():
	load_dotenv()
	cfg = {
		"azure_openai_endpoint": os.getenv("AZURE_OPENAI_ENDPOINT"),
		"azure_openai_key": os.getenv("AZURE_OPENAI_KEY"),
		# Azureで作成したデプロイ名(マルチモーダル/画像対応のデプロイである必要があります)
		"deployment": os.getenv("AZURE_OPENAI_DEPLOYMENT"),
		# 任意: tiktoken でのトークンエンコーディングに使うモデル名(例: "gpt-4o-mini-vision")
		"model_name": os.getenv("AZURE_OPENAI_MODEL", "gpt-4o-mini-vision")
	}
	return cfg


def image_to_data_uri(path: str) -> str:
	"""画像を読み込み、チャットメッセージに埋め込むのに適した data URI(base64)文字列を返します。

	注意: この方法はメッセージ内に data URI として埋め込まれた画像を受け取れるマルチモーダルモデルを前提としています
	(markdown の <img> タグや HTML)。Azure OpenAI のデプロイが Vision をサポートしていることを確認してください。
	"""
	with open(path, "rb") as f:
		b = f.read()
	b64 = base64.b64encode(b).decode("utf-8")
	# 拡張子から MIME タイプを推測する
	ext = os.path.splitext(path)[1].lower()
	if ext in [".jpg", ".jpeg"]:
		mime = "image/jpeg"
	elif ext == ".png":
		mime = "image/png"
	elif ext == ".gif":
		mime = "image/gif"
	else:
		mime = "application/octet-stream"
	return f"data:{mime};base64,{b64}"


def pretty_token_list(encoding, token_ids):
	"""各トークンIDを個別にデコードして (id, text) の一覧を返します。
	1トークンずつデコードすると、マルチバイトのトークンでは完全な文字列にならないことがありますが、
	トークン境界の断片を確認するのに便利です。
	"""
	out = []
	for tid in token_ids:
		try:
			txt = encoding.decode([tid])
		except Exception:
			# フォールバック: 空文字にする
			txt = ""
		out.append((int(tid), txt))
	return out


def main(image_path: str):
	if OpenAIClient is None:
		print("azure.ai.openai がインポートできません。\nインストール: python -m pip install azure-ai-openai python-dotenv tiktoken")
		sys.exit(1)

	cfg = load_env()
	endpoint = cfg["azure_openai_endpoint"]
	key = cfg["azure_openai_key"]
	deployment = cfg["deployment"]
	model_name = cfg["model_name"]

	if not endpoint or not key or not deployment:
		print("環境変数 AZURE_OPENAI_ENDPOINT, AZURE_OPENAI_KEY, AZURE_OPENAI_DEPLOYMENT を設定してください。")
		sys.exit(1)

	# 画像から data URI を作成し、markdown の <img> タグに埋め込む
	data_uri = image_to_data_uri(image_path)

	# メッセージを用意。画像は埋め込まれており、マルチモーダル対応モデルなら読み取るはずです。
	user_msg = {
		"role": "user",
		"content": f"以下の画像からテキストを抽出してください。抽出したテキストをそのまま出力してください。\n\n<img src=\"{data_uri}\" />"
	}

	client = OpenAIClient(endpoint=endpoint, credential=AzureKeyCredential(key))

	# 指定デプロイに対して chat completions を呼び出す
	try:
		resp = client.get_chat_completions(deployment_name=deployment, messages=[system_msg, user_msg])
	except Exception as e:
		print("Azure OpenAI へのリクエスト中にエラーが発生しました:", e)
		print("注意: デプロイがマルチモーダル(画像入力対応)である必要があります。例: gpt-4o-mini-vision など")
		sys.exit(1)

	# アシスタントの応答を取得(最初の choice を使用)
	choice = resp.choices[0]
	assistant_text = choice.message.content

	print("\n=== 抽出テキスト(モデル出力)===\n")
	print(assistant_text)

	# usage 情報があれば表示
	usage = getattr(resp, "usage", None)
	if usage:
		print("\n=== Usage (count) ===")
		try:
			print(f"prompt_tokens: {usage.get('prompt_tokens')}")
			print(f"completion_tokens: {usage.get('completion_tokens')}")
			print(f"total_tokens: {usage.get('total_tokens')}")
		except Exception:
			# 属性としてのフォールバック
			print(usage)

	print("\n=== Assistant tokens (model output) ===")
	print(f"count: {len(assistant_token_ids)}")
	for tid, txt in pretty_token_list(enc, assistant_token_ids):
		print(f"{tid}: {repr(txt)}")


if __name__ == "__main__":
	if len(sys.argv) < 2:
		print("使い方: python gpt.py <画像ファイルパス>\n例: python gpt.py D:\\images\\sample.jpg")
		sys.exit(1)
	image_path = sys.argv[1]
	main(image_path)





27
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?