yeelou commited on
Commit
fdee2ff
·
verified ·
1 Parent(s): 2b8dd98
Files changed (5) hide show
  1. app.py +110 -0
  2. gpt_request.py +28 -0
  3. prompts.py +164 -0
  4. report.py +67 -0
  5. requirements.txt +3 -0
app.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """risk_demo.ipynb
3
+
4
+ Automatically generated by Colaboratory.
5
+
6
+ Original file is located at
7
+ https://colab.research.google.com/drive/10O8RqzRNTUw5fZd-V7dCvS22oAFkTc1i
8
+ """
9
+
10
+ # env
11
+ # !pip install -qqq gradio openai tenacity
12
+
13
+ # !cp "/content/drive/MyDrive/Colab Notebooks/risk/gpt_request.py" /content/
14
+ # !cp "/content/drive/MyDrive/Colab Notebooks/risk/prompts.py" /content/
15
+ # !cp "/content/drive/MyDrive/Colab Notebooks/risk/report.py" /content/
16
+
17
+ import gradio as gr
18
+ import time
19
+ import json
20
+ import random
21
+
22
+ from prompts import *
23
+ from report import *
24
+
25
+ GPT_MODEL_DICT = {"GPT3.5":"gpt-3.5-turbo-0125",
26
+ "GPT4":"gpt-4-0125-preview"}
27
+
28
+ def gen_report(text, gpt, progress=gr.Progress()):
29
+ gpt_model = GPT_MODEL_DICT[gpt]
30
+ progress(0, desc="Starting")
31
+ ex_t_rnd = list(range(1,len(risk_ex_t)+1))
32
+ ex_f_rnd = list(range(1,len(risk_ex_f)+1))
33
+ progress(0.1, desc="risk")
34
+ risk_response = risk(text, ex_t_rnd, ex_f_rnd, gpt_model)
35
+ if risk_response[0]["risk"] != "yes":
36
+ return "### ノーリスク"
37
+ progress(0.3, desc="title")
38
+ title_response = title(text, ex_t_rnd, risk_response[0]["risk_key"], gpt_model)
39
+ progress(0.5, desc="summary")
40
+ summary_response = summary(text, ex_t_rnd, gpt_model)
41
+ progress(0.7, desc="alert")
42
+ alert_response = alert(text, ex_t_rnd, risk_response[0]["risk_key"], gpt_model)
43
+ print("translate start")
44
+ res_dict = {
45
+ 'title':title_response[0]['title'],
46
+ 'summary':summary_response[0]['summary'],
47
+ 'alert':alert_response[0]['alert'],
48
+ 'news':text,
49
+ 'risk':risk_response[0]['risk_key'],
50
+ 'reason':risk_response[0]['reason']
51
+ }
52
+ # save
53
+
54
+ progress(0.85, desc="alert")
55
+ translate_response = translate(res_dict, gpt_model)
56
+ progress(0.90, desc="over")
57
+ res_msg = report_msg.format(
58
+ title=translate_response[0]['title'],
59
+ summary=translate_response[0]['summary'],
60
+ alert=translate_response[0]['alert'],
61
+ news=translate_response[0]['news'],
62
+ risk=translate_response[0]['risk_key'],
63
+ reason=translate_response[0]['reason']
64
+ )
65
+ return res_msg
66
+
67
+ def example_f(input,choice):
68
+ if input == risk_ex_t['ex1']['news']:
69
+ res = risk_ex_t['ex1']
70
+ elif input == risk_ex_t['ex2']['news']:
71
+ res = risk_ex_t['ex2']
72
+ elif input == risk_ex_t['ex3']['news']:
73
+ res = risk_ex_t['ex3']
74
+ else:
75
+ print("error")
76
+
77
+ res_msg = report_msg.format(
78
+ title=json.loads(res['title'])['title'],
79
+ summary=json.loads(res['summary'])['summary'],
80
+ alert=json.loads(res['alert'])['alert'],
81
+ news=res['news'],
82
+ risk=json.loads(res['risk'])['risk_key'],
83
+ reason=json.loads(res['risk'])['reason']
84
+ )
85
+ return res_msg
86
+
87
+ with gr.Blocks(title="アラート生成demo", theme="bethecloud/storj_theme") as demo:
88
+ gr.Markdown("# アラート生成demo")
89
+ gr.Markdown("gptを通じてアラートメッセージを生成する")
90
+ with gr.Row():
91
+ with gr.Column():
92
+ choice = gr.Radio(choices = ["GPT3.5", "GPT4"], label = "GPTモデル")
93
+ input = gr.Textbox(label="INPUT",lines=7)
94
+ with gr.Column():
95
+ gr.Markdown("OUTPUT")
96
+ output = gr.Markdown(label="report")
97
+
98
+ gen_btn = gr.Button("生成")
99
+ gr.ClearButton([input,output],"クリア")
100
+ gr.Examples(
101
+ examples = [[risk_ex_t['ex1']['news'],"GPT3.5"],[risk_ex_t['ex2']['news'],"GPT3.5"],[risk_ex_t['ex3']['news'],"GPT3.5"]],
102
+ inputs = [input,choice],
103
+ outputs = [output],
104
+ fn=example_f,
105
+ cache_examples = True
106
+ )
107
+
108
+ gen_btn.click(fn=gen_report, inputs=[input,choice], outputs=output)
109
+ # demo.launch(inline=False, share=True, debug=True)
110
+ demo.launch()
gpt_request.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from openai import OpenAI
2
+ from tenacity import retry, wait_random_exponential, stop_after_attempt
3
+ import random
4
+ import json
5
+
6
+ import os
7
+ os.environ['OPENAI_API_KEY'] = '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'
8
+
9
+ client = OpenAI()
10
+
11
+ # openai sent
12
+ @retry(wait=wait_random_exponential(multiplier=1, max=40), stop=stop_after_attempt(3))
13
+ def chat_completion_request(messages, tools=None, tool_choice=None, model="gpt-3.5-turbo-0125", temperature=0.6):
14
+ try:
15
+ response = client.chat.completions.create(
16
+ model=model,
17
+ messages=messages,
18
+ temperature=temperature,
19
+ tools=tools,
20
+ tool_choice=tool_choice,
21
+ response_format={ "type": "json_object" }
22
+ )
23
+
24
+ return json.loads(response.choices[0].message.content),response.usage.completion_tokens,response.usage.prompt_tokens
25
+ except Exception as e:
26
+ print("Unable to generate ChatCompletion response")
27
+ print(f"Exception: {e}")
28
+ return e
prompts.py ADDED
@@ -0,0 +1,164 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ risk_list ="""
2
+ "自然災害":"地震、洪水、台風、異常気象による被害など",
3
+ "製造物責任":"製品の瑕疵(かし)、リコールなど",
4
+ "サイバーセキュリティ":"サイバー攻撃やデータ漏洩など",
5
+ "事故":"交通事故や設備交渉など",
6
+ "感染症":"新型ウイルスのパンデミックなど",
7
+ "環境問題":"工場排水の不適切な処理など"
8
+ "不正会計":"粉飾決算、横領など",
9
+ "調達価格":"原材料、原油価格の高騰など",
10
+ "投資活動":"投資活動の失敗による損失など",
11
+ """
12
+
13
+ # risk list ex
14
+ risk_ex_t = {
15
+ "ex1":{
16
+ "news":"台風7号はきょう11日午前3時、「強い」台風から、「非常に強い」勢力に変わりました。きょう11日の夕方にかけて小笠原諸島に最接近し、小笠原諸島は大荒れの天気でしょう。14日(月)には勢力は一つランクを下げるものの、「強い」勢力で暴風域を伴って本州に接近し、15日(火)頃から16日(水)にかけて東日本や西日本にかなり接近、上陸する恐れがあります。",
17
+ "risk":'{"ja": "yes", "risk": "yes", "risk_key":"自然災害","reason":"台風7号はきょう11日午前3時、「強い」台風から、「非常に強い」勢力に変わりました。"}',
18
+ "title":'{"title":"[自然災害]台風7号接近、工場で浸水の可能性あり、ご確認お願い致します。"}',
19
+ "summary":'{"summary":"台風7号はきょう11日午前3時、「強い」台風から、「非常に強い」勢力に変わりました。15日(火)頃から16日(水)にかけて東日本や西日本にかなり接近、上陸する恐れがあります。"}',
20
+ "alert":'{"alert":"!!台風7号接近、非常に悪天候、潜在的な被害、および混乱の高いリスク。油断せず、必要な予防措置を取ってください。!!"}'
21
+ },
22
+ "ex2":{
23
+ "news":"JetBrainsが提供するCI/CDツール「TeamCity」に深刻な脆弱性「CVE-2024-23917」が明らかとなった。悪用されるとリモートよりコードを実行されるおそれがある。同製品に認証回避の脆弱性「CVE-2024-23917」が明らかとなったもの。HTTP経由でアクセスできる場合、認証をバイパスして「TeamCityサーバ」の管理を行うことが可能となり、リモートよりコードを実行されるおそれがある。",
24
+ "risk":'{"ja": "yes", "risk": "yes", "risk_key":"サイバーセキュリティ","reason":"JetBrainsが提供するCI/CDツール「TeamCity」に深刻な脆弱性「CVE-2024-23917」が明らかとなった。"}',
25
+ "title":'{"title":"[サイバーセキュリティ] JetBrainsのCI/CDツール「TeamCity」に深刻な脆弱性発覚、リモートコード実行の危険性と対策に注意"}',
26
+ "summary":'{"summary":"JetBrainsのCI/CDツール「TeamCity」に深刻な脆弱性「CVE-2024-23917」が発見されました。 この脆弱性を悪用すると、リモートからコードが実行される危険性があります。"}',
27
+ "alert":'{"alert":"!!重要!!JetBrainsのCI/CDツール「TeamCity」に深刻な脆弱性「CVE-2024-23917」が発見されました。コードが実行される危険性があります。すぐに対策を講じ、システムの保護を強化してください。!!"}'
28
+
29
+ },
30
+ "ex3":{
31
+ "news":"2024年1月1日16時10分頃、石川県能登地方を震源とするマグニチュード7.6(最大震度7)の地震が発生しました。 被災された方々には謹んでお見舞い申し上げます。 本地震における本投資法人の保有物件所在地の最大震度は4であり、現在のところ人的被害や運用状況に重要な影響を及ぼす被害等は確認されておりません。",
32
+ "risk":'{"ja": "yes", "risk": "yes", "risk_key":"自然災害","reason":"2024年1月1日16時10分頃、石川県能登地方を震源とするマグニチュード7.6(最大震度7)の地震が発生しました。"}',
33
+ "title":'{"title":"[自然災害]地震発生、投資物件に最大震度4、被害の影響に注意"}',
34
+ "summary":'{"summary":"2024年1月1日16時10分頃、石川県能登地方を震源とするマグニチュード7.6(最大震度7)の地震が発生しました。保有物件の最大震度は4で、本地震における本投資法人の保有物件所在地の最大震度は4であり、現在のところ人的被害や運用状況に重要な影響を及ぼす被害等は確認されておりません。"}',
35
+ "alert":'{"alert":"!!石川県能登地方で発生したM7.6の地震、最大震度7。被害情報はまだ確認されていませんが、注意が必要。地域の安全確認と適切な対策を急いで実施してください。"}'
36
+ }
37
+ }
38
+ risk_ex_f = {
39
+ "ex1":{
40
+ "news":"花巻東高(岩手)で通算140本塁打を放った佐々木麟太郎内野手が、米スタンフォード大学へ進学することが決まった。同大学が公式ホームページで発表した。",
41
+ "risk":'{"ja": "yes", "risk": "no", "risk_key":"","reason":""}'
42
+ },
43
+ "ex2":{
44
+ "news":"「ももいろクローバーZ」百田夏菜子(29)が14日、東京・渋谷で行われた「カラダうごかせ!ニッポン!」プロジェクト発足記者発表会に登場。「KinKi Kids」堂本剛(44)と結婚発表後、初めての公の場で、左手に指輪はしていなかったが、幸せいっぱいの笑顔を見せた。",
45
+ "risk":'{"ja": "yes", "risk": "no", "risk_key":"","reason":""}'
46
+ },
47
+ }
48
+
49
+ # prompt
50
+ ## risk list
51
+ risk_sys_msg = """
52
+ You are a helpful business analyst expert designed to \
53
+ provide me with the information on risks appearing in the news, formatted in JSON.
54
+ """
55
+ risk_usr_msg ="""
56
+ Enter the news and risks that all companies can refer to. \
57
+ Determine whether there is risk information in the news. \
58
+ If there is, output yes, the risk information contained, \
59
+ and the original text basis that can be judged. \
60
+ If there is no, only output no.
61
+ Determine if the news is written in Japanese. Output the results in JSON format. \
62
+ like {{'ja': determine if the news is written in Japanese ,'risk': Is there any risk , 'risk_key': Risk type ,'reason': The basis of the original text}} \
63
+ Think about it a few more steps \n\n \
64
+ news: {n1} \n
65
+ risk list:{r1}\n
66
+ output:{o1} \n\n
67
+ news: {n2} \n
68
+ risk list:{r2}\n
69
+ output:{o2} \n\n
70
+ news: {n3} \n
71
+ risk list:{r3}\n
72
+ output:{o3} \n\n
73
+ news: {n4}\n
74
+ risk list:{r4}\n
75
+ output:
76
+ """
77
+ ## title
78
+ title_usr_msg = """
79
+ I need a compelling and insightful title for a report based on input news. \
80
+ The news highlights potential risks or challenges in the {risk} sector. Generate a concise, \
81
+ attention-grabbing title that encapsulates the essence of the risks discussed in the news article. \
82
+ frame the title to capture the attention of decision-makers. Output the results in JSON format. \
83
+ like {{'title':generated title}} \
84
+ Think about it a few more steps \n\n \
85
+ news: {n1} \n
86
+ output:{o1} \n\n
87
+ news: {n2} \n
88
+ output:{o2} \n\n
89
+ news: {n3} \n
90
+ output:
91
+ """
92
+ ## sum
93
+ summary_usr_msg ="""
94
+ I need a concise news summary focusing on risks based on the provided news input. \
95
+ Please craft a brief summary that highlights potential risks associated with the given news. Within two sentences\
96
+ Output the results in JSON format. \
97
+ like {{'summary':generated summary}} \
98
+ Think about it a few more steps \n\n \
99
+ news: {n1} \n
100
+ output:{o1} \n\n
101
+ news: {n2} \n
102
+ output:{o2} \n\n
103
+ news: {n3} \n
104
+ output:
105
+ """
106
+ ## alert msg
107
+ alert_usr_msg ="""
108
+ I need assistance in creating an alert message based on the risk-related content of the entered news. \
109
+ As a risk analyst, guide me in generating a concise and informative alert message summarizing the potential {risk} risk highlighted in the news. \
110
+ This alert is crucial for making timely decisions and assessing the impact of the information. \
111
+ Output the results in JSON format.\
112
+ like {{'alert':generated alert message}} \
113
+ Think about it a few more steps \n\n \
114
+ news: {n1} \n
115
+ output:{o1} \n\n
116
+ news: {n2} \n
117
+ output:{o2} \n\n
118
+ news: {n3} \n
119
+ output:
120
+ """
121
+ ## report
122
+ report_msg = """
123
+ ## アラートメッセージ
124
+
125
+ ### {title}
126
+
127
+ ### [サマリ]
128
+ {summary}
129
+
130
+ ### [アラート]
131
+ {alert}
132
+
133
+ ### [本文]
134
+ {news}
135
+
136
+ #### [リスク]
137
+ {risk}
138
+
139
+ #### [根拠]
140
+ {reason}
141
+ """
142
+ ## japanese
143
+ translate_sys_msg = """
144
+ You are a helpful Japanese translation expert designed to \
145
+ provide me translate non-Japanese text, formatted in JSON.
146
+ """
147
+
148
+ translate_usr_msg = """
149
+ Translate the following non-Japanese text in a dictionary into formal Japanese for me. \
150
+ Do not translate proper nouns. \
151
+ If text is Japanese, return unchanged. \
152
+ Ensure the correctness of grammar and vocabulary. \
153
+ Output the results in JSON format.
154
+ like {{'title':translated title,'summary':translated summary,'alert':translated alert,'news':translated news,'risk_key':translated risk_key,'reason':translated reason}}
155
+ input: {dictionary}
156
+ output:
157
+ """
158
+
159
+ news_e = "The lingering storm system that has battered California for days continues to pose a flooding risk for southern parts of the state. A rare tornado warning was issued for parts of San Diego County. The warning has expired, but heavy rain and lightning were still possible. The San Diego region remains under a flood watch through tonight because of excessive rainfall, the National Weather Service said, and residents in mountain areas are being warned about rockslides and rocks on the roads."
160
+ news1 = "14日午後6時33分ごろ、鹿児島市の桜島・南岳山頂火口で爆発的噴火があり、噴煙が火口から5千メートルの高さまで上がった。気象庁は熊本、宮崎、鹿児島各県の一部に降灰予報を出した。鹿児島県によると、けが人や建物被害は確認されていない。5千メートルに達したのは、同じ火口で噴火した"
161
+ news2 = "岸田首相(自民党総裁)は14日午前の衆院予算委員会集中審議で、自民党派閥の政治資金規正法違反事件を受け、規正法違反で会計責任者が逮捕・起訴された場合に議員本人も処分できるよう党則を改正する考えを明らかにした。3月17日の党大会で決定する意向だ。"
162
+ news3 = "楽天グループの去年1年間の連結決算は3394億円の最終赤字になりました。赤字額は過去最大だったおととしより縮小したものの、赤字は5年連続で、その大きな要因となっているのがモバイル事業です。これまで、携帯電話の基地局建設には1兆円以上を投じていますが、その一方で、去年12月時点での契約者数は609万件と大手3社の10分の1以下です。また、基地局建設にあたって発行した社債、いわゆる借金の返済額は今年と来年の2年間でおよそ8000億円に上りますが、三木谷社長は「資金繰りは心配ない」と強調しました。"
163
+ news4 = "LINEヤフーは14日、新たに従業員などの個人情報13万件以上が流出した可能性があると発表した。LINEヤフーは2023年11月に大株主である韓国ネット大手・NAVERがサイバー攻撃を受けたことでLINE利用者の個人情報44万件が不正アクセスを受けた可能性があると発表していた。追加調査の結果、NAVERのサーバー経由で従業員などの氏名や顔写真など、個人情報が追加で約8万件、また、他の委託先経由で従業員などの個人データが6万件近く、あわせて13万件以上が流出した可能性が確認された。"
164
+ news5 = "韓国人俳優のマ・ドンソクが14日、都内で行われた主演映画『犯罪都市 NO WAY OUT』(2月23日公開)のジャパンプレミアにイ・サンヨン監督、青木崇高、國村隼とともに出席。初の公式来日を果たした。"
report.py ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import json
2
+ from prompts import *
3
+ from gpt_request import chat_completion_request
4
+ def risk(news_text, ex_t_rnd, ex_f_rnd, model):
5
+ messages = []
6
+ messages.append({"role": "system", "content": risk_sys_msg})
7
+ messages.append({"role": "user", "content": risk_usr_msg.format(
8
+ n1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["news"],
9
+ r1=risk_list,
10
+ o1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["risk"],
11
+ n2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["news"],
12
+ r2=risk_list,
13
+ o2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["risk"],
14
+ n3=risk_ex_f[f"ex{ex_f_rnd[0]}"]["news"],
15
+ r3=risk_list,
16
+ o3=risk_ex_f[f"ex{ex_f_rnd[0]}"]["risk"],
17
+ n4=news_text,
18
+ r4=risk_list)})
19
+ risk_response = chat_completion_request(messages, model=model)
20
+ return risk_response
21
+
22
+ def title(news_text, ex_t_rnd, risk, model):
23
+ messages = []
24
+ messages.append({"role": "system", "content": risk_sys_msg})
25
+ messages.append({"role": "user", "content": title_usr_msg.format(
26
+ risk=risk,
27
+ n1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["news"],
28
+ o1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["title"],
29
+ n2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["news"],
30
+ o2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["title"],
31
+ n3=news_text)})
32
+ title_response = chat_completion_request(messages, model=model)
33
+ return title_response
34
+
35
+ def summary(news_text, ex_t_rnd, model):
36
+ messages = []
37
+ messages.append({"role": "system", "content": risk_sys_msg})
38
+ messages.append({"role": "user", "content": summary_usr_msg.format(
39
+ n1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["news"],
40
+ o1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["summary"],
41
+ n2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["news"],
42
+ o2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["summary"],
43
+ n3=news_text)})
44
+ summary_response = chat_completion_request(messages,model=model)
45
+ return summary_response
46
+
47
+ def alert(news_text, ex_t_rnd, risk, model):
48
+ messages = []
49
+ messages.append({"role": "system", "content": risk_sys_msg})
50
+ messages.append({"role": "user", "content": alert_usr_msg.format(
51
+ risk=risk,
52
+ n1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["news"],
53
+ o1=risk_ex_t[f"ex{ex_t_rnd[0]}"]["alert"],
54
+ n2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["news"],
55
+ o2=risk_ex_t[f"ex{ex_t_rnd[1]}"]["alert"],
56
+ n3=news_text)})
57
+ alert_response = chat_completion_request(messages,model=model)
58
+ return alert_response
59
+
60
+ def translate(report_dict,model):
61
+ messages = []
62
+ messages.append({"role": "system", "content": translate_sys_msg})
63
+ messages.append({"role": "user", "content": translate_usr_msg.format(dictionary=json.dumps(report_dict))})
64
+ translate_response = chat_completion_request(messages,model=model)
65
+ return translate_response
66
+
67
+
requirements.txt ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ gradio
2
+ openai
3
+ tenacity