17 KiB
17 KiB
比赛备赛规划文档
一、赛题核心理解
1.1 赛题名称
A23 - 基于大语言模型的文档理解与多源数据融合 参赛院校:金陵科技学院
1.2 核心任务
- 文档解析:解析 docx/md/xlsx/txt 四种格式的源数据文档
- 模板填写:根据模板表格要求,从源文档中提取数据填写到 Word/Excel 模板
- 准确率与速度:准确率优先,速度作为辅助评分因素
1.3 评分规则
| 要素 | 说明 |
|---|---|
| 准确率 | 填写结果与样例表格对比的正确率 |
| 响应时间 | 从导入文档到得到结果的时间 ≤ 90s × 文档数量 |
| 评测方式 | 赛方提供空表格模板 + 样例表格(人工填写),系统自动填写后对比 |
1.4 关键Q&A摘录
| 问题 | 解答要点 |
|---|---|
| Q2: 模板与文档的关系 | 前2个表格只涉及1份文档;第3-4个涉及多份文档;第5个涉及大部分文档(从易到难) |
| Q5: 响应时间定义 | 从导入文档到最终得到结果的时间 ≤ 90s × 文档数量 |
| Q7: 需要读取哪些文件 | 每个模板只读取指定的数据文件,不需要读取全部 |
| Q10: 部署方式 | 不要求部署到服务器,本地部署即可 |
| Q14: 模板匹配 | 模板已指定数据文件,不需要算法匹配 |
| Q16: 数据库存储 | 可跳过,不强制要求 |
| Q20: 创新点 | 不用管,随意发挥 |
| Q21: 填写依据 | 按照测试表格模板给的提示词进行填写 |
二、已完成功能清单
2.1 后端服务 (backend/app/services/)
| 服务文件 | 功能状态 | 说明 |
|---|---|---|
file_service.py |
✅ 已完成 | 文件上传、保存、类型识别 |
excel_storage_service.py |
✅ 已完成 | Excel 存储到 MySQL,支持 XML 回退解析 |
table_rag_service.py |
⚠️ 已禁用 | RAG 索引构建(当前禁用,仅记录日志) |
llm_service.py |
✅ 已完成 | LLM 调用、流式输出、多模型支持 |
markdown_ai_service.py |
✅ 已完成 | Markdown AI 分析、分章节提取、流式输出、图表生成 |
excel_ai_service.py |
✅ 已完成 | Excel AI 分析 |
visualization_service.py |
✅ 已完成 | 图表生成(matplotlib) |
rag_service.py |
⚠️ 已禁用 | FAISS 向量检索(当前禁用) |
prompt_service.py |
✅ 已完成 | Prompt 模板管理 |
text_analysis_service.py |
✅ 已完成 | 文本分析 |
chart_generator_service.py |
✅ 已完成 | 图表生成服务 |
template_fill_service.py |
✅ 已完成 | 模板填写服务,支持多行提取、直接从结构化数据提取、JSON容错、Word文档表格处理 |
2.2 API 接口 (backend/app/api/endpoints/)
| 接口文件 | 路由 | 功能状态 |
|---|---|---|
upload.py |
/api/v1/upload/document |
✅ 文档上传与解析 |
documents.py |
/api/v1/documents/* |
✅ 文档管理(列表、删除、搜索) |
ai_analyze.py |
/api/v1/analyze/* |
✅ AI 分析(Excel、Markdown、流式) |
rag.py |
/api/v1/rag/* |
⚠️ RAG 检索(当前返回空) |
tasks.py |
/api/v1/tasks/* |
✅ 异步任务状态查询 |
templates.py |
/api/v1/templates/* |
✅ 模板管理(含多行导出、Word导出、Word结构化字段解析) |
visualization.py |
/api/v1/visualization/* |
✅ 可视化图表 |
health.py |
/api/v1/health |
✅ 健康检查 |
2.3 前端页面 (frontend/src/pages/)
| 页面文件 | 功能 | 状态 |
|---|---|---|
Documents.tsx |
主文档管理页面 | ✅ 已完成 |
TemplateFill.tsx |
智能填表页面 | ✅ 已完成 |
ExcelParse.tsx |
Excel 解析页面 | ✅ 已完成 |
2.4 文档解析能力
| 格式 | 解析状态 | 说明 |
|---|---|---|
| Excel (.xlsx/.xls) | ✅ 已完成 | pandas + XML 回退解析,支持多sheet |
| Markdown (.md) | ✅ 已完成 | 正则 + AI 分章节 |
| Word (.docx) | ✅ 已完成 | python-docx 解析,支持表格提取和字段识别 |
| Text (.txt) | ✅ 已完成 | chardet 编码检测,支持文本清洗和结构化提取 |
三、核心功能实现详情
3.1 模板填写模块(✅ 已完成)
核心流程:
上传模板表格(Word/Excel)
↓
解析模板,提取需要填写的字段和提示词
↓
根据源文档ID列表读取源数据(MongoDB或文件)
↓
优先从结构化数据直接提取(Excel rows)
↓
无法直接提取时使用 LLM 从文本中提取
↓
将提取的数据填入原始模板对应位置(保持模板格式)
↓
导出填写完成的表格(Excel/Word)
关键特性:
- 原始模板填充:直接打开原始模板文件,填充数据到原表格/单元格
- 多行数据支持:每个字段可提取多个值,导出时自动扩展行数
- 结构化数据优先:直接从 Excel rows 提取,无需 LLM
- JSON 容错:支持 LLM 返回的损坏/截断 JSON
- Markdown 清理:自动清理 LLM 返回的 markdown 格式
3.2 Word 文档解析(✅ 已完成)
已实现功能:
docx_parser.py- Word 文档解析器- 提取段落文本
- 提取表格内容(支持比赛表格格式:字段名 | 提示词 | 填写值)
parse_tables_for_template()- 解析表格模板,提取字段extract_template_fields_from_docx()- 提取模板字段定义_infer_field_type_from_hint()- 从提示词推断字段类型- API 端点:
/api/v1/templates/parse-word-structure- 上传 Word 文档,提取结构化字段并存入 MongoDB - API 端点:
/api/v1/templates/word-fields/{doc_id}- 获取已存文档的模板字段信息
3.3 Text 文档解析(✅ 已完成)
已实现功能:
txt_parser.py- 文本文件解析器- 编码自动检测 (chardet)
- 文本清洗(去除控制字符、规范化空白)
- 结构化数据提取(邮箱、URL、电话、日期、金额)
四、参赛材料准备
4.1 必交材料
| 材料 | 要求 | 当前状态 | 行动项 |
|---|---|---|---|
| 项目概要介绍 | PPT 格式 | ❌ 待制作 | 制作 PPT |
| 项目简介 PPT | - | ❌ 待制作 | 制作 PPT |
| 项目详细方案 | 文档 | ⚠️ 部分完成 | 完善文档 |
| 项目演示视频 | - | ❌ 待制作 | 录制演示视频 |
| 训练素材说明 | 来源说明 | ⚠️ 已有素材 | 整理素材文档 |
| 关键模块设计文档 | 概要设计 | ⚠️ 已有部分 | 完善文档 |
| 可运行 Demo | 核心代码 | ✅ 已完成 | 打包可运行版本 |
4.2 Demo 提交要求
根据 Q&A:
- 可以只提交核心代码,不需要完整运行环境
- 现场答辩可使用自带笔记本电脑
- 需要提供部署和运行说明(README)
五、测试验证计划
5.1 使用现有测试数据
docs/test/
├── 2023年文化和旅游发展统计公报.md
├── 2024年卫生健康事业发展统计公报.md
├── 第三次全国工业普查主要数据公报.md
5.2 模板填写测试流程
- 准备一个 Word/Excel 模板表格
- 指定源数据文档
- 上传模板和文档
- 执行模板填写
- 检查填写结果准确率
- 记录响应时间
5.3 性能目标
| 指标 | 目标 | 当前状态 |
|---|---|---|
| 信息提取准确率 | ≥80% | 需测试验证 |
| 单次响应时间 | ≤90s × 文档数 | 需测试验证 |
六、工作计划(建议)
第一优先级:端到端测试
- 使用真实测试数据进行准确率测试
- 验证多行数据导出是否正确
- 测试 Word 模板解析是否正常
第二优先级:Demo 打包与文档
- 制作项目演示 PPT
- 录制演示视频
- 完善 README 部署文档
第三优先级:优化
- 优化响应时间
- 完善错误处理
- 增加更多测试用例
七、注意事项
- 创新点:根据 Q&A,不必纠结创新点数量限制
- 数据库:不强制要求数据库存储,可跳过
- 部署:本地部署即可,不需要公网服务器
- 评测数据:初赛仅使用目前提供的数据
- RAG 功能:当前已临时禁用,不影响核心评测功能(因为使用直接文件读取)
文档版本: v1.5 最后更新: 2026-04-09
八、技术实现细节
8.1 模板填表流程
流程图
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 上传模板 │ ──► │ 选择数据源 │ ──► │ 智能填表 │
└─────────────┘ └─────────────┘ └─────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────────┐ ┌───────────────┐ ┌───────────────┐
│ 结构化数据提取 │ │ LLM 提取 │ │ 导出结果 │
│ (直接读rows) │ │ (文本理解) │ │ (Excel/Word) │
└───────────────┘ └───────────────┘ └───────────────┘
核心组件
| 组件 | 文件 | 说明 |
|---|---|---|
| 模板上传 | templates.py /templates/upload |
接收模板文件,提取字段 |
| 字段提取 | template_fill_service.py |
从 Word/Excel 表格提取字段定义 |
| 文档解析 | docx_parser.py, xlsx_parser.py, txt_parser.py |
解析源文档内容 |
| 智能填表 | template_fill_service.py fill_template() |
结构化提取 + LLM 提取 |
| 多行支持 | template_fill_service.py FillResult |
values 数组支持 |
| JSON 容错 | template_fill_service.py _fix_json() |
修复损坏的 JSON |
| 结果导出 | templates.py /templates/export |
多行 Excel + Word 导出 |
8.2 源文档加载方式
模板填表服务支持两种方式加载源文档:
-
通过 MongoDB 文档 ID:
source_doc_ids- 文档已上传并存入 MongoDB
- 服务直接查询 MongoDB 获取文档内容
-
通过文件路径:
source_file_paths- 直接读取本地文件
- 使用对应的解析器解析内容
8.3 Word 表格模板解析
比赛评分表格通常是 Word 格式,docx_parser.py 提供了专门的解析方法:
# 提取表格模板字段
from docx_parser import DocxParser
parser = DocxParser()
fields = parser.extract_template_fields_from_docx(file_path)
# 返回格式
# [
# {
# "cell": "T0R1", # 表格0,行1
# "name": "字段名",
# "hint": "提示词",
# "field_type": "text/number/date",
# "required": True
# },
# ...
# ]
8.4 字段类型推断
系统支持从提示词自动推断字段类型:
| 关键词 | 推断类型 | 示例 |
|---|---|---|
| 年、月、日、日期、时间、出生 | date | 出生日期 |
| 数量、金额、比率、%、率、合计 | number | 增长比率 |
| 其他 | text | 姓名、地址 |
8.5 API 接口
POST /api/v1/templates/upload
上传模板文件,提取字段定义。
响应:
{
"success": true,
"template_id": "/path/to/saved/template.docx",
"filename": "模板.docx",
"file_type": "docx",
"fields": [
{"cell": "A1", "name": "姓名", "field_type": "text", "required": true, "hint": "提取人员姓名"}
],
"field_count": 1
}
POST /api/v1/templates/fill
填写请求:
{
"template_id": "模板ID",
"template_fields": [
{"cell": "A1", "name": "姓名", "field_type": "text", "required": true, "hint": "提取人员姓名"}
],
"source_doc_ids": ["mongodb_doc_id_1", "mongodb_doc_id_2"],
"source_file_paths": [],
"user_hint": "请从xxx文档中提取"
}
响应(含多行支持):
{
"success": true,
"filled_data": {
"姓名": ["张三", "李四", "王五"],
"年龄": ["25", "30", "28"]
},
"fill_details": [
{
"field": "姓名",
"cell": "A1",
"values": ["张三", "李四", "王五"],
"value": "张三",
"source": "结构化数据直接提取",
"confidence": 1.0
}
],
"source_doc_count": 2,
"max_rows": 3
}
POST /api/v1/templates/export
导出请求(创建新文件):
{
"template_id": "模板ID",
"filled_data": {"姓名": ["张三", "李四"], "金额": ["10000", "20000"]},
"format": "xlsx"
}
POST /api/v1/templates/fill-and-export
填充原始模板并导出(推荐用于比赛)
直接打开原始模板文件,将数据填入模板的表格/单元格中,然后导出。保持原始模板格式不变。
请求:
{
"template_path": "/path/to/original/template.docx",
"filled_data": {
"姓名": ["张三", "李四", "王五"],
"年龄": ["25", "30", "28"]
},
"format": "docx"
}
响应:填充后的 Word/Excel 文件(文件流)
特点:
- 打开原始模板文件
- 根据表头行匹配字段名到列索引
- 将数据填入对应列的单元格
- 多行数据自动扩展表格行数
- 保持原始模板格式和样式
POST /api/v1/templates/parse-word-structure
上传 Word 文档并提取结构化字段(比赛专用)
上传 Word 文档,从表格模板中提取字段定义(字段名、提示词、字段类型)并存入 MongoDB。
请求:multipart/form-data
- file: Word 文件
响应:
{
"success": true,
"doc_id": "mongodb_doc_id",
"filename": "模板.docx",
"file_path": "/path/to/saved/template.docx",
"field_count": 5,
"fields": [
{
"cell": "T0R1",
"name": "字段名",
"hint": "提示词",
"field_type": "text",
"required": true
}
],
"tables": [...],
"metadata": {
"paragraph_count": 10,
"table_count": 1,
"word_count": 500,
"has_tables": true
}
}
GET /api/v1/templates/word-fields/{doc_id}
获取 Word 文档模板字段信息
根据 doc_id 获取已上传的 Word 文档的模板字段信息。
响应:
{
"success": true,
"doc_id": "mongodb_doc_id",
"filename": "模板.docx",
"fields": [...],
"tables": [...],
"field_count": 5,
"metadata": {...}
}
8.6 多行数据处理
FillResult 数据结构:
@dataclass
class FillResult:
field: str
values: List[Any] = None # 支持多个值(数组)
value: Any = "" # 保留兼容(第一个值)
source: str = "" # 来源文档
confidence: float = 1.0 # 置信度
导出逻辑:
- 计算所有字段的最大行数
- 遍历每一行,取对应索引的值
- 不足的行填空字符串
8.7 JSON 容错处理
当 LLM 返回的 JSON 损坏或被截断时,系统会:
- 清理 markdown 代码块标记(
json,) - 尝试配对括号找到完整的 JSON
- 移除末尾多余的逗号
- 使用正则表达式提取 values 数组
- 备选方案:直接提取所有引号内的字符串
8.8 结构化数据优先提取
对于 Excel 等有 rows 结构的文档,系统会:
- 直接从
structured_data.rows中查找匹配列 - 使用模糊匹配(字段名包含或被包含)
- 提取该列的所有行值
- 无需调用 LLM,速度更快,准确率更高
# 内部逻辑
if structured.get("rows"):
columns = structured.get("columns", [])
values = _extract_column_values(rows, columns, field_name)
九、依赖说明
Python 依赖
# requirements.txt 中需要包含
fastapi>=0.104.0
uvicorn>=0.24.0
motor>=3.3.0 # MongoDB 异步驱动
sqlalchemy>=2.0.0 # MySQL ORM
pandas>=2.0.0 # Excel 处理
openpyxl>=3.1.0 # Excel 写入
python-docx>=0.8.0 # Word 处理
chardet>=4.0.0 # 编码检测
httpx>=0.25.0 # HTTP 客户端
前端依赖
# package.json 中需要包含
react>=18.0.0
react-dropzone>=14.0.0
lucide-react>=0.300.0
sonner>=1.0.0 # toast 通知
十、启动说明
后端启动
cd backend
.\venv\Scripts\Activate.ps1 # 或 Activate.bat
pip install -r requirements.txt # 确保依赖完整
.\venv\Scripts\python.exe -m uvicorn app.main:app --host 127.0.0.1 --port 8000 --reload
前端启动
cd frontend
npm install
npm run dev
环境变量
在 backend/.env 中配置:
MONGODB_URL=mongodb://localhost:27017
MONGODB_DB_NAME=document_system
MYSQL_HOST=localhost
MYSQL_PORT=3306
MYSQL_USER=root
MYSQL_PASSWORD=your_password
MYSQL_DATABASE=document_system
LLM_API_KEY=your_api_key
LLM_BASE_URL=https://api.minimax.chat
LLM_MODEL_NAME=MiniMax-Text-01