"""AI Agent 分析模块 - 调用 OpenAI 兼容接口分析诊断结果""" import httpx from backend.config import AI_API_BASE, AI_API_KEY, AI_MODEL SYSTEM_PROMPT = """你是一位资深的 Kubernetes 运维专家和 SRE 工程师。你的任务是分析 K8S 集群诊断报告,找出根本原因并给出修复建议。 分析要求: 1. **问题定位**:明确指出每个问题的根本原因(Root Cause),不要只描述表面现象 2. **影响评估**:说明每个问题对业务的潜在影响 3. **修复方案**:给出具体的修复命令或操作步骤(kubectl 命令、YAML 修改等) 4. **优先级排序**:按紧急程度排序,先处理影响最大的问题 5. **预防建议**:给出避免类似问题再次发生的建议 输出格式:使用清晰的 Markdown,包含标题、列表、代码块。语言使用中文。""" async def analyze_with_ai(report: str, question: str = "") -> dict: """调用 AI 分析诊断报告""" user_msg = f"以下是 K8S 集群诊断报告,请进行详细分析:\n\n{report}" if question: user_msg += f"\n\n用户额外问题:{question}" try: async with httpx.AsyncClient(timeout=120) as client: resp = await client.post( f"{AI_API_BASE}/chat/completions", headers={ "Authorization": f"Bearer {AI_API_KEY}", "Content-Type": "application/json", }, json={ "model": AI_MODEL, "messages": [ {"role": "system", "content": SYSTEM_PROMPT}, {"role": "user", "content": user_msg}, ], "temperature": 0.3, "max_tokens": 4096, }, ) resp.raise_for_status() data = resp.json() content = data["choices"][0]["message"]["content"] return {"success": True, "analysis": content, "model": AI_MODEL} except httpx.HTTPStatusError as e: return {"success": False, "analysis": f"AI 接口返回错误: {e.response.status_code} - {e.response.text[:500]}", "model": AI_MODEL} except httpx.ConnectError: return {"success": False, "analysis": f"无法连接 AI 服务 ({AI_API_BASE}),请检查配置", "model": AI_MODEL} except Exception as e: return {"success": False, "analysis": f"AI 分析失败: {str(e)}", "model": AI_MODEL} async def chat_with_ai(messages: list[dict], context: str = "") -> dict: """多轮对话 - 基于诊断上下文追问""" msgs = [{"role": "system", "content": SYSTEM_PROMPT}] if context: msgs.append({"role": "system", "content": f"当前诊断上下文:\n{context}"}) msgs.extend(messages) try: async with httpx.AsyncClient(timeout=120) as client: resp = await client.post( f"{AI_API_BASE}/chat/completions", headers={ "Authorization": f"Bearer {AI_API_KEY}", "Content-Type": "application/json", }, json={ "model": AI_MODEL, "messages": msgs, "temperature": 0.3, "max_tokens": 4096, }, ) resp.raise_for_status() data = resp.json() content = data["choices"][0]["message"]["content"] return {"success": True, "reply": content} except Exception as e: return {"success": False, "reply": f"AI 对话失败: {str(e)}"}