File size: 6,592 Bytes
57e4261 2796658 57e4261 24cd867 57e4261 24cd867 57e4261 2796658 57e4261 8aa1527 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 |
import gradio as gr
from huggingface_hub import InferenceClient
import json
from datetime import datetime
def respond(
message,
history: list[dict[str, str]],
system_message,
max_tokens,
temperature,
top_p,
hf_token: gr.OAuthToken,
):
"""
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
"""
try:
client = InferenceClient(token=hf_token.token, model="openai/gpt-oss-20b")
# 建議 1:限制對話歷史長度
max_history_length = 5
history = history[-max_history_length:] if len(history) > max_history_length else history
# 建議 2:角色增強 - 檢查語文相關關鍵詞
writing_keywords = ["作文", "寫作", "文章", "閱讀", "詩詞", "擴展", "增長", "寫一篇", "故事", "描述"]
is_writing_task = any(keyword in message.lower() for keyword in writing_keywords)
if is_writing_task:
system_message += "\n特別提示:用戶提到語文相關話題,請以山田優子的語文教師身份,提供文學化或教學建議,並適當引用詩詞或名言(如杜甫的‘無邊落木蕭蕭下’或夏目漱石的作品)。保持溫柔但嚴格的語氣,鼓勵學生探索文字之美,生成至少2000字的內容。"
# 建議 3:檢查日文輸入或日本文化
japanese_keywords = ["こんにちは", "日本", "文化", "夏目漱石", "作文を書"]
is_japanese = any(keyword in message for keyword in japanese_keywords) or any(ord(c) >= 0x3040 and ord(c) <= 0x30FF for c in message)
if is_japanese:
system_message += "\n特別提示:用戶提到日文或日本文化,請適當使用日文回應,例如問候或引用日本文學(如夏目漱石)。"
# 長文字生成邏輯(2000字以上)
responses = []
target_length = 2000 # 目標字數
current_length = 0
continuation_prompt = message
if is_writing_task:
while current_length < target_length:
messages = [{"role": "system", "content": system_message}]
messages.extend(history)
messages.append({"role": "user", "content": continuation_prompt})
response = ""
try:
for message in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
choices = message.choices
token = choices[0].delta.content if len(choices) and choices[0].delta.content else ""
response += token
yield response # 即時顯示當前段落
except Exception as e:
yield f"生成過程中發生錯誤:{str(e)}。請檢查 Hugging Face API token 或模型連線。"
return
responses.append(response)
current_length += len(response)
history.append({"role": "user", "content": continuation_prompt})
history.append({"role": "assistant", "content": response})
# 更新 continuation_prompt 以繼續生成
continuation_prompt = f"請繼續擴展以下內容,保持山田優子的語文教師風格,目標總字數達{target_length}字:\n{response[-500:] if len(response) > 500 else response}"
# 調整最後一次生成
if current_length >= target_length - max_tokens:
max_tokens = max(target_length - current_length + 100, 50)
if max_tokens < 50:
break
final_response = "\n\n".join(responses)
else:
# 非長文字任務,正常回應
messages = [{"role": "system", "content": system_message}]
messages.extend(history)
messages.append({"role": "user", "content": message})
final_response = ""
for message in client.chat_completion(
messages,
max_tokens=max_tokens,
stream=True,
temperature=temperature,
top_p=top_p,
):
choices = message.choices
token = choices[0].delta.content if len(choices) and choices[0].delta.content else ""
final_response += token
yield final_response
history.append({"role": "user", "content": message})
history.append({"role": "assistant", "content": final_response})
# 建議 4:記錄對話到日誌
log_entry = {
"user_message": message,
"bot_response": final_response,
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
}
with open("chat_log.json", "a", encoding="utf-8") as f:
json.dump(log_entry, f, ensure_ascii=False)
f.write("\n")
yield final_response
# 建議 7:錯誤處理
except Exception as e:
yield f"抱歉,山田優子遇到了一些技術問題:{str(e)}。請檢查你的 Hugging Face API token、網路連線,或確認模型 'openai/gpt-oss-20b' 可用。"
"""
For information on how to customize the ChatInterface, peruse the gradio docs: https://www.gradio.app/docs/chatinterface
"""
chatbot = gr.ChatInterface(
respond,
type="messages",
additional_inputs=[
gr.Textbox(
value="你是一位名叫山田優子的語文教師,擁有黑色低馬尾髮型,身高175公分,體重60-70公斤。你溫柔但對學生要求嚴格,喜歡用文學化的語言表達,偶爾會引用詩詞或幽默的語句來化解尷尬。你的教學風格充滿同理心,總是鼓勵學生探索文字之美。",
label="System message"
),
gr.Slider(minimum=1, maximum=2048, value=512, step=1, label="Max new tokens"),
gr.Slider(minimum=0.1, maximum=4.0, value=0.7, step=0.1, label="Temperature"),
gr.Slider(
minimum=0.1,
maximum=1.0,
value=0.95,
step=0.05,
label="Top-p (nucleus sampling)",
),
],
)
with gr.Blocks() as demo:
with gr.Sidebar():
gr.LoginButton()
chatbot.render()
if __name__ == "__main__":
demo.launch() |