做 AI for Drug Discovery(AIDD)相关工作一段时间后,我越来越强烈地感受到一个问题:信息更新太快,而真正值得跟踪的论文又太分散了。
一边是 arXiv、PubMed、各类期刊和会议不断冒出新工作;另一边是我们每天真正能消化的时间非常有限。更麻烦的是,这些论文并不是都值得读。很多文章标题看起来"很 AI"、也"很生物",但真正和 AIDD 直接相关的并不多;还有一些文章虽然相关,但创新点一般,未必值得投入完整阅读时间。
这让我产生了一个很直接的想法:
能不能做一个低成本、自动化、本地可运行的 AIDD 文献监测工具?
我的目标并不是做一个重型平台,更不是搭一个复杂的在线服务,而是做一个足够实用、足够轻量、可以自己长期维护的小系统:它能自动抓取论文,先做规则筛选,再调用大模型做结构化解读,最后以静态网页的形式展示出来。这样我每天要做的事情,就从"大海捞针式找论文",变成"看已经被筛过、被解释过的候选列表"。
这个项目后来被我命名为:AIDD Scholar。
一、为什么我想做这个项目
这个项目最初的出发点,其实很朴素。
我平时会持续关注分子生成、蛋白设计、抗体工程、结构预测、逆合成等方向的工作,但这些内容分散在不同渠道中:
-
arXiv 适合追踪最新预印本;
-
PubMed 更适合看正式进入生命科学语境的文献;
-
不同期刊又会在各自站点更新最新文章;
-
真正和 AIDD 有关的工作,往往横跨机器学习、计算生物、药化、结构生物学多个子领域。
如果只是靠手工订阅 RSS、刷 PubMed、刷 arXiv,其实也能做,但会很快遇到两个问题:
第一,效率低 。
你每天可能会看到很多标题,但并不清楚哪些值得点进去,哪些只是"沾边"。
第二,判断成本高 。
就算一篇文章确实和 AIDD 相关,是否值得深读,往往还要自己快速扫摘要、判断创新点、判断它是方法论文、数据集论文还是应用论文。
我希望把这部分工作尽可能自动化。不是完全替代阅读,而是先做一层"前置筛选和解读",把我每天要面对的信息量降下来。
所以这个项目的核心目标,从一开始就很明确:
-
自动抓取 AIDD 相关论文;
-
尽量少花钱,甚至零服务器成本;
-
大模型只在必要时调用,避免浪费 Token;
-
所有结果都以静态内容导出,本地即可浏览;
-
前后端边界清晰,后续便于维护和迭代。
二、我不是先写代码,而是先和 GPT 讲清楚"我要什么"
这次做项目,我并没有先打开编辑器从头手写框架,而是先花时间把需求整理成一段比较完整的提示词,让 GPT 帮我搭项目骨架。
我给 GPT 的要求,本质上不是"帮我写一个爬虫",而是让它站在一个资深 Python 全栈工程师 + AIDD 领域专家的角度,帮我从 0 到 1 设计一个文献自动化站点。
我一开始和 GPT 沟通时,大概明确了几件事:
-
项目的名字叫 AIDD Scholar
-
后端是 Python Pipeline
-
状态管理要用 SQLite 或 TinyDB
-
前端用 Astro 做静态站点
-
不要设计在线 API
-
文献源至少包括 arXiv、PubMed、RSS
-
大模型只处理通过关键词筛选的论文
-
输出必须是结构化结果,方便前端展示
-
整体方案要尽量低成本、能离线跑、能本地使用
在这个过程中,我发现一个很重要的经验:
如果你只是说"帮我做个网站",模型给出的东西往往会很泛;但如果你把架构、边界、模块职责和成本约束都说清楚,它生成出来的代码骨架会稳定很多。
也就是说,提示词并不是"下命令",而更像是在做一轮轻量化的产品设计和技术设计。
三、项目的整体构建逻辑
在和 GPT 反复交流后,这个项目逐渐形成了一条很清晰的链路:
文献抓取 → 去重 → 关键词过滤 → LLM 解读 → Markdown 导出 → Astro 静态渲染
这条链路看起来很简单,但它其实决定了项目的整体风格:
它不是"在线检索系统",而是一个离线处理流水线。
1. 数据源层
目前项目会从三类地方抓文献:
-
arXiv :重点关注
q-bio.BM、cs.LG、stat.ML -
PubMed:通过 Entrez API 检索 AIDD 相关论文
-
RSS:作为期刊补充源
2. 处理层
抓下来的文献先统一成标准结构,然后进入后续处理:
-
做标题 + 摘要指纹去重
-
按关键词规则筛选
-
通过筛选的,再交给大模型解读
-
最后导出为前端可直接读取的 Markdown
3. 状态层
为了避免重复抓取、重复分析、重复消费 Token,我用了 SQLite 做状态管理。
它记录的核心信息包括:
-
论文来源
-
外部 ID
-
指纹
-
是否通过关键词筛选
-
是否完成 LLM 解读
-
是否已导出
4. 展示层
前端不需要数据库,也不需要在线 API。
Astro 只负责读取导出的 Markdown 文件,并在构建时静态渲染页面。
这一点是我很喜欢的部分:
前端极轻,后端也不需要常驻服务,整个项目的复杂度被控制得比较低。
四、我最终采用了哪些工具
这个项目虽然不大,但工具组合非常典型,基本把"轻量自动化内容站点"的核心链路串起来了。
后端
-
Python 3
-
arxiv:抓 arXiv
-
Biopython / Entrez:抓 PubMed
-
feedparser:解析 RSS
-
PyYAML:读取 YAML 配置
-
python-dotenv :读取
.env -
sqlite3:状态管理
大模型接入
我最开始预留的是 OpenAI 兼容接口,后来在实际运行中切到了千问兼容模式 。
这也是整个项目里我很满意的一点:因为一开始就把 llm_agent.py 写成了 OpenAI-compatible 的形式,所以后面切模型时并不需要改核心逻辑,只需要换配置。
前端
-
Astro
-
Astro Content Collections
-
Markdown + frontmatter
Astro 很适合这个项目,因为它天然适合静态内容站点,而且 Markdown 驱动内容展示这件事做得非常顺手。
五、我是怎么让 GPT 帮我生成代码骨架的
整个项目不是一次生成出来的,而是分几轮逐步推进的。
第一步:先让它给完整目录结构和配置文件
我首先让 GPT 输出:
-
项目目录结构
-
rss_sources.yaml -
keywords.yaml
这一步的意义在于先把"系统长什么样"搭出来,而不是一上来就纠结细节代码。
第二步:生成核心后端模块
接着我让它分别生成:
-
collector.py -
processor.py -
llm_agent.py
这三个模块基本对应系统的三大核心能力:
-
抓取
-
规则筛选
-
大模型解读
第三步:补齐状态管理和导出
后面我又继续补了:
-
db.py -
exporter.py -
pipeline.py -
main.py
到这一步时,项目才真正具备"可以跑"的意义。
第四步:生成前端 Astro 页面
在有了 Markdown 输出之后,我再让 GPT 给 Astro 首页示例代码,让前端至少可以把论文列表渲染出来。
这个过程让我再次确认一件事:
生成代码最怕一步到位。
如果直接让模型"帮我生成完整项目",它很容易给出一个看起来完整、但细节很多不落地的结果。
而分模块推进,就能边看边改,发现问题也容易定位。
六、项目的配置方式
这个项目的配置并不复杂,主要分三类:
1. 抓取源配置
通过 rss_sources.yaml 管理:
-
arXiv 查询
-
PubMed 查询
-
RSS 源定义
这使得抓取源是可配置的,而不是硬编码在 Python 里。
2. 关键词规则配置
通过 keywords.yaml 管理不同方向的筛选逻辑,例如:
-
分子生成
-
蛋白设计
-
抗体设计
-
大环肽
-
逆合成
-
结构辅助药物设计
-
数据集 / Benchmark
每个类别不仅有关键词,还支持:
-
include
-
exclude
-
must_have
-
权重和阈值
也就是说,这一层不是简单的"命中就保留",而是一个比较精细的规则系统。
3. 环境变量配置
通过 .env 管理模型和本地环境,例如:
LLM_API_KEY=你的API Key
LLM_BASE_URL=https://dashscope.aliyuncs.com/compatible-mode/v1
LLM_MODEL=qwen-plus
ENTREZ_EMAIL=你的邮箱
ENABLE_LLM=true
这里有一个我一开始也踩过的点:
ENTREZ_EMAIL 不是给千问用的,而是给 PubMed / NCBI Entrez API 用的。
它和你是手机号注册千问还是邮箱注册千问没有关系。
七、项目是怎么运行起来的
项目第一次运行前,我先初始化数据库:
python scripts/init_db.py
执行后会生成本地 SQLite 数据库。
然后主流程运行:
python main.py
这条命令会完成:
-
读取
.env -
加载抓取源配置
-
加载关键词规则
-
构建数据库连接
-
抓取新文献
-
去重
-
关键词筛选
-
调用大模型做结构化解读
-
导出 Markdown 到 Astro 内容目录
前端本地预览则是:
cd frontend
npm install
npm run dev
然后在浏览器中访问本地地址查看页面效果。
八、实际运行时遇到的问题
这个项目虽然整体很顺,但实际跑的时候还是遇到了一些典型问题。
1. yaml 模块报错
一开始运行 python main.py 时,报了:
ModuleNotFoundError: No module named 'yaml'
后来确认并不是代码写错,而是环境里没有装 PyYAML。
这个问题挺典型,因为 Python 里导入写的是 import yaml,但实际安装包名是 PyYAML。
2. 千问模型配置
最开始默认思路更接近 OpenAI 模型,但后面我希望切到千问。
幸运的是,因为代码是按 OpenAI 兼容接口封装的,所以只需要改:
-
API Key
-
Base URL
-
Model 名称
就能切过去,不需要改整体逻辑。
3. RSS 源质量问题
实际运行后发现,arXiv 和 PubMed 抓取效果比较稳定,但很多 RSS 源返回 0 条。
这说明 RSS 模块代码本身没问题,但部分 feed 配置还需要后续精修。
九、项目实际跑出来的效果
在一次完整运行中,我看到的日志大致是这样的:
-
从 arXiv 和 PubMed 抓到了上百篇新论文
-
大模型接口调用成功
-
最终导出了几十篇候选论文
例如有一次,整个流程的结果大概是:
-
总抓取:194 篇
-
最终导出:27 篇
这个结果对我来说是很有意义的,因为它说明系统已经不是"只是抓下来",而是完成了:
抓取 → 去重 → 规则筛选 → LLM 解读 → 内容导出
这条完整闭环。
而且从实际效果看,关键词层确实起到了很大作用:
它帮我把大量不够相关的论文挡在了 LLM 前面,既节省了 Token,也提高了结果质量。
十、我后来又做了哪些修改
在项目初版跑通之后,我又继续和 GPT 交流,对它做了一些定向修正和增强。
例如:
1. 模型接入改成千问
这是最明确的一项本地修改。
项目原本更偏向 OpenAI 兼容示例,后来已经切换为千问接口并成功运行。
2. 启用真实的 LLM 解读
最开始出于保守考虑,项目是可以不开启模型调用的。
后来为了验证真实效果,我把 ENABLE_LLM 改成了 true,让系统实际调用模型返回结构化结果。
3. 开始思考前端的分类与筛选
在前端初版能显示论文之后,我又进一步思考如何让页面更实用,例如:
-
最近一周 / 最近一个月筛选
-
按类别筛选,如抗体设计、结构预测、分子生成
-
增加期刊影响因子
-
优化整体视觉风格
虽然这部分还处在继续迭代阶段,但方向已经很清晰了:
前端不只是"展示列表",而要逐步变成一个更像研究工作台的页面。
十一、这次做项目,我最大的感受是什么
这次项目给我最深的感受,并不是"GPT 帮我写了很多代码",而是:
如果你能把问题定义清楚,GPT 在项目搭建早期真的能极大提高效率。
但同时,它也不是"你说一句,它就给你一个完美系统"。
真正有效的方式其实是:
-
先把目标、边界和约束讲清楚;
-
分模块让它生成;
-
运行后根据真实报错和真实效果继续修正;
-
把它当成一个高效协作的工程助手,而不是全自动交付者。
从这个角度看,AIDD Scholar 并不只是一个文献站点项目,它也是一次很完整的"用提示词驱动软件原型开发"的实践。
十二、写在最后
AIDD Scholar 现在还不是一个"最终版产品",但它已经完成了我最关心的那部分能力建设:
-
能自动抓 AIDD 相关论文;
-
能通过规则控制成本;
-
能用大模型做结构化解读;
-
能以静态内容方式沉淀结果;
-
能在本地完成完整运行和浏览。
对我来说,这就已经很有价值了。
因为它让我不再只是被动地跟论文赛跑,而是开始拥有一个属于自己的、可持续迭代的文献监测工具。
后面,我还会继续完善它的分类体系、期刊指标、筛选体验和页面样式。但无论后面怎么改,这个项目最重要的一步已经走出来了:
它从一个想法,变成了一条真正跑通的工作流。