60 lines
1.9 KiB
Python
60 lines
1.9 KiB
Python
# -*- coding: utf-8 -*-
|
|
"""
|
|
DeepSeek API 封装
|
|
使用 OpenAI 兼容接口
|
|
"""
|
|
import os
|
|
import json
|
|
import requests
|
|
|
|
|
|
class DeepSeekService:
|
|
"""DeepSeek 流式对话服务"""
|
|
|
|
def __init__(self):
|
|
self.api_key = os.getenv("DEEPSEEK_API_KEY", "")
|
|
self.model = os.getenv("DEEPSEEK_MODEL", "deepseek-chat")
|
|
self.base_url = os.getenv("DEEPSEEK_BASE_URL", "https://api.deepseek.com")
|
|
|
|
def stream_chat(self, messages):
|
|
"""
|
|
流式对话,逐块 yield 文本内容
|
|
:param messages: [{"role": "user"|"assistant"|"system", "content": str}]
|
|
"""
|
|
if not self.api_key:
|
|
raise RuntimeError("未配置 DEEPSEEK_API_KEY,请在 .env 中设置")
|
|
|
|
url = f"{self.base_url}/chat/completions"
|
|
headers = {
|
|
"Authorization": f"Bearer {self.api_key}",
|
|
"Content-Type": "application/json",
|
|
}
|
|
body = {
|
|
"model": self.model,
|
|
"messages": messages,
|
|
"stream": True,
|
|
}
|
|
|
|
with requests.post(
|
|
url, headers=headers, json=body, stream=True, timeout=120
|
|
) as resp:
|
|
if resp.status_code != 200:
|
|
raise RuntimeError(
|
|
f"DeepSeek 接口错误 {resp.status_code}: {resp.text}"
|
|
)
|
|
for line in resp.iter_lines(decode_unicode=True):
|
|
if not line:
|
|
continue
|
|
if line.startswith("data:"):
|
|
data = line[5:].strip()
|
|
if data == "[DONE]":
|
|
break
|
|
try:
|
|
obj = json.loads(data)
|
|
delta = obj.get("choices", [{}])[0].get("delta", {})
|
|
content = delta.get("content")
|
|
if content:
|
|
yield content
|
|
except json.JSONDecodeError:
|
|
continue
|