新闻详情

新闻详情

首页 / 资讯中心 / 详情

zotero-arxiv-daily 项目架构解析:基于 Zotero 文献库的每日论文推荐流水线

发布时间:2026/10/2 8:04:27来源:尧图网络
zotero-arxiv-daily 项目架构解析:基于 Zotero 文献库的每日论文推荐流水线
人工智能AI 应用RAG科研【免费下载链接】zotero-arxiv-dailyRecommend new arxiv papers of your interest daily according to your Zotero libarary.项目地址https://gitcode.com/GitHub_Trending/zo/zotero-arxiv-daily点击查看免费下载本文以仓库 CLAUDE.md 为骨架深度解析 zotero-arxiv-daily 的整体架构它如何以你的 Zotero 文献库为兴趣画像通过嵌入相似度对 arXiv/bioRxiv/medRxiv/chemRxiv 每日新论文做相关性重排再用 LLM 生成 TLDR 与机构信息并通过邮件送达。读完本文你将掌握这条流水线每一阶段的实现原理、Hydra OmegaConf 的组合配置体系、Retriever/Reranker 插件扩展机制、测试策略与本地运行方式可直接在仓库源码中逐行验证。项目定位与核心思想Zotero-arXiv-Daily 的核心目标非常朴素你 Zotero 里存了什么就代表你对什么感兴趣把每天新发布的论文里和你库中论文最相关的挑出来发到你的邮箱。它不是为了泛泛抓取 arXiv 每日更新而是基于用户自身的文献积累做个性化推荐。从 CLAUDE.md 的项目概述看它覆盖四个论文来源arXiv / bioRxiv / medRxiv / chemRxiv计算新论文与用户现有库的嵌入相似度通过 LLM 生成 TLDR太长不看版摘要最终以 HTML 邮件形式投递且被设计为零成本运行在 GitHub Actions 工作流上。整个应用由Executor编排成一条线性流水线没有任何复杂的调度框架这让它极易被理解、扩展和二次开发。上图为项目 README 中展示的最终邮件呈现效果论文按相关性排序附带 AI 生成的 TLDR、作者机构与 PDF/代码链接。六阶段线性流水线从 Zotero 到邮箱应用的全部业务逻辑集中在 executor.py由Executor类驱动。流水线共六个阶段代码路径Executor.run()见 executor.py#L93-L124Fetch Zotero corpus拉取 Zotero 语料通过pyzoteroAPI 拉取用户文献库只保留conferencePaper || journalArticle || preprint三种条目类型且含摘要abstractNote ! 的论文同时递归解析每个条目的 Collection 路径get_collection_path沿parentCollection逐级向上拼接出如2026/survey的层级路径见 executor.py#L49-L56。Filter corpus过滤语料按include_path/ignore_path两组 glob 模式筛选相关 Collection这决定了你的兴趣画像具体由库中哪些论文构成详见下文Collection 路径过滤小节。Retrieve new papers抓取新论文从配置指定的来源抓取新论文。arXiv 走 RSS feedbioRxiv/medRxiv 走 REST APIchemRxiv 经 Crossref REST API。Rerank重排打分用嵌入模型计算候选论文与语料的相似度并按时间衰减权重加权——越晚加入 Zotero 的论文权重越高代表最近的研究兴趣。Generate TLDRs affiliations生成摘要与机构通过 OpenAI 兼容的 LLM API为每篇候选论文生成一句话 TLDR并尽量解析出作者机构列表。Render send email渲染并发送邮件将结果渲染为 HTML 邮件经 SMTP 发送到收件箱。流水线中的关键防御逻辑值得一提若过滤后语料为空len(corpus) 0run()会记录错误日志并直接返回executor.py#L96-L98若当天无任何新论文除非配置了send_empty: true否则不发送空邮件executor.py#L118-L120。Collection 路径过滤精准圈定兴趣画像范围默认情况下你的全部 Zotero 文献都会参与相似度计算但通过 config/base.yaml 中的两个配置项可以精准圈定范围zotero: include_path: null # 只保留匹配的 Collection例[2026/survey/**, 2026/reading-group/**] ignore_path: null # 排除匹配的 Collection例[2026/ignore/**, archive/**]其实现逻辑在Executor.filter_corpus()executor.py#L65-L90include_path存在时仅保留任一 Collection 路径匹配任一模式的论文ignore_path存在时剔除所有匹配的论文两者可同时配置先 include 后 ignore过滤后若两者任一启用会从结果中随机采样至多 5 篇论文打印标题与路径便于在日志中确认兴趣画像构成。参数校验由normalize_path_patterns()executor.py#L16-L29完成配置值必须是字符串列表或null不支持单个字符串例如2026/survey/**会被拒绝并抛出TypeError提示应写成[2026/survey/**]。glob 匹配的具体实现位于 utils.py 的glob_match并有对应的单元测试可参考。插件系统Retriever 与 Reranker 的注册-发现机制CLAUDE.md 明确指出本项目的两套插件体系其设计高度对称Retriever论文源插件注册在类上使用register_retriever(arxiv)装饰器如 arxiv_retriever.py#L210装饰器把类挂到registered_retrievers字典并写入cls.nameretriever/base.py#L39-L46发现get_retriever_cls(name)按名称查表未注册的名称抛出ValueErrorretriever/base.py#L48-L51契约每个 Retriever 继承BaseRetriever实现两个抽象方法——_retrieve_raw_papers()抓取原始数据、convert_to_paper()将原始数据转换为统一的Paper对象retriever/base.py#L16-L22批量处理retrieve_papers()模板方法逐条转换失败的单条论文被跳过并告警每条之间sleep(1)限速retriever/base.py#L24-L37。以 ArxivRetriever 为例它通过feedparser解析https://rss.arxiv.org/atom/{category}组合出的 RSS 地址category 用连接带 5 次重试与 HTTP 状态/解析器状态校验失败 5 次才抛出RuntimeError。include_cross_list: false时只保留arxiv_announce_type new的条目debug 模式下只取前 10 条arxiv_retriever.py#L259-L265。转换阶段还会按 tar 源码包 → HTML → PDF 的优先级提取全文PDF/TeX 提取均在子进程中执行并设有硬超时PDF 180 秒、TAR 180 秒超时或失败自动降级见_run_with_hard_timeoutarxiv_retriever.py#L57-L90。Reranker重排插件注册/发现机制与 Retriever 完全同构register_rerankerget_reranker_cls()reranker/base.py#L26-L36两个内置实现locallocal.pysentence-transformers 本地嵌入模型与apiapi.pyOpenAI 兼容嵌入接口打分核心在BaseReranker.rerank()reranker/base.py#L10-L20语料先按加入日期降序排列时间衰减权重为1 / (1 log10(序号 1))并归一化最终得分为(相似度矩阵 × 时间权重).sum(axis1) × 10再按得分降序输出。这个时间衰减公式是整个推荐算法的灵魂Zotero 中第 1 篇论文权重最高第 100 篇的权重约为第 1 篇的1 / (1 log10(101)) ≈ 1/3即近期加入的文献对兴趣画像的贡献显著大于早期文献——因为研究者当前关注的方向往往与最近阅读的文献一致。配置体系Hydra OmegaConf 的组合式配置项目采用 Hydra OmegaConf 管理配置这是 CLAUDE.md 明确点出的技术选型。配置组合方式入口 main.py 通过hydra.main(version_baseNone, config_path../../config, config_namedefault)main.py#L12启动。default.yaml仅做两件事——组合两个配置组default.yamldefaults: - base # 全量配置模板??? 为必填占位 - custom # 用户覆盖层用环境变量插值填充base.yaml定义了全部配置项的默认值与注释说明???表示必须填写custom.yaml则以${oc.env:VAR_NAME,default}语法从环境变量读取实际值例如zotero: user_id: ${oc.env:ZOTERO_ID} api_key: ${oc.env:ZOTERO_KEY} include_path: null email: sender: ${oc.env:SENDER} receiver: ${oc.env:RECEIVER} smtp_server: smtp.qq.com smtp_port: 465 sender_password: ${oc.env:SENDER_PASSWORD} llm: api: key: ${oc.env:OPENAI_API_KEY} base_url: ${oc.env:OPENAI_API_BASE} api_mode: chat_completion generation_kwargs: model: gpt-4o-mini source: arxiv: category: [cs.AI,cs.CV,cs.LG,cs.CL] executor: debug: ${oc.env:DEBUG,null} source: [arxiv]在 GitHub Actions 部署场景中这份custom.yaml的内容会被完整粘贴到名为CUSTOM_CONFIG的仓库变量里作为运行时覆盖层写入从而实现仓库代码 用户秘密/变量的完全解耦。${oc.env:XXX,yyy}语义为取环境变量XXX的值未设置则回退到默认值yyy。配置项全景下表汇总 config/base.yaml 中全部配置参数???为必填配置路径默认值说明zotero.user_id???Zotero 账户的 User ID数字串非用户名zotero.api_key???具有读权限的 Zotero API Keyzotero.include_pathnull参与推荐的 Collection glob 列表如[2026/survey/**]zotero.ignore_pathnull排除的 Collection glob 列表source.arxiv.categorynullarXiv 订阅分类缩写如[cs.AI,cs.CV,cs.LG,cs.CL]source.arxiv.include_cross_listfalse是否纳入 cross-list 条目source.biorxiv.categorynullbioRxiv 分类按站点分类名填写source.medrxiv.categorynullmedRxiv 分类source.chemrxiv.include_new_versionsfalse是否纳入已发布预印本的修订版chemRxiv 无分类过滤每天新预印本约几十篇全量抓取交由重排器筛选email.sender/receiver???发件邮箱 / 收件邮箱email.smtp_server/smtp_port???/???SMTP 服务器与端口如smtp.qq.com:465email.sender_password???SMTP 授权码不一定是邮箱登录密码llm.api.key/base_url???LLM API Key 与 Base URLllm.api_modechat_completionchat_completion或responseResponses APIllm.generation_kwargs.max_tokens16384生成最大 token 数llm.generation_kwargs.model???使用的模型名如gpt-4o-minillm.languageEnglishTLDR 输出语言reranker.local.modeljinaai/jina-embeddings-v5-text-nano-retrieval本地嵌入模型名reranker.local.encode_kwargs{task: retrieval, prompt_name: document}传给SentenceTransformer.encode的参数reranker.api.key/base_url/model/batch_sizenullAPI 型嵌入模型的配置executor.debugfalse调试模式启用更详细日志、缩小数据量executor.send_emptyfalse无新论文时是否仍发送空邮件executor.max_paper_num100邮件中最多呈现的论文数executor.source???论文来源列表如[arxiv,biorxiv,medrxiv,chemrxiv]executor.rerankerlocal使用的重排器local或apiapi_mode与generation_kwargs的语义可在 protocol.py#L12-L36 的_request_llm()中验证chat_completion模式调用openai_client.chat.completions.create(messages...)response模式则调用openai_client.responses.create(input...)并把max_tokens自动映射为max_output_tokens两者都透传剩余的 generation 参数。核心数据结构Paper 与 CorpusPaper两类数据类定义在 protocol.py#L39-L139是贯穿全流水线的类型契约Paper候选新论文携带source、title、authors、abstract、url、pdf_url、可选的full_text、tldr、affiliations与score。它的两个 LLM 增强方法直接在数据类上实现generate_tldr()构造系统提示你是一位完美总结科学论文的助手与用户提示含标题、摘要、全文预览先用 gpt-4o 分词器把 prompt 截断到 4000 token再调用 LLM语言由llm.language控制protocol.py#L52-L96。异常时降级为返回原始摘要generate_affiliations()仅在有full_text时执行要求 LLM 输出按作者顺序排列的 Python 列表、只保留顶层机构、去重随后用正则\[.*?\]提取列表并json.loads解析异常时置为Noneprotocol.py#L98-L133。CorpusPaperZotero 语料论文只包含title、abstract、added_date加入日期用于时间衰减加权和paths所属 Collection 路径列表用于 glob 过滤。在流水线中Executor构造时即创建各来源 Retriever、Reranker 和 OpenAI 客户端OpenAI(api_key..., base_url...)executor.py#L37-L41重排后按max_paper_num截断逐个generate_tldrgenerate_affiliations最后由 construct_email.py 的render_email()渲染、utils.py 的send_email()发送executor.py#L109-L124。测试策略默认跳过慢测试纯 Python stub 即可运行CLAUDE.md 用专节说明了测试策略这是项目工程质量的关键设计慢测试标记标注pytest.mark.slow的测试依赖重型依赖典型如 sentence-transformers 模型下载默认被跳过默认排除机制pyproject.toml中配置addopts -m not slow因此本地uv run pytest默认只跑非慢测试零 Docker 依赖除慢测试外其余测试使用纯 Python stub如 mock Zotero / mock OpenAI 服务器即可运行无需任何容器。测试基建见 tests/utils/mock_openai/含 Dockerfile 与openai_server.py与 tests/utils/mock_zotero/。仓库内已具备覆盖各模块的测试test_executor.py、test_protocol.py、test_utils.py含TestGlobMatch、test_construct_email.py、test_main.py以及 retriever 与 reranker 各自的测试目录tests/retriever/、tests/reranker/其中 tests/retriever/arxiv_rss_example.xml 提供了可离线复用的 RSS 样例数据。常用命令运行、测试与依赖管理CLAUDE.md 给出的命令体系如下项目由 uv依赖声明见 pyproject.toml# 运行应用默认从 config/ 组合 default.yaml 配置 uv run src/zotero_arxiv_daily/main.py # 运行测试默认排除慢测试 uv run pytest # 运行全部测试包括慢测试 uv run pytest -m # 运行单个测试 uv run pytest tests/test_utils.py::TestGlobMatch -v # 安装/同步依赖 uv sync # 带覆盖率运行 uv run pytest --covsrc/zotero_arxiv_daily --cov-reportterm-missing值得注意的实现细节main.py启动时设置TOKENIZERS_PARALLELISMfalse并用dotenv.load_dotenv()加载本地.env文件main.py#L9-L10本地运行时可直接在项目根目录准备.env注入秘密日志级别由config.executor.debug决定DEBUG/INFO并借助loguru输出带颜色与调用位置信息的结构化日志同时把第三方库日志静默到 WARNINGmain.py#L15-L26。项目未配置 linter 或 formatter属于刻意精简的工具链。本地完整运行示例需先按上文表格导出环境变量export ZOTERO_IDxxxx export ZOTERO_KEYxxxx export SENDERabcqq.com export SENDER_PASSWORDxxxx export RECEIVERabcoutlook.com export OPENAI_API_KEYsk-xxx export OPENAI_API_BASEhttps://api.openai.com/v1 uv run src/zotero_arxiv_daily/main.py调试模式与运行边界executor.debug: true是一把双刃剑它一方面把日志级别降到 DEBUG 便于排查另一方面会显著缩小数据规模——arXiv Retriever 只取前 10 个 RSS 条目arxiv_retriever.py#L264-L265本地嵌入模型会保留进度条输出。README 中对应的 GitHub Actions Test-Workflow 工作流正是 debug 版无论日期如何始终抓取少量论文用于验证链路而主工作流每天自动运行、只抓取昨天发布的新论文周末与节假日无新论文时主工作流日志会出现 No new papers found。关于max_paper_numREADME 明确提示其上限受限于 GitHub Actions 运行器配额公共仓库单次 6 小时、私有仓库每月 2000 分钟数值过高会导致执行超时。需要更大吞吐时可考虑自有服务器部署参考 assets/use_docker.md 的 Docker/Compose 方案支持定时执行、日志持久化与模型缓存。扩展指南如何接入新论文源或新嵌入模型结合插件机制扩展点非常清晰新增论文源在retriever/下新建类继承BaseRetriever用register_retriever(你的名字)注册实现_retrieve_raw_papers()返回原始条目列表与convert_to_paper()转为Paper然后在config.executor.source中追加该名称即可新增嵌入方式在reranker/下继承BaseReranker用register_reranker(你的名字)注册只需实现get_similarity_score(s1, s2) - np.ndarray返回候选×语料的相似度矩阵时间衰减加权与排序逻辑由基类免费提供换 LLM无需改代码llm.api.base_urlgeneration_kwargs.model支持任意 OpenAI 兼容端点。可以推断这种注册-发现-模板方法的组合使项目在保持流水线单线推进的前提下将抓什么怎么排序谁生成摘要三个易变点全部开放为配置与插件这是它作为 GitHub Actions 零成本服务仍能保持良好可维护性的根本原因。总结zotero-arxiv-daily 用一个克制而完整的架构回答了如何每天自动推荐感兴趣的论文Executor单线程编排六阶段流水线CorpusPaper/Paper数据类承载全链路类型契约Hydra OmegaConf 把仓库默认配置、用户覆盖配置、环境变量秘密三者干净分离Retriever/Reranker 双插件系统让数据源与排序算法可独立替换时间衰减加权让推荐始终偏向最近的研究兴趣而慢测试默认跳过 纯 stub 可测的策略保障了零成本 CI 的可行性。对希望借鉴订阅制个性化推荐 定时任务 LLM 增强工程范式的开发者来说这份仓库是一份低门槛、可逐行验证的完整参考实现。赞分享人工智能AI 应用RAG科研【免费下载链接】zotero-arxiv-dailyRecommend new arxiv papers of your interest daily according to your Zotero libarary.项目地址https://gitcode.com/GitHub_Trending/zo/zotero-arxiv-daily点击查看免费下载相关推荐如何用Zotero-arXiv-Daily打造专属论文推荐系统每天3分钟获取领域前沿研究如何用Zotero arXiv Daily打造专属论文推荐系统每天3分钟获取领域前沿研究 Zotero arXiv Daily是一款基于Zotero图书馆的a人工智能AI 应用RAG科研【亲测免费】 Zotero-arXiv-Daily每日推荐您感兴趣的 arXiv 论文Zotero arXiv Daily每日推荐您感兴趣的 arXiv 论文 项目介绍 Zotero arXiv Daily 是一个开源项目旨在帮助科研人员跟踪人工智能AI 应用RAG科研如何快速上手FastDeploy5分钟部署你的第一个AI模型如何快速上手FastDeploy5分钟部署你的第一个AI模型 FastDeploy是一个简单易用且高效的深度学习模型部署工具包支持云、移动端和边缘设备涵盖人工智能大模型模型推理服务推理引擎模型量化强化学习本地部署上一篇5分钟搞定专业中文排版霞鹜文楷终极免费字体指南下一篇Syncthing跨平台部署终极指南Windows/macOS/Linux完整教程创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

HowToCook 干锅花菜实战指南:湘味家常菜的标准化做法与火候原理 2026/10/2 21:02:12

HowToCook 干锅花菜实战指南:湘味家常菜的标准化做法与火候原理

文档教程 【免费下载链接】HowToCook Programmers guide about how to cook at home. 项目地址: https://gitcode.com/GitHub_Trending/ho/HowToCook 点击查看 免费下载 干锅花菜是一道湘味家常菜,以脆嫩干香的花菜搭配焦香四溢的五花肉为核心&#xff…

阅读更多 →
SnapOtter权限管理:RBAC角色、17种细粒度权限与API密钥范围完全指南 2026/10/2 21:01:59

SnapOtter权限管理:RBAC角色、17种细粒度权限与API密钥范围完全指南

SnapOtter权限管理:RBAC角色、17种细粒度权限与API密钥范围完全指南 【免费下载链接】SnapOtter Open-source, self-hosted file-processing tool. Convert, compress, OCR, transcribe & run local AI across image, video, audio, PDF & documents, via UI, REST API…

阅读更多 →
FreeRTOS 实战教程-第一章 2026/10/2 21:01:59

FreeRTOS 实战教程-第一章

第一章 FreeRTOS 基础与 CubeIDE 配置 1.1 从裸机到多任务:为什么要用 RTOS 先回顾一下我们写过的 9 个裸机工程,它们几乎都是同一种结构 —— 超级循环(Super Loop): int main(void) {HAL_Init(); /* 各种初始化 */SystemClock_Config();MX_GPIO_Init()…

阅读更多 →
单视频三维重构与无人机蜂群协同侦察阵地态势融合技术白皮书 2026/10/2 21:01:59

单视频三维重构与无人机蜂群协同侦察阵地态势融合技术白皮书

1. 摘要现代化阵地攻防作战呈现立体化、全域化、快节奏、高对抗发展趋势,传统二维视频监控、单机侦察、空地独立感知的态势体系已无法满足全天候、无盲区、连续化的战备感知需求。地面固定视频监控存在维度单一、纵深不足、遮挡盲区泛滥、立体态势缺失等短板&#x…

阅读更多 →
《动手学深度学习》Adadelta 优化算法全解:无需学习率的自适应梯度方法(d2l-zh) 2026/10/2 21:01:59

《动手学深度学习》Adadelta 优化算法全解:无需学习率的自适应梯度方法(d2l-zh)

人工智能深度学习机器学习教程 【免费下载链接】d2l-zh 《动手学深度学习》:面向中文读者、能运行、可讨论。中英文版被70多个国家的500多所大学用于教学。 项目地址: https://gitcode.com/GitHub_Trending/d2/d2l-zh 点击查看 免费下载 Adadelta 是 Ad…

阅读更多 →
南昌市热门的老板桌源头工厂排名及服务好的定制厂家推荐汇总 鑫恒家具 2026/10/2 21:01:59

南昌市热门的老板桌源头工厂排名及服务好的定制厂家推荐汇总 鑫恒家具

南昌选老板桌不想踩坑?这篇源头工厂挑选干货值得看完开篇导语: 老板桌(班台)是办公室里最能体现企业形象的一件家具,但市面上产品鱼龙混杂:板材异味重、封边开裂、大桌进不了电梯、售后没人管……在南昌,江西省鑫恒家具有限公司(…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞 ✉