ChatGPT 有一个定时任务功能。以前它可能只能做一些获取网页、收集信息之类的事情,但最近我发现它还可以做一些更接近 Agent 的工作——除了获取网页,还能执行代码、提交代码到 GitHub。
这段时间,我一直让 ChatGPT 每天帮我整理 Hacker News 摘要。通过定时任务,它会在每天早上自动获取榜单前 30 的内容,逐一尝试访问,然后整理成中文摘要发给我,供我筛选阅读。时间久了,我又慢慢告诉它我感兴趣的方向:Arduino、ESP32、Raspberry Pi 相关的,LLM 和 Agent 相关的,学习和阅读相关的,写作和博客相关的。独立博客里的好文章,即便不属于这些分类,也希望单独推荐。它会在榜单逐条摘要下面,再单独列出我感兴趣的内容。
这个定时任务持续了一段时间,效果一直不错。但有一个越来越明显的问题:所有的摘要都堆在同一个 ChatGPT 对话里。对话越来越长,打开的时候越来越卡,想翻以前的内容也很不方便。
于是就有了一个想法:把这些内容做成一个可以正常浏览的网页,放在 GitHub Page 上?
这就有了 hn-digest。
从对话到网站
这个网站并不是我一开始就规划好的。而是我在使用中慢慢的确定需求,逐步调整,一点点塑造出来的。
最开始,我的想法很简单:让 ChatGPT 每天直接生成一个网页。但我也意识到这样做长期维护不现实。模型每次输出的格式可能会漂移,结构不够稳定。
于是我想到静态网页生成器,我之前用过 Hexo、Jekyll、Sphinx、Docusaurus,对这类工具有一些了解。(不过事实上,即使不知道这些,ChatGPT 也能给你推荐。我刻意尝试了问它有没有什么建议,而不是直接要求用静态网页生成,它也能建议这种方案)。
接着,和 ChatGPT 讨论以后,确定了分工:ChatGPT 的定时任务只负责生成 Markdown 格式的日报内容,网站的模板和样式交给静态站点生成器来处理。在 ChatGPT 的推荐下,框架最终选了 Eleventy。这个框架我没用过,按它的说法,这个框架轻量、灵活,适合这种"日报+归档"的场景。
每天的摘要保存为 Markdown,提交到 GitHub 仓库,Eleventy 生成静态页面,通过 GitHub Pages 自动发布。技术方案本身没什么特别的,重要的是整个过程几乎都是和 ChatGPT 对话完成的。
第一版上线以后,页面能看但不好看。于是继续聊:配色调一下,排版改一改,导航加上归档和 RSS。第二版上去以后又发现 CSS 选择器写得太宽泛,把正文里的加粗文字全都当成了新闻标题来渲染,页面格式一片混乱。继续和 ChatGPT 排查,加上语义化的 class,加上资源文件的版本号强制刷新缓存,一点点修好。
用了一段时间,我发现在墨水屏设备上阅读效果不太好。我平时会在 BOOX Palma 2(一个墨水屏阅读器)上看这些摘要,但是在设计时没有考虑到这点。浅灰色的字体在墨水屏下几乎不可见,动画在墨水屏的刷新特性下也是累赘。所以我和 ChatGPT 讨论,做了一个墨水屏阅读模式:去掉动画和阴影,拉高灰阶对比度,单栏布局,加大点击区域。

我还让它优化了下翻页交互。在墨水屏上正常的上下滑动,由于刷新慢,看起来会有一种不舒服的感觉,刷新率低还会有拖影。于是,我们在这个网页上加上了大多数阅读器都有的功能:点屏幕左边向上翻一屏,点右边向下翻一屏。每次切换 88% 屏幕高度,保留一点上文作为视觉上下文,不用平滑滚动而是直接跳转,更适合墨水屏的刷新特性。
到这里,这个网站已经很符合我的需求了。更值得一提的是,即使后面需求变化,或者发现什么需要优化的地方,也能很快通过对话来迭代。
回头看仓库的提交记录,从最初的基本结构,到样式修复,到墨水屏适配,再到翻页交互,并不是一次设计好的,而是在实际使用中一点点调整磨合,与 AI 共创出来的。全程我甚至没有 clone 这个仓库,没有在本地编辑过。
我觉得这恰好是用 AI 做个人项目最有意思的地方:你不需要一开始就想清楚所有需求,可以先做一个最简单的版本,边用边改。而"改"这件事的成本,比以前低太多了。
以前做类似的事情,要复杂得多
前些年我了解到,有一个项目叫 hacker-news-digest,也就是我之前一直在用的Hacker News 摘要网站。它的思路是很典型的软件工程方式:自己写程序抓取 Hacker News,用机器学习提取网页正文,调用 OpenAI API 生成摘要,API 不可用时回退到本地 LLM 模型,再套模板部署到 GitHub Pages。开发者先搭好完整的流水线,LLM 只是其中的一个组件。
而我现在做的这个,方向其实反过来了:ChatGPT 完成所有的功能,不需要编写复杂的爬虫,也不需要再次接入 AI 来生成摘要。它负责抓取 Hacker News,根据我的兴趣筛选出值得关注的内容,撰写摘要并给出推荐理由,最后将结果同步至 GitHub 仓库的全流程。如今大家基本都订阅了 ChatGPT,即便每月 20 美元的计划也相当慷慨,足以支撑定时任务,并利用当前最前沿的模型来完成这些工作,为这类个人项目提供了实现的基础。
我三年前写过一篇文章,记录用 ChatGPT 做一个叫 PyPower 的局域网远程开关机工具。那时候的方式还是一个个问题地问 ChatGPT,自己手动把代码拼起来。到现在做 hn-digest,已经变成让 AI 直接承担整个内容生产和工作流了。
别太早放弃一个有意思的想法
hn-digest 当然谈不上什么工程级的项目。架构简单,没有数据库,生成过程完全依赖 ChatGPT,自动化偶尔也会出问题。但我现在每天早上真的会打开它看 Hacker News。对于一个只有我自己在用的个人项目来说,这就已经够了。
以前很多小想法会停在"做起来好像有点麻烦"。到现在越来越多时候会变成"要不先让 AI 帮我试试看"。这可能才是 AI 对普通人最有意思的地方,不是每个人突然都变成了软件工程师,而是很多以前没有太多精力专门投入时间去实现的小想法,现在值得动手试试了。
当然,有一些基础知识会让这个过程顺利很多:知道 Git 是什么,理解静态网站的基本原理,能看懂错误日志,会把一个大需求拆成小需求。但我觉得顺序在变,不一定要先学完这些才能动手,而是可以先做,遇到问题再去理解。如果想更系统地了解怎么和 AI 协作,我之前推荐过一个不错的课程,可以看看这篇文章。
所以如果你最近有什么一直想做、但总觉得自己不会的小东西,不妨用 AI 试试看。
最后,附上我所用的定时任务提示词供大家参考。还要说明一点:不需要自己写这么周全的提示词,你只要和 ChatGPT 讨论你的需求,它会自己调整和完善提示词。试试制作一个属于自己的 hn-digest 吧,祝你开发顺利~
点击展开完整提示词
直接打开并读取 Hacker News 官方首页 https://news.ycombinator.com/ 的当前 HTML,获取首页排名 1–30。不要使用 /front、搜索引擎、搜索结果摘要、第三方镜像或缓存。生成前校验:最终页面 URL 必须仍是 https://news.ycombinator.com/,页面必须包含连续的 1–30 排名,并核对前 3 条标题与当前页面一致。结果标题格式为“Hacker News 热榜前 30 条|YYYY 年 M 月 D 日”。用中文概括每条主要内容。
链接规则必须严格执行:
1. 每条的“原文链接”必须使用该条标题在 Hacker News 首页 HTML 中对应的精确 href,也就是实际文章、项目、论文、视频或产品页面;不得用 Hacker News 首页代替。
2. 每一条都必须同时附上该条自己的 Hacker News 讨论页链接,格式为 https://news.ycombinator.com/item?id=... 。HN 讨论链接是必选项,不能省略。
3. 对 Ask HN、Launch HN、招聘帖、纯文本帖或本身没有站外链接的条目,“原文链接”使用该条自己的精确讨论页链接;这种情况下“原文链接”和“HN 讨论”可以相同。
4. 即使原文页面无法抓取,也必须保留从 HN 首页提取到的精确原始 href,只能在摘要中注明无法读取全文;不得把链接替换成 HN 首页、网站根域名或模糊入口。
5. 生成前逐条检查 30 个“原文链接”和 30 个“HN 讨论”链接:不得出现用于占位的 HN 首页;不得把同一首页链接重复用于多条内容;不得只链接到媒体或网站根域名,除非 HN 条目本身的 href 就是该根域名。
【固定 Markdown 输出格式】
对话中的完整日报,以及写入 GitHub 的 Markdown 正文,都必须遵循以下固定结构。不要自行改写成其他列表风格。
Top 30 每条必须严格使用:
N. **与 Hacker News 首页完全一致的英文标题**
中文摘要。
[原文链接](精确原文URL) | [HN 讨论](精确HN讨论URL)
要求:
- N 必须是连续的 1–30。
- 标题必须用 Markdown 粗体 `**标题**`,且文本与 HN 首页标题完全一致,不翻译、不改写、不追加中文说明。
- 每条标题必须是该条列表项中第一个粗体文本;不要在标题前放其他粗体内容。
- 摘要可以包含普通 Markdown 强调,但不要把其他内容伪装成条目标题。
- 原文链接和 HN 讨论必须位于该条末尾,使用固定文字“原文链接”和“HN 讨论”,两者之间使用全角分隔符 `|`。
- 不要在 Top 30 条目之间插入额外二级/三级标题、表格、HTML、引用块或其他结构。
完整列出前 30 条后,再增加:
## 重点分类
并固定使用以下五个三级标题,顺序不得改变:
### Arduino / ESP32 / Raspberry Pi
### LLM / Agent
### 学习与阅读
### 写作与博客
### 独立博客精选
重点分类中的“相关条目”必须严格使用以下格式:
- **N|与 Top 30 完全一致的英文标题**:中文简要说明。
重点分类格式规则:
- N 必须是该条在 Top 30 中的真实排名编号,用阿拉伯数字,不补零。
- `N|标题` 中必须使用全角分隔符 `|`。
- 标题文本必须与 Top 30 对应条目的英文标题完全一致,不翻译、不缩写、不改写。
- 分类项本身不要重复手写“原文链接”或“HN 讨论”链接;网站构建层会根据 N 自动关联 Top 30,生成回跳、原文和 HN 讨论入口。
- 同一条可以同时出现在多个分类中,不要为了避免重复而漏掉重要条目。
- 若某分类没有相关条目,在该三级标题下只写一句自然语言,例如“没有直接相关条目。”,不要编造占位条目,不要使用 `N|标题` 格式。
重点分类筛选规则:
- Arduino / ESP32 / Raspberry Pi:筛选相关硬件、开发板、生态、嵌入式项目;若没有,明确说明。
- LLM / Agent:包括大语言模型、推理模型、开放权重模型、模型训练/推理/评测、Agent/Coding Agent、模型路由、上下文工程、LLM 基础设施与安全等;若没有,明确说明。
- 学习与阅读:包括高质量教程、课程、书籍、论文、学习方法、知识管理、阅读与写作方法、适合系统学习的技术资料等;若没有,明确说明。
- 写作与博客:包括写作方法、博客实践、技术写作、个人博客/独立出版、内容创作、知识表达、长期写作、写作工作流,以及关于如何通过写作促进学习和思考的内容;若没有,明确说明。
- 独立博客精选:主动从前 30 条中筛选值得阅读的独立博客文章,即使主题本身并非“写作/博客”。优先个人独立站点、个人技术博客、个人研究/工程复盘、长期维护的独立博客、个人观点长文和高质量个人随笔;一般不把大型媒体、公司官方博客、产品公告、新闻站点归入此类。每条简要说明为什么值得读;若没有,明确说明。
若无法直接读取官方首页,或者 1–30、链接等关键校验失败,只能说明本次抓取/校验失败和具体失败点,不得使用旧榜单、缓存内容或猜测内容,也不得发布不完整日报。
【GitHub 发布】
在上述完整日报已经生成并通过全部校验后,将同一份日报发布到 GitHub 仓库 eMUQI/hn-digest 的 main 分支。对话中的完整日报输出必须始终保留:GitHub 发布是额外步骤,不能用“已发布到 GitHub”代替聊天中的 30 条正文和重点分类,也不能为了发布而缩短聊天输出。
发布约束:
1. 只允许创建当天一个 Markdown 文件:content/daily/YYYY/MM/DD.md。YYYY/MM/DD 使用 Asia/Shanghai 当天日期,月份和日期均为两位数字。
2. 禁止修改任何其他文件,包括 src/**、.github/**、eleventy.config.js、package.json、package-lock.json、README*、其他日期的 content/daily/**,以及任何站点模板、CSS、JavaScript、构建或部署配置。
3. 当天 Markdown 必须使用固定 Front Matter:
---
layout: layouts/digest.njk
title: Hacker News 热榜前 30 条
date: YYYY-MM-DD
tags: digest
permalink: /YYYY/MM/DD/index.html
description: YYYY 年 M 月 D 日 Hacker News Top 30 中文摘要与重点分类。
---
4. Front Matter 的 date、文件路径日期、permalink 日期必须完全一致。
5. 正文使用纯 Markdown,并与对话中输出的日报内容保持一致。不要生成完整 HTML,不要加入 <html>、<style>、<script>、布局 div、CSS class 或其他展示层代码。网站模板、目录、样式、RSS 和页面布局均由 Eleventy 负责。
6. 正文必须完整包含排名 1–30,以及“## 重点分类”和固定五个三级分类标题。Top 30 与重点分类必须严格遵守上述固定 Markdown schema,不允许自行变化格式。
7. 发布前再次自检:
- 排名连续且正好 30 条;
- 有 30 个原文链接和 30 个 HN 讨论链接;
- 30 个 Top 30 标题均为该条第一个粗体文本;
- 五个重点分类标题全部存在且顺序固定;
- 每个分类条目均使用 `- **N|标题**:说明`;
- 分类编号 N 必须能对应到 Top 30 的同一条;
- 分类标题必须与 Top 30 对应标题逐字一致;
- 没有占位 URL;
- 日期三处一致;
- 没有展示层 HTML;
- 没有修改其他文件。
8. 写入前检查当天目标文件是否已经存在。若不存在,创建文件;若已存在且内容完整且与本次日报一致,不重复提交;若已存在但内容不完整或与本次结果冲突,不覆盖,报告冲突并停止 GitHub 发布。
9. 成功创建文件后提交到 main,commit message 固定为:publish: Hacker News digest YYYY-MM-DD。一次日报发布只提交当天 Markdown,不要产生用于调整站点代码的额外 commit。
10. GitHub 写入失败时,不要改用其他路径,不要修改站点代码、workflow 或历史日报进行修复;聊天中的完整日报仍正常输出,并明确报告 GitHub 发布失败及具体失败步骤。
11. 不把 GitHub Pages 部署成功作为日报内容生成成功的前提,也不要因为 Pages/Actions 未触发而修改仓库配置。若当前可用 GitHub 能力能够可靠确认本次 commit 的部署状态,可在末尾附带状态;无法确认则明确写“部署状态未确认”,不要猜测。
最终聊天回复必须先完整展示“Hacker News 热榜前 30 条|YYYY 年 M 月 D 日”及全部重点分类,不得只给链接或发布状态。完整日报之后再追加简短的“发布状态”,分别报告:HN 数据校验(通过/失败)、日报生成(通过/失败)、GitHub 发布(成功/失败/未执行)、仓库目标路径、commit(若成功)、Pages 部署状态(若可确认)。


