Skip to content

资料库 ⑤ · 编辑器、工具链与工程实践

第 81–100 条 · 共 20 条 · 来源:Simon WillisonVS Code Updates · 时间跨度 2026-01 至 2026-08-19

前四卷都围着 LLM 和 agent 转,这一卷把镜头拉开:2026 年这半年多,日常工具链本身发生了什么。

选的是 Simon Willison 2026 年那些不以 AI 为主题的文章,加上 VS Code 的最新一版发布说明。收录理由是这些变化影响的是你每天都在碰的东西——怎么打包、怎么沙箱、怎么部署、怎么防供应链攻击、编辑器怎么和 agent 配合。这些不上头条,但改变你日常工作的程度可能超过任何一次模型更新。

按时间排。最后一条(第 100 条)是这个资料库全部 500 条的收尾,日期是 2026 年 8 月 19 日——截止日期的前一天。

关于时效

这一卷 会过期 的比例较高,因为涉及具体的版本和工具状态。但里面几条关于打包生态所有权供应链攻击手法沙箱技术路线的判断,影响是长期的。

2026 年 1—2 月:静态托管、沙箱与可检视的产出

81. Introducing gisthost.github.io

来源:Simon Willison,2026 年 1 月 1 日。会过期

读它解决什么:怎么用最低的成本把一段 HTML 放到网上。

要点

  • 一个把 GitHub gist 里的内容当网页托管的服务
  • 思路是复用已有的基础设施(gist + GitHub Pages),不自建后端

我的补充:这一条的实际价值在于它把"我想给别人看一个能跑的东西"的成本压到了接近零

这个需求在有了 agent 之后突然变得高频:让 agent 写个小工具、做个可视化、生成一个演示页面,然后你需要把它变成一个能发给别人的链接。以前这一步的摩擦不小(起个项目、配部署、买域名),现在几分钟就完事。

我自己在用的同类方案,按摩擦从低到高排:

  • gist + 这类托管服务 —— 最快,适合单文件的一次性演示
  • GitHub Pages 上的一个仓库 —— 适合会持续改的东西
  • Cloudflare Pages / Netlify / Vercel —— 需要构建步骤时用
  • 自己的服务器 —— 只有在需要后端逻辑时才值得

这些便宜的托管方式有个共同的注意事项:内容是公开的。 gist 即便设为 secret 也只是"不可搜索",不是"需要授权"。别把带内部数据的演示页面这样放出去——我见过这类事故,原因通常是"就临时看一下"。

阅读原文 →

82. Fly's new Sprites.dev addresses both developer sandboxes and API sandboxes at the same time

来源:Simon Willison,2026 年 1 月 9 日。会过期

读它解决什么:agent 执行代码需要沙箱,这类基础设施现在长什么样。

要点

  • Fly.io 的 Sprites.dev 同时覆盖两个场景:开发者用的沙箱通过 API 调用的沙箱
  • 后者正是 agent 执行代码需要的东西

我的补充"沙箱即服务"这一类产品在 2025—2026 年集中出现,不是偶然——它对应的是 agent 需要一个能安全执行任意代码的地方这个新需求。(第二卷第 29、39 条讲的正是这个需求的另一半。)

自建 vs 用服务,我的判断标准:

自建(Docker / Firecracker / gVisor)的理由:数据不能出自己的环境、量大到服务费用不划算、需要特殊的运行时配置。

用服务的理由:不想自己处理隔离的正确性——这一条比大多数人估计的更重要。容器逃逸、资源耗尽、网络隔离配错,这些坑很深,而且配错了你不会立刻知道。

无论哪种,选沙箱时我会检查这几条

  • 网络是否默认关闭。 默认能上网的沙箱在 agent 场景下等于第三卷第 43 条里的"对外通信"那条腿是通的。
  • 文件系统是否隔离且一次性。 每次运行都是干净状态,运行完销毁。
  • 有没有资源限制(CPU、内存、执行时间)。没有的话,一个死循环就能拖垮宿主。
  • 能不能审计——执行了什么代码、访问了什么。出事时这是唯一线索。
  • 启动速度。 agent 场景下可能每分钟要起好几个,秒级启动和分钟级启动是完全不同的体验。

阅读原文 →

83. Adding dynamic features to an aggressively cached website

来源:Simon Willison,2026 年 1 月 28 日。结构性

读它解决什么:一个被 CDN 重度缓存的站点,怎么加上需要实时的功能。

要点

  • 他的博客缓存策略很激进(为了性能和抗流量)
  • 加动态功能时的冲突:缓存要求内容不变,动态功能要求内容随请求变化
  • 讨论了怎么在保留缓存收益的前提下加进动态部分

我的补充这是个每个做静态站的人都会撞上的问题,我自己在这个博客上也撞过。

冲突的本质:缓存的收益来自"同一个 URL 对所有人返回同样的内容",而动态功能恰好要打破这一点。

可行的做法,按我的推荐顺序:

  1. 把动态部分挪到客户端。 页面本体全缓存,动态内容用 JS 在浏览器里请求。这是首选,因为缓存收益一点不损失。评论数、阅读量、"你上次读到哪"都适合这样做。
  2. 边缘计算。 Cloudflare Workers / Pages Functions 这类,在 CDN 节点上跑一小段逻辑。适合需要服务端处理但又要快的场景,比如按地区返回不同内容、做轻量的 API 代理。
  3. 分离缓存策略。 HTML 长缓存,API 端点不缓存或短缓存。关键是把动态数据从 HTML 里彻底分出去
  4. 按需清理缓存。 内容更新时主动 purge。这个最容易出错——漏清一处,用户就看到旧内容,而且很难复现。

最容易踩的坑我踩过两次:把用户相关的内容放进了被缓存的 HTML 里。结果是 A 用户的页面被缓存后,B 用户看到了 A 的内容——这是数据泄露,不只是显示错误。判断标准很简单:任何随登录用户变化的内容,都不能进可缓存的 HTML。

阅读原文 →

84. Distributing Go binaries like sqlite-scanner through PyPI using go-to-wheel

来源:Simon Willison,2026 年 2 月 4 日。结构性

读它解决什么:怎么让 Python 用户能用 pip install 装一个 Go 写的命令行工具。

要点

  • go-to-wheel 把 Go 编译出的二进制打包成 Python wheel
  • 好处是复用 PyPI 这个分发渠道和 pip/uv 这个安装入口

我的补充这个技巧的意义在于它把"分发渠道"和"实现语言"解耦了——用户装的时候不需要知道也不需要在意这东西是用什么写的。

为什么值得这么做,是个很实在的成本问题:

  • 用户已经有 pip / uv,不需要再装 Go 工具链
  • PyPI 是现成的分发基础设施——版本管理、依赖解析、镜像、企业内网代理,全都有
  • 可以进 requirements.txt / pyproject.toml,跟着项目依赖一起装。这一条最实用——让二进制工具变成可锁定版本的项目依赖。
  • 用户不需要手动下载二进制、chmod +x、放进 PATH

同类的模式在别处也成立ruffuv 是 Rust 写的,但都通过 PyPI 分发;很多 npm 包实际是包装了预编译二进制。"用目标用户最熟的包管理器分发"这个原则,比"用实现语言对应的渠道分发"更重要。

要注意的点:多平台构建(Linux/macOS/Windows × x86_64/arm64)需要在 CI 里做全套;wheel 的平台标签要打对,否则用户装到错误架构的版本;二进制体积会让包变大,注意 PyPI 的大小限制

阅读原文 →

85. Running Pydantic's Monty Rust sandboxed Python subset in WebAssembly

来源:Simon Willison,2026 年 2 月 6 日。会过期

读它解决什么:怎么安全地执行不可信的 Python 代码。

要点

  • Monty 是 Pydantic 团队用 Rust 写的沙箱化 Python 子集
  • 把它编译到 WebAssembly,于是可以在浏览器或任何 WASM 运行时里跑
  • 两层隔离:语言层面是受限子集,运行时层面是 WASM 沙箱

我的补充"执行不可信 Python"是个出名地难的问题,值得说清为什么。

标准 Python 几乎无法安全沙箱化,因为逃逸路径太多:__import__evalexec__subclasses__ 遍历拿到危险类、C 扩展、ctypes、frame 内省……历史上所有"纯 Python 沙箱"方案最终都被绕过了,这是公认的结论。

所以现在的正确路线都是换一层隔离

  • WASM(Pyodide、这里的 Monty)—— 内存隔离由运行时保证,不依赖语言层的正确性。这是目前最主流的方向。
  • 容器 / microVM(Docker、Firecracker)—— 更重,但兼容完整 Python
  • 受限子集 —— 从语言层砍掉危险特性,通常和上面两者叠加使用

"Rust 实现的受限子集 + WASM"这个组合的好处是启动快、内存占用小、隔离性有运行时保证。 代价是不完全兼容标准 Python——用不了大部分第三方库,这是关键限制。

选型判断:需要跑任意 Python(含 numpy 之类)→ 容器;只需要跑简单的逻辑/表达式/用户脚本 → WASM 子集,快得多也安全得多。

在 agent 场景下这个区别很实际:如果 agent 只需要算个表达式或做点数据变换,用 WASM 子集比起一个容器要划算得多。

阅读原文 →

86. Introducing Showboat and Rodney, so agents can demo what they've built

来源:Simon Willison,2026 年 2 月 10 日。会过期

读它解决什么:agent 说"我做完了",你怎么快速确认它到底做出了什么。

要点

  • Showboat 和 Rodney 这两个工具,让 agent 能演示自己的成果而不只是报告
  • 针对的是"agent 声称完成,但你要花很久才能验证"这个摩擦

我的补充这个方向我认为被严重低估:agent 的产出需要"可检视性"(inspectability),而不只是"正确性"。

具体的痛点是这样的:agent 跑了二十分钟,说"实现完成,测试通过"。此时你要花五分钟启动、点击、检查,才知道它做的是不是你要的。 这五分钟乘以每天几十次,是很大的成本——而且因为它累人,你会逐渐跳过(第三卷第 55 条的偏差正常化)。

让 agent 主动提供可检视的产出,就把这个成本降下来了:

  • 截图——UI 改动最有效,一眼就能看出对不对
  • 录屏 / 视频(第 98 条的 shot-scraper video)——交互流程
  • 可访问的临时链接——你直接点开试
  • 结构化的变更摘要——改了哪些文件、为什么
  • 测试输出的原文——不是"测试通过",而是实际的输出

我自己在 CLAUDE.md 里明确要求的一条:改动 UI 之后要提供截图;改动 API 之后要提供实际的 curl 请求和响应。这一条对我的实际效率影响很大——因为它把"我要去验证"变成了"我看一眼就知道"。

顺带一个反面提醒:agent 提供的证据本身也要是可验证的。我遇到过 agent 声称"测试通过"但实际上改了测试断言的情况——所以要看测试的原始输出,而不是它的总结。这也是第二卷第 33 条讲的"声称完成但没做"那类失败。

阅读原文 →

87. Two new Showboat tools: Chartroom and datasette-showboat

来源:Simon Willison,2026 年 2 月 17 日。会过期

读它解决什么:把演示能力接进图表和数据库探索。

要点

  • Chartroom 和 datasette-showboat,是第 86 条那套思路的延伸
  • 覆盖到图表生成和 Datasette 集成

我的补充:把这一条和上一条一起看,能看出一个工具生态是怎么长出来的:先有一个核心机制(让 agent 展示成果),然后针对不同场景做适配(图表、数据库、视频)。

"数据可视化"在 agent 场景下特别需要可检视性,原因是这类产出的错误方式很隐蔽:

  • 一段代码错了,测试会报错
  • 一张图表错了(坐标轴搞反、数据没排序、聚合方式不对、缺失值被当成 0),图还是能画出来,看起来很正常

这类错误只能靠看图发现,看代码很难看出。 我的经验是:让 agent 生成图表时,一定要看实际的图,而不只是看生成图表的代码。而且要专门检查几件事:坐标轴的量级对不对、有没有排序、缺失值怎么处理的、总数加起来对不对。

这也是这个资料库里一个反复出现的主题:验证手段要匹配错误的类型。 逻辑错误靠测试,视觉错误靠看,性能问题靠压测,安全问题靠架构审查——用错了工具,等于没验证。

阅读原文 →

88. Adding TILs, releases, museums, tools and research to my blog

来源:Simon Willison,2026 年 2 月 20 日。结构性

读它解决什么:一个内容量很大的个人站点,怎么组织不同类型的内容。

要点

  • 给博客加了几种新的内容类型:TIL(今天学到)、releases、museums、tools、research
  • 每种类型有自己的呈现方式,但共用同一套基础设施

我的补充这一条对任何维护个人博客的人都直接有用(包括这个站点——这个资料库本身就是一种"内容类型"的实践)。

核心洞察是:不同类型的内容需要不同的结构,硬塞进"文章"这一种形态会两边都别扭。

  • TIL —— 短、频繁、不需要打磨。如果只有"写文章"这一个入口,这类内容根本不会被写下来,因为门槛太高。降低门槛是 TIL 这个形态最大的价值。
  • release notes —— 结构化、需要能按项目聚合
  • 工具/资料索引 —— 需要能检索、能分类,不适合按时间流展示

我的建议是从内容的"生命周期"来划分类型

  • 一次性的(新闻、随笔)→ 时间流
  • 会持续更新的(工具索引、资料库)→ 固定 URL + 版本说明。这个资料库就是这一类,所以它有固定的 permalink 而不是随机 ID。
  • 需要检索的(TIL、代码片段)→ 标签 + 搜索
  • 有结构的(release、书评)→ 统一模板

技术上最重要的一点:这些类型应该共用同一套基础设施(同一个构建流程、同一套样式、同一个搜索索引),只在呈现层区分。否则每加一种类型就多一套要维护的东西,很快就维护不动了。

阅读原文 →

2026 年 3—4 月:生态易主与供应链攻击

89. Thoughts on OpenAI acquiring Astral and uv/ruff/ty

来源:Simon Willison,2026 年 3 月 19 日。结构性

读它解决什么:Python 工具链的关键基础设施被一家 AI 公司买了,这意味着什么。

要点

  • OpenAI 收购 Astral——uv(包管理)、ruff(linter/formatter)、ty(类型检查)的开发方
  • 这几个工具在 Python 生态里已经占据了很关键的位置
  • 讨论社区应该怎么看这件事

我的补充这是这一卷里影响最深远的一条,因为它涉及的是"你的工具链归谁"这个问题。

先说事实层面的份量:uvruff 在 2025—2026 年基本重塑了 Python 的工具链体验——快到让人不想回去用旧的。很多项目已经把它们写进了 CI 和开发流程。

这类"关键基础设施被单一商业实体拥有"的情况,历史上的走向不止一种:

  • 变好:有资源投入,迭代更快,长期维护有保障(第四卷第 68 条 ggml.ai 加入 Hugging Face 是这个方向)
  • 变糟:路线图开始服务于收购方的商业目标,社区需求被降级
  • 分叉:社区不满,fork 出去(Elasticsearch → OpenSearch、Terraform → OpenTofu、Redis → Valkey,这几年例子不少)
  • 弃养:收购方战略转向,项目停摆

我认为务实的态度不是站队,而是评估自己的暴露程度

  • 这些工具是开源许可的uvruff 都是宽松许可),已发布的版本永远可用——这是最重要的兜底
  • 风险在未来的方向,不在现有版本
  • 实际的应对是保持退路ruff 的格式化风格和 black 兼容,uv 能读标准的 pyproject.toml所以迁回去的成本是可控的。这一点比"要不要现在换掉"重要得多。

我的做法是继续用,但避免依赖它们的独家特性。 用标准的 pyproject.toml、不依赖某个工具专属的配置格式——这样万一需要换,成本是几小时而不是几周。这个原则对所有第三方工具都成立。

阅读原文 →

90. Can coding agents relicense open source through a "clean room" implementation of code?

来源:Simon Willison,2026 年 3 月 5 日。结构性

读它解决什么:让 agent 重写一段 GPL 代码,产出的代码是什么许可。

要点

  • chardet 为例讨论这个问题
  • 涉及"净室实现"(clean room implementation)这个法律概念在 agent 时代是否还成立
  • 是个尚无定论的问题

我的补充这是个我认为每个用 agent 写代码的人都应该知道的风险,即便它目前没有明确答案。

传统的净室实现是有严格程序的:A 组读原始代码,写出功能规格;B 组只看规格,不看原始代码,写出实现。 关键在于 B 组从未接触过原始代码,所以产出不构成衍生作品。IBM 兼容 BIOS 就是这么做的。

agent 场景下这个程序的前提被破坏了,问题出在几个层面:

  • 模型的训练数据里可能包含那段原始代码
  • 你无法验证它是否"记得",也无法验证它的输出受了多少影响
  • "没看过"这个条件无法证明——而净室实现的法律效力恰恰依赖这个条件可证明
  • 模型可能输出近乎逐字的复现,而你不知道

我在实际工作里的做法(保守但省心):

  • 不用 agent 做"重写某个特定项目以改许可"这件事。 这是最直接踩线的用法。
  • 需要某个功能时,让它按需求实现,而不是"参考 XX 项目重写一遍"。措辞的差别在这里是实质性的。
  • 商业项目里,用许可扫描工具检查产出是否和已知的开源代码高度相似
  • 涉及 GPL / AGPL 的场景格外小心——这类许可的传染性会影响整个项目
  • 如果确实需要某个 GPL 库的功能,优先考虑直接用它并遵守许可,或者找宽松许可的替代品

这个问题目前没有判例,所以"不确定"本身就是风险。 在商业项目里,我倾向于不去测试边界。

阅读原文 →

91. Perhaps not Boring Technology after all

来源:Simon Willison,2026 年 3 月 9 日。结构性

读它解决什么:"选无聊的技术"这条老建议,在 agent 时代还成立吗。

要点

  • 对 "Choose Boring Technology"(Dan McKinley 那篇著名文章)的重新审视
  • agent 改变了学习和使用新技术的成本结构

我的补充这一条讲的是一条被广泛接受的工程建议正在被重新评估,值得认真想。

原来的论证是这样的:选成熟技术,因为你已经知道它的坑,遇到问题能搜到答案,招人容易。新技术的隐性成本(踩坑、查文档、没有社区答案)远超它的收益。这个论证的核心是"学习和排错的成本高"。

agent 改变了这个成本的一部分:

  • 读文档的成本大幅下降——agent 能快速消化一个新框架的文档
  • 写样板代码的成本下降——不熟悉的 API 也能快速用起来
  • 上手一个新语言的门槛降低

但有些成本完全没变,而且这是关键:

  • 踩到罕见 bug 时,agent 也不知道答案——因为它的训练数据里同样没有
  • 生态成熟度没变:库少、工具链弱、集成方案缺失,这些是客观的
  • 长期维护的负担没变——三年后这个技术还有人维护吗
  • 团队里其他人的理解成本没变(虽然也降了一些)
  • agent 对新技术的知识可能是过时的或者干脆是幻觉的——这一点反而是新增的风险,因为它会自信地写出不存在的 API

我的结论是这条建议需要修正,但不该丢掉

  • 探索性的、可以丢掉的项目 → 新技术的成本现在低多了,可以试
  • 要长期维护的核心系统"无聊"依然是对的,因为长期成本没变
  • 判断标准从"我熟不熟"部分转向了"它的生态和维护状况如何"——这个转变我认为是真实的

阅读原文 →

92. Experimenting with Starlette 1.0 with Claude skills

来源:Simon Willison,2026 年 3 月 22 日。会过期

读它解决什么:用 Skill 把一个框架的知识固化下来,效果如何。

要点

  • 拿 Starlette 1.0 做实验,用 Claude Skills 来处理框架相关的工作
  • 是第二卷第 28 条(Agent Skills)的一个具体应用

我的补充这一条正好回应了上一条(第 91 条)的关键问题:新框架的知识缺口,能不能用 Skill 补上?

答案是部分可以,值得说清哪部分可以哪部分不行:

Skill 能解决的:把最新的 API 文档、常见用法、项目里的约定写进去,让 agent 不依赖训练数据里可能过时的知识。对"框架刚发大版本、API 变了"这个场景特别有效——这正好是 Starlette 1.0 这个例子。

Skill 解决不了的:框架的隐性行为、罕见的 bug、性能特性、和其他库的兼容性问题。这些没写在文档里,只存在于踩过坑的人的经验里。

我自己给新框架写 Skill 的做法:

  1. 把官方文档的核心部分摘进去(不是全文,是你实际会用的部分)
  2. 明确写清版本号——Starlette 1.0,因为 0.x 和 1.0 的 API 可能完全不同
  3. 写下"和旧版本的区别"——这是防止 agent 用训练数据里的旧 API 最有效的一招
  4. 踩到坑就记进去。这是 Skill 长期价值的来源,也是它超过官方文档的地方。
  5. 放几个能跑的最小示例——比描述可靠得多

第 3 点是我认为最关键的。 agent 用旧 API 写代码是最常见的失败模式,而且它会写得很自信。明确写出"不要用 X,1.0 里改成了 Y",效果立竿见影。

阅读原文 →

93. The Axios supply chain attack used individually targeted social engineering

来源:Simon Willison,2026 年 4 月 3 日。结构性

读它解决什么:一次真实的 npm 供应链攻击是怎么发生的。

要点

  • Axios(下载量极大的 HTTP 库)遭遇供应链攻击
  • 手法是针对个人的社会工程,不是技术漏洞
  • 攻击者精准地针对特定维护者

我的补充这一条和第三卷第 56 条(Clinejection)是配套的,两条一起看能看清供应链攻击的两条路径:一条骗人,一条骗 agent。

"针对个人的社会工程"这个手法值得讲清,因为它绕过了所有技术防护:

  • 不需要找代码漏洞
  • 不需要破解密码
  • 只需要说服一个有发布权限的人做一件看起来无害的事

常见的具体套路:伪装成"想帮忙维护"的贡献者、假的安全报告要求紧急合并、冒充公司招聘、伪造的 CI 服务通知要求授权、假的域名过期通知……开源维护者往往是无偿的、精力有限的、并且渴望有人帮忙——这三点加起来使他们成为高价值且相对脆弱的目标。

作为使用者,我能做的(按性价比排序):

  1. 锁定版本 + 校验和。 package-lock.jsonuv.lockCargo.lock 必须提交进仓库。这是最基本也最有效的一条。
  2. 不自动升级依赖。 Dependabot 的 PR 要人看过再合,尤其是小版本号的紧急更新——攻击后的恶意版本通常伪装成 patch 版本。
  3. 注意新发布的版本。刚发布几小时的版本不要立刻上生产。给社区留出发现问题的时间。
  4. 减少依赖数量。 每个依赖都是攻击面,间接依赖也算。一个 npm install 拉进来几百个包时,你的攻击面是几百个维护者账号。
  5. CI 里做依赖审计npm auditpip-auditcargo audit),并且在构建时限制网络出站——恶意 postinstall 脚本的第一件事通常是回连。

作为维护者:开启 2FA、用硬件密钥、对"紧急"的请求保持怀疑、发布流程尽量自动化并限制权限。

阅读原文 →

94. Extract PDF text in your browser with LiteParse for the web

来源:Simon Willison,2026 年 4 月 23 日。会过期

读它解决什么:怎么在浏览器里提取 PDF 文本,不上传到服务器。

要点

  • LiteParse 编译到 WASM,在浏览器里跑
  • 好处是文件不需要离开用户的机器

我的补充"在浏览器里处理,数据不上传"这个模式的价值主要是隐私和合规,这一点在实际项目里经常是决定性的。

适用场景很实在:

  • 用户上传的是敏感文档(合同、病历、财务报表)→ 不上传是最彻底的合规方案,因为你的服务器从未持有过这些数据
  • 不想承担存储和传输的责任——数据不经过你,很多合规要求就不适用了
  • 省服务器成本(计算在用户机器上)
  • 可以离线用

技术上要知道的限制:

  • 大文件会吃内存——浏览器的可用内存有限,几百 MB 的 PDF 可能直接崩
  • 首次加载 WASM 模块有体积成本(可能几 MB)
  • 性能不如原生,但对单个文件的处理通常够用
  • 不同浏览器的支持和性能有差异,Safari 经常是短板

和第 85 条(Monty in WASM)一起看,能看出 WASM 在 2026 年的两个主要用途:一个是沙箱(隔离不可信代码),一个是把原生库搬进浏览器(避免数据上传)。这两个方向都不是"用 WASM 替代 JS"——WASM 的实际价值不在性能,而在"能安全地跑别的语言写的东西"。

顺带提醒第三卷第 60 条的坑:PDF 是不可信内容。 提取出来的文本如果要喂给 agent,那它就是注入的入口——PDF 里可以藏不可见文字层。

阅读原文 →

2026 年 6—8 月:沙箱、数据工具与编辑器

95. Running Python code in a sandbox with MicroPython and WASM

来源:Simon Willison,2026 年 6 月 6 日。会过期

读它解决什么:另一条在 WASM 里跑 Python 的路线。

要点

  • MicroPython 编译到 WASM,得到一个轻量的 Python 沙箱
  • 和 Pyodide(完整 CPython)相比体积小得多、启动快得多

我的补充:这一条和第 85 条(Monty)是同一个问题的第三种解法。三条路线的取舍值得记住:

方案体积启动兼容性
Pyodide(完整 CPython + WASM)大(几十 MB)慢(秒级)高,能装 numpy 等
MicroPython + WASM小(几百 KB 级)中,标准库是子集
Monty(Rust 实现的子集)低,语言子集

选择标准很直接:

  • 需要 numpy / pandas / 科学计算只能 Pyodide,没有替代
  • 只跑用户写的简单脚本、表达式、数据变换 → MicroPython 或 Monty,体积和启动速度差一到两个量级
  • 在 agent 场景下频繁创建沙箱启动速度是主要指标,选轻量方案

一个常见的判断错误:默认选 Pyodide 因为"兼容性好",结果为了跑几行简单逻辑加载了几十 MB 的运行时。先看你实际需要什么库,再选方案。 我的经验是大多数"跑用户脚本"的需求根本不需要第三方库。

阅读原文 →

96. Publishing WASM wheels to PyPI for use with Pyodide

来源:Simon Willison,2026 年 6 月 13 日。会过期

读它解决什么:怎么让自己的 Python 包能在 Pyodide 里用。

要点

  • 把包编译成 WASM 平台的 wheel 并发布到 PyPI
  • 于是浏览器里的 Python 也能 pip install 你的包

我的补充这一条是第 84 条(Go 二进制走 PyPI)的镜像:一个是把非 Python 的东西塞进 PyPI,一个是把 Python 包扩展到非传统平台。共同点是"复用已有的分发基础设施"。

为什么需要专门的 WASM wheel:纯 Python 的包在 Pyodide 里直接就能用。但带 C 扩展的包必须重新编译成 WASM 目标——这是主要工作量所在。

对包作者来说要注意:

  • CI 里加一个 WASM 目标的构建(Emscripten 工具链)
  • 平台标签要打对,否则 Pyodide 认不出来
  • 有些依赖在 WASM 下不可用——文件系统、网络、多进程、线程都受限。这一条最容易踩:你的包在本地测试通过,在浏览器里因为用了 subprocesssocket 而失败。
  • 测试要在真实的 Pyodide 环境里跑,不能只在本地跑

如果你的包可能被用在浏览器里(数据处理、格式解析、算法库这类),支持 WASM 是个不小的加分项——它让你的包能进入一整类新场景:交互式文档、在线演示、不需要后端的工具站。

阅读原文 →

97. Datasette Apps: Host custom HTML applications inside Datasette

来源:Simon Willison,2026 年 6 月 18 日。会过期

读它解决什么:怎么在 Datasette 里放自定义的 HTML 应用。

要点

  • Datasette Apps 让你把自己写的 HTML 应用托管在 Datasette 里面
  • 直接用 Datasette 已有的数据访问能力和权限系统

我的补充这个模式的价值在于"复用已有的权限和数据层",而这恰好是自建工具最费时间的部分。

一个具体场景:你有个 SQLite 数据库,想做个小工具让同事查数据。传统做法要写后端 API、做认证、处理权限、部署——大部分工作都不是你真正关心的那个界面。放进 Datasette 的话,数据访问和权限都是现成的,你只写界面。

这和"agent 让写代码变便宜"结合起来,效果被放大了:写界面的成本本来就在下降,而"接数据 + 做权限"的成本一直是硬的。Datasette Apps 把后者也消掉了,于是"做个内部小工具"这件事的总成本可能降到一个下午。

这类"内部小工具"的价值经常被低估——很多人在用 Excel 手工做的事,一个针对性的小界面就能自动化。以前不做是因为成本不划算,现在这个算式变了。

安全提醒:把自定义 HTML 放进有数据访问权限的环境,要注意 XSS 和权限绕过。如果 HTML 内容可能由不完全可信的人提供(包括 agent 生成的),要确认它不能越过 Datasette 的权限检查读到不该读的数据。 第三卷第 43 条的三要素判断在这里同样适用。

阅读原文 →

98. Have your agent record video demos of its work with shot-scraper video

来源:Simon Willison,2026 年 6 月 30 日。会过期

读它解决什么:让 agent 录一段视频来展示它做的东西。

要点

  • shot-scraper 加了录视频的能力
  • agent 完成 UI 相关的工作后,可以录一段操作视频

我的补充这是第 86 条(可检视性)在 UI 场景下最完整的解法,我认为是这一卷里对日常效率影响最直接的一条。

为什么视频比截图更有用——因为交互过程无法用静态图表达

  • 点了按钮之后发生了什么
  • 动画和过渡是否正常
  • 表单校验的提示时机对不对
  • 加载状态、错误状态的呈现
  • 多步流程的完整走通——这是最有价值的部分

我的实际做法:在 CLAUDE.md 里要求 UI 改动必须附截图,多步交互的改动附视频。这样我 review 的时候先看视频,两分钟就能判断方向对不对,不对的话根本不需要读代码。这一步省下的时间非常可观。

它还有个副作用是我没预料到的:为了录视频,agent 必须真的把功能跑通。这本身就排除了一类"代码写完了但根本跑不起来"的情况——它没法录一个跑不起来的东西的视频。这个约束比任何"请确保代码能运行"的措辞都有效。

配合第二卷第 23 条(Claude Code 最佳实践)里的验证思路,以及第一卷第 16 条(交付你证明过能跑的代码)——视频就是"证明"的一种具体形式

阅读原文 →

99. sqlite-utils 4.0, now with database schema migrations

来源:Simon Willison,2026 年 7 月 7 日。会过期

读它解决什么sqlite-utils 大版本更新,加了 schema 迁移和嵌套事务。

要点

  • 4.0 版本加入数据库 schema 迁移支持
  • 以及嵌套事务(在 rc1 里提到)
  • 这是一次大版本,意味着有不兼容变更

我的补充"迁移"是个所有数据库项目最终都会需要的东西,而它常常被推迟到已经很痛的时候。

没有迁移机制时的典型状态:

  • 手写 ALTER TABLE记不住哪个环境执行过哪些
  • 新环境要靠一份可能过时的建表脚本
  • 回滚基本不可能
  • 多人协作时 schema 变更冲突,而且冲突不会报错,只会在运行时炸

迁移机制解决的是**"schema 版本"这个概念的缺失**:每个变更有编号、有记录、按顺序执行、执行过的不重复执行。

顺带一个和这个资料库主题相关的观察:这个项目的 4.0rc2 据 Simon Willison 自己说主要由 Claude Fable 写的,成本约 149.25 美元。这个数字值得记住,因为它给"用 agent 做一个真实项目的一个大版本"提供了一个具体的量级参考——不是"很便宜"也不是"很贵",而是一个明确的数。

同时注意这不是"149 美元换一个版本"这么简单:前提是有一个成熟的项目、清楚的目标、完整的测试套件、以及一个知道自己要什么并且会验证结果的维护者。去掉这些前提,同样的钱换不到同样的东西。 这一点回到第一卷第 17 条讲的:不看代码的前提是验证体系足够强。

阅读原文 →

100. VS Code 1.134:agent host、chat 网格布局与 prompt 时间线

来源:VS Code 官方发布说明,2026 年 8 月 19 日。会过期

读它解决什么:编辑器层面,agent 集成做到了什么程度。

要点(来自官方发布说明):

  • Agent host:一个 agent 会话可以同时连接多个 VS Code 窗口;harness 跑在独立进程里,基于 Agent Host Protocol;Copilot harness 跑在 Copilot SDK 上,所以行为和 Copilot CLI、独立应用一致。仍在积极开发中。
  • Chat 的网格布局:把多个 chat 横向或纵向分组,并行观察多个任务的进展;可以拖拽 chat 或 subagent chat 进组;切回会话时会恢复布局和焦点
  • Prompt 时间线:编辑器边栏的时间线,每个点是你的一次 prompt;悬停预览、点击跳转;改过文件的 prompt 会显示增删行数并直接链到 diff;由 sessions.chatTimeline.display 控制
  • Find in chatCtrl+F / Cmd+F 在 chat 里搜索,覆盖整个对话(包括没渲染出来的部分),会自动展开含匹配的折叠区块;支持大小写、全词、正则
  • 侧栏布局改进:单栏布局现在遵循 workbench.editor.showTabs;文本编辑器加了面包屑;面板尺寸和可见性能跨会话保持
  • 编辑器体验:按住 Alt 点关闭按钮变成"关闭其他编辑器";本地 HTML 文件可以用内置浏览器打开(通过 workbench.editorAssociations
  • 另有一批社区贡献的内存泄漏修复

我的补充这一版发布说明最值得注意的是它的重心——七个头条特性里五个是 agent 和 chat 相关的,终端、源码管理、扩展这三块这一版只有 bug 修复。编辑器的开发重心已经明确转向 agent 集成了,这个信号比任何单个特性都重要。

几个我认为实际有用的:

Prompt 时间线解决的是一个真实痛点:长会话里"我什么时候让它改的这个文件"很难查。把每个 prompt 变成时间轴上的一个点,还能直接跳到 diff——这本质上是给 agent 会话加了版本控制的视图。我认为这是这一版最实用的特性。

Chat 网格布局对应第一卷第 8 条(并行 coding agent)。并行跑多个 agent 时,最大的摩擦一直是"不知道哪个跑到哪了",需要在几个窗口之间切来切去。能在一个视图里并排看,这个摩擦就小很多。

Find in chat 覆盖未渲染的内容,这个细节看起来小但很实用——长会话里搜"我之前提到的那个文件名",如果只搜可见区域基本没用。

Agent host 让一个会话连多个窗口,这个设计的意义是把"会话"从"窗口"里解放出来:会话变成一个独立的、可以从多处观察的资源。这和第二卷第 40 条(brain/hands 解耦)是同一个方向——把状态和展示分开

阅读原文 →


这个资料库到这里结束

第 100 条是 35.工具 这一册的最后一条,也是整个资料库 500 条的最后一条。

本卷小结:81–85 条是托管和沙箱(第 85、95 条那三条 WASM 路线的取舍表最实用);86–88 条是 agent 产出的可检视性(第 86、98 条改变了我的日常 review 方式);89–94 条是生态所有权和供应链风险(第 89 条 uv/ruff 易主和第 93 条 Axios 攻击是影响面最大的两条);95–100 条是数据工具和编辑器(第 100 条显示编辑器的重心已经全面转向 agent)。

这一卷里最不会过期的四条:第 83 条(缓存和动态内容的冲突)、第 89 条(保持退路的原则)、第 91 条("选无聊技术"需要修正但不该丢)、第 93 条(供应链防护清单)。

五卷的整体建议:如果你只有一小时,读第 43 条(lethal trifecta,会改变你的架构决策)、第 16 条(交付你证明过能跑的代码,会改变你的工作标准)、第 21 条(agent 的分类学,会改变你怎么选方案)、第 27 条(上下文是有限资源,会改变你的日常用法)。这四条的共同点是它们都不是技巧,而是判断标准——技巧会过期,判断标准不会。


上一卷: ← ④ 本地模型与 LLM 命令行 · 总览: 工具资料库 · 其他资料库: 专题 · 运维 · 前端