1. 为什么我要做这个每日ArXiv CV论文分享
从2023年下半年开始,我养成了一个习惯:每天早上到工位的第一件事,不是打开邮箱,而是刷一遍ArXiv上cs.CV板块的新论文。这个习惯坚持到现在,最大的感受就是——信息过载比信息匮乏更可怕。每天cs.CV板块新增的论文数量经常在200到400篇之间浮动,如果算上交叉列表里的cs.LG、eess.IV、cs.MM,一天要面对的新内容轻松超过500篇。你不可能全部读完,但你又怕漏掉真正重要的那几篇。
这个每日更新的分享项目,本质上就是解决这个矛盾:用一套可复现的筛选流程,把每天几百篇论文压缩成一份10到20篇的精读清单,覆盖视觉基础模型、Transformer架构演进、多模态融合这几个核心方向。它适合三类人:一是做CV方向的研究生和算法工程师,需要跟踪前沿但没时间全量浏览;二是刚入门想了解领域脉络的初学者,需要有人帮忙做初筛;三是做多模态产品落地的开发者,关心哪些新方法能直接迁移到业务里。
我踩过的坑不少。最开始我是按ArXiv默认的"new submissions"列表从头翻到尾,结果每天花一个多小时,还经常被标题党论文浪费时间。后来改成按关键词订阅RSS,又发现关键词设太窄会漏、设太宽会炸。再后来尝试用脚本抓取+本地排序,才慢慢摸索出一套相对稳定的流程。这篇文章就把这套流程完整拆开,包括筛选逻辑、工具选型、参数设置、常见故障排查,以及我积累下来的一些"反直觉"经验。
需要先说明一点:ArXiv本身是一个预印本平台,论文没有经过同行评审,质量参差不齐是常态。所以这套流程的核心不是"找到最好的论文",而是"用最低成本排除明显不值得读的,把注意力留给值得深挖的"。这个定位很重要,它决定了后面所有筛选策略的取舍。
2. 整体筛选思路与方案选型
2.1 从"全量浏览"到"分层过滤"的思路转变
我最初的做法是线性的:打开列表,逐条看标题,感兴趣就点进去看摘要。这个方式的问题在于,你的注意力是均匀分配的,而实际上论文的价值分布是极度不均匀的——可能一天里真正值得读的就三五篇,但你为了找到它们,必须把几百个标题都过一遍。时间一长,注意力疲劳会导致你开始"漏看",明明标题里有"vision foundation model"这种关键词,眼睛却滑过去了。
后来我改成分层过滤:第一层用机器做粗筛,把明显不相关的砍掉;第二层用规则做排序,把可能重要的往前排;第三层才是人工精读。这样人的注意力只花在第三层,前两层交给脚本。这个思路的转变是整套流程的基石。
分层过滤的关键在于,每一层的"召回率"和"精确率"要平衡。第一层粗筛要保证召回率——宁可多留一些,也不能把好论文误杀;第二层排序要保证精确率——把真正可能重要的排到前面。如果第一层就设很严的规则,很容易漏掉那些标题写得比较"朴素"但内容扎实的论文。
2.2 为什么选ArXiv API而不是网页抓取
工具选型上,我试过三种方案:直接爬网页、用RSS订阅、调ArXiv官方API。最后稳定用的是ArXiv API,原因有几个。
网页抓取最直接,但问题也最多。ArXiv的页面结构偶尔会调整,你的解析规则就得跟着改;而且高频抓取容易被限流,我试过一天抓十几次,后来就收到过429响应。RSS订阅相对稳定,但它的更新有延迟,而且分类粒度不够细,你没法按"cs.CV + 特定关键词"这种组合来订阅。ArXiv API则是官方提供的结构化接口,返回的是Atom格式的XML,字段清晰,支持按分类、关键词、时间范围组合查询,还能控制返回数量,非常适合做自动化。
API的基本调用形式是这样的:
# 查询cs.CV分类下最近提交的论文,按提交时间倒序,最多返回100条 curl "http://export.arxiv.org/api/query?search_query=cat:cs.CV&sortBy=submittedDate&sortOrder=descending&max_results=100"这里有个细节要注意:max_results单次最多建议不超过2000,但实际用的时候我一般设100到200,因为再多你也不会全看,而且响应会变慢。另外API有访问频率限制,官方建议是每3秒不超过1次请求,所以如果你要抓多个分类,中间要加延时。
2.3 关键词体系的搭建逻辑
关键词是整个筛选流程的灵魂。我一开始的关键词表很随意,想到什么加什么,结果就是要么漏要么炸。后来我把它分成三层来管理:
核心层是绝对不能漏的方向词,比如vision transformer、multimodal、foundation model、vision-language。这些词一旦出现在标题或摘要里,论文必须进入候选池。
扩展层是相关但没那么核心的词,比如swin、clip、diffusion、detection、segmentation。这些词单独出现不一定重要,但和核心层词组合出现时权重会提高。
排除层是我明确不关心的方向,比如medical image(除非同时出现foundation model)、remote sensing(除非涉及多模态融合)、autonomous driving(除非是端到端多模态方案)。排除层的作用是降低噪音,但设置要谨慎,因为有些跨领域的工作恰恰是最有启发的。
关键词匹配我建议同时匹配标题和摘要,但标题的权重更高。一个简单的做法是:标题命中核心词得3分,摘要命中得1分,标题命中扩展词得1分,摘要命中得0.3分,最后按总分排序。这个权重不是拍脑袋来的,是我对比了几周的人工筛选结果后调出来的——标题里出现核心词的论文,我最终精读的概率大概是摘要里出现的两倍多。
3. 核心环节的实操细节与参数设置
3.1 API查询的完整参数拆解
ArXiv API的查询参数看起来简单,但组合起来有不少门道。我把常用的参数和我的设置列一下:
| 参数 | 作用 | 我的设置 | 说明 |
|---|---|---|---|
| search_query | 查询条件 | 组合表达式 | 支持AND/OR/ANDNOT |
| sortBy | 排序字段 | submittedDate | 按提交时间 |
| sortOrder | 排序方向 | descending | 最新的在前 |
| max_results | 返回数量 | 150 | 单次抓取上限 |
| start | 起始偏移 | 0 | 分页用 |
search_query的语法值得单独说。它支持字段前缀,比如ti:表示标题,abs:表示摘要,cat:表示分类,au:表示作者。组合的时候用+AND+、+OR+、+ANDNOT+连接。举个例子,我想找cs.CV分类下标题或摘要里包含"vision transformer"或"multimodal"的论文:
search_query=cat:cs.CV+AND+(ti:%22vision+transformer%22+OR+abs:%22vision+transformer%22+OR+ti:%22multimodal%22+OR+abs:%22multimodal%22)注意引号要URL编码成%22,空格编码成+。这个表达式看起来复杂,但拆开看就是"分类是cs.CV,并且(标题或摘要含vision transformer,或者标题或摘要含multimodal)"。
我实测下来,单次查询如果条件太宽,返回的150条里可能只有三四十条是真正相关的。所以我的做法是分多次查询:先查核心词组合,再查扩展词组合,最后合并去重。这样虽然请求次数多了,但每次的结果更聚焦,后续排序也更准。
3.2 去重与增量更新的处理
每天抓取都会遇到重复问题:同一篇论文可能昨天已经抓过,今天又出现在列表里(因为ArXiv的提交时间有更新机制)。如果不做去重,你的候选池会越来越臃肿。
我的做法是维护一个本地已处理ID库,用论文的ArXiv ID(比如2409.12345)作为唯一键。每次抓取后,先过滤掉ID库里已有的,剩下的才是新论文。ID库用简单的文本文件或SQLite都行,我用的SQLite,因为查询快,而且可以顺便记录每篇论文的处理状态(已读、已跳过、已精读)。
增量更新还有个细节:ArXiv的论文有"提交时间"和"更新时间"两个字段。有些论文是先提交后更新,更新时间变了但ID没变。如果你只按提交时间去重,会漏掉那些"老论文新版本"的情况。我的处理是:ID相同但更新时间变了的,标记为"有更新",单独列出来,但不重复计入新论文数。
3.3 排序算法的具体实现
排序是决定你每天先看哪几篇的关键。我用的是一个加权评分模型,核心逻辑是:
def score_paper(paper, core_kw, ext_kw, exclude_kw): score = 0 title = paper['title'].lower() abstract = paper['abstract'].lower() # 核心词:标题权重3,摘要权重1 for kw in core_kw: if kw in title: score += 3 if kw in abstract: score += 1 # 扩展词:标题权重1,摘要权重0.3 for kw in ext_kw: if kw in title: score += 1 if kw in abstract: score += 0.3 # 排除词:命中直接大幅降权 for kw in exclude_kw: if kw in title: score -= 5 if kw in abstract: score -= 2 # 新鲜度加成:当天提交的加2分 if paper['is_today']: score += 2 return score这个模型很简单,但效果比我试过的复杂模型(比如用TF-IDF或embedding相似度)更稳定。原因是:关键词匹配虽然粗糙,但可解释性强,你能清楚知道为什么某篇论文排前面。而embedding相似度虽然理论上更"智能",但一旦排序结果不符合预期,你很难调试——你不知道是embedding模型的问题,还是阈值设得不对。
新鲜度加成是我后来加的。因为ArXiv上有些论文是几天前提交的,但因为更新或者分类调整,今天才出现在列表里。这类论文不一定不重要,但优先级确实应该低于当天的新论文。加2分是个经验值,加太多会导致老论文永远排不上来,加太少又没效果。
3.4 每日清单的生成与呈现
排序完成后,我会生成一份Markdown格式的清单,每篇论文包含:标题、作者、ArXiv链接、一句话摘要(从abstract里截取前两句)、评分、命中的关键词。这样做的目的是让你在点进去之前,就能快速判断这篇论文值不值得读。
清单的呈现我建议按评分分三档:必读(评分前5)、选读(评分6到15)、备查(其余)。必读的我会在清单里加粗,选读的正常显示,备查的折叠起来。这样你每天打开清单,先看必读的5篇,有时间再看选读,没时间就跳过备查。这个分层让"每天花多少时间"变得可控。
4. 常见问题与排查技巧实录
4.1 API返回空结果或结果异常
这是最常见的问题。可能的原因有几个:一是查询表达式语法错误,比如括号不匹配、引号没编码;二是分类名写错,cs.CV是对的,但有人会写成cs.cv或CS.CV,ArXiv是大小写敏感的;三是时间范围设得太窄,比如你查"今天提交的",但ArXiv的时区是UTC,你本地是东八区,可能你早上查的时候UTC还是前一天。
排查方法:先用最简单的查询测试,比如cat:cs.CV不带任何其他条件,看能不能返回结果。如果能,再逐步加条件,定位是哪一步出的问题。时区问题我建议统一用UTC来算,或者干脆查"最近48小时",避免边界情况。
4.2 关键词命中但论文不相关
这是关键词筛选的固有缺陷。比如"multimodal"这个词,在CV领域通常指视觉+语言,但在有些论文里可能指"多模态医学影像",跟你想看的完全不是一回事。再比如"foundation model",有些论文只是蹭热度,实际做的还是小模型。
我的应对策略是加负向关键词。比如你发现"medical"、"clinical"、"patient"这些词频繁出现在你不想要的论文里,就把它们加到排除层。但要注意,排除词不能设太多,否则会误杀跨领域的好工作。我的经验是排除词控制在10个以内,而且只排除你确定不关心的方向。
另一个技巧是看作者和机构。如果一篇论文的作者来自你熟悉的、经常发高质量工作的组,那即使标题看起来一般,也值得点进去看看。这个信息API里也有,可以在排序时给个小的加成。
4.3 抓取频率过高被限流
ArXiv API虽然没有严格的配额,但高频请求会触发限流,表现为返回503或429。我踩过一次坑:为了测试,我写了个循环连续请求了20次,结果后面半小时都返回错误。
解决办法很简单:加延时。每次请求之间sleep 3秒,这是官方建议的最小间隔。如果你要抓多个分类,可以把它们合并到一个查询里,用OR连接,这样一次请求就能覆盖,比多次请求更稳妥。另外,抓取时间建议放在凌晨或清晨,这个时段ArXiv的负载相对低,响应更快。
4.4 清单越来越长,失去筛选意义
这个问题我遇到过。一开始每天清单有50多篇,后来发现根本看不完,清单就变成了摆设。根本原因是筛选阈值太松。我的调整是把必读档控制在5篇以内,选读档控制在10篇以内,超出的全部归入备查。这样即使某天论文特别多,你的核心阅读量也是稳定的。
还有一个心态问题:你不需要读完所有论文。ArXiv上的论文,99%你都不需要读。接受这一点,筛选才有意义。我现在的标准是:必读的5篇里,能有2篇让我有收获,这一天就没白过。
4.5 常见问题速查表
| 问题现象 | 可能原因 | 排查方法 | 解决措施 |
|---|---|---|---|
| API返回空 | 表达式语法错误 | 用最简查询测试 | 检查括号、引号编码 |
| 结果不相关 | 关键词太宽泛 | 看命中词分布 | 加负向关键词 |
| 被限流 | 请求频率过高 | 看HTTP状态码 | 加3秒延时 |
| 清单过长 | 阈值太松 | 统计每日数量 | 收紧必读/选读档 |
| 漏掉重要论文 | 关键词覆盖不足 | 对比人工筛选 | 补充核心词 |
| 重复论文多 | 未做去重 | 检查ID库 | 维护本地ID库 |
5. 我踩过的坑和几条实在经验
5.1 不要迷信"热点关键词"
有段时间我特别关注"diffusion"相关的论文,因为那阵子diffusion model很火。结果就是我的清单里塞满了各种diffusion的变体,很多只是在小数据集上刷了个点,实际价值有限。后来我意识到,热点关键词会带来大量低质量跟风工作,你需要用更细的规则去过滤,比如看论文有没有开源代码、有没有在主流benchmark上评测、作者是不是这个方向的活跃研究者。
5.2 摘要的前两句往往就够了
我一开始每篇论文都点进去看全文,效率极低。后来发现,摘要的前两句通常就说明了这篇论文做了什么、解决了什么问题。如果前两句没让你产生兴趣,后面大概率也不会有。所以我的精读流程是:先看清单里的一句话摘要,感兴趣的点进去看完整摘要,还感兴趣才下载PDF。这个漏斗能帮你省下大量时间。
5.3 周末的论文值得单独处理
ArXiv的提交量在工作日和周末差异很大。周一到周四通常最多,周五开始减少,周末最少。但周末提交的论文里,有时候会有一些"憋大招"的工作——作者可能花了一周时间打磨,周末才提交。所以我的做法是:周末的清单单独存一份,周一早上花20分钟快速过一遍,往往能捡到漏。
5.4 建立自己的"论文库"比每天追新更重要
追新是必要的,但如果你只是每天看清单,看完就忘,那价值有限。我后来建了一个本地的论文库,把精读过的论文按主题分类存起来,每篇写两三句笔记:核心方法是什么、和之前的工作比有什么改进、能不能用到我的项目里。这个库积累到几百篇之后,你会发现很多"新论文"其实是在解决你早就见过的问题,只是换了个说法。这时候你的判断力就上来了。
5.5 工具是辅助,判断力才是核心
最后说个心态上的经验。这套流程再自动化,也只是帮你做初筛。真正决定你能否从论文里获得价值的,是你自己的判断力——你能不能看出一个方法的核心创新点、能不能判断它是否适合你的场景、能不能把它和已有的知识体系连接起来。工具能帮你省时间,但省下来的时间要花在提升判断力上,而不是刷更多论文。我见过一些人,每天读几十篇摘要,但问他某篇论文到底做了什么,说不清楚。这就是本末倒置了。
这套每日更新的流程,我从最初的纯手工,到半自动,再到现在的相对稳定,前后调整了大概半年。现在每天早上花15到20分钟,就能完成从抓取到精读清单的全过程。如果你也在做类似的事情,建议先从最简单的API查询开始,跑通了再逐步加排序和去重,不要一上来就追求完美。流程是迭代出来的,不是设计出来的。