跳到正文
原文
Simon Willison·· 3 小时前AI 评分59

Simon Willison 用 Codex 语音模式做出博客 Newsletter 索引页

A new feature for my blog, built using my voice

AI 导读

Simon Willison 用 ChatGPT 桌面端 Codex 的语音模式,几乎全程靠说话为博客上线了汇总每周免费 Substack 与每月赞助者通讯的 Newsletter 索引页。

正文 · AI 翻译

9th October 2026

我今天为我的博客发布了一个新功能:Newsletters 页面,它索引了我发出过的所有新闻通讯,既包括我的免费 每周 Substack,也包括我的 每月仅限赞助者 更新。我几乎完全用语音做完了这个功能,一边做晚饭一边对着笔记本电脑聊天。

Codex 语音模式

我用的是 ChatGPT 桌面应用,在 Codex 标签页里,使用语音对话模式,对着本地开发环境运行。它看起来是这样的:

Three columns of the ChatGPT app. The left hand column shows my recent conversations. The middle column is a transcript of the conversation, with a throbbing black blob representing voice mode. The right hand column shows a local dev server version of my blog, with the Newsletters page visible.

我针对本地的 simonwillisonblog 检出启动了这次会话,输入的是:

Start dev server and open in browser

这让我预览了它将要处理的站点,也意味着我之后可以让它把新页面展示给我,从而直观地跟踪它的进度。

然后我点击了“Start new voice chat”按钮——那不是麦克风按钮,而是它右边的那个——并把笔记本电脑架在厨房里,这样我做饭时就能跟它说话。

跟我的电脑说话

我很清楚自己想构建什么,而且这是一个足够简单的 Django 功能,我确信这个模型(这里是 GPT-6 Astra High)能够完成。一个新模型、一次迁移、一些视图代码、若干模板,以及几个从外部来源填充数据库的导入函数。

以下是 Codex 捕获的我的语音转录摘录:

嗯,它们不会。嗯,这将是一种新的内容类型。嗯,它不会显示出来……哦,等一下。对,不——我不希望它出现在我的,嗯,标签页和日期归档页以及……其实,不,我想……我不希望它出现在标签页上。我不希望它出现在,嗯,博客索引页上。但我想我确实希望它出现在按日期的页面上。你知道,如果你导航到 September the 19th,而我在那一页发过一份新闻通讯,我想我希望它显示出来。所以……这是——所以我想我们大概需要一个新模型。另一件事是我希望它们可搜索,呃 Substack 那些不可搜索,因为那些实际上只是我博客上其他 s- 内容的副本。这些每月的确实包含独特内容,而且 spe- 而且一旦它们……发布,也就是在发出一个月后被公开,我希望它们出现在我的搜索结果里。

显然这已经足够清楚,模型知道我想构建什么!你可以阅读完整转录,不流畅之处一应俱全,就在这个 Gist 里。

我们就这样持续了大约半小时(做晚饭所用的时间)。模型会回复,偶尔提出澄清问题,然后着手修改代码。

我们构建了什么

我们完全靠语音就推进到了出人意料的程度:

  • 一个新模型和迁移,用于在 Django 中表示导入的新闻通讯,外加相应的 Django Admin 配置
  • Four working imports:
    • 通过 RSS 获取的最新 Substack 条目
    • 通过其未公开的 API 获取的其余所有 Substack 条目,GPT-6 Astra 要么本来就知道,要么是通过搜索找到的
    • 我已发布的全部每月新闻通讯,来自我的 simonw/monthly-newsletter-archive GitHub 仓库
    • 来自一个私有仓库的、我最新的仅限赞助者私密新闻通讯
  • 公开归档页面 /newsletters/ 和 /newsletters/2026/
  • 新闻通讯也会出现在按日和按月的归档页上,但不会出现在标签页或我的主页上
  • 每周 Substack 新闻通讯链接到 Substack;已归档的每月新闻通讯则有自己的页面
  • 与我的站点搜索引擎集成

它几乎可以发布了。问题出在导入上:Astra 提出从我的本地副本导出数据,以便我将其导入生产环境,但我希望它能像我的其他导入脚本一样工作。由于部分数据存放在一个私有 GitHub 仓库中,这就需要创建一个新的 API 密钥,而我知道为此我得在键盘前坐上一会儿。

通过审查来收尾

等我做完饭,并判断它大体上功能已完备后,我让 Codex 创建了一个分支并打开了一个 pull request。

我在 GitHub 的 PR 界面中审查了代码。它几乎就是我需要的,只不过它选择在其中一个导入脚本里通过子进程使用 Git。我需要其中一项导入从私有 Git 仓库拉取内容,所以我认为 API 会是更好的选择。于是我改用打字,让 Codex 把它换成基于 API 的导入。

你可以查看我在审查期间所做的更改,就在该 PR 的额外提交里。我修复了导入机制,并对那些公开页面的展示做了几处调整。又花了半小时基于打字的提示,才到我乐意通过合并该 PR 将其部署到生产环境的地步。

最终结果

你可以在新的新闻通讯索引页看到最终结果,或者查看以往月度新闻通讯的页面。

Newsletters page. It shows two Substack posts (with thumbnails) and one LLM digest Sponsors-only newsletter with a list of headings. On the right is a CTA to subscribe to my Substack and another one for my $10/month monthly briefing newsletter.

索引页将我最近的 Substack 每周新闻通讯和 GitHub sponsors 每月新闻通讯混合在一起,按时间倒序排列。页面再往下是指向我按年份归档页面的链接。

GPT-6 Astra 设计了这个页面,然后根据我隔着厨房瞥了一眼本地预览后给出的语音反馈,对设计做了调整。

更适合多任务处理,而非作为日常主力工具

OpenAI 喜欢在DevDay 之类的场合使用这样的语音驱动演示——而且它们在那种环境中确实效果很好。不过我不认为这会成为我的日常主力工具。

我以前写过,遛狗时用手机上的 ChatGPT 语音模式能完成多少“工作”——主要是研究和头脑风暴,但偶尔也会通过让 ChatGPT 编写并测试代码片段来做实际的开发工作。

这次感觉不一样。加上可视化预览,以及在需要传达语音说不清楚的内容时可以用键盘输入或粘贴,这让与编程代理交互的方式强大了许多。

不过一旦落到细节上,我还是会切换回打字。能够粘贴示例和错误信息,或者直接标出需要修改的代码或功能,仍然比试图用言语描述更高效。

我主要在家工作,这倒是好事,因为我绝不会想在共享工作空间里这样跟电脑说话!

对我来说,杀手级功能是能够多任务处理。我通常做饭时开着播客或 TikTok;现在我可以真正动手做东西了。

来源:Simon Willison · simonwillison.net