Spaces:
Running
Running
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 ํค๋ฅผ ํ๊ฒฝ ๋ณ์์์ ๊ฐ์ ธ์ค๊ธฐ | |
GEMINI_API_KEY = os.getenv("GEMINI_API_KEY") | |
genai.configure(api_key=GEMINI_API_KEY) | |
# Gemini 2.0 Flash ๋ชจ๋ธ (Thinking ๊ธฐ๋ฅ ํฌํจ) ์ฌ์ฉ | |
model = genai.GenerativeModel("gemini-2.0-flash-thinking-exp-1219") | |
# PharmKG ๋ฐ์ดํฐ์ ๋ก๋ | |
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}") | |
# Gemini์ฉ ๋ํ ๊ธฐ๋ก ํฌ๋งท | |
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}" | |
# Gemini ์ฑํ ์์ | |
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": "โ๏ธ ์๊ฐ ์ค: *๋ชจ๋ธ์ ์ํด ์์ฑ๋ ์๊ฐ์ ์คํ์ ์ ๋๋ค."} | |
) | |
#time.sleep(0.05) # ๋๋ฒ๊น /์๊ฐํ๋ฅผ ์ํด ์ฝ๊ฐ์ ์ง์ฐ์ ์ถ๊ฐํ๋ ค๋ฉด ์ฃผ์ ํด์ ํฉ๋๋ค. ์ต์ข ๋ฒ์ ์์๋ ์ ๊ฑฐํฉ๋๋ค. | |
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) | |
# PharmKG ๋ฐ์ดํฐ์ ๋ด ์ ์ฌ ๋ฐ์ดํฐ ๊ฒ์ (์ ์ฝ ๊ฐ๋ฐ ๊ด๋ จ ์ ๋ณด ํฌํจ ๊ฐ๋ฅ) | |
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. **๋ํ ์ด๊ธฐํ**: "๋ํ ์ด๊ธฐํ" ๋ฒํผ์ ์ฌ์ฉํ์ฌ ์ ์ธ์ ์ ์์ํ์ธ์. | |
**์ฃผ์ ์ฌํญ:** | |
* '์๊ฐ ์ค' ๊ธฐ๋ฅ์ ์คํ์ ์ด์ง๋ง ์๋ต ์์ฑ ๊ณผ์ ์ ์ผ๋ถ ๋จ๊ณ๋ฅผ ๋ณด์ฌ์ค๋๋ค. | |
* ์๋ต์ ํ์ง์ ์ ๋ ฅ ํ๋กฌํํธ์ ๊ตฌ์ฒด์ฑ์ ๋ฐ๋ผ ๋ฌ๋ผ์ง๋๋ค. | |
* ์ด ์ฑ๋ด์ ์ ๋ณด ์ ๊ณต์ฉ ๋๊ตฌ์ด๋ฉฐ, ์๋ฃ ์ง๋จ์ด๋ ์น๋ฃ ๊ถ๊ณ ๋ก ์ฌ์ฉํด์๋ ์ ๋ฉ๋๋ค. | |
""" | |
) | |
# Launch the interface | |
if __name__ == "__main__": | |
demo.launch(debug=True) | |