KOyuki-0129 commited on
Commit
bda8348
·
verified ·
1 Parent(s): 78b2087

Update src/daily_ra/services/llm_service.py

Browse files
Files changed (1) hide show
  1. src/daily_ra/services/llm_service.py +78 -78
src/daily_ra/services/llm_service.py CHANGED
@@ -1,78 +1,78 @@
1
- from pydantic import BaseModel
2
- from typing import List
3
- from openai import OpenAI
4
- from dotenv import load_dotenv
5
- import os, json
6
-
7
- # .env を読み込む
8
- load_dotenv()
9
-
10
- # クライアントを初期化
11
- client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
12
-
13
- # ======== Pydantic スキーマ ========
14
- class DailyRAInput(BaseModel):
15
- work_date: str
16
- work_content: str
17
- hazard_points: str
18
- general_comments: str
19
- risk_identification: str
20
- mitigation_measures: str
21
- inspection_items: str
22
-
23
- class GeneratedRule(BaseModel):
24
- object1: str
25
- object2: str
26
- risk: str
27
-
28
- # ======== LLM サービス ========
29
- class LLMService:
30
- @staticmethod
31
- def generate_prompt(data: DailyRAInput) -> str:
32
- return f"""
33
- 以下は日次RAの作業内容です。作業者、重機、クレーンなどの対象物と危険性を抽出し、
34
- 安全ルールを JSON 形式で返してください。出力形式は
35
- [{{"object1": "対象1", "object2": "対象2", "risk": "リスク"}}] です。
36
-
37
- 作業日: {data.work_date}
38
- 作業内容: {data.work_content}
39
- 作業危険ポイント: {data.hazard_points}
40
- 元請コメント: {data.general_comments}
41
- 危険性・有害性の特定: {data.risk_identification}
42
- 危険性・有害性の低減策: {data.mitigation_measures}
43
- 点検事項: {data.inspection_items}
44
- """
45
-
46
- @staticmethod
47
- def generate_rules(data: DailyRAInput) -> List[GeneratedRule]:
48
- prompt = LLMService.generate_prompt(data)
49
-
50
- try:
51
- response = client.chat.completions.create(
52
- model="gpt-4o-mini",
53
- messages=[
54
- {"role": "system", "content": "あなたは建設現場の安全ルール生成AIです。"},
55
- {"role": "user", "content": prompt},
56
- ],
57
- temperature=0.2,
58
- )
59
- text = response.choices[0].message.content.strip()
60
-
61
- # ✅ コードブロック(````json ... `````)を除去
62
- if text.startswith("```"):
63
- text = text.strip("`")
64
- text = text.replace("json", "").strip()
65
-
66
- # JSONとしてパース
67
- rules_raw = json.loads(text)
68
- return [GeneratedRule(**r) for r in rules_raw]
69
-
70
- except json.JSONDecodeError as e:
71
- print(f"⚠️ JSONデコードエラー: {e}\n出力内容: {text}")
72
- return []
73
- except Exception as e:
74
- print(f"⚠️ LLM生成エラー: {e}")
75
- return []
76
-
77
- # シングルトンインスタンス
78
- llm_service = LLMService()
 
1
+ from pydantic import BaseModel
2
+ from typing import List
3
+ from openai import OpenAI
4
+ from dotenv import load_dotenv
5
+ import os, json
6
+
7
+ # .env を読み込む
8
+ load_dotenv()
9
+
10
+ # クライアントを初期化
11
+ client = OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
12
+
13
+ # ======== Pydantic スキーマ ========
14
+ class DailyRAInput(BaseModel):
15
+ work_date: str
16
+ work_content: str
17
+ hazard_points: str
18
+ general_comments: str
19
+ risk_identification: str
20
+ mitigation_measures: str
21
+ inspection_items: str
22
+
23
+ class GeneratedRule(BaseModel):
24
+ object1: str
25
+ object2: str
26
+ risk: str
27
+
28
+ # ======== LLM サービス ========
29
+ class LLMService:
30
+ @staticmethod
31
+ def generate_prompt(data: DailyRAInput) -> str:
32
+ return f"""
33
+ 以下は日次RAの作業内容です。作業者、重機、クレーンなどの対象物と対象物同士の関係性を抽出し、
34
+ 安全ルールを JSON 形式で返してください。出力形式は
35
+ [{{"object1": "対象1", "object2": "対象2", "risk": "リスク"}}] です。
36
+
37
+ 作業日: {data.work_date}
38
+ 作業内容: {data.work_content}
39
+ 作業危険ポイント: {data.hazard_points}
40
+ 元請コメント: {data.general_comments}
41
+ 危険性・有害性の特定: {data.risk_identification}
42
+ 危険性・有害性の低減策: {data.mitigation_measures}
43
+ 点検事項: {data.inspection_items}
44
+ """
45
+
46
+ @staticmethod
47
+ def generate_rules(data: DailyRAInput) -> List[GeneratedRule]:
48
+ prompt = LLMService.generate_prompt(data)
49
+
50
+ try:
51
+ response = client.chat.completions.create(
52
+ model="gpt-4o-mini",
53
+ messages=[
54
+ {"role": "system", "content": "あなたは建設現場の安全ルール生成AIです。"},
55
+ {"role": "user", "content": prompt},
56
+ ],
57
+ temperature=0.2,
58
+ )
59
+ text = response.choices[0].message.content.strip()
60
+
61
+ # ✅ コードブロック(````json ... `````)を除去
62
+ if text.startswith("```"):
63
+ text = text.strip("`")
64
+ text = text.replace("json", "").strip()
65
+
66
+ # JSONとしてパース
67
+ rules_raw = json.loads(text)
68
+ return [GeneratedRule(**r) for r in rules_raw]
69
+
70
+ except json.JSONDecodeError as e:
71
+ print(f"⚠️ JSONデコードエラー: {e}\n出力内容: {text}")
72
+ return []
73
+ except Exception as e:
74
+ print(f"⚠️ LLM生成エラー: {e}")
75
+ return []
76
+
77
+ # シングルトンインスタンス
78
+ llm_service = LLMService()