RAG3 / deepseek_utils.py
jeongsoo's picture
Initial commit
9b87c26
"""
DeepSeek API ํ…Œ์ŠคํŠธ ๋ฐ ์œ ํ‹ธ๋ฆฌํ‹ฐ ๊ธฐ๋Šฅ
"""
import os
import logging
import requests
import json
from typing import Dict, Any, Optional
# ๋กœ๊น… ์„ค์ •
logger = logging.getLogger("DeepSeekUtils")
class DeepSeekError(Exception):
"""DeepSeek API ๊ด€๋ จ ์˜ค๋ฅ˜"""
pass
def test_deepseek_api(api_key: str, endpoint: str, model: str) -> Dict[str, Any]:
"""
DeepSeek API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ
Args:
api_key: DeepSeek API ํ‚ค
endpoint: DeepSeek API ์—”๋“œํฌ์ธํŠธ
model: ์‚ฌ์šฉํ•  ๋ชจ๋ธ๋ช…
Returns:
ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ๋”•์…”๋„ˆ๋ฆฌ (์„ฑ๊ณต ์—ฌ๋ถ€ ๋ฐ ๋ฉ”์‹œ์ง€)
"""
if not api_key:
logger.error("DeepSeek API ํ‚ค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.")
return {
"success": False,
"message": "API ํ‚ค๊ฐ€ ์ œ๊ณต๋˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค.",
"status_code": None,
"response": None
}
try:
logger.info(f"DeepSeek API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์‹œ์ž‘: {endpoint}, ๋ชจ๋ธ: {model}")
# ํ…Œ์ŠคํŠธ์šฉ ๊ฐ„๋‹จํ•œ ํ”„๋กฌํ”„ํŠธ
test_prompt = "Hello, please respond with a short greeting."
# API ์š”์ฒญ ํ—ค๋” ๋ฐ ๋ฐ์ดํ„ฐ
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
payload = {
"model": model,
"messages": [{"role": "user", "content": test_prompt}],
"temperature": 0.7,
"max_tokens": 50
}
# API ์š”์ฒญ ์ „์†ก
response = requests.post(
endpoint,
headers=headers,
data=json.dumps(payload),
timeout=10 # 10์ดˆ ํƒ€์ž„์•„์›ƒ
)
# ์‘๋‹ต ํ™•์ธ
if response.status_code == 200:
logger.info("DeepSeek API ์—ฐ๊ฒฐ ์„ฑ๊ณต")
response_data = response.json()
# ์‘๋‹ต ๋‚ด์šฉ ํ™•์ธ
if "choices" in response_data and len(response_data["choices"]) > 0:
message_content = response_data["choices"][0].get("message", {}).get("content", "")
return {
"success": True,
"message": "API ์—ฐ๊ฒฐ ์„ฑ๊ณต",
"status_code": response.status_code,
"response": message_content[:100] + "..." if len(message_content) > 100 else message_content
}
else:
return {
"success": True,
"message": "API ์—ฐ๊ฒฐ ์„ฑ๊ณตํ–ˆ์œผ๋‚˜ ์‘๋‹ต ํ˜•์‹์ด ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฆ…๋‹ˆ๋‹ค.",
"status_code": response.status_code,
"response": response_data
}
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
return {
"success": False,
"message": f"API ์˜ค๋ฅ˜: {error_message}",
"status_code": response.status_code,
"response": error_message
}
except requests.exceptions.Timeout:
logger.error("DeepSeek API ์š”์ฒญ ์‹œ๊ฐ„ ์ดˆ๊ณผ")
return {
"success": False,
"message": "API ์š”์ฒญ ์‹œ๊ฐ„ ์ดˆ๊ณผ",
"status_code": None,
"response": None
}
except requests.exceptions.ConnectionError:
logger.error("DeepSeek API ์—ฐ๊ฒฐ ์‹คํŒจ")
return {
"success": False,
"message": "API ์„œ๋ฒ„ ์—ฐ๊ฒฐ ์‹คํŒจ",
"status_code": None,
"response": None
}
except Exception as e:
logger.error(f"DeepSeek API ํ…Œ์ŠคํŠธ ์ค‘ ์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜: {e}", exc_info=True)
return {
"success": False,
"message": f"์˜ˆ์ƒ์น˜ ๋ชปํ•œ ์˜ค๋ฅ˜: {str(e)}",
"status_code": None,
"response": None
}
def create_deepseek_client(api_key: str, endpoint: str, model: str):
"""
DeepSeek ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ (LangChain ํ˜ธํ™˜)
Args:
api_key: DeepSeek API ํ‚ค
endpoint: DeepSeek API ์—”๋“œํฌ์ธํŠธ
model: ์‚ฌ์šฉํ•  ๋ชจ๋ธ๋ช…
Returns:
DeepSeek ํด๋ผ์ด์–ธํŠธ ๊ฐ์ฒด ๋˜๋Š” None
"""
# LangChain๊ณผ DeepSeek ํ†ตํ•ฉ ์‹œ๋„
try:
from langchain_openai import ChatOpenAI
# API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ๋จผ์ € ์ˆ˜ํ–‰
test_result = test_deepseek_api(api_key, endpoint, model)
if not test_result["success"]:
logger.error(f"DeepSeek API ์—ฐ๊ฒฐ ํ…Œ์ŠคํŠธ ์‹คํŒจ: {test_result['message']}")
return None
# ์ •์ƒ ์—ฐ๊ฒฐ ์‹œ ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ
# DeepSeek๋Š” OpenAI ํ˜ธํ™˜ API๋ฅผ ์ œ๊ณตํ•˜๋ฏ€๋กœ ChatOpenAI๋ฅผ ์‚ฌ์šฉ
client = ChatOpenAI(
model=model,
temperature=0.2,
api_key=api_key,
base_url=endpoint.rstrip("/v1/chat/completions"), # OpenAI ํ˜ธํ™˜ ๋ฒ ์ด์Šค URL
)
logger.info(f"DeepSeek ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ ์„ฑ๊ณต: {model}")
return client
except ImportError as e:
logger.error(f"ํ•„์š”ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž„ํฌํŠธ ์‹คํŒจ: {e}")
return None
except Exception as e:
logger.error(f"DeepSeek ํด๋ผ์ด์–ธํŠธ ์ƒ์„ฑ ์ค‘ ์˜ค๋ฅ˜: {e}", exc_info=True)
return None