Spaces:
Sleeping
Sleeping
| import gradio as gr | |
| import requests | |
| import json | |
| import os | |
| # === Gemini API 設定(比照你另一個機器人) === | |
| GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") | |
| API_URL = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-2.0-flash:generateContent?key={GEMINI_API_KEY}" | |
| SYSTEM_PROMPT = """ | |
| 【成分人體效應模擬要求】 | |
| 請依據下列科學生理機制,模擬「每一個成分」進入人體後在各系統的可能作用。模型必須基於以下框架逐步推演,而非捏造研究結果: | |
| 1. 吸收(Absorption) | |
| - 以成分的化學性質(極性、溶解性、粒徑、離子化狀態)推估腸胃道吸收率與速率 | |
| - 若為礦物、金屬或無機物質,要明確評估其溶解、解離與吸收途徑 | |
| - 若資料不足,請標示為「資料有限,以下為推測性機轉」 | |
| 2. 分布(Distribution) | |
| - 模擬成分在血液、淋巴系統、肝臟、腎臟、肌肉、脂肪或細胞外液的分布情形 | |
| - 依分子大小/帶電情形推估是否能進入細胞、穿越血腦障壁、或累積於肝腎 | |
| - 若成分能調整腸道菌相,其效應以「微生物代謝物與宿主免疫反應」方式表達 | |
| 3. 代謝(Metabolism) | |
| - 成分是否需要肝臟 Phase I/Phase II 代謝? | |
| - 是否可能抑制/誘導 CYP450(如 CYP3A4、2C19、1A2 等) | |
| - 是否會影響氧化還原反應、自由基清除、炎症訊號? | |
| 4. 排泄(Excretion) | |
| - 評估腎臟、膽汁、糞便途徑 | |
| - 無機成分若不被代謝,需評估體內累積或沉積的可能性。 | |
| 5. 細胞與分子層級作用(Mechanistic Simulation) | |
| 請基於: | |
| - 酸鹼變化 | |
| - 離子交換 | |
| - 膜電位影響 | |
| - 免疫調節(先天/後天免疫) | |
| - 氧化還原反應(ROS / RNS) | |
| - 受體參與或酵素抑制/活化(若已知) | |
| - 微生物代謝副產物與宿主交互作用 | |
| 並模擬可能的: | |
| - 生理效應(如血糖、血壓、腸胃道 Motility) | |
| - 細胞層效應(如 Ca2+ 流動、ROS 下降或上升) | |
| - 免疫系統效應(如促炎/抗炎傾向) | |
| - 內分泌影響 | |
| - 神經系統反應(如交感/副交感調節) | |
| 6. 成分之間的相互作用(Interaction Simulation) | |
| 請評估: | |
| - 化學層面(酸鹼反應、螯合、沉澱、氧化還原) | |
| - 生物層面(共同影響肝臟酵素、腎臟負擔、中樞神經、腸道菌相) | |
| - 功效層面(加乘、拮抗、不相容) | |
| 若屬推測性,請使用「推測性機轉」標記。 | |
| 7. 與用途的匹配度(Mechanism-Utility Match) | |
| - 判斷此配方內的機轉是否真正有助於使用者輸入的用途 | |
| - 若用途與機轉不符,需清楚指出 | |
| - 對整體配方給出「低/中/高」風險與科學合理性評估 | |
| 【重要限制】 | |
| - 不得捏造臨床試驗數據 | |
| - 不得提供劑量建議 | |
| - 所有未知處以「資料有限」標記 | |
| """ | |
| INTRO_MD = """ | |
| # 成分安全性與交互作用評估beta | |
| 輸入主成分、其餘成分、產品類型與預期用途,系統會產生一份簡易的安全性與交互作用報告。 | |
| > 本工具僅提供一般性科學與安全性資訊整理,**不構成醫療診斷或處方建議**。 | |
| """ | |
| def build_prompt(main_ingredient: str, | |
| other_ingredients: str, | |
| product_type: str, | |
| purpose: str) -> str: | |
| user_block = f""" | |
| 主成分:{main_ingredient} | |
| 其餘成分: | |
| {other_ingredients} | |
| 產品類型:{product_type} | |
| 預期用途:{purpose} | |
| 請依照系統提示詞的規範,產生一份結構化的中文報告。 | |
| """ | |
| return SYSTEM_PROMPT.strip() + "\n\n==== 使用者輸入 ====\n" + user_block.strip() | |
| def call_gemini_api(prompt: str) -> str: | |
| if not GEMINI_API_KEY: | |
| return "【設定錯誤】找不到 GEMINI_API_KEY,請在 Hugging Face Space 的 Secrets 中設定。" | |
| headers = {"Content-Type": "application/json"} | |
| data = { | |
| "contents": [ | |
| { | |
| "parts": [ | |
| {"text": prompt} | |
| ] | |
| } | |
| ] | |
| } | |
| try: | |
| resp = requests.post(API_URL, headers=headers, data=json.dumps(data), timeout=60) | |
| except Exception as e: | |
| return f"【網路或連線錯誤】{e}" | |
| if resp.status_code != 200: | |
| return f"【API 錯誤 {resp.status_code}】{resp.text[:500]}" | |
| try: | |
| j = resp.json() | |
| text = j["candidates"][0]["content"]["parts"][0]["text"] | |
| return text.strip() | |
| except Exception as e: | |
| return f"【解析回應失敗】{e}|原始:{resp.text[:500]}" | |
| def analyze_formula(main_ingredient, other_ingredients, product_type, purpose): | |
| if not main_ingredient and not other_ingredients: | |
| return "請至少輸入主成分或其餘成分。" | |
| prompt = build_prompt(main_ingredient, other_ingredients, product_type, purpose) | |
| return call_gemini_api(prompt) | |
| def clear_all(): | |
| # 對應 outputs 的順序:主成分、其餘成分、產品類型、用途、報告 | |
| return "", "", "保健品", "", "(已清空)" | |
| with gr.Blocks(title="成分安全性與交互作用評估") as demo: | |
| gr.Markdown(INTRO_MD) | |
| with gr.Row(): | |
| main_ingredient = gr.Textbox( | |
| label="主成分", | |
| placeholder="例如:富氫碳酸鈣、維生素D3……" | |
| ) | |
| product_type = gr.Radio( | |
| label="產品類型", | |
| choices=["食品", "保健品", "藥品"], | |
| value="保健品", | |
| ) | |
| other_ingredients = gr.Textbox( | |
| label="其餘成分", | |
| lines=4, | |
| placeholder="用逗號或換行分隔,例如:麥芽糊精、硬脂酸鎂、明膠膠囊……" | |
| ) | |
| purpose = gr.Textbox( | |
| label="預期用途", | |
| lines=3, | |
| placeholder="例如:協助入睡、運動後恢復、長期糖尿病患者補充鈣質……" | |
| ) | |
| report = gr.Markdown(label="分析報告") | |
| with gr.Row(): | |
| analyze_btn = gr.Button("分析配方", variant="primary") | |
| clear_btn = gr.Button("清空", variant="secondary") | |
| analyze_btn.click( | |
| fn=analyze_formula, | |
| inputs=[main_ingredient, other_ingredients, product_type, purpose], | |
| outputs=report, | |
| ) | |
| clear_btn.click( | |
| fn=clear_all, | |
| inputs=[], | |
| outputs=[main_ingredient, other_ingredients, product_type, purpose, report], | |
| ) | |
| if __name__ == "__main__": | |
| demo.launch() | |