deepseek_service.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. """
  2. DeepSeek AI 服务
  3. """
  4. import httpx
  5. import json
  6. from typing import AsyncGenerator
  7. from utils.config import settings
  8. from utils.logger import logger
  9. class DeepSeekService:
  10. def __init__(self):
  11. self.api_key = settings.deepseek.api_key
  12. self.api_url = settings.deepseek.api_url
  13. self.base_url = f"{self.api_url}/v1"
  14. self._timeout = httpx.Timeout(120.0, connect=10.0)
  15. self._limits = httpx.Limits(max_connections=50, max_keepalive_connections=20)
  16. self._client = httpx.AsyncClient(timeout=self._timeout, limits=self._limits)
  17. async def aclose(self) -> None:
  18. await self._client.aclose()
  19. async def chat(self, messages: list, model: str = "deepseek-chat") -> str:
  20. """同步聊天"""
  21. headers = {
  22. "Authorization": f"Bearer {self.api_key}",
  23. "Content-Type": "application/json"
  24. }
  25. data = {
  26. "model": model,
  27. "messages": messages,
  28. "temperature": 0.7
  29. }
  30. try:
  31. response = await self._client.post(
  32. f"{self.base_url}/chat/completions",
  33. headers=headers,
  34. json=data,
  35. )
  36. response.raise_for_status()
  37. result = response.json()
  38. return result['choices'][0]['message']['content']
  39. except Exception as e:
  40. logger.error(f"DeepSeek API 调用失败: {e}")
  41. raise
  42. async def stream_chat(self, messages: list, model: str = "deepseek-chat") -> AsyncGenerator[str, None]:
  43. """流式聊天"""
  44. headers = {
  45. "Authorization": f"Bearer {self.api_key}",
  46. "Content-Type": "application/json"
  47. }
  48. data = {
  49. "model": model,
  50. "messages": messages,
  51. "temperature": 0.7,
  52. "stream": True
  53. }
  54. try:
  55. async with self._client.stream(
  56. "POST",
  57. f"{self.base_url}/chat/completions",
  58. headers=headers,
  59. json=data,
  60. ) as response:
  61. response.raise_for_status()
  62. async for line in response.aiter_lines():
  63. if line.startswith("data: "):
  64. data_str = line[6:]
  65. if data_str == "[DONE]":
  66. break
  67. try:
  68. data_json = json.loads(data_str)
  69. if 'choices' in data_json and len(data_json['choices']) > 0:
  70. delta = data_json['choices'][0].get('delta', {})
  71. content = delta.get('content', '')
  72. if content:
  73. yield content
  74. except json.JSONDecodeError:
  75. continue
  76. except Exception as e:
  77. logger.error(f"DeepSeek 流式 API 调用失败: {e}")
  78. raise
  79. # 全局实例
  80. deepseek_service = DeepSeekService()