fix code
This commit is contained in:
@@ -55,16 +55,16 @@ class QaExerciseProcessor(TaskProcessor):
|
||||
' 2. `dimension`:考察维度;\n'
|
||||
' 3. `key_pronunciation_words`:核心发音单词(2-3个);\n'
|
||||
' 4. `answers`:多版本回答(spoken/written/friendly);\n'
|
||||
' 5. `correct_options`:正确选项数组(含`content`/`type`字段);\n'
|
||||
' 6. `incorrect_options`:错误选项数组(含`content`/`error_type`/`error_reason`字段);\n'
|
||||
' 5. `correct_options`:正确选项数组(含`content`/`type`字段),每个选项都是一个陈述句;\n'
|
||||
' 6. `incorrect_options`:错误选项数组(含`content`/`error_type`/`error_reason`字段),无语法类干扰;\n'
|
||||
' 7. `cloze`:填词模式专项字段:\n'
|
||||
' - `sentence_with_blank`:含 ___ 的填空句;\n'
|
||||
' - `correct_word`:填空处原词,一个正确选项;\n'
|
||||
' - `sentence`:含 correct_word 的完整句子;\n'
|
||||
' - `distractor_words`:近义词干扰项数组(3-4个,无语法类干扰)。\n'
|
||||
'3. 输出限制:仅返回JSON字符串,无其他解释文字,确保可被`JSON.parse`直接解析。\n'
|
||||
'输入图片描述:' + json.dumps(payload, ensure_ascii=False) + '\n'
|
||||
'### 输出JSON格式\n'
|
||||
'{ "qa_list": [ { "question": "", "dimension": "", "key_pronunciation_words": [], "answers": { "spoken": "", "written": "", "friendly": "", "lively": "" }, "correct_options": [ { "content": "", "type": "core" } ], "incorrect_options": [ { "content": "", "error_type": "词汇混淆", "error_reason": "" } ], "cloze": { "sentence_with_blank": "", "correct_word": "", "distractor_words": [] } } ] }'
|
||||
'{ "qa_list": [ { "question": "", "dimension": "", "key_pronunciation_words": [], "answers": { "spoken": "", "written": "", "friendly": "", "lively": "" }, "correct_options": [ { "content": "", "type": "core" } ], "incorrect_options": [ { "content": "", "error_type": "词汇混淆", "error_reason": "" } ], "cloze": { "sentence": "", "correct_word": "", "distractor_words": [] } } ] }'
|
||||
)
|
||||
res = await self._call_llm_chat(prompt=prompt, image_id=image.id, user_id=task.user_id, chat_type='qa_exercise')
|
||||
if not res.get('success'):
|
||||
@@ -304,12 +304,13 @@ class QaService:
|
||||
evaluation = {'type': 'choice', 'result': result_text, 'detail': is_correct, 'selected': {'correct': [], 'incorrect': selected_incorrect}, 'missing_correct': [o.get('content') if isinstance(o, dict) else o for o in raw_correct]}
|
||||
return evaluation, is_correct, selected_list
|
||||
|
||||
def _evaluate_cloze(self, q: QaQuestion, cloze_options: List[str]) -> Tuple[Dict[str, Any], str, List[str]]:
|
||||
def _evaluate_cloze(self, q: QaQuestion, cloze_options: Optional[List[str]]) -> Tuple[Dict[str, Any], str, str]:
|
||||
ext = q.ext or {}
|
||||
cloze = ext.get('cloze') or {}
|
||||
correct_word = cloze.get('correct_word')
|
||||
# Support multiple selections: treat as correct if any selected matches a correct answer
|
||||
selection_list = [s for s in cloze_options if isinstance(s, str) and s.strip()]
|
||||
selection_list = [s for s in (cloze_options or []) if isinstance(s, str) and s.strip()]
|
||||
input_str = selection_list[0] if selection_list else ''
|
||||
def _norm(v):
|
||||
try:
|
||||
return str(v).strip().lower()
|
||||
@@ -343,7 +344,7 @@ class QaService:
|
||||
is_correct = 'incorrect'
|
||||
result_text = '完全错误'
|
||||
evaluation = {'type': 'cloze', 'result': result_text, 'detail': is_correct, 'selected': {'correct': [], 'incorrect': user_incorrect}, 'missing_correct': [cw for cw in correct_candidates]}
|
||||
return evaluation, is_correct, selection_list
|
||||
return evaluation, is_correct, input_str
|
||||
|
||||
async def submit_attempt(self, question_id: int, exercise_id: int, user_id: int, mode: str, selected_options: Optional[List[str]] = None, input_text: Optional[str] = None, cloze_options: Optional[List[str]] = None, file_id: Optional[int] = None, session_id: Optional[int] = None, is_trial: bool = False) -> Dict[str, Any]:
|
||||
async with async_db_session.begin() as db:
|
||||
@@ -364,12 +365,15 @@ class QaService:
|
||||
}
|
||||
}
|
||||
elif mode == EXERCISE_TYPE_CLOZE:
|
||||
evaluation, _, selection_list = self._evaluate_cloze(q, cloze_options)
|
||||
c_opts = cloze_options
|
||||
if not c_opts and input_text:
|
||||
c_opts = [input_text]
|
||||
evaluation, _, input_str = self._evaluate_cloze(q, c_opts)
|
||||
return {
|
||||
'session_id': None,
|
||||
'type': 'cloze',
|
||||
'cloze': {
|
||||
'input': selection_list,
|
||||
'input': input_str,
|
||||
'evaluation': evaluation
|
||||
}
|
||||
}
|
||||
@@ -379,7 +383,11 @@ class QaService:
|
||||
if attempt:
|
||||
attempt.task_id = None
|
||||
attempt.choice_options = selected_options if mode == EXERCISE_TYPE_CHOICE else attempt.choice_options
|
||||
attempt.cloze_options = ((cloze_options[0] if isinstance(cloze_options, list) and cloze_options else None) if mode == EXERCISE_TYPE_CLOZE else attempt.cloze_options)
|
||||
if mode == EXERCISE_TYPE_CLOZE:
|
||||
if isinstance(cloze_options, list) and cloze_options:
|
||||
attempt.cloze_options = cloze_options[0]
|
||||
elif input_text:
|
||||
attempt.cloze_options = input_text
|
||||
attempt.input_text = input_text if mode == EXERCISE_TYPE_FREE_TEXT else attempt.input_text
|
||||
attempt.status = 'pending'
|
||||
ext0 = attempt.ext or {}
|
||||
@@ -399,7 +407,7 @@ class QaService:
|
||||
'task_id': None,
|
||||
'recording_id': recording_id,
|
||||
'choice_options': selected_options if mode == EXERCISE_TYPE_CHOICE else None,
|
||||
'cloze_options': ((cloze_options[0] if isinstance(cloze_options, list) and cloze_options else None) if mode == EXERCISE_TYPE_CLOZE else None),
|
||||
'cloze_options': ((cloze_options[0] if isinstance(cloze_options, list) and cloze_options else (input_text if input_text else None)) if mode == EXERCISE_TYPE_CLOZE else None),
|
||||
'input_text': input_text if mode == EXERCISE_TYPE_FREE_TEXT else None,
|
||||
'status': 'pending',
|
||||
'evaluation': None,
|
||||
@@ -501,19 +509,23 @@ class QaService:
|
||||
}
|
||||
|
||||
if mode == EXERCISE_TYPE_CLOZE:
|
||||
c_opts = attempt.cloze_options or []
|
||||
if not c_opts and attempt.input_text:
|
||||
c_opts = [attempt.input_text]
|
||||
c_opts: List[str] = []
|
||||
if isinstance(cloze_options, list) and cloze_options:
|
||||
c_opts = cloze_options
|
||||
elif input_text:
|
||||
c_opts = [input_text]
|
||||
elif attempt.cloze_options:
|
||||
c_opts = [attempt.cloze_options]
|
||||
if cloze_options:
|
||||
c_opts = cloze_options
|
||||
|
||||
evaluation, is_correct, selection_list = self._evaluate_cloze(q, c_opts)
|
||||
evaluation, is_correct, input_str = self._evaluate_cloze(q, c_opts)
|
||||
|
||||
# update ext with cloze details
|
||||
attempt.ext = {**(attempt.ext or {}), 'type': 'cloze', 'cloze': {'input': selection_list, 'evaluation': evaluation}}
|
||||
attempt.ext = {**(attempt.ext or {}), 'type': 'cloze', 'cloze': {'input': input_str, 'evaluation': evaluation}}
|
||||
await db.flush()
|
||||
merged_eval = dict(attempt.evaluation or {})
|
||||
merged_eval['cloze'] = {'input': selection_list, 'evaluation': evaluation}
|
||||
merged_eval['cloze'] = {'input': input_str, 'evaluation': evaluation}
|
||||
await qa_attempt_dao.update_status(db, attempt.id, 'completed', merged_eval)
|
||||
|
||||
if not is_trial:
|
||||
@@ -541,7 +553,7 @@ class QaService:
|
||||
'session_id': str(session_id_val) if session_id_val is not None else None,
|
||||
'type': 'cloze',
|
||||
'cloze': {
|
||||
'input': selection_list,
|
||||
'input': input_str,
|
||||
'evaluation': evaluation
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,6 +138,7 @@ jinja2==3.1.6
|
||||
# via
|
||||
# fastapi
|
||||
# fastapi-best-architecture
|
||||
langchain==1.2.3
|
||||
kombu==5.5.1
|
||||
# via celery
|
||||
loguru==0.7.3
|
||||
|
||||
Reference in New Issue
Block a user