|
""" |
|
μ§μ DeepSeek API νΈμΆμ μν ν΄λΌμ΄μΈνΈ ꡬν |
|
""" |
|
import os |
|
import time |
|
import logging |
|
import requests |
|
import json |
|
from typing import Dict, Any, Optional, List |
|
|
|
|
|
logger = logging.getLogger("DirectDeepSeek") |
|
|
|
class DirectDeepSeekClient: |
|
""" |
|
DeepSeek APIλ₯Ό μ§μ νΈμΆνλ ν΄λΌμ΄μΈνΈ |
|
OpenAI ν΄λΌμ΄μΈνΈλ₯Ό μ°ννκ³ μ§μ HTTP μμ² μ¬μ© |
|
""" |
|
def __init__(self, api_key: str, model_name: str = "deepseek-chat"): |
|
""" |
|
ν΄λΌμ΄μΈνΈ μ΄κΈ°ν |
|
|
|
Args: |
|
api_key: DeepSeek API ν€ |
|
model_name: μ¬μ©ν λͺ¨λΈ μ΄λ¦ (κΈ°λ³Έκ°: "deepseek-chat") |
|
""" |
|
self.api_key = api_key |
|
self.model_name = model_name |
|
self.endpoint = os.getenv("DEEPSEEK_ENDPOINT", "https://api.deepseek.com/v1/chat/completions") |
|
logger.info(f"DirectDeepSeekClient μ΄κΈ°ν: λͺ¨λΈ={model_name}, μλν¬μΈνΈ={self.endpoint}") |
|
|
|
def generate(self, |
|
prompt: str, |
|
temperature: float = 0.3, |
|
max_tokens: int = 1000, |
|
max_retries: int = 3, |
|
timeout: int = 60) -> Dict[str, Any]: |
|
""" |
|
ν
μ€νΈ μμ± μμ² |
|
|
|
Args: |
|
prompt: μ
λ ₯ ν둬ννΈ |
|
temperature: μμ± μ¨λ (0.0 ~ 1.0) |
|
max_tokens: μ΅λ μμ± ν ν° μ |
|
max_retries: μ¬μλ νμ |
|
timeout: μμ² νμμμ (μ΄) |
|
|
|
Returns: |
|
μμ± κ²°κ³Ό λμ
λ리 (success, response, message λ±) |
|
""" |
|
|
|
messages = [{"role": "user", "content": prompt}] |
|
return self.chat(messages, temperature, max_tokens, max_retries, timeout) |
|
|
|
def chat(self, |
|
messages: List[Dict[str, str]], |
|
temperature: float = 0.3, |
|
max_tokens: int = 1000, |
|
max_retries: int = 3, |
|
timeout: int = 60) -> Dict[str, Any]: |
|
""" |
|
μ±ν
API νΈμΆ |
|
|
|
Args: |
|
messages: μ±ν
λ©μμ§ λ¦¬μ€νΈ (role, content ν€λ₯Ό κ°μ§ λμ
λ리 리μ€νΈ) |
|
temperature: μμ± μ¨λ (0.0 ~ 1.0) |
|
max_tokens: μ΅λ μμ± ν ν° μ |
|
max_retries: μ¬μλ νμ |
|
timeout: μμ² νμμμ (μ΄) |
|
|
|
Returns: |
|
μμ± κ²°κ³Ό λμ
λ리 (success, response, message λ±) |
|
""" |
|
|
|
headers = { |
|
"Content-Type": "application/json", |
|
"Authorization": f"Bearer {self.api_key}" |
|
} |
|
|
|
payload = { |
|
"model": self.model_name, |
|
"messages": messages, |
|
"temperature": temperature, |
|
"max_tokens": max_tokens |
|
} |
|
|
|
|
|
retry_delay = 1.0 |
|
attempt = 0 |
|
|
|
while attempt < max_retries: |
|
attempt += 1 |
|
try: |
|
logger.info(f"DeepSeek API μμ² μλ ({attempt}/{max_retries})...") |
|
|
|
|
|
response = requests.post( |
|
self.endpoint, |
|
headers=headers, |
|
json=payload, |
|
timeout=timeout |
|
) |
|
|
|
|
|
if response.status_code == 200: |
|
result = response.json() |
|
|
|
|
|
if "choices" in result and len(result["choices"]) > 0: |
|
message_content = result["choices"][0].get("message", {}).get("content", "") |
|
logger.info(f"DeepSeek API μλ΅ μ±κ³΅ (κΈΈμ΄: {len(message_content)})") |
|
|
|
return { |
|
"success": True, |
|
"response": message_content, |
|
"status_code": response.status_code, |
|
"raw_response": result |
|
} |
|
else: |
|
logger.warning(f"DeepSeek API μλ΅μ μ±κ³΅νμΌλ μμμΉ λͺ»ν μλ΅ νμ: {result}") |
|
return { |
|
"success": False, |
|
"message": "μλ΅μμ λ©μμ§λ₯Ό μ°Ύμ μ μμ΅λλ€", |
|
"status_code": response.status_code, |
|
"raw_response": result |
|
} |
|
else: |
|
logger.error(f"DeepSeek API μ€λ₯: μν μ½λ {response.status_code}") |
|
|
|
|
|
error_message = "" |
|
try: |
|
error_data = response.json() |
|
error_message = error_data.get("error", {}).get("message", str(error_data)) |
|
except: |
|
error_message = response.text |
|
|
|
|
|
if response.status_code == 429: |
|
retry_delay = min(retry_delay * 3, 15) |
|
else: |
|
retry_delay = min(retry_delay * 2, 10) |
|
|
|
if attempt < max_retries: |
|
logger.info(f"{retry_delay}μ΄ ν μ¬μλ...") |
|
time.sleep(retry_delay) |
|
else: |
|
|
|
return { |
|
"success": False, |
|
"message": f"API μ€λ₯: {error_message}", |
|
"status_code": response.status_code |
|
} |
|
|
|
except requests.exceptions.Timeout: |
|
logger.error("DeepSeek API μμ² μκ° μ΄κ³Ό") |
|
|
|
if attempt < max_retries: |
|
logger.info(f"{retry_delay}μ΄ ν μ¬μλ...") |
|
time.sleep(retry_delay) |
|
retry_delay = min(retry_delay * 2, 10) |
|
else: |
|
return { |
|
"success": False, |
|
"message": "API μμ² μκ° μ΄κ³Ό", |
|
"status_code": None |
|
} |
|
|
|
except requests.exceptions.ConnectionError: |
|
logger.error("DeepSeek API μ°κ²° μ€ν¨") |
|
|
|
if attempt < max_retries: |
|
logger.info(f"{retry_delay}μ΄ ν μ¬μλ...") |
|
time.sleep(retry_delay) |
|
retry_delay = min(retry_delay * 2, 10) |
|
else: |
|
return { |
|
"success": False, |
|
"message": "API μλ² μ°κ²° μ€ν¨", |
|
"status_code": None |
|
} |
|
|
|
except Exception as e: |
|
logger.error(f"DeepSeek API μμ² μ€ μμμΉ λͺ»ν μ€λ₯: {e}") |
|
|
|
if attempt < max_retries: |
|
logger.info(f"{retry_delay}μ΄ ν μ¬μλ...") |
|
time.sleep(retry_delay) |
|
retry_delay = min(retry_delay * 2, 10) |
|
else: |
|
return { |
|
"success": False, |
|
"message": f"μμμΉ λͺ»ν μ€λ₯: {str(e)}", |
|
"status_code": None |
|
} |
|
|
|
|
|
return { |
|
"success": False, |
|
"message": "μ΅λ μ¬μλ νμ μ΄κ³Ό", |
|
"status_code": None |
|
} |
|
|
|
def system_prompt_chat(self, |
|
system_prompt: str, |
|
user_prompt: str, |
|
temperature: float = 0.3, |
|
max_tokens: int = 1000, |
|
max_retries: int = 3, |
|
timeout: int = 60) -> Dict[str, Any]: |
|
""" |
|
μμ€ν
ν둬ννΈμ μ¬μ©μ ν둬ννΈλ₯Ό μ΄μ©ν μ±ν
API νΈμΆ |
|
|
|
Args: |
|
system_prompt: μμ€ν
ν둬ννΈ |
|
user_prompt: μ¬μ©μ ν둬ννΈ |
|
temperature: μμ± μ¨λ (0.0 ~ 1.0) |
|
max_tokens: μ΅λ μμ± ν ν° μ |
|
max_retries: μ¬μλ νμ |
|
timeout: μμ² νμμμ (μ΄) |
|
|
|
Returns: |
|
μμ± κ²°κ³Ό λμ
λ리 |
|
""" |
|
messages = [ |
|
{"role": "system", "content": system_prompt}, |
|
{"role": "user", "content": user_prompt} |
|
] |
|
|
|
return self.chat(messages, temperature, max_tokens, max_retries, timeout) |
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
|
logging.basicConfig(level=logging.INFO) |
|
|
|
|
|
api_key = os.environ.get("DEEPSEEK_API_KEY") |
|
if not api_key: |
|
print("νκ²½ λ³μ DEEPSEEK_API_KEYκ° μ€μ λμ§ μμμ΅λλ€.") |
|
exit(1) |
|
|
|
|
|
client = DirectDeepSeekClient(api_key) |
|
|
|
|
|
response = client.generate("Hello, what can you do?") |
|
|
|
|
|
if response["success"]: |
|
print("μλ΅ μ±κ³΅!") |
|
print(response["response"]) |
|
else: |
|
print(f"μλ΅ μ€ν¨: {response['message']}") |