PhysicsCorrection/AGENTS.md

392 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 项目概述
- **名称**: 初中物理作业批改工作流
- **功能**: 上传多张作业图片和Word答案文件自动识别学生答案、提取标准答案、精准批改并返回批改结果JSON
### 节点清单
| 节点名 | 文件位置 | 类型 | 功能描述 | 分支逻辑 | 配置文件 |
|-------|---------|------|---------|---------|---------|
| doc_extract | `nodes/doc_extract_node.py` | agent | 从Word文件.docx提取题干和标准答案如无URL则返回空列表 | - | `config/doc_extract_llm_cfg.json` |
| process_images | `nodes/process_images_node.py` | looparray | 循环调用子图处理每张作业图片,生成最终批改结果 | - | - |
**类型说明**: task(普通任务节点) / agent(大模型节点) / condition(条件分支) / looparray(列表循环) / loopcond(条件循环)
## 子图清单
| 子图名 | 文件位置 | 功能描述 | 被调用节点 |
|-------|---------|------|---------|
| single_image_subgraph | `graphs/loop_graph.py` | 处理单张图片的完整批改流程(预处理→识别批改→整合→包装) | process_images |
### 子图内部节点
| 节点名 | 文件位置 | 类型 | 功能描述 |
|-------|---------|------|---------|
| image_preprocess | `nodes/image_preprocess_node.py` | task | 下载图片、自动旋转横向→纵向、缩放到固定宽度1000px、上传对象存储 |
| recognize_and_correct | `nodes/recognize_and_correct_node.py` | agent | **一体化识别批改**合并识别题目和批改为一次LLM调用 |
| result_merge | `nodes/result_merge_node.py` | task | 将识别结果和批改结果合并为最终批注 |
| wrap_result | `graphs/loop_graph.py` | task | 包装子图结果为SingleImageResult输出 |
## 技能使用
- 节点 `recognize_and_correct` 使用大语言模型技能(多模态,识别+批改合并)
- 模型:`doubao-seed-2-0-pro-260215`(旗舰视觉模型,推理能力强,输出简洁)
- 节点 `doc_extract` 使用大语言模型技能
- 模型:`doubao-seed-2-0-pro-260215`(旗舰模型,复杂推理能力强)
- 使用 python-docx 解析 Word 文档
## 工作流程(多图片批改架构)
```
┌─────────────────────┐
│ doc_extract │
│ (Word答案解析) │
└──────────┬──────────┘
┌─────────────────────┐
│ process_images │
│ (多图片循环处理) │
│ 生成最终批改结果 │
└─────────────────────┘
```
### 子图内部流程(处理单张图片 - 优化版)
```
┌─────────────────────┐
│ image_preprocess │
│ (图像预处理) │
└──────────┬──────────┘
┌─────────────────────┐
│recognize_and_correct│ ← 合并节点:识别+批改一次完成
│ (一体化识别批改) │
└──────────┬──────────┘
┌─────────────────────┐
│ result_merge │
│ (结果整合) │
└──────────┬──────────┘
┌─────────────────────┐
│ wrap_result │
│ (包装输出) │
└─────────────────────┘
```
## 核心功能:多图片批改机制
### 输入参数
- `homework_images`: 上传的作业图片列表List[File],支持多张图片)
- `answer_doc_url`: 正确答案Word文件的URL.docx格式**可选**
- `comment_max_length`: 评语最大字数默认100字**可选**
- `max_concurrent`: 并行批改的最大数量默认10**可选**
- `grade_standards`: 评价等级标准(**可选**,默认值如下)
```json
{
"A+": {"min_percentage": 95, "description": "答案全部正确,步骤完整规范,逻辑严谨;书写/格式整洁无错别字、无遗漏完成度100%,态度认真,质量上乘"},
"A": {"min_percentage": 90, "description": "答案完全正确无任何错误步骤合理、格式规范无原则性问题完成度100%,满足全部要求"},
"B": {"min_percentage": 80, "description": "存在少量非关键性错误,或步骤略有缺失;整体思路基本正确,仅细节、格式、计算等小问题;完成大部分内容,整体合格但不够严谨"},
"C": {"min_percentage": 70, "description": "错误较多,部分核心题目作答错误;步骤不完整、逻辑不够清晰;完成度一般,有明显应付、漏答情况"},
"D": {"min_percentage": 0, "description": "大面积错误,核心知识点未掌握;大量空白、敷衍、抄袭;未达到基本完成要求"}
}
```
### 输出结果
- `final_result`: 最终批改结果JSON包含多图片
- `total_images`: 总图片数
- `image_results`: 各图片的批改结果列表
- `overall_comment`: 整体评价(根据得分率生成)
- `total_score`: 总得分
- `full_score`: 总满分
- `grade`: 等级评定
### 批改优先级(严格按照以下顺序)
1. **最优先**使用Word文档中的标准答案批改
- 当提供了`answer_doc_url`且在文档中找到对应题目时
- 严格按照标准答案判断学生答案正误
2. **降级方案**:使用专业物理老师批改
- 场景1未提供`answer_doc_url`
- 场景2提供了URL但文档中未找到对应题目
- 使用专业物理老师的经验自主判断答案正误
### 功能说明
1. **多图片支持**可上传多张作业图片系统会并行处理每张图片并发数限制为3
2. **Word答案提取**:从.docx文件中提取题干和标准答案
3. **子图循环处理**:使用子图封装单图片处理流程,主图调用子图处理每张图片
4. **批改结果JSON**返回包含所有图片批改结果的结构化JSON
5. **智能降级**:无标准答案时自动切换到专业老师模式
## 优化记录
### 2026-03-26 填空题拆分优化(重要)
**问题**:一道题有多个填空时,被合并成一个答案,批改标记无法精准定位
**修复内容**
1. **优化Prompt**
- 明确要求:一道题有多个填空时,**每个空单独识别为一个题目**
- 题号格式:\"3(1)第一空\"、\"3(1)第二空\"、\"4(2)第一空\"、\"4(2)第二空\"
- 每个空单独批改,单独打分
2. **示例说明**
```
❌ 错误3(1) → "4、1"(合并)
✅ 正确3(1)第一空 → "4"
3(1)第二空 → "1"
```
3. **参数传递优化**
- comment_max_length参数正确传递到Jinja2模板
- 确保LLM生成符合长度要求的comment
**效果**
- 识别数量从9个增加到13个
- 每个填空都有独立的批改标记
- 批改标记精准定位到每个答案位置
### 2026-03-26 JSON解析优化重要
**问题**LLM输出可能不完整被max_completion_tokens截断导致JSON解析失败
**修复内容**
1. **新增fix_incomplete_json函数**
- 自动检测缺失的括号(}和]
- 自动补全缺失的括号使JSON完整
- 示例:`{"results": [{"id": 1}` → 自动补全为 `{"results": [{"id": 1}]}`
2. **增强JSON解析流程**
- 第一步:尝试直接解析
- 第二步尝试修复不完整的JSON补全括号
- 第三步尝试提取JSON对象
- 第四步尝试修复提取的JSON
3. **移除错误的截断逻辑**
- 不再在解析后截断comment可能破坏转义字符
- 完全依赖LLM遵守comment_max_length限制
- 通过Prompt明确要求LLM控制comment长度
4. **参数正确传递**
- comment_max_length参数正确传递到Prompt
- LLM根据该参数生成符合长度的comment
**效果**
- JSON解析成功率大幅提升
- 能够处理不完整的JSON输出
- comment长度由LLM控制避免截断破坏格式
### 2026-03-26 识别优化:禁止标注实验装置图(重要)
**问题**
1. 在实验装置图(如弹簧测力计、烧杯等)上标注了批改气泡
2. 坐标定位不够精准
**修复内容**
1. **Prompt优化**
- 明确禁止标注实验装置图、示意图、电路图
- 明确禁止标注图中标注的字母如A、B、C、D、E、F、G
- 强调只标注学生手写答案
2. **工程规范优化**
- 从config文件读取sp和up符合工程规范
- 使用Jinja2模板渲染Prompt
- 代码中只保留动态部分构建(标准答案、图片尺寸等)
3. **识别流程优化**
- 找题号 → 找学生答案 → 框选答案 → 判断正误
- 强调学生答案的特征:手写、填写空白处、计算结果
**效果**:不再误标注实验装置图,只标注学生手写答案
### 2026-03-26 新增并行数量控制参数
**优化前**硬编码并发数限制为3不够灵活
**优化后**添加max_concurrent参数默认值10用户可自定义
**具体优化**
1. **新增参数**`max_concurrent`可选默认10
2. **修改位置**
- `GraphInput.max_concurrent: Optional[int] = 10`
- `GlobalState.max_concurrent: int = 10`
- `ProcessImagesInput.max_concurrent: int`
3. **使用方式**
```json
{
"homework_images": [...],
"max_concurrent": 5 // 最多同时处理5张图片
}
```
**效果**:用户可根据服务器性能和网络情况灵活调整并发数
### 2026-03-26 学科变更
**修改**:将所有"数学"改为"物理"
- 节点描述:数学作业 → 物理作业
- Prompt中的学科引用数学 → 物理
- 配置文件说明更新
### 2026-03-25 多图片并行处理优化
**优化前**:多图片串行处理,总时间 = 单张图片时间 × 图片数量
**优化后**多图片并行处理并发数限制为3总时间大幅缩短
**具体优化**
1. **并行处理架构**:使用 `ThreadPoolExecutor` 并行调用子图处理每张图片
- 最多同时处理3张图片
- 结果按 `image_index` 正确排序,保证顺序一致性
2. **性能提升**
- 3张图片时间减少约66%从3份时间 → 1份时间
- 5张图片时间减少约80%从5份时间 → 约2份时间分两批并行
3. **质量保证**
- 每张图片独立处理,互不影响
- 识别逻辑、批改逻辑完全相同,质量不受影响
### 2026-03-26 坐标定位修复(重要)
**问题**:坐标定位特别不准,批改标记位置错误
**原因**Y坐标修正逻辑错误导致坐标被错误缩放
**修复内容**
1. **坐标系统重构**从绝对坐标改为相对坐标0-1000系统
- AI返回相对坐标0-1000(0,0)为图片左上角,(1000,1000)为右下角
- 代码将相对坐标转换为绝对坐标:`绝对X = 相对X × width / 1000``绝对Y = 相对Y × height / 1000`
2. **Prompt优化**
- 明确要求AI返回相对坐标0-1000
- 添加坐标系统说明和示例
3. **转换逻辑修正**
- 移除错误的Y坐标修正`Y × height_ratio`
- 实现正确的相对坐标到绝对坐标转换
**效果**:坐标定位准确,批改标记位置正确
### 2026-03-26 题目和答案识别优化(重要)
**问题**
1. 无法准确区分"题干"和"学生答案"
2. 批改气泡不在学生答案位置
3. 题干位置被误标注为答案
**修复内容**
1. **Prompt重写**
- 明确定义"题干"和"学生答案"的区别
- 强调只标注学生手写答案,不标注印刷体题干
- 添加识别流程指导
2. **坐标定位优化**
- 自动计算mark_position答案框右侧30像素垂直居中
- 添加边界检查,确保不超出图片范围
- 不再依赖AI返回的mark_position可能不准确
3. **识别指导**
- 题号识别如1、2、3、(1)、(2)等
- 答案定位:学生手写内容(不是印刷体)
- bbox框选准确框选学生答案区域
**效果**:更准确地区分题干和答案,批改气泡位置更精准
### 2026-03-25 批改速度优化
**优化前**每张图片需要3次LLM调用识别+批改+整体评价)
**优化后**每张图片只需1次LLM调用
**具体优化**
1. **合并识别和批改**:将`homework_recognize`和`correction_judge`合并为`recognize_and_correct`节点
- 识别题目、学生答案、坐标的同时进行批改
- 减少一次LLM调用速度提升约50%
2. **简化整体评价**不再调用LLM生成整体评价
- 使用规则直接生成评价内容
- 根据得分率和错误数量生成个性化评语
- 减少一次LLM调用
3. **子图节点精简**从5个节点减少到4个节点
- 移除homework_recognize、correction_judge
- 新增recognize_and_correct合并节点
- 保留image_preprocess、result_merge、wrap_result
**效果**
- LLM调用次数每张图片从3次减少到1次
- 预计批改时间减少约60%
### 2026-03-25 新增输入参数控制
1. **新增 `comment_max_length` 参数**控制评语最大字数默认100字
2. **新增 `grade_standards` 参数**:自定义评价等级标准
- 支持自定义各等级的最低得分率百分比
- 支持自定义各等级的描述
- 默认标准A+(≥95%)、A(≥90%)、B(≥80%)、C(≥70%)、D(<70%)
3. **使用方式**
```json
{
"homework_images": [...],
"comment_max_length": 50, // 评语最多50字
"grade_standards": {
"A+": {"min_percentage": 98, "description": "完美"},
"A": {"min_percentage": 90, "description": "优秀"},
...
}
}
```
### 2026-03-25 评语优化与整体评价
1. **评语具体化**批改评语要求具体说明对错原因
- 正确时说明为什么正确
- 错误时指出错误原因并给出正确答案
- 部分正确时说明哪些对了哪些错了
- 字数限制50字以内最多不超过100字
- 不要显示思考过程只输出结果
2. **评语示例**
- 选择题正确答案为B与标准答案一致正确
- 填空题错误答案应为8+√7和8-7学生只写了一个不完整
- 解答题正确解题过程完整步骤清晰结果正确
- 计算题错误计算过程有误正确答案是m=2建议检查移项步骤。
3. **整体评价**根据所有批改内容自动生成简短的整体评价
- 调用LLM生成个性化评价
- 评价不超过50字
- 包含主要问题或优点
- 给出简短建议
4. **HTML报告优化**在统计总览后显示整体评价区域
### 2026-03-25 自动旋转功能
1. **新增横向图片自动旋转**如果上传的图片宽度大于高度横向图片系统会自动旋转-90度使其变为纵向
2. **旋转时机**在图像预处理阶段下载图片后缩放前进行旋转
3. **旋转方向**逆时针旋转90度rotate(-90)确保文字方向正确
4. **日志记录**添加详细的旋转日志便于调试
### 2026-03-25 多图片批改功能
1. **新增多图片支持**从单图片批改升级为支持多图片批量批改
2. **新增子图架构**创建 `loop_graph.py` 封装单图片处理流程
3. **新增循环节点**创建 `process_images_node.py` 循环调用子图处理每张图片
4. **重构状态定义**
- `GraphInput.homework_image` `homework_images: List[File]`
- 新增 `SubgraphState`、`SubgraphInput`、`SubgraphOutput` 子图状态
- 新增 `SingleImageResult` 单图片批改结果
- 新增 `FinalResult.image_results` 多图片结果列表
5. **重构HTML生成**支持生成包含所有图片批改标注的HTML报告
6. **优化主图编排**简化为三节点线性流程doc_extract process_images html_generate
### 2026-03-25 双模式批改机制
1. **新增智能降级逻辑**优先使用标准答案无标准答案时自动切换专业老师模式
2. **修改state.py**`answer_doc_url`改为可选字段支持不提供答案URL的场景
3. **升级correction_judge_node**实现题目分离逻辑有标准答案和无标准答案分别处理
4. **更新Prompt**批改节点支持两种模式标准答案模式 + 专业老师模式
5. **优化doc_extract_node**无URL时返回空列表不中断工作流
### 2026-03-25 Word答案解析功能
1. 新增 `doc_extract_node` 节点从Word文件.docx提取题干和标准答案
2. 使用 python-docx 提取 Word 文档内容
3. 并行处理架构图像识别与答案解析同时进行
4. 基于 Word 中的标准答案进行精准批改
### 2026-03-25 OCR识别能力优化
1. 问题识别节点把学生答案中的"8"错认成"9"导致误判
2. 优化识别节点prompt增加OCR识别特别提示强调区分8和96和01和7等相似字符
3. 效果第7题正确识别为"8+√78-7"满分通过
### 2026-03-25 批改能力升级
1. 升级批改节点模型`doubao-seed-1-6-vision-250815` `doubao-seed-2-0-pro-260215`
2. 原因较小模型对选择题判断准确率不足
3. 效果选择题判断准确率大幅提升推理过程更严谨
### 2026-03-24 重构学习豆包APP方式
1. 从8个节点简化为5个节点现调整为子图+主图架构
2. 采用一体化识别AI识别answer_bbox代码计算mark_position
3. 实现精准坐标计算Y坐标与答案垂直中心完美对齐
## TODO
- 提供真实的多页作业图片进行完整流程测试
- 优化HTML报告的图片展示布局
- 支持PDF格式答案文档