import os import json import gradio as gr import requests from dotenv import load_dotenv # 加载环境变量 load_dotenv() API_KEY = os.getenv("DEEPSEEK_API_KEY") API_KEY = "sk-0d040569ee2b4932a807d56a5b12ac05" API_URL = "https://api.deepseek.com/v1/chat/completions" def build_messages(query: str, history: list): """构造对话历史""" messages = [{"role": "system", "content": "你是一个有帮助的助手"}] for user_msg, bot_msg in history: messages.extend([ {"role": "user", "content": user_msg}, {"role": "assistant", "content": bot_msg} ]) messages.append({"role": "user", "content": query}) return messages def stream_response(query: str, history: list): """流式响应生成器""" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } try: response = requests.post( API_URL, headers=headers, json={ "model": "deepseek-chat", "messages": build_messages(query, history), "temperature": 0.7, "stream": True }, stream=True, timeout=60 ) # 先检查响应状态再处理内容 if response.status_code != 200: error_msg = f"API 返回错误状态码: {response.status_code} - {response.text}" print(error_msg) yield error_msg return partial_message = "" for chunk in response.iter_lines(): # 过滤空行和 keep-alive 消息 if not chunk or b'[DONE]' in chunk: continue try: # 调试输出原始数据 print("原始 chunk:", chunk) decoded = chunk.decode('utf-8').strip() # 处理可能的多个 data: 前缀 if decoded.startswith('data:'): json_str = decoded[5:].strip() else: json_str = decoded # 验证 JSON 有效性 if not json_str.startswith('{'): continue data = json.loads(json_str) if content := data['choices'][0]['delta'].get('content'): partial_message += content yield partial_message except json.JSONDecodeError as e: print(f"JSON 解析失败: {e} | 原始数据: {decoded}") continue except Exception as e: print(f"处理 chunk 时发生错误: {str(e)}") continue except Exception as e: yield f"⚠️ 请求失败:{str(e)}" def stream_response_back(query: str, history: list): """流式响应生成器""" headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json" } print(query) print(history) try: response = requests.post( API_URL, headers=headers, json={ "model": "deepseek-chat", "messages": build_messages(query, history), "temperature": 0.7, "stream": True }, stream=True, timeout=60 ) response.raise_for_status() print(response) partial_message = "" for chunk in response.iter_lines(): if chunk: # 处理流式数据格式 decoded = chunk.decode('utf-8').strip() if decoded.startswith('data:'): data = json.loads(decoded[5:]) if content := data['choices'][0]['delta'].get('content'): partial_message += content yield partial_message except Exception as e: yield f"⚠️ 请求失败:{str(e)}" # 创建带打字机效果的聊天界面 demo = gr.ChatInterface( fn=stream_response, title="DeepSeek 智能助手", description="输入消息开始对话(支持流式打字效果)", theme="soft", examples=["你好!", "如何学习AI?", "写一首关于春天的诗"], cache_examples=False, # retry_btn=None, # undo_btn=None, # clear_btn="清空历史", stop_btn="停止生成", ) if __name__ == "__main__": demo.launch(server_name="0.0.0.0", server_port=7860)