大四毕设开源|手搓了一个能"看懂图表"的 PDF 问答系统,让回答图文并茂
先说说我是谁
我叫熊乐乐,前端 / 全栈方向的大四学生,毕业设计做的是 RAG 方向。
做这个项目的起因很简单:我在用各种现成的 RAG 工具处理论文 PDF 时,被一个问题搞得很烦——
那些工具根本不会处理图表。
问一张架构图是什么意思?模型要么说"我不知道",要么一本正经地胡说。问一个表格里的数字?检索压根没召回那个表格,因为表格被转成了一坨乱码文本。更别说分块了——传统固定长度分块会把一段完整的技术描述劈成两截,导致每一块都缺失上下文。
网上有一些解决方案,但要么只处理文本,要么对图表的处理浅尝辄止。于是我决定从头手搓一个,把这几个问题彻底解决掉。
项目叫 ViewRAG,已经开源:github.com/David-Lolly…
⭐ 如果觉得有用,欢迎点个 Star,这对独立开发的学生来说意义很大。
它长什么样
主界面支持图文并茂的问答,大模型回答时可以直接内联引用 PDF 里的图片:
三个核心技术亮点
1. 图表深度理解——不只是"提取",而是"看懂"
传统做法:图片直接跳过,或者只存个路径;表格转成乱码文本送去 Embedding。
ViewRAG 的做法:
- 图片:用 PyMuPDF 按 PaddleX 返回的
bbox坐标精准裁剪,上传 MinIO,再调用 Vision LLM 生成一段结构化的语义描述,描述这张图讲了什么,然后对这段描述做 Embedding,存入 pgvector。 - 表格:调用文本 LLM 生成表格摘要,同样走向量化流程。
这样图表就有了真正可检索的语义表示,用户问"第三章那张精度对比图说明了什么",系统能召回对应图片,大模型回答时也能内联引用它。
PDF 图片 → PyMuPDF 按 bbox 裁剪 → MinIO 存储
↓
Vision LLM 生成语义描述
↓
Embedding → pgvector
2. 精准引用溯源——解决"大模型说了但你不知道他是不是在编"
这是我觉得最有工程价值的地方。
系统在构建 LLM 上下文时,会给每个检索到的 Chunk 分配一个引用编号,同时把图片以 image:图片N 的占位符形式注入 Prompt,并通过 REFERENCE_SYSTEM_PROMPT 明确告诉模型:引用内容时必须标注编号,引用图片时必须使用占位符。
前端拿到流式输出后:
- 遇到
[N]角标 → 展示对应 Chunk 的来源(页码 + 片段文本 + 图片预览) - 遇到
image:图片N→ 实时替换为实际图片渲染
点击引用编号,直接跳转到内嵌 PDF 对应页面并高亮定位。
3. 基于版式识别的智能分块——保留段落结构
传统固定长度 / 递归分块的问题:不管段落边界在哪,到了长度上限就切断。一段"方法描述 + 对应公式"很可能被切成两个毫无关联的碎片。
ViewRAG 的分块策略建立在 PaddleX 版式解析结果之上:
- 标题 + 正文自动合并:识别到标题块后,将其后紧跟的段落文本合并为一个语义单元。
- 小块智能拼接:短文本块按顺序拼接,直到接近 1024 token 的阈值,保证每块都有足够的信息密度。
- 图表独立成块:图片和表格不参与合并,保持独立,附带 Vision LLM 生成的语义描述。
结果是每个 Chunk 都对应一个完整的文档语义单元,而不是随机截断的文字碎片。
技术栈一览
| 层级 | 技术 |
|---|---|
| 前端 | Vue 3 + Vite + Tailwind CSS |
| 后端 | FastAPI + Python 3.10 |
| 向量数据库 | PostgreSQL + pgvector |
| 对象存储 | MinIO |
| PDF 解析 | PaddleX 版式解析 API + PyMuPDF |
| LLM 接入 | OpenAI 兼容 API(Qwen / DeepSeek 等) |
| 部署 | Docker Compose(一键启动全部服务) |
其他功能
-
多模态模型支持:文本模型、视觉模型、推理模型(DeepSeek-R1 等)均可配置
-
知识库管理:创建永久知识库,多份 PDF 统一检索

-
任意节点编辑重生成:可以从对话历史中任意一条消息重新编辑并生成,不用重开会话

-
深度推理 & 视觉理解:支持接入推理模型进行深度思考,支持多模态模型直接理解图片
深度推理 视觉理解
部署方式
已经做好了 Docker Compose 一键部署,三条命令搞定:
git clone https://github.com/David-Lolly/ViewRAG.git
cd ViewRAG/docker
docker compose up -d
启动后访问 http://localhost:8080,进入配置页面填写模型 API Key(支持阿里云百炼、硅基流动等所有 OpenAI 兼容接口)和 PaddleX API 即可使用。
还有哪些不足
项目目前还有一些局限,说实话:
- PaddleX 解析依赖外部 API,本地离线模式还没做
- Rerank 模型的效果还没有充分验证
- 前端某些细节交互还比较粗糙
后续打算做的事:
- 支持本地 PDF 解析,去掉对 PaddleX API 的依赖
- 实现 Agentic RAG,让检索更智能
- 开放 OCR 服务接口,为其他项目提供解析能力
最后
这是我大四毕设的成果,从头设计到写完大概用了几个月。开源出来一方面是希望得到反馈和建议,另一方面也希望能帮到有类似需求的同学。
有任何问题欢迎提 Issue 或者在评论区交流,我会认真回复。