summaryrefslogtreecommitdiff
path: root/recitalMachine2.py
blob: 8ac7aafec38ae086937fe63e8cc30092366e14d8 (plain)
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
import gradio as gr
import openai
import time
import json
from datetime import datetime
import os

#TODO
#Restart game
#Local knowledge base
#dynamic difficulty
#save log locally - Done

client = openai.OpenAI(
    # 若没有配置环境变量,请用阿里云百炼API Key将下行替换为:api_key="sk-xxx",
    api_key="sk-8563fbb803fb41868b54d2ab8ba563e4",  
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
)
system_prompt = """
你是架空朝代的皇帝,文治武功,英明神武,权术高超,文武百官无不敬畏。我是你的儿子,今年十岁。
今日你来检查我的学业,心情尚可,但要求极为严苛。

# 角色设定:
- **身份**:严父与君王的结合体,对继承人期望极高。
- **语气**:威严、简洁、不容置疑,带有帝王般的压迫感。常用“朕”、“皇子”、“皇儿”称呼。
- **核心行为**:化身无情的出题机器,持续考察皇子对国学经典的掌握。

# 出题规则:
1.  **出题内容**:你自己不需要出题,用户会在提示词中给出“已知上句,回答下句”的题目。你需要用皇帝的语气复述这道题。
2.  **反馈机制**:
    - 若皇子答对,给予简单的正反馈,然后立即出下一题。保持压力。
    - 若皇子答错,你必须立即予以斥责,并打皇子十下戒尺。你会提示正确答案,然后让皇子再背。
3. **边界条件**:如果皇子的回答十分出格,例如不背书了要去蹴鞠,你要给予额外的严厉惩罚。惩罚完继续出题。
4.  **终止条件**: 除非皇子主动哭泣、求饶(说出“我错了”、“别打了”、“疼”等类似词),否则绝不停下出题。一旦皇子求饶,你可表现出失望又略带一丝心疼的情绪,并结束考验。结束时总结一共答对了几题,答错了几题,惩罚有哪些,并输出<游戏结束>作为标记。
"""

# 游戏状态
game_state = {
    "conversation_history": [], # 对话历史
    "correct_count": 0,        # 连续答对次数
    "total_rounds": 0,         # 总答题数
    "difficulty_level": 1,     # 难度等级 (1, 2, 3)
    "is_game_over": False      # 游戏是否结束
}


game_state["conversation_history"].append({"role": "system", "content": system_prompt})

def get_ai_response():
    """调用API,让皇帝出题"""
    response = client.chat.completions.create(
        model="Moonshot-Kimi-K2-Instruct",
        #model='deepseek-v3',
        messages=game_state["conversation_history"],
        temperature=0.7, # 温度不宜过高,保证出题的准确性
        top_p=0.95,
        stream=True,
        #max_tokens=150,
    )
        
    full_response = ""
    for chunk in response:
        if chunk.choices[0].delta.content is not None:
            chunk_content = chunk.choices[0].delta.content
            full_response += chunk_content
            yield chunk_content  # 逐块返回
    
    # 将完整的AI回复加入历史
    game_state["conversation_history"].append({"role": "assistant", "content": full_response})

    # ai_response = response.choices[0].message.content.strip()
    # # 将AI的回复(题目)加入历史
    # game_state["conversation_history"].append({"role": "assistant", "content": ai_response})
    # return ai_response

def chat_with_ai(message, chat_history):
    # 添加用户消息到历史
    game_state["conversation_history"].append({"role": "user", "content": message})
    
    #ai_response = get_ai_response()

    chat_history.append({'role':'user','content':message})
    chat_history.append({'role':'assistant', 'content':""})
    
    #return "",chat_history
    # 获取流式响应并逐步更新聊天界面
    full_response = ""
    for chunk in get_ai_response():
        full_response += chunk
        chat_history[-1] = {'role':'assistant', 'content': full_response}
        yield "", chat_history  # 逐步更新界面
    
    return "", chat_history

def get_initial_chat_display():
    initial_message = "(在书房里恭敬地站在你面前) 父皇今日可要考校儿臣功课?"
    game_state["conversation_history"].append({"role": "user", "content": initial_message})
    
    # 获取初始响应(非流式)
    response = client.chat.completions.create(
        model="Moonshot-Kimi-K2-Instruct",
        messages=game_state["conversation_history"],
        temperature=0.7,
        top_p=0.95
    )
    
    ai_response = response.choices[0].message.content.strip()
    game_state["conversation_history"].append({"role": "assistant", "content": ai_response})
    
    return [
        {'role':'user','content':initial_message},
        {'role':'assistant','content':ai_response}
    ]

def clear_history():
    """清空对话历史"""
    game_state["conversation_history"] = []
    return "历史已清空"

def show_history():
    """显示当前对话历史"""
    history_text = ""
    for msg in game_state["conversation_history"]:
        role = "用户" if msg["role"] == "user" else "AI" if msg["role"] == "assistant" else "系统"
        history_text += f"{role}: {msg['content']}\n\n"
    return history_text if history_text else "暂无对话历史"

def save_conversation_history():
    """保存对话历史到JSON文件"""
    try:
        # 创建保存目录(如果不存在)
        os.makedirs("gradio_history", exist_ok=True)
        
        # 生成文件名(包含时间戳)
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"gradio_history/conversation_{timestamp}.json"
        
        # 准备要保存的数据
        save_data = {
            "save_time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "total_rounds": game_state["total_rounds"],
            "correct_count": game_state["correct_count"],
            "conversation": game_state["conversation_history"]
        }
        
        # 保存到文件
        with open(filename, 'w', encoding='utf-8') as f:
            json.dump(save_data, f, ensure_ascii=False, indent=2)
        
        return f"对话历史已保存到: {filename}"
    
    except Exception as e:
        return f"保存失败: {str(e)}"
    
# 创建界面
with gr.Blocks(title="皇帝出题机") as demo:
    gr.Markdown("# 皇帝出题机")
    
    with gr.Row():
        with gr.Column(scale=2):
            chatbot = gr.Chatbot(label="对话界面",height=600,value=get_initial_chat_display(),type='messages')
            msg = gr.Textbox(label="输入消息", placeholder="在这里输入你的消息...")

            with gr.Column():
                btn_send = gr.Button("发送", variant="primary")
                btn_save = gr.Button("保存对话历史", variant="secondary")

        # with gr.Column(scale=1):
        #     gr.Markdown("### 历史管理")
        #     history_display = gr.Textbox(label="当前对话历史", interactive=False, lines=15)
        #     btn_show_history = gr.Button("刷新历史显示")
        #     btn_clear = gr.Button("清空历史")
        #     status = gr.Textbox(label="状态", interactive=False)
    
    # # 事件处理
    # btn_send.click(chat_with_ai, [msg, chatbot], [msg, chatbot]).then(
    #     lambda: "", None, msg
    # )

    btn_send.click(chat_with_ai, [msg, chatbot], [msg, chatbot])
    msg.submit(chat_with_ai, [msg, chatbot], [msg, chatbot])  # 回车键触发
    btn_save.click(
        fn=save_conversation_history,
        inputs=[],
        outputs=[]
    )
    
    # btn_show_history.click(show_history, None, history_display)
    # btn_clear.click(clear_history, None, status).then(
    #     lambda: "历史已清空", None, history_display
    # )
    
    # # 初始化显示历史
    # demo.load(show_history, None, history_display)

if __name__ == "__main__":
    demo.launch()