高橋慧 commited on
Commit
43ddf11
·
1 Parent(s): c33e580

light editon

Browse files
Files changed (4) hide show
  1. README.md +17 -6
  2. app.py +4 -9
  3. app_fixed.py +0 -321
  4. requirements.txt +1 -41
README.md CHANGED
@@ -5,7 +5,7 @@ colorFrom: blue
5
  colorTo: green
6
  sdk: gradio
7
  sdk_version: 4.36.1
8
- app_file: app_fixed.py
9
  pinned: false
10
  license: mit
11
  ---
@@ -14,16 +14,27 @@ license: mit
14
 
15
  このアプリケーションは患者情報に基づいて適切な臨床試験を見つけ、AIエージェントが適格性を自動評価するシステムです。
16
 
 
 
 
 
 
 
 
17
  ## 必要な環境変数
18
 
19
- Spacesの設定で以下の環境変数を設定してください:
20
 
21
- - `GROQ_API_KEY`: GroqのAPIキー
22
  - `OPENAI_API_KEY`: OpenAIのAPIキー(オプション)
23
 
24
  ## 使用方法
25
 
26
  1. 患者の基本情報(年齢、性別、腫瘍タイプ)を入力
27
- 2. 遺伝子変異情報、測定可能腫瘍の有無を入力
28
- 3. 「Generate Clinical Trials Data」をクリック
29
- 4. 結果をフィルタリング・ダウンロード
 
 
 
 
 
5
  colorTo: green
6
  sdk: gradio
7
  sdk_version: 4.36.1
8
+ app_file: app.py
9
  pinned: false
10
  license: mit
11
  ---
 
14
 
15
  このアプリケーションは患者情報に基づいて適切な臨床試験を見つけ、AIエージェントが適格性を自動評価するシステムです。
16
 
17
+ ## 機能
18
+
19
+ - 患者情報入力(年齢、性別、腫瘍タイプ等)
20
+ - 臨床試験データの自動検索
21
+ - AI による適格性評価
22
+ - 結果のフィルタリング・エクスポート
23
+
24
  ## 必要な環境変数
25
 
26
+ **Settings → Variables and secrets** で以下を設定してください:
27
 
28
+ - `GROQ_API_KEY`: GroqのAPIキー(必須)
29
  - `OPENAI_API_KEY`: OpenAIのAPIキー(オプション)
30
 
31
  ## 使用方法
32
 
33
  1. 患者の基本情報(年齢、性別、腫瘍タイプ)を入力
34
+ 2. 遺伝子変異情報、測定可能腫瘍の有無を選択
35
+ 3. 「Generate Sample Data」をクリック
36
+ 4. 結果をフィルタリング(Eligible/Ineligible/Unclear)
37
+
38
+ ## 現在のバージョン
39
+
40
+ これは軽量版です。完全版では実際の臨床試験データベースからリアルタイム検索を行います。
app.py CHANGED
@@ -66,14 +66,15 @@ def filter_dataframe(df, grade):
66
  def create_interface():
67
  missing_vars = check_environment()
68
 
69
- with gr.Blocks(title="臨床試験適格性評価(軽量版)", theme=gr.themes.Soft()) as demo:
70
- gr.Markdown("## 臨床試験適格性評価インターフェース(デバッグ版)")
71
 
72
  # 環境変数状態の表示
73
  if not missing_vars:
74
  gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
75
  else:
76
  gr.Markdown(f"⚠️ **注意**: 環境変数が不足しています: {', '.join(missing_vars)}")
 
77
 
78
  gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Sample Data」をクリックしてください。")
79
 
@@ -151,10 +152,4 @@ def create_interface():
151
  # アプリケーション起動
152
  if __name__ == "__main__":
153
  demo = create_interface()
154
- demo.launch(
155
- server_name="0.0.0.0",
156
- server_port=7860,
157
- share=False,
158
- debug=True,
159
- show_error=True
160
- )
 
66
  def create_interface():
67
  missing_vars = check_environment()
68
 
69
+ with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
70
+ gr.Markdown("## 🏥 臨床試験適格性評価インターフェース")
71
 
72
  # 環境変数状態の表示
73
  if not missing_vars:
74
  gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
75
  else:
76
  gr.Markdown(f"⚠️ **注意**: 環境変数が不足しています: {', '.join(missing_vars)}")
77
+ gr.Markdown("Settings → Variables and secrets で API キーを設定してください")
78
 
79
  gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Sample Data」をクリックしてください。")
80
 
 
152
  # アプリケーション起動
153
  if __name__ == "__main__":
154
  demo = create_interface()
155
+ demo.launch()
 
 
 
 
 
 
app_fixed.py DELETED
@@ -1,321 +0,0 @@
1
- import gradio as gr
2
- import pandas as pd
3
- import time
4
- import traceback
5
- import os
6
- from OpenAITools.FetchTools import fetch_clinical_trials
7
- from langchain_openai import ChatOpenAI
8
- from langchain_groq import ChatGroq
9
- from OpenAITools.CrinicalTrialTools import SimpleClinicalTrialAgent, GraderAgent, LLMTranslator, generate_ex_question_English
10
-
11
- # 環境変数チェック
12
- def check_environment():
13
- """環境変数をチェックし、不足している場合は警告"""
14
- missing_vars = []
15
-
16
- if not os.getenv("GROQ_API_KEY"):
17
- missing_vars.append("GROQ_API_KEY")
18
-
19
- if not os.getenv("OPENAI_API_KEY"):
20
- missing_vars.append("OPENAI_API_KEY")
21
-
22
- if missing_vars:
23
- print(f"⚠️ 環境変数が設定されていません: {', '.join(missing_vars)}")
24
- print("一部の機能が制限される可能性があります。")
25
-
26
- return len(missing_vars) == 0
27
-
28
- # 環境変数チェック実行
29
- env_ok = check_environment()
30
-
31
- # モデルとエージェントの安全な初期化
32
- def safe_init_agents():
33
- """エージェントを安全に初期化"""
34
- try:
35
- groq = ChatGroq(model_name="llama3-70b-8192", temperature=0)
36
- translator = LLMTranslator(groq)
37
- criteria_agent = SimpleClinicalTrialAgent(groq)
38
- grader_agent = GraderAgent(groq)
39
- return translator, criteria_agent, grader_agent
40
- except Exception as e:
41
- print(f"エージェント初期化エラー: {e}")
42
- return None, None, None
43
-
44
- # エージェント初期化
45
- translator, CriteriaCheckAgent, grader_agent = safe_init_agents()
46
-
47
- # エラーハンドリング付きでエージェント評価を実行する関数
48
- def evaluate_with_retry(agent, criteria, question, max_retries=3):
49
- """エラーハンドリング付きでエージェント評価を実行"""
50
- if agent is None:
51
- return "評価エラー: エージェントが初期化されていません。API keyを確認してください。"
52
-
53
- for attempt in range(max_retries):
54
- try:
55
- return agent.evaluate_eligibility(criteria, question)
56
- except Exception as e:
57
- if "missing variables" in str(e):
58
- # プロンプトテンプレートの変数エラーの場合
59
- print(f"プロンプトテンプレートエラー (試行 {attempt + 1}/{max_retries}): {e}")
60
- return "評価エラー: プロンプトテンプレートの設定に問題があります"
61
- elif "no healthy upstream" in str(e) or "InternalServerError" in str(e):
62
- # Groqサーバーエラーの場合
63
- print(f"Groqサーバーエラー (試行 {attempt + 1}/{max_retries}): {e}")
64
- if attempt < max_retries - 1:
65
- time.sleep(2) # 2秒待機してリトライ
66
- continue
67
- else:
68
- return "評価エラー: サーバーに接続できませんでした"
69
- elif "API key" in str(e) or "authentication" in str(e).lower():
70
- return "評価エラー: API keyが無効または設定されていません"
71
- else:
72
- print(f"予期しないエラー (試行 {attempt + 1}/{max_retries}): {e}")
73
- if attempt < max_retries - 1:
74
- time.sleep(1)
75
- continue
76
- else:
77
- return f"評価エラー: {str(e)}"
78
- return "評価エラー: 最大リトライ回数に達しました"
79
-
80
- def evaluate_grade_with_retry(agent, judgment, max_retries=3):
81
- """エラーハンドリング付きでグレード評価を実行"""
82
- if agent is None:
83
- return "unclear"
84
-
85
- for attempt in range(max_retries):
86
- try:
87
- return agent.evaluate_eligibility(judgment)
88
- except Exception as e:
89
- if "no healthy upstream" in str(e) or "InternalServerError" in str(e):
90
- print(f"Groqサーバーエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
91
- if attempt < max_retries - 1:
92
- time.sleep(2)
93
- continue
94
- else:
95
- return "unclear"
96
- elif "API key" in str(e) or "authentication" in str(e).lower():
97
- return "unclear"
98
- else:
99
- print(f"予期しないエラー (グレード評価 - 試行 {attempt + 1}/{max_retries}): {e}")
100
- if attempt < max_retries - 1:
101
- time.sleep(1)
102
- continue
103
- else:
104
- return "unclear"
105
- return "unclear"
106
-
107
- # データフレームを生成する関数
108
- def generate_dataframe(age, sex, tumor_type, GeneMutation, Meseable, Biopsiable):
109
- try:
110
- # 入力検証
111
- if not all([age, sex, tumor_type]):
112
- return pd.DataFrame(), pd.DataFrame()
113
-
114
- # 日本語の腫瘍タイプを英語に翻訳
115
- try:
116
- if translator is not None:
117
- TumorName = translator.translate(tumor_type)
118
- else:
119
- print("翻訳エージェントが利用できません。元の値を使用します。")
120
- TumorName = tumor_type
121
- except Exception as e:
122
- print(f"翻訳エラー: {e}")
123
- TumorName = tumor_type # 翻訳に失敗した場合は元の値を使用
124
-
125
- # 質問文を生成
126
- try:
127
- ex_question = generate_ex_question_English(age, sex, TumorName, GeneMutation, Meseable, Biopsiable)
128
- except Exception as e:
129
- print(f"質問生成エラー: {e}")
130
- return pd.DataFrame(), pd.DataFrame()
131
-
132
- # 臨床試験データの取得
133
- try:
134
- df = fetch_clinical_trials(TumorName)
135
- if df.empty:
136
- print("臨床試験データが見つかりませんでした")
137
- return pd.DataFrame(), pd.DataFrame()
138
- except Exception as e:
139
- print(f"臨床試験データ取得エラー: {e}")
140
- return pd.DataFrame(), pd.DataFrame()
141
-
142
- df['AgentJudgment'] = None
143
- df['AgentGrade'] = None
144
-
145
- # 臨床試験の適格性の評価
146
- NCTIDs = list(df['NCTID'])
147
- progress = gr.Progress(track_tqdm=True)
148
-
149
- for i, nct_id in enumerate(NCTIDs):
150
- try:
151
- target_criteria = df.loc[df['NCTID'] == nct_id, 'Eligibility Criteria'].values[0]
152
-
153
- # エラーハンドリング付きで評価実行
154
- agent_judgment = evaluate_with_retry(CriteriaCheckAgent, target_criteria, ex_question)
155
- agent_grade = evaluate_grade_with_retry(grader_agent, agent_judgment)
156
-
157
- # データフレームの更新
158
- df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = agent_judgment
159
- df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = agent_grade
160
-
161
- except Exception as e:
162
- print(f"NCTID {nct_id} の評価中にエラー: {e}")
163
- df.loc[df['NCTID'] == nct_id, 'AgentJudgment'] = f"エラー: {str(e)}"
164
- df.loc[df['NCTID'] == nct_id, 'AgentGrade'] = "unclear"
165
-
166
- progress((i + 1) / len(NCTIDs))
167
-
168
- # 列を指定した順に並び替え
169
- columns_order = ['NCTID', 'AgentGrade', 'Title', 'AgentJudgment', 'Japanes Locations',
170
- 'Primary Completion Date', 'Cancer', 'Summary', 'Eligibility Criteria']
171
-
172
- # 存在する列のみを選択
173
- available_columns = [col for col in columns_order if col in df.columns]
174
- df = df[available_columns]
175
-
176
- return df, df # フィルタ用と表示用にデータフレームを返す
177
-
178
- except Exception as e:
179
- print(f"データフレーム生成中に予期しないエラー: {e}")
180
- traceback.print_exc()
181
- return pd.DataFrame(), pd.DataFrame()
182
-
183
- # CSVとして保存しダウンロードする関数
184
- def download_filtered_csv(df):
185
- try:
186
- if df is None or len(df) == 0:
187
- return None
188
- file_path = "filtered_data.csv"
189
- df.to_csv(file_path, index=False)
190
- return file_path
191
- except Exception as e:
192
- print(f"CSV保存エラー: {e}")
193
- return None
194
-
195
- # 全体結果をCSVとして保存しダウンロードする関数
196
- def download_full_csv(df):
197
- try:
198
- if df is None or len(df) == 0:
199
- return None
200
- file_path = "full_data.csv"
201
- df.to_csv(file_path, index=False)
202
- return file_path
203
- except Exception as e:
204
- print(f"CSV保存エラー: {e}")
205
- return None
206
-
207
- # Gradioインターフェースの作成
208
- with gr.Blocks(title="臨床試験適格性評価", theme=gr.themes.Soft()) as demo:
209
- gr.Markdown("## 臨床試験適格性評価インターフェース")
210
-
211
- # 環境変数状態の表示
212
- if env_ok:
213
- gr.Markdown("✅ **ステータス**: 全ての環境変数が設定されています")
214
- else:
215
- gr.Markdown("⚠️ **注意**: 一部の環境変数が設定されていません。機能が制限される可能性があります。")
216
-
217
- gr.Markdown("💡 **使用方法**: 患者情報を入力して「Generate Clinical Trials Data」をクリックしてください。")
218
-
219
- # 各種入力フィールド
220
- with gr.Row():
221
- with gr.Column():
222
- age_input = gr.Textbox(label="Age", placeholder="例: 65", value="")
223
- sex_input = gr.Dropdown(choices=["男性", "女性"], label="Sex", value=None)
224
- tumor_type_input = gr.Textbox(label="Tumor Type", placeholder="例: gastric cancer", value="")
225
-
226
- with gr.Column():
227
- gene_mutation_input = gr.Textbox(label="Gene Mutation", placeholder="例: HER2", value="")
228
- measurable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Measurable Tumor", value=None)
229
- biopsiable_input = gr.Dropdown(choices=["有り", "無し", "不明"], label="Biopsiable Tumor", value=None)
230
-
231
- # データフレーム表示エリア(修正版)
232
- dataframe_output = gr.DataFrame(
233
- label="Clinical Trials Results",
234
- interactive=False,
235
- wrap=True
236
- )
237
-
238
- # 内部状態用の非表示コンポーネント
239
- original_df_state = gr.State(value=None)
240
- filtered_df_state = gr.State(value=None)
241
-
242
- # ボタン類
243
- with gr.Row():
244
- generate_button = gr.Button("Generate Clinical Trials Data", variant="primary")
245
-
246
- with gr.Row():
247
- yes_button = gr.Button("Show Eligible Trials", variant="secondary")
248
- no_button = gr.Button("Show Ineligible Trials", variant="secondary")
249
- unclear_button = gr.Button("Show Unclear Trials", variant="secondary")
250
-
251
- with gr.Row():
252
- download_filtered_button = gr.Button("Download Filtered Data")
253
- download_full_button = gr.Button("Download Full Data")
254
-
255
- # ダウンロードファイル
256
- download_filtered_output = gr.File(label="Download Filtered Data", visible=False)
257
- download_full_output = gr.File(label="Download Full Data", visible=False)
258
-
259
- # イベントハンドリング
260
- def update_dataframe_and_state(age, sex, tumor_type, gene_mutation, measurable, biopsiable):
261
- """データフレーム生成と状態更新"""
262
- df, _ = generate_dataframe(age, sex, tumor_type, gene_mutation, measurable, biopsiable)
263
- return df, df, df
264
-
265
- def filter_and_update(original_df, grade):
266
- """フィルタリングと表示更新"""
267
- if original_df is None or len(original_df) == 0:
268
- return original_df, original_df
269
-
270
- try:
271
- df_filtered = original_df[original_df['AgentGrade'] == grade]
272
- return df_filtered, df_filtered
273
- except Exception as e:
274
- print(f"フィルタリングエラー: {e}")
275
- return original_df, original_df
276
-
277
- # ボタン動作の設定
278
- generate_button.click(
279
- fn=update_dataframe_and_state,
280
- inputs=[age_input, sex_input, tumor_type_input, gene_mutation_input, measurable_input, biopsiable_input],
281
- outputs=[dataframe_output, original_df_state, filtered_df_state]
282
- )
283
-
284
- yes_button.click(
285
- fn=lambda df: filter_and_update(df, "yes"),
286
- inputs=[original_df_state],
287
- outputs=[dataframe_output, filtered_df_state]
288
- )
289
-
290
- no_button.click(
291
- fn=lambda df: filter_and_update(df, "no"),
292
- inputs=[original_df_state],
293
- outputs=[dataframe_output, filtered_df_state]
294
- )
295
-
296
- unclear_button.click(
297
- fn=lambda df: filter_and_update(df, "unclear"),
298
- inputs=[original_df_state],
299
- outputs=[dataframe_output, filtered_df_state]
300
- )
301
-
302
- download_filtered_button.click(
303
- fn=download_filtered_csv,
304
- inputs=[filtered_df_state],
305
- outputs=[download_filtered_output]
306
- )
307
-
308
- download_full_button.click(
309
- fn=download_full_csv,
310
- inputs=[original_df_state],
311
- outputs=[download_full_output]
312
- )
313
-
314
- if __name__ == "__main__":
315
- demo.launch(
316
- server_name="0.0.0.0",
317
- server_port=7860,
318
- share=False,
319
- debug=False,
320
- show_error=True
321
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
requirements.txt CHANGED
@@ -1,42 +1,2 @@
1
- # Core web framework (安定バージョンに固定)
2
  gradio==4.36.1
3
-
4
- # Data processing
5
- pandas>=1.5.0
6
- numpy>=1.21.0
7
- requests>=2.25.0
8
-
9
- # LangChain ecosystem (互換性のあるバージョンに調整)
10
- langchain==0.2.16
11
- langchain-community==0.2.16
12
- langchain-core==0.2.38
13
- langchain-openai==0.1.23
14
- langchain-groq==0.1.9
15
- langchain-text-splitters==0.2.4
16
-
17
- # LLM providers
18
- openai>=1.0.0,<2.0.0
19
- groq>=0.4.0
20
-
21
- # Database utilities
22
- SQLAlchemy>=2.0.0,<3.0.0
23
-
24
- # Pydantic (LangChain互換性のため)
25
- pydantic>=2.5.0,<3.0.0
26
-
27
- # Text processing
28
- tiktoken>=0.4.0
29
-
30
- # Utilities
31
- tenacity>=8.0.0
32
- packaging>=23.0.0
33
-
34
- # Bio-related libraries (必要に応じて)
35
- # biopython>=1.83
36
- # bio>=1.7.1
37
- # biothings-client>=0.3.1
38
- # mygene>=3.2.2
39
-
40
- # Optional: Advanced LangChain features
41
- # langchainhub>=0.1.20
42
- # langgraph>=0.2.30
 
 
1
  gradio==4.36.1
2
+ pandas==1.5.3