基于GitHub Actions与arXiv API构建韩语论文摘要聚合器

发布时间:2026/5/17 0:48:46

基于GitHub Actions与arXiv API构建韩语论文摘要聚合器 1. 项目概述一个为韩语社区服务的每日论文摘要聚合器如果你是一名关注前沿技术动态尤其是人工智能、机器学习领域的研究者或开发者并且主要使用韩语进行信息获取那么你很可能遇到过这样的困境每天都有海量的新论文在arXiv等预印本平台发布但要从英文的标题和摘要中快速筛选出自己感兴趣的内容不仅耗时还存在语言门槛。l-yohai/daily_papers_ko这个项目正是为了解决这个痛点而生。它是一个自动化的工具每天抓取特定领域如计算机科学的最新论文将其标题和摘要翻译成韩语并以清晰、易读的格式如Markdown整理发布。本质上它是一个为韩语技术社区量身定做的“每日论文速递”服务。这个项目的核心价值在于“降本增效”。它节省了研究者手动检索、筛选和翻译的时间成本让非英语母语者也能几乎无延迟地触达全球最前沿的研究成果。对于韩国的AI实验室、高校研究团队以及个人爱好者来说这相当于配备了一位不知疲倦的、精通专业术语的翻译和情报整理员。项目名称中的“daily_papers_ko”清晰地揭示了其功能每日论文和目标语言韩语ko是韩语的语言代码。接下来我将从设计思路、技术实现、部署运维到优化扩展为你完整拆解如何构建这样一个系统。2. 核心架构设计与技术选型考量构建一个稳定的每日自动化摘要系统远不止是“抓取-翻译-发布”这么简单。我们需要一个健壮、可维护且容错的架构。整个系统的核心工作流可以概括为定时触发 - 数据获取 - 内容处理 - 格式生成 - 结果发布。2.1 为什么选择服务器less与事件驱动架构对于这种低频每日一次、计算量可控的定时任务采用完全托管式的服务器less架构是性价比和运维复杂度的最优解。我选择GitHub Actions作为调度核心原因如下零成本与易集成对于开源项目和个人使用GitHub Actions提供了充足的免费额度完全满足每日一次的任务需求。它与GitHub仓库原生集成发布结果Markdown文件可以直接提交回仓库形成完美的闭环。强大的生态与可靠性Actions有丰富的社区Action如用于日期处理的actions/github-script和官方维护的虚拟机环境稳定性极高。通过schedule事件可以方便地配置Cron表达式实现定时触发。事件驱动除了定时我们还可以配置在仓库push事件时手动触发工作流方便测试和调试。与之对比自建服务器或使用传统的VPS需要自己维护系统、处理日志和监控对于这个小项目来说属于“杀鸡用牛刀”增加了不必要的运维负担。2.2 数据源与抓取策略解析数据源首选arXiv API。它是一个免费、稳定、无需认证的RESTful API专门为学术论文检索设计。为什么不用爬虫爬arXiv网站使用官方API是更规范、更稳定且对服务器友好的做法。API返回结构化的XML或JSON数据避免了解析HTML的脆弱性也遵守了网站的robots.txt规则。API查询策略我们需要精心设计查询参数。例如可以限定分类为cs.CL计算与语言、cs.CV计算机视觉、cs.LG机器学习等。通过sortBysubmittedDate和sortOrderdescending确保获取最新提交的论文。通常我们每次抓取过去24小时内更新的论文通过API的start和max_results参数控制数量避免单次处理数据量过大。2.3 翻译引擎的选择与权衡这是项目的核心环节也是成本和质量的关键。主要有以下几个选项Google Cloud Translation API翻译质量公认最佳尤其是对学术术语的处理。但它是一项付费服务虽然有免费额度但长期运行需考虑成本。Papago API (Naver)作为韩国本土的顶级翻译服务对韩语的自然语言处理有独特优势尤其擅长韩英互译。对于目标用户是韩语社区的项目Papago是不容忽视的选项。同样需要API Key和面临成本问题。开源大模型本地翻译 (如DeepSeek, Qwen)这是一个新兴且极具性价比的方案。我们可以利用像DeepSeek这样的开源大模型通过其API或甚至在GitHub Actions环境中轻型部署进行翻译。优势是可能成本更低或完全免费取决于调用方式且可控性强。劣势是可能需要更多的提示词工程来保证学术翻译的准确性并且速度可能慢于商用API。混合策略在实际项目中可以采用“缓存降级”策略。为已翻译过的论文标题建立缓存例如存储在一个JSON文件中避免重复翻译。当主要翻译API调用失败或额度用尽时可以降级使用开源模型作为备用方案。注意无论选择哪种翻译服务都必须严格遵守其服务条款和使用限制特别是关于自动化和批量翻译的规定。滥用API可能导致账号被封禁。2.4 输出格式与发布渠道输出格式选择Markdown是自然而然的。它轻量、易读、版本可控并且能被GitHub完美渲染。每日生成的Markdown文件可以按日期命名如2024-05-17.md提交到仓库的docs或papers目录下。发布渠道则与GitHub生态紧密绑定GitHub Pages可以将存放Markdown文件的目录设置为GitHub Pages的源自动生成一个静态网站。这样用户可以通过一个固定的网址如https://[username].github.io/daily_papers_ko浏览每日更新。GitHub Wiki 或 Issue也可以考虑将每日摘要发布到项目的Wiki页面或一个固定的Issue中通过评论追加更新但这两种方式的组织和浏览体验不如Pages。同步到其他平台作为扩展可以通过Webhook将生成的内容同步到Notion数据库、Discord频道或Slack工作空间实现多渠道推送。3. 核心模块实现与实操详解下面我们深入到具体实现环节。我将以使用GitHub Actions arXiv API DeepSeek API作为翻译引擎示例的方案为例拆解关键步骤。3.1 GitHub Actions工作流定义在项目根目录创建.github/workflows/daily-fetch.yml文件。name: Daily Papers Fetch Translate on: schedule: # 每天UTC时间00:01运行对应韩国时间09:01 - cron: 1 0 * * * workflow_dispatch: # 允许手动触发 jobs: fetch-and-translate: runs-on: ubuntu-latest steps: - name: Checkout repository uses: actions/checkoutv4 - name: Set up Python uses: actions/setup-pythonv5 with: python-version: 3.11 - name: Install dependencies run: | python -m pip install --upgrade pip pip install requests feedparser lxml - name: Run the main script env: DEEPSEEK_API_KEY: ${{ secrets.DEEPSEEK_API_KEY }} run: python scripts/fetch_papers.py - name: Commit and push if changes run: | git config --local user.email actiongithub.com git config --local user.name GitHub Action git add docs/ git diff --quiet git diff --staged --quiet || (git commit -m Update daily papers for $(date %Y-%m-%d) git push)关键点解析schedule: Cron表达式1 0 * * *表示每天UTC时间0点1分运行。你需要根据目标读者的活跃时间调整例如让更新发生在韩国时间早晨。workflow_dispatch: 提供手动运行入口便于测试。secrets.DEEPSEEK_API_KEY: 将API密钥存储在仓库的Settings/Secrets中避免硬编码在脚本里保障安全。最后一步的git diff判断这是一个经典技巧。只有当docs/目录下的文件真有变化时才会执行提交和推送避免产生空的提交记录。3.2 论文抓取与解析脚本创建scripts/fetch_papers.py。这里使用feedparser库来解析arXiv的Atom feed它比直接处理HTTP请求更简单。import feedparser import requests import os from datetime import datetime, timedelta import time def fetch_recent_papers(categories[cs.CL, cs.CV, cs.LG, cs.AI], max_results50): 从arXiv API获取最近24小时内指定类别的最新论文。 base_url http://export.arxiv.org/api/query? # 构造查询搜索指定分类按提交日期降序获取最近一天的结果 query OR .join([fcat:{cat} for cat in categories]) yesterday (datetime.utcnow() - timedelta(days1)).strftime(%Y%m%d) params { search_query: f({query}) AND submittedDate:[{yesterday} TO *], sortBy: submittedDate, sortOrder: descending, max_results: max_results, start: 0 } response feedparser.parse(base_url .join([f{k}{v} for k,v in params.items()])) papers [] for entry in response.entries: # 提取arXiv ID arxiv_id entry.id.split(/abs/)[-1] # 标题通常包含换行符需要清理 title entry.title.replace(\n, ).strip() # 摘要也需要清理 summary entry.summary.replace(\n, ).strip() # 提取作者列表 authors , .join(author.name for author in entry.authors) # 论文链接 link entry.link # 主要分类 primary_category entry.tags[0][term] if entry.tags else N/A papers.append({ id: arxiv_id, title: title, summary: summary, authors: authors, link: link, category: primary_category, published: entry.published }) return papers3.3 集成翻译API接下来在脚本中添加翻译函数。这里以DeepSeek API为例。def translate_to_korean(text, api_key): 使用DeepSeek API将文本翻译成韩语。 注意需根据DeepSeek API的最新文档调整端点、参数和模型名称。 if not api_key or not text: return text # 模拟API调用实际请替换为真实的API调用代码 # 例如使用requests库向DeepSeek的聊天补全端点发送请求 headers { Authorization: fBearer {api_key}, Content-Type: application/json } payload { model: deepseek-chat, # 请确认可用模型 messages: [ {role: system, content: 你是一位专业的学术翻译助手擅长将英文计算机科学论文标题和摘要准确、流畅地翻译成韩语。保持术语的准确性语言风格正式、清晰。}, {role: user, content: f请将以下英文文本翻译成韩语\n\n{text}} ], temperature: 0.1, # 低温度保证翻译的确定性和一致性 max_tokens: 2000 } try: # 注意此处为示例URL请替换为DeepSeek API的真实端点 response requests.post(https://api.deepseek.com/chat/completions, jsonpayload, headersheaders, timeout30) response.raise_for_status() result response.json() translated_text result[choices][0][message][content].strip() return translated_text except requests.exceptions.RequestException as e: print(f翻译API请求失败: {e}) # 失败时返回原文避免流程中断 return text实操心得速率限制与批处理无论是DeepSeek还是其他商用API都有速率限制。不要逐篇论文循环调用这既慢又容易触发限流。应该将多篇论文的标题和摘要批量收集一次性发送给支持批量处理的API或者至少在每次请求间添加time.sleep(1)之类的间隔。上下文管理在给大模型的系统提示词中明确其角色和任务要求如“专业学术翻译”、“术语准确”能显著提升翻译质量。对于摘要可以要求它“保持原意的完整性但语言可适当优化使其更符合韩语阅读习惯”。缓存机制实现一个简单的文件缓存如translation_cache.json将(原文MD5, 翻译引擎)作为键翻译结果作为值存储。在翻译前先查缓存命中则直接使用能极大减少API调用量和成本。3.4 生成Markdown与文件管理最后将处理好的数据组装成Markdown格式并写入文件。def generate_markdown(papers, date_str): 生成每日论文摘要的Markdown内容。 lines [] lines.append(f# {date_str} 每日论文速递 (컴퓨터 과학)) lines.append() # 空行 lines.append( 本摘要由自动化工具生成旨在为韩语研究者提供快速参考。翻译由DeepSeek模型提供可能存在细微误差建议结合原文阅读。) lines.append() for i, paper in enumerate(papers, 1): lines.append(f## {i}. {paper[title_ko]}) # 使用翻译后的标题 lines.append() lines.append(f- **원문 제목**: {paper[title]}) lines.append(f- **저자**: {paper[authors]}) lines.append(f- **분류**: {paper[category]}) lines.append(f- **arXiv**: [{paper[id]}]({paper[link]})) lines.append(f- **게시일**: {paper[published]}) lines.append() lines.append(**초록 (번역):**) lines.append() lines.append(f{paper[summary_ko]}) # 使用翻译后的摘要 lines.append() lines.append(---) lines.append() return \n.join(lines) def main(): api_key os.getenv(DEEPSEEK_API_KEY) if not api_key: print(警告: DEEPSEEK_API_KEY 环境变量未设置将跳过翻译步骤。) # 1. 抓取论文 print(正在从arXiv抓取论文...) papers fetch_recent_papers(max_results30) # 控制数量避免翻译负担过重 print(f抓取到 {len(papers)} 篇论文。) # 2. 翻译 for paper in papers: print(f正在翻译: {paper[title][:50]}...) paper[title_ko] translate_to_korean(paper[title], api_key) # 摘要可能较长可以截断前500字符进行翻译以节省token summary_preview paper[summary][:1000] paper[summary_ko] translate_to_korean(summary_preview, api_key) time.sleep(0.5) # 请求间短暂停顿避免速率限制 # 3. 生成Markdown today_str datetime.utcnow().strftime(%Y-%m-%d) md_content generate_markdown(papers, today_str) # 4. 写入文件 docs_dir docs os.makedirs(docs_dir, exist_okTrue) file_path os.path.join(docs_dir, f{today_str}.md) with open(file_path, w, encodingutf-8) as f: f.write(md_content) print(fMarkdown文件已生成: {file_path}) # 5. (可选) 更新索引文件 update_index(docs_dir, today_str) if __name__ __main__: main()4. 部署、优化与扩展实践4.1 初始部署与测试准备仓库在GitHub上创建一个新的公共仓库例如daily_papers_ko。设置密钥在仓库的Settings - Secrets and variables - Actions页面添加名为DEEPSEEK_API_KEY的密钥填入你从DeepSeek平台获取的API Key。提交代码将上述脚本文件fetch_papers.py和工作流文件.github/workflows/daily-fetch.yml以及一个简单的requirements.txt提交到仓库。手动触发测试在仓库的Actions页面找到“Daily Papers Fetch Translate”工作流点击“Run workflow”进行手动触发。这是排查问题最关键的一步。检查结果工作流运行成功后查看是否在docs目录下生成了以当天日期命名的Markdown文件。4.2 性能优化与成本控制技巧选择性抓取不要抓取所有cs分类。根据你的目标受众精选3-5个最相关的子分类如cs.CL,cs.CV,cs.LG。这能减少数据处理量和后续翻译成本。摘要截断论文摘要可能很长。翻译全部摘要成本高昂且对于速览目的前2-3句话通常已包含核心贡献。可以考虑只翻译摘要的前300-500个字符。利用缓存如前所述实现翻译缓存。很多论文标题是常见的组合缓存能避免大量重复翻译。失败重试与降级在GitHub Actions脚本中为网络请求和API调用添加重试逻辑。当主翻译服务失败时可以尝试备用服务如另一个开源模型API甚至直接输出英文摘要并标记“翻译失败”保证日报每日都能生成不影响服务连续性。监控与通知在GitHub Actions工作流中可以添加一个步骤在工作流失败时通过邮件、Slack或Discord Webhook通知你。这能让你及时发现问题并修复。4.3 内容质量提升策略术语表统一建立一个领域关键词的英韩对照术语表例如“Transformer”, “Attention Mechanism”, “Diffusion Model”在翻译后处理阶段用脚本根据术语表进行统一替换保证专业术语的一致性。后编辑Post-editing如果对质量要求极高可以引入轻量级的人工后编辑环节。例如生成日报后自动创建一个包含日报链接的Issue邀请社区贡献者提交翻译修正的Pull Request。添加个性化标签在解析论文时可以根据标题和摘要中的关键词自动打上一些标签如#논문구현,#리뷰,#새로운데이터셋等方便读者快速过滤。4.4 项目扩展方向一个基础的日报生成器运行稳定后可以考虑以下扩展增加其价值多语言支持核心架构是通用的。可以复制一份工作流和脚本修改目标语言和翻译API轻松扩展出daily_papers_ja日语、daily_papers_zh中文等版本。主题分类与订阅不再生成单一的综合日报而是按主题生成多份日报如“每日NLP论文”、“每日CV论文”。用户可以通过关注特定文件或目录来“订阅”他们感兴趣的主题。生成摘要与亮点不仅仅翻译利用大模型的能力为每篇论文生成一段更简短的韩语亮点总结Bullet Points甚至提出1-2个思考问题帮助读者更快抓住精髓。集成到个人知识库将生成的Markdown文件自动导入到你的Obsidian、Logseq或Notion知识库中形成个人化的论文追踪体系。5. 常见问题与故障排查实录在实际运行中你肯定会遇到各种问题。以下是我在搭建类似系统时踩过的坑和解决方案。问题1GitHub Actions 定时任务不运行或运行时间不对。排查首先确认.github/workflows/*.yml文件已正确提交到仓库默认分支。其次GitHub Actions的schedule使用的是UTC时间。如果你设定了cron: 0 9 * * *意思是UTC时间9点运行而不是你本地时间9点。使用在线Cron表达式生成器时要注意时区。解决将你的本地时间换算成UTC时间。例如想让任务在韩国时间上午9点运行KST, UTC9那么UTC时间就是0点Cron表达式应为0 0 * * *。问题2arXiv API 返回空结果或结果不全。排查检查你的查询URL。最常见的问题是submittedDate的范围设置不对。arXiv的日期格式是YYYYMMDD。确保yesterday的计算是正确的UTC日期。另外检查分类名称是否正确arXiv分类是树状结构cs.CV是有效的但cs.ComputerVision无效。解决在脚本中打印出最终构建的查询URL手动在浏览器中访问这个URL查看返回的Atom feed数据是否正常。可以使用print(fQuery URL: {base_url ...})来调试。问题3翻译API调用超时或返回错误导致整个流程中断。排查网络波动、API服务临时故障、达到速率限制、API密钥失效或额度用尽。解决增加超时和重试在requests.post调用中设置timeout30并封装在重试循环中。实现降级方案在try...except块中如果主翻译API失败则尝试调用备用API或者将paper[title_ko]设置为paper[title] (번역 실패)让流程继续。监控成本与额度定期检查翻译服务提供商的控制台设置用量告警。问题4生成的Markdown文件在GitHub Pages上显示为乱码或格式错乱。排查文件编码问题。Windows系统默认编码可能是cp949而GitHub Pages期望UTF-8。解决在Python写入文件时显式指定encodingutf-8。确保Markdown文件开头没有BOM字节顺序标记。问题5GitHub Actions 日志显示“Nothing to commit”即使有新论文。排查这通常是因为翻译缓存机制导致生成的Markdown内容与前一天完全相同例如某天没有新论文或者所有新论文的翻译都命中了缓存。解决这是正常现象不是错误。我们的git diff判断逻辑就是为了避免空提交。如果你希望每天都有一个提交记录即使内容相同可以移除这个判断。但从仓库整洁度考虑保留现有逻辑更好。构建daily_papers_ko这样的项目技术难点并不算高但非常考验系统的稳定性和可持续性设计。核心在于如何以最低的运维成本和资源消耗提供一个可靠、有价值的信息服务。从我的经验来看成功的关键在于精细化的成本控制、健壮的错误处理机制以及对目标社区需求的持续关注和迭代。当你看到每天的日报自动更新并且有用户开始Star你的仓库或通过Issues提出建议时这种自动化创造价值的感觉正是此类项目最大的乐趣所在。

相关新闻