Spaces:
Running
Running
新テンプレ、質問json修正、逸脱発生報告書、逸脱報告書
Browse files- data/questions/原薬_グレード_x.json +7 -7
- data/questions/原薬_製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)_x.json +16 -4
- data/questions/原薬_製造所(A社→B社)_x.json +19 -7
- data/questions/原薬_製造方法_x.json +7 -3
- data/questions/原薬_製造設備_x.json +11 -3
- data/questions/原薬_試験規格の変更_x.json +58 -0
- data/questions/添加物_製造メーカー(A社→B社)_x.json +4 -0
- data/questions/添加物_製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)_x.json +4 -0
- data/questions/{資材変更_セット箱_製造所の変更.json → 資材変更_セット箱_製造所(メーカー)の変更.json} +1 -1
- data/questions/{資材変更_チューブ・容器キャップ(直接容器)_形状変更.json → 資材変更_チューブ・容器キャップ(直接容器)_形状(金型・グレード)変更.json} +1 -1
- data/questions/{資材変更_チューブ・容器キャップ(直接容器)_製造所の変更.json → 資材変更_チューブ・容器キャップ(直接容器)_製造所(メーカー)の変更.json} +1 -1
- data/questions/{資材変更_個箱_製造所の変更.json → 資材変更_個箱_製造所(メーカー)の変更.json} +1 -1
- data/questions/{資材変更_添付文書_製造所の変更.json → 資材変更_添付文書_製造所(メーカー)の変更.json} +1 -1
- data/template/template.docx +0 -0
- data/template/template_deviation.docx +0 -0
- data/{template_deviation.docx → template/template_deviation_occurrence.docx} +0 -0
- data/template_12.docx +0 -0
- data/template_3.docx +0 -0
- data/template_4.docx +0 -0
- data/template_base.docx +0 -0
- main.py +13 -6
- src/embed_output.py +9 -17
- src/embed_output_deviation.py +25 -15
- src/embed_output_deviation_occurrence.py +76 -0
- src/forms.py +443 -35
- src/prompts.py +84 -25
- src/questions.py +2 -4
data/questions/原薬_グレード_x.json
CHANGED
@@ -3,31 +3,31 @@
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
-
"question": "
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーから安定性試験結果を入手できるか",
|
10 |
-
"question": "
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
-
"question": "
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
18 |
-
"question": "
|
19 |
},
|
20 |
{
|
21 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
22 |
-
"question": "
|
23 |
},
|
24 |
{
|
25 |
"item": "ニトロソアミン類の混入に関するリスク管理に変わりはないか",
|
26 |
-
"question": "
|
27 |
},
|
28 |
{
|
29 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
30 |
-
"question": "
|
31 |
}
|
32 |
]
|
33 |
}
|
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
+
"question": "原薬メーカー又は製造販売業者からの変更指示書が提供されていますか?もしそうであれば、その内容を詳しく教えてください。"
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーから安定性試験結果を入手できるか",
|
10 |
+
"question": "変更後の原薬に関する安定性試験結果を原薬メーカーから入手することは可能ですか?また、その試験結果を共有していただけますか?"
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
+
"question": "変更後の原薬に対して、どのような試験を計画していますか?また、その試験方法と期待される結果について詳しく教えてください。"
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
18 |
+
"question": "変更後の原薬を使用した試作品の評価は計画されていますか?もしそうであれば、どのような評価項目を設定していますか?"
|
19 |
},
|
20 |
{
|
21 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
22 |
+
"question": "変更後の原薬に関して、元素不純物リスクアセスメントの結果に変更はありますか?もしある場合、その詳細を教えてください。"
|
23 |
},
|
24 |
{
|
25 |
"item": "ニトロソアミン類の混入に関するリスク管理に変わりはないか",
|
26 |
+
"question": "変更後の原薬におけるニトロソアミン類の混入リスク管理に変更はありますか?変更がある場合、そのリスク管理方法を詳しく教えてください。"
|
27 |
},
|
28 |
{
|
29 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
30 |
+
"question": "提案される原薬の変更は自然切替で対応可能ですか?もし不可能な場合、どのような切替計画を考えていますか?"
|
31 |
}
|
32 |
]
|
33 |
}
|
data/questions/原薬_製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)_x.json
CHANGED
@@ -3,19 +3,23 @@
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
-
"question": "
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
-
"question": "
|
|
|
|
|
|
|
|
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
-
"question": "
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
18 |
-
"question": "
|
19 |
},
|
20 |
{
|
21 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
@@ -36,6 +40,14 @@
|
|
36 |
{
|
37 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
38 |
"question": "この変更を行う際の切替方法は確認済みですか?自然切替で問題ないですか?"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
39 |
}
|
40 |
]
|
41 |
}
|
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
+
"question": "原薬メーカーまたは製造販売業者からの変更指示書を提供していただけますか?"
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
+
"question": "原薬メーカーで行われた安定性試験の結果を入手することは可能ですか?"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"item": "原料メーカーから均一性の評価結果を入手できるか",
|
14 |
+
"question": "原薬メーカーの均一性の評価結果を入手できますか?また、その結果の詳細を共有してください。"
|
15 |
},
|
16 |
{
|
17 |
"item": "原料試験による評価の実施",
|
18 |
+
"question": "新しい原薬に対して実施した試験評価の結果はありますか?"
|
19 |
},
|
20 |
{
|
21 |
"item": "試作品による評価の実施",
|
22 |
+
"question": "変更後の原薬を使用した試作品による評価は行いましたか?"
|
23 |
},
|
24 |
{
|
25 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
|
|
40 |
{
|
41 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
42 |
"question": "この変更を行う際の切替方法は確認済みですか?自然切替で問題ないですか?"
|
43 |
+
},
|
44 |
+
{
|
45 |
+
"item": "全梱包確認試験の実施の有無",
|
46 |
+
"question": "全梱包確認試験は実地されましたか?詳しい内容を説明してください。"
|
47 |
+
},
|
48 |
+
{
|
49 |
+
"item": "追加",
|
50 |
+
"question": "承認書の変更(一部変更承認申請/軽微変更届)の要否について、製造販売業者に確認しましたか。また、変更にあたっての内容及びスケジュールは調整済みですか?"
|
51 |
}
|
52 |
]
|
53 |
}
|
data/questions/原薬_製造所(A社→B社)_x.json
CHANGED
@@ -3,19 +3,23 @@
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
-
"question": "
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
-
"question": "
|
|
|
|
|
|
|
|
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
-
"question": "
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
18 |
-
"question": "
|
19 |
},
|
20 |
{
|
21 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
@@ -35,15 +39,23 @@
|
|
35 |
},
|
36 |
{
|
37 |
"item": "原料メーカーと取り決めを結んでいるか",
|
38 |
-
"question": "
|
39 |
},
|
40 |
{
|
41 |
"item": "供給者監査(新規メーカー)を実施しているか",
|
42 |
-
"question": "
|
43 |
},
|
44 |
{
|
45 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
46 |
-
"question": "
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
}
|
48 |
]
|
49 |
}
|
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
+
"question": "原薬メーカー又は製造販売業者からの変更指示書を提供してください。また、その指示内容を詳しく説明してください。"
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
+
"question": "原薬メーカーで実施された安定性試験の結果を入手できますか?また、その結果の詳細を共有してください。"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"item": "原料メーカーから均一性の評価結果を入手できるか",
|
14 |
+
"question": "原薬メーカーの均一性の評価結果を入手できますか?また、その結果の詳細を共有してください。"
|
15 |
},
|
16 |
{
|
17 |
"item": "原料試験による評価の実施",
|
18 |
+
"question": "変更後の原薬に対して、どのような試験を実施予定ですか?試験の種類とその基準を説明してください。"
|
19 |
},
|
20 |
{
|
21 |
"item": "試作品による評価の実施",
|
22 |
+
"question": "変更後の原薬を使用した試作品による評価は実施しますか?その評価方法と予定される試験項目について説明してください。"
|
23 |
},
|
24 |
{
|
25 |
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
|
|
39 |
},
|
40 |
{
|
41 |
"item": "原料メーカーと取り決めを結んでいるか",
|
42 |
+
"question": "新しい原薬メーカーとの間で、品質や供給に関する取り決めを行いましたか?その取り決めの内容を具体的に説明してください。"
|
43 |
},
|
44 |
{
|
45 |
"item": "供給者監査(新規メーカー)を実施しているか",
|
46 |
+
"question": "新規の原薬メーカーに対して供給者監査を実施しましたか?実施した場合、その監査結果を共有してください。"
|
47 |
},
|
48 |
{
|
49 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
50 |
+
"question": "現行の原薬から新しい原薬への切替方法は確認しましたか?自然切替で対応可能ですか、それとも別の手順が必要ですか?"
|
51 |
+
},
|
52 |
+
{
|
53 |
+
"item": "全梱包確認試験の実施の有無",
|
54 |
+
"question": "全梱包確認試験は実地されましたか?詳しい内容を説明してください。"
|
55 |
+
},
|
56 |
+
{
|
57 |
+
"item": "追加",
|
58 |
+
"question": "承認書の変更(一部変更承認申請/軽微変更届)の要否について、製造販売業者に確認しましたか。また、変更にあたっての内容及びスケジュールは調整済みですか?"
|
59 |
}
|
60 |
]
|
61 |
}
|
data/questions/原薬_製造方法_x.json
CHANGED
@@ -3,15 +3,19 @@
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
-
"question": "
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
-
"question": "
|
|
|
|
|
|
|
|
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
-
"question": "
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
|
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
6 |
+
"question": "原薬メーカー又は製造販売業者からの変更指示書を提供できますか?"
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
+
"question": "原薬メーカーで行われた安定性試験の結果を入手できますか?結果の詳細を共有してください。"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"item": "原料メーカーから均一性の評価結果を入手できるか",
|
14 |
+
"question": "原薬メーカーの均一性の評価結果を入手できますか?また、その結果の詳細を共有してください。"
|
15 |
},
|
16 |
{
|
17 |
"item": "原料試験による評価の実施",
|
18 |
+
"question": "変更後の原薬を用いた試験を実施しましたか?その結果はどうでしたか?"
|
19 |
},
|
20 |
{
|
21 |
"item": "試作品による評価の実施",
|
data/questions/原薬_製造設備_x.json
CHANGED
@@ -7,15 +7,19 @@
|
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
-
"question": "
|
|
|
|
|
|
|
|
|
11 |
},
|
12 |
{
|
13 |
"item": "原料試験による評価の実施",
|
14 |
-
"question": "
|
15 |
},
|
16 |
{
|
17 |
"item": "試作品による評価の実施",
|
18 |
-
"question": "
|
19 |
},
|
20 |
{
|
21 |
"item": "原薬情報更新が必要か",
|
@@ -32,6 +36,10 @@
|
|
32 |
{
|
33 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
34 |
"question": "提案された変更を実施するにあたって、自然切替で対応できますか?それとも特別な手順が必要ですか?具体的な切替計画を教えてください。"
|
|
|
|
|
|
|
|
|
35 |
}
|
36 |
]
|
37 |
}
|
|
|
7 |
},
|
8 |
{
|
9 |
"item": "原料メーカーでの安定性試験結果を入手できるか",
|
10 |
+
"question": "原薬メーカーによる安定性試験の結果を提供してください。また、その試験結果の要約を教えてください。"
|
11 |
+
},
|
12 |
+
{
|
13 |
+
"item": "原料メーカーから均一性の評価結果を入手できるか",
|
14 |
+
"question": "原薬メーカーの均一性の評価結果を入手できますか?また、その結果の詳細を共有してください。"
|
15 |
},
|
16 |
{
|
17 |
"item": "原料試験による評価の実施",
|
18 |
+
"question": "変更後の原薬に対してどのような試験を行う予定ですか?試験計画を教えてください。"
|
19 |
},
|
20 |
{
|
21 |
"item": "試作品による評価の実施",
|
22 |
+
"question": "変更後の原薬を使用した試作品の評価はどのように実施しますか?具体的な評価計画を教えてください。"
|
23 |
},
|
24 |
{
|
25 |
"item": "原薬情報更新が必要か",
|
|
|
36 |
{
|
37 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
38 |
"question": "提案された変更を実施するにあたって、自然切替で対応できますか?それとも特別な手順が必要ですか?具体的な切替計画を教えてください。"
|
39 |
+
},
|
40 |
+
{
|
41 |
+
"item": "追加",
|
42 |
+
"question": "承認書の変更(一部変更承認申請/軽微変更届)の要否について、製造販売業者に確認しましたか。"
|
43 |
}
|
44 |
]
|
45 |
}
|
data/questions/原薬_試験規格の変更_x.json
ADDED
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
{
|
3 |
+
"name": "原薬_試験規格の変更_x",
|
4 |
+
"items": [
|
5 |
+
{
|
6 |
+
"item": "原料メーカー又は製造販売業者から変更指示書があるか",
|
7 |
+
"question": "変更を指示する原薬メーカーまたは製造販売業者からの指示書の提供を確認できますか?"
|
8 |
+
},
|
9 |
+
{
|
10 |
+
"item": "原料メーカーから安定性試験結果を入手できるか",
|
11 |
+
"question": "変更後の原薬に関する安定性試験結果を原薬メーカーから入手できますか?"
|
12 |
+
},
|
13 |
+
{
|
14 |
+
"item": "原料メーカーから均一性の評価結果を入手できるか",
|
15 |
+
"question": "変更後の原薬について、原薬メーカーから均一性の評価結果を提供してもらえますか?"
|
16 |
+
},
|
17 |
+
{
|
18 |
+
"item": "メーカーラベルに変更はないか",
|
19 |
+
"question": "この変更によってメーカーラベルに何か変更がありますか?"
|
20 |
+
},
|
21 |
+
{
|
22 |
+
"item": "変更後の試験規格で受入試験ができるか",
|
23 |
+
"question": "変更後の試験規格に基づいた受入試験は、現在の設備と方法で実施可能ですか?"
|
24 |
+
},
|
25 |
+
{
|
26 |
+
"item": "先行サンプル等による評価が必要か",
|
27 |
+
"question": "変更を適用する前に、先行サンプルやその他の材料を用いた評価が必要ですか?"
|
28 |
+
},
|
29 |
+
{
|
30 |
+
"item": "使用期限・品質保証期限又はリテスト期限に変更はないか",
|
31 |
+
"question": "この変更に伴い、使用期限、品質保証期限、またはリテスト期限に変更はありますか?"
|
32 |
+
},
|
33 |
+
{
|
34 |
+
"item": "試作品による評価の実施が必要か",
|
35 |
+
"question": "変更後の原薬を使った試作品による評価が必要ですか?"
|
36 |
+
},
|
37 |
+
{
|
38 |
+
"item": "元素不純物リスクアセスメント結果に変更はないか",
|
39 |
+
"question": "変更により、元素不純物リスクアセスメント結果に変更はありますか?"
|
40 |
+
},
|
41 |
+
{
|
42 |
+
"item": "ニトロソアミン類の混入に関するリスク管理に変わりはないか",
|
43 |
+
"question": "変更により、ニトロソアミン類の混入に関するリスク管理の方針に変更は生じますか?"
|
44 |
+
},
|
45 |
+
{
|
46 |
+
"item": "残留溶媒に関するリスク管理に変わりはないか",
|
47 |
+
"question": "残留溶媒に関するリスク管理に変更はありますか?"
|
48 |
+
},
|
49 |
+
{
|
50 |
+
"item": "切替方法の確認(自然切替で対応可能か)",
|
51 |
+
"question": "この変更を行う際の切替方法は自然切替で対応可能ですか?それとも特別な措置が必要ですか?"
|
52 |
+
},
|
53 |
+
{
|
54 |
+
"item": "追加",
|
55 |
+
"question": "承認書の変更(一部変更承認申請/軽微変更届)の要否について、製造販売業者に確認しましたか。また、変更にあたっての内容及びスケジュールは調整済みですか?"
|
56 |
+
}
|
57 |
+
]
|
58 |
+
}
|
data/questions/添加物_製造メーカー(A社→B社)_x.json
CHANGED
@@ -45,6 +45,10 @@
|
|
45 |
{
|
46 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
47 |
"question": "現在の原料メーカーから新しいメーカーへの切替方法について、自然切替で対応可能ですか?それとも特別な手順が必要ですか?"
|
|
|
|
|
|
|
|
|
48 |
}
|
49 |
]
|
50 |
}
|
|
|
45 |
{
|
46 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
47 |
"question": "現在の原料メーカーから新しいメーカーへの切替方法について、自然切替で対応可能ですか?それとも特別な手順が必要ですか?"
|
48 |
+
},
|
49 |
+
{
|
50 |
+
"item": "全梱包確認試験の実施の有無",
|
51 |
+
"question": "全梱包確認試験は実地されましたか?詳しい内容を説明してください。"
|
52 |
}
|
53 |
]
|
54 |
}
|
data/questions/添加物_製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)_x.json
CHANGED
@@ -24,6 +24,10 @@
|
|
24 |
{
|
25 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
26 |
"question": "この変更を行うにあたっての切替方法を教えてください。自然切替で対応可能ですか、それとも特別な手順が必要ですか?その理由も含めて説明してください。"
|
|
|
|
|
|
|
|
|
27 |
}
|
28 |
]
|
29 |
}
|
|
|
24 |
{
|
25 |
"item": "切替方法の確認(自然切替で対応可能か)",
|
26 |
"question": "この変更を行うにあたっての切替方法を教えてください。自然切替で対応可能ですか、それとも特別な手順が必要ですか?その理由も含めて説明してください。"
|
27 |
+
},
|
28 |
+
{
|
29 |
+
"item": "全梱包確認試験の実施の有無",
|
30 |
+
"question": "全梱包確認試験は実地されましたか?詳しい内容を説明してください。"
|
31 |
}
|
32 |
]
|
33 |
}
|
data/questions/{資材変更_セット箱_製造所の変更.json → 資材変更_セット箱_製造所(メーカー)の変更.json}
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
{
|
2 |
-
"name": "資材変更_セット箱_
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "包装工程のテストが必要か",
|
|
|
1 |
{
|
2 |
+
"name": "資材変更_セット箱_製造所(メーカー)の変更",
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "包装工程のテストが必要か",
|
data/questions/{資材変更_チューブ・容器キャップ(直接容器)_形状変更.json → 資材変更_チューブ・容器キャップ(直接容器)_形状(金型・グレード)変更.json}
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
{
|
2 |
-
"name": "資材変更_チューブ・容器キャップ(直接容器)_
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
|
|
1 |
{
|
2 |
+
"name": "資材変更_チューブ・容器キャップ(直接容器)_形状(金型・グレード)変更",
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
data/questions/{資材変更_チューブ・容器キャップ(直接容器)_製造所の変更.json → 資材変更_チューブ・容器キャップ(直接容器)_製造所(メーカー)の変更.json}
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
{
|
2 |
-
"name": "資材変更_チューブ・容器キャップ(直接容器)_
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
|
|
1 |
{
|
2 |
+
"name": "資材変更_チューブ・容器キャップ(直接容器)_製造所(メーカー)の変更",
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
data/questions/{資材変更_個箱_製造所の変更.json → 資材変更_個箱_製造所(メーカー)の変更.json}
RENAMED
@@ -1,5 +1,5 @@
|
|
1 |
{
|
2 |
-
"name": "資材変更_個箱_
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
|
|
1 |
{
|
2 |
+
"name": "資材変更_個箱_製造所(メーカー)の変更",
|
3 |
"items": [
|
4 |
{
|
5 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
data/questions/{資材変更_添付文書_製造所の変更.json → 資材変更_添付文書_製造所(メーカー)の変更.json}
RENAMED
@@ -1,6 +1,6 @@
|
|
1 |
|
2 |
{
|
3 |
-
"name": "資材変更_添付文書_
|
4 |
"items": [
|
5 |
{
|
6 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
|
|
1 |
|
2 |
{
|
3 |
+
"name": "資材変更_添付文書_製造所(メーカー)の変更",
|
4 |
"items": [
|
5 |
{
|
6 |
"item": "資材メーカー又は製造販売業者から変更指示書があるか",
|
data/template/template.docx
ADDED
Binary file (31.8 kB). View file
|
|
data/template/template_deviation.docx
ADDED
Binary file (29.8 kB). View file
|
|
data/{template_deviation.docx → template/template_deviation_occurrence.docx}
RENAMED
File without changes
|
data/template_12.docx
DELETED
Binary file (31.9 kB)
|
|
data/template_3.docx
DELETED
Binary file (31.2 kB)
|
|
data/template_4.docx
DELETED
Binary file (31 kB)
|
|
data/template_base.docx
DELETED
Binary file (28.7 kB)
|
|
main.py
CHANGED
@@ -1,14 +1,21 @@
|
|
1 |
import streamlit as st
|
2 |
|
3 |
from src.embed_output import main as embed_output
|
4 |
-
from src.
|
|
|
|
|
5 |
|
6 |
pages = {
|
7 |
"変更申請書": change_request_form,
|
8 |
-
|
|
|
9 |
}
|
10 |
|
11 |
-
selected_page = st.sidebar.selectbox(
|
12 |
-
|
13 |
-
|
14 |
-
pages[
|
|
|
|
|
|
|
|
|
|
1 |
import streamlit as st
|
2 |
|
3 |
from src.embed_output import main as embed_output
|
4 |
+
from src.embed_output_deviation import main as embed_output_deviation
|
5 |
+
from src.embed_output_deviation_occurrence import main as embed_output_deviation_occurrence
|
6 |
+
from src.forms import change_request_form, deviation_occurrence_report_form, deviation_report_form
|
7 |
|
8 |
pages = {
|
9 |
"変更申請書": change_request_form,
|
10 |
+
"逸脱発生報告書": deviation_occurrence_report_form,
|
11 |
+
"逸脱報告書": deviation_report_form,
|
12 |
}
|
13 |
|
14 |
+
selected_page = st.sidebar.selectbox("作成する文書を選択してください。", list(pages.keys()))
|
15 |
+
match selected_page:
|
16 |
+
case "変更申請書":
|
17 |
+
pages["変更申請書"](embed_output)
|
18 |
+
case "逸脱発生報告書":
|
19 |
+
pages["逸脱発生報告書"](embed_output_deviation_occurrence)
|
20 |
+
case "逸脱報告書":
|
21 |
+
pages["逸脱報告書"](embed_output_deviation)
|
src/embed_output.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1 |
-
from docx import Document
|
2 |
import json
|
3 |
|
|
|
|
|
|
|
4 |
def replace_text_in_paragraphs(paragraphs, replacements):
|
5 |
"""
|
6 |
パラグラフ内のテキストを置き換える
|
@@ -32,24 +34,14 @@ def replace_text_in_docx(template_path, replacements):
|
|
32 |
|
33 |
|
34 |
def main():
|
35 |
-
|
36 |
-
|
37 |
-
|
38 |
-
|
39 |
-
template_path = "data/template_base.docx"
|
40 |
-
with open('data/change_request.json', 'r') as file:
|
41 |
data = json.load(file)
|
42 |
|
43 |
-
|
44 |
-
case "第一・第二工場":
|
45 |
-
template_path = "data/template_12.docx"
|
46 |
-
case "第三工場":
|
47 |
-
template_path = "data/template_3.docx"
|
48 |
-
case "第四工場":
|
49 |
-
template_path = "data/template_4.docx"
|
50 |
-
|
51 |
|
52 |
replacements = {
|
|
|
53 |
"[applicant]": data["申請者"],
|
54 |
"[apply_date]": data["申請日"],
|
55 |
"[subject_to_change]": data["変更対象"],
|
@@ -57,8 +49,8 @@ def main():
|
|
57 |
"[details_of_change]": data["変更内容"],
|
58 |
"[reason_for_change]": data["変更理由"],
|
59 |
"[impact_on_quality]": data["品質への影響"],
|
60 |
-
"[attached_file]"
|
61 |
-
"[supplementary_information]": data["備考"]
|
62 |
}
|
63 |
|
64 |
doc = replace_text_in_docx(template_path, replacements)
|
|
|
|
|
1 |
import json
|
2 |
|
3 |
+
from docx import Document
|
4 |
+
|
5 |
+
|
6 |
def replace_text_in_paragraphs(paragraphs, replacements):
|
7 |
"""
|
8 |
パラグラフ内のテキストを置き換える
|
|
|
34 |
|
35 |
|
36 |
def main():
|
37 |
+
template_path = "data/template/template_base.docx"
|
38 |
+
with open("data/change_request.json", "r") as file:
|
|
|
|
|
|
|
|
|
39 |
data = json.load(file)
|
40 |
|
41 |
+
template_path = "data/template/template.docx"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
42 |
|
43 |
replacements = {
|
44 |
+
"[plant]": data["工場"],
|
45 |
"[applicant]": data["申請者"],
|
46 |
"[apply_date]": data["申請日"],
|
47 |
"[subject_to_change]": data["変更対象"],
|
|
|
49 |
"[details_of_change]": data["変更内容"],
|
50 |
"[reason_for_change]": data["変更理由"],
|
51 |
"[impact_on_quality]": data["品質への影響"],
|
52 |
+
"[attached_file]": data["添付資料"],
|
53 |
+
"[supplementary_information]": data["備考"],
|
54 |
}
|
55 |
|
56 |
doc = replace_text_in_docx(template_path, replacements)
|
src/embed_output_deviation.py
CHANGED
@@ -1,6 +1,7 @@
|
|
1 |
-
from docx import Document
|
2 |
import json
|
3 |
|
|
|
|
|
4 |
|
5 |
def replace_text_in_paragraphs(paragraphs, replacements):
|
6 |
"""
|
@@ -33,21 +34,27 @@ def replace_text_in_docx(template_path, replacements):
|
|
33 |
|
34 |
|
35 |
def main():
|
36 |
-
|
37 |
-
# ここをJSONから読み込むように変更する
|
38 |
-
|
39 |
-
template_path = "data/template_deviation.docx"
|
40 |
|
41 |
with open("data/deviation_report.json", "r") as file:
|
42 |
data = json.load(file)
|
43 |
|
44 |
-
if data["
|
45 |
-
|
46 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
47 |
attached_file = ""
|
48 |
else:
|
49 |
-
|
50 |
-
|
51 |
attached_file = data["添付資料"]
|
52 |
|
53 |
replacements = {
|
@@ -57,13 +64,16 @@ def main():
|
|
57 |
"[lot_number]": data["ロットNo."],
|
58 |
"[occurrence_datetime]": data["発生日時"],
|
59 |
"[occurrence_place]": data["発生場所"],
|
60 |
-
"[discoverer_name]": data["発見者"],
|
61 |
-
"[worker_name]": data["作業者"],
|
62 |
"[deviation_discovery]": data["逸脱内容・発見の経緯"],
|
63 |
"[first_aid_reason]": data["応急処置・処置の理由"],
|
64 |
-
"[impact_on_quality]": data["
|
65 |
-
"[
|
66 |
-
"[
|
|
|
|
|
|
|
|
|
|
|
67 |
"[attached_file]": attached_file,
|
68 |
"[supplementary_information]": data["備考"],
|
69 |
}
|
|
|
|
|
1 |
import json
|
2 |
|
3 |
+
from docx import Document
|
4 |
+
|
5 |
|
6 |
def replace_text_in_paragraphs(paragraphs, replacements):
|
7 |
"""
|
|
|
34 |
|
35 |
|
36 |
def main():
|
37 |
+
template_path = "data/template/template_deviation.docx"
|
|
|
|
|
|
|
38 |
|
39 |
with open("data/deviation_report.json", "r") as file:
|
40 |
data = json.load(file)
|
41 |
|
42 |
+
if data["出荷の制限"] == "なし":
|
43 |
+
yes_sr = "□"
|
44 |
+
no_sr = "☑"
|
45 |
+
shipping_restriction = ""
|
46 |
+
else:
|
47 |
+
yes_sr = "☑"
|
48 |
+
no_sr = "□"
|
49 |
+
shipping_restriction = data["出荷の制限"]
|
50 |
+
|
51 |
+
if data["添付資料"] == "なし":
|
52 |
+
yes_af = "□"
|
53 |
+
no_af = "☑"
|
54 |
attached_file = ""
|
55 |
else:
|
56 |
+
yes_af = "☑"
|
57 |
+
no_af = "□"
|
58 |
attached_file = data["添付資料"]
|
59 |
|
60 |
replacements = {
|
|
|
64 |
"[lot_number]": data["ロットNo."],
|
65 |
"[occurrence_datetime]": data["発生日時"],
|
66 |
"[occurrence_place]": data["発生場所"],
|
|
|
|
|
67 |
"[deviation_discovery]": data["逸脱内容・発見の経緯"],
|
68 |
"[first_aid_reason]": data["応急処置・処置の理由"],
|
69 |
+
"[impact_on_quality]": data["品質への影響の調査結果"],
|
70 |
+
"[cause_investigation]": data["原因調査結果"],
|
71 |
+
"[corrective_preventive_measures]": data["是正措置・予防措置"],
|
72 |
+
"[yes_sr]": yes_sr,
|
73 |
+
"[no_sr]": no_sr,
|
74 |
+
"[shipping_restriction]": shipping_restriction,
|
75 |
+
"[yes_af]": yes_af,
|
76 |
+
"[no_af]": no_af,
|
77 |
"[attached_file]": attached_file,
|
78 |
"[supplementary_information]": data["備考"],
|
79 |
}
|
src/embed_output_deviation_occurrence.py
ADDED
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import json
|
2 |
+
|
3 |
+
from docx import Document
|
4 |
+
|
5 |
+
|
6 |
+
def replace_text_in_paragraphs(paragraphs, replacements):
|
7 |
+
"""
|
8 |
+
パラグラフ内のテキストを置き換える
|
9 |
+
"""
|
10 |
+
for paragraph in paragraphs:
|
11 |
+
for key, value in replacements.items():
|
12 |
+
if key in paragraph.text:
|
13 |
+
paragraph.text = paragraph.text.replace(key, value)
|
14 |
+
|
15 |
+
|
16 |
+
def replace_text_in_tables(tables, replacements):
|
17 |
+
"""
|
18 |
+
テーブル内のテキストを置き換える
|
19 |
+
"""
|
20 |
+
for table in tables:
|
21 |
+
for row in table.rows:
|
22 |
+
for cell in row.cells:
|
23 |
+
replace_text_in_paragraphs(cell.paragraphs, replacements)
|
24 |
+
|
25 |
+
|
26 |
+
def replace_text_in_docx(template_path, replacements):
|
27 |
+
"""
|
28 |
+
ドキュメント内の指定されたテキストを置き換える
|
29 |
+
"""
|
30 |
+
doc = Document(template_path)
|
31 |
+
replace_text_in_paragraphs(doc.paragraphs, replacements)
|
32 |
+
replace_text_in_tables(doc.tables, replacements)
|
33 |
+
return doc
|
34 |
+
|
35 |
+
|
36 |
+
def main():
|
37 |
+
template_path = "data/template/template_deviation_occurrence.docx"
|
38 |
+
|
39 |
+
with open("data/deviation_occurrence_report.json", "r") as file:
|
40 |
+
data = json.load(file)
|
41 |
+
|
42 |
+
if data["添付資料"] == "なし":
|
43 |
+
yes = "□"
|
44 |
+
no = "☑"
|
45 |
+
attached_file = ""
|
46 |
+
else:
|
47 |
+
yes = "☑"
|
48 |
+
no = "□"
|
49 |
+
attached_file = data["添付資料"]
|
50 |
+
|
51 |
+
replacements = {
|
52 |
+
"[reporter_name]": data["報告者"],
|
53 |
+
"[report_date]": data["報告日"],
|
54 |
+
"[product_name]": data["品名"],
|
55 |
+
"[lot_number]": data["ロットNo."],
|
56 |
+
"[occurrence_datetime]": data["発生日時"],
|
57 |
+
"[occurrence_place]": data["発生場所"],
|
58 |
+
"[discoverer_name]": data["発見者"],
|
59 |
+
"[worker_name]": data["作業者"],
|
60 |
+
"[deviation_discovery]": data["逸脱内容・発見の経緯"],
|
61 |
+
"[first_aid_reason]": data["応急処置・処置の理由"],
|
62 |
+
"[impact_on_quality]": data["品質への影響の調査状況"],
|
63 |
+
"[yes]": yes,
|
64 |
+
"[no]": no,
|
65 |
+
"[attached_file]": attached_file,
|
66 |
+
"[supplementary_information]": data["備考"],
|
67 |
+
}
|
68 |
+
|
69 |
+
doc = replace_text_in_docx(template_path, replacements)
|
70 |
+
output_path = "data/output_deviation_occurrence.docx"
|
71 |
+
doc.save(output_path)
|
72 |
+
print(f"Document saved to {output_path}")
|
73 |
+
|
74 |
+
|
75 |
+
if __name__ == "__main__":
|
76 |
+
main()
|
src/forms.py
CHANGED
@@ -7,11 +7,13 @@ from openai import OpenAI
|
|
7 |
from pinecone import Pinecone
|
8 |
|
9 |
from src.prompts import (
|
|
|
|
|
|
|
10 |
system_template_review,
|
11 |
systemprompt_template_1,
|
12 |
systemprompt_template_2,
|
13 |
systemprompt_template_3,
|
14 |
-
user_template_review,
|
15 |
)
|
16 |
from src.questions import get_questions
|
17 |
from src.utils import get_embedding, load_env_vars
|
@@ -38,6 +40,7 @@ SUBTYPES = {
|
|
38 |
"製造方法",
|
39 |
"製造所(A社→B社)",
|
40 |
"製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)",
|
|
|
41 |
],
|
42 |
"添加物": [
|
43 |
"",
|
@@ -89,9 +92,9 @@ SUBTYPES2 = {
|
|
89 |
("資材変更", "チューブ・容器キャップ(直接容器)"): [
|
90 |
"",
|
91 |
"製造設備の変更",
|
92 |
-
"
|
93 |
"材質の変更",
|
94 |
-
"
|
95 |
"版番号の変更",
|
96 |
],
|
97 |
("資材変更", "容器ラベル"): [
|
@@ -101,14 +104,14 @@ SUBTYPES2 = {
|
|
101 |
],
|
102 |
("資材変更", "添付文書"): [
|
103 |
"",
|
104 |
-
"
|
105 |
"材質変更",
|
106 |
"厚さ変更",
|
107 |
"版番号の変更",
|
108 |
],
|
109 |
("資材変更", "個箱"): [
|
110 |
"",
|
111 |
-
"
|
112 |
"捺印位置の変更",
|
113 |
"個箱形状変更",
|
114 |
"個箱の材質(表面加工)",
|
@@ -117,7 +120,7 @@ SUBTYPES2 = {
|
|
117 |
],
|
118 |
("資材変更", "セット箱"): [
|
119 |
"",
|
120 |
-
"
|
121 |
"捺印位置の変更",
|
122 |
"セット箱形状変更",
|
123 |
"版番号の変更",
|
@@ -149,9 +152,7 @@ def change_request_form(embed_output):
|
|
149 |
with st.form("my_form"):
|
150 |
col1, col2 = st.columns(2)
|
151 |
with col1:
|
152 |
-
plant_type = st.selectbox(
|
153 |
-
"工場", ["", "第一・第二工場", "第三工場", "第四工場"]
|
154 |
-
)
|
155 |
with col2:
|
156 |
applicant_name = st.text_input("申請者")
|
157 |
|
@@ -161,9 +162,7 @@ def change_request_form(embed_output):
|
|
161 |
with col2_2:
|
162 |
application_date = st.date_input("申請日", date.today())
|
163 |
|
164 |
-
change_details = st.text_area(
|
165 |
-
"変更対象 (変更対象となる製品名・原料名・設備名等を記入する)"
|
166 |
-
)
|
167 |
implementation_date = st.text_area("実施予定時期")
|
168 |
|
169 |
moveon_button = st.form_submit_button("進む")
|
@@ -186,7 +185,7 @@ def change_request_form(embed_output):
|
|
186 |
subtypes2 = [None] * change_num
|
187 |
|
188 |
if st.session_state["form_submitted"]:
|
189 |
-
st.session_state[
|
190 |
|
191 |
for change in range(change_num):
|
192 |
if st.session_state[f"subtype_chosen_{change-1}"]:
|
@@ -206,27 +205,21 @@ def change_request_form(embed_output):
|
|
206 |
SUBTYPES.get(types[change], [""]),
|
207 |
key=f"subtype_{change}",
|
208 |
)
|
209 |
-
if subtypes[change] in SUBTYPES2.get(
|
210 |
-
(types[change], subtypes[change]), []
|
211 |
-
):
|
212 |
subtypes2[change] = st.selectbox(
|
213 |
"詳しい内容を選択してください:",
|
214 |
SUBTYPES2[(types[change], subtypes[change])],
|
215 |
key=f"subtype2_{change}",
|
216 |
)
|
217 |
|
218 |
-
if subtypes[change] and (
|
219 |
-
subtypes2[change] or subtypes2[change] is None
|
220 |
-
):
|
221 |
st.session_state[f"subtype_chosen_{change}"] = True
|
222 |
|
223 |
if st.session_state[f"subtype_chosen_{change_num-1}"]:
|
224 |
q = []
|
225 |
|
226 |
for change in range(change_num):
|
227 |
-
q.append(
|
228 |
-
f"Q{change+1}-1 : 今回の変更内容を教えて下さい。変更前と変更後の両方を明記してください。"
|
229 |
-
)
|
230 |
q.append(f"Q{change+1}-2 : 今回の変更を行う理由を教えて下さい。")
|
231 |
|
232 |
qs = get_questions(types[change], subtypes[change], subtypes2[change])
|
@@ -244,22 +237,22 @@ def change_request_form(embed_output):
|
|
244 |
input_values = [None] * question_num
|
245 |
nos = [None] * question_num
|
246 |
qs_now = 1
|
247 |
-
st.markdown(
|
248 |
for k in range(question_num):
|
249 |
if int(q[k][1]) != qs_now:
|
250 |
st.markdown(f"**{qs_now+1}つ目の変更について**")
|
251 |
qs_now += 1
|
252 |
input_values[k] = st.text_area(q[k], key=f"input_1_{k}")
|
253 |
-
nos[k] = st.checkbox(
|
254 |
st.write("\n")
|
255 |
st.markdown("***")
|
256 |
supplementary_information = st.text_area(
|
257 |
f"Q{change_num+1} : 備考があれば記入してください。",
|
258 |
-
key=
|
259 |
)
|
260 |
attached_files = st.text_area(
|
261 |
f"Q{change_num+2} : 添付資料名を記入してください。",
|
262 |
-
key=
|
263 |
)
|
264 |
submitted = st.form_submit_button("送信")
|
265 |
|
@@ -268,11 +261,7 @@ def change_request_form(embed_output):
|
|
268 |
if nos[k]:
|
269 |
input_values[k] = "特になし"
|
270 |
|
271 |
-
system_prompt =
|
272 |
-
system_template_review
|
273 |
-
+ systemprompt_template_1
|
274 |
-
+ systemprompt_template_2
|
275 |
-
)
|
276 |
for k in range(question_num):
|
277 |
system_prompt += f" {q[k]} : {input_values[k]}\n"
|
278 |
system_prompt += systemprompt_template_3
|
@@ -288,7 +277,7 @@ def change_request_form(embed_output):
|
|
288 |
{"role": "system", "content": system_prompt},
|
289 |
{"role": "user", "content": user_prompt},
|
290 |
],
|
291 |
-
response_format="json_object",
|
292 |
temperature=0.0,
|
293 |
)
|
294 |
response_text = response.choices[0].message.content
|
@@ -367,11 +356,22 @@ def change_request_form(embed_output):
|
|
367 |
)
|
368 |
reasons = [r["metadata"]["change_reason"] for r in res["matches"]]
|
369 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
370 |
system = system_template_review
|
371 |
|
372 |
-
user = user_template_review.format(
|
373 |
-
reasons=reasons, query_content=query_content, query_reason=query_reason
|
374 |
-
)
|
375 |
|
376 |
completion = client.chat.completions.create(
|
377 |
model="gpt-4o",
|
@@ -383,3 +383,411 @@ def change_request_form(embed_output):
|
|
383 |
)
|
384 |
review = completion.choices[0].message.content
|
385 |
st.markdown(f"**レビュー結果** : {review}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7 |
from pinecone import Pinecone
|
8 |
|
9 |
from src.prompts import (
|
10 |
+
deviation_occurrence_system_template_review,
|
11 |
+
deviation_occurrence_systemprompt_template_1,
|
12 |
+
deviation_occurrence_systemprompt_template_2,
|
13 |
system_template_review,
|
14 |
systemprompt_template_1,
|
15 |
systemprompt_template_2,
|
16 |
systemprompt_template_3,
|
|
|
17 |
)
|
18 |
from src.questions import get_questions
|
19 |
from src.utils import get_embedding, load_env_vars
|
|
|
40 |
"製造方法",
|
41 |
"製造所(A社→B社)",
|
42 |
"製造場所(製造メーカーに変更はない。A社の①工場→A社の②工場)",
|
43 |
+
"試験規格の変更",
|
44 |
],
|
45 |
"添加物": [
|
46 |
"",
|
|
|
92 |
("資材変更", "チューブ・容器キャップ(直接容器)"): [
|
93 |
"",
|
94 |
"製造設備の変更",
|
95 |
+
"製造所(メーカー)の変更",
|
96 |
"材質の変更",
|
97 |
+
"形状(金型・グレード)変更",
|
98 |
"版番号の変更",
|
99 |
],
|
100 |
("資材変更", "容器ラベル"): [
|
|
|
104 |
],
|
105 |
("資材変更", "添付文書"): [
|
106 |
"",
|
107 |
+
"製造所(メーカー)の変更",
|
108 |
"材質変更",
|
109 |
"厚さ変更",
|
110 |
"版番号の変更",
|
111 |
],
|
112 |
("資材変更", "個箱"): [
|
113 |
"",
|
114 |
+
"製造所(メーカー)の変更",
|
115 |
"捺印位置の変更",
|
116 |
"個箱形状変更",
|
117 |
"個箱の材質(表面加工)",
|
|
|
120 |
],
|
121 |
("資材変更", "セット箱"): [
|
122 |
"",
|
123 |
+
"製造所(メーカー)の変更",
|
124 |
"捺印位置の変更",
|
125 |
"セット箱形状変更",
|
126 |
"版番号の変更",
|
|
|
152 |
with st.form("my_form"):
|
153 |
col1, col2 = st.columns(2)
|
154 |
with col1:
|
155 |
+
plant_type = st.selectbox("工場", ["", "第一・第二工場", "第三工場", "第四工場"])
|
|
|
|
|
156 |
with col2:
|
157 |
applicant_name = st.text_input("申請者")
|
158 |
|
|
|
162 |
with col2_2:
|
163 |
application_date = st.date_input("申請日", date.today())
|
164 |
|
165 |
+
change_details = st.text_area("変更対象 (変更対象となる製品名・原料名・設備名等を記入する)")
|
|
|
|
|
166 |
implementation_date = st.text_area("実施予定時期")
|
167 |
|
168 |
moveon_button = st.form_submit_button("進む")
|
|
|
185 |
subtypes2 = [None] * change_num
|
186 |
|
187 |
if st.session_state["form_submitted"]:
|
188 |
+
st.session_state["subtype_chosen_-1"] = True
|
189 |
|
190 |
for change in range(change_num):
|
191 |
if st.session_state[f"subtype_chosen_{change-1}"]:
|
|
|
205 |
SUBTYPES.get(types[change], [""]),
|
206 |
key=f"subtype_{change}",
|
207 |
)
|
208 |
+
if subtypes[change] in SUBTYPES2.get((types[change], subtypes[change]), []):
|
|
|
|
|
209 |
subtypes2[change] = st.selectbox(
|
210 |
"詳しい内容を選択してください:",
|
211 |
SUBTYPES2[(types[change], subtypes[change])],
|
212 |
key=f"subtype2_{change}",
|
213 |
)
|
214 |
|
215 |
+
if subtypes[change] and (subtypes2[change] or subtypes2[change] is None):
|
|
|
|
|
216 |
st.session_state[f"subtype_chosen_{change}"] = True
|
217 |
|
218 |
if st.session_state[f"subtype_chosen_{change_num-1}"]:
|
219 |
q = []
|
220 |
|
221 |
for change in range(change_num):
|
222 |
+
q.append(f"Q{change+1}-1 : 今回の変更内容を教えて下さい。変更前と変更後の両方を明記してください。")
|
|
|
|
|
223 |
q.append(f"Q{change+1}-2 : 今回の変更を行う理由を教えて下さい。")
|
224 |
|
225 |
qs = get_questions(types[change], subtypes[change], subtypes2[change])
|
|
|
237 |
input_values = [None] * question_num
|
238 |
nos = [None] * question_num
|
239 |
qs_now = 1
|
240 |
+
st.markdown("**1つ目の変更について**")
|
241 |
for k in range(question_num):
|
242 |
if int(q[k][1]) != qs_now:
|
243 |
st.markdown(f"**{qs_now+1}つ目の変更について**")
|
244 |
qs_now += 1
|
245 |
input_values[k] = st.text_area(q[k], key=f"input_1_{k}")
|
246 |
+
nos[k] = st.checkbox("特になし", key=f"check_{k}")
|
247 |
st.write("\n")
|
248 |
st.markdown("***")
|
249 |
supplementary_information = st.text_area(
|
250 |
f"Q{change_num+1} : 備考があれば記入してください。",
|
251 |
+
key="supplementary_information_1",
|
252 |
)
|
253 |
attached_files = st.text_area(
|
254 |
f"Q{change_num+2} : 添付資料名を記入してください。",
|
255 |
+
key="attached_files_1",
|
256 |
)
|
257 |
submitted = st.form_submit_button("送信")
|
258 |
|
|
|
261 |
if nos[k]:
|
262 |
input_values[k] = "特になし"
|
263 |
|
264 |
+
system_prompt = system_template_review + systemprompt_template_1 + systemprompt_template_2
|
|
|
|
|
|
|
|
|
265 |
for k in range(question_num):
|
266 |
system_prompt += f" {q[k]} : {input_values[k]}\n"
|
267 |
system_prompt += systemprompt_template_3
|
|
|
277 |
{"role": "system", "content": system_prompt},
|
278 |
{"role": "user", "content": user_prompt},
|
279 |
],
|
280 |
+
response_format={"type": "json_object"},
|
281 |
temperature=0.0,
|
282 |
)
|
283 |
response_text = response.choices[0].message.content
|
|
|
356 |
)
|
357 |
reasons = [r["metadata"]["change_reason"] for r in res["matches"]]
|
358 |
|
359 |
+
user_template_review = f"""
|
360 |
+
## レビュー例:
|
361 |
+
{reasons}
|
362 |
+
|
363 |
+
## 前提知識:
|
364 |
+
{query_content}
|
365 |
+
|
366 |
+
## 変更理由:
|
367 |
+
{query_reason}
|
368 |
+
|
369 |
+
返答:
|
370 |
+
"""
|
371 |
+
|
372 |
system = system_template_review
|
373 |
|
374 |
+
user = user_template_review.format(reasons=reasons, query_content=query_content, query_reason=query_reason)
|
|
|
|
|
375 |
|
376 |
completion = client.chat.completions.create(
|
377 |
model="gpt-4o",
|
|
|
383 |
)
|
384 |
review = completion.choices[0].message.content
|
385 |
st.markdown(f"**レビュー結果** : {review}")
|
386 |
+
|
387 |
+
|
388 |
+
def deviation_occurrence_report_form(embed_output_deviation_occurrence):
|
389 |
+
st.title("逸脱発生報告書 文書生成")
|
390 |
+
|
391 |
+
load_env_vars()
|
392 |
+
open_api_key = os.environ.get("OPENAI_API_KEY")
|
393 |
+
client = OpenAI(api_key=open_api_key)
|
394 |
+
|
395 |
+
for state in ["form_submitted", "document_generated"]:
|
396 |
+
if state not in st.session_state:
|
397 |
+
st.session_state[state] = False
|
398 |
+
|
399 |
+
with st.form("my_form_deviation_occurrence"):
|
400 |
+
col1, col2 = st.columns(2)
|
401 |
+
with col1:
|
402 |
+
reporter_name = st.text_input("報告者")
|
403 |
+
with col2:
|
404 |
+
report_date = st.date_input("報告日", date.today())
|
405 |
+
|
406 |
+
col2_1, col2_2 = st.columns(2)
|
407 |
+
with col2_1:
|
408 |
+
product_name = st.text_input("品名")
|
409 |
+
with col2_2:
|
410 |
+
lot_number = st.text_input("ロットNo.")
|
411 |
+
|
412 |
+
col1, col2, col3 = st.columns([1, 1, 2])
|
413 |
+
with col1:
|
414 |
+
occurrence_date = st.date_input("発生日", date.today())
|
415 |
+
with col2:
|
416 |
+
occurrence_time = st.time_input("発生時間", datetime.now().time())
|
417 |
+
with col3:
|
418 |
+
occurrence_place = st.text_input("発生場所")
|
419 |
+
|
420 |
+
col2_1, col2_2 = st.columns(2)
|
421 |
+
with col2_1:
|
422 |
+
discoverer_name = st.text_input("発見者")
|
423 |
+
with col2_2:
|
424 |
+
worker_name = st.text_input("作業者")
|
425 |
+
|
426 |
+
submit_button0 = st.form_submit_button("進む")
|
427 |
+
if submit_button0:
|
428 |
+
st.session_state["form_submitted"] = True
|
429 |
+
|
430 |
+
if st.session_state["form_submitted"]:
|
431 |
+
q = [
|
432 |
+
"Q1 : 逸脱内容を記入してください。(どの手順・規格から逸脱したのか)",
|
433 |
+
"Q2 : 逸脱の発見の経緯を記入してください。",
|
434 |
+
"Q3 : 応急処置とその処置の理由を記入してください。",
|
435 |
+
"Q4 : 当該ロットの試験実施等による品質評価が必要な場合はその詳しい内容を記入してください。",
|
436 |
+
"Q5 : 安定性モニタリングの対象ロットである、もしくは対象ロットとする場合はその詳しい内容を記入してください。",
|
437 |
+
"Q6 : 安定性モニタリングの検体採取表を更新する場合はその詳しい内容を記入してください",
|
438 |
+
"Q7 : 在庫品の原料・充填資材・包装資材に関して、在庫ロットの品質評価や在庫量・発注状況確認が必要な場合はその詳しい内容を記入してください。",
|
439 |
+
"Q8 : 原料メーカー・資材メーカー・設備メーカーへの調査依頼が必要な場合はその詳しい内容を記入してください",
|
440 |
+
"Q9 : 次回製造ロットの生産スケジュール、受注状況を変更する場合はその詳しい内容を記入して下さい。",
|
441 |
+
"Q10 : 出荷日を変更する場合はその詳しい内容を記入してください。",
|
442 |
+
"Q11 : 製造販売業者への連絡が必要な場合はその詳しい内容を記入してください",
|
443 |
+
"Q12 : 他製品・他ラインへの影響がある場合はその内容を記入してください。",
|
444 |
+
"Q13 : 過去製造ロットの品質の再評価が必要な場合はその詳しい内容を記入してください。",
|
445 |
+
"Q14 : その他の品質への影響があれば記入してください。",
|
446 |
+
]
|
447 |
+
|
448 |
+
q_not = [
|
449 |
+
"",
|
450 |
+
"",
|
451 |
+
"",
|
452 |
+
"品質評価は必要ない",
|
453 |
+
"対象ロットではない(しない)",
|
454 |
+
"更新しない",
|
455 |
+
"評価・確認は必要ない",
|
456 |
+
"依頼は必要ない",
|
457 |
+
"変更しない",
|
458 |
+
"変更しない",
|
459 |
+
"連絡は必要ない",
|
460 |
+
"影響はない",
|
461 |
+
"再評価は必要ない",
|
462 |
+
"なし",
|
463 |
+
]
|
464 |
+
q_num = len(q)
|
465 |
+
|
466 |
+
with st.form(key="my_form2_deviation_occurrence"):
|
467 |
+
input_values = [""] * q_num
|
468 |
+
nos = [None] * q_num
|
469 |
+
for k in range(q_num):
|
470 |
+
input_values[k] = st.text_area(q[k], key=f"input_deviatoin_occurrence_{k}")
|
471 |
+
if k > 2:
|
472 |
+
nos[k] = st.checkbox(f"{q_not[k]}", key=f"check_{k}")
|
473 |
+
st.markdown("***")
|
474 |
+
|
475 |
+
attached_files = st.text_area("Q14 : 添付資料名を記入してください。", key="attached_files_deviation_occurrence")
|
476 |
+
no_attached_file = st.checkbox("添付資料なし", key="check_attached_file")
|
477 |
+
supplementary_information = st.text_area(
|
478 |
+
"Q15 : 備考があれば記入してください。",
|
479 |
+
key="supplementary_information_deviation_occurrence",
|
480 |
+
)
|
481 |
+
no_supplementary_information = st.checkbox("なし", key="check_supplementary_information")
|
482 |
+
submitted = st.form_submit_button("送信")
|
483 |
+
|
484 |
+
if submitted:
|
485 |
+
for i in range(q_num - 3):
|
486 |
+
if nos[i + 2]:
|
487 |
+
input_values[i + 3] = q_not[i + 3]
|
488 |
+
|
489 |
+
if no_attached_file:
|
490 |
+
attached_files = "なし"
|
491 |
+
if no_supplementary_information:
|
492 |
+
supplementary_information = "なし"
|
493 |
+
|
494 |
+
system_prompt = deviation_occurrence_systemprompt_template_1
|
495 |
+
for k in range(q_num):
|
496 |
+
system_prompt += q[k]
|
497 |
+
system_prompt += "\n"
|
498 |
+
system_prompt += deviation_occurrence_systemprompt_template_2
|
499 |
+
|
500 |
+
user_prompt = ""
|
501 |
+
for k in range(q_num):
|
502 |
+
user_prompt += f" A{k+1} : {input_values[k]}"
|
503 |
+
user_prompt += "\n"
|
504 |
+
|
505 |
+
client = OpenAI(api_key=open_api_key)
|
506 |
+
response = client.chat.completions.create(
|
507 |
+
model="gpt-4-0125-preview",
|
508 |
+
messages=[
|
509 |
+
{"role": "system", "content": system_prompt},
|
510 |
+
{"role": "user", "content": user_prompt},
|
511 |
+
],
|
512 |
+
response_format={"type": "json_object"},
|
513 |
+
temperature=0.0,
|
514 |
+
)
|
515 |
+
response_text = response.choices[0].message.content
|
516 |
+
|
517 |
+
response_data = json.loads(response_text)
|
518 |
+
|
519 |
+
report_date = report_date.strftime("%Y年%m月%d日")
|
520 |
+
occurrence_datetime = datetime.combine(occurrence_date, occurrence_time).strftime("%Y年%m月%d日%H時%M分")
|
521 |
+
|
522 |
+
json_data = {
|
523 |
+
"報告者": reporter_name,
|
524 |
+
"報告日": report_date,
|
525 |
+
"品名": product_name,
|
526 |
+
"ロットNo.": lot_number,
|
527 |
+
"発生日時": occurrence_datetime,
|
528 |
+
"発生場所": occurrence_place,
|
529 |
+
"発見者": discoverer_name,
|
530 |
+
"作業者": worker_name,
|
531 |
+
"逸脱内容・発見の経緯": str(response_data["逸脱内容・発見の経緯"]),
|
532 |
+
"応急処置・処置の理由": str(response_data["応急処置・処置の理由"]),
|
533 |
+
"品質への影響の調査状況": str(response_data["品質への影響の調査状況"]),
|
534 |
+
"添付資料": attached_files,
|
535 |
+
"備考": supplementary_information,
|
536 |
+
"ユーザープロンプト": user_prompt,
|
537 |
+
}
|
538 |
+
|
539 |
+
filename = "data/deviation_occurrence_report.json"
|
540 |
+
with open(filename, "w") as file:
|
541 |
+
json.dump(json_data, file, ensure_ascii=False, indent=4)
|
542 |
+
|
543 |
+
embed_output_deviation_occurrence()
|
544 |
+
st.session_state["document_generated"] = True
|
545 |
+
|
546 |
+
if st.session_state["document_generated"]:
|
547 |
+
st.markdown("以下の内容を記入した変更申請書(.docx)を作成しました。")
|
548 |
+
|
549 |
+
with open("data/output_deviation_occurrence.docx", "rb") as file:
|
550 |
+
st.download_button(
|
551 |
+
label="ダウンロード",
|
552 |
+
data=file,
|
553 |
+
file_name="output_deviation_occurrence.docx",
|
554 |
+
mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
555 |
+
)
|
556 |
+
|
557 |
+
with open("data/deviation_occurrence_report.json", "r") as file:
|
558 |
+
json_data = json.load(file)
|
559 |
+
st.markdown(f'**報告者** : {json_data["報告者"]}')
|
560 |
+
st.markdown(f'**報告日** : {json_data["報告日"]}')
|
561 |
+
st.markdown(f'**品名** : {json_data["品名"]}')
|
562 |
+
st.markdown(f'**ロットNo.** : {json_data["ロットNo."]}')
|
563 |
+
st.markdown(f'**発生日時** : {json_data["発生日時"]}')
|
564 |
+
st.markdown(f'**発生場所** : {json_data["発生場所"]}')
|
565 |
+
st.markdown(f'**発見者** : {json_data["発見者"]}')
|
566 |
+
st.markdown(f'**作業者** : {json_data["作業者"]}')
|
567 |
+
st.markdown(f'**逸脱内容・発見の経緯** : {json_data["逸脱内容・発見の経緯"]}')
|
568 |
+
st.markdown(f'**応急処置・処置の理由** : {json_data["応急処置・処置の理由"]}')
|
569 |
+
st.markdown(f'**品質への影響の調査状況** : {json_data["品質への影響の調査状況"]}')
|
570 |
+
st.markdown(f'**添付資料** : {json_data["添付資料"]}')
|
571 |
+
st.markdown(f'**備考** : {json_data["備考"]}')
|
572 |
+
|
573 |
+
deviation_occurrence_user_template_review = f"""
|
574 |
+
## 今回の「逸脱内容・発見の経緯」:
|
575 |
+
{json_data["逸脱内容・発見の経緯"]}
|
576 |
+
|
577 |
+
返答:
|
578 |
+
"""
|
579 |
+
|
580 |
+
review_button = st.button("レビューする")
|
581 |
+
if review_button:
|
582 |
+
completion = client.chat.completions.create(
|
583 |
+
model="gpt-4-0125-preview",
|
584 |
+
messages=[
|
585 |
+
{
|
586 |
+
"role": "system",
|
587 |
+
"content": deviation_occurrence_system_template_review,
|
588 |
+
},
|
589 |
+
{
|
590 |
+
"role": "user",
|
591 |
+
"content": deviation_occurrence_user_template_review,
|
592 |
+
},
|
593 |
+
],
|
594 |
+
temperature=0.7,
|
595 |
+
)
|
596 |
+
review = completion.choices[0].message.content
|
597 |
+
|
598 |
+
st.markdown(f"**レビュー結果** : {review}")
|
599 |
+
|
600 |
+
|
601 |
+
def deviation_report_form(embed_output_deviation):
|
602 |
+
st.title("逸脱報告書 文書生成")
|
603 |
+
|
604 |
+
load_env_vars()
|
605 |
+
open_api_key = os.environ.get("OPENAI_API_KEY")
|
606 |
+
client = OpenAI(api_key=open_api_key)
|
607 |
+
|
608 |
+
for state in ["form_submitted", "document_generated"]:
|
609 |
+
if state not in st.session_state:
|
610 |
+
st.session_state[state] = False
|
611 |
+
|
612 |
+
with st.form("my_form_deviation"):
|
613 |
+
col1, col2 = st.columns(2)
|
614 |
+
with col1:
|
615 |
+
reporter_name = st.text_input("報告者")
|
616 |
+
with col2:
|
617 |
+
report_date = st.date_input("報告日", date.today())
|
618 |
+
|
619 |
+
col2_1, col2_2 = st.columns(2)
|
620 |
+
with col2_1:
|
621 |
+
product_name = st.text_input("品名")
|
622 |
+
with col2_2:
|
623 |
+
lot_number = st.text_input("ロットNo.")
|
624 |
+
|
625 |
+
col1, col2, col3 = st.columns([1, 1, 2])
|
626 |
+
with col1:
|
627 |
+
occurrence_date = st.date_input("発生日", date.today())
|
628 |
+
with col2:
|
629 |
+
occurrence_time = st.time_input("発生時間", datetime.now().time())
|
630 |
+
with col3:
|
631 |
+
occurrence_place = st.text_input("発生場所")
|
632 |
+
|
633 |
+
submit_button0 = st.form_submit_button("進む")
|
634 |
+
if submit_button0:
|
635 |
+
st.session_state["form_submitted"] = True
|
636 |
+
|
637 |
+
if st.session_state["form_submitted"]:
|
638 |
+
q = [
|
639 |
+
"Q1 : 逸脱内容を記入してください。(どの手順・規格から逸脱したのか)",
|
640 |
+
"Q2 : 逸脱の発見の経緯を記入してください。",
|
641 |
+
"Q3 : 応急処置とその処置の理由を記入してください。",
|
642 |
+
"Q4 : 品質への影響の調査結果を記入してください。",
|
643 |
+
"Q5 : 原因調査結果について記入してください",
|
644 |
+
"Q6 : 是正措置について記入してください",
|
645 |
+
"Q7 : 予防措置について記入してください",
|
646 |
+
]
|
647 |
+
|
648 |
+
q_num = len(q)
|
649 |
+
|
650 |
+
with st.form(key="my_form2_deviation"):
|
651 |
+
input_values = [""] * q_num
|
652 |
+
for k in range(q_num):
|
653 |
+
input_values[k] = st.text_area(q[k], key=f"input_deviatoin_{k}")
|
654 |
+
st.markdown("***")
|
655 |
+
|
656 |
+
shipping_restriction = st.text_area(
|
657 |
+
"Q8 : 出荷の制限について記入してください。", key="shipping_restriction_deviation"
|
658 |
+
)
|
659 |
+
no_shipping_restriction = st.checkbox("出荷の制限なし", key="check_shipping_restriction")
|
660 |
+
attached_files = st.text_area("Q9 : 添付資料名を記入してください。", key="attached_files_deviation")
|
661 |
+
no_attached_file = st.checkbox("添付資料なし", key="check_attached_file")
|
662 |
+
supplementary_information = st.text_area(
|
663 |
+
"Q10 : 備考があれば記入してください。",
|
664 |
+
key="supplementary_information_deviation",
|
665 |
+
)
|
666 |
+
no_supplementary_information = st.checkbox("なし", key="check_supplementary_information")
|
667 |
+
submitted = st.form_submit_button("送信")
|
668 |
+
|
669 |
+
if submitted:
|
670 |
+
|
671 |
+
if no_shipping_restriction:
|
672 |
+
shipping_restriction = "なし"
|
673 |
+
if no_attached_file:
|
674 |
+
attached_files = "なし"
|
675 |
+
if no_supplementary_information:
|
676 |
+
supplementary_information = "なし"
|
677 |
+
|
678 |
+
# システムプロンプトを作成する
|
679 |
+
systemprompt_template_1 = """
|
680 |
+
***
|
681 |
+
逸脱内容・発見の経緯:
|
682 |
+
応急処置・処置の理由:
|
683 |
+
品質への影響の調査結果:
|
684 |
+
原因調査結果:
|
685 |
+
是正措置・予防措置:
|
686 |
+
***
|
687 |
+
あなたは、質問に対して入力された情報から、詳しい内容を含んだ逸脱発生報告書の文章を生成するアシスタントです。\n
|
688 |
+
上記の形式に従って、入力された情報を当てはめて出力してください。報告書の読みやすさ、明瞭さ、正確さに注意してください。\n
|
689 |
+
変更や必要がないという回答に関してはは特にそのことを記述する必要はありません。特別な記述があった場合にのみ記述してください。
|
690 |
+
「だ・である」調で出力してください。\n
|
691 |
+
あなたは返答をすべてJSON形式で出力します。\n
|
692 |
+
あなたが質問した内容は以下です。\n
|
693 |
+
***
|
694 |
+
"""
|
695 |
+
|
696 |
+
systemprompt_template_2 = """
|
697 |
+
***
|
698 |
+
出力は以下のjsonテンプレートに従って出力してください。\n
|
699 |
+
{
|
700 |
+
"逸脱内容・発見の経緯":"",
|
701 |
+
"応急処置・処置の理由":"",
|
702 |
+
"品質への影響の調査結果": "",
|
703 |
+
"原因調査結果": "",
|
704 |
+
"是正措置・予防措置": ""
|
705 |
+
}
|
706 |
+
***
|
707 |
+
「です・ます」調ではなく「だ・である」調で出力してください。\n
|
708 |
+
"""
|
709 |
+
|
710 |
+
system_prompt = systemprompt_template_1
|
711 |
+
for k in range(q_num):
|
712 |
+
system_prompt += q[k]
|
713 |
+
system_prompt += "\n"
|
714 |
+
system_prompt += systemprompt_template_2
|
715 |
+
|
716 |
+
# ユーザープロンプトを作成する
|
717 |
+
user_prompt = ""
|
718 |
+
for k in range(q_num):
|
719 |
+
user_prompt += f" A{k+1} : {input_values[k]}"
|
720 |
+
user_prompt += "\n"
|
721 |
+
|
722 |
+
# OpenAIのAPIを使用して応答を生成
|
723 |
+
client = OpenAI(api_key=open_api_key)
|
724 |
+
response = client.chat.completions.create(
|
725 |
+
model="gpt-4-0125-preview",
|
726 |
+
messages=[
|
727 |
+
{"role": "system", "content": system_prompt},
|
728 |
+
{"role": "user", "content": user_prompt},
|
729 |
+
],
|
730 |
+
response_format={"type": "json_object"},
|
731 |
+
temperature=0.0,
|
732 |
+
)
|
733 |
+
response_text = response.choices[0].message.content
|
734 |
+
|
735 |
+
# 応答をjsonに変換
|
736 |
+
response_data = json.loads(response_text)
|
737 |
+
|
738 |
+
report_date = report_date.strftime("%Y年%m月%d日")
|
739 |
+
occurrence_datetime = datetime.combine(occurrence_date, occurrence_time).strftime("%Y年%m月%d日%H時%M分")
|
740 |
+
|
741 |
+
# jsonデータを作成
|
742 |
+
json_data = {
|
743 |
+
"報告者": reporter_name,
|
744 |
+
"報告日": report_date,
|
745 |
+
"品名": product_name,
|
746 |
+
"ロットNo.": lot_number,
|
747 |
+
"発生日時": occurrence_datetime,
|
748 |
+
"発生場所": occurrence_place,
|
749 |
+
"逸脱内容・発見の経緯": str(response_data["逸脱内容・発見の経緯"]),
|
750 |
+
"応急処置・��置の理由": str(response_data["応急処置・処置の理由"]),
|
751 |
+
"品質への影響の調査結果": str(response_data["品質への影響の調査結果"]),
|
752 |
+
"原因調査結果": str(response_data["原因調査結果"]),
|
753 |
+
"是正措置・予防措置": str(response_data["是正措置・予防措置"]),
|
754 |
+
"出荷の制限": shipping_restriction,
|
755 |
+
"添付資料": attached_files,
|
756 |
+
"備考": supplementary_information,
|
757 |
+
"ユーザープロンプト": user_prompt,
|
758 |
+
}
|
759 |
+
|
760 |
+
filename = "data/deviation_report.json"
|
761 |
+
with open(filename, "w") as file:
|
762 |
+
json.dump(json_data, file, ensure_ascii=False, indent=4)
|
763 |
+
|
764 |
+
embed_output_deviation()
|
765 |
+
st.session_state["document_generated"] = True
|
766 |
+
|
767 |
+
if st.session_state["document_generated"]:
|
768 |
+
st.markdown("以下の内容を記入した変更申請書(.docx)を作成しました。")
|
769 |
+
|
770 |
+
with open("data/output_deviation.docx", "rb") as file:
|
771 |
+
st.download_button(
|
772 |
+
label="ダウンロード",
|
773 |
+
data=file,
|
774 |
+
file_name="output_deviation.docx",
|
775 |
+
mime="application/vnd.openxmlformats-officedocument.wordprocessingml.document",
|
776 |
+
)
|
777 |
+
|
778 |
+
with open("data/deviation_report.json", "r") as file:
|
779 |
+
json_data = json.load(file)
|
780 |
+
st.markdown(f'**報告者** : {json_data["報告者"]}')
|
781 |
+
st.markdown(f'**報告日** : {json_data["報告日"]}')
|
782 |
+
st.markdown(f'**品名** : {json_data["品名"]}')
|
783 |
+
st.markdown(f'**ロットNo.** : {json_data["ロットNo."]}')
|
784 |
+
st.markdown(f'**発生日時** : {json_data["発生日時"]}')
|
785 |
+
st.markdown(f'**発生場所** : {json_data["発生場所"]}')
|
786 |
+
st.markdown(f'**逸脱内容・発見の経緯** : {json_data["逸脱内容・発見の経緯"]}')
|
787 |
+
st.markdown(f'**応急処置・処置の理由** : {json_data["応急処置・処置の理由"]}')
|
788 |
+
st.markdown(f'**品質への影響の調査結果** : {json_data["品質への影響の調査結果"]}')
|
789 |
+
st.markdown(f'**原因調査結果** : {json_data["原因調査結果"]}')
|
790 |
+
st.markdown(f'**是正措置・予防措置** : {json_data["是正措置・予防措置"]}')
|
791 |
+
st.markdown(f'**出荷の制限** : {json_data["出荷の制限"]}')
|
792 |
+
st.markdown(f'**添付資料** : {json_data["添付資料"]}')
|
793 |
+
st.markdown(f'**備考** : {json_data["備考"]}')
|
src/prompts.py
CHANGED
@@ -59,7 +59,7 @@ systemprompt_template_3 = """
|
|
59 |
system_template_review = """
|
60 |
あなたは製薬会社の品質管理部門のリーダーです。今回、あなたの部下が作成した変更申請書の内容をレビューすることになりました。
|
61 |
## レビュー例 に示される変更理由の手本に基づいて,以下の'''変更理由'''の修正すべき点を指摘してください.
|
62 |
-
## レビュー例 は正しい変更理由を示しています.その内容を参考にして,以下の'''変更理由'''
|
63 |
ただし改善例を示す必要はありません.
|
64 |
|
65 |
それではステップバイステップで生成していきましょう。
|
@@ -68,13 +68,13 @@ This is very important to my career.
|
|
68 |
## 出力例:
|
69 |
- 例1:
|
70 |
ユーザー:
|
71 |
-
前提知識 :
|
72 |
'充填工程で、現行のノルデンチューブ充填機にJM2チューブ充填機を追加する。
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
|
78 |
'
|
79 |
変更理由 :
|
80 |
'ノルデンチューブ充填機(J-CH5)が故障した為、生産スケジュールの都合上、生産できる充填機を追加する。 '
|
@@ -83,17 +83,17 @@ This is very important to my career.
|
|
83 |
- 故障した充填機について、機番を明記するとともに、『故障』ではなく『不具合』と表現を変更してください。また、部品の取り寄せを依頼している状況や、海外製であるため修理の目処が立たないことも追記が必要です。
|
84 |
- 代替として使用するJM2チューブ充填機についても、機番を明記し、ジルダザック軟膏3%10gと同サイズのチューブホルダーがあることを説明してください。
|
85 |
- さらに、JM2チューブ充填機が国内メーカーであるガデリウスの製品であり、同社が販売と修理を行っていることも追記してください。
|
86 |
-
'
|
87 |
|
|
|
88 |
- 例2:
|
89 |
ユーザー:
|
90 |
-
前提知識 :
|
91 |
'
|
92 |
-
【原料:カルボキシビニルポリマーの変更】
|
93 |
-
変更前:メーカー;住友精化株式会社(岡山大鵬薬品支給)
|
94 |
-
商品名;HV-505HC
|
95 |
-
変更後:メーカー;富士フイルム和光純薬株式会社(万協調達)
|
96 |
-
商品名;ハイビスワコー103
|
97 |
'
|
98 |
変更理由 :
|
99 |
'現行品のカルボキシビニルポリマー(商品名;HV-505HC)が終売となるため。 '
|
@@ -101,13 +101,13 @@ This is very important to my career.
|
|
101 |
'
|
102 |
- 必要十分な情報が記載されています。修正の必要はありません。
|
103 |
'
|
104 |
-
|
105 |
- 例3:
|
106 |
ユーザー:
|
107 |
-
前提知識 :
|
108 |
'
|
109 |
-
製造設備及び仕込み量の変更
|
110 |
-
変更前;1t乳化機1t仕込み もしくは1t乳化機750kg仕込み
|
111 |
変更後;500kg乳化機400kg仕込み
|
112 |
'
|
113 |
変更理由 :
|
@@ -120,15 +120,74 @@ This is very important to my career.
|
|
120 |
'
|
121 |
"""
|
122 |
|
123 |
-
|
124 |
-
|
125 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
126 |
|
127 |
-
##
|
128 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
129 |
|
130 |
-
|
131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
132 |
|
|
|
|
|
|
|
|
|
133 |
返答:
|
|
|
|
|
|
|
|
|
|
|
134 |
"""
|
|
|
59 |
system_template_review = """
|
60 |
あなたは製薬会社の品質管理部門のリーダーです。今回、あなたの部下が作成した変更申請書の内容をレビューすることになりました。
|
61 |
## レビュー例 に示される変更理由の手本に基づいて,以下の'''変更理由'''の修正すべき点を指摘してください.
|
62 |
+
## レビュー例 は正しい変更理由を示しています.その内容を参考にして,以下の'''変更理由'''の修正すべき点を指摘してください。
|
63 |
ただし改善例を示す必要はありません.
|
64 |
|
65 |
それではステップバイステップで生成していきましょう。
|
|
|
68 |
## 出力例:
|
69 |
- 例1:
|
70 |
ユーザー:
|
71 |
+
前提知識 :
|
72 |
'充填工程で、現行のノルデンチューブ充填機にJM2チューブ充填機を追加する。
|
73 |
+
変更前:ノルデンチューブ充填機(J-CH5)
|
74 |
+
ノルデンチューブ充填機(J-CH8)
|
75 |
+
変更後:ノルデンチューブ充填機(J-CH5)
|
76 |
+
ノルデンチューブ充填機(J-CH8)
|
77 |
+
JM2チューブ充填機(J-CH4)
|
78 |
'
|
79 |
変更理由 :
|
80 |
'ノルデンチューブ充填機(J-CH5)が故障した為、生産スケジュールの都合上、生産できる充填機を追加する。 '
|
|
|
83 |
- 故障した充填機について、機番を明記するとともに、『故障』ではなく『不具合』と表現を変更してください。また、部品の取り寄せを依頼している状況や、海外製であるため修理の目処が立たないことも追記が必要です。
|
84 |
- 代替として使用するJM2チューブ充填機についても、機番を明記し、ジルダザック軟膏3%10gと同サイズのチューブホルダーがあることを説明してください。
|
85 |
- さらに、JM2チューブ充填機が国内メーカーであるガデリウスの製品であり、同社が販売と修理を行っていることも追記してください。
|
|
|
86 |
|
87 |
+
|
88 |
- 例2:
|
89 |
ユーザー:
|
90 |
+
前提知識 :
|
91 |
'
|
92 |
+
【原料:カルボキシビニルポリマーの変更】
|
93 |
+
変更前:メーカー;住友精化株式会社(岡山大鵬薬品支給)
|
94 |
+
商品名;HV-505HC
|
95 |
+
変更後:メーカー;富士フイルム和光純薬株式会社(万協調達)
|
96 |
+
商品名;ハイビスワコー103
|
97 |
'
|
98 |
変更理由 :
|
99 |
'現行品のカルボキシビニルポリマー(商品名;HV-505HC)が終売となるため。 '
|
|
|
101 |
'
|
102 |
- 必要十分な情報が記載されています。修正の必要はありません。
|
103 |
'
|
104 |
+
|
105 |
- 例3:
|
106 |
ユーザー:
|
107 |
+
前提知識 :
|
108 |
'
|
109 |
+
製造設備及び仕込み量の変更
|
110 |
+
変更前;1t乳化機1t仕込み もしくは1t乳化機750kg仕込み
|
111 |
変更後;500kg乳化機400kg仕込み
|
112 |
'
|
113 |
変更理由 :
|
|
|
120 |
'
|
121 |
"""
|
122 |
|
123 |
+
deviation_occurrence_systemprompt_template_1 = """
|
124 |
+
***
|
125 |
+
逸脱内容・発見の経緯:
|
126 |
+
応急処置・処置の理由:
|
127 |
+
品質への影響の調査状況:
|
128 |
+
***
|
129 |
+
あなたは、質問に対して入力された情報から、詳しい内容を含んだ逸脱発生報告書の文章を生成するアシスタントです。\n
|
130 |
+
上記の形式に従って、入力された情報を当てはめて出力してください。報告書の読みやすさ、明瞭さ、正確さに注意してください。\n
|
131 |
+
変更や必要がないという回答に関してはは特にそのことを記述する必要はありません。特別な記述があった場合にのみ記述してください。
|
132 |
+
「だ・である」調で出力してくだ���い。\n
|
133 |
+
あなたは返答をすべてJSON形式で出力します。\n
|
134 |
+
あなたが質問した内容は以下です。\n
|
135 |
+
***
|
136 |
+
"""
|
137 |
+
|
138 |
+
deviation_occurrence_systemprompt_template_2 = """
|
139 |
+
***
|
140 |
+
出力は以下のjsonテンプレートに従って出力してください。\n
|
141 |
+
{
|
142 |
+
"逸脱内容・発見の経緯":"",
|
143 |
+
"応急処置・処置の理由":"",
|
144 |
+
"品質への影響の調査状況": "",
|
145 |
+
}
|
146 |
+
***
|
147 |
+
「です・ます」調ではなく「だ・である」調で出力してください。\n
|
148 |
+
"""
|
149 |
+
|
150 |
+
deviation_occurrence_system_template_review = """
|
151 |
+
あなたは製薬会社の品質管理部門のリーダーです。今回、あなたの部下が作成した逸脱発生報告書の内容をレビューすることになりました。
|
152 |
+
## 出力例 を参考にしながら,以下の'''今回の「逸脱内容・発見の経緯」'''の修正すべき点を指摘してください.
|
153 |
+
逸脱の根本原因がしっかりと記載されているかが重要です.
|
154 |
+
ただし改善例を示す必要はありません.
|
155 |
+
|
156 |
+
それではステップバイステップで生成していきましょう。
|
157 |
+
This is very important to my career.
|
158 |
|
159 |
+
## 出力例:
|
160 |
+
- 例1:
|
161 |
+
ユーザー:
|
162 |
+
逸脱内容・発見の経緯 :
|
163 |
+
'インドメタシンゲル製造時、溶解槽①に工程3)で使用する精製水①が投入されていたが、作業者は間違いに気が付かず原料を投入してしまった。その後、指図書の指示内容から大きく逸脱していることに気づいたが原料投入が終わっていた。'
|
164 |
+
返答:
|
165 |
+
'
|
166 |
+
- 作業者の役割と行動を具体的に説明し、どの工程でどのようなミスが発生したかを明確にしてください。
|
167 |
+
- 原料の投入ミスが発覚した具体的な工程や確認方法を記載してください。
|
168 |
+
- 事前投入された精製水①の量を明記し、投入された他の原料の詳細な情報も追加してください。
|
169 |
+
'
|
170 |
|
171 |
+
- 例2:
|
172 |
+
ユーザー:
|
173 |
+
逸脱内容・発見の経緯 :
|
174 |
+
'オイラックスクリーム秤量中、確認者がパラオキシ安息香酸メチルを準備し、秤量作業を行おうとした。その際、ひとつ前に秤量を行ったパラオキシ安息香酸プロピルが秤量台に残っていたため作業者が勘違いし、準備したパラオキシ安息香酸メチルを片付けてしまった。秤量者は秤量が終わっているパラオキシ安息香酸プロピルをパラオキシ安息香酸メチルと思い込み、再度秤量してしまった。'
|
175 |
+
返答:
|
176 |
+
'
|
177 |
+
- 配合成分試験結果について、具体的な数値や試験方法を詳細に記載してください。
|
178 |
+
- ラボエラー及び製造工程の確認方法や、その結果判明した事実を詳細に説明してください。
|
179 |
+
- 逸脱の原因となった在庫量の確認方法や、それに基づく原料の秤量ミスについて具体的に記載してください。
|
180 |
+
- 誤って秤量された原料の量とその理論値についても具体的に記載し、相関性を示してください。
|
181 |
+
'
|
182 |
|
183 |
+
- 例3:
|
184 |
+
ユーザー:
|
185 |
+
逸脱内容・発見の経緯 :
|
186 |
+
'本ロットは、原薬追加のバリデーション対象である。pH試験を3ポイントn=1で実施したところ、pHの規格が6.0以下に対し、①6.16②6.10③6.09と規格を上回った。'
|
187 |
返答:
|
188 |
+
'
|
189 |
+
- バリデーション対象の理由やその背景を詳細に説明してください。
|
190 |
+
- pH試験結果について、各ポイントの具体的な数値と承認規格を明記してください。
|
191 |
+
- 過去の試験結果を比較し、トレンド外の結果について詳細に記載してください。
|
192 |
+
'
|
193 |
"""
|
src/questions.py
CHANGED
@@ -2,11 +2,9 @@ import json
|
|
2 |
|
3 |
|
4 |
def get_questions(type, subtype, subtype2):
|
5 |
-
if subtype2
|
6 |
subtype2 = "x"
|
7 |
-
with open(
|
8 |
-
f"data/questions/{type}_{subtype}_{subtype2}.json", "r", encoding="utf-8"
|
9 |
-
) as file:
|
10 |
data = json.load(file)
|
11 |
|
12 |
questions = [i["question"] for i in data["items"]]
|
|
|
2 |
|
3 |
|
4 |
def get_questions(type, subtype, subtype2):
|
5 |
+
if subtype2 is None:
|
6 |
subtype2 = "x"
|
7 |
+
with open(f"data/questions/{type}_{subtype}_{subtype2}.json", "r", encoding="utf-8") as file:
|
|
|
|
|
8 |
data = json.load(file)
|
9 |
|
10 |
questions = [i["question"] for i in data["items"]]
|