构建自动化技术日报系统:从Hacker News到智能摘要的完整流水线
2026/5/12 17:58:05 网站建设 项目流程

1. 项目概述:一个自动化的Hacker News日报中文摘要生成与发布系统

如果你和我一样,每天都会花点时间浏览Hacker News,但又苦于信息过载,或者想快速获取当天技术热点的精华,那么这个项目“HN Daily Skill”绝对值得你深入了解。它不是一个简单的爬虫或聚合器,而是一个集成了智能摘要生成、格式转换、静态站点构建与自动化发布的完整流水线。简单来说,它能自动抓取Hacker News Daily(一个每日精选HN热门文章的站点)的内容,利用OpenClaw智能体为每篇文章生成结构化的中文总结,最终打包成一份可直接阅读的Markdown报告和PDF文件,并自动发布到GitHub Pages上,形成一个持续更新的技术日报站。

这个项目的核心价值在于“自动化”和“结构化”。它解决了手动筛选、翻译、总结技术文章的高时间成本问题,将原本可能需要数小时的工作压缩到一次自动化的执行流程中。对于技术内容创作者、希望建立个人知识库的开发者,或是团队内部希望同步技术动态的Leader来说,这是一个非常实用的工具。通过剖析这个项目的设计与实现,我们不仅能学会如何构建一个内容自动化流水线,更能深入理解现代开发中CI/CD、智能体集成与静态站点部署的最佳实践组合。

2. 核心架构与设计思路拆解

2.1 双链路设计:草稿与发布的清晰边界

项目最精妙的设计之一在于其清晰的“草稿链路”与“发布链路”分离。这不是简单的代码分支,而是产物级别的严格区分。

  • 草稿链路 (scripts/auto-digest.mjs):这条链路的核心目标是“快速试错”和“数据抓取验证”。它只负责最基础的工作:从HN Daily源抓取指定日期的文章列表和原文内容。生成的Markdown可能只包含原始链接和标题,或者是最初步的、未经深度处理的摘要。这条链路的产物存放在output/目录下,文件名格式为hn-daily-YYYY-MM-DD.md。它不参与任何对外发布流程,仅供内部校验数据源是否正常、抓取逻辑是否正确。
  • 发布链路 (scripts/generate-complete.mjs):这是项目的“主生产线”,也是对外发布内容的唯一权威入口。它基于草稿链路获取的原始数据,调用OpenClaw智能体对每一篇文章进行深度处理,生成包含中文标题、摘要、关键要点和技术洞察的结构化内容。之后,它会进行完整性校验、导出PDF,并最终将成品同步到docs/目录等待发布。其产物命名包含-complete后缀,如hn-daily-YYYY-MM-DD-complete.md

设计思考:为什么需要两条链路?在内容生成类项目中,将“数据准备”和“内容精加工”分离是降低复杂度的关键。草稿链路可以频繁、低成本地运行,用于监控数据源变化或调试抓取规则,而发布链路则因为涉及成本较高的AI调用,需要更谨慎地触发和管理。这种分离也使得项目结构更清晰,职责更明确,后期维护和问题排查时能快速定位是数据源问题还是AI处理环节的问题。

2.2 模块化脚本组织与职责划分

查看scripts/目录,可以看到项目被拆分成多个高内聚、低耦合的模块,这是其能稳定运行的基础。

  1. 入口脚本

    • auto-digest.mjs: 草稿链路的单一入口。
    • generate-complete.mjs: 发布链路的单一入口,协调后续所有环节。
    • daily:pipeline(npm script): 封装了从生成到发布的完整工作流,是自动化调用的推荐入口。
  2. 核心库模块 (scripts/lib/)

    • Provider: 负责与数据源(HN Daily)和AI服务(OpenClaw)的通信。这里封装了HTTP请求、错误重试、速率限制等底层细节,为上层的业务逻辑提供干净的接口。
    • Parser: 解析原始HTML或API返回的复杂数据结构,将其转换为项目内部统一的、易于处理的JavaScript对象。例如,从HN Daily页面中提取文章标题、链接、分数等信息。
    • Prompt: 这是AI生成质量的核心。它定义了发送给OpenClaw智能体的“指令”,确保返回的摘要结构一致(如固定包含“核心要点”、“技术细节”、“启示”等段落)。好的Prompt工程是获得高质量、结构化输出的前提。
    • Renderer: 负责将处理后的结构化数据(文章列表+AI摘要)渲染成最终形态的Markdown报告。它控制着最终输出的排版、样式和元信息(如日期、生成时间戳)的嵌入。
  3. 质量与运维脚本

    • check-completeness.mjs: 发布前的“质量门禁”。它会检查生成的Markdown报告是否完整,例如是否每篇文章都有摘要、关键要点是否非空等,防止半成品被发布出去。
    • sync-pages-and-push.mjs: 发布流程的“最后一公里”。负责将校验通过的-complete产物复制到docs/data/目录,更新站点索引文件,并执行Git提交与推送,触发Pages部署。
    • build-pages.mjs: 构建静态站点所需的资源,例如生成docs/data/index.json索引文件,供前端页面列出所有历史日报。

这种组织方式使得每个脚本功能单一,易于测试和维护。当需要更换AI提供商或调整摘要格式时,你只需要修改对应的ProviderPrompt模块,而无需触动整个流水线。

3. 环境配置与核心依赖详解

要让这个流水线在你的环境里跑起来,需要仔细配置以下几个关键部分。这里我会补充一些原文档未提及的细节和避坑指南。

3.1 Node.js与项目初始化

项目要求Node.js 20+,主要是为了使用稳定的ES模块(.mjs后缀)和一些较新的API。首先克隆项目并安装依赖:

git clone https://github.com/Levix/hn-daily-skill.git cd hn-daily-skill npm install

这里有个细节:npm install安装的依赖可能并不多,因为项目的核心能力依赖于外部的OpenClaw CLI。项目本身的package.json更可能包含的是开发工具(如Markdown/PDF处理库)和脚本运行器。

3.2 OpenClaw CLI与Agent环境配置

这是整个项目的核心依赖,也是最容易出错的环节。OpenClaw CLI是与OpenClaw智能体服务交互的命令行工具。

  1. 安装与验证OpenClaw CLI: 首先,你需要确保openclaw命令在终端中可用。通常可以通过其官方提供的安装脚本或npm包安装。安装后,运行openclaw --versionopenclaw agent --json来验证基础功能是否正常。如果命令未找到,请检查你的PATH环境变量,或将CLI工具放置在项目根目录下。

  2. 理解Agent路由与环境变量: 项目通过环境变量OPENCLAW_AGENT来指定使用哪个智能体。例如OPENCLAW_AGENT=product表示使用名为“product”的智能体。这背后意味着你的OpenClaw服务端配置了不同特长的智能体(如“coding”、“writing”、“analysis”),你需要根据摘要生成的需求选择合适的那个。

    • OPENCLAW_AGENT_ID/OPENCLAW_SESSION_ID: 用于更细粒度的会话控制,在需要保持对话上下文时使用。
    • OPENCLAW_TO/OPENCLAW_CHANNEL: 可能用于指定消息投递的目标或渠道,在复杂的工作流中会用到。实操建议:在项目根目录创建一个.env.local文件(记得加入.gitignore),将环境变量写在这里,然后使用source .env.local或在命令前直接指定。这比每次都在命令行中输入更安全、更方便。
    # .env.local 示例 OPENCLAW_AGENT=analysis OPENCLAW_AGENT_ID=your_agent_id_here
  3. 网络与权限问题: OpenClaw服务可能部署在内网或需要认证。请确保你的运行环境能够访问到OpenClaw服务端点,并且CLI具有有效的认证凭证(可能是API Token或OAuth)。这部分配置通常位于~/.openclaw/config或类似位置,请参考OpenClaw的官方文档。

3.3 GitHub仓库与Pages配置

自动化发布依赖于GitHub的权限和功能。

  1. 仓库推送权限:运行同步脚本 (sync-pages-and-push.mjs) 的机器或GitHub Actions Runner需要对仓库的main分支有写入权限。个人使用通常是配置SSH密钥或Personal Access Token (PAT)。

    • 使用PAT:在GitHub设置中生成一个具有repo权限的PAT。在本地运行脚本时,可以通过git remote set-url origin https://<PAT>@github.com/<username>/<repo>.git来配置远程仓库地址。
    • 在GitHub Actions中:使用actions/checkout动作的token参数即可自动获得对应权限。
  2. GitHub Pages配置: 这是静态站点展示的关键。按照文档,在仓库Settings -> Pages中,选择从main分支的/docs文件夹部署。

    • 重要检查点:确保docs/index.html文件存在且正确。这个文件是站点的入口,它会加载docs/app.js并读取docs/data/index.json来渲染日报列表。
    • 自定义域名(可选):如果你有自己的域名,可以在这里配置CNAME记录,实现个性化访问。

4. 完整流水线实操与核心环节实现

让我们以手动触发一次完整流程为例,拆解每一步发生了什么。假设我们要生成2024-05-20的日报。

4.1 步骤一:启动完整发布流水线

最直接的方式是使用项目预定义的npm脚本:

OPENCLAW_AGENT=product npm run daily:pipeline -- --date 2024-05-20

命令解析

  • OPENCLAW_AGENT=product: 设置环境变量,指定使用product智能体。
  • npm run daily:pipeline: 执行package.json中定义的daily:pipeline脚本。
  • -- --date 2024-05-20: 第一个--用于将参数传递给npm脚本内部的实际命令,--date是脚本接收的参数,指定处理哪一天的数据。HN Daily通常是处理前一天的新闻,所以这里日期要对应。

4.2 步骤二:流水线内部执行流程详解

当你按下回车后,幕后发生了以下一连串操作:

  1. 数据抓取 (collectDailyArticles)generate-complete.mjs首先会调用数据抓取模块,访问https://www.daemonology.net/hn-daily/2024-05-20.html。解析该页面,获取当天HN Daily推荐的8-10篇文章的标题、链接、HN讨论链接和分数。然后,它会逐篇访问原始文章链接,抓取文章的全文内容或主要文本。这一步可能遇到网站反爬、网络超时、页面结构变化等问题,因此代码中必须有健壮的错误处理和重试机制。

  2. AI摘要生成 (OpenClaw agent per article): 这是最耗时也最核心的步骤。对于抓取到的每一篇文章的原文(或主要段落),脚本会构造一个特定的Prompt(提示词),通过OpenClaw CLI调用指定的智能体。Prompt示例(模拟)

    请将以下英文技术文章翻译并总结成中文,要求结构如下: 1. 【中文标题】:提供一个准确、吸引人的中文标题。 2. 【核心摘要】:用一段话概括文章主旨。 3. 【关键要点】:分条列出文章的核心观点或技术细节(3-5条)。 4. 【技术洞察】:分析文章的技术价值、创新点或对开发者的启示。 原文标题:{article_title} 原文内容:{article_content_snippet}

    OpenClaw智能体会根据这个Prompt返回结构化的JSON或文本。脚本的Parser模块会解析这个返回结果,提取出各个字段,存入内存中的数据结构。

  3. 报告渲染与完整性校验 (renderCompleteReport&check-completeness): 当所有文章都处理完毕后,Renderer模块会将所有结构化的文章数据,套用一个Markdown模板,生成一份完整的日报。模板会包含日期、生成时间、目录以及每篇文章的格式化摘要。 生成完Markdown后,check-completeness.mjs脚本会被调用,对这份报告进行校验。它会检查:

    • 文章数量是否与抓取的一致。
    • 每篇文章是否都包含“中文标题”、“核心摘要”等必需字段。
    • 这些字段的内容是否非空或超过最小长度阈值。 如果校验失败,整个流程会中止,避免有缺陷的内容进入后续环节。
  4. PDF导出与产物同步 (export PDF&sync to docs): 校验通过后,脚本会使用类似puppeteermarkdown-pdf的库,将Markdown报告转换为PDF格式,保持排版美观。 接着,sync-pages-and-push.mjs脚本开始工作:

    • *-complete.md*.pdf复制到docs/data/目录,并按日期重命名(如2024-05-20.md)。
    • 更新docs/data/index.json文件,在数组的开头插入新日期的元数据(日期、标题、文件路径),确保最新日报排在前面。
    • 执行git add,git commit,git push将变更推送到远程仓库的main分支。
  5. 静态站点部署 (GitHub Pages): GitHub检测到main分支的docs/目录有更新,会自动启动Pages部署流程。通常几分钟后,访问你的Pages站点(如https://<username>.github.io/hn-daily-skill/),就能在列表页看到新日期的条目,点击即可阅读完整的Markdown或下载PDF。

4.3 核心脚本参数与自定义运行

除了完整流水线,你还可以分步执行,便于调试:

  • 仅生成草稿node scripts/auto-digest.mjs --date 2024-05-20。这步很快,可以用来确认当天HN Daily是否有更新,或者抓取规则是否有效。
  • 仅生成完整报告OPENCLAW_AGENT=product node scripts/generate-complete.mjs --date 2024-05-20。这步会调用AI,生成-complete系列文件,但不会同步到docs/或推送。
  • 手动同步与发布:当你已经有了*-complete.md等文件,可以运行node scripts/sync-pages-and-push.mjs --date 2024-05-20来完成发布。

5. 自动化部署与持续集成策略

项目的自动化程度很高,这主要依靠GitHub Actions和OpenClaw的定时任务(cron)来实现。

5.1 GitHub Actions工作流解析

项目中的.github/workflows/pages-refresh.yml是实现自动化的关键。

# 这是一个简化的逻辑示意 name: Refresh Pages Data on: schedule: - cron: '30 0 * * *' # 每天UTC时间00:30(通常对应北京时间08:30)运行 push: paths: - 'docs/**' - 'output/*-complete.md' - 'scripts/build-pages.mjs' workflow_dispatch: # 支持手动触发 jobs: refresh: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: { node-version: '20' } - run: npm ci - name: Run Daily Pipeline env: OPENCLAW_AGENT: ${{ secrets.OPENCLAW_AGENT }} OPENCLAW_AGENT_ID: ${{ secrets.OPENCLAW_AGENT_ID }} run: npm run daily:pipeline -- --date $(date -d "yesterday" '+%Y-%m-%d') - name: Deploy to GitHub Pages uses: peaceiris/actions-gh-pages@v3 with: github_token: ${{ secrets.GITHUB_TOKEN }} publish_dir: ./docs

工作流解读

  1. 触发时机
    • 定时触发 (schedule): 每天UTC 00:30自动运行,处理“昨天”的数据。这是日报更新的核心自动化。
    • 路径触发 (push): 当docs/output/*-complete.md等关键文件被推送时,也会触发工作流,用于重建站点索引或手动更新后的重新部署。
    • 手动触发 (workflow_dispatch): 在GitHub仓库的Actions标签页,可以手动点击运行,方便测试或补跑数据。
  2. 执行步骤
    • 准备环境(检出代码、安装Node.js、安装依赖)。
    • 关键步骤:运行npm run daily:pipeline,并传入昨天的日期。这里使用了secrets.OPENCLAW_AGENT等环境变量,这些敏感信息需要在仓库的Settings -> Secrets and variables -> Actions中配置,避免硬编码在代码里。
    • 使用peaceiris/actions-gh-pages这个流行的Action,将docs/目录的内容部署到GitHub Pages。

5.2 使用OpenClaw Cron实现更灵活的调度

除了GitHub Actions,项目文档也提到了可以使用OpenClaw自身的cron功能。如果你的OpenClaw环境更稳定,或者希望将整个流水线作为一个任务在OpenClaw平台管理,这会是一个好选择。

在OpenClaw中,你可以创建一个Cron Job,配置类似的命令:

OPENCLAW_AGENT=product npm run daily:pipeline -- --date $(date -d "yesterday" '+%Y-%m-%d')

并设置每天早上的执行时间。这样做的好处是,整个任务执行的环境和OpenClaw智能体调用在同一上下文中,可能网络更通畅,配置更简单。但需要确保该Cron任务运行的机器也能访问GitHub仓库并具有推送权限。

5.3 自动化策略选型心得

在实际部署中,我推荐以GitHub Actions为主。原因如下:

  1. 集成度高:与GitHub仓库无缝集成,代码更新和部署在同一平台,权限管理方便。
  2. 免费额度充足:对于个人项目,GitHub Actions提供的免费计算分钟数完全够用。
  3. 生态丰富:有大量预制的Action(如部署Pages、缓存依赖)可以使用,简化配置。
  4. 日志清晰:执行日志直接在GitHub上查看,非常直观。

将OpenClaw相关的密钥配置为Actions Secrets,既能保证安全,又能让流水线顺利调用AI服务。OpenClaw Cron可以作为备选或用于执行非发布性的、更重型的AI分析任务。

6. 常见问题排查与实战调试技巧

即使设计再完善,在实际运行中也会遇到各种问题。下面是我在部署和运行类似项目时总结的排查清单和技巧。

6.1 页面内容未更新

这是最常见的问题。你运行了脚本,也看到了成功的提交,但网站内容还是旧的。

三层排查法

  1. 检查本地main分支:首先确认你的本地或GitHub上的main分支是否真的包含了新生成的docs/data/2024-05-20.md和更新后的docs/data/index.json。可以直接在GitHub仓库的文件浏览器中查看。
  2. 检查GitHub Actions运行状态:去仓库的“Actions”标签页,查看最新的Refresh Pages Data工作流运行记录。是正在运行、成功、还是失败了?如果失败,点击进去查看具体哪一步报错。
  3. 检查线上索引文件:直接访问你的Pages站点索引文件,如https://levix.github.io/hn-daily-skill/data/index.json。查看这个JSON文件里的最新日期是否更新。如果这里更新了但页面没刷新,可能是浏览器缓存,尝试强制刷新(Ctrl+F5)或清除缓存。

根本原因通常在于

  • GitHub Pages部署延迟:即使Actions显示成功,Pages部署也可能需要1-2分钟才能在全球CDN生效。
  • 工作流未正确触发:检查.github/workflows/pages-refresh.yml中的on.push.paths配置,确保你修改的文件路径匹配。如果你只修改了output/下的文件而没有修改docs/或指定脚本,推送可能不会触发部署。
  • 同步脚本未执行或失败sync-pages-and-push.mjs脚本可能因为前置条件不满足(如缺少-complete.md文件)而静默失败,导致根本没有向docs/目录复制文件。

6.2 AI摘要生成失败

generate-complete.mjs失败时,通常控制台会输出OpenClaw调用相关的错误。

排查步骤

  1. 验证OpenClaw CLI连通性:在终端手动执行openclaw agent --json,看是否能返回有效的JSON信息。如果报错“command not found”或连接错误,说明CLI安装或配置有问题。
  2. 检查环境变量:确认OPENCLAW_AGENT等环境变量是否已正确设置。可以在脚本开头加一句console.log(process.env.OPENCLAW_AGENT)来打印验证。
  3. 检查单篇文章处理:修改脚本,或在调用AI的代码处加入更详细的日志,打印出发送给OpenClaw的Prompt和返回的原始响应。有时是Prompt导致AI返回了非结构化内容,Parser无法解析。
  4. 网络与超时:抓取原文或调用AI服务都可能因网络超时而失败。需要在Provider模块中增加重试逻辑和更友好的超时错误提示。

6.3 完整性检查失败

check-completeness.mjs失败意味着生成的Markdown报告不符合发布标准。

常见原因

  • AI返回内容不完整:某篇文章的AI摘要可能只返回了“标题”,而“关键要点”字段为空字符串或根本不存在。
  • 文章抓取失败:可能某篇原文链接失效或无法访问,导致传递给AI的内容是空的,生成的摘要自然也不完整。
  • Markdown格式错误:渲染器在拼接Markdown时可能产生了非法的语法,导致解析器无法正确识别文章区块。

调试技巧:可以临时修改check-completeness.mjs,让它把检查失败的具体文章和缺失的字段详细打印出来,而不是直接报错退出。这样就能快速定位是哪篇文章、哪个环节出了问题。

6.4 PDF导出问题

如果Markdown生成成功但PDF导出失败,问题通常出在PDF转换工具上。

  • 依赖缺失:如果使用puppeteer(无头Chrome),确保运行环境(尤其是GitHub Actions的Linux环境)已安装所有必要的系统库(如字体库)。
  • 内存不足:转换长文档或并发处理时可能内存溢出。考虑增加Node.js进程的内存限制(NODE_OPTIONS=--max-old-space-size=4096)或优化转换逻辑。
  • 样式丢失:Markdown中的自定义CSS或特殊样式可能在PDF中无法呈现。需要检查PDF转换工具的配置,确保它加载了正确的样式表。

7. 项目扩展与自定义改造思路

这个项目提供了一个优秀的自动化内容流水线框架,你可以基于它进行各种定制,满足自己的需求。

7.1 更换或增加数据源

目前数据源是“Hacker News Daily”。你可以修改scripts/lib/provider.js中的抓取逻辑,使其支持其他优质技术资讯源,例如:

  • Lobsters: 另一个受欢迎的技术新闻聚合站。
  • 特定领域的优质博客/周刊:如Morning Brew(科技商业)、Data Elixir(数据科学)等。
  • RSS订阅聚合:编写一个模块,定期抓取你订阅的一批技术博客的RSS,将新文章作为输入。

关键在于将不同来源的数据,适配成项目内部统一的文章数据结构(包含title,url,content等字段)。

7.2 集成其他AI服务

项目目前深度绑定OpenClaw。如果你想使用OpenAI的GPT、Anthropic的Claude,或国内的通义千问、DeepSeek等模型,需要改造Provider层。

  1. 为新的AI服务创建一个新的Provider类,实现相同的接口(如generateSummary(article)方法)。
  2. 设计针对新模型的Prompt,以获取结构化的摘要。
  3. 在配置中增加一个开关(如环境变量AI_PROVIDER=openai),让主脚本可以动态选择使用哪个Provider。

7.3 输出格式与分发渠道扩展

  • 更多格式:除了Markdown和PDF,还可以考虑生成EPUB(适合电纸书)、纯文本邮件正文、或适合发布到知乎/公众号的富文本格式。
  • 自动发布:在流水线末端,可以集成其他平台的API,实现自动发布。
    • 博客平台:通过GitHub Actions将Markdown自动提交到你的Hugo、Hexo静态博客仓库。
    • 社交媒体:将每日最精华的一两条摘要,通过IFTTT、Zapier或平台API自动发布到Twitter、Telegram频道。
    • 邮件列表:使用邮件发送服务(如SendGrid、Mailchimp)的API,将日报PDF或精华版发送给订阅者。

7.4 增加内容过滤与标签系统

目前的流程是处理HN Daily推荐的所有文章。你可以增加一个“过滤”层。

  • 关键词过滤:只处理包含你感兴趣的技术栈(如“Rust”,“Kubernetes”)的文章。
  • 分数阈值:只处理HN原始分数超过一定阈值的文章。
  • 自动打标:在AI摘要生成后,让AI多做一个任务:为文章打上多个标签(如“前端”、“后端”、“算法”、“创业”)。然后,你可以在静态站点中增加按标签筛选的功能。

改造这样一个项目,最大的乐趣在于将它从一个“别人的工具”,变成完全贴合自己工作流和兴趣的“个人助理”。每一次成功的自动化,都意味着从重复劳动中又解放出来一部分时间。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询