Python實例題
題目
基于 Python 的簡單聊天機器人
要求:
- 使用 Python 構建一個聊天機器人,支持以下功能:
- 基于規則的簡單問答系統
- 關鍵詞匹配和意圖識別
- 上下文記憶功能
- 支持多輪對話
- 可擴展的知識庫
- 使用
tkinter
構建圖形用戶界面。 - 實現至少 5 個不同領域的問答功能。
解題思路:
- 使用
tkinter
構建界面,包括消息顯示區和輸入框。 - 設計基于規則的問答引擎,使用關鍵詞匹配和模式識別。
- 實現簡單的上下文管理,支持多輪對話。
代碼實現:
import tkinter as tk
from tkinter import ttk, scrolledtext
import re
import random
import time
from datetime import datetimeclass ChatBot:def __init__(self, root):self.root = rootself.root.title("智能聊天機器人")self.root.geometry("600x700")# 對話歷史self.chat_history = []# 上下文記憶self.context = {}# 知識庫self.knowledge_base = self._load_knowledge_base()# 創建主界面self.create_main_window()def _load_knowledge_base(self):"""加載知識庫"""return {"問候": {"patterns": ["你好", "hi", "hello", "嗨", "早上好", "中午好", "晚上好"],"responses": ["你好!有什么我可以幫助你的嗎?", "嗨,今天過得怎么樣?", "你好呀!", "很高興見到你!"]},"天氣": {"patterns": ["天氣", "下雨", "晴天", "溫度", "多云"],"responses": ["我無法實時獲取天氣信息呢。你可以查看天氣預報網站或應用程序。", "天氣變化莫測,建議你出門前查看一下天氣預報。"]},"時間": {"patterns": ["時間", "幾點", "什么時候"],"responses": ["現在的時間是:{}", "當前時間為:{}"]},"姓名": {"patterns": ["你叫什么", "名字", "稱呼"],"responses": ["我叫智能聊天機器人,你可以叫我小智。", "我是小智,很高興認識你!"]},"愛好": {"patterns": ["喜歡", "愛好", "興趣"],"responses": ["我喜歡和人聊天,了解各種知識!", "我的愛好是回答你的問題,有什么想聊的嗎?"]},"功能": {"patterns": ["能做什么", "功能", "可以幫助", "用途"],"responses": ["我可以回答問題、提供信息、陪你聊天,還可以和你討論各種話題!", "我是一個多功能聊天機器人,有什么需要我幫忙的嗎?"]},"再見": {"patterns": ["再見", "拜拜", "bye", "下次見", "回頭見"],"responses": ["再見!祝你有個愉快的一天!", "期待下次再聊,拜拜!", "bye~"]},"感謝": {"patterns": ["謝謝", "感謝", "感激", "謝謝啦"],"responses": ["不客氣,隨時為你服務!", "能幫到你我很開心!", "這是我應該做的!"]},"吃飯": {"patterns": ["吃什么", "推薦食物", "午餐", "晚餐", "早餐"],"responses": ["今天推薦你嘗試一下意大利面,配上紅酒和沙拉,非常美味!", "如果你喜歡中餐,可以試試宮保雞丁和炒飯。", "壽司和刺身也是不錯的選擇哦!"]},"旅游": {"patterns": ["旅游", "去哪里玩", "推薦景點", "旅行"],"responses": ["如果你喜歡自然風光,可以考慮去黃山或張家界。", "歷史愛好者可以去北京、西安等古都。", "喜歡海濱城市的話,三亞和廈門是不錯的選擇。"]},"學習": {"patterns": ["學習", "如何學習", "提高成績", "讀書"],"responses": ["制定合理的學習計劃很重要,每天堅持學習一定時間。", "多做練習、總結歸納是提高學習效果的好方法。", "閱讀是獲取知識的有效途徑,建議你多讀書。"]}}def create_main_window(self):"""創建主窗口"""# 創建頂部標題ttk.Label(self.root, text="智能聊天機器人", font=('SimHei', 16, 'bold')).pack(pady=10)# 創建聊天歷史顯示區域chat_frame = ttk.LabelFrame(self.root, text="聊天記錄")chat_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=5)self.chat_display = scrolledtext.ScrolledText(chat_frame, wrap=tk.WORD, state=tk.DISABLED)self.chat_display.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)# 創建輸入區域input_frame = ttk.Frame(self.root)input_frame.pack(fill=tk.X, padx=10, pady=10)self.message_var = tk.StringVar()message_entry = ttk.Entry(input_frame, textvariable=self.message_var, width=50)message_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=5)message_entry.bind("<Return>", self.send_message)ttk.Button(input_frame, text="發送", command=self.send_message).pack(side=tk.RIGHT, padx=5)# 創建狀態欄self.status_var = tk.StringVar(value="就緒")ttk.Label(self.root, textvariable=self.status_var, relief=tk.SUNKEN, anchor=tk.W).pack(side=tk.BOTTOM, fill=tk.X)# 顯示歡迎信息self._display_message("機器人", "你好!我是智能聊天機器人,有什么可以幫助你的嗎?")def send_message(self, event=None):"""發送消息"""message = self.message_var.get().strip()if not message:return# 顯示用戶消息self._display_message("你", message)# 清空輸入框self.message_var.set("")# 更新狀態欄self.status_var.set("思考中...")# 在單獨的線程中生成回復threading.Thread(target=self._generate_response, args=(message,)).start()def _generate_response(self, message):"""生成回復"""try:# 記錄對話歷史self.chat_history.append(("你", message))# 處理消息response = self._process_message(message)# 延遲顯示,模擬思考time.sleep(0.5)# 顯示回復self.root.after(0, lambda: self._display_message("機器人", response))# 更新狀態欄self.root.after(0, lambda: self.status_var.set("就緒"))except Exception as e:self.root.after(0, lambda: self._display_message("機器人", f"抱歉,發生了錯誤:{str(e)}"))self.root.after(0, lambda: self.status_var.set("就緒"))def _process_message(self, message):"""處理用戶消息"""# 預處理消息message = message.lower()# 檢查是否有上下文if 'context' in self.context:context = self.context['context']if context == 'time':# 處理時間相關的上下文del self.context['context']return datetime.now().strftime("%Y-%m-%d %H:%M:%S")# 檢查知識庫匹配for category, data in self.knowledge_base.items():for pattern in data['patterns']:if re.search(pattern, message):# 特殊處理時間查詢if category == "時間":self.context['context'] = 'time'# 隨機選擇一個回復response = random.choice(data['responses'])# 如果回復中需要填充內容if "{}" in response:if category == "時間":response = response.format(datetime.now().strftime("%Y-%m-%d %H:%M:%S"))return response# 如果沒有匹配到任何內容return "抱歉,我不理解你的問題。你可以換一種表達方式或問我其他問題。"def _display_message(self, sender, message):"""顯示消息"""self.chat_display.config(state=tk.NORMAL)# 添加消息timestamp = datetime.now().strftime("%H:%M:%S")self.chat_display.insert(tk.END, f"[{timestamp}] {sender}: {message}\n\n")# 滾動到底部self.chat_display.see(tk.END)# 禁用編輯self.chat_display.config(state=tk.DISABLED)if __name__ == "__main__":root = tk.Tk()app = ChatBot(root)root.mainloop()