2025-12-04 11:09:54 +03:00
|
|
|
|
from openai import AsyncOpenAI
|
|
|
|
|
|
from config.settings import settings
|
|
|
|
|
|
from typing import Dict, List
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AIService:
|
2025-12-04 14:39:23 +03:00
|
|
|
|
"""Сервис для работы с OpenAI API через Cloudflare Gateway"""
|
2025-12-04 11:09:54 +03:00
|
|
|
|
|
|
|
|
|
|
def __init__(self):
|
2025-12-04 14:39:23 +03:00
|
|
|
|
# Проверяем, настроен ли Cloudflare AI Gateway
|
|
|
|
|
|
if settings.cloudflare_account_id:
|
|
|
|
|
|
# Используем Cloudflare AI Gateway
|
|
|
|
|
|
base_url = (
|
|
|
|
|
|
f"https://gateway.ai.cloudflare.com/v1/"
|
|
|
|
|
|
f"{settings.cloudflare_account_id}/"
|
|
|
|
|
|
f"{settings.cloudflare_gateway_id}/"
|
2025-12-04 14:46:30 +03:00
|
|
|
|
f"compat"
|
2025-12-04 14:39:23 +03:00
|
|
|
|
)
|
|
|
|
|
|
self.client = AsyncOpenAI(
|
|
|
|
|
|
api_key=settings.openai_api_key,
|
|
|
|
|
|
base_url=base_url
|
|
|
|
|
|
)
|
|
|
|
|
|
else:
|
|
|
|
|
|
# Прямое подключение к OpenAI
|
|
|
|
|
|
self.client = AsyncOpenAI(api_key=settings.openai_api_key)
|
2025-12-04 11:09:54 +03:00
|
|
|
|
|
|
|
|
|
|
async def translate_word(self, word: str, target_lang: str = "ru") -> Dict:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Перевести слово и получить дополнительную информацию
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
word: Слово для перевода
|
|
|
|
|
|
target_lang: Язык перевода (по умолчанию русский)
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Dict с переводом, транскрипцией и примерами
|
|
|
|
|
|
"""
|
|
|
|
|
|
prompt = f"""Переведи английское слово/фразу "{word}" на русский язык.
|
|
|
|
|
|
|
|
|
|
|
|
Верни ответ строго в формате JSON:
|
|
|
|
|
|
{{
|
|
|
|
|
|
"word": "{word}",
|
|
|
|
|
|
"translation": "перевод",
|
|
|
|
|
|
"transcription": "транскрипция в IPA",
|
|
|
|
|
|
"examples": [
|
|
|
|
|
|
{{"en": "пример на английском", "ru": "перевод примера"}},
|
|
|
|
|
|
{{"en": "ещё один пример", "ru": "перевод примера"}}
|
|
|
|
|
|
],
|
|
|
|
|
|
"category": "категория слова (работа, еда, путешествия и т.д.)",
|
|
|
|
|
|
"difficulty": "уровень сложности (A1/A2/B1/B2/C1/C2)"
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
|
|
Важно: верни только JSON, без дополнительного текста."""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
response = await self.client.chat.completions.create(
|
|
|
|
|
|
model="gpt-4o-mini",
|
|
|
|
|
|
messages=[
|
|
|
|
|
|
{"role": "system", "content": "Ты - помощник для изучения английского языка. Отвечай только в формате JSON."},
|
|
|
|
|
|
{"role": "user", "content": prompt}
|
|
|
|
|
|
],
|
|
|
|
|
|
temperature=0.3,
|
|
|
|
|
|
response_format={"type": "json_object"}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
|
result = json.loads(response.choices[0].message.content)
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
# Fallback в случае ошибки
|
|
|
|
|
|
return {
|
|
|
|
|
|
"word": word,
|
|
|
|
|
|
"translation": "Ошибка перевода",
|
|
|
|
|
|
"transcription": "",
|
|
|
|
|
|
"examples": [],
|
|
|
|
|
|
"category": "unknown",
|
|
|
|
|
|
"difficulty": "A1"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
async def check_answer(self, question: str, correct_answer: str, user_answer: str) -> Dict:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Проверить ответ пользователя с помощью ИИ
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
question: Вопрос задания
|
|
|
|
|
|
correct_answer: Правильный ответ
|
|
|
|
|
|
user_answer: Ответ пользователя
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Dict с результатом проверки и обратной связью
|
|
|
|
|
|
"""
|
|
|
|
|
|
prompt = f"""Проверь ответ пользователя на задание по английскому языку.
|
|
|
|
|
|
|
|
|
|
|
|
Задание: {question}
|
|
|
|
|
|
Правильный ответ: {correct_answer}
|
|
|
|
|
|
Ответ пользователя: {user_answer}
|
|
|
|
|
|
|
|
|
|
|
|
Верни ответ в формате JSON:
|
|
|
|
|
|
{{
|
|
|
|
|
|
"is_correct": true/false,
|
|
|
|
|
|
"feedback": "краткое объяснение (если ответ неверный, объясни ошибку и дай правильный вариант)",
|
|
|
|
|
|
"score": 0-100
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
|
|
Учитывай возможные вариации ответа. Если смысл передан правильно, даже с небольшими грамматическими неточностями, засчитывай ответ."""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
response = await self.client.chat.completions.create(
|
|
|
|
|
|
model="gpt-4o-mini",
|
|
|
|
|
|
messages=[
|
|
|
|
|
|
{"role": "system", "content": "Ты - преподаватель английского языка. Проверяй ответы справедливо, учитывая контекст."},
|
|
|
|
|
|
{"role": "user", "content": prompt}
|
|
|
|
|
|
],
|
|
|
|
|
|
temperature=0.3,
|
|
|
|
|
|
response_format={"type": "json_object"}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
|
result = json.loads(response.choices[0].message.content)
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
return {
|
|
|
|
|
|
"is_correct": False,
|
|
|
|
|
|
"feedback": "Ошибка проверки ответа",
|
|
|
|
|
|
"score": 0
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-04 14:46:30 +03:00
|
|
|
|
async def generate_fill_in_sentence(self, word: str) -> Dict:
|
|
|
|
|
|
"""
|
|
|
|
|
|
Сгенерировать предложение с пропуском для заданного слова
|
|
|
|
|
|
|
|
|
|
|
|
Args:
|
|
|
|
|
|
word: Слово, для которого нужно создать предложение
|
|
|
|
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
|
|
Dict с предложением и правильным ответом
|
|
|
|
|
|
"""
|
|
|
|
|
|
prompt = f"""Создай предложение на английском языке, используя слово "{word}".
|
|
|
|
|
|
Замени это слово на пропуск "___".
|
|
|
|
|
|
|
|
|
|
|
|
Верни ответ в формате JSON:
|
|
|
|
|
|
{{
|
|
|
|
|
|
"sentence": "предложение с пропуском ___",
|
|
|
|
|
|
"answer": "{word}",
|
|
|
|
|
|
"translation": "перевод предложения на русский"
|
|
|
|
|
|
}}
|
|
|
|
|
|
|
|
|
|
|
|
Предложение должно быть простым и естественным. Контекст должен четко подсказывать правильное слово."""
|
|
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
response = await self.client.chat.completions.create(
|
|
|
|
|
|
model="gpt-4o-mini",
|
|
|
|
|
|
messages=[
|
|
|
|
|
|
{"role": "system", "content": "Ты - преподаватель английского языка. Создавай простые и понятные упражнения."},
|
|
|
|
|
|
{"role": "user", "content": prompt}
|
|
|
|
|
|
],
|
|
|
|
|
|
temperature=0.7,
|
|
|
|
|
|
response_format={"type": "json_object"}
|
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
import json
|
|
|
|
|
|
result = json.loads(response.choices[0].message.content)
|
|
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
|
|
|
except Exception as e:
|
|
|
|
|
|
return {
|
|
|
|
|
|
"sentence": f"I like to ___ every day.",
|
|
|
|
|
|
"answer": word,
|
|
|
|
|
|
"translation": f"Мне нравится {word} каждый день."
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-12-04 11:09:54 +03:00
|
|
|
|
|
|
|
|
|
|
# Глобальный экземпляр сервиса
|
|
|
|
|
|
ai_service = AIService()
|