diff --git a/HANDOFF.md b/HANDOFF.md index 6977495..3164a1d 100644 --- a/HANDOFF.md +++ b/HANDOFF.md @@ -1,6 +1,6 @@ # WiseGrade(智评)交接说明 -更新日期:2026-09-27。先阅读 [技术规格](docs/WISEGRADE_TECHNICAL_SPEC.md)、[会话页面与业务 Agent](docs/CHAT_AGENT.md) 和 [部署与使用指南](docs/DEPLOYMENT.md);本文件记录当前实现、验证边界和接手后的优先事项。 +更新日期:2026-09-27。先阅读 [项目指南](docs/GUIDE.md)(部署、使用、技术设计与会话实现);本文件记录当前实现、验证边界和接手后的优先事项。 ## 当前状态 @@ -33,7 +33,7 @@ ## 启动与检查 -首次部署复制 `.env.example` 为 `.env`,设置学生目录 `WISEGRADE_DATA_DIR`、随机 `WISEGRADE_SECRET_KEY`、DeepSeek 地址及密钥,并把离线 BGE-M3 模型放在 `models/bge-m3/`。扫描版 PDF 另需 `models/ocr/detection/` 和 `models/ocr/recognition/`。模型目录和 `.env` 均不提交到 Git。详情及 Windows 路径写法见 [部署指南](docs/DEPLOYMENT.md)。 +首次部署复制 `.env.example` 为 `.env`,设置学生目录 `WISEGRADE_DATA_DIR`、随机 `WISEGRADE_SECRET_KEY`、DeepSeek 地址及密钥,并把离线 BGE-M3 模型放在 `models/bge-m3/`。扫描版 PDF 另需 `models/ocr/detection/` 和 `models/ocr/recognition/`。模型目录和 `.env` 均不提交到 Git。详情及 Windows 路径写法见 [部署指南](docs/GUIDE.md)。 ```bash docker compose up @@ -56,7 +56,7 @@ uv run pytest -q ## 已验证与尚未验证 - 部署镜像内完整后端测试:**19 通过、0 跳过**,包括 DOCX/PPTX 转换与页面图像测试。宿主机运行结果为 18 通过、1 跳过,因为宿主机未安装 LibreOffice;部署容器内为 25.2.3.2。另已用课程 DOCX 和验收 PPTX 实际验证页数、文字及页面图片。 -- 2026-09-25:后端测试已改用独立 PostgreSQL + pgvector,并通过真实 DeepSeek 和本地 BGE-M3 模型测试。19 个其他测试通过;使用课程示例材料的完整流程单独重跑通过,22 个评分项全部完成,教师复核和导出检查通过。测试命令见 `docs/DEPLOYMENT.md`。 +- 2026-09-25:后端测试已改用独立 PostgreSQL + pgvector,并通过真实 DeepSeek 和本地 BGE-M3 模型测试。19 个其他测试通过;使用课程示例材料的完整流程单独重跑通过,22 个评分项全部完成,教师复核和导出检查通过。测试命令见 `docs/GUIDE.md`。 - 2026-09-25 旧版部署时:前端生产构建通过;Compose 的 PostgreSQL、Redis、API、worker、Web 启动,首页、深链接、`/api/health`、课程及仪表盘 API 返回正常。数据库当时为 `0002`;全新 SQLite 数据库迁移至 `0002` 也已验证。 - 2026-09-26 当前源码:宿主机独立 PostgreSQL 测试执行 `uv run pytest -q -m 'not integration'`,**24 通过、1 跳过、2 个真实集成测试未运行**;使用既有测试镜像加只读源码挂载执行 Compose 同组测试,**25 通过、2 个真实集成测试未运行**。单独构造旧版 `0002` 表结构,在临时 PostgreSQL 数据库升级 `0003` 通过;新数据库迁移也由测试覆盖。前端 `npm run build` 和新 Nginx 配置 `nginx -t` 通过。 - 2026-09-26 最小真实 DeepSeek `tool_calls` 兼容性探针通过,完整工具白名单也返回 `list_courses` 原生调用;该端点拒绝 `tool_choice="required"`,适配层已使用 `auto` 并校验返回的工具调用。未在该探针发送学生原件。 diff --git a/README.md b/README.md index 15b265b..b44b1ff 100644 --- a/README.md +++ b/README.md @@ -1,33 +1,27 @@ # WiseGrade(智评) -WiseGrade 是面向《自动化专业综合实践》课程的教师端自动评分系统。 +WiseGrade 是面向《自动化专业综合实践》课程的教师端自动评分系统,采用个人电脑本地部署、单机单管理员模式。 -教师端系统包含持久会话与业务 Agent、课程版本、挂载目录导入、自动文档解析与索引、知识库检索、独立评分批次、教师复核及导出。完整技术规格见: - -- [技术方案与开发规格](docs/WISEGRADE_TECHNICAL_SPEC.md) -- [会话页面与业务 Agent](docs/CHAT_AGENT.md) -- [Codex Goal 模式开发提示词](docs/CODEX_GOAL_PROMPT.md) - -## 当前约束 - -- 仅供教师使用 -- 通过宿主机挂载目录读取学生材料 -- 支持 PDF、DOCX、PPTX 和 PPT 导出的 PDF -- 使用本地 BGE-M3 嵌入模型 -- 使用 `deepseek-flash` 进行文本和图像理解 -- 支持课程、评分规则和评分批次版本化 -- 支持 Excel 成绩表和逐生 PDF 反馈导出 - -## 资料 - -课程原始资料位于 `docs/` 目录。 +系统支持课程与评分规则版本管理、挂载目录导入、文档解析与知识库检索、独立评分批次、教师复核、Excel 成绩表和逐生 PDF 反馈导出。教师也可通过持久会话查询材料、调用业务功能,并在确认卡片中核对和执行写入操作。 ## 快速启动 -1. 复制 `.env.example` 为 `.env`,设置 `WISEGRADE_DATA_DIR`、`DEEPSEEK_API_KEY` 和 `WISEGRADE_SECRET_KEY`。 -2. 将离线嵌入模型放在 `models/bge-m3/`(或修改 `EMBEDDING_MODEL_PATH`)。 -3. 运行 `docker compose up`,访问 。 +1. 复制 `.env.example` 为 `.env`,设置学生材料目录 `WISEGRADE_DATA_DIR`、`DEEPSEEK_API_KEY` 和随机 `WISEGRADE_SECRET_KEY`。 +2. 将离线 BGE-M3 模型放在 `models/bge-m3/`;扫描 PDF 另需离线 OCR 模型。 +3. 在仓库根目录运行 `docker compose up`,访问 。 -打开系统默认进入空白“会话”草稿;点击“新建”也只切换草稿,发送第一条消息才保存会话。历史会话可从列表继续或删除;回答上方可逐层展开工具调用,末尾可展开引用原文与页面链接。查询可直接执行,导入、入库、建批、启动、复核和导出先展示确认卡片,由教师点击后执行。学生材料只从只读挂载的 `/data/inbox` 读取。没有本地嵌入模型或 API 密钥时,系统仍可启动和完成导入;索引、会话或评分会显示明确错误。详细部署和使用步骤见 [部署与使用指南](docs/DEPLOYMENT.md)。 +学生材料从只读挂载的 `/data/inbox` 读取,支持 PDF、DOCX、PPTX 和 PPT 导出的 PDF。默认使用本地 BGE-M3 嵌入模型及 `deepseek-flash` 模型配置;模型端点需支持所用功能的文本、图像和工具调用。没有本地嵌入模型或 API 密钥时仍可启动和导入,依赖模型的功能会显示配置错误。 -评分证据与会话检索引用共用文档 ID 和页码。页面文字来自 PostgreSQL 的完整资料页记录,检索片段与向量也在 PostgreSQL;页面 PNG 位于 `data/processed/`,可从引用的“查看图像”打开。数据库直接生成的课程目标和规则没有实体页图像,因此只显示“查看页面文字”。历史引用由迁移 `0005` 一次性规范化。 +## 文档入口 + +部署、使用和技术说明统一维护在 **[项目指南](docs/GUIDE.md)**: + +- [部署与配置](docs/GUIDE.md#deployment):Linux、Windows Docker Desktop、离线模型和 OCR。 +- [教师使用](docs/GUIDE.md#usage):导入、评分、复核、导出与会话确认规则。 +- [业务规则与技术设计](docs/GUIDE.md#design):成绩结构、课程依据、解析、RAG、评分和版本管理。 +- [会话与业务 Agent 实现](docs/GUIDE.md#agent):任务、数据、工具边界、API 和恢复机制。 +- [开发与测试](docs/GUIDE.md#development) · [故障定位](docs/GUIDE.md#troubleshooting)。 + +[开发提示词](docs/prompts/README.md) 集中存放阶段任务说明;[交接记录](HANDOFF.md) 保留实现进展、验证记录和接手事项。 + +课程原始资料及测试示例仍位于 `docs/` 根目录,应用和测试按现有路径读取;学生原件、模型权重和运行产物不纳入项目文档。 diff --git a/docs/CHAT_AGENT.md b/docs/CHAT_AGENT.md deleted file mode 100644 index e9def94..0000000 --- a/docs/CHAT_AGENT.md +++ /dev/null @@ -1,35 +0,0 @@ -# 会话页面与业务 Agent - -更新日期:2026-09-27。本功能在原单机教师端内实现;原课程、导入、评分、复核和导出页面继续可用。 - -## 使用 - -打开系统默认进入空白“会话”草稿,点击“新建”立即切换到另一空白草稿,不弹窗、不写数据库。可在输入区直接提问,并在首次发送前反复选择或清除课程版本、评分批次和学生项目。发送首条非空消息时,会话和消息在同一事务保存;此后范围固定且在界面显示为只读。旧版留下的空会话仍可编辑范围。选择批次或项目会自动带入所属课程版本,清除课程版本会同时清除下级选择。范围固定后,工具不能读取范围之外的对象。会话列表、消息、引用、待确认操作和运行状态保存在数据库,刷新后可查看历史会话;刷新或再次进入页面仍打开新草稿。 - -可先问“列出课程版本”“扫描 batch 目录”“查看批次 3 的失败评分项”“查询项目 12 的报告实验数据”。课程目标与规则来自数据库;指定批次时使用批次创建时的快照。课程资料和报告通过 BGE-M3/pgvector 检索,回答附资料名、页码或幻灯片编号、原文片段和来源链接。评分证据与 Agent 检索引用都使用 `KnowledgeDocument` 的文档 ID、页码,对应同一 `KnowledgePage`:`/api/knowledge/documents/{id}/pages/{page}` 返回该页完整提取文字,`/image` 返回存在的页面 PNG。评分引用另有“查看评分”链接。历史引用由迁移 `0005` 一次性改写为这些统一地址;会话读取不再猜测旧图像链接。实体 PDF、DOCX、PPTX 页面经解析后通常同时有文字和图像;数据库直接生成的课程目标、评分规则等虚拟资料没有实体页面图像,只提供文字。没有证据时应明确说明。正式回答上方的“工具调用”先整体折叠,展开后每次调用仍独立折叠,可逐项查看参数和结果;回答末尾的“引用”也默认整体折叠。会话页不显示全局后台进度卡片,正在运行的会话仍在列表中标记。 - -扫描只读,可直接执行。导入、课程资料入库、创建批次、启动或重试、教师复核、导出和索引重试会生成确认卡片。卡片列出目标、范围、现值、新值及异常;教师点击“确认执行”才写入。模型工具白名单没有确认工具,聊天文字也不能代替按钮。导入候选有重复、识别异常或待确认文件时,卡片禁用确认;教师在卡片中修正身份、类别和文件选择,再“更新预览”。导入确认同时授权后台解析、必要 OCR 和项目索引。 - -教师复核必须在当前消息明确写出分数,例如“给 8 分”。Agent 可草拟评语,确认卡片展示批次、学生、评分项、模型原分、教师原分、证据、异常、新分和修改原因。失败或无法评分的项也可人工复核;原始模型分、证据和教师修改历史保留。 - -## 数据与任务 - -迁移 `0003` 添加会话、消息、运行、待确认操作、索引任务和批次固定项目清单;`0004` 添加首次请求幂等键与有界工具进度记录;`0005` 回填完整资料页文字与相对图像路径,并将历史会话中的引用一次性转换为统一页面链接。检索片段的文字和 1024 维向量保存在 PostgreSQL 的 `knowledge_chunks`;供教师核对的完整页文字单独保存在 `knowledge_pages`,避免以有重叠的检索片段拼接页面。PNG 文件位于共享 `data/processed/`,数据库只存相对于处理目录的路径;学生原件仍只读挂载在 `/data/inbox`。新批次在创建时保存项目 ID 列表;评分、结果查询和导出都使用该列表。旧批次该字段为 `NULL`,界面显示“历史项目清单未知”,只能按课程版本当前项目兼容读取,不能声称还原了创建时的范围。批次状态为 `created`、`queued`、`running`、`partial`、`failed`、`completed`;重复启动已入队或运行中的批次返回冲突。重试保留已评分项和教师复核。 - -导入后的每个待解析文件对应持久 `IndexTask`。worker 复用评分的解析和 RAG 入库代码;同一文件用共享处理目录中的文件锁串行化,避免自动索引与评分竞争写入。任务有 queued/running/completed/failed 状态、错误和重试入口。课程资料入库在会话中也作为索引任务执行。若 Redis 不可用,导入数据仍保存,索引任务标记失败并可重试。原始学生文件只从只读 `/data/inbox` 读取,文件 SHA-256 在预览和确认时复查。 - -待确认操作保存不可变参数、20 分钟有效期、幂等键和预期数据状态。确认时再次比对课程发布状态、规则与项目范围、批次状态、成绩与文件哈希。状态变化返回“重新预览”;重复确认已完成操作返回原结果。执行与会话 ID 写入审计日志。服务异常的操作标记失败,需重新准备;若进程在执行中崩溃,卡片保留 `executing` 状态,管理员应先核查实际业务记录再处理,不应直接重复写入。 - -批次汇总从数据库和现有权重规则计算完成数、未完成数、状态数量、分布、模型原始分均值和教师最终分均值。只有完整项目参与成绩均值及分布;失败、无法评分和待处理项不补零。详情仍可按学生、批次和评分项状态筛选。 - -## 模型与安全边界 - -会话使用模型设置页的 OpenAI 兼容 `/chat/completions` 地址、模型和后端 API Key。适配层按 [DeepSeek 原生工具调用文档](https://api-docs.deepseek.com/guides/tool_calls) 发送 `tools`,在每轮前用不含学生资料的 `wisegrade_ping` 最小探针验证端点会返回 `tool_calls`。当前 `deepseek-flash` 端点支持自动工具选择,但拒绝强制 `tool_choice="required"`,因此探针采用 `auto` 并检查返回结构。模型不支持时会显示明确配置错误,不会伪装工具已执行。既有评分 `json_call` 保持原有 JSON 行为。 - -工具输入由 Pydantic 校验,后端再校验课程、批次和项目关系。每条教师消息默认最多调用工具 32 次,成功、失败与跳过的尝试均计数;模型最多请求 33 轮,以便用完工具次数后还能生成回答。同一轮中工具名和经校验的参数(含默认分页值)完全相同时,后续调用会标为“已跳过”,模型收到前次调用标识并使用此前结果,不再执行工具;不同查询词、筛选或分页偏移仍会正常执行。可在 `.env` 中通过 `CHAT_MAX_TOOL_CALLS` 调整工具上限(1–64),修改后重新创建 API 容器。`get_scores` 每次最多返回一个项目的六项评分,响应给出 `next_criterion_offset` 和 `next_project_offset` 供继续查询;长结果保留结构化评分数据,不再变成无内容的截断提示。检索工具的运行记录保留每次调用找到的有界原文片段;回答引用对各次调用的证据去重后保存,不再只取前 20 条。工具没有任意 SQL、任意文件路径、HTTP 请求、代码执行或确认能力。检索片段只作为数据,不作为工具指令。模型只收到当前问题所需的规则摘要、检索片段或紧凑统计;API Key 不写入日志或会话表。 - -## API 与故障恢复 - -草稿仅存在于浏览器;`POST /api/conversations/first-message` 以 UUID 请求键原子创建会话、首条教师消息及运行,重复请求返回同一 ID。`POST /api/conversations` 保留给旧客户端。`GET /api/conversations` 返回列表和各会话运行标识;`GET /api/conversations/{id}` 恢复消息、卡片、工具记录和运行状态;`PUT /api/conversations/{id}/scope` 仅允许首条教师消息前编辑范围;`DELETE /api/conversations/{id}` 删除非运行中的会话。删除会话会清理消息、运行与待确认卡片,不回滚已经确认的业务操作,相关业务审计仍保留。`POST /api/conversations/{id}/messages/start` 在提交消息后启动独立后台运行;`GET /api/conversations/{id}/runs/{run_id}/events` 可按运行 ID 订阅持久 SSE 事件。旧版 `POST /api/conversations/{id}/messages` 继续提供 SSE 的 `run`、`tool`、`message`、`error`、`done` 事件。确认、取消和导入编辑分别为 `POST /api/conversations/{id}/actions/{action_id}/confirm|cancel|edit-import`。索引任务可通过 `GET /api/index-tasks`、`GET /api/index-tasks/{id}` 查询,失败任务可重试。Nginx 对消息流关闭代理缓冲并设置 900 秒读取超时。 - -回答生成由后台线程执行,页面切换或 SSE 断开不会停止运行;前端按运行 ID 订阅 SSE,并轮询列表和当前会话详情恢复进度,可同时运行多个不同会话。同一会话仍拒绝并发发送。刷新后默认打开新草稿,点击历史会话即可查看正在运行的工具状态或最终结果。运行中的会话删除返回冲突,应待完成后重试。服务进程异常留下的 `running` 记录超过 15 分钟,在读取会话时标为中断。模型失败时,已提交的教师消息仍保留,可在同一会话继续提问。工具记录保存有界查询词、筛选、分页及必要标识;教师复核评语和原因只显示省略标记,未知字段与密钥不保存。旧记录中未保存的检索查询词无法还原,界面明确标明;旧评分记录可从工具结果恢复实际分页偏移。检索工具记录有界原文片段,评分工具记录有界评分行,其他工具记录结构摘要。回答按安全 Markdown 渲染,HTML 不执行,链接仅允许 HTTP(S);工具过程在回答上方,引用在回答最后,二者默认折叠。待确认卡片始终独立显示。若嵌入模型或 OCR 缺失,任务保留具体失败原因;补齐离线模型后重试。若课程资料缺失、原件哈希变化、课程或批次状态变化,应重新预览。 diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md deleted file mode 100644 index 7360f35..0000000 --- a/docs/DEPLOYMENT.md +++ /dev/null @@ -1,132 +0,0 @@ -# WiseGrade(智评)部署与使用 - -WiseGrade 是单机单管理员教师端。Web 服务仅绑定 `127.0.0.1`,默认端口为 `18080`,可通过 `.env` 中的 `WISEGRADE_WEB_PORT` 修改。学生原件通过只读目录挂载进入容器,不经过浏览器上传。 - -## 准备 - -- Docker Engine + Compose v2(Linux),或 Windows Docker Desktop(WSL2 后端,运行 Linux 容器)。 -- 一个存放学生材料的宿主机目录;其下每个批次目录包含 `学号_姓名_选题题目` 子目录。 -- `deepseek-flash` 可访问的 OpenAI 兼容 API 地址和密钥;该端点必须支持文本、图片输入及原生 `tool_calls`。若只做评分而不使用对话,仍可沿用已有 JSON 调用。 -- 离线嵌入模型包。默认使用 BAAI/bge-m3。内存不足时可改用 BAAI/bge-small-zh-v1.5。 - -仓库的 `docs/` 是课程资料,不是学生原件。旧版 `.doc` 只用于课程模板,经 LibreOffice 转换;学生输入只接受 PDF、DOCX、PPTX。 -LibreOffice 已安装在后端 Docker 镜像中。按本指南使用容器时,教师不需要在 Windows 或 Linux 宿主机单独安装 LibreOffice;仅在脱离容器运行后端时才需自行安装。 - -## Linux 启动 - -```bash -cp .env.example .env -mkdir -p data/inbox data/processed data/exports models/bge-m3 -``` - -编辑 `.env`: - -```env -WISEGRADE_DATA_DIR=/absolute/path/to/WiseGradeData -DEEPSEEK_API_KEY=your-key -WISEGRADE_SECRET_KEY=用随机值替换且至少32位 -EMBEDDING_MODEL_PATH=/models/bge-m3 -``` - -也可以启动后在“模型设置”页面填写 API Key。密钥由后端加密保存,浏览器不会直接调用模型服务。`WISEGRADE_SECRET_KEY` 一旦用于加密设置,不要随意更换,否则已保存的密钥将无法解密。 - -```bash -docker compose up -docker compose ps -curl http://127.0.0.1:18080/api/health -``` - -打开 。`api` 启动时执行 Alembic 迁移并创建初始课程、目标、指标点和规则。评分任务由 `worker` 容器处理。 - -如 `18080` 端口已被占用,在 `.env` 中将 `WISEGRADE_WEB_PORT` 改为其他空闲端口,重新运行 `docker compose up -d`,并使用对应端口访问。 - -## Windows Docker Desktop 启动 - -1. 安装并启动 Docker Desktop,启用 WSL2 后端,保持 Linux 容器模式。 -2. 在 PowerShell 中进入项目目录:`Copy-Item .env.example .env`。 -3. 编辑 `.env` 中的 `WISEGRADE_DATA_DIR`,使用正斜杠绝对路径,例如 `D:/WiseGradeData`。不要在 `.env` 中添加引号。 -4. 将离线模型目录放在 `models/bge-m3`,填写 API 配置和随机 `WISEGRADE_SECRET_KEY`。 -5. 运行 `docker compose up`,访问 。 - -如果挂载失败,先确认 `WISEGRADE_DATA_DIR` 存在、Docker Desktop 已取得对应磁盘访问权,再运行 `docker compose config` 查看展开后的挂载路径。首次启动后若修改了 `.env` 中的 API Key 等配置,运行 `docker compose up -d --force-recreate api worker web`,使容器读取新值。当前仓库尚未在 Windows 实机验证上述路径和文件挂载。 - -## 离线模型包 - -应用镜像不在启动时下载 BGE-M3。将独立模型包解压到 `models/bge-m3/`,目录应包含模型权重、`config.json`、分词器文件及 SentenceTransformers 配置。容器中该目录只读映射为 `/models/bge-m3`。替代模型需同时修改: - -```env -EMBEDDING_MODEL_NAME=BAAI/bge-small-zh-v1.5 -EMBEDDING_MODEL_PATH=/models/bge-small-zh-v1.5 -EMBEDDING_MODEL_VERSION=your-package-version -``` - -`EMBEDDING_MODEL_VERSION` 会写入每个评分批次快照。若模型目录缺失或内容不完整,导入仍可完成,知识库入库和评分会显示错误。可离线分发 `docker save` 生成的镜像包及单独的 `models-bge-m3.tar.zst`;目标机执行 `docker load -i docker-images.tar` 后解压模型包,运行相同的 Compose 配置。 -也可以把模型复制进后端镜像,但当前 Dockerfile 和 Compose 采用只读目录挂载;若改成镜像内置模型,须同时调整构建上下文,并移除会遮盖镜像内 `/models` 的挂载。本机 BGE-M3 必需文件约 2.29 GB,后端镜像当前约 1.08 GB;直接内置后镜像未压缩体积预计约 3.37 GB。API 与 worker 可以共用镜像层,不必各存一份模型。独立模型包便于单独更新和分发。 - -扫描 PDF 的 OCR 使用 PaddleOCR。离线 OCR 包放在 `models/ocr/detection/` 和 `models/ocr/recognition/`,或修改 `OCR_MODEL_DIR` 指向包含这两个子目录的位置。没有 OCR 模型且 PDF 无可提取文字时,文件进入解析失败状态并显示原因;系统不会在解析时自动下载 OCR 模型。 - -下面这组 PP-OCRv5 mobile 中文识别模型已在 PaddleOCR 3.7.0 中验证。下载后将压缩包的顶层目录去掉,使 `detection/` 和 `recognition/` 内直接包含 `inference.yml`、`inference.json` 和 `inference.pdiparams`: - -```bash -mkdir -p models/ocr/detection models/ocr/recognition -curl -fL -o models/ocr/PP-OCRv5_mobile_det_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_det_infer.tar -curl -fL -o models/ocr/PP-OCRv5_mobile_rec_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_rec_infer.tar -tar -xf models/ocr/PP-OCRv5_mobile_det_infer.tar --strip-components=1 -C models/ocr/detection -tar -xf models/ocr/PP-OCRv5_mobile_rec_infer.tar --strip-components=1 -C models/ocr/recognition -``` - -模型名称从各自的 `inference.yml` 读取,不能让 PaddleOCR 使用与离线权重不匹配的默认模型。模型目录经 Compose 只读挂载,放入权重后无需修改 `.env`。 - -## 教师操作 - -打开系统默认进入“对话”。可新建并限定课程版本、批次和学生项目,使用自然语言查询规则、报告和进度。扫描目录可直接执行;导入、课程资料入库、建批、启动/重试、复核和导出须核对确认卡片并点击“确认执行”。有重复或识别异常的文件需先在卡片中修正选择。刷新后会话、引用和卡片保留。后台索引任务和评分进度可在对话页查看。详细规则见 [对话页面与业务 Agent](CHAT_AGENT.md)。 - -1. 在“课程与规则”中查看初始课程版本和评分规则。已发布版本不能直接覆盖;复制草稿、编辑、保存并发布新版本。课程目标、指标点、选题方向、模板和三个 Prompt 都属于课程版本。 -2. 在“知识库资料”中选课程版本并入库课程资料。入库使用本地嵌入模型和 PostgreSQL `pgvector`。 -3. 在“目录扫描与导入”中浏览 `/data/inbox` 下的相对目录,选择学生总目录并扫描。修正学号、姓名、选题和材料类型;PPT 导出的 PDF 必须确认成“汇报PPT/PDF”。每类材料只选择一个文件。 - 确认导入后,材料自动进入后台解析、必要 OCR 和索引任务;评分前即可检索已完成索引的报告。失败任务可从索引任务列表重试。 -4. 在“评分批次”中选择已发布课程和规则版本,创建并启动批次。每次评分建立独立批次;重试不会覆盖其他批次。 -5. 在“评分与复核”中查看逐项模型原始分、原文证据、页码、页面图像和异常。教师可逐项填写分数、评语和修改说明;修改历史单独保留。 -6. 在“导出任务”中按批次导出 Excel,按学生导出 PDF 反馈。缺失或无法评分的项目显示待处理,不自动补零。 - -成绩为阶段报告 1、2、3 各占 10%,期末占 70%。期末四项为任务完成度 20、报告规范性 20、汇报答辩 40、结果分析 20。系统的“汇报答辩”只评价 PPT 或 PPT PDF 页面内容,不评价口头答辩。 - -## 开发与测试(uv) - -Python 依赖由 `backend/pyproject.toml` 管理: - -```bash -cd backend -uv sync --extra ocr --group dev -uv run alembic upgrade head -uv run uvicorn wisegrade.main:app --reload -``` - -测试从仓库根目录运行: - -```bash -docker compose --profile test run --build --rm test -``` - -先验证无需真实 API Key 的测试可运行:`docker compose --profile test run --build --rm test pytest -q -m 'not integration'`。宿主机运行同一测试时,须把 `TEST_DATABASE_URL` 指向独立 PostgreSQL 测试库,并将 `EMBEDDING_MODEL_PATH` 指向本机离线模型目录。完整集成测试会访问真实模型,应单独执行和记录。 - -测试使用独立的 PostgreSQL 16 + pgvector 容器和 `test-redis`,不连接业务数据库或业务任务队列。每个数据库测试创建临时数据库,执行 Alembic 迁移后运行,结束时删除;`test-db` 的数据目录为 tmpfs,不会写入业务数据卷。测试会从 `.env` 读取真实 DeepSeek API Key,并加载 `models/bge-m3` 和 `models/ocr` 中的离线模型;完整流程测试会发起真实模型请求。在宿主机直接运行 `uv run pytest` 时,需先设置指向专用 `wisegrade_tests` 数据库的 `TEST_DATABASE_URL`(使用 `postgresql+psycopg` 驱动,账号需有创建数据库的权限),并提供可用的模型配置。 - -本地开发需提供 PostgreSQL、Redis 和与容器路径一致的挂载目录;可用 Compose 启动 `db` 和 `redis`。Vite 前端: - -```bash -cd frontend -npm install -npm run dev -``` - -开发服务器将 `/api` 代理到 `localhost:8000`。集成测试从仓库 `docs/` 复制阶段报告 1、2、3 与最终报告,并生成一份汇报 PDF 测试材料。 - -## 故障定位 - -- `docker compose logs api worker` 查看迁移、解析和任务异常。日志不输出 API Key。 -- 模型请求失败后按配置有限重试,评分项显示失败原因;可修复配置后重试该批次。 -- 对话若提示端点或模型不支持 `tool_calls`,在“模型设置”中选择支持工具调用的 OpenAI 兼容端点和模型。探针不发送课程或学生资料;普通模型对话仍有调用次数和超时限制。 -- 导入后索引任务若显示失败,查看 `/api/index-tasks/{id}` 的错误并修复 Redis、离线 BGE-M3 或 OCR,再重试。批次若已入队或运行,重复点击启动会返回冲突。 -- 原件哈希变化后必须重新扫描并确认导入,否则解析会报“源文件已变化”。 -- 源文件和模型目录为只读挂载;解析产物在 `data/processed/`,导出在 `data/exports/`,均被 Git 忽略。 diff --git a/docs/GUIDE.md b/docs/GUIDE.md new file mode 100644 index 0000000..5cbbf92 --- /dev/null +++ b/docs/GUIDE.md @@ -0,0 +1,1055 @@ +# WiseGrade(智评)项目指南 + +本指南统一维护部署、教师使用、技术设计和开发说明;项目简介和快速启动见 [README](../README.md)。整理日期:2026-09-30;会话实现说明沿用 2026-09-27 的记录。 + +部署与会话章节描述已有实现;“业务规则与技术设计”保留原始设计基线,其中标为初稿、建议或验收目标的内容不代表已全部实现。当前实现与验证边界见 [交接记录](../HANDOFF.md),具体接口以代码和运行中的 `/docs` 为准。开发任务提示词集中在 [prompts](prompts/README.md),不作为功能完成证明。 + +## 目录 + +- [部署与配置](#deployment) +- [教师使用](#usage) +- [业务规则与技术设计](#design) +- [会话与业务 Agent 实现](#agent) +- [开发与测试](#development) +- [故障定位与恢复](#troubleshooting) + + + +## 部署与配置 + +WiseGrade 是单机单管理员教师端。Web 服务仅绑定 `127.0.0.1`,默认端口为 `18080`,可通过 `.env` 中的 `WISEGRADE_WEB_PORT` 修改。学生原件通过只读目录挂载进入容器,不经过浏览器上传。以下命令除明确切换目录外,均从仓库根目录执行。 + +### 准备 + +- Docker Engine + Compose v2(Linux),或 Windows Docker Desktop(WSL2 后端,运行 Linux 容器)。 +- 一个存放学生材料的宿主机目录;其下每个批次目录包含 `学号_姓名_选题题目` 子目录。 +- `deepseek-flash` 可访问的 OpenAI 兼容 API 地址和密钥;该端点必须支持文本、图片输入及原生 `tool_calls`。若只做评分而不使用对话,仍可沿用已有 JSON 调用。 +- 离线嵌入模型包。默认使用 BAAI/bge-m3。内存不足时可改用 BAAI/bge-small-zh-v1.5。 + +仓库的 `docs/` 同时存放项目文档与课程示例资料;其中 PDF、DOC、DOCX 是课程资料,不是待导入的学生原件。旧版 `.doc` 只用于课程模板,经 LibreOffice 转换;学生输入只接受 PDF、DOCX、PPTX。 +LibreOffice 已安装在后端 Docker 镜像中。按本指南使用容器时,教师不需要在 Windows 或 Linux 宿主机单独安装 LibreOffice;仅在脱离容器运行后端时才需自行安装。 + +### Linux 启动 + +```bash +cp .env.example .env +mkdir -p data/inbox data/processed data/exports models/bge-m3 +``` + +编辑 `.env`: + +```env +WISEGRADE_DATA_DIR=/absolute/path/to/WiseGradeData +DEEPSEEK_API_KEY=your-key +WISEGRADE_SECRET_KEY=用随机值替换且至少32位 +EMBEDDING_MODEL_PATH=/models/bge-m3 +``` + +也可以启动后在“模型设置”页面填写 API Key。密钥由后端加密保存,浏览器不会直接调用模型服务。`WISEGRADE_SECRET_KEY` 一旦用于加密设置,不要随意更换,否则已保存的密钥将无法解密。 + +```bash +docker compose up +docker compose ps +curl http://127.0.0.1:18080/api/health +``` + +打开 。`api` 启动时执行 Alembic 迁移并创建初始课程、目标、指标点和规则。评分任务由 `worker` 容器处理。 + +如 `18080` 端口已被占用,在 `.env` 中将 `WISEGRADE_WEB_PORT` 改为其他空闲端口,重新运行 `docker compose up -d`,并使用对应端口访问。 + +### Windows Docker Desktop 启动 + +1. 安装并启动 Docker Desktop,启用 WSL2 后端,保持 Linux 容器模式。 +2. 在 PowerShell 中进入项目目录:`Copy-Item .env.example .env`。 +3. 编辑 `.env` 中的 `WISEGRADE_DATA_DIR`,使用正斜杠绝对路径,例如 `D:/WiseGradeData`。不要在 `.env` 中添加引号。 +4. 将离线模型目录放在 `models/bge-m3`,填写 API 配置和随机 `WISEGRADE_SECRET_KEY`。 +5. 运行 `docker compose up`,访问 。 + +如果挂载失败,先确认 `WISEGRADE_DATA_DIR` 存在、Docker Desktop 已取得对应磁盘访问权,再运行 `docker compose config` 查看展开后的挂载路径。首次启动后若修改了 `.env` 中的 API Key 等配置,运行 `docker compose up -d --force-recreate api worker web`,使容器读取新值。当前仓库尚未在 Windows 实机验证上述路径和文件挂载。 + +### 离线模型包 + +应用镜像不在启动时下载 BGE-M3。将独立模型包解压到 `models/bge-m3/`,目录应包含模型权重、`config.json`、分词器文件及 SentenceTransformers 配置。容器中该目录只读映射为 `/models/bge-m3`。替代模型需同时修改: + +```env +EMBEDDING_MODEL_NAME=BAAI/bge-small-zh-v1.5 +EMBEDDING_MODEL_PATH=/models/bge-small-zh-v1.5 +EMBEDDING_MODEL_VERSION=your-package-version +``` + +`EMBEDDING_MODEL_VERSION` 会写入每个评分批次快照。若模型目录缺失或内容不完整,导入仍可完成,知识库入库和评分会显示错误。可离线分发 `docker save` 生成的镜像包及单独的 `models-bge-m3.tar.zst`;目标机执行 `docker load -i docker-images.tar` 后解压模型包,运行相同的 Compose 配置。 +也可以把模型复制进后端镜像,但当前 Dockerfile 和 Compose 采用只读目录挂载;若改成镜像内置模型,须同时调整构建上下文,并移除会遮盖镜像内 `/models` 的挂载。本机 BGE-M3 必需文件约 2.29 GB,后端镜像当前约 1.08 GB;直接内置后镜像未压缩体积预计约 3.37 GB。API 与 worker 可以共用镜像层,不必各存一份模型。独立模型包便于单独更新和分发。 + +扫描 PDF 的 OCR 使用 PaddleOCR。离线 OCR 包放在 `models/ocr/detection/` 和 `models/ocr/recognition/`,或修改 `OCR_MODEL_DIR` 指向包含这两个子目录的位置。没有 OCR 模型且 PDF 无可提取文字时,文件进入解析失败状态并显示原因;系统不会在解析时自动下载 OCR 模型。 + +下面这组 PP-OCRv5 mobile 中文识别模型已在 PaddleOCR 3.7.0 中验证。下载后将压缩包的顶层目录去掉,使 `detection/` 和 `recognition/` 内直接包含 `inference.yml`、`inference.json` 和 `inference.pdiparams`: + +```bash +mkdir -p models/ocr/detection models/ocr/recognition +curl -fL -o models/ocr/PP-OCRv5_mobile_det_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_det_infer.tar +curl -fL -o models/ocr/PP-OCRv5_mobile_rec_infer.tar https://paddle-model-ecology.bj.bcebos.com/paddlex/official_inference_model/paddle3.0.0/PP-OCRv5_mobile_rec_infer.tar +tar -xf models/ocr/PP-OCRv5_mobile_det_infer.tar --strip-components=1 -C models/ocr/detection +tar -xf models/ocr/PP-OCRv5_mobile_rec_infer.tar --strip-components=1 -C models/ocr/recognition +``` + +模型名称从各自的 `inference.yml` 读取,不能让 PaddleOCR 使用与离线权重不匹配的默认模型。模型目录经 Compose 只读挂载,放入权重后无需修改 `.env`。 + + + +## 教师使用 + +### 课程、导入、评分与导出 + +1. 在“课程与规则”中查看初始课程版本和评分规则。已发布版本不能直接覆盖;复制草稿、编辑、保存并发布新版本。课程目标、指标点、选题方向、模板和三个 Prompt 都属于课程版本。 +2. 在“知识库资料”中选课程版本并入库课程资料。入库使用本地嵌入模型和 PostgreSQL `pgvector`。 +3. 在“目录扫描与导入”中浏览 `/data/inbox` 下的相对目录,选择学生总目录并扫描。修正学号、姓名、选题和材料类型;PPT 导出的 PDF 必须确认成“汇报PPT/PDF”。每类材料只选择一个文件。 + 确认导入后,材料自动进入后台解析、必要 OCR 和索引任务;评分前即可检索已完成索引的报告。失败任务可从索引任务列表重试。 +4. 在“评分批次”中选择已发布课程和规则版本,创建并启动批次。每次评分建立独立批次;重试不会覆盖其他批次。 +5. 在“评分与复核”中查看逐项模型原始分、原文证据、页码、页面图像和异常。教师可逐项填写分数、评语和修改说明;修改历史单独保留。 +6. 在“导出任务”中按批次导出 Excel,按学生导出 PDF 反馈。缺失或无法评分的项目显示待处理,不自动补零。 + +成绩权重和评分依据见下文“业务规则与技术设计”。 + +### 会话、范围与操作确认 + +打开系统默认进入空白“会话”草稿,点击“新建”立即切换到另一空白草稿,不弹窗、不写数据库。可在输入区直接提问,并在首次发送前反复选择或清除课程版本、评分批次和学生项目。发送首条非空消息时,会话和消息在同一事务保存;此后范围固定且在界面显示为只读。旧版留下的空会话仍可编辑范围。选择批次或项目会自动带入所属课程版本,清除课程版本会同时清除下级选择。范围固定后,工具不能读取范围之外的对象。会话列表、消息、引用、待确认操作和运行状态保存在数据库,刷新后可查看历史会话;刷新或再次进入页面仍打开新草稿。 + +可先问“列出课程版本”“扫描 batch 目录”“查看批次 3 的失败评分项”“查询项目 12 的报告实验数据”。课程目标与规则来自数据库;指定批次时使用批次创建时的快照。课程资料和报告通过 BGE-M3/pgvector 检索,回答附资料名、页码或幻灯片编号、原文片段和来源链接。评分证据与 Agent 检索引用都使用 `KnowledgeDocument` 的文档 ID、页码,对应同一 `KnowledgePage`:`/api/knowledge/documents/{id}/pages/{page}` 返回该页完整提取文字,`/image` 返回存在的页面 PNG。评分引用另有“查看评分”链接。历史引用由迁移 `0005` 一次性改写为这些统一地址;会话读取不再猜测旧图像链接。实体 PDF、DOCX、PPTX 页面经解析后通常同时有文字和图像;数据库直接生成的课程目标、评分规则等虚拟资料没有实体页面图像,只提供文字。没有证据时应明确说明。正式回答上方的“工具调用”先整体折叠,展开后每次调用仍独立折叠,可逐项查看参数和结果;回答末尾的“引用”也默认整体折叠。会话页不显示全局后台进度卡片,正在运行的会话仍在列表中标记。 + +扫描只读,可直接执行。导入、课程资料入库、创建批次、启动或重试、教师复核、导出和索引重试会生成确认卡片。卡片列出目标、范围、现值、新值及异常;教师点击“确认执行”才写入。模型工具白名单没有确认工具,聊天文字也不能代替按钮。导入候选有重复、识别异常或待确认文件时,卡片禁用确认;教师在卡片中修正身份、类别和文件选择,再“更新预览”。导入确认同时授权后台解析、必要 OCR 和项目索引。 + +教师复核必须在当前消息明确写出分数,例如“给 8 分”。Agent 可草拟评语,确认卡片展示批次、学生、评分项、模型原分、教师原分、证据、异常、新分和修改原因。失败或无法评分的项也可人工复核;原始模型分、证据和教师修改历史保留。 + + + +## 业务规则与技术设计 + +以下保留初始业务约束、数据示例和设计要求。会话、持久任务及统一证据页的增量实现见[会话与业务 Agent 实现](#agent);原始页面清单和 API 初稿仅供理解设计。 + +### 项目概述 + +#### 项目目标 + +构建一个前后端分离的自动评分系统,对自动化专业综合实践课程中的以下材料进行内容评分: + +1. 阶段报告 1 +2. 阶段报告 2 +3. 阶段报告 3 +4. 最终报告 +5. 汇报 PPT,或 PPT 导出的 PDF + +系统输出可复核的逐项评分、原文证据、页码或幻灯片编号、缺失内容、评语和改进建议。 + +#### 非目标 + +第一版不实现: + +- 学生账号和在线提交 +- 现场口头答辩、答辩视频和语音评分 +- 学生个人贡献度自动识别 +- 代码仓库自动审查 +- AI 生成内容检测 +- 自动控制实验硬件的远程接入 + +课程评分表中的“汇报答辩 40 分”保留原名称,但本系统只依据 PPT 内容或 PPT PDF 内容评分,不评价现场口头答辩。 + +### 已确定的业务规则 + +#### 教师使用流程 + +系统只供教师使用,采用单机单管理员模式。教师不需要创建学生账号。 + +教师流程: + +```text +选择课程和学期 + -> 选择评分规则版本 + -> 选择挂载数据目录中的学生总文件夹 + -> 扫描学生子文件夹 + -> 自动识别学生信息和五类材料 + -> 教师确认导入结果 + -> 批量解析和评分 + -> 查看模型评分和证据 + -> 修改分数和评语 + -> 导出 Excel 成绩表和逐生 PDF 反馈 +``` + +#### 学生目录结构 + +宿主机数据目录示例: + +```text +WiseGradeData/ +└── 2026春季第1批/ + ├── 1023009006_李傲琦_基于ROS2系统的自瞄移动机器人/ + │ ├── 阶段报告1.pdf + │ ├── 阶段报告2.pdf + │ ├── 阶段报告3.pdf + │ ├── 自动化专业综合实践报告.pdf + │ └── 汇报PPT.pptx + └── 其他学生/ +``` + +学生目录命名格式: + +```text +学号_姓名_选题题目 +``` + +文件夹名称只用于初步识别。系统还要从文件首页、标题和正文中抽取姓名、学号、项目题目和选题方向,并在不一致时提醒教师确认。 + +#### 支持文件 + +支持: + +- PDF +- DOCX +- PPTX +- PPT 导出的 PDF + +不支持旧版 `.doc` 作为学生输入。 + +PPT PDF 必须在导入确认阶段标记为“汇报材料”,以免与最终报告 PDF 混淆。 + +#### 成绩结构 + +总评成绩: + +```text +总评 = 阶段报告1 × 10% + + 阶段报告2 × 10% + + 阶段报告3 × 10% + + 期末成绩 × 70% +``` + +期末评分保持课程评分表结构: + +| 评分项 | 分值 | +|---|---:| +| 任务完成度 | 20 | +| 报告规范性 | 20 | +| 汇报答辩(系统仅按 PPT 内容评价) | 40 | +| 结果分析 | 20 | + +#### 评分批次 + +每次评分创建独立批次。批次之间不覆盖、不替代,也不设置唯一“正式批次”。每个批次均可查看、复核和导出。 + +批次必须保存: + +- 课程版本 +- 评分规则版本 +- 课程目标版本 +- `deepseek-flash` 模型配置快照 +- 嵌入模型名称和版本 +- 创建时间和结束时间 +- 评分任务状态 + +### 课程和评分依据 + +初始资料位于 `docs/`: + +- `课程导学-自动化专业综合实践.pdf` +- `自动化专业综合实践三融合选题课程概述.pdf` +- `大作业评分表-自动化专业综合实践.docx` +- `阶段报告1模板.doc` +- `阶段报告2模板.doc` +- `阶段报告3模板.doc` +- `阶段报告1.pdf` +- `阶段报告2.pdf` +- `阶段报告3.pdf` +- `自动化专业综合实践报告.pdf` + +#### 课程目标和毕业要求指标点 + +系统初始知识库必须包含并建立关联: + +- 课程目标 1:问题解决与研究能力 +- 课程目标 2:知识运用与分析能力 +- 课程目标 3:实验设计与操作能力 +- 课程目标 4:数据处理与报告撰写能力 +- 毕业要求指标点 2.3、2.4 +- 毕业要求指标点 4.1、4.2、4.3、4.4 +- 毕业要求指标点 11.1、11.2 + +#### 阶段报告要求 + +##### 阶段报告 1:复杂自动化工程问题解决方案论证报告 + +重点内容: + +- 文献调研和技术现状 +- 复杂工程问题分析 +- 主方案和至少一套替代方案 +- 方案原理、适用场景和优劣对比 +- 数理或工程依据下的可行性论证 +- 进度计划、资源配置、成本构成和经济性分析 + +初始评分框架: + +| 评分项 | 分值 | +|---|---:| +| 复杂工程问题和需求分析 | 25 | +| 文献调研和技术现状总结 | 20 | +| 主方案和替代方案设计 | 25 | +| 可行性、风险和合理性论证 | 15 | +| 工程管理、进度和成本分析 | 10 | +| 报告完整性和规范性 | 5 | +| 合计 | 100 | + +##### 阶段报告 2:实验系统设计与硬件搭建方案 + +重点内容: + +- 硬件选型清单、参数和依据 +- 系统架构图、硬件连接或接口关系 +- 分步骤实验计划、测试方法和预期指标 +- 安全风险、防护措施和操作规范 + +初始评分框架: + +| 评分项 | 分值 | +|---|---:| +| 系统架构和实现思路 | 20 | +| 硬件选型及选型依据 | 20 | +| 系统框图、连接关系和接口设计 | 20 | +| 实验方案、测试方法和预期指标 | 20 | +| 安全风险和防护措施 | 10 | +| 阶段进展及下一阶段计划 | 10 | +| 合计 | 100 | + +##### 阶段报告 3:软件设计与系统调试报告 + +重点内容: + +- 软件逻辑、流程图或状态图 +- 核心代码片段和实现说明 +- 调试过程、故障现象、原因和解决方法 +- 实验数据整理和初步分析 +- 系统功能、性能指标和存在问题 + +初始评分框架: + +| 评分项 | 分值 | +|---|---:| +| 软件逻辑和系统实现 | 20 | +| 核心代码和功能说明 | 20 | +| 调试过程、问题分析和解决方法 | 20 | +| 实验数据和初步分析 | 20 | +| 功能和性能指标验证 | 15 | +| 下一阶段计划及报告规范性 | 5 | +| 合计 | 100 | + +阶段评分框架必须作为可编辑的初始规则导入,不能写死在业务代码中。 + +### 总体架构 + +```text +React 前端 + | +FastAPI 后端 + |-- 课程、版本和规则管理 + |-- 挂载目录扫描和导入 + |-- 文档解析和事实抽取 + |-- RAG 检索 + |-- 评分编排和批次管理 + |-- 教师复核 + |-- Excel/PDF 导出 + | +PostgreSQL + pgvector +Redis + RQ +本地文件存储 +本地 BGE-M3 嵌入模型 +DeepSeek API(deepseek-flash) +``` + +采用模块化单体后端,不在第一版拆分成大量微服务。模块边界清晰,后续可以拆分。 + +#### 推荐技术栈 + +- 前端:React、TypeScript、Vite、Ant Design +- 后端:Python、FastAPI、SQLAlchemy、Pydantic +- 数据库:PostgreSQL、pgvector +- 后台任务:Redis、RQ +- PDF 解析:PyMuPDF +- DOCX 解析:python-docx +- PPTX 解析:python-pptx +- 页面转换:LibreOffice headless +- OCR:PaddleOCR,扫描 PDF 时作为回退 +- 本地嵌入:`BAAI/bge-m3` +- 模型调用:OpenAI 兼容客户端,统一模型名 `deepseek-flash` +- Excel:openpyxl 或 pandas +- PDF 反馈:HTML/CSS + WeasyPrint 或 Playwright +- 部署:Docker Compose + +### 宿主机目录挂载方案 + +原始学生材料不通过浏览器上传。前端只选择后端可见的挂载目录下的大文件夹,后端扫描和读取文件。 + +挂载路径与平台配置统一见[部署与配置](#deployment)。 + +#### 路径安全 + +- 后端只允许访问 `/data/inbox` +- 前端只提交挂载目录内的相对路径 +- 禁止提交绝对路径 +- 后端必须执行路径规范化和越界检查 +- 原始输入目录只读挂载 +- 解析结果、任务状态和导出文件写入独立目录 + +#### 文件变更检测 + +导入时保存: + +- 相对路径 +- 文件大小 +- 修改时间 +- SHA-256 +- MIME 类型 +- 解析状态 + +若文件哈希未变化,不重复解析和向量化。源文件变化时提示重新导入。 + +### 文档解析和结构化 + +#### 统一文档对象 + +每个文档解析为: + +```json +{ + "document_type": "stage1", + "source_path": "...", + "pages": [ + { + "page_number": 1, + "text": "...", + "tables": [], + "images": [], + "rendered_image_path": "..." + } + ] +} +``` + +必须保留页码、章节名、表格和图片关联。 + +#### 文件识别 + +支持通过以下信号识别材料类型: + +- 文件名关键词 +- 文件扩展名 +- 文档标题 +- 首页文本 +- 章节标题 +- PPT 页数和标题 + +识别结果包括: + +```text +确定 +不确定 +缺失 +重复 +无法解析 +``` + +不确定的文件进入教师确认界面。 + +#### PPT/PDF 视觉处理 + +- 提取 PPT 原生文字、表格和备注 +- 将每一页渲染为图片 +- PDF 每页保存页面图像 +- 评分相关页面连同文字一起发送给 `deepseek-flash` +- 图片证据必须关联页码或幻灯片编号 + +### RAG 方案 + +#### 知识库分层 + +##### 公共课程知识库 + +- 课程导学 +- 课程目标 +- 毕业要求指标点 +- 评分表 +- 三个阶段模板 +- 各选题方向要求 +- 优秀报告 +- 课程版本资料 + +##### 学生项目知识库 + +每个学生独立命名空间: + +```text +course_2026/project_1023009006/ + stage1/ + stage2/ + stage3/ + final_report/ + presentation/ +``` + +禁止评分时检索其他学生的材料。 + +#### 文本切分 + +- 按标题和章节进行结构感知切分 +- 普通文本块约 400~800 个中文字符 +- 重叠约 80~120 个中文字符 +- 表格单独保存 +- 图片及图片说明单独保存 +- 每块必须保留页码、章节、文档类型和评分指标关联 + +#### 检索 + +采用混合检索: + +```text +PostgreSQL 全文检索 ++ pgvector 向量检索 ++ 课程版本过滤 ++ 学生项目过滤 ++ 报告类型过滤 ++ 阶段过滤 +``` + +默认每个评分项取 8~12 个候选证据块,去重后送入模型。 + +#### 嵌入模型 + +默认使用本地 `BAAI/bge-m3`;离线包、替代模型和版本配置见[部署与配置](#deployment)。 + +### DeepSeek 接入 + +#### 统一模型 + +只使用一个模型配置: + +```yaml +provider: deepseek +base_url: https://api.deepseek.com +model: deepseek-flash +``` + +同一个模型负责: + +- 文本理解 +- 图像理解 +- 事实抽取 +- 评分 +- 评语生成 +- PPT 分析 +- 跨文档一致性检查 + +#### 密钥管理 + +教师可以在设置页面配置: + +- API Key +- Base URL +- 模型名 +- 并发数 +- 超时时间 +- 重试次数 + +安全要求: + +- 前端不直接调用 DeepSeek +- API Key 只发送给后端 +- 数据库保存加密后的密钥 +- 日志禁止输出 API Key +- 支持环境变量初始化 + +#### 发送数据范围 + +原始文件保存在本地。模型请求只发送当前评分项所需的: + +- 文本证据块 +- 表格内容 +- 必要的页面图片 +- 课程评分标准 +- 已抽取的项目事实 + +不把全部报告无条件重复发送给每一个评分项。 + +### 评分引擎 + +评分采用多阶段流程: + +```text +文件导入 + -> 文档解析 + -> 项目事实抽取 + -> 规则检查 + -> 指标级 RAG 检索 + -> 指标级评分 + -> 跨文档一致性检查 + -> 分数汇总 + -> 教师复核 +``` + +#### 事实抽取 + +抽取: + +- 学号、姓名、项目名称 +- 选题方向 +- 功能目标 +- 性能指标 +- 硬件型号 +- 软件技术 +- 实验方案 +- 实验数据 +- 进度计划 +- 成本信息 +- 结论和改进方向 + +#### 评分输出 + +每个评分项必须返回结构化 JSON: + +```json +{ + "criterion_id": "stage1.solution_design", + "score": 17, + "max_score": 20, + "reason": "...", + "evidence": [ + { + "document": "阶段报告1", + "page": 12, + "quote": "..." + } + ], + "missing_evidence": ["..."], + "suggestion": "...", + "confidence": 0.84 +} +``` + +模型不得对没有证据的内容自行假设。结构化输出必须经过 Pydantic 校验;失败时自动重试或进入人工处理。 + +#### 跨文档一致性 + +至少检查: + +- 阶段 1 计划是否在阶段 2、3 中落实 +- 各报告中的项目名称、硬件型号和技术路线是否一致 +- 实验数据是否前后一致 +- 最终报告和 PPT 是否描述同一成果 +- 指标是否存在明显夸大或矛盾 + +### 规则配置和版本管理 + +规则不能写死在 Prompt 或 Python 代码中。 + +#### 评分指标结构 + +```yaml +criterion_id: stage1.solution_feasibility +name: 方案合理性与可行性 +max_score: 15 +description: 评价方案是否具有工程依据、可实施性和风险分析 +linked_outcomes: [2.3, 2.4, 4.1] +required_evidence: + - 主方案 + - 替代方案 + - 方案比较 + - 风险分析 +score_levels: + - min: 12 + max: 15 + description: 论证充分,方案比较清晰,风险分析具体 + - min: 6 + max: 11 + description: 基本完成论证,但证据或分析不充分 + - min: 0 + max: 5 + description: 缺少核心论证 +``` + +#### 版本要求 + +课程、课程目标、毕业要求、模板、评分规则和 Prompt 都需要版本号。评分批次保存完整版本快照。 + +教师修改规则后创建新版本,不覆盖历史版本。 + +### 核心数据表 + +建议至少包含: + +```text +courses +course_versions +course_objectives +graduation_indicators +topic_directions +rubric_versions +rubric_criteria +rubric_score_levels +knowledge_documents +knowledge_chunks +students +projects +submissions +submission_files +scoring_batches +criterion_scores +score_evidences +teacher_revisions +export_tasks +app_settings +audit_logs +``` + +#### 评分批次 + +```text +scoring_batches + id + course_version_id + rubric_version_id + model_name + model_config_snapshot + embedding_model_name + embedding_model_version + status + created_at + finished_at +``` + +#### 评分项结果 + +```text +criterion_scores + id + batch_id + project_id + criterion_id + model_score + teacher_score + final_score + model_comment + teacher_comment + confidence + status +``` + +```text +final_score = teacher_score(存在时)或 model_score +``` + +模型原始结果不得被教师修改覆盖。 + +### 前端页面 + +第一版页面建议: + +1. 仪表盘 +2. 课程管理 +3. 课程版本和评分规则管理 +4. 课程资料/知识库管理 +5. 数据目录扫描与导入确认 +6. 学生项目列表 +7. 评分批次列表 +8. 批量评分进度 +9. 学生评分详情 +10. 证据和页码查看 +11. 教师复核 +12. Excel/PDF 导出 +13. 模型和系统设置 + +### 后端 API 初稿 + +#### 课程和规则 + +```text +GET /api/courses +POST /api/courses +GET /api/courses/{id}/versions +POST /api/courses/{id}/versions +GET /api/rubrics/{version_id} +PUT /api/rubrics/{version_id} +POST /api/rubrics/{version_id}/publish +``` + +#### 文件扫描和项目导入 + +```text +GET /api/storage/directories +GET /api/storage/directories/{relative_path}/children +POST /api/import/scan +POST /api/import/confirm +GET /api/projects +GET /api/projects/{id} +``` + +#### 评分 + +```text +POST /api/scoring-batches +GET /api/scoring-batches +GET /api/scoring-batches/{id}/progress +POST /api/scoring-batches/{id}/start +GET /api/scoring-batches/{id}/scores +GET /api/projects/{id}/scores?batch_id={batch_id} +PUT /api/criterion-scores/{id}/review +``` + +#### 导出 + +```text +POST /api/exports/excel +POST /api/exports/project-pdf +GET /api/exports/{id} +``` + +### 缺失和异常处理 + +材料状态: + +```text +已提交 +缺失 +重复 +无法解析 +内容不完整 +待人工确认 +``` + +处理原则: + +- 缺失阶段报告:该阶段进入待人工处理,不默认静默给零分 +- 缺失 PPT:汇报材料项显示无法评分 +- 缺少章节:按照对应评分项判断并扣分 +- 文件损坏:进入人工确认列表 +- DeepSeek 调用失败:自动有限重试,仍失败则标记评分项失败 +- 评分批次允许部分完成,但导出时必须显示未完成项目 + + + +## 会话与业务 Agent 实现 + +会话交互及确认规则见[教师使用](#usage)。以下记录数据、模型边界、接口与运行恢复机制。 + +### 数据与任务 + +迁移 `0003` 添加会话、消息、运行、待确认操作、索引任务和批次固定项目清单;`0004` 添加首次请求幂等键与有界工具进度记录;`0005` 回填完整资料页文字与相对图像路径,并将历史会话中的引用一次性转换为统一页面链接。检索片段的文字和 1024 维向量保存在 PostgreSQL 的 `knowledge_chunks`;供教师核对的完整页文字单独保存在 `knowledge_pages`,避免以有重叠的检索片段拼接页面。PNG 文件位于共享 `data/processed/`,数据库只存相对于处理目录的路径;学生原件仍只读挂载在 `/data/inbox`。新批次在创建时保存项目 ID 列表;评分、结果查询和导出都使用该列表。旧批次该字段为 `NULL`,界面显示“历史项目清单未知”,只能按课程版本当前项目兼容读取,不能声称还原了创建时的范围。批次状态为 `created`、`queued`、`running`、`partial`、`failed`、`completed`;重复启动已入队或运行中的批次返回冲突。重试保留已评分项和教师复核。 + +导入后的每个待解析文件对应持久 `IndexTask`。worker 复用评分的解析和 RAG 入库代码;同一文件用共享处理目录中的文件锁串行化,避免自动索引与评分竞争写入。任务有 queued/running/completed/failed 状态、错误和重试入口。课程资料入库在会话中也作为索引任务执行。若 Redis 不可用,导入数据仍保存,索引任务标记失败并可重试。原始学生文件只从只读 `/data/inbox` 读取,文件 SHA-256 在预览和确认时复查。 + +待确认操作保存不可变参数、20 分钟有效期、幂等键和预期数据状态。确认时再次比对课程发布状态、规则与项目范围、批次状态、成绩与文件哈希。状态变化返回“重新预览”;重复确认已完成操作返回原结果。执行与会话 ID 写入审计日志。服务异常的操作标记失败,需重新准备;若进程在执行中崩溃,卡片保留 `executing` 状态,管理员应先核查实际业务记录再处理,不应直接重复写入。 + +批次汇总从数据库和现有权重规则计算完成数、未完成数、状态数量、分布、模型原始分均值和教师最终分均值。只有完整项目参与成绩均值及分布;失败、无法评分和待处理项不补零。详情仍可按学生、批次和评分项状态筛选。 + +### 模型与安全边界 + +会话使用模型设置页的 OpenAI 兼容 `/chat/completions` 地址、模型和后端 API Key。适配层按 [DeepSeek 原生工具调用文档](https://api-docs.deepseek.com/guides/tool_calls) 发送 `tools`,在每轮前用不含学生资料的 `wisegrade_ping` 最小探针验证端点会返回 `tool_calls`。当前 `deepseek-flash` 端点支持自动工具选择,但拒绝强制 `tool_choice="required"`,因此探针采用 `auto` 并检查返回结构。模型不支持时会显示明确配置错误,不会伪装工具已执行。既有评分 `json_call` 保持原有 JSON 行为。 + +工具输入由 Pydantic 校验,后端再校验课程、批次和项目关系。每条教师消息默认最多调用工具 32 次,成功、失败与跳过的尝试均计数;模型最多请求 33 轮,以便用完工具次数后还能生成回答。同一轮中工具名和经校验的参数(含默认分页值)完全相同时,后续调用会标为“已跳过”,模型收到前次调用标识并使用此前结果,不再执行工具;不同查询词、筛选或分页偏移仍会正常执行。可在 `.env` 中通过 `CHAT_MAX_TOOL_CALLS` 调整工具上限(1–64),修改后重新创建 API 容器。`get_scores` 每次最多返回一个项目的六项评分,响应给出 `next_criterion_offset` 和 `next_project_offset` 供继续查询;长结果保留结构化评分数据,不再变成无内容的截断提示。检索工具的运行记录保留每次调用找到的有界原文片段;回答引用对各次调用的证据去重后保存,不再只取前 20 条。工具没有任意 SQL、任意文件路径、HTTP 请求、代码执行或确认能力。检索片段只作为数据,不作为工具指令。模型只收到当前问题所需的规则摘要、检索片段或紧凑统计;API Key 不写入日志或会话表。 + +### API 与故障恢复 + +草稿仅存在于浏览器;`POST /api/conversations/first-message` 以 UUID 请求键原子创建会话、首条教师消息及运行,重复请求返回同一 ID。`POST /api/conversations` 保留给旧客户端。`GET /api/conversations` 返回列表和各会话运行标识;`GET /api/conversations/{id}` 恢复消息、卡片、工具记录和运行状态;`PUT /api/conversations/{id}/scope` 仅允许首条教师消息前编辑范围;`DELETE /api/conversations/{id}` 删除非运行中的会话。删除会话会清理消息、运行与待确认卡片,不回滚已经确认的业务操作,相关业务审计仍保留。`POST /api/conversations/{id}/messages/start` 在提交消息后启动独立后台运行;`GET /api/conversations/{id}/runs/{run_id}/events` 可按运行 ID 订阅持久 SSE 事件。旧版 `POST /api/conversations/{id}/messages` 继续提供 SSE 的 `run`、`tool`、`message`、`error`、`done` 事件。确认、取消和导入编辑分别为 `POST /api/conversations/{id}/actions/{action_id}/confirm|cancel|edit-import`。索引任务可通过 `GET /api/index-tasks`、`GET /api/index-tasks/{id}` 查询,失败任务可重试。Nginx 对消息流关闭代理缓冲并设置 900 秒读取超时。 + +回答生成由后台线程执行,页面切换或 SSE 断开不会停止运行;前端按运行 ID 订阅 SSE,并轮询列表和当前会话详情恢复进度,可同时运行多个不同会话。同一会话仍拒绝并发发送。刷新后默认打开新草稿,点击历史会话即可查看正在运行的工具状态或最终结果。运行中的会话删除返回冲突,应待完成后重试。服务进程异常留下的 `running` 记录超过 15 分钟,在读取会话时标为中断。模型失败时,已提交的教师消息仍保留,可在同一会话继续提问。工具记录保存有界查询词、筛选、分页及必要标识;教师复核评语和原因只显示省略标记,未知字段与密钥不保存。旧记录中未保存的检索查询词无法还原,界面明确标明;旧评分记录可从工具结果恢复实际分页偏移。检索工具记录有界原文片段,评分工具记录有界评分行,其他工具记录结构摘要。回答按安全 Markdown 渲染,HTML 不执行,链接仅允许 HTTP(S);工具过程在回答上方,引用在回答最后,二者默认折叠。待确认卡片始终独立显示。若嵌入模型或 OCR 缺失,任务保留具体失败原因;补齐离线模型后重试。若课程资料缺失、原件哈希变化、课程或批次状态变化,应重新预览。 + + + +## 开发与测试 + +### 本地开发和测试命令 + +Python 依赖由 `backend/pyproject.toml` 管理: + +```bash +cd backend +uv sync --extra ocr --group dev +uv run alembic upgrade head +uv run uvicorn wisegrade.main:app --reload +``` + +测试从仓库根目录运行: + +```bash +docker compose --profile test run --build --rm test +``` + +先验证无需真实 API Key 的测试可运行:`docker compose --profile test run --build --rm test pytest -q -m 'not integration'`。宿主机运行同一测试时,须把 `TEST_DATABASE_URL` 指向独立 PostgreSQL 测试库,并将 `EMBEDDING_MODEL_PATH` 指向本机离线模型目录。完整集成测试会访问真实模型,应单独执行和记录。 + +测试使用独立的 PostgreSQL 16 + pgvector 容器和 `test-redis`,不连接业务数据库或业务任务队列。每个数据库测试创建临时数据库,执行 Alembic 迁移后运行,结束时删除;`test-db` 的数据目录为 tmpfs,不会写入业务数据卷。测试会从 `.env` 读取真实 DeepSeek API Key,并加载 `models/bge-m3` 和 `models/ocr` 中的离线模型;完整流程测试会发起真实模型请求。在宿主机直接运行 `uv run pytest` 时,需先设置指向专用 `wisegrade_tests` 数据库的 `TEST_DATABASE_URL`(使用 `postgresql+psycopg` 驱动,账号需有创建数据库的权限),并提供可用的模型配置。 + +本地开发需提供 PostgreSQL、Redis 和与容器路径一致的挂载目录;可用 Compose 启动 `db` 和 `redis`。Vite 前端: + +```bash +cd frontend +npm install +npm run dev +``` + +开发服务器将 `/api` 代理到 `localhost:8000`。集成测试从仓库 `docs/` 复制阶段报告 1、2、3 与最终报告,并生成一份汇报 PDF 测试材料。 + +### 测试要求 + +#### 单元测试 + +- 目录扫描 +- 学号/姓名/题目解析 +- 文件类型识别 +- 路径越界防护 +- 文件哈希检测 +- 规则权重计算 +- 缺失材料处理 +- 分数汇总 +- 评分 JSON 校验 +- 版本绑定 + +#### 集成测试 + +- 从示例材料导入到项目生成 +- PDF/DOCX/PPTX 解析 +- PPT PDF 识别 +- 知识库入库和检索 +- 模型 API mock 调用 +- 评分批次创建、运行和查询 +- 教师修改分数 +- Excel 导出 +- PDF 反馈导出 + +#### 验收测试 + +至少使用当前 `docs/` 中的示例材料完成一次完整流程: + +```text +扫描目录 + -> 导入学生项目 + -> 解析五类材料 + -> 创建评分批次 + -> mock 或真实调用 deepseek-flash + -> 查看逐项证据 + -> 修改分数 + -> 导出 Excel + -> 导出学生 PDF 反馈 +``` + +不应在测试中提交真实 API Key。使用环境变量或 mock 服务。 + +### Git 开发约定 + +必须创建合理的 `.gitignore`,至少忽略: + +```text +.env +data/processed/ +data/exports/ +models/ +__pycache__/ +.pytest_cache/ +node_modules/ +dist/ +*.pyc +``` + +开发和测试过程中按阶段提交,推荐提交节点: + +```text +chore: initialize project structure +feat: add backend foundation +feat: add course and rubric versioning +feat: add mounted directory scanning +feat: add document parsing pipeline +feat: add knowledge base and hybrid retrieval +feat: add deepseek-flash adapter +feat: add scoring batch orchestration +feat: add teacher review workflow +feat: add excel and pdf exports +test: add integration coverage +docs: add deployment and usage guides +``` + +每个提交应保持可理解、可回退、尽量可运行。禁止把 API Key、真实学生隐私数据和模型权重提交到 Git。 + +### 原始开发阶段(历史规划) + +以下优先级保留为初始实施顺序,不是当前待办清单;接手事项见 [HANDOFF](../HANDOFF.md)。 + +#### P0:可运行骨架 + +- Git、README、Docker Compose +- 前端和后端健康检查 +- 数据库迁移 +- 单管理员设置 + +#### P1:课程和导入 + +- 课程版本和规则配置 +- 挂载目录扫描 +- 学生目录识别 +- 文件识别和导入确认 + +#### P2:解析和知识库 + +- PDF/DOCX/PPTX 解析 +- 页面渲染 +- OCR 回退 +- BGE-M3 嵌入 +- pgvector 混合检索 + +#### P3:评分 + +- 事实抽取 +- 指标级 RAG 评分 +- 跨文档一致性检查 +- 批次状态和失败重试 + +#### P4:复核和导出 + +- 教师修改分数和评语 +- Excel 成绩表 +- 逐生 PDF 反馈 +- 审计日志 + +#### P5:验收和部署 + +- 示例材料完整验收 +- Linux 部署文档 +- Windows Docker Desktop 部署文档 +- 离线模型包说明 + +### 第一版验收目标 + +以下是验收目标,不代表所有平台和场景已实测。 + +当以下条件全部满足时,第一版系统完成: + +- Linux 上可以通过 Docker Compose 启动 +- Windows Docker Desktop 有明确部署步骤 +- 教师可以选择挂载目录下的大文件夹 +- 系统可以识别每个学生目录 +- 支持五类材料和 PPT PDF +- 规则、课程目标和课程版本可编辑 +- 可创建独立评分批次 +- 使用本地嵌入模型完成检索 +- 使用 `deepseek-flash` 完成文本和图像评分 +- 每项评分显示证据和页码/幻灯片编号 +- 教师可以修改分数和评语 +- 每个批次都可以导出 Excel 和逐生 PDF +- 示例材料可以完成端到端测试 +- Git 历史包含清晰的阶段提交 + + + +## 故障定位与恢复 + +- `docker compose logs api worker` 查看迁移、解析和任务异常。日志不输出 API Key。 +- 模型请求失败后按配置有限重试,评分项显示失败原因;可修复配置后重试该批次。 +- 对话若提示端点或模型不支持 `tool_calls`,在“模型设置”中选择支持工具调用的 OpenAI 兼容端点和模型。探针不发送课程或学生资料;普通模型对话仍有调用次数和超时限制。 +- 导入后索引任务若显示失败,查看 `/api/index-tasks/{id}` 的错误并修复 Redis、离线 BGE-M3 或 OCR,再重试。批次若已入队或运行,重复点击启动会返回冲突。 +- 原件哈希变化后必须重新扫描并确认导入,否则解析会报“源文件已变化”。 +- 源文件和模型目录为只读挂载;解析产物在 `data/processed/`,导出在 `data/exports/`,均被 Git 忽略。 + +会话运行中断、待确认操作卡在 `executing`、旧批次范围兼容等情况,见[会话与业务 Agent 实现](#agent)。 diff --git a/docs/WISEGRADE_TECHNICAL_SPEC.md b/docs/WISEGRADE_TECHNICAL_SPEC.md deleted file mode 100644 index 79f0943..0000000 --- a/docs/WISEGRADE_TECHNICAL_SPEC.md +++ /dev/null @@ -1,931 +0,0 @@ -# WiseGrade(智评)技术方案与开发规格 - -> 2026-09-26 增量实现:默认“对话”页面、应用内固定工具 Agent、持久会话、待确认操作、自动索引任务和批次固定项目清单。具体状态机、API 与恢复流程见 [对话页面与业务 Agent](CHAT_AGENT.md)。旧版正文的阶段计划按原始系统设计编写,新增业务边界以该增量文档及当前代码为准。 - -## 1. 项目概述 - -### 1.1 基本信息 - -- 英文名:**WiseGrade** -- 中文名:**智评** -- 当前服务课程:**自动化专业综合实践** -- 使用对象:教师 -- 部署形态:个人电脑本地部署 -- 当前开发环境:Linux -- 目标运行环境:Linux、Windows(Docker Desktop) -- 主要大模型:`deepseek-flash` -- 主要能力:课程材料管理、学生材料批量导入、RAG 辅助评分、教师复核、成绩和反馈导出 - -### 1.2 项目目标 - -构建一个前后端分离的自动评分系统,对自动化专业综合实践课程中的以下材料进行内容评分: - -1. 阶段报告 1 -2. 阶段报告 2 -3. 阶段报告 3 -4. 最终报告 -5. 汇报 PPT,或 PPT 导出的 PDF - -系统输出可复核的逐项评分、原文证据、页码或幻灯片编号、缺失内容、评语和改进建议。 - -### 1.3 非目标 - -第一版不实现: - -- 学生账号和在线提交 -- 现场口头答辩、答辩视频和语音评分 -- 学生个人贡献度自动识别 -- 代码仓库自动审查 -- AI 生成内容检测 -- 自动控制实验硬件的远程接入 - -课程评分表中的“汇报答辩 40 分”保留原名称,但本系统只依据 PPT 内容或 PPT PDF 内容评分,不评价现场口头答辩。 - -## 2. 已确定的业务规则 - -### 2.1 教师使用流程 - -系统只供教师使用,采用单机单管理员模式。教师不需要创建学生账号。 - -教师流程: - -```text -选择课程和学期 - -> 选择评分规则版本 - -> 选择挂载数据目录中的学生总文件夹 - -> 扫描学生子文件夹 - -> 自动识别学生信息和五类材料 - -> 教师确认导入结果 - -> 批量解析和评分 - -> 查看模型评分和证据 - -> 修改分数和评语 - -> 导出 Excel 成绩表和逐生 PDF 反馈 -``` - -### 2.2 学生目录结构 - -宿主机数据目录示例: - -```text -WiseGradeData/ -└── 2026春季第1批/ - ├── 1023009006_李傲琦_基于ROS2系统的自瞄移动机器人/ - │ ├── 阶段报告1.pdf - │ ├── 阶段报告2.pdf - │ ├── 阶段报告3.pdf - │ ├── 自动化专业综合实践报告.pdf - │ └── 汇报PPT.pptx - └── 其他学生/ -``` - -学生目录命名格式: - -```text -学号_姓名_选题题目 -``` - -文件夹名称只用于初步识别。系统还要从文件首页、标题和正文中抽取姓名、学号、项目题目和选题方向,并在不一致时提醒教师确认。 - -### 2.3 支持文件 - -支持: - -- PDF -- DOCX -- PPTX -- PPT 导出的 PDF - -不支持旧版 `.doc` 作为学生输入。 - -PPT PDF 必须在导入确认阶段标记为“汇报材料”,以免与最终报告 PDF 混淆。 - -### 2.4 成绩结构 - -总评成绩: - -```text -总评 = 阶段报告1 × 10% - + 阶段报告2 × 10% - + 阶段报告3 × 10% - + 期末成绩 × 70% -``` - -期末评分保持课程评分表结构: - -| 评分项 | 分值 | -|---|---:| -| 任务完成度 | 20 | -| 报告规范性 | 20 | -| 汇报答辩(系统仅按 PPT 内容评价) | 40 | -| 结果分析 | 20 | - -### 2.5 评分批次 - -每次评分创建独立批次。批次之间不覆盖、不替代,也不设置唯一“正式批次”。每个批次均可查看、复核和导出。 - -批次必须保存: - -- 课程版本 -- 评分规则版本 -- 课程目标版本 -- `deepseek-flash` 模型配置快照 -- 嵌入模型名称和版本 -- 创建时间和结束时间 -- 评分任务状态 - -## 3. 课程和评分依据 - -初始资料位于 `docs/`: - -- `课程导学-自动化专业综合实践.pdf` -- `自动化专业综合实践三融合选题课程概述.pdf` -- `大作业评分表-自动化专业综合实践.docx` -- `阶段报告1模板.doc` -- `阶段报告2模板.doc` -- `阶段报告3模板.doc` -- `阶段报告1.pdf` -- `阶段报告2.pdf` -- `阶段报告3.pdf` -- `自动化专业综合实践报告.pdf` - -### 3.1 课程目标和毕业要求指标点 - -系统初始知识库必须包含并建立关联: - -- 课程目标 1:问题解决与研究能力 -- 课程目标 2:知识运用与分析能力 -- 课程目标 3:实验设计与操作能力 -- 课程目标 4:数据处理与报告撰写能力 -- 毕业要求指标点 2.3、2.4 -- 毕业要求指标点 4.1、4.2、4.3、4.4 -- 毕业要求指标点 11.1、11.2 - -### 3.2 阶段报告要求 - -#### 阶段报告 1:复杂自动化工程问题解决方案论证报告 - -重点内容: - -- 文献调研和技术现状 -- 复杂工程问题分析 -- 主方案和至少一套替代方案 -- 方案原理、适用场景和优劣对比 -- 数理或工程依据下的可行性论证 -- 进度计划、资源配置、成本构成和经济性分析 - -初始评分框架: - -| 评分项 | 分值 | -|---|---:| -| 复杂工程问题和需求分析 | 25 | -| 文献调研和技术现状总结 | 20 | -| 主方案和替代方案设计 | 25 | -| 可行性、风险和合理性论证 | 15 | -| 工程管理、进度和成本分析 | 10 | -| 报告完整性和规范性 | 5 | -| 合计 | 100 | - -#### 阶段报告 2:实验系统设计与硬件搭建方案 - -重点内容: - -- 硬件选型清单、参数和依据 -- 系统架构图、硬件连接或接口关系 -- 分步骤实验计划、测试方法和预期指标 -- 安全风险、防护措施和操作规范 - -初始评分框架: - -| 评分项 | 分值 | -|---|---:| -| 系统架构和实现思路 | 20 | -| 硬件选型及选型依据 | 20 | -| 系统框图、连接关系和接口设计 | 20 | -| 实验方案、测试方法和预期指标 | 20 | -| 安全风险和防护措施 | 10 | -| 阶段进展及下一阶段计划 | 10 | -| 合计 | 100 | - -#### 阶段报告 3:软件设计与系统调试报告 - -重点内容: - -- 软件逻辑、流程图或状态图 -- 核心代码片段和实现说明 -- 调试过程、故障现象、原因和解决方法 -- 实验数据整理和初步分析 -- 系统功能、性能指标和存在问题 - -初始评分框架: - -| 评分项 | 分值 | -|---|---:| -| 软件逻辑和系统实现 | 20 | -| 核心代码和功能说明 | 20 | -| 调试过程、问题分析和解决方法 | 20 | -| 实验数据和初步分析 | 20 | -| 功能和性能指标验证 | 15 | -| 下一阶段计划及报告规范性 | 5 | -| 合计 | 100 | - -阶段评分框架必须作为可编辑的初始规则导入,不能写死在业务代码中。 - -## 4. 总体架构 - -```text -React 前端 - | -FastAPI 后端 - |-- 课程、版本和规则管理 - |-- 挂载目录扫描和导入 - |-- 文档解析和事实抽取 - |-- RAG 检索 - |-- 评分编排和批次管理 - |-- 教师复核 - |-- Excel/PDF 导出 - | -PostgreSQL + pgvector -Redis + RQ -本地文件存储 -本地 BGE-M3 嵌入模型 -DeepSeek API(deepseek-flash) -``` - -采用模块化单体后端,不在第一版拆分成大量微服务。模块边界清晰,后续可以拆分。 - -### 4.1 推荐技术栈 - -- 前端:React、TypeScript、Vite、Ant Design -- 后端:Python、FastAPI、SQLAlchemy、Pydantic -- 数据库:PostgreSQL、pgvector -- 后台任务:Redis、RQ -- PDF 解析:PyMuPDF -- DOCX 解析:python-docx -- PPTX 解析:python-pptx -- 页面转换:LibreOffice headless -- OCR:PaddleOCR,扫描 PDF 时作为回退 -- 本地嵌入:`BAAI/bge-m3` -- 模型调用:OpenAI 兼容客户端,统一模型名 `deepseek-flash` -- Excel:openpyxl 或 pandas -- PDF 反馈:HTML/CSS + WeasyPrint 或 Playwright -- 部署:Docker Compose - -## 5. 宿主机目录挂载方案 - -原始学生材料不通过浏览器上传。前端只选择后端可见的挂载目录下的大文件夹,后端扫描和读取文件。 - -### 5.1 Docker 挂载 - -```yaml -volumes: - - ${WISEGRADE_DATA_DIR}:/data/inbox:ro - - ./data/processed:/data/processed - - ./data/exports:/data/exports - - ./models:/models:ro -``` - -Linux 示例: - -```env -WISEGRADE_DATA_DIR=/home/teacher/WiseGradeData -``` - -Windows 示例: - -```env -WISEGRADE_DATA_DIR=D:/WiseGradeData -``` - -Windows 使用 Docker Desktop 时,教师需要允许 Docker Desktop 访问对应磁盘。 - -### 5.2 路径安全 - -- 后端只允许访问 `/data/inbox` -- 前端只提交挂载目录内的相对路径 -- 禁止提交绝对路径 -- 后端必须执行路径规范化和越界检查 -- 原始输入目录只读挂载 -- 解析结果、任务状态和导出文件写入独立目录 - -### 5.3 文件变更检测 - -导入时保存: - -- 相对路径 -- 文件大小 -- 修改时间 -- SHA-256 -- MIME 类型 -- 解析状态 - -若文件哈希未变化,不重复解析和向量化。源文件变化时提示重新导入。 - -## 6. 文档解析和结构化 - -### 6.1 统一文档对象 - -每个文档解析为: - -```json -{ - "document_type": "stage1", - "source_path": "...", - "pages": [ - { - "page_number": 1, - "text": "...", - "tables": [], - "images": [], - "rendered_image_path": "..." - } - ] -} -``` - -必须保留页码、章节名、表格和图片关联。 - -### 6.2 文件识别 - -支持通过以下信号识别材料类型: - -- 文件名关键词 -- 文件扩展名 -- 文档标题 -- 首页文本 -- 章节标题 -- PPT 页数和标题 - -识别结果包括: - -```text -确定 -不确定 -缺失 -重复 -无法解析 -``` - -不确定的文件进入教师确认界面。 - -### 6.3 PPT/PDF 视觉处理 - -- 提取 PPT 原生文字、表格和备注 -- 将每一页渲染为图片 -- PDF 每页保存页面图像 -- 评分相关页面连同文字一起发送给 `deepseek-flash` -- 图片证据必须关联页码或幻灯片编号 - -## 7. RAG 方案 - -### 7.1 知识库分层 - -#### 公共课程知识库 - -- 课程导学 -- 课程目标 -- 毕业要求指标点 -- 评分表 -- 三个阶段模板 -- 各选题方向要求 -- 优秀报告 -- 课程版本资料 - -#### 学生项目知识库 - -每个学生独立命名空间: - -```text -course_2026/project_1023009006/ - stage1/ - stage2/ - stage3/ - final_report/ - presentation/ -``` - -禁止评分时检索其他学生的材料。 - -### 7.2 文本切分 - -- 按标题和章节进行结构感知切分 -- 普通文本块约 400~800 个中文字符 -- 重叠约 80~120 个中文字符 -- 表格单独保存 -- 图片及图片说明单独保存 -- 每块必须保留页码、章节、文档类型和评分指标关联 - -### 7.3 检索 - -采用混合检索: - -```text -PostgreSQL 全文检索 -+ pgvector 向量检索 -+ 课程版本过滤 -+ 学生项目过滤 -+ 报告类型过滤 -+ 阶段过滤 -``` - -默认每个评分项取 8~12 个候选证据块,去重后送入模型。 - -### 7.4 嵌入模型 - -默认: - -```text -BAAI/bge-m3 -``` - -低配置电脑可配置: - -```text -BAAI/bge-small-zh-v1.5 -``` - -模型通过独立离线包提供,不在应用镜像中强制在线下载。配置中保存模型名称、版本和本地路径。 - -## 8. DeepSeek 接入 - -### 8.1 统一模型 - -只使用一个模型配置: - -```yaml -provider: deepseek -base_url: https://api.deepseek.com -model: deepseek-flash -``` - -同一个模型负责: - -- 文本理解 -- 图像理解 -- 事实抽取 -- 评分 -- 评语生成 -- PPT 分析 -- 跨文档一致性检查 - -### 8.2 密钥管理 - -教师可以在设置页面配置: - -- API Key -- Base URL -- 模型名 -- 并发数 -- 超时时间 -- 重试次数 - -安全要求: - -- 前端不直接调用 DeepSeek -- API Key 只发送给后端 -- 数据库保存加密后的密钥 -- 日志禁止输出 API Key -- 支持环境变量初始化 - -### 8.3 发送数据范围 - -原始文件保存在本地。模型请求只发送当前评分项所需的: - -- 文本证据块 -- 表格内容 -- 必要的页面图片 -- 课程评分标准 -- 已抽取的项目事实 - -不把全部报告无条件重复发送给每一个评分项。 - -## 9. 评分引擎 - -评分采用多阶段流程: - -```text -文件导入 - -> 文档解析 - -> 项目事实抽取 - -> 规则检查 - -> 指标级 RAG 检索 - -> 指标级评分 - -> 跨文档一致性检查 - -> 分数汇总 - -> 教师复核 -``` - -### 9.1 事实抽取 - -抽取: - -- 学号、姓名、项目名称 -- 选题方向 -- 功能目标 -- 性能指标 -- 硬件型号 -- 软件技术 -- 实验方案 -- 实验数据 -- 进度计划 -- 成本信息 -- 结论和改进方向 - -### 9.2 评分输出 - -每个评分项必须返回结构化 JSON: - -```json -{ - "criterion_id": "stage1.solution_design", - "score": 17, - "max_score": 20, - "reason": "...", - "evidence": [ - { - "document": "阶段报告1", - "page": 12, - "quote": "..." - } - ], - "missing_evidence": ["..."], - "suggestion": "...", - "confidence": 0.84 -} -``` - -模型不得对没有证据的内容自行假设。结构化输出必须经过 Pydantic 校验;失败时自动重试或进入人工处理。 - -### 9.3 跨文档一致性 - -至少检查: - -- 阶段 1 计划是否在阶段 2、3 中落实 -- 各报告中的项目名称、硬件型号和技术路线是否一致 -- 实验数据是否前后一致 -- 最终报告和 PPT 是否描述同一成果 -- 指标是否存在明显夸大或矛盾 - -## 10. 规则配置和版本管理 - -规则不能写死在 Prompt 或 Python 代码中。 - -### 10.1 评分指标结构 - -```yaml -criterion_id: stage1.solution_feasibility -name: 方案合理性与可行性 -max_score: 15 -description: 评价方案是否具有工程依据、可实施性和风险分析 -linked_outcomes: [2.3, 2.4, 4.1] -required_evidence: - - 主方案 - - 替代方案 - - 方案比较 - - 风险分析 -score_levels: - - min: 12 - max: 15 - description: 论证充分,方案比较清晰,风险分析具体 - - min: 6 - max: 11 - description: 基本完成论证,但证据或分析不充分 - - min: 0 - max: 5 - description: 缺少核心论证 -``` - -### 10.2 版本要求 - -课程、课程目标、毕业要求、模板、评分规则和 Prompt 都需要版本号。评分批次保存完整版本快照。 - -教师修改规则后创建新版本,不覆盖历史版本。 - -## 11. 核心数据表 - -建议至少包含: - -```text -courses -course_versions -course_objectives -graduation_indicators -topic_directions -rubric_versions -rubric_criteria -rubric_score_levels -knowledge_documents -knowledge_chunks -students -projects -submissions -submission_files -scoring_batches -criterion_scores -score_evidences -teacher_revisions -export_tasks -app_settings -audit_logs -``` - -### 11.1 评分批次 - -```text -scoring_batches - id - course_version_id - rubric_version_id - model_name - model_config_snapshot - embedding_model_name - embedding_model_version - status - created_at - finished_at -``` - -### 11.2 评分项结果 - -```text -criterion_scores - id - batch_id - project_id - criterion_id - model_score - teacher_score - final_score - model_comment - teacher_comment - confidence - status -``` - -```text -final_score = teacher_score(存在时)或 model_score -``` - -模型原始结果不得被教师修改覆盖。 - -## 12. 前端页面 - -第一版页面建议: - -1. 仪表盘 -2. 课程管理 -3. 课程版本和评分规则管理 -4. 课程资料/知识库管理 -5. 数据目录扫描与导入确认 -6. 学生项目列表 -7. 评分批次列表 -8. 批量评分进度 -9. 学生评分详情 -10. 证据和页码查看 -11. 教师复核 -12. Excel/PDF 导出 -13. 模型和系统设置 - -## 13. 后端 API 初稿 - -### 课程和规则 - -```text -GET /api/courses -POST /api/courses -GET /api/courses/{id}/versions -POST /api/courses/{id}/versions -GET /api/rubrics/{version_id} -PUT /api/rubrics/{version_id} -POST /api/rubrics/{version_id}/publish -``` - -### 文件扫描和项目导入 - -```text -GET /api/storage/directories -GET /api/storage/directories/{relative_path}/children -POST /api/import/scan -POST /api/import/confirm -GET /api/projects -GET /api/projects/{id} -``` - -### 评分 - -```text -POST /api/scoring-batches -GET /api/scoring-batches -GET /api/scoring-batches/{id}/progress -POST /api/scoring-batches/{id}/start -GET /api/scoring-batches/{id}/scores -GET /api/projects/{id}/scores?batch_id={batch_id} -PUT /api/criterion-scores/{id}/review -``` - -### 导出 - -```text -POST /api/exports/excel -POST /api/exports/project-pdf -GET /api/exports/{id} -``` - -## 14. 缺失和异常处理 - -材料状态: - -```text -已提交 -缺失 -重复 -无法解析 -内容不完整 -待人工确认 -``` - -处理原则: - -- 缺失阶段报告:该阶段进入待人工处理,不默认静默给零分 -- 缺失 PPT:汇报材料项显示无法评分 -- 缺少章节:按照对应评分项判断并扣分 -- 文件损坏:进入人工确认列表 -- DeepSeek 调用失败:自动有限重试,仍失败则标记评分项失败 -- 评分批次允许部分完成,但导出时必须显示未完成项目 - -## 15. 模型离线分发 - -`bge-m3` 不依赖启动时在线下载。推荐单独提供模型包: - -```text -WiseGrade-release/ -├── docker-images.tar -├── models-bge-m3.tar.zst -├── docker-compose.yml -├── .env.example -└── README.md -``` - -也支持将模型目录放在: - -```text -./models/bge-m3/ -``` - -容器只读挂载: - -```yaml -volumes: - - ./models:/models:ro -``` - -在线下载脚本是可选工具,不得成为系统正常启动的前置条件。 - -## 16. 测试要求 - -### 16.1 单元测试 - -- 目录扫描 -- 学号/姓名/题目解析 -- 文件类型识别 -- 路径越界防护 -- 文件哈希检测 -- 规则权重计算 -- 缺失材料处理 -- 分数汇总 -- 评分 JSON 校验 -- 版本绑定 - -### 16.2 集成测试 - -- 从示例材料导入到项目生成 -- PDF/DOCX/PPTX 解析 -- PPT PDF 识别 -- 知识库入库和检索 -- 模型 API mock 调用 -- 评分批次创建、运行和查询 -- 教师修改分数 -- Excel 导出 -- PDF 反馈导出 - -### 16.3 验收测试 - -至少使用当前 `docs/` 中的示例材料完成一次完整流程: - -```text -扫描目录 - -> 导入学生项目 - -> 解析五类材料 - -> 创建评分批次 - -> mock 或真实调用 deepseek-flash - -> 查看逐项证据 - -> 修改分数 - -> 导出 Excel - -> 导出学生 PDF 反馈 -``` - -不应在测试中提交真实 API Key。使用环境变量或 mock 服务。 - -## 17. Git 开发要求 - -开发前初始化 Git: - -```bash -git init -``` - -必须创建合理的 `.gitignore`,至少忽略: - -```text -.env -data/processed/ -data/exports/ -models/ -__pycache__/ -.pytest_cache/ -node_modules/ -dist/ -*.pyc -``` - -开发和测试过程中按阶段提交,推荐提交节点: - -```text -chore: initialize project structure -feat: add backend foundation -feat: add course and rubric versioning -feat: add mounted directory scanning -feat: add document parsing pipeline -feat: add knowledge base and hybrid retrieval -feat: add deepseek-flash adapter -feat: add scoring batch orchestration -feat: add teacher review workflow -feat: add excel and pdf exports -test: add integration coverage -docs: add deployment and usage guides -``` - -每个提交应保持可理解、可回退、尽量可运行。禁止把 API Key、真实学生隐私数据和模型权重提交到 Git。 - -## 18. 开发优先级 - -### P0:可运行骨架 - -- Git、README、Docker Compose -- 前端和后端健康检查 -- 数据库迁移 -- 单管理员设置 - -### P1:课程和导入 - -- 课程版本和规则配置 -- 挂载目录扫描 -- 学生目录识别 -- 文件识别和导入确认 - -### P2:解析和知识库 - -- PDF/DOCX/PPTX 解析 -- 页面渲染 -- OCR 回退 -- BGE-M3 嵌入 -- pgvector 混合检索 - -### P3:评分 - -- 事实抽取 -- 指标级 RAG 评分 -- 跨文档一致性检查 -- 批次状态和失败重试 - -### P4:复核和导出 - -- 教师修改分数和评语 -- Excel 成绩表 -- 逐生 PDF 反馈 -- 审计日志 - -### P5:验收和部署 - -- 示例材料完整验收 -- Linux 部署文档 -- Windows Docker Desktop 部署文档 -- 离线模型包说明 - -## 19. 完成标准 - -当以下条件全部满足时,第一版系统完成: - -- Linux 上可以通过 Docker Compose 启动 -- Windows Docker Desktop 有明确部署步骤 -- 教师可以选择挂载目录下的大文件夹 -- 系统可以识别每个学生目录 -- 支持五类材料和 PPT PDF -- 规则、课程目标和课程版本可编辑 -- 可创建独立评分批次 -- 使用本地嵌入模型完成检索 -- 使用 `deepseek-flash` 完成文本和图像评分 -- 每项评分显示证据和页码/幻灯片编号 -- 教师可以修改分数和评语 -- 每个批次都可以导出 Excel 和逐生 PDF -- 示例材料可以完成端到端测试 -- Git 历史包含清晰的阶段提交 diff --git a/docs/CODEX_CHAT_AGENT_GOAL_PROMPT.md b/docs/prompts/CODEX_CHAT_AGENT_GOAL_PROMPT.md similarity index 88% rename from docs/CODEX_CHAT_AGENT_GOAL_PROMPT.md rename to docs/prompts/CODEX_CHAT_AGENT_GOAL_PROMPT.md index b54a371..4abc416 100644 --- a/docs/CODEX_CHAT_AGENT_GOAL_PROMPT.md +++ b/docs/prompts/CODEX_CHAT_AGENT_GOAL_PROMPT.md @@ -7,7 +7,7 @@ ## 先了解现状 -先检查工作区状态并阅读 README.md、HANDOFF.md、docs/WISEGRADE_TECHNICAL_SPEC.md、docs/DEPLOYMENT.md。核对当前代码,尤其是 frontend/src/App.tsx、frontend/src/api.ts、backend/wisegrade/api.py、models.py、storage.py、parsing.py、rag.py、llm.py、scoring.py、exports.py、settings_store.py、migrations/ 和 backend/tests/。以当前代码和本提示词确定本次增量工作;旧版 docs/CODEX_GOAL_PROMPT.md 中“从零创建系统”的步骤不适用于本次任务。保留工作区已有用户修改,不泄露或提交 .env、API Key、模型权重、运行数据及学生原件。 +先检查工作区状态并阅读 README.md、HANDOFF.md、docs/GUIDE.md。核对当前代码,尤其是 frontend/src/App.tsx、frontend/src/api.ts、backend/wisegrade/api.py、models.py、storage.py、parsing.py、rag.py、llm.py、scoring.py、exports.py、settings_store.py、migrations/ 和 backend/tests/。以当前代码和本提示词确定本次增量工作;旧版 docs/prompts/CODEX_GOAL_PROMPT.md 中“从零创建系统”的步骤不适用于本次任务。保留工作区已有用户修改,不泄露或提交 .env、API Key、模型权重、运行数据及学生原件。 现有系统是单机单教师应用:React/TypeScript/Vite/Ant Design 前端,FastAPI/SQLAlchemy 后端,PostgreSQL + pgvector,Redis + RQ;原始学生材料只从只读挂载目录 /data/inbox 读取。现有课程版本、规则、扫描导入、解析、知识库、评分批次、教师复核和导出功能必须继续可用。当前 DeepSeekClient 主要支持结构化 JSON 评分调用,尚无对话工具编排;RAG 检索主要服务评分;学生材料通常在评分时解析和建索引。 @@ -39,13 +39,13 @@ 前端应支持从对话引用跳到原有课程、项目、评分和导出详情,并保持必要的上下文。导入预览应显示学号、姓名、选题、材料类型、缺失、重复、识别异常和文件选择;这些可由教师在确认前修正,不得由模型静默代选有歧义的文件。批次部分完成或导出包含待处理项目时,确认卡片应明确提示。 -更新 README.md、docs/DEPLOYMENT.md、docs/WISEGRADE_TECHNICAL_SPEC.md 或新增专门设计文档,说明对话操作、确认规则、索引任务、模型配置及异常处理;同步更新 HANDOFF.md 中与本次实现相关的状态,但不要编造未实际验证的结果。现有教师单机、只读挂载目录、课程和评分版本化、证据可追溯及导出规则不能退化。 +更新 README.md、docs/GUIDE.md 或新增专门设计文档,说明对话操作、确认规则、索引任务、模型配置及异常处理;同步更新 HANDOFF.md 中与本次实现相关的状态,但不要编造未实际验证的结果。现有教师单机、只读挂载目录、课程和评分版本化、证据可追溯及导出规则不能退化。 ## 验收与验证 新增有意义的后端测试,使用模拟模型工具调用和独立测试数据库验证:工具参数校验与作用域隔离、课程及批次快照规则、跨学生检索隔离和引用、扫描预览与文件哈希变化、确认前无副作用及重复确认幂等、导入后自动索引、批次项目清单固定与重复入队防护、明确分数的教师复核与修改历史、部分完成批次总结不补零、失败和断线后的恢复。验证原有 API 和评分流程无回归;前端至少完成 TypeScript 和生产构建,并检查主页面、会话恢复、确认卡片和跳转。 -优先运行不依赖真实 API Key 的自动测试;若当前环境具备有效配置,可另外做一次最小真实 DeepSeek tool_calls 冒烟验证,不输出密钥或学生原件。按 docs/DEPLOYMENT.md 的 uv/pytest、npm 构建及 Docker Compose 路径执行适用验证。若环境限制导致某项无法运行,明确记录具体命令、原因和剩余风险;不要把未执行验证写成通过。 +优先运行不依赖真实 API Key 的自动测试;若当前环境具备有效配置,可另外做一次最小真实 DeepSeek tool_calls 冒烟验证,不输出密钥或学生原件。按 docs/GUIDE.md 的 uv/pytest、npm 构建及 Docker Compose 路径执行适用验证。若环境限制导致某项无法运行,明确记录具体命令、原因和剩余风险;不要把未执行验证写成通过。 按可验证的阶段持续完成工作:共享业务服务与数据迁移 → 自动索引和可引用检索 → Agent 工具编排与持久会话 → 对话页面和确认流程 → 回归测试及文档。每阶段发现与现有代码不符的细节时,以本提示词的用户确认边界为准做合理实现调整。不要因普通实现选择停下询问;只有确实无法从代码和本提示词解决的业务矛盾才提出问题。完成后给出改动、验证结果和实际限制;遵循仓库现有 Conventional Commits 惯例提交可回退的阶段性修改,不提交秘密或运行数据。 ``` diff --git a/docs/prompts/CODEX_EVIDENCE_RAG_GOAL_PROMPT.md b/docs/prompts/CODEX_EVIDENCE_RAG_GOAL_PROMPT.md new file mode 100644 index 0000000..6082711 --- /dev/null +++ b/docs/prompts/CODEX_EVIDENCE_RAG_GOAL_PROMPT.md @@ -0,0 +1,75 @@ +# WiseGrade 目录、摘要与正文证据治理:Codex Goal 模式提示词 + +将下方提示词完整复制到 Codex Goal 模式,在本仓库执行。本提示词授权新任务修改仓库源码和隔离测试环境;不授权改写当前业务数据库、批次 3 或会话 6。 + +~~~text +你是 WiseGrade(智评)项目的开发代理。请在 /home/sky/files/Agent/WiseGrade 完整实现“区分报告目录、摘要与正文的证据检索和评分”功能,完成迁移、测试、界面衔接及文档更新。持续推进到下列验收条件全部满足,不要只提交设计方案。 + +## 先了解现状 + +先检查工作区状态,阅读: +- /home/sky/files/Agent/WiseGrade/README.md +- /home/sky/files/Agent/WiseGrade/HANDOFF.md +- /home/sky/files/Agent/WiseGrade/docs/GUIDE.md + +重点检查 backend/wisegrade 下的 parsing.py、rag.py、models.py、scoring.py、llm.py、indexing.py、services.py、agent_tools.py、chat_api.py、exports.py、actions.py,以及 frontend/src/App.tsx、frontend/src/Chat.tsx、数据库迁移和相关测试。以当前代码为准,保留工作区已有修改。 + +当前问题已通过只读检查确认:批次 3 的 77 条评分引文中有 14 条来自目录页,涉及 9 个评分项;会话 6 保存的 20 条引用中有 5 条指向阶段报告 1 的目录页。目录既被当作正文证据,也挤占候选位置,使实际存在的正文难以检索到。上述数字是诊断基线,不是要求修改这些历史记录。 + +## 已确定的业务规则 + +1. 目录可以证明章节和报告结构,也可以帮助定位正文;不能证明章节的具体内容、完成质量、测试结果或分析。 +2. 摘要可以用于“摘要称……”这类明确归属的概述,不能单独证明方法已实现、实验已完成或指标已达标。 +3. 内容性评分必须使用正文中的实质段落、数据、表格或适用的附录。正文页上的单独章节标题也不能充当内容证据。 +4. 经过针对性正文补检后,若内容性评分目标仍只有目录或摘要命中,该评分项进入“待教师复核”:模型分为 null,总分保持待处理;不得自动给低分或断言“学生未写”。 +5. 教师已录入的复核分、评语和修改历史必须保留。不要自动改写批次 3 的既有分数或会话 6 的历史消息。 + +## 页面标注 + +以文档实际页码或 PPT 幻灯片编号为主要标注单位,至少区分 cover、abstract、toc、body、references、unknown。普通知识片段继承所在页面类型。允许 mixed 页面:当目录和正文确实共处一页时,仅对该页按文本块进一步区分,不把整页正文排除。 + +识别目录时结合页首标题、章节条目密度、点线与末尾页码,并识别跨页续目录;摘要、参考文献也要识别连续页面。不能只凭“目录”一词或固定页号判定。清理重复页眉页脚,保留判定依据和识别版本。对有疑义的页面标为 unknown,不强行认作正文。 + +设计统一的页面级持久化结构,让学生材料和公共课程资料都能查询页面类型;知识片段关联其来源页。另行提取真正的正文章节路径,不要直接把当前“页面第一行”字段当成章节。 + +## 证据政策与检索 + +把“必备证据的用途”纳入可版本化的评分规则,并随批次保存快照;对既有字符串形式的 required_evidence 做兼容处理。结构目标允许封面、目录或参考文献等对应页面;内容目标只允许正文及有实质内容的附录。不要只在 Prompt 中写规则,也不要仅按评分项 ID 临时硬编码。 + +每个必备证据目标分别检索。先限定课程版本、学生项目、材料类别和允许的页面类型,再取候选;页面过滤必须发生在候选数量限制之前。扩大初始候选池,让语义匹配和关键词匹配分别有召回机会,再合并去重。评估现有 PostgreSQL simple 全文检索对中文材料的表现,采用适合当前语料的关键词召回方式。融合排序时避免直接相加未经归一化的语义分与关键词分,可采用基于排名的融合,并用回归样本调整参数。 + +第一轮优先分散到不同页面;有可靠章节路径后,再对同一章节设置软上限。名额不足时可回填同页或同节的其他正文片段,但不能放宽证据类型。评分最终给模型的片段数量保持受控,Agent 搜索也保持受控。宽泛的跨报告问题适度覆盖不同文档;明确指定某一报告时不要强制跨文档。 + +若某个内容目标未找到正文,利用目录标题匹配实际正文标题,补检该章节及相邻正文页。目录只作导航,最终内容引文必须落在实际正文页。评分发送给模型的页面图像也应优先选择相关的不同正文页,而非目录页。 + +## 评分与 Agent 出口 + +扩展评分输出及校验,使每条引文关联它要支持的评分目标。除现有原文与页码校验外,还须校验证据来源类型是否获准;内容性判断不能仅由目录、摘要或单独标题支撑。LLM 负责理解证据、判断评分要求和提出补检目标;页面权限及状态转换由代码执行,LLM 不能绕过。 + +新增清晰的“待教师复核”评分状态,与材料缺失、解析失败和模型调用失败区分。补检仍不足时记录缺少的正文证据目标和检索范围,模型分保持 null。同步更新批次完成状态、仪表盘待处理数、API 与 Agent 状态筛选、评分详情、导出及教师复核流程。待复核项的教师评分输入框不能预填 0;教师复核后应能正常形成最终分,同时保留原始检索问题记录。 + +项目事实抽取也要遵循来源类型,避免从目录标题推断实现结果。 + +Agent 的内容搜索和结构/目录查询使用相同的证据政策;可调整现有工具参数或增加清晰区分的只读工具,但保持原有项目范围隔离。工具返回页面类型和稳定的引用标识。最终回答仅附上实际使用、能对应回答判断的引用,而不是汇总所有工具命中。旧批次评分证据若来自目录,展示为“历史评分引用”,不能自动当作报告正文证据。 + +## 迁移与历史数据 + +增加必要的 Alembic 迁移和索引版本升级。优先利用已保存的学生材料解析页面重新分类和建索引;公共课程资料按现有入库路径处理。旧版索引在完成升级前不得被默默当作已分类正文使用。迁移和重建过程应可重试、可审计,保留原始文件、评分批次、教师复核及会话历史。 + +本任务只可在隔离测试数据库和测试材料上执行迁移、重建索引及评分验证。不要对当前业务数据库运行迁移、重建索引、重新评分或修改批次 3/会话 6。提供业务环境应用步骤和批次 3 的复核清单,但不执行这些业务数据操作。 + +## 有意义的回归验证 + +使用现有报告的已知页面及必要的合成混合页作为回归样本,至少覆盖: + +1. 阶段报告 1 的目录页与第 6–7 页文献调研正文正确区分;stage1.literature 能召回正文分析。 +2. 阶段报告 3 的目录页与第 11–12 页测试正文正确区分;stage3.data 能召回测试描述。不要把“找到了这些页”直接等同于“应得某个分数”。 +3. 最终报告的摘要页、跨页目录和正文正确区分;目录仍可支持章节完整性评分。 +4. 混合页、目录续页、重复页眉和识别不确定页面不会被静默当作普通正文。 +5. 内容性评分不得引用目录、摘要或单独标题;结构性评分仍能合理使用目录。 +6. 正文补检仍不足时,模型分为 null、状态为待教师复核、总分待处理;教师能够正常复核,界面不预填 0。 +7. Agent 最终引用只包含回答实际使用且通过校验的来源;历史评分引文不会被误用作正文证据。 +8. 学生项目隔离、课程版本隔离、已有评分与导出功能保持可用。 + +优先运行针对性后端测试、隔离 PostgreSQL 集成测试、前端类型检查和生产构建。需要真实模型才能验证的部分单独说明,不要把未运行的验证写成通过。更新必要的项目文档,最后报告修改内容、实际测试结果、批次 3 建议复核的项目,以及尚待业务环境执行的步骤。 +~~~ diff --git a/docs/CODEX_GOAL_PROMPT.md b/docs/prompts/CODEX_GOAL_PROMPT.md similarity index 98% rename from docs/CODEX_GOAL_PROMPT.md rename to docs/prompts/CODEX_GOAL_PROMPT.md index 705e625..b06abdd 100644 --- a/docs/CODEX_GOAL_PROMPT.md +++ b/docs/prompts/CODEX_GOAL_PROMPT.md @@ -7,7 +7,7 @@ ## 最高优先级要求 -1. 先完整阅读 `docs/WISEGRADE_TECHNICAL_SPEC.md`,它是本项目的技术规格和业务约束。 +1. 先完整阅读 `docs/GUIDE.md`,它是本项目的技术规格和业务约束。 2. 当前项目英文名为 WiseGrade,中文名为智评。 3. 当前只实现“自动化专业综合实践”,但课程、课程版本、课程目标、毕业要求指标点、评分规则、选题方向和 Prompt 必须可配置、可版本化,未来可以扩展其他课程。 4. 系统只供教师使用,采用单机单管理员模式,不实现学生账号。 @@ -41,7 +41,7 @@ ### 第一步:检查和初始化 - 检查当前目录、现有文件和 `docs/` 资料。 -- 阅读 `docs/WISEGRADE_TECHNICAL_SPEC.md`。 +- 阅读 `docs/GUIDE.md`。 - 如果没有 Git,执行 `git init`。 - 创建合理的 `.gitignore`,不得忽略课程资料和源代码,但必须忽略 `.env`、模型目录、运行数据、缓存、构建产物和真实学生材料。 - 创建 `README.md`,说明项目名称、启动方式、配置方法和开发状态。 diff --git a/docs/CODEX_SESSION_UI_GOAL_PROMPT.md b/docs/prompts/CODEX_SESSION_UI_GOAL_PROMPT.md similarity index 88% rename from docs/CODEX_SESSION_UI_GOAL_PROMPT.md rename to docs/prompts/CODEX_SESSION_UI_GOAL_PROMPT.md index 9c36ba4..334dbe8 100644 --- a/docs/CODEX_SESSION_UI_GOAL_PROMPT.md +++ b/docs/prompts/CODEX_SESSION_UI_GOAL_PROMPT.md @@ -5,7 +5,7 @@ ```text 你是 WiseGrade 项目的开发代理。请直接在当前仓库完成“对话”界面的增量更新,包含必要的前后端、数据库迁移、测试和文档修改,直到下面的验收条件全部满足。不要只给出方案或界面样例。 -先检查 git 工作区状态,阅读 README.md、HANDOFF.md、docs/CHAT_AGENT.md,并查看 frontend/src/App.tsx、Chat.tsx、style.css、api.ts,backend/wisegrade/chat_api.py、actions.py、models.py,相关 Alembic 迁移及 backend/tests/test_chat_agent.py。保留已有用户修改;沿用当前 React/TypeScript/Ant Design、FastAPI/SQLAlchemy、SSE 和业务 Agent 架构。旧的 docs/CODEX_CHAT_AGENT_GOAL_PROMPT.md 是上一阶段的实现提示词,本次以当前代码和以下需求为准。 +先检查 git 工作区状态,阅读 README.md、HANDOFF.md、docs/GUIDE.md,并查看 frontend/src/App.tsx、Chat.tsx、style.css、api.ts,backend/wisegrade/chat_api.py、actions.py、models.py,相关 Alembic 迁移及 backend/tests/test_chat_agent.py。保留已有用户修改;沿用当前 React/TypeScript/Ant Design、FastAPI/SQLAlchemy、SSE 和业务 Agent 架构。旧的 docs/prompts/CODEX_CHAT_AGENT_GOAL_PROMPT.md 是上一阶段的实现提示词,本次以当前代码和以下需求为准。 ## 产品行为 @@ -25,5 +25,5 @@ 补充有意义的后端测试,覆盖首次发送的持久化时机与幂等/并发、范围修改与锁定、关联数据删除、运行中删除、历史会话兼容、工具记录恢复、切换或断开连接后原会话继续运行,以及不同会话并行且事件不串流。前端至少完成 TypeScript 与生产构建,并实际检查新建无弹窗、范围选择、历史切换、删除确认、Markdown、引用、工具折叠、运行时切换会话、多会话同时运行及移动端布局;若具备浏览器测试工具,执行交互验证。按项目现有方式运行适用测试;环境无法验证的项目说明具体原因,不把未运行的测试写成通过。 -同步更新 README.md、docs/CHAT_AGENT.md 和必要的 HANDOFF.md 描述。完成后报告主要改动、实际验证命令及结果、仍有的限制。不要提交 .env、API Key、运行数据或学生原件。除确实无法从代码和本目标推断的业务矛盾外,自主完成实现,不停在普通实现选择上征求确认。 +同步更新 README.md、docs/GUIDE.md 和必要的 HANDOFF.md 描述。完成后报告主要改动、实际验证命令及结果、仍有的限制。不要提交 .env、API Key、运行数据或学生原件。除确实无法从代码和本目标推断的业务矛盾外,自主完成实现,不停在普通实现选择上征求确认。 ``` diff --git a/docs/prompts/README.md b/docs/prompts/README.md new file mode 100644 index 0000000..acb25a6 --- /dev/null +++ b/docs/prompts/README.md @@ -0,0 +1,12 @@ +# 开发提示词 + +本目录集中保存供 Codex 执行的阶段开发任务。请在仓库根目录使用;提示词正文中的文件路径均相对于仓库根目录(明确写出的绝对路径除外)。使用前先阅读 [项目指南](../GUIDE.md) 和 [交接记录](../../HANDOFF.md),核对当前实现及任务范围。 + +| 提示词 | 用途 | +|---|---| +| [初始系统开发](CODEX_GOAL_PROMPT.md) | 从零搭建系统的历史任务,保留作需求参考。 | +| [业务 Agent](CODEX_CHAT_AGENT_GOAL_PROMPT.md) | 会话、业务工具、操作确认与自动索引的阶段任务。 | +| [会话界面](CODEX_SESSION_UI_GOAL_PROMPT.md) | 草稿、范围、历史会话、Markdown、工具记录和后台运行的增量任务。 | +| [目录、摘要与正文证据治理](CODEX_EVIDENCE_RAG_GOAL_PROMPT.md) | 页面分类、检索与评分证据治理任务,包含业务数据库不可改写的明确边界。 | + +提示词记录任务要求,不代表功能已经完成或通过验证。应用运行时的评分 Prompt 由课程版本管理,不在本目录维护。