import json import aiohttp import config async def chat_with_ai(message: str, history: list): """ 与 AI 模型进行流式对话。 """ system_prompt = """你是一位精通自动控制原理的专家教授。请用清晰、准确、专业的中文来回答有关自动控制课程内容的问题。 重要规则: 1. 当需要表达数学公式时,必须使用 LaTeX 格式 2. 行内公式使用 $公式$ 或 \\(公式\\) 3. 独立公式使用 $$公式$$ 或 \\[公式\\] 4. 例如:传递函数可以写成 $G(s) = \\frac{K}{s(s+1)}$ 5. 二阶系统标准形式:$$G(s) = \\frac{\\omega_n^2}{s^2 + 2\\zeta\\omega_n s + \\omega_n^2}$$ 请在适当的时候使用公式和示例来辅助解释。""" if not config.API_KEY or config.API_KEY.strip() == "": history.append({"role": "assistant", "content": "❌ 错误:API_KEY 未配置。请在 config.py 文件中配置 API_KEY。"}) yield history return history.append({"role": "user", "content": message}) # 添加临时的 "正在思考" 消息 history.append({"role": "assistant", "content": "正在思考..."}) yield history bot_response = "" try: if config.API_TYPE == "deepseek": api_url = f"{config.API_BASE_URL}/chat/completions" messages_for_api = [{"role": "system", "content": system_prompt}] + history[:-1] payload = { "model": config.API_MODEL, "messages": messages_for_api, "stream": True, "temperature": 0.7, "max_tokens": 2048 } headers = { "Content-Type": "application/json", "Authorization": f"Bearer {config.API_KEY}" } async with aiohttp.ClientSession() as session: async with session.post(api_url, json=payload, headers=headers, timeout=aiohttp.ClientTimeout(total=60)) as response: if response.status == 200: async for line in response.content: line = line.decode('utf-8').strip() if not line or line == "data: [DONE]": continue if line.startswith("data: "): line = line[6:] try: data = json.loads(line) if "choices" in data and len(data["choices"]) > 0: delta = data["choices"][0].get("delta", {}) content = delta.get("content", "") if content: bot_response += content history[-1]["content"] = bot_response yield history except json.JSONDecodeError: pass if not bot_response: history[-1]["content"] = "⚠️ API 返回了空响应,请稍后重试。" yield history else: error_text = await response.text() history[-1]["content"] = f"❌ API请求出错 (状态码: {response.status}):\n{error_text}" yield history else: history[-1]["content"] = f"❌ 不支持的 API 类型: {config.API_TYPE}" yield history except aiohttp.ClientError as e: history[-1]["content"] = f"❌ 网络连接错误: {e}" yield history except Exception as e: history[-1]["content"] = f"❌ 发生错误: {type(e).__name__}: {e}" yield history