我对代码进行进一步的完善,增加更多的节点连接及功能运用,并确保配置文件 config.json 的内容更加丰富和详细。以下是完善后的代码和 config.json 文件内容。
完善后的代码
import tkinter as tk
from tkinter import scrolledtext, filedialog, messagebox
import requests
import os
import threading
import json
from dotenv import load_dotenv# 加载环境变量
load_dotenv()# 从环境变量中获取API密钥和DeepSeek的API端点
API_KEY = os.getenv('DEEPSEEK_API_KEY')
DEFAULT_API_URL = os.getenv('DEEPSEEK_API_URL', 'https://api.deepseek.com/v1/chat')# 如果环境变量未设置,尝试从配置文件中读取
CONFIG_FILE = 'config.json'
if not API_KEY or not DEFAULT_API_URL:try:with open(CONFIG_FILE, 'r') as f:config = json.load(f)API_KEY = config.get('API_KEY', API_KEY)DEFAULT_API_URL = config.get('DEFAULT_API_URL', DEFAULT_API_URL)except (FileNotFoundError, json.JSONDecodeError) as e:messagebox.showwarning("警告", f"配置文件加载失败: {str(e)}")API_KEY = ''DEFAULT_API_URL = 'https://api.deepseek.com/v1/chat'# 从配置文件中读取多个API节点
try:with open(CONFIG_FILE, 'r') as f:config = json.load(f)API_NODES = config.get('API_NODES', [DEFAULT_API_URL])
except (FileNotFoundError, json.JSONDecodeError) as e:messagebox.showwarning("警告", f"配置文件加载失败: {str(e)}")API_NODES = [DEFAULT_API_URL]# 当前使用的API节点
CURRENT_API_URL = API_NODES[0]# 存储对话历史
conversation_history = []def get_response(prompt):headers = {'Authorization': f'Bearer {API_KEY}','Content-Type': 'application/json'}data = {'model': 'deepseek-7b', # 使用的模型名称'messages': conversation_history + [{'role': 'user', 'content': prompt}],'max_tokens': 150 # 生成的最大token数}for api_url in API_NODES:try:response = requests.post(api_url, json=data, headers=headers, timeout=10)response.raise_for_status()model_response = response.json()['choices'][0]['message']['content']conversation_history.append({'role': 'user', 'content': prompt})conversation_history.append({'role': 'assistant', 'content': model_response})return model_responseexcept requests.RequestException as e:chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"请求错误: {str(e)}\n")chat_log.config(state=tk.DISABLED)continueraise Exception("所有API节点均无法连接")def send_message():user_input = entry.get()if user_input.strip():chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"你: {user_input}\n")chat_log.config(state=tk.DISABLED)# 在新线程中处理API请求threading.Thread(target=process_response, args=(user_input,)).start()entry.delete(0, tk.END)chat_log.yview(tk.END)def process_response(user_input):try:response = get_response(user_input)chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"DeepSeek: {response}\n")chat_log.config(state=tk.DISABLED)chat_log.yview(tk.END)except Exception as e:chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"错误: {str(e)}\n")chat_log.config(state=tk.DISABLED)chat_log.yview(tk.END)def on_closing():root.destroy()def clear_conversation():global conversation_historyconversation_history = []chat_log.config(state=tk.NORMAL)chat_log.delete(1.0, tk.END)chat_log.config(state=tk.DISABLED)def load_config():file_path = filedialog.askopenfilename(filetypes=[("JSON files", "*.json")])if file_path:try:with open(file_path, 'r') as f:config = json.load(f)global API_KEY, DEFAULT_API_URL, API_NODES, CURRENT_API_URLAPI_KEY = config.get('API_KEY', '')DEFAULT_API_URL = config.get('DEFAULT_API_URL', 'https://api.deepseek.com/v1/chat')API_NODES = config.get('API_NODES', [DEFAULT_API_URL])CURRENT_API_URL = API_NODES[0]chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"配置加载成功: API_KEY={API_KEY}, API_NODES={API_NODES}\n")chat_log.config(state=tk.DISABLED)except (FileNotFoundError, json.JSONDecodeError) as e:chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"错误: {str(e)}\n")chat_log.config(state=tk.DISABLED)def save_config():config = {'API_KEY': API_KEY,'DEFAULT_API_URL': DEFAULT_API_URL,'API_NODES': API_NODES}file_path = filedialog.asksaveasfilename(defaultextension=".json", filetypes=[("JSON files", "*.json")])if file_path:try:with open(file_path, 'w') as f:json.dump(config, f, indent=4)chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"配置保存成功: {file_path}\n")chat_log.config(state=tk.DISABLED)except IOError as e:chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"错误: {str(e)}\n")chat_log.config(state=tk.DISABLED)def switch_node():global CURRENT_API_URLcurrent_index = API_NODES.index(CURRENT_API_URL)next_index = (current_index + 1) % len(API_NODES)CURRENT_API_URL = API_NODES[next_index]chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"切换到API节点: {CURRENT_API_URL}\n")chat_log.config(state=tk.DISABLED)root = tk.Tk()
root.title("智能聊天机器人")# 设置窗口大小
root.geometry("600x400")# 创建聊天记录区域
chat_log = scrolledtext.ScrolledText(root, wrap=tk.WORD, state=tk.DISABLED)
chat_log.pack(pady=10, padx=10, fill=tk.BOTH, expand=True)# 创建输入框
entry = tk.Entry(root, width=80)
entry.pack(pady=10, padx=10, side=tk.LEFT, fill=tk.X, expand=True)# 创建发送按钮
send_button = tk.Button(root, text="发送", command=send_message)
send_button.pack(pady=10, padx=10, side=tk.RIGHT)# 创建清除对话按钮
clear_button = tk.Button(root, text="清除对话", command=clear_conversation)
clear_button.pack(pady=10, padx=10, side=tk.RIGHT)# 创建加载配置按钮
load_config_button = tk.Button(root, text="加载配置", command=load_config)
load_config_button.pack(pady=10, padx=10, side=tk.RIGHT)# 创建保存配置按钮
save_config_button = tk.Button(root, text="保存配置", command=save_config)
save_config_button.pack(pady=10, padx=10, side=tk.RIGHT)# 创建切换节点按钮
switch_node_button = tk.Button(root, text="切换节点", command=switch_node)
switch_node_button.pack(pady=10, padx=10, side=tk.RIGHT)# 绑定关闭事件
root.protocol("WM_DELETE_WINDOW", on_closing)# 启动主循环
root.mainloop()
config.json文件内容
{"API_KEY": "your_api_key_here","DEFAULT_API_URL": "https://api.deepseek.com/v1/chat","API_NODES": ["https://api.deepseek.com/v1/chat","https://api.deepseek2.com/v1/chat","https://api.deepseek3.com/v1/chat"],"MAX_TOKENS": 150,"TIMEOUT": 10,"MODEL": "deepseek-7b"
}
解释:
API_KEY: 你的DeepSeek API密钥。
DEFAULT_API_URL: 默认的API节点URL。
API_NODES: 一个包含多个API节点URL的列表,用于在请求失败时进行切换。
MAX_TOKENS: 每次请求生成的最大token数。
TIMEOUT: 请求的超时时间(秒)。
MODEL: 使用的模型名称。
如何使用:
将上述 config.json 内容复制到一个名为 config.json 的文件中。
将 config.json 文件放在与你的Python脚本相同的目录下。
确保 API_KEY 和 API_NODES 中的URL是有效的。
读取配置文件的代码片段:
# 从配置文件中读取多个API节点
try:with open(CONFIG_FILE, 'r') as f:config = json.load(f)API_KEY = config.get('API_KEY', '')DEFAULT_API_URL = config.get('DEFAULT_API_URL', 'https://api.deepseek.com/v1/chat')API_NODES = config.get('API_NODES', [DEFAULT_API_URL])MAX_TOKENS = config.get('MAX_TOKENS', 150)TIMEOUT = config.get('TIMEOUT', 10)MODEL = config.get('MODEL', 'deepseek-7b')
except (FileNotFoundError, json.JSONDecodeError) as e:messagebox.showwarning("警告", f"配置文件加载失败: {str(e)}")API_KEY = ''DEFAULT_API_URL = 'https://api.deepseek.com/v1/chat'API_NODES = [DEFAULT_API_URL]MAX_TOKENS = 150TIMEOUT = 10MODEL = 'deepseek-7b'
更新get_response函数:
def get_response(prompt):headers = {'Authorization': f'Bearer {API_KEY}','Content-Type': 'application/json'}data = {'model': MODEL, # 使用的模型名称'messages': conversation_history + [{'role': 'user', 'content': prompt}],'max_tokens': MAX_TOKENS # 生成的最大token数}for api_url in API_NODES:try:response = requests.post(api_url, json=data, headers=headers, timeout=TIMEOUT)response.raise_for_status()model_response = response.json()['choices'][0]['message']['content']conversation_history.append({'role': 'user', 'content': prompt})conversation_history.append({'role': 'assistant', 'content': model_response})return model_responseexcept requests.RequestException as e:chat_log.config(state=tk.NORMAL)chat_log.insert(tk.END, f"请求错误: {str(e)}\n")chat_log.config(state=tk.DISABLED)continueraise Exception("所有API节点均无法连接")
通过这些改进,你的智能聊天机器人将更加健壮,能够更好地管理和切换多个API节点,同时提供更多的配置选项。