from __future__ import annotations import os import json import httpx OPENAI_BASE = os.environ.get("OPENAI_BASE", "https://api.openai.com/v1") OPENAI_MODEL = os.environ.get("OPENAI_MODEL", "gpt-4o-mini") OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY") HEADERS = { "Authorization": f"Bearer {OPENAI_API_KEY}" if OPENAI_API_KEY else "", "Content-Type": "application/json", } async def openai_chat(messages, temperature: float = 0.7, max_tokens: int = 300) -> str: """自由回答(プレーンテキスト)""" if not OPENAI_API_KEY: raise RuntimeError("OPENAI_API_KEY is not set in environment variables.") url = f"{OPENAI_BASE}/chat/completions" payload = { "model": OPENAI_MODEL, "messages": messages, "temperature": float(temperature), "max_tokens": int(max_tokens), } async with httpx.AsyncClient(timeout=60) as client: r = await client.post(url, headers=HEADERS, json=payload) r.raise_for_status() data = r.json() return data["choices"][0]["message"]["content"].strip() async def openai_chat_json(messages, temperature: float = 0.2, max_tokens: int = 1200) -> dict: """JSONモード(出力は厳密なJSON文字列)""" if not OPENAI_API_KEY: raise RuntimeError("OPENAI_API_KEY is not set in environment variables.") url = f"{OPENAI_BASE}/chat/completions" payload = { "model": OPENAI_MODEL, "messages": messages, "temperature": float(temperature), "max_tokens": int(max_tokens), "response_format": {"type": "json_object"}, } async with httpx.AsyncClient(timeout=60) as client: r = await client.post(url, headers=HEADERS, json=payload) r.raise_for_status() data = r.json() content = data["choices"][0]["message"]["content"].strip() return json.loads(content) def openai_judge(system: str, user: str) -> dict: """審査用(JSONモード)。同期呼び出し""" if not OPENAI_API_KEY: raise RuntimeError("OPENAI_API_KEY is not set in environment variables.") url = f"{OPENAI_BASE}/chat/completions" payload = { "model": OPENAI_MODEL, "messages": [ {"role": "system", "content": system}, {"role": "user", "content": user}, ], "response_format": {"type": "json_object"}, "temperature": 0.0, "max_tokens": 400, } with httpx.Client(timeout=60) as client: r = client.post(url, headers=HEADERS, json=payload) r.raise_for_status() data = r.json() content = data["choices"][0]["message"]["content"].strip() return json.loads(content)