Simon Willison 用 Codex 语音模式构建博客 Newsletters 页面
A new feature for my blog, built using my voice
Simon Willison 今天为博客上线了 Newsletters 页面,该功能几乎全部通过 ChatGPT 桌面端 Codex 语音模式(GPT-6 Astra High)在做饭的约半小时内口述完成。
作者完整记录了用 Codex 语音模式配合本地预览驱动编码智能体的过程,读者可据此判断该模式是否适合自己的多任务开发场景。
2026年10月9日
今天我为我的博客上线了一个新功能:Newsletters 页面,它提供了我发出的所有通讯的索引,包括我免费的 每周 Substack 和我的 每月赞助商专属 更新。这个功能几乎完全是我用语音完成的,一边做晚饭一边对着笔记本聊天。
Codex 语音模式
我使用 ChatGPT 桌面应用来完成这件事,在 Codex 标签页中,使用语音对话模式,针对本地开发环境运行。它是这样的:

我先通过输入以下命令,针对本地的 simonwillisonblog 检出副本启动了会话:
Start dev server and open in browser
这让我预览了它将要处理的网站,也意味着我之后可以要求它向我展示新页面,从而直观地跟踪它的进度。
然后我点击了“开始新的语音聊天”按钮——那不是麦克风按钮,而是它右边的那个按钮——并把笔记本放在厨房里,这样我就可以一边做饭一边和它说话。
和我的电脑对话
我很清楚自己想要构建什么,而且这是一个足够简单的 Django 功能,所以我确信模型(在这个例子中是 GPT-6 Astra High)能够完成它。一个新模型、一个迁移、一些视图代码、模板,以及几个从外部来源填充数据库的导入函数。
以下是 Codex 捕获的我的语音转录片段:
嗯,它们没有。嗯,这将是一种新类型的内容。嗯,它不会显示出来……哦,等等。是的,不——我不希望它出现在我的,嗯,标签页面和日期归档页面上,而且……其实,不,我觉得……我不希望它出现在标签页面上。我不希望它出现在,嗯,博客索引页面上。但我认为我确实希望它出现在基于日期的页面上。你知道的,如果你导航到 9 月 19 日,而我在那一天发了一篇通讯,我希望它能显示出来。所以……这——所以我觉得我们可能需要一个新模型。另一件事是我希望它们可被搜索,呃,Substack 的那些不可搜索,因为它们实际上只是我的博客上其他内容的副本。这些每月的内容确实包含独特的内容,而且,一旦它们……被发布,比如在发出一个月后被公开,我希望它们能出现在我的搜索结果中。
显然,这段表述已经足够清晰,模型知道我想构建什么!你可以阅读完整的记录,包括不流畅之处等等,在这个 Gist 中。
我们就这样继续了大约半个小时(也就是做晚饭花的时间)。模型会作出回答,偶尔提出澄清性问题,然后开始修改代码。
我们构建了什么
仅仅依靠语音,我们出乎意料地推进了很远:
- 一个用于在 Django 中表示导入的 newsletter 的新模型和迁移,以及相应的 Django Admin 配置
- Four working imports:
- 通过 RSS 获取最新的 Substack 内容
- 通过其未公开的 API 获取其余所有 Substack 内容——GPT-6 Astra 知道这个 API(它直接尝试了
/api/v1/archive),随后进行搜索以弄清如何分页,并找到了 Karen Spinner 写的这篇文章 - 我的 simonw/monthly-newsletter-archive GitHub 仓库中所有已发布的月度 newsletter
- 我最近的仅限赞助者查看的私有 newsletter,来自一个私有仓库
- /newsletters/ 和 /newsletters/2026/ 公开存档页面
- Newsletter 也会出现在按日和按月的存档页面上,但不会出现在标签页面或我的主页上
- 每周的 Substack 简报会链接到 Substack;归档的每月简报有各自的页面
- 与我网站的搜索引擎集成
它几乎已经可以发布了。问题在于导入:Astra 提议从我的本地副本导出数据,这样我就能把它导入到生产环境,但我希望它的工作方式和我其他的导入脚本一样。由于部分数据存放在一个私有的 GitHub 仓库里,这就需要创建一个新的 API 密钥,而我知道为此得在键盘前坐上一阵子。
以一次审查收尾
等我完成“烹饪”并判定它基本功能完备后,我让 Codex 创建了一个分支并发起了一个 pull request。
我在 GitHub 的 PR 界面里审查了代码。它几乎正是我需要的,只不过其中一个导入脚本它选择了在子进程中使用 Git。我需要其中一个导入从私有 Git 仓库拉取数据,所以我觉得用 API 会更靠谱。我切换回打字,让 Codex 把它换成基于 API 的导入方式。
你可以在 PR 的额外提交中看到我在审查时所做的修改。我修复了导入机制,并对这些公开页面的展示做了一些调整。又花了半小时基于打字的提示,才达到让我满意并可以通过合并 PR 部署到生产环境的程度。
最终成果
你可以在新的简报索引页看到最终成果,或者查看某期往期每月简报的页面。

索引页按时间倒序混合展示了我最近的 Substack 每周简报和 GitHub sponsors 每月简报。页面更下方是我按年份归档页面的链接。
GPT-6 Astra 设计了这个页面,然后根据我在厨房里瞥一眼本地预览后给出的语音反馈调整了设计。
更适合多任务处理,而不是作为日常主力
OpenAI 很喜欢在DevDay 之类的场合使用这样的语音驱动演示——而且它们在这种环境下确实很有效。不过我觉得它不会成为我的日常主力工具。
我之前写过,遛狗时用手机上的 ChatGPT 语音模式能完成多少“工作”——主要是研究和头脑风暴,但偶尔也会做些真正的开发工作,让 ChatGPT 编写并测试代码片段。
这次的感觉不一样。加入了可视化预览,再加上当我需要表达一些语音说不清的东西时可以用键盘输入或粘贴内容,这让与编码智能体的交互变得强大得多。
不过一旦深入到细节,我还是会切换回打字。能够粘贴示例和错误信息,或者直接高亮需要修改的代码或功能,仍然比用文字描述更高效。
我主要在家办公,这挺好的,因为我绝不想在共享办公空间里这样跟我的电脑说话!
对我来说,杀手级功能是多任务处理。我做饭时通常会放播客或刷 TikTok;现在我可以真正动手做点东西了。
来源:Simon Willison · simonwillison.net