单容器重构

This commit is contained in:
2025-12-12 22:36:25 +08:00
parent 31de3a94a6
commit 62cb6d18b0
14 changed files with 767 additions and 261 deletions

View File

@@ -118,47 +118,83 @@ class LLMService:
"""
prompt = """你是一个专业的试题解析专家。请仔细分析下面的文档内容,提取其中的所有试题。
请注意
**识别规则**
- 文档中可能包含中文或英文题目
- 题目可能有多种格式,请灵活识别
- 即使格式不标准,也请尽量提取题目内容
- 如果文档只是普通文章而没有题目,请返回空数组 []
对于每道题目,请识别
1. 题目内容 (完整的题目文字)
2. 题目类型(**只能**使用以下4种类型之一
- single单选题
- multiple多选
- judge判断题
- short简答题包括问答题、计算题、证明题、填空题等所有非选择题
3. 选项 (仅针对选择题,格式: ["A. 选项1", "B. 选项2", ...])
4. 正确答案 (请仔细查找文档中的答案。如果确实没有答案,可以填 null)
5. 解析/说明 (如果有的话)
**题目类型识别** (严格使用以下4种类型之一)
1. **single** - 单选题:只有一个正确答案的选择题
2. **multiple** - 多选题有多个正确答案的选择题答案格式如AB、ABC、ACD等
3. **judge** - 判断题:对错/是非/True False题目
4. **short** - 简答题:包括问答、计算、证明、填空、编程等所有非选择
**重要**:题目类型必须是 single、multiple、judge、short 之一,不要使用其他类型名称!
**多选题识别关键词**
- 明确标注"多选""多项选择""Multiple Choice"
- 题干中包含"可能""正确的有""包括"
- 答案是多个字母组合ABC、BD、ABCD
返回格式:请**只返回** JSON 数组,不要有任何其他文字或 markdown 代码块
**每道题目提取字段**
1. **content**: 完整的题目文字(去除题号)
2. **type**: 题目类型single/multiple/judge/short
3. **options**: 选项数组(仅选择题,格式: ["A. 选项1", "B. 选项2", ...]
4. **answer**: 正确答案
- 单选题: 单个字母 (如 "A""B")
- 多选题: 多个字母无空格 (如 "AB""ABC""BD")
- 判断题: ""/"""正确"/"错误""True"/"False"
- 简答题: 完整答案文本,如果没有答案填 null
5. **analysis**: 解析说明(如果有)
**JSON 格式要求**
- 必须返回一个完整的 JSON 数组 (以 [ 开始,以 ] 结束)
- 不要包含 markdown 代码块标记 (```json 或 ```)
- 不要包含任何解释性文字
- 字符串中的特殊字符必须正确转义(换行用 \\n引号用 \\",反斜杠用 \\\\
- 不要在字符串值中使用未转义的控制字符
**返回格式示例**
[
{{
"content": "题目内容",
"content": "下列关于Python的描述正确的是",
"type": "single",
"options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"],
"answer": "A",
"analysis": "解析说明"
"options": ["A. Python是编译型语言", "B. Python支持面向对象编程", "C. Python不支持函数式编程", "D. Python只能用于Web开发"],
"answer": "B",
"analysis": "Python是解释型语言支持多种编程范式"
}},
...
{{
"content": "以下哪些是Python的优点多选",
"type": "multiple",
"options": ["A. 语法简洁", "B. 库丰富", "C. 执行速度最快", "D. 易于学习"],
"answer": "ABD",
"analysis": "Python优点是语法简洁、库丰富、易学但执行速度不是最快的"
}},
{{
"content": "Python是一种高级编程语言",
"type": "judge",
"options": [],
"answer": "",
"analysis": null
}},
{{
"content": "请解释Python中的装饰器是什么",
"type": "short",
"options": [],
"answer": "装饰器是Python中一种特殊的函数用于修改其他函数的行为...",
"analysis": null
}}
]
文档内容:
**文档内容**
---
{content}
---
重要提示
- 仔细阅读文档内容
- 识别所有看起来像试题的内容
- 如果文档中没有题目(比如只是普通文章),返回 []
- **只返回 JSON 数组**,不要包含 ```json 或其他标记"""
**最后提醒**
- 仔细识别多选题(看题干、看答案格式)
- 单选和多选容易混淆,请特别注意区分
- 如果文档中没有题目,返回 []
- 只返回 JSON 数组,不要有任何其他内容"""
try:
if self.provider == "anthropic":
@@ -242,6 +278,14 @@ class LLMService:
result = result.strip()
# Additional cleanup: fix common JSON issues
# 1. Remove trailing commas before closing brackets
import re
result = re.sub(r',(\s*[}\]])', r'\1', result)
# 2. Fix unescaped quotes in string values (basic attempt)
# This is tricky and may not catch all cases, but helps with common issues
# Log the cleaned result for debugging
print(f"[LLM Cleaned JSON] Length: {len(result)} chars")
print(f"[LLM Cleaned JSON] First 300 chars:\n{result[:300]}")
@@ -377,42 +421,61 @@ class LLMService:
prompt = """你是一个专业的试题解析专家。请仔细分析这个 PDF 文档,提取其中的所有试题。
请注意
- PDF 中可能包含中文或英文题目
**识别规则**
- PDF 中可能包含中文或英文题目、图片、表格、公式
- 题目可能有多种格式,请灵活识别
- 即使格式不标准,也请尽量提取题目内容
- 题目内容如果包含代码或换行,请将换行符替换为空格或\\n
- 题目内容如果包含代码或换行,请将换行符替换为\\n
- 图片中的文字也要识别并提取
对于每道题目,请识别
1. 题目内容 (完整的题目文字,如果有代码请保持在一行或用\\n表示换行)
2. 题目类型(**只能**使用以下4种类型之一
- single单选题
- multiple多选
- judge判断题
- short简答题包括问答题、计算题、证明题、填空题等所有非选择题
3. 选项 (仅针对选择题,格式: ["A. 选项1", "B. 选项2", ...])
4. 正确答案 (请仔细查找文档中的答案。如果确实没有答案,可以填 null)
5. 解析/说明 (如果有的话)
**题目类型识别** (严格使用以下4种类型之一)
1. **single** - 单选题:只有一个正确答案的选择题
2. **multiple** - 多选题有多个正确答案的选择题答案格式如AB、ABC、ACD等
3. **judge** - 判断题:对错/是非/True False题目
4. **short** - 简答题:包括问答、计算、证明、填空、编程等所有非选择
**重要**:题目类型必须是 single、multiple、judge、short 之一,不要使用其他类型名称!
**多选题识别关键词**
- 明确标注"多选""多项选择""Multiple Choice"
- 题干中包含"可能""正确的有""包括"
- 答案是多个字母组合ABC、BD、ABCD
返回格式要求
**每道题目提取字段**
1. **content**: 完整的题目文字(去除题号,换行用\\n表示
2. **type**: 题目类型single/multiple/judge/short
3. **options**: 选项数组(仅选择题,格式: ["A. 选项1", "B. 选项2", ...]
4. **answer**: 正确答案
- 单选题: 单个字母 (如 "A""B")
- 多选题: 多个字母无空格 (如 "AB""ABC""BD")
- 判断题: ""/"""正确"/"错误""True"/"False"
- 简答题: 完整答案文本,如果没有答案填 null
5. **analysis**: 解析说明(如果有)
**JSON 格式要求**
1. **必须**返回一个完整的 JSON 数组(以 [ 开始,以 ] 结束)
2. **不要**返回 JSONL 格式(每行一个 JSON 对象)
3. **不要**包含 markdown 代码块标记(```json 或 ```
4. **不要**包含任何解释性文字
5. 字符串中的特殊字符必须正确转义(换行用 \\n引号用 \\",反斜杠用 \\\\
6. 不要在字符串值中使用未转义的控制字符
正确的格式示例:
**返回格式示例**
[
{{
"content": "题目内容",
"content": "下列关于Python的描述正确的是",
"type": "single",
"options": ["A. 选项1", "B. 选项2", "C. 选项3", "D. 选项4"],
"answer": "A",
"analysis": "解析说明"
"options": ["A. Python是编译型语言", "B. Python支持面向对象编程", "C. Python不支持函数式编程", "D. Python只能用于Web开发"],
"answer": "B",
"analysis": "Python是解释型语言支持多种编程范式"
}},
{{
"content": "第二道题",
"content": "以下哪些是Python的优点多选",
"type": "multiple",
"options": ["A. 语法简洁", "B. 库丰富", "C. 执行速度最快", "D. 易于学习"],
"answer": "ABD",
"analysis": "Python优点是语法简洁、库丰富、易学但执行速度不是最快的"
}},
{{
"content": "Python是一种高级编程语言",
"type": "judge",
"options": [],
"answer": "",
@@ -420,9 +483,10 @@ class LLMService:
}}
]
重要提示
**最后提醒**
- 请仔细查看 PDF 的每一页
- 识别所有看起来像试题的内容
- 仔细识别多选题(看题干、看答案格式)
- 单选和多选容易混淆,请特别注意区分
- 如果找不到明确的选项,可以根据上下文推断题目类型
- 题目内容中的换行请用\\n或空格替换确保 JSON 格式正确
- **只返回一个 JSON 数组**,不要包含其他任何内容"""
@@ -501,6 +565,11 @@ class LLMService:
result = result.strip()
# Additional cleanup: fix common JSON issues
# 1. Remove trailing commas before closing brackets
import re
result = re.sub(r',(\s*[}\]])', r'\1', result)
# Log the cleaned result for debugging
print(f"[LLM Cleaned JSON] Length: {len(result)} chars", flush=True)
print(f"[LLM Cleaned JSON] First 300 chars:\n{result[:300]}", flush=True)