текущая версия (рабочая)
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
from typing import Any
|
||||
|
||||
import httpx
|
||||
|
||||
from app import config
|
||||
from app.models import Settings, Review
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class GPTClient:
|
||||
def __init__(self):
|
||||
self.api_url = config.GPT_API_URL
|
||||
self.headers = {
|
||||
"Authorization": f"Bearer {config.GPTUNNEL_API_KEY}",
|
||||
"Content-Type": "application/json",
|
||||
}
|
||||
|
||||
async def _make_request(
|
||||
self, messages: list, model: str = "gpt-4o", max_tokens: int = 100, retry: bool = False
|
||||
) -> str:
|
||||
data = {
|
||||
"model": model,
|
||||
"max_tokens": max_tokens,
|
||||
"messages": messages,
|
||||
}
|
||||
|
||||
try:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.post(
|
||||
self.api_url, headers=self.headers, json=data
|
||||
)
|
||||
response.raise_for_status()
|
||||
result = response.json()
|
||||
logger.info("GPT response: %s", result)
|
||||
answer = (
|
||||
result.get("choices", [{}])[0].get("message", {}).get("content", "")
|
||||
)
|
||||
return answer
|
||||
except httpx.HTTPError as e:
|
||||
logger.error(f"Error making GPT request: {e.__class__.__name__}: {e}")
|
||||
if retry:
|
||||
return ""
|
||||
logger.info("Waiting 15 seconds and retrying")
|
||||
await asyncio.sleep(15)
|
||||
return await self._make_request(messages, model, max_tokens, retry=True)
|
||||
|
||||
async def analyze_review(self, settings: Settings, review: Review) -> str:
|
||||
review_text = (
|
||||
f"Комментарий: {review.text}\n"
|
||||
f"Название товара: {review.product_name or '-'}\n"
|
||||
f"Оценка пользователя: {review.rating}"
|
||||
)
|
||||
messages = [
|
||||
{"role": "system", "content": settings.analysis_prompt},
|
||||
{
|
||||
"role": "user",
|
||||
"content": review_text,
|
||||
},
|
||||
]
|
||||
|
||||
return await self._make_request(messages, model=settings.gpt_model, max_tokens=settings.max_tokens)
|
||||
|
||||
async def generate_answer(self, settings: Settings, review: Review) -> str:
|
||||
review_text = (
|
||||
f"Комментарий: {review.text}\n"
|
||||
f"Название товара: {review.product_name or '-'}\n"
|
||||
f"Оценка пользователя: {review.rating}"
|
||||
)
|
||||
messages = [
|
||||
{"role": "system", "content": settings.answer_prompt},
|
||||
{
|
||||
"role": "user",
|
||||
"content": f"{review_text}\nОтвет представителя бренда:",
|
||||
},
|
||||
]
|
||||
|
||||
return await self._make_request(
|
||||
messages, model=settings.gpt_model, max_tokens=settings.max_tokens
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def extract_analysis_data(analysis_text: str) -> dict[str, Any]:
|
||||
try:
|
||||
analysis_text = analysis_text.replace("```json", "").replace("```", "")
|
||||
data = json.loads(analysis_text)
|
||||
|
||||
tone = (data.get("tone") or "").lower()
|
||||
tone_reason = data.get("reason") or ""
|
||||
is_critical = data.get("is_critical") or None
|
||||
except (json.JSONDecodeError, ValueError, AttributeError) as e:
|
||||
logger.error(f"Error parsing analysis JSON: {e}. Raw text: {analysis_text}")
|
||||
raise e
|
||||
|
||||
return {
|
||||
"tone": tone,
|
||||
"tone_reason": tone_reason,
|
||||
"is_critical": is_critical,
|
||||
}
|
||||
Reference in New Issue
Block a user