Corin1998 commited on
Commit
e22b238
·
verified ·
1 Parent(s): 04d7c18

Update app/llm.py

Browse files
Files changed (1) hide show
  1. app/llm.py +27 -10
app/llm.py CHANGED
@@ -1,8 +1,20 @@
 
 
1
  from openai import OpenAI
2
  from app.config import settings
3
- from typing import Literal
4
 
5
- client = OpenAI(api_key=settings.OPENAI_API_KEY)
 
 
 
 
 
 
 
 
 
 
 
6
 
7
  TONE_MAP = {
8
  "neutral": "ニュートラルで事実中心",
@@ -26,7 +38,7 @@ SYSTEM_TMPL = """
26
  """
27
 
28
  PROMPT_TMPL = """
29
- 【目的}{ctype}のドラフトを{tone_ja}で作成。
30
  【入力テキスト要約】以下の素材から、要点を抽出し、{ctype_guide}に沿ってMarkdownドラフトを生成。
31
  ---
32
  {source_text}
@@ -39,7 +51,12 @@ PROMPT_TMPL = """
39
  - 最後に「メタデータ」セクションを追加(推奨タグ・要約140字・推奨URLスラッグ)
40
  """
41
 
42
- def generate_draft(source_text: str, content_type: Literal["press_release","ir_letter","investor_summary"], tone: str):
 
 
 
 
 
43
  tone_ja = TONE_MAP.get(tone, TONE_MAP["neutral"])
44
  guide = TYPE_GUIDE[content_type]
45
 
@@ -50,7 +67,7 @@ def generate_draft(source_text: str, content_type: Literal["press_release","ir_l
50
  tone_ja=tone_ja,
51
  ctype_guide=guide,
52
  source_text=source_text[:12000],
53
- )}
54
  ]
55
 
56
  resp = client.chat.completions.create(
@@ -60,20 +77,20 @@ def generate_draft(source_text: str, content_type: Literal["press_release","ir_l
60
  )
61
  text = resp.choices[0].message.content
62
 
63
- # 件名(Subject)候補A/Bも同時生成
64
  subj_resp = client.chat.completions.create(
65
  model=settings.OPENAI_MODEL,
66
  temperature=0.3,
67
  messages=[
68
- {"role":"system","content":"日本語のPRメール件名ライター。50文字以内、事実に忠実。"},
69
- {"role":"user","content": f"次のMarkdownドラフトから、差分のある件名案を2つ出して。\n---\n{text[:6000]}"}
70
- ]
71
  )
72
  subs = subj_resp.choices[0].message.content.splitlines()
73
  subj_a = next((s for s in subs if s.strip()), "お知らせ")
74
  subj_b = next((s for s in subs[1:] if s.strip()), subj_a + "【続報】")
75
 
76
- # タイトル抽出(先頭行# 見出し)
77
  title = None
78
  for line in text.splitlines():
79
  if line.strip().startswith("# "):
 
1
+ import os
2
+ from typing import Literal
3
  from openai import OpenAI
4
  from app.config import settings
 
5
 
6
+ # 遅延初期化:インポート時にHTTPクライアントを作らない(環境差異の影響を減らす)
7
+ _client = None
8
+
9
+ def _get_client() -> OpenAI:
10
+ global _client
11
+ if _client is None:
12
+ api_key = settings.OPENAI_API_KEY or os.getenv("OPENAI_API_KEY", "")
13
+ if not api_key:
14
+ # 起動時ではなく呼び出し時に明示エラー
15
+ raise RuntimeError("OPENAI_API_KEY is not set. Please add it to HF Spaces Secrets or .env.")
16
+ _client = OpenAI(api_key=api_key)
17
+ return _client
18
 
19
  TONE_MAP = {
20
  "neutral": "ニュートラルで事実中心",
 
38
  """
39
 
40
  PROMPT_TMPL = """
41
+ 【目的{ctype}のドラフトを{tone_ja}で作成。
42
  【入力テキスト要約】以下の素材から、要点を抽出し、{ctype_guide}に沿ってMarkdownドラフトを生成。
43
  ---
44
  {source_text}
 
51
  - 最後に「メタデータ」セクションを追加(推奨タグ・要約140字・推奨URLスラッグ)
52
  """
53
 
54
+ def generate_draft(
55
+ source_text: str,
56
+ content_type: Literal["press_release", "ir_letter", "investor_summary"],
57
+ tone: str,
58
+ ):
59
+ client = _get_client()
60
  tone_ja = TONE_MAP.get(tone, TONE_MAP["neutral"])
61
  guide = TYPE_GUIDE[content_type]
62
 
 
67
  tone_ja=tone_ja,
68
  ctype_guide=guide,
69
  source_text=source_text[:12000],
70
+ )},
71
  ]
72
 
73
  resp = client.chat.completions.create(
 
77
  )
78
  text = resp.choices[0].message.content
79
 
80
+ # 件名(Subject)候補A/B
81
  subj_resp = client.chat.completions.create(
82
  model=settings.OPENAI_MODEL,
83
  temperature=0.3,
84
  messages=[
85
+ {"role": "system", "content": "日本語のPRメール件名ライター。50文字以内、事実に忠実。"},
86
+ {"role": "user", "content": f"次のMarkdownドラフトから、差分のある件名案を2つ出して。\n---\n{text[:6000]}"},
87
+ ],
88
  )
89
  subs = subj_resp.choices[0].message.content.splitlines()
90
  subj_a = next((s for s in subs if s.strip()), "お知らせ")
91
  subj_b = next((s for s in subs[1:] if s.strip()), subj_a + "【続報】")
92
 
93
+ # タイトル抽出(先頭行 # 見出し)
94
  title = None
95
  for line in text.splitlines():
96
  if line.strip().startswith("# "):