资讯动态

基于Python的LLM论文自动化追踪系统设计与实现

发布时间:2026/9/30 17:38:47 来源:尧图企业网站定制
1. 项目概述一个AI论文追踪器的诞生作为一名长期混迹于AI研究一线的从业者我深知信息过载的痛。每天ArXiv、ACL Anthology、OpenReview等平台都会涌现出数十甚至上百篇与大型语言模型LLM相关的新论文。从模型架构的革新、训练技巧的突破到具体应用场景的落地信息洪流让人应接不暇。手动追踪不仅效率低下还极易错过那些“藏在深巷”里的关键工作。正是在这种背景下我萌生了构建一个自动化、个性化LLM论文追踪工具的想法并将其开源为xianshang33/llm-paper-daily这个项目。简单来说llm-paper-daily是一个旨在帮助研究者、工程师和爱好者高效获取、筛选和整理每日最新LLM相关学术论文的工具。它的核心价值在于“降噪”和“提效”。它不是一个简单的RSS订阅器而是通过一系列自动化流程从源头抓取、关键词过滤、信息结构化到最终通过邮件或Webhook进行个性化推送形成了一套完整的解决方案。无论你是想紧跟SOTAState-of-the-art模型动态还是专注于某个细分领域如推理、对齐、长文本处理这个工具都能帮你从海量信息中打捞出真正有价值的内容。2. 核心需求与设计思路拆解2.1 痛点分析我们到底需要什么在动手之前我花了些时间梳理了自身以及身边同行们的核心痛点信息源分散高质量的论文分布在多个平台没有一个聚合入口。筛选成本高即使订阅了某个平台的更新90%的论文标题可能都与你的兴趣无关需要人工逐一点开判断。信息结构化差获取到的往往是简单的标题和链接缺乏摘要、作者、关键代码/项目链接等结构化信息无法快速评估论文价值。缺乏个性化每个人的研究兴趣不同有人关心高效微调有人专注多模态理解通用的推送无法满足个性化需求。无法回溯与归档今天看到一篇好论文过几天想再找可能就淹没在历史记录里了。基于这些痛点我确定了项目的核心设计目标自动化、个性化、结构化、可归档。2.2 技术选型与架构设计为了实现上述目标我选择了以Python为核心的技术栈这主要基于其丰富的科学计算和网络爬虫生态。整个系统的架构可以概括为“采集-处理-分发”三层管道。采集层负责从目标数据源抓取原始数据。我首选了ArXiv的官方API因为它稳定、免费且提供了结构化的元数据标题、摘要、作者、分类、PDF链接等。对于其他没有开放API的平台则采用requests和BeautifulSoup4进行定向爬取但会严格遵守网站的robots.txt规则并设置合理的请求间隔避免对服务器造成压力。处理层这是项目的“大脑”负责核心的过滤和增强。关键词过滤这是实现个性化的关键。用户可以通过配置文件定义一组关键词如“LoRA”、“reasoning”、“retrieval-augmented”。系统会将论文标题和摘要与这些关键词进行匹配支持简单的布尔逻辑AND/OR和模糊匹配以筛选出相关论文。信息结构化与增强从API或网页中解析出的信息被整理成统一的JSON格式。此外我还集成了第三方工具例如尝试调用学术搜索引擎的API在合规前提下来补充论文的被引用数、代码仓库链接如GitHub链接等信息让推送内容更丰富。去重机制利用论文的唯一标识符如ArXiv ID或标题作者的特征哈希确保同一天或历史周期内不会重复推送同一篇论文。分发层负责将处理好的内容送达用户。我实现了两种主流方式邮件推送使用smtplib库通过配置好的SMTP服务器如Gmail、QQ邮箱、SendGrid等发送格式精美的HTML日报。邮件模板清晰列出了论文标题、作者、摘要、链接以及匹配到的关键词一目了然。Webhook推送为了适配现代工作流我增加了Webhook支持。可以将每日摘要推送到企业微信机器人、钉钉机器人、Slack频道甚至自己的笔记软件如Notion中实现无缝集成。整个系统通过schedule库或操作系统的定时任务如cron驱动实现每日定时运行。注意在设计爬虫部分时务必保持友好。过快的请求频率可能导致IP被封锁。我的经验是为每个目标网站设置至少5-10秒的请求间隔并实现简单的错误重试和日志记录机制这对于长期稳定运行至关重要。3. 核心模块实现与实操要点3.1 数据采集器的稳健实现数据采集是流水线的源头必须保证其稳定性和可扩展性。以ArXiv API为例其查询接口非常灵活。import arxiv import logging def fetch_arxiv_papers(keywords, max_results100): 从ArXiv获取与关键词相关的近期论文 client arxiv.Client() # 构建查询字符串例如all:“large language model” AND (abs:“reasoning” OR abs:“LoRA”) query fall:large language model AND ({ OR .join([fabs:\\{k}\\ for k in keywords])}) search arxiv.Search( queryquery, max_resultsmax_results, sort_byarxiv.SortCriterion.SubmittedDate, sort_orderarxiv.SortOrder.Descending ) papers [] try: for result in client.results(search): paper_info { id: result.entry_id, title: result.title, abstract: result.summary, authors: [a.name for a in result.authors], published: result.published.strftime(%Y-%m-%d), pdf_url: result.pdf_url, primary_category: result.primary_category, categories: result.categories } papers.append(paper_info) except Exception as e: logging.error(f从ArXiv获取数据失败: {e}) return papers实操要点查询构造ArXiv查询语法支持ti标题、abs摘要、au作者等字段。精心构造查询式可以极大减少后续过滤的压力。例如abs:“reinforcement learning from human feedback”能精准抓取摘要中包含RLHF的论文。错误处理与日志网络请求充满不确定性。必须用try-except包裹核心请求逻辑并记录详细的日志便于问题排查。速率限制即使使用官方API也应避免短时间内发起大量请求。可以引入time.sleep()或在客户端配置延迟。3.2 个性化过滤引擎的设计采集到的论文可能仍有大量无关内容。过滤引擎需要平衡准确性和灵活性。import re from typing import List, Dict class PaperFilter: def __init__(self, user_keywords: List[str], match_mode: str or): :param user_keywords: 用户定义的关键词列表 :param match_mode: “or” 表示匹配任一关键词“and” 表示需匹配所有关键词 self.keywords [k.lower() for k in user_keywords] self.match_mode match_mode # 可以预编译一些常见的关键词变体或同义词正则 self.patterns {kw: re.compile(rf\b{re.escape(kw)}\b, re.IGNORECASE) for kw in self.keywords} def is_relevant(self, paper: Dict) - bool: 判断一篇论文是否相关 text_to_check f{paper[title]} {paper[abstract]}.lower() matches [] for kw in self.keywords: # 使用正则进行单词边界匹配避免匹配到单词的一部分如“cat”匹配到“category” if self.patterns[kw].search(text_to_check): matches.append(kw) if self.match_mode or: return len(matches) 0 elif self.match_mode and: return set(self.keywords).issubset(set(matches)) return False def get_matched_keywords(self, paper: Dict) - List[str]: 返回匹配到的具体关键词用于在推送中高亮显示 text_to_check f{paper[title]} {paper[abstract]}.lower() matched [] for kw in self.keywords: if self.patterns[kw].search(text_to_check): matched.append(kw) return matched实操心得模糊匹配与精确匹配简单的关键词匹配可能不够。例如用户关心“efficient fine-tuning”但论文中可能只写“parameter-efficient tuning”。初期可以采用模糊匹配如计算文本相似度但计算成本较高。一个折中的办法是维护一个“关键词-同义词”映射表。基于分类的过滤ArXiv论文自带分类标签如cs.CL代表计算语言学cs.AI代表人工智能。在配置中允许用户排除某些不感兴趣的类别如cs.DC分布式计算可以进一步降噪。负向关键词允许用户设置“不想看到”的关键词对于过滤掉某些过于热门但你不关心的子领域非常有效。3.3 内容生成与推送将过滤后的论文列表转化为用户友好的格式并推送出去是价值交付的最后一步。邮件推送示例 我使用Jinja2模板引擎来生成HTML邮件这样可以使日报的排版更美观、更专业。from jinja2 import Template import smtplib from email.mime.text import MIMEText from email.mime.multipart import MIMEMultipart def send_email_report(filtered_papers, recipient, smtp_config): 生成并发送HTML日报邮件 # 1. 准备数据 context { date: datetime.now().strftime(%Y-%m-%d), papers: filtered_papers, # 每篇paper包含 matched_keywords total_count: len(filtered_papers) } # 2. 渲染HTML模板 html_template html body h2 LLM论文日报 {{ date }}/h2 p今日共筛选到 strong{{ total_count }}/strong 篇相关论文。/p hr {% for paper in papers %} div stylemargin-bottom: 20px; padding: 10px; border-left: 4px solid #4CAF50; h3a href{{ paper.pdf_url }}{{ paper.title }}/a/h3 pstrong作者:/strong {{ paper.authors | join(, ) }}/p pstrong发布于:/strong {{ paper.published }} | strong分类:/strong {{ paper.categories | join(, ) }}/p pstrong匹配关键词:/strong {% for kw in paper.matched_keywords %} span stylebackground-color: #e0f7fa; padding: 2px 6px; margin: 2px; border-radius: 3px; font-size: 0.9em;{{ kw }}/span {% endfor %} /p pstrong摘要:/strongbr{{ paper.abstract[:300] }}{% if paper.abstract|length 300 %}...{% endif %}/p /div {% endfor %} /body /html template Template(html_template) html_content template.render(context) # 3. 构建并发送邮件 msg MIMEMultipart(alternative) msg[Subject] fLLM论文日报 {context[date]} - {context[total_count]}篇新论文 msg[From] smtp_config[sender] msg[To] recipient msg.attach(MIMEText(html_content, html)) with smtplib.SMTP_SSL(smtp_config[server], smtp_config[port]) as server: server.login(smtp_config[username], smtp_config[password]) server.send_message(msg) logging.info(f邮件已发送至 {recipient})Webhook推送示例以企业微信机器人为例import requests import json def send_wechat_webhook(papers, webhook_url): 推送Markdown格式消息到企业微信机器人 if not papers: return papers_text for i, paper in enumerate(papers[:10]): # 限制前10篇避免消息过长 kw_tags .join([f{kw} for kw in paper.get(matched_keywords, [])]) papers_text f{i1}. **{paper[title]}**\n papers_text f 作者: {, .join(paper[authors][:3])}{等 if len(paper[authors])3 else }\n papers_text f 关键词: {kw_tags}\n papers_text f [阅读摘要与PDF]({paper[pdf_url]})\n\n markdown_content f### 今日LLM论文精选 ({len(papers)}篇)\n---\n{papers_text} payload { msgtype: markdown, markdown: { content: markdown_content } } try: resp requests.post(webhook_url, jsonpayload, timeout10) resp.raise_for_status() logging.info(Webhook推送成功) except requests.exceptions.RequestException as e: logging.error(fWebhook推送失败: {e})提示邮件推送更适合深度阅读而Webhook推送如群聊机器人适合团队共享和快速浏览。在实际部署中我建议两者都配置。个人用邮件归档团队用机器人同步信息。4. 部署、配置与持续运行4.1 环境配置与依赖管理项目使用requirements.txt或pyproject.toml来管理Python依赖。核心依赖包括arxiv、requests、beautifulsoup4、jinja2、schedule等。为了隔离环境强烈建议使用虚拟环境venv或conda。# 克隆项目 git clone https://github.com/xianshang33/llm-paper-daily.git cd llm-paper-daily # 创建并激活虚拟环境 python -m venv venv source venv/bin/activate # Linux/macOS # venv\Scripts\activate # Windows # 安装依赖 pip install -r requirements.txt4.2 配置文件详解项目的灵活性很大程度上来自于配置文件如config.yaml。用户无需修改代码只需编辑此文件即可定制自己的论文追踪器。# config.yaml 示例 user: interests: - keywords: [LoRA, QLoRA, parameter-efficient fine-tuning] match_mode: or category_blacklist: [cs.CV, cs.LG] # 排除计算机视觉和机器学习通用类 - keywords: [reasoning, chain of thought, CoT] match_mode: or - keywords: [retrieval augmented generation, RAG] match_mode: and # 必须同时包含“retrieval”和“generation” sources: arxiv: enabled: true max_results_per_query: 150 categories: [cs.CL, cs.AI, stat.ML] # 限定主要类别 acl_anthology: enabled: false # 暂时关闭 base_url: https://aclanthology.org notification: email: enabled: true sender: your-emailgmail.com recipients: [yourselfdomain.com, teammatedomain.com] smtp_server: smtp.gmail.com smtp_port: 465 smtp_username: your-emailgmail.com smtp_password: your-app-password # 注意使用应用专用密码非邮箱密码 webhook: wecom: enabled: true url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?keyYOUR_KEY slack: enabled: false url: YOUR_SLACK_WEBHOOK_URL schedule: daily_run_time: 08:00 # 每天上午8点运行 timezone: Asia/Shanghai配置关键点兴趣组interests是一个列表允许你设置多组兴趣。系统会为每一组兴趣独立执行查询和过滤这样推送的论文可以按主题分组逻辑更清晰。应用专用密码对于Gmail等邮箱务必使用生成的“应用专用密码”而非邮箱登录密码否则会因安全策略导致登录失败。时区设置定时任务的时间必须考虑服务器所在时区确保在正确的时间点触发。4.3 部署方案选择本地电脑最简单在个人电脑上运行适合个人使用。缺点是电脑需要常开。# 直接运行主脚本 python main.py # 或使用schedule库持续运行 python scheduler.py云服务器推荐购买一台最低配置的云服务器如1核1G使用系统的定时任务cron是最稳定、成本最低的方案。# 编辑crontab crontab -e # 添加一行例如每天北京时间早上8点运行 0 8 * * * cd /path/to/llm-paper-daily /usr/bin/python3 main.py /path/to/log/daily.log 21Serverless函数最省心利用云厂商的Serverless服务如AWS Lambda Google Cloud Functions 阿里云函数计算。将代码打包配置定时触发器。优点是无需管理服务器按实际运行时间计费成本极低。但调试和依赖管理可能稍复杂。我个人采用的方案一台轻量级云服务器 cron。理由是其稳定性最高日志查看方便并且可以同时运行其他一些小脚本。每月成本仅需少量费用。5. 高级功能与扩展思路基础功能稳定后可以在此基础上添加更多提升体验的功能。5.1 论文摘要的总结与翻译对于非英语母语的研究者或者想快速把握论文核心的读者自动摘要和翻译是杀手锏功能。可以利用开源的LLM如ChatGLM、Qwen或大厂提供的API需注意成本来实现。# 概念性代码展示集成思路 def summarize_and_translate(abstract, api_keyNone): 使用大模型API对摘要进行总结和翻译 # 本地模型方案示例 # from transformers import pipeline # summarizer pipeline(summarization, modelfacebook/bart-large-cnn) # summary summarizer(abstract, max_length100, min_length30, do_sampleFalse)[0][summary_text] # 调用API方案示例需替换为实际API prompt f请用中文简要总结以下英文论文摘要的核心贡献不超过100字\n\n{abstract} # 调用OpenAI GPT或国内合规的类似API # response openai.ChatCompletion.create(...) # summary_zh response.choices[0].message.content # 此处返回模拟结果 summary_zh f[模拟总结] 该论文主要研究了...提出了...方法在...数据集上取得了...效果。 return summary_zh注意事项此功能会显著增加运行时间和成本如果使用商用API。建议作为可选功能或仅对高相关性匹配关键词最多的论文启用。5.2 历史数据存储与检索简单的日报推送解决了“看新”的问题但“查旧”同样重要。可以引入一个轻量级数据库如SQLite来存储所有处理过的论文。import sqlite3 from datetime import datetime def init_database(db_pathpapers.db): conn sqlite3.connect(db_path) c conn.cursor() c.execute( CREATE TABLE IF NOT EXISTS papers (id TEXT PRIMARY KEY, title TEXT, abstract TEXT, authors TEXT, published DATE, pdf_url TEXT, source TEXT, matched_keywords TEXT, added_date DATE) ) conn.commit() conn.close() def store_papers(papers_list, db_pathpapers.db): conn sqlite3.connect(db_path) c conn.cursor() today datetime.now().date() for p in papers_list: # 避免重复插入 c.execute(SELECT id FROM papers WHERE id?, (p[id],)) if c.fetchone() is None: c.execute( INSERT INTO papers VALUES (?,?,?,?,?,?,?,?,?) , (p[id], p[title], p[abstract], ,.join(p[authors]), p[published], p[pdf_url], arxiv, ,.join(p.get(matched_keywords, [])), today)) conn.commit() conn.close()有了数据库就可以轻松实现按关键词、作者、时间范围进行历史论文检索的功能甚至可以做一个简单的Web界面来查询。5.3 多数据源聚合除了ArXiv还有许多重要的论文来源ACL Anthology计算语言学顶会论文库。OpenReview许多会议如NeurIPS, ICLR的开放评审平台可以获取到最新提交的论文。特定会议官网在CVPR、ICML等会议召开前后官网会放出被接收论文列表。扩展新的数据源本质上就是实现一个新的“采集器”类遵循统一的接口将其集成到主流程中。这体现了项目良好的模块化设计。6. 常见问题与排查技巧实录在实际运行和维护过程中我遇到了不少典型问题。这里记录下来希望能帮你绕过这些坑。6.1 数据源抓取失败问题现象日志显示ConnectionError或Timeout或者返回的数据为空。排查网络首先确认服务器或本地机器网络通畅可以ping或curl一下目标网站。检查API限制查看目标数据源如ArXiv的API使用条款是否有速率限制。我的脚本因为请求太快IP曾被暂时限制过。解决方案是增加请求间隔time.sleep(5)。更新解析逻辑网站结构可能发生变化。如果使用网页爬虫需要定期检查并更新HTML元素的CSS选择器或XPath。为爬虫部分编写单元测试定期运行能及早发现问题。使用重试机制对于网络请求实现一个简单的重试装饰器是很好的实践。import time from functools import wraps import logging def retry(max_attempts3, delay2): def decorator(func): wraps(func) def wrapper(*args, **kwargs): for attempt in range(max_attempts): try: return func(*args, **kwargs) except Exception as e: logging.warning(fAttempt {attempt1} failed: {e}) if attempt max_attempts - 1: time.sleep(delay) else: raise return wrapper return decorator retry(max_attempts3, delay5) def fetch_from_source(url): # ... 请求逻辑6.2 邮件推送被拒收或进入垃圾箱问题现象邮件发送成功日志但收件箱没有收到。检查发件人配置确保SMTP服务器、端口、用户名密码正确。对于Gmail需要开启“两步验证”并生成“应用专用密码”。检查收件人地址确认无误。检查垃圾箱很可能邮件被标记为垃圾邮件。优化方法设置合理的发件人名称如“LLM论文助手”不要用无意义的字符串。优化邮件内容HTML模板不要太花哨避免包含太多外链或敏感词汇如大量“free”、“prize”等。加入纯文本版本MIMEMultipart的alternative就是为此设计。配置SPF/DKIM记录如果你使用自己的域名邮箱务必在域名DNS中正确配置SPF和DKIM记录这是提升邮件送达率的关键。对于个人用户使用第三方邮箱如Gmail、QQ这一步通常由服务商处理好了。6.3 关键词过滤不准问题现象推送的论文不相关或者漏掉了相关论文。调整匹配模式将match_mode从宽松的or改为严格的and或者反之。优化关键词列表增加同义词例如除了“efficient fine-tuning”加上“PEFT”、“parameter-efficient”。使用词组用引号包裹词组如“reinforcement learning from human feedback”避免拆开匹配。引入负向关键词在配置中增加exclude_keywords: [survey, review]来过滤掉综述类文章如果你不想要的话。引入摘要重要性评分更高级的做法是不只判断关键词是否出现还判断其出现的频率和位置标题中的关键词权重高于摘要。甚至可以微调一个小的文本分类模型来打分但这属于进阶玩法了。6.4 定时任务不执行问题现象配置了cron或schedule库但脚本没有在预定时间运行。检查cron日志Linux下可以查看/var/log/cron或syslog看cron是否尝试执行了你的命令。检查环境变量cron执行的环境与用户shell环境不同可能找不到python3命令或项目依赖。在cron命令中使用绝对路径或者在脚本开头通过source命令加载虚拟环境。# 在cron中可以这样写 0 8 * * * cd /path/to/project /path/to/venv/bin/python /path/to/project/main.py /path/to/log.log 21检查脚本权限确保Python脚本有可执行权限 (chmod x main.py)。对于schedule库确保主程序是持续运行的并且没有因为未捕获的异常而退出。将主循环放在try-except块中并记录所有异常。6.5 项目依赖更新导致问题问题现象某天开始脚本突然报错提示某个模块找不到或方法不存在。锁定依赖版本在requirements.txt中指定关键依赖的具体版本号而不是使用。例如arxiv2.0.0。使用虚拟环境这能隔离项目环境避免与其他Python项目冲突。定期测试与更新可以设置一个单独的测试任务每周运行一次检查在最新依赖下脚本是否依然正常工作。如果测试通过再考虑更新生产环境的requirements.txt。这个项目从最初的一个简单脚本逐步演化成一个功能相对完善的小型系统它实实在在地提升了我追踪学术前沿的效率。开源出来是希望它能成为一个“种子”大家可以根据自己的需求进行修改和扩展。比如有人为它增加了对PubMed生物医学论文的支持有人集成了Telegram Bot推送这些都是我最初没想到的精彩应用。技术工具的价值正是在于解决具体问题并在社区协作中不断生长。如果你在使用中有什么问题或改进想法欢迎在项目仓库中交流。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑