diff --git a/.idea/AI-powered-switches.iml b/.idea/AI-powered-switches.iml index b5db305..a1bf3bb 100644 --- a/.idea/AI-powered-switches.iml +++ b/.idea/AI-powered-switches.iml @@ -9,7 +9,7 @@ - + diff --git a/src/backend/app/services/ai_services.py b/src/backend/app/services/ai_services.py index a213f27..8953941 100644 --- a/src/backend/app/services/ai_services.py +++ b/src/backend/app/services/ai_services.py @@ -1,64 +1,69 @@ +from typing import Dict, Any, Coroutine +from openai import OpenAI import json -import httpx -from typing import Dict, Any from src.backend.app.utils.exceptions import SiliconFlowAPIException +from openai.types.chat import ChatCompletionSystemMessageParam, ChatCompletionUserMessageParam +from src.backend.app.utils.logger import logger class AIService: def __init__(self, api_key: str, api_url: str): self.api_key = api_key self.api_url = api_url - self.headers = { - "Authorization": f"Bearer {self.api_key}", - "Content-Type": "application/json" - } + self.client = OpenAI( + api_key=self.api_key, + base_url=self.api_url + ) - async def parse_command(self, command: str) -> Dict[str, Any]: + async def parse_command(self, command: str) -> Any | None: """ 调用硅基流动API解析中文命令 """ - prompt = f""" - 你是一个网络设备配置专家,请将以下中文命令转换为网络设备配置JSON。 - 支持的配置包括:VLAN、端口、路由、ACL等。 - 返回格式必须为JSON,包含配置类型和详细参数。 - - 命令:{command} + prompt = """ + 你是一个网络设备配置专家,精通各种类型的路由器的配置,请将以下用户的中文命令转换为网络设备配置JSON + 但是请注意,由于贪婪的人们追求极高的效率,所以你必须严格按照 JSON 格式返回数据,不要包含任何额外文本或 Markdown 代码块 + 返回格式要求: + 1. 必须包含'type'字段指明配置类型(vlan/interface/acl/route等) + 2. 必须包含'commands'字段,包含可直接执行的命令列表 + 3. 其他参数根据配置类型动态添加 + 4. 不要包含解释性文本、步骤说明或注释 + 示例命令:'创建VLAN 100,名称为TEST' + 示例返回:{"type": "vlan", "vlan_id": 100, "name": "TEST", "commands": ["vlan 100", "name TEST"]} """ - data = { - "model": "deepseek-ai/DeepSeek-V3", - "prompt": prompt, - "max_tokens": 1000, - "temperature": 0.3 - } + messages = [ + ChatCompletionSystemMessageParam(role="system", content=prompt), + ChatCompletionUserMessageParam(role="user", content=command) + ] try: - async with httpx.AsyncClient() as client: - response = await client.post( - f"{self.api_url}/chat/completions", - headers=self.headers, - json=data, - timeout=30 - ) + response = self.client.chat.completions.create( + model="deepseek-ai/DeepSeek-V3", + messages=messages, + temperature=0.3, + max_tokens=1000, + response_format={"type": "json_object"} + ) - if response.status_code != 200: - raise SiliconFlowAPIException(response.text) + logger.debug(response) - result = response.json() - config_str = result["choices"][0]["text"].strip() + config_str = response.choices[0].message.content.strip() - # 确保返回的是有效的JSON - try: - config = json.loads(config_str) - return config - except json.JSONDecodeError: - # 尝试修复可能的多余字符 - if config_str.startswith("```json"): - config_str = config_str[7:-3].strip() - return json.loads(config_str) - raise SiliconFlowAPIException("Invalid JSON format returned from AI") - except httpx.HTTPError as e: + try: + config = json.loads(config_str) + return config + except json.JSONDecodeError: + # 尝试修复可能的多余字符 + if config_str.startswith("```json"): + config_str = config_str[7:-3].strip() + return json.loads(config_str) + raise SiliconFlowAPIException("Invalid JSON format returned from AI") + except KeyError: + logger.error(KeyError) + raise SiliconFlowAPIException("errrrrrrro") + + except Exception as e: raise SiliconFlowAPIException( detail=f"API请求失败: {str(e)}", - status_code=e.response.status_code if hasattr(e, "response") else 500 + status_code=getattr(e, "status_code", 500) ) \ No newline at end of file diff --git a/src/backend/requirements.txt b/src/backend/requirements.txt index fc26dff..880ac77 100644 --- a/src/backend/requirements.txt +++ b/src/backend/requirements.txt @@ -1,34 +1,26 @@ -# 核心依赖 -i https://pypi.tuna.tsinghua.edu.cn/simple fastapi==0.110.0 uvicorn==0.29.0 python-dotenv==1.0.1 - -# Pydantic 模型 -i https://pypi.tuna.tsinghua.edu.cn/simple +pysnmp pydantic==2.6.4 pydantic-settings==2.2.1 -# 网络操作 -i https://pypi.tuna.tsinghua.edu.cn/simple asyncssh==2.14.2 telnetlib3==2.0.3 httpx==0.27.0 python-nmap==0.7.1 - -# 异步文件操作 -i https://pypi.tuna.tsinghua.edu.cn/simple aiofiles==23.2.1 -# 日志管理 -i https://pypi.tuna.tsinghua.edu.cn/simple loguru==0.7.2 -# 重试机制 -i https://pypi.tuna.tsinghua.edu.cn/simple tenacity==8.2.3 -# 其他工具 -i https://pypi.tuna.tsinghua.edu.cn/simple asyncio==3.4.3 typing_extensions==4.10.0 -#监控依赖 Y - psutil==5.9.8 matplotlib==3.8.3 sqlalchemy==2.0.28 +sqlalchemy +openai \ No newline at end of file