Kim Juwon
update UI/UX
4b1f53c
raw
history blame
9.46 kB
import gradio as gr
from huggingface_hub import InferenceClient
"""
For more information on `huggingface_hub` Inference API support, please check the docs: https://huggingface.co/docs/huggingface_hub/v0.22.2/en/guides/inference
"""
client = InferenceClient("HuggingFaceH4/zephyr-7b-beta")
def create_system_prompt(agent_type, personality, expertise_level, language):
base_prompt = f"""You are a {agent_type} movie recommendation agent with the following characteristics:
- Personality: {personality}
- Expertise Level: {expertise_level}
- Language: {language}
Your role is to:
1. Understand user preferences and mood
2. Provide personalized movie recommendations
3. Explain why you're recommending specific movies
4. Maintain a {personality} tone throughout the conversation
5. Consider the user's expertise level ({expertise_level}) when explaining
Please respond in {language}."""
return base_prompt
def respond(
message,
history: list[tuple[str, str]],
agent_type,
personality,
expertise_level,
language,
max_tokens,
temperature,
top_p,
genre,
mood,
):
# μ‹œμŠ€ν…œ ν”„λ‘¬ν”„νŠΈ 생성
system_message = create_system_prompt(agent_type, personality, expertise_level, language)
messages = [{"role": "system", "content": system_message}]
# μ‚¬μš©μž μž…λ ₯에 μž₯λ₯΄μ™€ κΈ°λΆ„ 정보 μΆ”κ°€
enhanced_message = f"Genre: {genre}\nMood: {mood}\nUser request: {message}"
for val in history:
if val[0]:
messages.append({"role": "user", "content": val[0]})
if val[1]:
messages.append({"role": "assistant", "content": val[1]})
messages.append({"role": "user", "content": enhanced_message})
response = ""
for message in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
token = message.choices[0].delta.content
response += token
yield response
def reset_chat():
return None
def show_settings_changed_info(agent_type, personality, expertise_level, language):
return f"""
μƒˆλ‘œμš΄ Agent μ„€μ •:
- μœ ν˜•: {agent_type}
- 성격: {personality}
- μ„€λͺ… μˆ˜μ€€: {expertise_level}
- 응닡 μ–Έμ–΄: {language}
λŒ€ν™”κ°€ μ΄ˆκΈ°ν™”λ˜μ—ˆμŠ΅λ‹ˆλ‹€. μƒˆλ‘œμš΄ μ„€μ •μœΌλ‘œ λŒ€ν™”λ₯Ό μ‹œμž‘ν•΄μ£Όμ„Έμš”.
"""
"""
For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
"""
# μ»€μŠ€ν…€ CSS μŠ€νƒ€μΌ
custom_css = """
.gradio-container {
font-family: 'Helvetica Neue', Arial, sans-serif;
max-width: 1200px;
margin: auto;
padding: 20px;
}
.container {
max-width: 800px;
margin: auto;
padding: 20px;
}
/* μ±„νŒ… μ»¨ν…Œμ΄λ„ˆ μŠ€νƒ€μΌ */
.chat-container {
display: flex;
flex-direction: column;
height: 100%;
background: #ffffff;
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
/* μ±„νŒ… λ©”μ‹œμ§€ μŠ€νƒ€μΌ */
.chat-message {
padding: 20px;
margin: 10px;
border-radius: 10px;
max-width: 85%;
line-height: 1.5;
position: relative;
animation: fadeIn 0.3s ease-in-out;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}
/* μ‚¬μš©μž λ©”μ‹œμ§€ μŠ€νƒ€μΌ */
.user-message {
background-color: #f0f2f5;
margin-left: auto;
border-bottom-right-radius: 0;
}
/* 봇 λ©”μ‹œμ§€ μŠ€νƒ€μΌ */
.bot-message {
background-color: #e3f2fd;
margin-right: auto;
border-bottom-left-radius: 0;
}
/* μž…λ ₯ μ˜μ—­ μŠ€νƒ€μΌ */
.input-container {
display: flex;
gap: 10px;
padding: 20px;
background: #ffffff;
border-top: 1px solid #e0e0e0;
position: sticky;
bottom: 0;
}
/* μž…λ ₯ ν•„λ“œ μŠ€νƒ€μΌ */
input[type="text"] {
flex: 1;
padding: 12px;
border: 1px solid #e0e0e0;
border-radius: 8px;
font-size: 16px;
transition: border-color 0.3s ease;
}
input[type="text"]:focus {
border-color: #2196f3;
outline: none;
}
/* λ²„νŠΌ μŠ€νƒ€μΌ */
button {
padding: 12px 24px;
border: none;
border-radius: 8px;
background-color: #2196f3;
color: white;
font-weight: 600;
cursor: pointer;
transition: background-color 0.3s ease;
}
button:hover {
background-color: #1976d2;
}
/* μ„€μ • νŒ¨λ„ μŠ€νƒ€μΌ */
.settings-panel {
background: #ffffff;
padding: 20px;
border-radius: 10px;
box-shadow: 0 2px 6px rgba(0, 0, 0, 0.1);
}
/* λ“œλ‘­λ‹€μš΄ μŠ€νƒ€μΌ */
select {
width: 100%;
padding: 8px;
border: 1px solid #e0e0e0;
border-radius: 6px;
margin-bottom: 10px;
}
/* μŠ¬λΌμ΄λ” μŠ€νƒ€μΌ */
input[type="range"] {
width: 100%;
margin: 10px 0;
}
"""
with gr.Blocks(css=custom_css) as demo:
gr.Markdown("""
# 🎬 Personalized Movie Recommender
μ•ˆλ…•ν•˜μ„Έμš”! λ‹Ήμ‹ λ§Œμ„ μœ„ν•œ μ˜ν™” μΆ”μ²œ μ‹œμŠ€ν…œμž…λ‹ˆλ‹€.
μ„ ν˜Έν•˜λŠ” μž₯λ₯΄μ™€ ν˜„μž¬ 기뢄을 μ•Œλ €μ£Όμ‹œλ©΄, λ§žμΆ€ν˜• μ˜ν™”λ₯Ό μΆ”μ²œν•΄λ“œλ¦½λ‹ˆλ‹€.
""")
with gr.Row():
with gr.Column(scale=2):
with gr.Group(elem_classes="chat-container"):
chatbot = gr.Chatbot(
height=600,
show_copy_button=True,
avatar_images=("πŸ‘€", "🎬"),
bubble_full_width=False,
elem_classes=["chat-message"],
type="messages" # OpenAI μŠ€νƒ€μΌ λ©”μ‹œμ§€ ν˜•μ‹ μ‚¬μš©
)
with gr.Group(elem_classes="input-container"):
msg = gr.Textbox(
placeholder="μ–΄λ–€ μ˜ν™”λ₯Ό μ°Ύκ³  κ³„μ‹ κ°€μš”?",
show_label=False,
container=False
)
with gr.Row():
submit = gr.Button("μΆ”μ²œ λ°›κΈ°", variant="primary", size="sm")
clear = gr.Button("λŒ€ν™” μ΄ˆκΈ°ν™”", size="sm")
with gr.Column(scale=1):
with gr.Group(elem_classes="settings-panel"):
gr.Markdown("### 🎯 μΆ”μ²œ μ„€μ •")
genre = gr.Dropdown(
choices=["μ•‘μ…˜", "μ½”λ―Έλ””", "λ“œλΌλ§ˆ", "둜맨슀", "슀릴러", "SF", "νŒνƒ€μ§€", "μ• λ‹ˆλ©”μ΄μ…˜"],
label="μ„ ν˜Έν•˜λŠ” μž₯λ₯΄",
multiselect=True
)
mood = gr.Dropdown(
choices=["μ‹ λ‚˜λŠ”", "감성적인", "κΈ΄μž₯감 μžˆλŠ”", "νŽΈμ•ˆν•œ", "μ‹ λΉ„λ‘œμš΄"],
label="ν˜„μž¬ κΈ°λΆ„",
multiselect=True
)
with gr.Group(elem_classes="settings-panel"):
gr.Markdown("### πŸ€– Agent μ„€μ •")
agent_type = gr.Dropdown(
choices=["μ „λ¬Έκ°€", "친ꡬ", "μ˜ν™” 평둠가", "νλ ˆμ΄ν„°"],
label="Agent μœ ν˜•",
value="μ „λ¬Έκ°€"
)
personality = gr.Dropdown(
choices=["μΉœκ·Όν•œ", "전문적인", "μœ λ¨ΈλŸ¬μŠ€ν•œ", "감성적인", "객관적인"],
label="성격",
value="μΉœκ·Όν•œ"
)
expertise_level = gr.Dropdown(
choices=["초보자", "μ€‘κΈ‰μž", "μ „λ¬Έκ°€"],
label="μ„€λͺ… μˆ˜μ€€",
value="μ€‘κΈ‰μž"
)
language = gr.Dropdown(
choices=["ν•œκ΅­μ–΄", "μ˜μ–΄", "일본어"],
label="응닡 μ–Έμ–΄",
value="ν•œκ΅­μ–΄"
)
with gr.Group(elem_classes="settings-panel"):
gr.Markdown("### βš™οΈ κ³ κΈ‰ μ„€μ •")
max_tokens = gr.Slider(
minimum=1,
maximum=2048,
value=512,
step=1,
label="μ΅œλŒ€ 토큰 수"
)
temperature = gr.Slider(
minimum=0.1,
maximum=4.0,
value=0.7,
step=0.1,
label="Temperature"
)
top_p = gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.95,
step=0.05,
label="Top-p"
)
# μ„€μ • λ³€κ²½ μ‹œ μ±„νŒ… μ΄ˆκΈ°ν™” 및 μ•Œλ¦Ό ν‘œμ‹œ
for component in [agent_type, personality, expertise_level, language]:
component.change(
fn=show_settings_changed_info,
inputs=[agent_type, personality, expertise_level, language],
outputs=gr.Info()
).then(
fn=reset_chat,
outputs=chatbot
)
submit.click(
respond,
inputs=[
msg,
chatbot,
agent_type,
personality,
expertise_level,
language,
max_tokens,
temperature,
top_p,
genre,
mood,
],
outputs=chatbot,
).then(
lambda: "",
None,
msg,
queue=False
)
clear.click(lambda: None, None, chatbot, queue=False)
if __name__ == "__main__":
demo.launch()