import os from typing import List, Dict, Any from openai import OpenAI class OpenAILLM: def __init__(self,model_chat:str = "gpt-4o",model_translate:str = "gpt-4o", model_summarize:str = "gpt-4o"): api_key = os.environ.get("OPENAI_API_KEY2") if not api_key: raise RuntimeError("OPENAI_API_KEY2 is not set in environment variables.") self.client = OpenAI(api_key=api_key) self.model_chat = model_chat self.model_translate = model_translate self.model_summarize = model_summarize def generate_ceo_message(self,meta, kpi:Dict[str,float],esg_row:List[Dict[str,Any]])->str: prompt = ( "以下の企業情報・KPI・ESG指標をもとに、日本語で200字程度のCEOメッセージ草案を出力してください。" "投資家に伝わる簡潔なトーンで、過度な形容表現は避けてください。\n\n" f"企業情報: {meta.model_dump()}\n" f"KPI: {kpi}\n" f"ESG指標: {esg_row}\n" ) rsp = self.client.chat.completions.create( model=self.model_chat, messages=[{"role": "user", "content": prompt}], temperature=0.3, ) return rsp.choices[0].message.content.strip() def generate_risk_opportunity(self,meta,kpi:Dict[str,float],esg_row:List[Dict[str,Any]])->str: prompt = ( "以下の情報から、日本語で200字程度のリスクと機会の草案を出力してください。" "定量/定性のバランスを取り、具体的な観点を1-2点挙げてください。\n\n" f"企業情報: {meta.model_dump()}\n" f"KPI: {kpi}\n" f"ESG: {esg_row}\n" ) rsp = self.client.chat.completions.create( model=self.model_chat, messages=[{"role": "user", "content": prompt}], temperature=0.3, ) return rsp.choices[0].message.content.strip() def translate_text(self, texts:List[str], target_language: str) -> List[str]: if not texts: return texts system=( "You are precise financial/ESG translator.Preserve numbers,units,and proper nouns." "Keep tone concise,suitable for investor reports." ) SEP = "\n<<>>\n" joined = SEP.join(texts) prompt = f"Translate the following content to {target_language}.Keep layout minimal.\n\n{joined}" rsp = self.client.chat.completions.create( model=self.model_translate, messages=[ {"role": "user", "content": system},{"role": "user", "content": prompt} ], temperature=0.2, ) out = rsp.choices[0].message.content parts = [p.strip() for p in out.split("<<>>")] if len(parts) != len(texts): parts = [out]+texts[1:] parts = parts[:len(texts)] return parts