paperMind 项目阶段总结:面向学术论文阅读的 AI 文献智能平台
本文记录 paperMind 项目的当前建设情况。项目围绕“上传一篇论文之后,如何更高效地阅读、理解、翻译和追问”这个问题展开,目前已经形成了从 PDF 解析、论文结构化、向量入库,到智能问答、深度阅读、术语翻译、文献检索和个人中心的完整闭环。
一、项目背景
学术论文阅读一直是一个高成本任务。尤其是在阅读英文论文、长篇综述、公式密集型论文或实验细节较多的论文时,用户经常需要在多个工具之间来回切换:
- 用 PDF 阅读器打开论文;
- 用翻译工具翻译段落;
- 用搜索引擎查相关论文;
- 用大模型追问方法细节;
- 手动整理论文标题、作者、摘要和关键信息;
- 再把笔记、结论、引用关系单独保存下来。
这些操作本身都不复杂,但组合起来非常割裂。一个比较典型的场景是:用户读到论文中的某个公式,想知道这个公式的变量含义,就需要先复制上下文,再去问大模型;如果模型回答不准确,还要回到原文核对;如果涉及术语翻译,还要反复检查前后译法是否一致。
paperMind 要解决的就是这个问题:把论文解析、内容检索、大模型理解、学术翻译和阅读辅助整合到一个平台里。
我们的目标不是做一个简单的 PDF 转 Markdown 工具,也不是做一个普通聊天机器人,而是做一个真正围绕“论文对象”展开的智能阅读平台。
二、项目定位
paperMind 当前定位为:
AI 驱动的学术文献智能平台,帮助用户完成论文解析、论文问答、深度阅读、术语翻译和相关文献检索。
它的核心工作流如下:
用户上传 PDF
↓
MinerU 解析论文内容
↓
生成 Markdown 与结构化 JSON
↓
提取论文元数据
↓
正文分块并生成向量
↓
写入 ChromaDB 向量库
↓
围绕论文进行问答、翻译、深度阅读和文献检索
从用户角度看,paperMind 希望提供的是一个“论文工作台”:上传一篇论文之后,用户可以直接查看解析结果、围绕论文提问、让系统做系统性拆解、选中段落翻译,也可以继续搜索相关论文。
从技术角度看,项目的重点是把以下几类能力串起来:
- 文档解析能力:把 PDF 解析成可处理的 Markdown 和结构化数据;
- 检索增强能力:把论文切分成片段并写入向量库;
- 大模型理解能力:基于论文原文完成问答、分析和翻译;
- 多智能体编排能力:用 LangGraph 管理不同任务的执行路径;
- Web 平台能力:提供可交互的前端页面和稳定的后端接口。
三、整体功能概览
当前 paperMind 已经完成的主要模块包括:
| 模块 | 当前能力 |
|---|---|
| 文献解析 | PDF 上传、任务创建、MinerU 解析、Markdown 预览、资源路径处理 |
| 元数据提取 | 自动提取标题、作者、期刊、时间、DOI、摘要 |
| 向量入库 | Markdown 分块、本地 Embedding、ChromaDB 持久化 |
| 智能问答 | 基于当前论文全文和重点片段回答用户问题 |
| LangGraph 多智能体 | Router 分发不同意图,按任务调用不同 Agent |
| 深度阅读 | 从方法、公式、实验三个角度系统拆解论文 |
| 幻觉检查 | 对深度阅读结果进行原文支撑验证,必要时自动重写 |
| 学术翻译 | 提取术语表,基于术语约束翻译段落 |
| 选中翻译 | 在论文预览页选中文本后直接浮窗翻译 |
| 文献检索 | 接入 Semantic Scholar,并提供 DBLP 备用数据源 |
| 用户系统 | 注册、登录、退出、个人资料、头像上传、密码修改 |
| 健康提醒 | 支持阅读休息提醒,适合长时间论文阅读场景 |
下面按模块展开介绍。
四、文献解析模块
文献解析是 paperMind 的入口模块,也是后续所有智能能力的基础。
用户在前端“文献解析”页面上传 PDF 后,后端会通过 /api/v1/tasks 接口创建一个解析任务。每个任务都会生成一个唯一的 task_id,并创建独立的输出目录,用于保存上传文件、解析结果、任务状态和衍生资源。
解析任务的数据结构大致包括:
{ "task_id": "唯一任务 ID", "status": "pending / running / succeeded / failed", "created_at": "创建时间", "updated_at": "更新时间", "filename": "原始 PDF 文件名", "source": "cli 或 api", "error": "错误信息", "output_dir": "任务输出目录" }
1. 为什么采用异步任务
PDF 解析不是一个轻量操作。论文中如果包含大量图片、表格、数学公式或扫描内容,解析时间可能会比较长。如果直接在上传接口里同步等待,用户会一直卡在请求中,前端体验也不好。
因此项目采用异步任务方式:
前端上传 PDF
↓
后端立即创建任务并返回 task_id
↓
后台线程执行 MinerU 解析
↓
前端轮询任务状态
↓
解析成功后获取 Markdown 结果
这种方式的好处是接口响应更稳定,前端也可以展示“解析中”的状态提示。后续如果接入任务队列,也可以在这个基础上继续扩展。
2. MinerU 解析流程
项目使用 MinerU 作为 PDF 解析引擎。当前既支持本地 CLI 模式,也预留了 API 模式。
本地 CLI 模式适合开发环境和单机部署;API 模式适合后续把文档解析服务独立出去,形成专门的解析服务。
解析完成后,系统会在任务目录中保存:
- result.md:论文 Markdown 内容;
- result.json:结构化解析结果;
- task.json:任务状态与元信息;
- _cli_stdout.log / _cli_stderr.log:CLI 执行日志;
- 图片、表格等由 MinerU 生成的资源文件。
前端展示 Markdown 时,还需要处理图片路径。因为 MinerU 输出的图片路径通常是相对路径,浏览器不能直接访问,所以后端提供了:
/api/v1/tasks/{task_id}/assets/{asset_path}
用于安全访问任务目录下的资源文件。后端会校验资源路径,避免非法路径访问。
3. 解析结果预览
解析完成后,前端会调用:
GET /api/v1/tasks/{task_id}/result
拿到 Markdown、结构化 JSON、元数据和资源基础路径。页面会将 Markdown 渲染为可阅读的论文内容,并支持图片、表格、公式等内容展示。
从用户体验上看,这一步完成后,用户已经可以把 paperMind 当作一个论文解析和预览工具使用。
五、元数据提取模块
论文解析完成后,仅有正文内容还不够。一个文献平台还需要知道这篇论文的标题、作者、期刊、发表时间、DOI 和摘要等信息。
paperMind 在解析完成后会自动调用元数据提取逻辑,从 Markdown 和结构化 JSON 中提取论文信息。
当前提取的字段包括:
| 字段 | 说明 |
|---|---|
| title | 论文标题 |
| authors | 作者列表 |
| journal | 期刊或会议名称 |
| publish_date | 发表时间 |
| doi | DOI |
| abstract | 摘要 |
1. 标题提取
标题通常出现在论文开头,也是 Markdown 中最靠前的较长文本。系统会优先从前几行中寻找非空、非作者、非摘要、非章节标题的文本作为标题。
2. 作者提取
作者提取比标题复杂得多。论文作者行可能有很多格式:
- 逗号分隔;
- 上标数字标注机构;
- 星号标注通讯作者;
- 作者、邮箱、机构混在同一区域;
- 英文姓名和中文机构同时出现。
当前实现采用规则和正则组合的方式:先定位标题之后、摘要之前的头部区域,再过滤邮箱、机构名称和明显不是作者的内容,最后拆分出作者列表。
这种方式的优点是速度快,不需要额外调用大模型,也不会增加 API 成本。
3. 期刊、时间与 DOI
期刊和会议名称通过已知关键词和头部区域匹配获取,例如 Nature、Science、IEEE Transactions、NeurIPS、CVPR、ICML、ACL 等。
发表时间通过日期正则提取,支持常见格式:
- 2024
- March 2024
- 2024-03
- 2024年3月
DOI 则通过标准 DOI 模式匹配:
10.xxxx/xxxxx
4. 元数据的价值
元数据不仅用于页面展示,也为后续文献库、检索、排序、引文网络和导出功能打基础。用户打开论文时,首先看到的是标题、作者、摘要等摘要信息,而不是一整篇长 Markdown,这会让阅读入口更清晰。
六、论文分块与向量入库
为了让大模型能够围绕论文内容回答问题,系统需要先把论文内容变成可检索的数据。
paperMind 的做法是:
读取 result.md
↓
按 Markdown 标题和段落切分
↓
得到多个 Chunk
↓
用本地 Embedding 模型生成向量
↓
写入 ChromaDB
1. 为什么需要分块
一篇论文通常很长,如果每次问答都把全文完整塞给模型,会带来几个问题:
- 上下文太长,容易超出模型限制;
- 请求成本更高;
- 模型不一定能准确关注到问题相关段落;
- 回答速度会变慢。
因此系统会将论文拆成多个片段,每个片段带上所属章节、片段序号和 paper_id。当用户提问时,系统先用问题向量去检索最相关的片段,再把这些片段作为重点参考交给大模型。
2. 本地 Embedding
项目使用 sentence-transformers 中的 all-MiniLM-L6-v2 作为本地 Embedding 模型。这个模型体积较小,CPU 上也可以运行,适合当前项目阶段。
Embedding 和 LLM 是分开的:
- Embedding 负责“找内容”;
- LLM 负责“读内容并生成回答”。
这个拆分非常重要。Embedding 不需要和大模型使用同一个服务,本地小模型就可以满足语义检索需求,还能降低成本并提升可用性。
3. ChromaDB 持久化
向量数据写入 ChromaDB,并按 paper_id 做过滤。这样用户围绕某一篇论文提问时,系统可以只检索当前论文的片段,而不是从所有论文中混合检索。
向量库中的每条记录包含:
- chunk id;
- chunk 文本;
- embedding 向量;
- paper_id;
- section;
- chunk_index。
这为后续 RAG 问答提供了基础。
七、智能问答模块
智能问答是用户最直接感知到的 AI 能力。
用户在“智能问答”页面输入问题后,系统会判断用户意图,并基于当前论文内容生成回答。
例如用户可以问:
- “这篇论文主要解决了什么问题?”
- “方法部分的核心创新是什么?”
- “实验设计是否充分?”
- “公式 3 中的变量是什么意思?”
- “作者的结论是否有实验支持?”
1. 问答流程
当前问答流程如下:
用户输入问题
↓
Router 判断意图
↓
context_loader 加载当前论文全文
↓
Embedding 检索重点片段
↓
QA Agent 组织上下文
↓
DeepSeek Chat 生成回答
↓
返回前端展示
系统会同时使用两类信息:
- 当前论文全文;
- 向量检索得到的重点片段。
全文保证信息完整,重点片段帮助模型聚焦问题相关内容。对于较短论文,可以更多依赖全文;对于长论文,重点片段能明显提升回答的针对性。
2. 防止脱离原文
QA Agent 的系统提示中明确要求:
- 回答必须基于论文内容;
- 如果论文中没有相关信息,需要说明上下文不足;
- 对公式和术语保留原文表达;
- 尽量引用具体章节或段落作为依据。
这类约束可以减少大模型“凭常识补全”的倾向,让回答更贴近论文原文。
3. 前端交互
前端聊天区会显示用户问题和助手回答,并根据 Router 返回的 intent 展示当前调用的是哪一类 Agent。例如:
- QA 问答;
- 文献检索;
- 翻译;
- 溯源;
- 批判分析;
- 通用对话。
这让用户知道系统当前是按什么任务类型处理输入的。
八、LangGraph 多智能体调度
随着功能增加,如果把所有逻辑都写在一个接口里,很快就会变成难以维护的 if-else。paperMind 使用 LangGraph 来管理不同智能任务的执行路径。
当前主图结构如下:
router
↓
context_loader
↓
根据 intent 条件分发
├─ qa ├─ retrieval ├─ translate ├─ trace ├─ critic └─ general
↓
END
1. Router 节点
Router 的职责是判断用户意图。系统定义了几个意图类别:
| intent | 含义 |
|---|---|
| qa | 围绕当前论文提问 |
| retrieval | 搜索其他相关论文 |
| translate | 翻译某段内容 |
| trace | 追溯引用或验证来源 |
| critic | 批判性分析 |
| general | 普通对话 |
Router 使用 LLM 判断用户输入属于哪一类任务,并只返回类别名称。这样后续图就可以根据 intent 条件分发。
2. context_loader 节点
context_loader 的职责是根据 paper_id 加载当前论文内容。它会读取解析结果中的 Markdown,并写入共享状态 paper_context。
这个节点非常关键,因为后续 QA、翻译、深度阅读都需要论文上下文。
3. Agent 节点
不同 Agent 只关注自己的任务:
- qa:根据论文回答问题;
- retrieval:搜索外部文献;
- translate:翻译学术文本;
- trace:预留给溯源验证;
- critic:预留给批判性分析;
- general:处理普通对话。
每个节点都是一个接收 state、返回 state 的函数。节点之间通过共享状态传递数据,而不是互相直接调用。这种方式让各模块更容易拆分和复用。
4. 为什么选择 LangGraph
LangGraph 的优势在于它不仅能串联流程,还能表达条件分支和循环。对于 paperMind 这种“任务类型明确,但每类任务流程不同”的项目,非常合适。
相比让 LLM 自由选择工具,我们更希望流程由程序控制,大模型只在需要理解和生成的地方发挥作用。这样系统行为更可控,也更容易调试。
九、深度阅读模块
普通问答适合解决用户的具体问题,而深度阅读适合用户第一次系统理解一篇论文。
用户点击“开始深度阅读”后,系统会自动生成一份结构化分析报告,重点覆盖:
- 方法原理;
- 数学推导;
- 实验设计;
- 幻觉验证;
- 延伸思考问题。
1. 深度阅读流程
深度阅读使用一张独立的 LangGraph:
context_loader → deep_reader → hallucination_checker ↑ ↓ └── 可信度低时重写 可信度高/中 → questioner → END
这条流程不是简单的“一个 Prompt 生成一篇总结”,而是多个节点协作完成。
2. deep_reader:系统拆解论文
deep_reader 会读取论文全文,从三个角度进行分析。
方法原理拆解:
- 论文提出的核心方法是什么;
- 解决了什么问题;
- 方法整体架构如何;
- 与已有方法相比创新点在哪里。
数学推导分析:
- 核心公式有哪些;
- 变量和符号分别表示什么;
- 推导过程依赖哪些假设;
- 公式如何服务于论文方法。
实验设计评估:
- 使用了哪些数据集;
- 和哪些 baseline 对比;
- 使用了哪些评价指标;
- 消融实验是否支撑核心结论。
3. hallucination_checker:验证分析是否有原文支撑
深度分析最怕的问题是“总结得很像那么回事,但原文根本没这么说”。因此项目加入了幻觉检查节点。
hallucination_checker 会拿到:
- 论文原文;
- deep_reader 生成的分析报告。
然后检查分析中的论断是否有原文支撑,并给出可信度判断。如果可信度较低,流程会回到 deep_reader,让它根据检查反馈重写分析。
这一步让深度阅读具备了一个自我修正闭环:
生成分析 ↓ 检查支撑 ↓ 发现问题 ↓ 回退重写 ↓ 再继续生成问题
4. questioner:生成延伸问题
当分析通过检查后,questioner 会生成进一步阅读问题,帮助用户从“看懂论文”走向“思考论文”。
这些问题通常围绕:
- 方法是否可以迁移到其他任务;
- 实验是否还有补充空间;
- 假设条件是否合理;
- 与相关工作相比优势在哪里;
- 未来可以怎么改进。
这样深度阅读不只是总结,而是引导用户继续做批判性阅读。
5. 深度阅读追问
前端还支持基于深度阅读报告继续追问。用户可以针对分析报告中的某一部分继续提问,后端会同时参考:
- 论文原文;
- 已生成的深度分析;
- 幻觉验证报告;
- 用户追问。
这样用户可以沿着一篇论文持续深入,而不是每次都从零开始问。
十、学术翻译与术语约束
学术论文翻译和普通翻译不一样。普通翻译追求通顺,学术翻译还要保持术语一致、公式不变、上下文准确。
paperMind 的翻译模块采用“先提取术语表,再约束翻译”的设计。
1. 为什么需要术语表
同一篇论文中,一个术语可能反复出现。如果每次翻译都不一样,会严重影响阅读。例如:
- Attention Mechanism:注意力机制;
- Feature Alignment:特征对齐;
- Contrastive Learning:对比学习;
- Ablation Study:消融实验。
如果同一术语在不同段落中出现不同译法,用户很难建立稳定理解。因此系统先根据全文提取术语表,再让翻译 Agent 严格按照术语表翻译。
2. 术语提取流程
术语提取接口会先加载论文全文,然后调用 terminology_extractor 生成术语表。
流程如下:
用户点击提取术语表 ↓ context_loader 加载论文全文 ↓ terminology_extractor 识别核心术语 ↓ 生成中英术语对照表 ↓ 缓存到内存
缓存的作用很明显:术语提取相对耗时,但用户可能会频繁翻译不同段落。如果每次翻译都重新提取术语,体验会很差。
3. 翻译流程
当用户输入一段文本或在论文预览中选中文本时,系统会调用翻译接口:
POST /api/v1/translate
请求中会带上:
- paper_id:当前论文;
- text:需要翻译的文本;
- use_terms:是否使用术语表。
如果当前论文已经有术语表,translate_agent 会把术语表作为强约束传给 LLM,要求它保持术语一致,并保留 LaTeX 公式。
4. 选中翻译体验
前端在论文预览区监听文本选择。当用户选中一段文字后,会出现“翻译选中”的浮动按钮。点击后,翻译结果会以浮窗形式展示在原文附近。
这个交互适合真实阅读场景:用户不需要复制、切页面、粘贴,只需要选中论文中的一段内容,就可以直接查看翻译。
十一、文献检索模块
除了阅读当前论文,用户还经常需要继续查找相关工作。paperMind 提供了文献检索功能,用于根据关键词搜索外部论文。
当前检索入口是:
POST /api/v1/search
用户输入关键词后,系统优先请求 Semantic Scholar,返回:
- 标题;
- 作者;
- 年份;
- 摘要;
- 链接;
- 引用数;
- 数据来源。
1. Semantic Scholar
Semantic Scholar 提供的论文信息比较丰富,适合做学术检索。它可以返回摘要、引用数等信息,方便用户初步判断一篇论文是否值得继续阅读。
2. DBLP fallback
实际开发中,Semantic Scholar 在无 API Key 或请求频繁时可能触发限流。为了提升可用性,项目加入了 DBLP 作为备用数据源。
当 Semantic Scholar 暂时不可用时,系统自动切换到 DBLP。DBLP 返回的信息没有 Semantic Scholar 丰富,但可以提供标题、作者、年份和链接,足够作为基础检索结果。
3. 和 Chat Agent 的关系
文献检索既可以通过独立检索页面触发,也可以通过聊天意图触发。当用户在聊天中输入“帮我找几篇相关论文”这类请求时,Router 会将意图识别为 retrieval,然后调用 retrieval Agent。
这样用户不需要记住功能入口,可以自然地通过对话调用检索能力。
十二、用户系统与个人中心
为了让平台具备基本使用闭环,项目实现了用户系统和个人中心。
当前支持:
- 用户注册;
- 用户登录;
- 退出登录;
- 获取当前用户信息;
- 修改昵称;
- 修改邮箱;
- 修改密码;
- 上传头像。
1. 登录与会话
用户登录成功后,后端生成 session id,并通过 Cookie 返回给浏览器。后续请求会带上 Cookie,后端中间件根据 session 判断用户是否已登录。
对于未登录用户:
- 访问页面时会跳转到登录页;
- 访问 API 时会返回 401。
这种方式保证了主要功能都需要登录后才能使用。
2. 个人资料
个人中心页面展示当前用户信息,并支持修改昵称、邮箱和头像。
头像上传接口会检查文件类型和大小,保存到头像目录后,再通过静态资源路径访问。
3. 密码修改
密码修改需要输入旧密码和新密码。后端会先验证旧密码,确认通过后更新密码哈希。
这让项目具备了最基础的账号管理能力,也为后续多用户文献库、用户个人历史记录打下基础。
十三、健康提醒助手
paperMind 还加入了一个比较贴近使用场景的小功能:健康提醒助手。
论文阅读往往是长时间、强注意力的任务。用户可能连续阅读几十分钟甚至几个小时。健康提醒功能允许用户配置提醒间隔:
- 25 分钟;
- 45 分钟;
- 60 分钟;
- 自定义分钟数。
前端通过 localStorage 保存提醒设置,并使用定时器倒计时。到达时间后,页面会弹出休息提醒。
这个模块虽然不属于核心 AI 能力,但它体现了项目对真实使用场景的考虑:paperMind 不只是“能分析论文”,也希望成为一个适合长时间使用的阅读工作台。
十四、前端页面设计
当前前端采用单页 HTML 实现,通过顶部 Tab 切换不同模块。
主要页面包括:
- 文献解析;
- 智能问答;
- 深度阅读;
- 文献库;
- 文献检索;
- 引文网络;
- 全文翻译;
- 个人中心。
其中“文献库”和“引文网络”已经预留页面入口,方便后续扩展。
1. 文献解析页
文献解析页负责上传 PDF、展示解析状态、展示论文元数据和 Markdown 预览。
用户在这个页面完成论文导入后,其他模块都会围绕当前论文工作。
2. 智能问答页
智能问答页采用左右布局:
- 左侧展示当前论文信息和 Agent 类型说明;
- 右侧展示聊天记录和输入框。
用户可以直接围绕论文提问,系统会根据意图调用不同 Agent。
3. 深度阅读页
深度阅读页展示当前论文状态、分析进度和最终报告。报告分为:
- 深度分析;
- 幻觉验证;
- 延伸问题;
- 追问对话。
用户可以先看系统生成的结构化分析,再针对某个细节继续追问。
4. 全文翻译页
全文翻译页提供术语表提取和文本翻译能力。页面会提示当前是否已经加载论文、术语表是否已提取,以及本次翻译是否使用了术语约束。
5. 个人中心
个人中心整合用户资料、头像上传、密码修改和健康提醒设置,让平台更像一个完整应用,而不仅是一个技术 Demo。
十五、后端接口概览
项目后端使用 FastAPI,接口按功能组织。
1. 认证接口
| 接口 | 作用 |
|---|---|
| POST /api/v1/auth/register | 注册用户 |
| POST /api/v1/auth/login | 登录 |
| POST /api/v1/auth/logout | 退出登录 |
| GET /api/v1/auth/me | 获取当前用户 |
| PUT /api/v1/auth/profile | 更新资料 |
| PUT /api/v1/auth/password | 修改密码 |
| POST /api/v1/auth/avatar | 上传头像 |
2. 论文任务接口
| 接口 | 作用 |
|---|---|
| POST /api/v1/tasks | 上传 PDF 并创建解析任务 |
| GET /api/v1/tasks | 获取已解析论文列表 |
| GET /api/v1/tasks/{task_id} | 查询任务状态 |
| GET /api/v1/tasks/{task_id}/result | 获取解析结果 |
| GET /api/v1/tasks/{task_id}/metadata | 获取论文元数据 |
| GET /api/v1/tasks/{task_id}/assets/{asset_path} | 获取论文资源文件 |
3. AI 能力接口
| 接口 | 作用 |
|---|---|
| POST /api/v1/chat | 智能问答 |
| POST /api/v1/deep-reading | 深度阅读 |
| POST /api/v1/deep-reading/followup | 深度阅读追问 |
| POST /api/v1/translate/terms | 提取术语表 |
| POST /api/v1/translate | 翻译文本 |
| GET /api/v1/chat/history/{paper_id} | 获取聊天历史 |
| POST /api/v1/search | 文献检索 |
4. 状态接口
| 接口 | 作用 |
|---|---|
| GET /health | 服务健康检查 |
| GET /api/v1/capability | 检查 MinerU 能力 |
这些接口让前端页面和后端能力解耦,也方便后续接入新的前端框架或第三方调用。
十六、技术架构
当前项目采用轻量 Web 应用架构:
浏览器前端 ↓ FastAPI 后端 ├─ AuthService:用户与认证 ├─ TaskService:论文解析任务 ├─ MinerUClient:PDF 解析调用 ├─ MetadataExtractor:元数据提取 ├─ Chunker:论文分块 ├─ VectorStore:ChromaDB 向量库 ├─ LLMService:DeepSeek 与 Embedding └─ LangGraph Agents:问答、翻译、检索、深度阅读 数据层 ├─ SQLite ├─ ChromaDB ├─ data/parsed └─ 用户资料与头像文件
1. FastAPI
FastAPI 用于提供后端接口。它适合这种轻量但功能模块较多的应用,接口声明清晰,和 Pydantic 配合也比较方便。
2. SQLite
项目使用 SQLite 保存论文、分块、引用、用户和聊天记录等结构化数据。对于当前阶段来说,SQLite 足够轻量,部署简单,也方便本地开发。
3. ChromaDB
ChromaDB 用于保存论文片段向量。它承担的是语义检索能力,让系统可以根据用户问题找到论文中最相关的内容。
4. DeepSeek Chat
大模型推理使用 DeepSeek Chat,并通过 langchain-openai 的 OpenAI 兼容接口调用。这样项目后续如果要切换其他兼容模型,也比较容易。
5. sentence-transformers
Embedding 使用本地 sentence-transformers,避免每次检索都调用远程接口。这个选择让系统在向量化和检索上更稳定,也更适合本地演示和课程项目环境。
十七、工程实现中的几个关键设计
1. CLI 日志写入文件,避免管道阻塞
MinerU CLI 运行时会输出大量日志。如果使用 subprocess.run(capture_output=True) 把 stdout 和 stderr 全部收集到内存管道中,长时间运行时可能出现管道缓冲区阻塞。
项目选择把 stdout 和 stderr 写入日志文件:
_cli_stdout.log _cli_stderr.log
这样既能保留调试信息,又避免大日志导致解析进程卡住。
2. 主流程和增强流程解耦
论文解析成功后,向量入库是在后台尝试执行的。也就是说,解析结果可查看是主流程,向量化是增强流程。
这样设计的好处是用户可以尽快看到解析结果,不会因为向量库或 Embedding 的临时问题导致整篇论文解析失败。
3. Agent 共享状态
LangGraph 中的各个节点通过 AgentState 共享状态。常用字段包括:
- query:用户输入;
- paper_id:当前论文 ID;
- intent:意图分类结果;
- paper_context:论文全文;
- response:最终回答;
- deep_analysis:深度分析结果;
- hallucination_report:幻觉检查报告;
- terminology_table:术语表。
这种状态传递方式让每个节点只处理自己关心的字段,降低了模块之间的耦合。
4. 术语表缓存
术语表提取成本较高,因此项目使用内存缓存:
paper_id -> terminology_table
用户第一次提取术语表后,后续翻译可以直接复用。这个优化对选中翻译尤其重要,因为用户可能在同一篇论文里频繁翻译多个段落。
5. 检索接口 fallback
文献检索使用 Semantic Scholar + DBLP 的组合。主数据源负责提供更丰富的信息,备用数据源负责兜底可用性。
这种设计在真实应用里很常见:外部 API 不一定永远稳定,所以系统需要有降级策略。
十八、当前项目成果
从当前完成度来看,paperMind 已经具备一个学术论文智能平台的基本形态:
- 用户可以登录系统;
- 用户可以上传 PDF 论文;
- 系统可以解析 PDF 并生成 Markdown;
- 系统可以提取论文元数据;
- 系统可以将论文切分并写入向量库;
- 用户可以查看解析后的论文;
- 用户可以围绕论文进行智能问答;
- 用户可以启动深度阅读分析;
- 系统可以对深度分析做幻觉检查;
- 用户可以基于术语表翻译论文段落;
- 用户可以选中文本并快速翻译;
- 用户可以检索相关学术文献;
- 用户可以维护个人资料和头像;
- 用户可以配置阅读健康提醒。
这说明项目已经不只是单点功能验证,而是形成了较完整的产品闭环。
十九、后续建设方向
后续 paperMind 可以继续沿着以下方向增强。
1. 文献库管理
将已解析论文统一沉淀到文献库中,支持按标题、作者、年份、关键词和上传时间筛选。用户可以随时打开历史论文,继续问答、翻译或深度阅读。
2. 引文网络
基于论文 References 和外部学术 API,构建引用关系图谱。这样用户不仅能读当前论文,还能看到它引用了哪些工作、被哪些方向影响,以及相关研究如何演进。
3. 多论文对比阅读
科研中经常需要比较多篇论文的相同点和不同点。后续可以支持选择多篇论文,让系统对比方法、实验、数据集、创新点和结论。
4. 更强的 Agent 协作
当前 Agent 主要是按意图分发。后续可以进一步实现链式协作,例如:
QA Agent 生成回答 ↓ Critic Agent 检查回答依据 ↓ 依据不足则重新检索 ↓ Trace Agent 补充来源 ↓ 生成最终回答
这样系统会从“多功能助手”进一步升级为“多智能体协作式科研助手”。
5. 报告导出
深度阅读报告、术语表、翻译结果和问答记录都可以进一步支持导出,方便用户整理读书笔记、课程作业或研究报告。
二十、总结
paperMind 当前已经完成了学术论文智能阅读平台的核心链路:PDF 解析、元数据提取、论文分块、向量检索、智能问答、深度阅读、幻觉检查、术语翻译、文献检索和用户系统都已经串联起来。
这个项目的重点不只是“调用大模型回答问题”,而是把论文从静态 PDF 转换成可检索、可追问、可分析、可翻译的结构化知识对象。通过 MinerU、ChromaDB、LangGraph、DeepSeek Chat 和本地 Embedding 的组合,paperMind 已经具备了一个科研文献工作台的基础形态。
后续随着文献库、引文网络、多论文对比和多 Agent 协作继续完善,paperMind 可以进一步从“论文阅读助手”演进为“面向科研学习场景的智能文献平台”。
技术栈关键词:FastAPI、MinerU、LangGraph、DeepSeek Chat、ChromaDB、SQLite、sentence-transformers、RAG、学术论文解析、智能文献阅读
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐
所有评论(0)