Приложение для тестирования сотрудников клиники методом один вопрос - до пяти ответов один из которых правильный. Сотрудник должен выбрать правильный вариант ответа
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

208 lines
7.7 KiB

import json
from openai import AsyncOpenAI
from sqlalchemy import select
from sqlalchemy.ext.asyncio import AsyncSession
from app.models.setting import Setting
DEEPSEEK_BASE_URL = "https://api.deepseek.com"
DEEPSEEK_MODEL = "deepseek-chat"
async def _get_api_key(db: AsyncSession) -> str:
result = await db.execute(select(Setting).where(Setting.key == "deepseek_api_key"))
setting = result.scalar_one_or_none()
if not setting or not setting.value:
raise ValueError("API ключ DeepSeek не настроен. Перейдите в Настройки.")
return setting.value
def _client(api_key: str) -> AsyncOpenAI:
return AsyncOpenAI(api_key=api_key, base_url=DEEPSEEK_BASE_URL)
async def check_connection(db: AsyncSession) -> str:
api_key = await _get_api_key(db)
client = _client(api_key)
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": "Ответь одним словом: работает"}],
max_tokens=10,
)
return response.choices[0].message.content.strip()
async def generate_questions(
db: AsyncSession,
topic: str,
count: int = 7,
answers_count: int = 3,
) -> list[dict]:
api_key = await _get_api_key(db)
client = _client(api_key)
prompt = f"""Сгенерируй {count} вопросов для теста по теме: "{topic}".
Верни ТОЛЬКО JSON без пояснений в следующем формате:
{{
"questions": [
{{
"text": "Текст вопроса",
"answers": [
{{"text": "Вариант 1", "is_correct": true}},
{{"text": "Вариант 2", "is_correct": false}},
{{"text": "Вариант 3", "is_correct": false}}
]
}}
]
}}
Требования:
- Ровно {answers_count} вариантов ответа на каждый вопрос
- Ровно один правильный ответ на каждый вопрос
- Вопросы должны проверять практические знания по теме
- Варианты ответов должны быть правдоподобными"""
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
max_tokens=3000,
)
data = json.loads(response.choices[0].message.content)
return data["questions"]
async def improve_question(
db: AsyncSession, question: str, answers: list[str]
) -> dict:
api_key = await _get_api_key(db)
client = _client(api_key)
answers_str = "\n".join(f"{i + 1}. {a}" for i, a in enumerate(answers))
prompt = f"""Улучши формулировки вопроса и вариантов ответов для теста. Сделай их более чёткими, однозначными и профессиональными.
Вопрос: {question}
Варианты ответов (верни в том же порядке и том же количестве):
{answers_str}
Верни ТОЛЬКО JSON без пояснений:
{{
"question": "улучшенный текст вопроса",
"answers": ["улучшенный вариант 1", "улучшенный вариант 2", ...]
}}"""
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
max_tokens=600,
)
return json.loads(response.choices[0].message.content)
async def generate_distractors(
db: AsyncSession, question: str, existing_answers: list[str]
) -> list[str]:
api_key = await _get_api_key(db)
client = _client(api_key)
existing_str = "\n".join(f"- {a}" for a in existing_answers)
prompt = f"""Для вопроса теста сгенерируй 3 правдоподобных неправильных варианта ответа (дистракторы).
Вопрос: {question}
Уже существующие варианты ответов:
{existing_str}
Верни ТОЛЬКО JSON без пояснений:
{{"distractors": ["Вариант 1", "Вариант 2", "Вариант 3"]}}
Требования:
- Дистракторы должны быть правдоподобными, но неправильными
- Не повторяй уже существующие варианты
- Дистракторы должны быть сопоставимы по длине с существующими вариантами"""
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
max_tokens=400,
)
data = json.loads(response.choices[0].message.content)
return data["distractors"]
async def review_test(db: AsyncSession, title: str, questions: list[dict]) -> str:
api_key = await _get_api_key(db)
client = _client(api_key)
questions_str = ""
for i, q in enumerate(questions, 1):
questions_str += f"\nВопрос {i}: {q.get('text', '')}\n"
for a in q.get("answers", []):
marker = "" if a.get("is_correct") else ""
questions_str += f" {marker} {a.get('text', '')}\n"
prompt = f"""Проанализируй тест и дай рекомендации по улучшению его качества.
Название теста: {title}
Вопросы:
{questions_str}
Оцени по следующим критериям:
1. Качество и чёткость формулировок вопросов
2. Качество вариантов ответов (правдоподобность дистракторов)
3. Охват темы и разнообразие вопросов
4. Конкретные рекомендации по улучшению
Отвечай на русском языке, структурированно."""
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": prompt}],
max_tokens=1500,
)
return response.choices[0].message.content.strip()
async def improve_all(
db: AsyncSession, title: str, questions: list[dict]
) -> list[dict]:
api_key = await _get_api_key(db)
client = _client(api_key)
questions_str = ""
for i, q in enumerate(questions, 1):
questions_str += f"\nВопрос {i}: {q.get('text', '')}\n"
for j, a in enumerate(q.get("answers", []), 1):
questions_str += f" {j}. {a.get('text', '') if isinstance(a, dict) else a}\n"
prompt = f"""Улучши формулировки всех вопросов и вариантов ответов в тесте. Сделай их более чёткими, однозначными и профессиональными.
Название теста: {title}
Вопросы:
{questions_str}
Верни ТОЛЬКО JSON. Для каждого вопроса — улучшенную формулировку и все варианты ответов в том же порядке и том же количестве:
{{
"questions": [
{{
"question": "улучшенный текст вопроса 1",
"answers": ["улучшенный вариант 1", "улучшенный вариант 2", "..."]
}}
]
}}"""
response = await client.chat.completions.create(
model=DEEPSEEK_MODEL,
messages=[{"role": "user", "content": prompt}],
response_format={"type": "json_object"},
max_tokens=4000,
)
data = json.loads(response.choices[0].message.content)
return data["questions"]