feat: AI对话系统 v1.0.0 - 网页端和Matrix端实时同步
This commit is contained in:
80
services/ai_service.py
Normal file
80
services/ai_service.py
Normal file
@@ -0,0 +1,80 @@
|
||||
"""
|
||||
AI服务 - 调用大模型API
|
||||
"""
|
||||
import httpx
|
||||
from typing import List, Dict, Optional
|
||||
import json
|
||||
|
||||
|
||||
class AIService:
|
||||
def __init__(self, api_base: str = "http://192.168.2.17:19007/v1", api_key: str = "sk-local", model: str = "qwen3.5-4b"):
|
||||
self.api_base = api_base
|
||||
self.api_key = api_key
|
||||
self.model = model
|
||||
|
||||
async def chat(self, messages: List[Dict], stream: bool = False) -> str:
|
||||
"""
|
||||
调用AI模型进行对话
|
||||
|
||||
Args:
|
||||
messages: 对话历史 [{"role": "user", "content": "..."}]
|
||||
stream: 是否流式输出
|
||||
|
||||
Returns:
|
||||
AI回复内容
|
||||
"""
|
||||
url = f"{self.api_base}/chat/completions"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"model": self.model,
|
||||
"messages": messages,
|
||||
"stream": stream,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 2000
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||
response = await client.post(url, headers=headers, json=payload)
|
||||
response.raise_for_status()
|
||||
data = response.json()
|
||||
return data['choices'][0]['message']['content']
|
||||
|
||||
async def chat_stream(self, messages: List[Dict]):
|
||||
"""
|
||||
流式调用AI模型
|
||||
"""
|
||||
url = f"{self.api_base}/chat/completions"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {self.api_key}",
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
payload = {
|
||||
"model": self.model,
|
||||
"messages": messages,
|
||||
"stream": True,
|
||||
"temperature": 0.7,
|
||||
"max_tokens": 2000
|
||||
}
|
||||
|
||||
async with httpx.AsyncClient(timeout=60.0) as client:
|
||||
async with client.stream("POST", url, headers=headers, json=payload) as response:
|
||||
async for line in response.aiter_lines():
|
||||
if line.startswith("data: "):
|
||||
data_str = line[6:]
|
||||
if data_str == "[DONE]":
|
||||
break
|
||||
try:
|
||||
data = json.loads(data_str)
|
||||
if 'choices' in data and len(data['choices']) > 0:
|
||||
delta = data['choices'][0].get('delta', {})
|
||||
if 'content' in delta:
|
||||
yield delta['content']
|
||||
except json.JSONDecodeError:
|
||||
continue
|
||||
|
||||
|
||||
# 全局实例
|
||||
ai_service = AIService()
|
||||
Reference in New Issue
Block a user