|
import os |
|
import gradio as gr |
|
from gradio import ChatMessage |
|
from typing import Iterator |
|
import google.generativeai as genai |
|
import time |
|
from datasets import load_dataset |
|
from sentence_transformers import SentenceTransformer, util |
|
|
|
|
|
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") |
|
genai.configure(api_key=GEMINI_API_KEY) |
|
|
|
|
|
model = genai.GenerativeModel("gemini-2.5-flash-preview-04-17") |
|
|
|
|
|
pharmkg_dataset = load_dataset("vinven7/PharmKG") |
|
|
|
|
|
embedding_model = SentenceTransformer('sentence-transformers/all-MiniLM-L6-v2') |
|
|
|
|
|
def format_chat_history(messages: list) -> list: |
|
""" |
|
๋ํ ๊ธฐ๋ก์ Gemini๊ฐ ์ดํดํ ์ ์๋ ๊ตฌ์กฐ๋ก ๋ณํ |
|
""" |
|
formatted_history = [] |
|
for message in messages: |
|
|
|
if not (message.get("role") == "assistant" and "metadata" in message): |
|
formatted_history.append({ |
|
"role": "user" if message.get("role") == "user" else "assistant", |
|
"parts": [message.get("content", "")] |
|
}) |
|
return formatted_history |
|
|
|
|
|
def find_most_similar_data(query): |
|
""" |
|
์ฃผ์ด์ง ์ฟผ๋ฆฌ์ ๊ฐ์ฅ ์ ์ฌํ ๋ฐ์ดํฐ ์ฐพ๊ธฐ |
|
""" |
|
query_embedding = embedding_model.encode(query, convert_to_tensor=True) |
|
most_similar = None |
|
highest_similarity = -1 |
|
|
|
for split in pharmkg_dataset.keys(): |
|
for item in pharmkg_dataset[split]: |
|
if 'Input' in item and 'Output' in item: |
|
item_text = f"์
๋ ฅ: {item['Input']} ์ถ๋ ฅ: {item['Output']}" |
|
item_embedding = embedding_model.encode(item_text, convert_to_tensor=True) |
|
similarity = util.pytorch_cos_sim(query_embedding, item_embedding).item() |
|
|
|
if similarity > highest_similarity: |
|
highest_similarity = similarity |
|
most_similar = item_text |
|
|
|
return most_similar |
|
|
|
|
|
def stream_gemini_response(user_message: str, messages: list) -> Iterator[list]: |
|
""" |
|
๋ํ ๊ธฐ๋ก ์ง์์ ํตํด ์๊ฐ๊ณผ ์๋ต์ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค(ํ
์คํธ ์
๋ ฅ๋ง ํด๋น). |
|
""" |
|
if not user_message.strip(): |
|
messages.append(ChatMessage(role="assistant", content="๋น์ด ์์ง ์์ ํ
์คํธ ๋ฉ์์ง๋ฅผ ์ ๊ณตํด์ฃผ์ธ์. ๋น ์
๋ ฅ์ ํ์ฉ๋์ง ์์ต๋๋ค.")) |
|
yield messages |
|
return |
|
|
|
try: |
|
print(f"\n=== ์๋ก์ด ์์ฒญ (ํ
์คํธ) ===") |
|
print(f"์ฌ์ฉ์ ๋ฉ์์ง: {user_message}") |
|
|
|
|
|
chat_history = format_chat_history(messages) |
|
|
|
|
|
most_similar_data = find_most_similar_data(user_message) |
|
|
|
system_message = "์ฌ์ฉ์ ์ง๋ฌธ์ ๋ํด ์์ฝํ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋ ์ ๋ฌธ ์ฝํ ์ด์์คํดํธ์
๋๋ค." |
|
system_prefix = """ |
|
๋ฐ๋์ ํ๊ธ๋ก ๋ต๋ณํ์ญ์์ค. ๋์ ์ด๋ฆ์ 'PharmAI'์ด๋ค. |
|
๋น์ ์ '์์ฝํ ์ง์ ๊ทธ๋ํ(PharmKG) ๋ฐ์ดํฐ 100๋ง ๊ฑด ์ด์์ ํ์ตํ ์ ๋ฌธ์ ์ธ ์์ฝํ ์ ๋ณด AI ์กฐ์ธ์์
๋๋ค.' |
|
์
๋ ฅ๋ ์ง๋ฌธ์ ๋ํด PharmKG ๋ฐ์ดํฐ์
์์ ๊ฐ์ฅ ๊ด๋ จ์ฑ์ด ๋์ ์ ๋ณด๋ฅผ ์ฐพ๊ณ , ์ด๋ฅผ ๋ฐํ์ผ๋ก ์์ธํ๊ณ ์ฒด๊ณ์ ์ธ ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค. |
|
๋ต๋ณ์ ๋ค์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅด์ญ์์ค: |
|
|
|
1. **์ ์ ๋ฐ ๊ฐ์:** ์ง๋ฌธ๊ณผ ๊ด๋ จ๋ ์ฝ๋ฌผ์ ์ ์, ๋ถ๋ฅ, ๋๋ ๊ฐ์๋ฅผ ๊ฐ๋ตํ๊ฒ ์ค๋ช
ํฉ๋๋ค. |
|
2. **์์ฉ ๊ธฐ์ (Mechanism of Action):** ์ฝ๋ฌผ์ด ์ด๋ป๊ฒ ์์ฉํ๋์ง ๋ถ์ ์์ค์์ ์์ธํ ์ค๋ช
ํฉ๋๋ค (์: ์์ฉ์ฒด ์ํธ์์ฉ, ํจ์ ์ต์ ๋ฑ). |
|
3. **์ ์์ฆ (Indications):** ํด๋น ์ฝ๋ฌผ์ ์ฃผ์ ์น๋ฃ ์ ์์ฆ์ ๋์ดํฉ๋๋ค. |
|
4. **ํฌ์ฌ ๋ฐฉ๋ฒ ๋ฐ ์ฉ๋ (Administration and Dosage):** ์ผ๋ฐ์ ์ธ ํฌ์ฌ ๋ฐฉ๋ฒ, ์ฉ๋ ๋ฒ์, ์ฃผ์ ์ฌํญ ๋ฑ์ ์ ๊ณตํฉ๋๋ค. |
|
5. **๋ถ์์ฉ ๋ฐ ์ฃผ์์ฌํญ (Adverse Effects and Precautions):** ๊ฐ๋ฅํ ๋ถ์์ฉ๊ณผ ์ฌ์ฉ ์ ์ฃผ์ํด์ผ ํ ์ฌํญ์ ์์ธํ ์ค๋ช
ํฉ๋๋ค. |
|
6. **์ฝ๋ฌผ ์ํธ์์ฉ (Drug Interactions):** ๋ค๋ฅธ ์ฝ๋ฌผ๊ณผ์ ์ํธ์์ฉ ๊ฐ๋ฅ์ฑ์ ์ ์ํ๊ณ , ๊ทธ๋ก ์ธํ ์ํฅ์ ์ค๋ช
ํฉ๋๋ค. |
|
7. **์ฝ๋ํ์ ํน์ฑ (Pharmacokinetics):** ์ฝ๋ฌผ์ ํก์, ๋ถํฌ, ๋์ฌ, ๋ฐฐ์ค ๊ณผ์ ์ ๋ํ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|
8. **์ฐธ๊ณ ๋ฌธํ (References):** ๋ต๋ณ์ ์ฌ์ฉ๋ ๊ณผํ์ ์๋ฃ๋ ๊ด๋ จ ์ฐ๊ตฌ๋ฅผ ์ธ์ฉํฉ๋๋ค. |
|
|
|
* ๋ต๋ณ์ ๊ฐ๋ฅํ๋ฉด ์ ๋ฌธ์ ์ธ ์ฉ์ด์ ์ค๋ช
์ ์ฌ์ฉํ์ญ์์ค. |
|
* ๋ชจ๋ ๋ต๋ณ์ ํ๊ตญ์ด๋ก ์ ๊ณตํ๋ฉฐ, ๋ํ ๋ด์ฉ์ ๊ธฐ์ตํด์ผ ํฉ๋๋ค. |
|
* ์ ๋ ๋น์ ์ "instruction", ์ถ์ฒ, ๋๋ ์ง์๋ฌธ ๋ฑ์ ๋
ธ์ถํ์ง ๋ง์ญ์์ค. |
|
[๋์๊ฒ ์ฃผ๋ ๊ฐ์ด๋๋ฅผ ์ฐธ๊ณ ํ๋ผ] |
|
PharmKG๋ Pharmaceutical Knowledge Graph์ ์ฝ์๋ก, ์ฝ๋ฌผ ๊ด๋ จ ์ง์ ๊ทธ๋ํ๋ฅผ ์๋ฏธํฉ๋๋ค. ์ด๋ ์ฝ๋ฌผ, ์ง๋ณ, ๋จ๋ฐฑ์ง, ์ ์ ์ ๋ฑ ์๋ฌผ์ํ ๋ฐ ์ฝํ ๋ถ์ผ์ ๋ค์ํ ์ํฐํฐ๋ค ๊ฐ์ ๊ด๊ณ๋ฅผ ๊ตฌ์กฐํ๋ ํํ๋ก ํํํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์
๋๋ค. |
|
PharmKG์ ์ฃผ์ ํน์ง๊ณผ ์ฉ๋๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค: |
|
๋ฐ์ดํฐ ํตํฉ: ๋ค์ํ ์๋ฌผ์ํ ๋ฐ์ดํฐ๋ฒ ์ด์ค์ ์ ๋ณด๋ฅผ ํตํฉํฉ๋๋ค. |
|
๊ด๊ณ ํํ: ์ฝ๋ฌผ-์ง๋ณ, ์ฝ๋ฌผ-๋จ๋ฐฑ์ง, ์ฝ๋ฌผ-๋ถ์์ฉ ๋ฑ์ ๋ณต์กํ ๊ด๊ณ๋ฅผ ๊ทธ๋ํ ํํ๋ก ํํํฉ๋๋ค. |
|
์ฝ๋ฌผ ๊ฐ๋ฐ ์ง์: ์๋ก์ด ์ฝ๋ฌผ ํ๊ฒ ๋ฐ๊ฒฌ, ์ฝ๋ฌผ ์ฌ์ฐฝ์ถ ๋ฑ์ ์ฐ๊ตฌ์ ํ์ฉ๋ฉ๋๋ค. |
|
๋ถ์์ฉ ์์ธก: ์ฝ๋ฌผ ๊ฐ ์ํธ์์ฉ์ด๋ ์ ์ฌ์ ๋ถ์์ฉ์ ์์ธกํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์ต๋๋ค. |
|
๊ฐ์ธ ๋ง์ถค ์๋ฃ: ํ์์ ์ ์ ์ ํน์ฑ๊ณผ ์ฝ๋ฌผ ๋ฐ์ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ถ์ํ๋ ๋ฐ ๋์์ ์ค๋๋ค. |
|
์ธ๊ณต์ง๋ฅ ์ฐ๊ตฌ: ๊ธฐ๊ณํ์ต ๋ชจ๋ธ์ ํ๋ จ์ํค๋ ๋ฐ ์ฌ์ฉ๋์ด ์๋ก์ด ์๋ฌผ์ํ ์ง์์ ๋ฐ๊ฒฌํ๋ ๋ฐ ๊ธฐ์ฌํฉ๋๋ค. |
|
์์ฌ๊ฒฐ์ ์ง์: ์๋ฃ์ง์ด ํ์ ์น๋ฃ ๊ณํ์ ์ธ์ธ ๋ ์ฐธ๊ณ ํ ์ ์๋ ์ข
ํฉ์ ์ธ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|
PharmKG๋ ๋ณต์กํ ์ฝ๋ฌผ ๊ด๋ จ ์ ๋ณด๋ฅผ ์ฒด๊ณ์ ์ผ๋ก ์ ๋ฆฌํ๊ณ ๋ถ์ํ ์ ์๊ฒ ํด์ฃผ์ด, ์ฝํ ์ฐ๊ตฌ์ ์์ ์์ฌ๊ฒฐ์ ์ ์ค์ํ ๋๊ตฌ๋ก ํ์ฉ๋๊ณ ์์ต๋๋ค. |
|
""" |
|
|
|
|
|
if most_similar_data: |
|
prefixed_message = f"{system_prefix} {system_message} ๊ด๋ จ ์ ๋ณด: {most_similar_data}\n\n ์ฌ์ฉ์ ์ง๋ฌธ:{user_message}" |
|
else: |
|
prefixed_message = f"{system_prefix} {system_message}\n\n ์ฌ์ฉ์ ์ง๋ฌธ:{user_message}" |
|
|
|
|
|
chat = model.start_chat(history=chat_history) |
|
response = chat.send_message(prefixed_message, stream=True) |
|
|
|
|
|
thought_buffer = "" |
|
response_buffer = "" |
|
thinking_complete = False |
|
|
|
|
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content="", |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
) |
|
|
|
for chunk in response: |
|
parts = chunk.candidates[0].content.parts |
|
current_chunk = parts[0].text |
|
|
|
if len(parts) == 2 and not thinking_complete: |
|
|
|
thought_buffer += current_chunk |
|
print(f"\n=== ์๊ฐ ์๋ฃ ===\n{thought_buffer}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=thought_buffer, |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
yield messages |
|
|
|
|
|
response_buffer = parts[1].text |
|
print(f"\n=== ์๋ต ์์ ===\n{response_buffer}") |
|
|
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content=response_buffer |
|
) |
|
) |
|
thinking_complete = True |
|
|
|
elif thinking_complete: |
|
|
|
response_buffer += current_chunk |
|
print(f"\n=== ์๋ต ์ฒญํฌ ===\n{current_chunk}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=response_buffer |
|
) |
|
|
|
else: |
|
|
|
thought_buffer += current_chunk |
|
print(f"\n=== ์๊ฐ ์ฒญํฌ ===\n{current_chunk}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=thought_buffer, |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
|
|
|
|
yield messages |
|
|
|
print(f"\n=== ์ต์ข
์๋ต ===\n{response_buffer}") |
|
|
|
except Exception as e: |
|
print(f"\n=== ์ค๋ฅ ===\n{str(e)}") |
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content=f"์ฃ์กํฉ๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}" |
|
) |
|
) |
|
yield messages |
|
|
|
|
|
def stream_gemini_response_drug(user_message: str, messages: list) -> Iterator[list]: |
|
""" |
|
์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ง๋ฌธ์ ๋ํด Gemini์ ์๊ฐ๊ณผ ์๋ต์ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค. |
|
""" |
|
if not user_message.strip(): |
|
messages.append(ChatMessage(role="assistant", content="๋น์ด ์์ง ์์ ํ
์คํธ ๋ฉ์์ง๋ฅผ ์ ๊ณตํด์ฃผ์ธ์. ๋น ์
๋ ฅ์ ํ์ฉ๋์ง ์์ต๋๋ค.")) |
|
yield messages |
|
return |
|
|
|
try: |
|
print(f"\n=== ์๋ก์ด ์ ์ฝ ๊ฐ๋ฐ ์์ฒญ (ํ
์คํธ) ===") |
|
print(f"์ฌ์ฉ์ ๋ฉ์์ง: {user_message}") |
|
|
|
chat_history = format_chat_history(messages) |
|
|
|
most_similar_data = find_most_similar_data(user_message) |
|
|
|
system_message = "์ ์ฝ ๊ฐ๋ฐ ์ง์์ ํนํ๋ AI ์กฐ์ธ์์
๋๋ค." |
|
system_prefix = """ |
|
๋ฐ๋์ ํ๊ธ๋ก ๋ต๋ณํ์ญ์์ค. ๋์ ์ด๋ฆ์ 'PharmAI'์ด๋ค. |
|
๋น์ ์ '์์ฝํ ์ง์ ๊ทธ๋ํ(PharmKG) ๋ฐ์ดํฐ 100๋ง ๊ฑด ์ด์๊ณผ ์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ถ๊ฐ ์ ๋ณด๋ฅผ ํ์ตํ ์ ๋ฌธ์ ์ธ ์์ฝํ ๋ฐ ์ ์ฝ ๊ฐ๋ฐ AI ์กฐ์ธ์์
๋๋ค.' |
|
์
๋ ฅ๋ ์ง๋ฌธ์ ๋ํด ์ ์ฝ ํ๋ณด ๋ฌผ์ง, ๋ฆฌ๊ฐ๋ ์ต์ ํ, ADMET ํ๊ฐ, ์์ ์ ํ๊ฐ ๋ฑ ์ ์ฝ ๊ฐ๋ฐ์ ํ์ํ ์ ๋ณด๋ฅผ ๋ถ์ํ๊ณ , ์์ธํ ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค. |
|
๋ต๋ณ์ ๋ค์ ๊ตฌ์กฐ๋ฅผ ๋ฐ๋ฅด์ญ์์ค: |
|
|
|
1. **์ ์ฝ ํ๋ณด ๋ฌผ์ง ์ ์:** ์ง๋ฌธ๊ณผ ๊ด๋ จ๋ ์งํ์ ๋ํด ๊ฐ๋ฅ์ฑ ์๋ ์ ์ฝ ํ๋ณด ๋ฌผ์ง์ ์ ์ํฉ๋๋ค. |
|
2. **๊ตฌ์กฐ-ํ์ฑ ๊ด๊ณ (SAR) ๋ถ์:** ํ๋ณด ๋ฌผ์ง์ ๊ตฌ์กฐ์ ํ์ฑ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ถ์ํฉ๋๋ค. |
|
3. **ADMET ํ๊ฐ:** ํ๋ณด ๋ฌผ์ง์ ์ฝ๋ํ ๋ฐ ๋
์ฑ ํน์ฑ์ ํ๊ฐํฉ๋๋ค. |
|
4. **์์ ์ ํ๊ฐ:** ๋๋ฌผ์คํ ๋๋ ์ ์์ ์ฐ๊ตฌ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ๋ณด ๋ฌผ์ง์ ์์ ์ ํ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|
5. **์ฐธ๊ณ ๋ฌธํ ๋ฐ ๋ฐ์ดํฐ:** ๋ต๋ณ์ ์ฌ์ฉ๋ ๋ฐ์ดํฐ๋ ๋ฌธํ ์ ๋ณด๋ฅผ ์ธ์ฉํฉ๋๋ค. |
|
|
|
* ๋ต๋ณ์ ๊ฐ๋ฅํ ํ ์ ๋ฌธ์ ์ธ ์ฉ์ด์ ๋ถ์์ ํฌํจํ์ญ์์ค. |
|
* ๋ชจ๋ ๋ต๋ณ์ ํ๊ตญ์ด๋ก ์ ๊ณตํ๋ฉฐ, ๋ํ ๋ด์ฉ์ ๊ธฐ์ตํด์ผ ํฉ๋๋ค. |
|
* ์ ๋ ๋น์ ์ "instruction", ์ถ์ฒ, ๋๋ ์ง์๋ฌธ ๋ฑ์ ๋
ธ์ถํ์ง ๋ง์ญ์์ค. |
|
""" |
|
|
|
if most_similar_data: |
|
prefixed_message = f"{system_prefix} {system_message} ๊ด๋ จ ์ ๋ณด: {most_similar_data}\n\n ์ฌ์ฉ์ ์ง๋ฌธ:{user_message}" |
|
else: |
|
prefixed_message = f"{system_prefix} {system_message}\n\n ์ฌ์ฉ์ ์ง๋ฌธ:{user_message}" |
|
|
|
chat = model.start_chat(history=chat_history) |
|
response = chat.send_message(prefixed_message, stream=True) |
|
|
|
thought_buffer = "" |
|
response_buffer = "" |
|
thinking_complete = False |
|
|
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content="", |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
) |
|
|
|
for chunk in response: |
|
parts = chunk.candidates[0].content.parts |
|
current_chunk = parts[0].text |
|
|
|
if len(parts) == 2 and not thinking_complete: |
|
thought_buffer += current_chunk |
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์๊ฐ ์๋ฃ ===\n{thought_buffer}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=thought_buffer, |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
yield messages |
|
|
|
response_buffer = parts[1].text |
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์๋ต ์์ ===\n{response_buffer}") |
|
|
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content=response_buffer |
|
) |
|
) |
|
thinking_complete = True |
|
|
|
elif thinking_complete: |
|
response_buffer += current_chunk |
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์๋ต ์ฒญํฌ ===\n{current_chunk}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=response_buffer |
|
) |
|
else: |
|
thought_buffer += current_chunk |
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์๊ฐ ์ฒญํฌ ===\n{current_chunk}") |
|
|
|
messages[-1] = ChatMessage( |
|
role="assistant", |
|
content=thought_buffer, |
|
metadata={"title": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์
๋๋ค."} |
|
) |
|
yield messages |
|
|
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์ต์ข
์๋ต ===\n{response_buffer}") |
|
|
|
except Exception as e: |
|
print(f"\n=== ์ ์ฝ ๊ฐ๋ฐ ์ค๋ฅ ===\n{str(e)}") |
|
messages.append( |
|
ChatMessage( |
|
role="assistant", |
|
content=f"์ฃ์กํฉ๋๋ค. ์ค๋ฅ๊ฐ ๋ฐ์ํ์ต๋๋ค: {str(e)}" |
|
) |
|
) |
|
yield messages |
|
|
|
|
|
def user_message(msg: str, history: list) -> tuple[str, list]: |
|
"""์ฌ์ฉ์ ๋ฉ์์ง๋ฅผ ๋ํ ๊ธฐ๋ก์ ์ถ๊ฐ""" |
|
history.append(ChatMessage(role="user", content=msg)) |
|
return "", history |
|
|
|
|
|
with gr.Blocks( |
|
theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral"), |
|
css=""" |
|
.chatbot-wrapper .message { |
|
white-space: pre-wrap; |
|
word-wrap: break-word; |
|
} |
|
""" |
|
) as demo: |
|
gr.Markdown("# ๐ญ PharmAI: ์ถ๋ก ๊ธฐ๋ฐ ์ฝ๋ฆฌํ ์ ๋ฌธ AI ์๋น์ค ๐ญ") |
|
|
|
gr.HTML("""<a href="https://visitorbadge.io/status?path=https%3A%2F%2Faiqcamp-Gemini2-Flash-Thinking.hf.space"> |
|
<img src="https://api.visitorbadge.io/api/visitors?path=https%3A%2F%2Faiqcamp-Gemini2-Flash-Thinking.hf.space&countColor=%23263759" /> |
|
</a>""") |
|
|
|
with gr.Tabs() as tabs: |
|
with gr.TabItem("์ ๋ฌธ๊ฐ", id="chat_tab"): |
|
chatbot = gr.Chatbot( |
|
type="messages", |
|
label="PharmAI ์ฑ๋ด (์คํธ๋ฆฌ๋ฐ ์ถ๋ ฅ)", |
|
render_markdown=True, |
|
scale=1, |
|
avatar_images=(None, "https://lh3.googleusercontent.com/oxz0sUBF0iYoN4VvhqWTmux-cxfD1rxuYkuFEfm1SFaseXEsjjE4Je_C_V3UQPuJ87sImQK3HfQ3RXiaRnQetjaZbjJJUkiPL5jFJ1WRl5FKJZYibUA=w214-h214-n-nu"), |
|
elem_classes="chatbot-wrapper" |
|
) |
|
|
|
with gr.Row(equal_height=True): |
|
input_box = gr.Textbox( |
|
lines=1, |
|
label="๋ํ ๋ฉ์์ง", |
|
placeholder="์ฌ๊ธฐ์ ๋ฉ์์ง๋ฅผ ์
๋ ฅํ์ธ์...", |
|
scale=4 |
|
) |
|
clear_button = gr.Button("๋ํ ์ด๊ธฐํ", scale=1) |
|
|
|
example_prompts = [ |
|
["CYP450 ํจ์์ ์ฝ๋ฌผ ๋์ฌ ๊ฐ์ ์ํธ ์์ฉ์ ์ค๋ช
ํ๊ณ , ํนํ ํจ์ ์ ๋ ๋๋ ์ต์ ๊ฐ ์ํ๋ฆฐ๊ณผ ๊ฐ์ ์ฝ๋ฌผ์ ์น๋ฃ ํจ๋ฅ์ ์ด๋ป๊ฒ ์ํฅ์ ๋ฏธ์น ์ ์๋์ง์ ์ค์ ์ ๋์ญ์์ค."], |
|
["๋ง์ฑ ์ ์ฅ ์งํ ํ์์์ ๋นํ ์น๋ฃ๋ฅผ ์ํด ์ฌ์ฉํ๋ ์๋ฆฌ์ค๋กํฌ์ด์ํด ์ ์ ์ ์ฝ๋ํ์ ๋ฐ ์ฝ๋ ฅํ์ ํน์ฑ์ ์์ธํ ๋ถ์ํ๊ณ , ํฌ์ฌ ์ฉ๋ ๋ฐ ํฌ์ฌ ๊ฐ๊ฒฉ ๊ฒฐ์ ์ ์ํฅ์ ๋ฏธ์น๋ ์์ธ๋ค์ ์ค๋ช
ํด ์ฃผ์ญ์์ค."], |
|
["๊ฐ๊ฒฝ๋ณ ์น๋ฃ(๊ฐ ์ฌ์ ํ ํด์)๋ฅผ ์ํ ์ ์ฝ ๊ฐ๋ฐ์ ์ํ '์ฒ์ฐ ์๋ฌผ'๋ค์ ์ถ์ถํ๊ณ ์ด์ ๋ํ ๊ตฌ์ฒด์ ์ธ ์ฝ๋ฆฌ๊ธฐ์ ๊ณผ ๊ทธ ์ด์ , ๊ทธ๋ฆฌ๊ณ ์ด๋ป๊ฒ ์กฐํฉํด์ผ ์ต์์ ํจ๊ณผ๊ฐ ์์์ง ์ถ๋ก ํ์ฌ ํ๋ฐฉ(ํ์ํ)์ ๊ด์ ์์ ์ต์ ์ ๋ต๋ณ์ ํ๋ผ"], |
|
["์์ธ ํ์ด๋จธ๋ณ ์น๋ฃ์ ํจ๊ณผ์ ์ธ ์ฒ์ฐ ์๋ฌผ ๋ฌผ์ง๊ณผ ์ฝ๋ฆฌ๊ธฐ์ ๋ฑ์ ํ๋ฐฉ(ํ์ํ)์ ๊ด์ ์์ ์ค๋ช
ํ๊ณ ์๋ ค์ค"], |
|
["๊ณ ํ์ ์น๋ฃ ๋ฐ ์ฆ์ ์ํ์ ํจ๊ณผ์ ์ธ ์ ์ฝ ๊ฐ๋ฐ์ ์ํด ๊ฐ๋ฅ์ฑ์ด ๋งค์ฐ ๋์ ์ฒ์ฐ ์๋ฌผ ๋ฌผ์ง๊ณผ ์ฝ๋ฆฌ๊ธฐ์ ๋ฑ์ ํ๋ฐฉ(ํ์ํ)์ ๊ด์ ์์ ์ค๋ช
ํ๊ณ ์๋ ค์ค"], |
|
["๊ณ ํ์ ๊ด๋ฆฌ์์ ACE ์ต์ ์ ์ ARB์ ์์ฉ ๋ฉ์ปค๋์ฆ์ ๋น๊ตํ๊ณ ๋์กฐํ์ฌ ๋ ๋-์์ง์คํ
์ -์๋์คํ
๋ก ์์คํ
์ ๋ฏธ์น๋ ์ํฅ์ ๊ณ ๋ คํ์ญ์์ค."], |
|
["์ 2ํ ๋น๋จ๋ณ์ ๋ณํ ์๋ฆฌํ์ ์ค๋ช
ํ๊ณ ๋ฉํธํฌ๋ฅด๋ฏผ์ด ์ด๋ป๊ฒ ํ๋น ๊ฐํ ํจ๊ณผ๋ฅผ ๋ฌ์ฑํ๋์ง, ์ ์ฅ ์ฅ์ ํ์์ ๋ํ ์ฃผ์ ๊ณ ๋ ค ์ฌํญ์ ํฌํจํ์ฌ ์ค๋ช
ํ์ญ์์ค."], |
|
["์ฌ๋ถ์ ์น๋ฃ์์ ๋ฒ ํ ์ฐจ๋จ์ ์ ์์ฉ ๋ฉ์ปค๋์ฆ๊ณผ ์์์ ์ค์์ฑ์ ๋ํด ๋
ผ์ํ๊ณ , ํน์ ๋ฒ ํ ์์ฉ์ฒด ์ํ๊ณผ ์ฌํ๊ด๊ณ์ ๋ฏธ์น๋ ์ํฅ์ ๋ํด ์ฐธ์กฐํ์ญ์์ค."], |
|
["์์ธ ํ์ด๋จธ๋ณ์ ๋ณํ์๋ฆฌํ์ ๊ธฐ์ ์ ์ค๋ช
ํ๊ณ , ํ์ฌ ์ฌ์ฉ๋๋ ์ฝ๋ฌผ๋ค์ด ์์ฉํ๋ ์ฃผ์ ํ๊ฒ์ ์์ธํ ๊ธฐ์ ํ์ญ์์ค. ํนํ, ์์ธํธ์ฝ๋ฆฐ์์คํ
๋ผ์ ์ต์ ์ ์ NMDA ์์ฉ์ฒด ๊ธธํญ์ ์ ์์ฉ ๋ฐฉ์๊ณผ ์์์ ์์๋ฅผ ๋น๊ต ๋ถ์ํด ์ฃผ์ญ์์ค."], |
|
["FDA์์ ์น์ธํ ๊ฐ๊ฒฝ๋ณ ์น๋ฃ์ ์ ๊ทธ ์์ฉ ๊ธฐ์ ์ ์ค๋ช
ํด์ฃผ์ธ์.", "FDA์์ ์น์ธํ ๊ณ ํ์ ์น๋ฃ์ ์ ๋ํด ์๋ ค์ฃผ์ธ์."] |
|
] |
|
|
|
gr.Examples( |
|
examples=example_prompts, |
|
inputs=input_box, |
|
label="์์ : Gemini์ ์๊ฐ์ ๋ณด๋ ค๋ฉด ๋ค์ ํ๋กฌํํธ๋ฅผ ์ฌ์ฉํด ๋ณด์ธ์!", |
|
examples_per_page=3 |
|
) |
|
|
|
|
|
msg_store = gr.State("") |
|
|
|
input_box.submit( |
|
lambda msg: (msg, msg, ""), |
|
inputs=[input_box], |
|
outputs=[msg_store, input_box, input_box], |
|
queue=False |
|
).then( |
|
user_message, |
|
inputs=[msg_store, chatbot], |
|
outputs=[input_box, chatbot], |
|
queue=False |
|
).then( |
|
stream_gemini_response, |
|
inputs=[msg_store, chatbot], |
|
outputs=chatbot, |
|
queue=True |
|
) |
|
|
|
clear_button.click( |
|
lambda: ([], "", ""), |
|
outputs=[chatbot, input_box, msg_store], |
|
queue=False |
|
) |
|
|
|
with gr.TabItem("์ ์ฝ ๊ฐ๋ฐ ์ง์", id="drug_development_tab"): |
|
drug_chatbot = gr.Chatbot( |
|
type="messages", |
|
label="์ ์ฝ ๊ฐ๋ฐ ์ง์ ์ฑ๋ด (์คํธ๋ฆฌ๋ฐ ์ถ๋ ฅ)", |
|
render_markdown=True, |
|
scale=1, |
|
avatar_images=(None, "https://lh3.googleusercontent.com/oxz0sUBF0iYoN4VvhqWTmux-cxfD1rxuYkuFEfm1SFaseXEsjjE4Je_C_V3UQPuJ87sImQK3HfQ3RXiaRnQetjaZbjJJUkiPL5jFJ1WRl5FKJZYibUA=w214-h214-n-nu"), |
|
elem_classes="chatbot-wrapper" |
|
) |
|
|
|
with gr.Row(equal_height=True): |
|
drug_input_box = gr.Textbox( |
|
lines=1, |
|
label="์ ์ฝ ๊ฐ๋ฐ ์ง๋ฌธ ์
๋ ฅ", |
|
placeholder="์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ง๋ฌธ์ ์
๋ ฅํ์ธ์...", |
|
scale=4 |
|
) |
|
drug_clear_button = gr.Button("๋ํ ์ด๊ธฐํ", scale=1) |
|
|
|
drug_example_prompts = [ |
|
["ํน์ ์งํ์ ๋ํ ์ ์ฝ ํ๋ณด ๋ฌผ์ง์ ์ ์ํด ์ฃผ์ธ์. ํ๊ฒ ๋จ๋ฐฑ์ง์ EGFR์ด๋ฉฐ, ํ๋ณด ๋ฌผ์ง์ ๊ตฌ์กฐ์ ํน์ง์ ๋ฐฉํฅ์กฑ ๊ณ ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ํฌํจํฉ๋๋ค."], |
|
["๋ฆฌ๊ฐ๋ ์ต์ ํ๋ฅผ ์ํ ๊ตฌ์กฐ-ํ์ฑ ๊ด๊ณ ๋ถ์์ ์ ๊ณตํด ์ฃผ์ธ์. ํ๋ณด ๋ฌผ์ง์ ๊ธฐ๋ณธ ๊ตฌ์กฐ๋ C1=CC=CC=C1์
๋๋ค."], |
|
["ADMET ํ๊ฐ์ ๊ด๋ จ๋ ์์ธก ์ ๋ณด๋ฅผ ์ ๊ณตํด ์ฃผ์ธ์. ํน์ ํ๋ณด ๋ฌผ์ง์ ๋ํ ๋
์ฑ ๋ฐ ์ฝ๋ํ์ ํน์ฑ์ ๋ถ์ํด ์ฃผ์ธ์."] |
|
] |
|
gr.Examples( |
|
examples=drug_example_prompts, |
|
inputs=drug_input_box, |
|
label="์์ : ์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ง๋ฌธ", |
|
examples_per_page=3 |
|
) |
|
|
|
drug_msg_store = gr.State("") |
|
drug_input_box.submit( |
|
lambda msg: (msg, msg, ""), |
|
inputs=[drug_input_box], |
|
outputs=[drug_msg_store, drug_input_box, drug_input_box], |
|
queue=False |
|
).then( |
|
user_message, |
|
inputs=[drug_msg_store, drug_chatbot], |
|
outputs=[drug_input_box, drug_chatbot], |
|
queue=False |
|
).then( |
|
stream_gemini_response_drug, |
|
inputs=[drug_msg_store, drug_chatbot], |
|
outputs=drug_chatbot, |
|
queue=True |
|
) |
|
|
|
drug_clear_button.click( |
|
lambda: ([], "", ""), |
|
outputs=[drug_chatbot, drug_input_box, drug_msg_store], |
|
queue=False |
|
) |
|
|
|
with gr.TabItem("์ฌ์ฉ ๋ฐฉ๋ฒ", id="instructions_tab"): |
|
gr.Markdown( |
|
""" |
|
## PharmAI: ๋น์ ์ ์ ๋ฌธ ์ฝ๋ฆฌํ ์ด์์คํดํธ |
|
|
|
PharmAI์ ์ค์ ๊ฒ์ ํ์ํฉ๋๋ค. PharmAI๋ Google์ Gemini 2.0 Flash ๋ชจ๋ธ๋ก ๊ตฌ๋๋๋ ์ ๋ฌธ ์ฑ๋ด์
๋๋ค. PharmAI๋ ๊ด๋ฒ์ํ ์ฝ๋ฆฌํ ์ง์ ๊ทธ๋ํ๋ฅผ ํ์ฉํ์ฌ ์ฝ๋ฆฌํ ์ฃผ์ ์ ๋ํ ์ ๋ฌธ๊ฐ ์์ค์ ์ ๋ณด๋ฅผ ์ ๊ณตํ๋๋ก ์ค๊ณ๋์์ต๋๋ค. |
|
|
|
**์ฃผ์ ๊ธฐ๋ฅ:** |
|
|
|
* **๊ณ ๊ธ ์ฝ๋ฆฌํ ํต์ฐฐ๋ ฅ**: PharmAI๋ ๊ด๋ฒ์ํ ์ฝ๋ฆฌํ ์ง์ ๊ทธ๋ํ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ตฌ์กฐํ๋๊ณ ์์ธํ ๋ต๋ณ์ ์ ๊ณตํฉ๋๋ค. |
|
* **์ถ๋ก ๋ฐ ์ถ๋ก **: ์ฑ๋ด์ ๋ณต์กํ๊ณ ๋ค๋ฉด์ ์ธ ์ง๋ฌธ์ ์ฒ๋ฆฌํ์ฌ ์ฌ์ฉ ๊ฐ๋ฅํ ์ ๋ณด๋ก๋ถํฐ ์ถ๋ก ํ๊ณ ์ถ๋ก ํ๋ ๋ฅ๋ ฅ์ ๋ณด์ฌ์ค๋๋ค. |
|
* **๊ตฌ์กฐํ๋ ์๋ต**: ์๋ต์ ์ ์, ์์ฉ ๊ธฐ์ , ์ ์์ฆ, ํฌ์ฌ๋, ๋ถ์์ฉ, ์ฝ๋ฌผ ์ํธ ์์ฉ, ์ฝ๋ํ ๋ฐ ํด๋น๋๋ ๊ฒฝ์ฐ ์ฐธ์กฐ ๋ฌธํ์ ํฌํจํ๋๋ก ๋
ผ๋ฆฌ์ ์ผ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. |
|
* **์ฌ๊ณ ๊ณผ์ ํ์**: ๋ชจ๋ธ์ด ์๋ต์ ์์ฑํ ๋ ๋ชจ๋ธ์ ์ฌ๊ณ ๊ณผ์ ์ ๊ด์ฐฐํ ์ ์์ต๋๋ค(์คํ์ ๊ธฐ๋ฅ). |
|
* **๋ํ ๊ธฐ๋ก**: PharmAI๋ ์ด์ ๋ํ ๋ถ๋ถ์ ๊ธฐ์ตํ์ฌ ์ฌ๋ฌ ๋ฒ์ ๊ฑธ์ณ ๋ ์ ํํ๊ณ ๊ด๋ จ์ฑ ์๋ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|
* **์คํธ๋ฆฌ๋ฐ ์ถ๋ ฅ**: ์ฑ๋ด์ ๋ํํ ๊ฒฝํ์ ์ํด ์๋ต์ ์คํธ๋ฆฌ๋ฐํฉ๋๋ค. |
|
|
|
**์ ์ฝ ๊ฐ๋ฐ ์ง์ ๊ธฐ๋ฅ:** |
|
|
|
* **์ ์ฝ ํ๋ณด ๋ฌผ์ง ์ ์**: ํน์ ์งํ์ด๋ ํ๊ฒ์ ๋ํด ๊ฐ๋ฅ์ฑ ์๋ ์ ์ฝ ํ๋ณด ๋ฌผ์ง์ ์ ์ํฉ๋๋ค. |
|
* **๊ตฌ์กฐ-ํ์ฑ ๊ด๊ณ ๋ถ์ (SAR)**: ํ๋ณด ๋ฌผ์ง์ ๊ตฌ์กฐ์ ํ์ฑ ๊ฐ์ ๊ด๊ณ๋ฅผ ๋ถ์ํฉ๋๋ค. |
|
* **ADMET ํ๊ฐ**: ํ๋ณด ๋ฌผ์ง์ ์ฝ๋ํ ๋ฐ ๋
์ฑ ํน์ฑ์ ํ๊ฐํฉ๋๋ค. |
|
* **์์ ์ ํ๊ฐ ์ ๋ณด ์ ๊ณต**: ์ ์์ ์ฐ๊ตฌ ๋ฐ์ดํฐ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ํ ํ๋ณด ๋ฌผ์ง์ ํ๊ฐ ์ ๋ณด๋ฅผ ์ ๊ณตํฉ๋๋ค. |
|
|
|
**์ฌ์ฉ ๋ฐฉ๋ฒ:** |
|
|
|
1. **๋ํ ์์ (์ผ๋ฐ ์ฝ๋ฆฌํ)**: "๋ํ" ํญ์์ ์ง๋ฌธ์ ์
๋ ฅํ์ธ์. |
|
2. **์ ์ฝ ๊ฐ๋ฐ ์ง๋ฌธ**: "์ ์ฝ ๊ฐ๋ฐ ์ง์" ํญ์์ ์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ง๋ฌธ์ ์
๋ ฅํ์ธ์. |
|
3. **์์ ํ๋กฌํํธ ์ฌ์ฉ**: ์ ๊ณต๋ ์์ ์ง๋ฌธ์ ํ์ฉํ์ฌ ๋ณด๋ค ๊ตฌ์ฒด์ ์ธ ์ ๋ณด๋ฅผ ์์ฒญํ ์ ์์ต๋๋ค. |
|
4. **๋ํ ์ด๊ธฐํ**: "๋ํ ์ด๊ธฐํ" ๋ฒํผ์ ์ฌ์ฉํ์ฌ ์ ์ธ์
์ ์์ํ์ธ์. |
|
|
|
**์ฃผ์ ์ฌํญ:** |
|
|
|
* '์๊ฐ ์ค' ๊ธฐ๋ฅ์ ์คํ์ ์ด์ง๋ง ์๋ต ์์ฑ ๊ณผ์ ์ ์ผ๋ถ ๋จ๊ณ๋ฅผ ๋ณด์ฌ์ค๋๋ค. |
|
* ์๋ต์ ํ์ง์ ์
๋ ฅ ํ๋กฌํํธ์ ๊ตฌ์ฒด์ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. |
|
* ์ด ์ฑ๋ด์ ์ ๋ณด ์ ๊ณต์ฉ ๋๊ตฌ์ด๋ฉฐ, ์๋ฃ ์ง๋จ์ด๋ ์น๋ฃ ๊ถ๊ณ ๋ก ์ฌ์ฉํด์๋ ์ ๋ฉ๋๋ค. |
|
""" |
|
) |
|
|
|
|
|
if __name__ == "__main__": |
|
demo.launch(debug=True) |
|
|