Simon Willison’s Weblog

Newsletter

November 2026

40 posts: 4 entries, 7 links, 4 quotes, 2 notes, 20 beats, 3 newsletters

Sunday, 1st November 2026

More broadly, the use of LLMs erodes trust in documentation, in software, and in the organizations which produce them. Perhaps engineers will begin to treat any new software project with suspicion—the signals we used to rely on as markers of a mature system are now easier to counterfeit. [...]

In the age of LLMs, what can maintainers do to ensure correct software and accurate documentation? Having done that work, how can they demonstrate its quality to users?

— Kyle Kingsbury, Jepsen results for ParticleDB 1.1.4

# 4:49 pm / ai, generative-ai, llms, ai-misuse, kyle-kingsbury

Sighting 12:33 PM — Black Phoebe, in San Mateo County, CA, US
Black Phoebe
Black Phoebe
Sighting 3:18 PM – 3:23 PM — California Sea Lion, California Brown Pelican, in Pillar Point Harbor, CA, US
California Sea Lion
California Sea Lion
California Brown Pelican
California Brown Pelican
California Sea Lion
California Sea Lion

I've been getting the occasional confusing Python dependency error since switching over to Python 3.15 and the rule I'm having to remember is:

If in doubt, delete the uv.lock file

Most of my projects are libraries which don't include a uv.lock file, since it's rude for a library dependency to lock versions for anything else that uses it.

Running uv run pytest etc tends to leave uv.lock files lying around, which are listed in .gitignore and so do not get committed to my repositories.

But... sometimes that uv.lock pins a version of a dependency that doesn't yet have a Python 3.15 wheel. An example from earlier today:

error: Failed to build `watchfiles==1.1.1`
  cause: Call to `maturin.build_wheel` failed

error: the configured Python interpreter version (3.15) is newer
than PyO3's maximum supported version (3.14)

Deleting that file and running uv run pytest again usually fixes the problem.

# 11:24 pm / python, til, uv

Monday, 2nd November 2026

The U.S. Census Bureau and “Super Intelligence”

Visit The U.S. Census Bureau and “Super Intelligence”

I was reminded today of AI Adoption Rate Trending Down for Large Companies, a chart produced by Apollo Global Management in September 2025, which appeared to show a slowdown in U.S. corporate AI adoption based on numbers collected by the U.S. Census Bureau. At the time I used that chart to demonstrate GPT-5 data analysis, and then to experiment with Claude’s new Code Interpreter. I decided to try running those numbers again to see what had changed over the past year, and in doing so learned that the Bureau has fallen foul of Executive Order 14434, aka the asinine Super Intelligence one.

[... 1,068 words]

There's a lot of stuff in this new release of my LLM CLI tool and Python library, representing around two months of accumulated features and fixes.

I added gpt-6.1-sol and gpt-6.1-terra, plus a new llm openai endpoint add command to make it easier to configure additional models that use OpenAI-compatible endpoints.

I switched the default model (if you have not set your own default) to gpt-6-luna - half the price of the previous default, gpt-5.6-luna.

LLM's support for embeddings now accepts that different binary content may have different content-type - necessary for models like Gemini Embedding 2, which can embed text, audio, images, and video.

A lot of open source maintainers complain about a flood of AI-assisted PRs. LLM is my project that has been most affected by this and, to be honest, I'm not finding it to be a problem. That's mainly because I have Opus 5.5 or GPT-6 Astra help me with triage to spot the most useful fixes!

This release includes fixes from 12 authors - almost all AI-assisted - and the burden of reviewing them wasn't nearly as great as I expected. I really see them as bug reports with attached examples - sometimes I land them, sometimes I implement my own fix.

So thanks to 0d00ciallo0721, ac1982, Allen Flux, Bian Yuhan, Bishop Kammeraad, Chen Yufeiyang, Christopher Krah, Ethan Stoner, Jiachen Xie, Olamide Faniyan, Sharat Chandra Sai Boddu, nosmile99 for helping out with (or spending tokens on) this release!

Tuesday, 3rd November 2026

I sent out the October edition of my sponsors-only monthly newsletter. If you are a sponsor (or start a sponsorship now) you can access it here. This month:

  • The October inflection point for vibe game development
  • The vulnerability apocalypse gets hot
  • LLM releases
  • API credits for $100+/month subscriptions
  • What I'm using right now
  • My software releases

My September newsletter can now be seen here, as a preview of what you'll get. Pay $10/month to stay a month ahead of the free copy!

# 5:28 am / newsletter

I discovered a sound that leaks your exact location (and it’s everywhere)—YouTube (via) Genius piece of OSINT by Colsto, who demonstrates how you can take almost imperceptible background noise of planes from a video soundtrack, figure out their Doppler curves, then cross reference them against ADS-B data to find the exact location of the video based on their speed, distance, and gaps between different flights.

# 5:32 am / privacy, youtube

Qwen 3.8 27B on my laptop can interpret model weights, too

Yesterday’s hot paper was Sparks of Weight-Space Programming: LLMs can natively read & write neural network weights by Rikiya Takehi, Jayden Teoh, Alex Zhang, and Omar Khattab. The paper (OK, the authors classify is as a “blog post”, but it’s paper-shaped) found that frontier models, in particular GPT-6 Astra, can both interpret and modify the raw weights of a machine learning model—literally a text description of the model containing a bunch of floating point numbers. I’ve been playing with one of the examples from the paper and I’m delighted to share that Qwen 3.8 27B running on my laptop can do this as well!

[... 1,211 words]

Comment My comment on AI is destroying my CS degree — Hacker News

I don't envy educators right now.

AI clearly means you need to change how you teach and evaluate students. We are only a few years in though, and it's still extremely unclear what effective teaching with these tools looks like.

The worst part is that the evaluation loop is measured in multiple years! If you start trying some new education mechanism today you won't get a robust idea of how well it works until your current cohort graduate in 3-6 years time.

Students effectively all become guinea pigs for untested new ways of learning and teaching.

# 4:42 pm / education, hacker-news, ai, ai-ethics

A bugfix release for LLM, with contributions from Steven Huang, Tao An, Arjan Mossel, and XQ.

This is a significant release of Datasette Agent. The most notable new feature is called the panel - it lets the agent chat open and then sit next to pages from Datasette, for example a table or query page.

When combined with datasette-apps this means you can prompt a database-backed app into existence and then modify it from the chat that sits next to that app.

Screenshot of a split-screen chat interface titled "evaluate llm prices" (model tag "gpt-6-luna"): the conversation runs in a narrow column on the left, and a wide side panel on the right displays the app the assistant built, with "EXPORT" and "Close panel" buttons above it. In the chat, blue user bubbles read "Build an app to help explore this data" and "give it a more hacker aesthetic design", each followed by collapsed tool calls (app_create, app_render, app_view, app_str_replace), "LLM Price Explorer v1." and "v2." entries with "View app" and "Edit" buttons, and short assistant replies describing the app and its new dark terminal-inspired theme. The right panel shows the resulting "LLM Price Explorer" in neon green monospace on black: stat cards for 185 models from 12 providers with workload costs from $0.042 (Jev 1.13) to $300.00 (o1 Pro), filter and workload cost estimate controls, and a table of matching models with input, output and cached input prices per million tokens.

You can try it by signing in with your GitHub account to agent.datasette.io.

Wednesday, 4th November 2026

Datasette Apps adds support for hosting and editing custom HTML applications inside of Datasette.

These can be created by hand, but it's easier to create them using LLMs via Datasette Agent. This release improves that integration:

  • Apps can now be tagged in Datasette Agent chat messages by typing #, which autocompletes from the apps the user has permission to view.
  • New app_add_stored_queries() and app_remove_stored_queries() tools let the agent manage which stored queries an app is allowed to call. Granting a write query requires approval from the user first.
  • app_create() now checks that each requested stored query exists and that the user can view it, and asks the user to approve any write queries before the app is created.
  • The "View app" buttons shown by the agent tools, and the links on # app references, now open the app full screen in the Datasette Agent panel.

Fixes a bug that affected my agent.datasette.io demo site, where the set of available LLM models was not correctly restricted to just those in the configuration.

Thursday, 5th November 2026

Sighting 5:49 PM — Brandt's Cormorant, in Pillar Point Harbor, CA, US
Brandt's Cormorant
Brandt's Cormorant
Brandt's Cormorant
Brandt's Cormorant

The web browser is very, very, very powerful software for applications, and the cost of accessing that power is going down seemingly every day.

— Paul Ford, The Web Is More Than Enough

# 5:34 pm / browsers, paul-ford, web-development

Friday, 6th November 2026

The products aren't good enough to sell people on the costs.

You cannot tell people that you have to listen to the whine of a data center in their backyard for AI overviews and some of the most hilarious deep fake slop in history.

It's not worth it. It just isn't worth it to anyone. And agents aren't real and they might not be being used the way that anyone wants them to yet. All these companies are spending more than they're making on these products. Refrigerators holding blood storage in Europe are being hacked.

The costs are too high. The benefits are not real. And if you connect that to corruption, you're like, in order to impose these costs on me, these CEOs are in the White House shaking Trump's hand, renaming it to the Gulf of America, paying for this ballroom that we don't want. It's obvious crypto-corruption, and it's still slop.

The AI industry will not get out of it until they make better products. Until everyone can see without needing to be convinced, without needing an ad campaign, without any of this stuff that just using these products makes your life better.

— Nilay Patel, The Vergecast: Big Tech lost big in the 2026 election

# 5:13 pm / ai, generative-ai, slop, nilay-patel, ai-ethics

Saturday, 7th November 2026

Comment My comment on Terry Pratchett's Study — Hacker News

Terry Pratchett once wrote about the concept of "horizontal wealth". Vertical wealth is where you spend money on rich people stuff - yachts and suchlike. Horizontal wealth is where you spend more money on the things you liked before you got rich: https://chibuikeani.blogspot.com/2017/02/the-price-of-happin...

But horizontal wealth means not letting your increased income dictate your tastes. You like books and now you have money? Buy more books! Change those catenary bookshelves for good hardwood ones! In my case, build a library extension to your office. And, of course, you buy what will be useful for that most wonderful of pursuits, blind research, which is research without direction for the sheer joy of it.

(Original source is his book A Slip of the Keyboard - this linked blog post quotes that bit.)

# 7:34 pm / hacker-news, terry-pratchett

datasette #3046: Don’t serve link: rel=next HTTP headers to Firefox for HTML pages. I was looking at the Firefox network panel today when I noticed that requests to a Datasette table page were triggering an HTTP prefetch to the next page of rows in that table.

This was happening because Datasette pages serve an HTTP link header like this:

link: <https://latest.datasette.io/fixtures/compound_three_primary_keys?_next=a%2Cd%2Cv>; rel="next"

This is bad. A tiny fraction of the visitors to one of those pages will click the "next" link, which means for everyone else their browser is fetching unnecessary data and the Datasette server is having to render an entire page that then gets thrown away.

I dug in and learned that Firefox has an issue that has been open for 24 years about this behavior...

And one of the early comments on that issue links to my blog post from 2002 complaining about this feature. I hadn't just forgotten that I had written about it, I had forgotten the feature entirely!

# 11:57 pm / firefox, html, mozilla, datasette

Sunday, 8th November 2026

Sighting 11:05 AM – 11:40 AM — Great Blue Heron, Western Grebe, Botta's Pocket Gopher, California Brown Pelican, California Sea Lion, Pacific Harbor Seal, in Monterey Bay National Marine Sanctuary, CA, US, CA
Great Blue Heron
Great Blue Heron
Great Blue Heron
Great Blue Heron
Western Grebe
Western Grebe
Botta's Pocket Gopher
Botta's Pocket Gopher
California Brown Pelican
California Brown Pelican
California Sea Lion
California Sea Lion
Pacific Harbor Seal
Pacific Harbor Seal

I was out walking the dog when I got curious about how easy/difficult it would be to write a SQLite C extension that adds a parse_number() function for turning strings like -$1,234.56 or '12.5%' into numeric values that could be summed and sorted.

I fired up regular Claude chat (Opus 5.5) and prompted:

I'm thinking about a SQLite custom function 'parse_number(value)' that strips ',', '$', '£' and '%', handles a leading '-', and returns 'NULL' for anything it can’t parse

Explore the difference between building this as a SQLite extension in C v.s. in Rust - I want to compare performance and code complexity and size of the resulting.so(or whatever) file

This gave me a solid starting point - the Rust extension was 321 KB (using Rusqlite) and 298 KB (using sqlite-loadable-rs), while the C extension was 14 KB. But the Rust extension was faster!

Turns out that's because the Rust equivalent of C's strtod is "twice as fast". So I prompted:

Try writing your own C function for parsing text into a decimal number that catches up to or beats the Rust implementation

And it did, using "Clinger's fast path":

Net cost per row over 2 million rows, lower is better:

first C new C rusqlite sqlite-loadable
Mixed data 67 ns 19 ns 46 ns 41 ns
Integers only 25 ns 16 ns 36 ns 32 ns
Decimals only 106 ns 18 ns 55 ns 47 ns

Finally, I had it rewrite the prototype as a research report to match the others in simonw/research by prompting this:

Clone simonw/research from GitHub and turn your above investigation into a research report as seen in that repository - you can give me a zip file to download that contains your new folder

Here's the resulting report.

Monday, 9th November 2026

Hide your slop PR descriptions behind <details><summary>

Visit Hide your slop PR descriptions behind <details><summary>

Most of the changes I make to my projects these days come in the form of PRs opened for me by Claude Code or Codex. The PR is my unit of work—I use them to bundle commits together, iterating on them until a feature is complete, document decisions and then merge the finished result. Today’s coding agents are great at writing PR descriptions.

[... 987 words]

Comment My comment on The Web Is More Than Enough, by Paul Ford — Hacker News

OK, this comment convinced me to give that a shot.

Here's a thing I made in Three.js this morning - a Nudibranch themed Faberge Egg: https://static.simonwillison.net/static/2026/Hidden-Reef-Egg... (77KB)

I just asked Claude (Opus 5.5 Medium running in regular Claude Chat) to port that to Vanilla JS, in the same thread where it had built it, and got this: https://static.simonwillison.net/static/2026/Hidden-Reef-Egg... (98KB)

They aren't identical - you can see what Claude said about that in the transcript (I don't fully understand why it differed): https://claude.ai/share/e56d163e-2793-4677-aa11-191d5058b414

But yeah, it turns out Claude Opus 5.5 is perfectly capable of 3D modeling in Vanilla JS + WebGL without Three.js.

In eyeballing the code I find the Three.js slightly easier to understand myself, but I rarely look at the code for these 3D projects so that isn't a particularly big deal.

# 4:32 am / hacker-news, javascript, ai, generative-ai, llms, claude, three-js

Locating the source of a mysterious beep with Claude

Visit Locating the source of a mysterious beep with Claude

Our house has a box room, full of boxes that we still haven’t unpacked from our last move. A couple of weeks ago something in that room started intermittently beeping. The beeps were far enough apart that standing in the room and trying to determine the source of the noise was frustrating, and I really didn’t want to dig through every one of those boxes. So I had Claude Code build Beep Locator, a software system for triangulating the source of a mysterious beep using multiple devices scattered around the room.

[... 2,039 words]

Anthropic released Fable 5.2 and Mythos 5.2 today. Fable 5.2 is currently ranked first on Artificial Analysis. Anthropic say it "solved two open problems in the physics of black holes", so clearly their internal benchmarks have become more ambitious!

I've added the new models to llm-anthropic, so you can now run prompts through Fable 5.2 like this:

uv tool install llm
llm install llm-anthropic
llm keys set anthropic
# paste key here
llm -m claude-fable-5.2 "Generate an SVG of a pelican riding a bicycle"

I ran pelicans at all five reasoning levels - low, medium, high, xhigh, and max. You can see them all here - here's the best result I got, from xhigh:

It's good - legs the right side of the bicycle, good frame, nice pouch, weird little fingers on the handlebars. The pouch looks slightly misaligned with the top of the beak.

max failed to return an image at all, running out of tokens after spending 128,000 thinking about them. That's the same bug that I saw with Opus 5.5 - but it's new for the Fable series, both Fable 5 and Fable 5.1 returned max effort pelicans just fine.

It's priced at $8/million input and $40/million output, which is a 20% discount on the previous Fable 5.1 ($10/$50).

I also used Fable 5.2 to help identify the source of a mysterious beep.

Tuesday, 10th November 2026

I realized I didn't know where Yonkers was, so I looked it up on Google Maps and then, to help embed its location and shape in my head (and to try out Claude Fable 5.2's 3D modeling and animation skills), I prompted Fable 5.2 Medium to:

Make a three js animation where yonkers stands up as a big mech (cool stand up motion) and átomos around manhattan and queens and Brooklyn, use openstreetmap mapping data

It correctly deduced that "átomos" was a mobile keyboard typo for "stomps":

Claude Fable 5.2 pays close attention to who owns the code it works on. In Anthropic’s testing on small coding tasks, the model tended to add to the existing structure when the prompt said nothing about ownership or presented the code base as someone else’s, even when that duplicated existing code. When the prompt said the code base was the model’s own, it often consolidated duplicated code and sometimes made related fixes without being asked.

If you want the model to improve the structure as it works, say that the code is its own:

You are the owner and long-term maintainer of this codebase, and its design is up to you.

The ownership sentence makes the model much more likely to consolidate duplicated code into one shared function. In Anthropic’s testing on small coding tasks, the model consolidated duplicated code in under 10 percent of runs without the sentence and in about 75 percent of runs with it.

— Prompting Claude Fable 5.2, Anthropic documentation

# 5:34 am / ai, prompt-engineering, generative-ai, llms, anthropic, claude-mythos-fable

Introducing Our Smallest, Most Efficient Model: Muse Ember. Meta AI just launched their entry in the Claude Haiku/GPT Luna category: Muse Ember, which they describe as:

[...] our smallest and most efficient model designed for complex reasoning execution and the work agents repeat all day: tool calls, coding subtasks, routing, extraction, and long document parsing.

For shorter prompts it's priced the same as GPT-6 Luna and Claude Haiku 5.5 - both are $0.10/million input tokens and $0.50/million output. Today's other big model release, Claude Fable 5.2, is 80x that price at $8/$40.

The pricing is a little less straightforward as prompts get longer, though. Luna, Ember, and Haiku all support up to a million input tokens, but they also all have a threshold after which the price goes up. Taking that threshold into account Ember is priced between the two others:

Model Prompt size Input ($/M) Cached input Output
GPT-6 Luna ≤272k $0.10 $0.01 $0.50
>272k $0.20 $0.02 $0.75
Muse Ember 1.0 ≤200k $0.10 $0.004 $0.50
>200k $0.30 $0.012 $1.50
Claude Haiku 5.5 ≤100k $0.10 $0.01 $0.50
>100k $0.50 $0.05 $2.50

But comparing price-per-token doesn't really make sense these days, when reasoning tokens mean that different models might use dramatically different numbers of tokens to solve the same problem.

For that, one measure that's useful is the Artificial Analysis.

Stacked bar chart from Artificial Analysis comparing a cost in dollars across six models, each bar split into four unlabeled stacked segments, sorted from lowest to highest total. Claude Haiku 5.5 (low): $0.04* total, bottom segment $0.02, three thin unlabeled segments above. GPT-6 Luna (non-reasoning): $0.07 total, bottom segment $0.06, thin unlabeled segments above. GPT-6 Luna (xhigh): $0.10 total, segments from bottom $0.07, $0.02, $0.02, plus a thin unlabeled top segment. Muse Ember (xhigh): $0.12 total, segments from bottom $0.06, $0.02, $0.02, plus a thin unlabeled top segment. Muse Ember (max): $0.14 total, segments from bottom $0.07, $0.03, $0.03, $0.02. Claude Haiku 5.5 (xhigh): $0.25* total, segments from bottom $0.14, $0.04, $0.05, $0.02. Anthropic bars are terracotta, OpenAI bars are dark gray, Meta bars are blue, each with the company logo beneath.

And even more useful than that is their Intelligence Index vs. Cost per Task chart, which shows the following for those three models:

Scatter plot from Artificial Analysis titled "Intelligence Index vs. Cost per Task", plotting Artificial Analysis Intelligence Index (y-axis, 5 to 40) against cost per task in USD on a log scale (x-axis, $0.04 to $0.3), with a green "most attractive quadrant" in the upper left and a dotted Pareto line. Claude Haiku 5.5 (low)* scores about 19 at roughly $0.044. GPT-6 Luna (non-reasoning) scores about 9.5 at roughly $0.07. GPT-6 Luna (xhigh) scores about 23.5 at roughly $0.10. Muse Ember (xhigh) scores about 34 at roughly $0.12 and Muse Ember (max) about 36 at roughly $0.14, both on the Pareto line. Claude Haiku 5.5 (xhigh)* scores about 34.5 at roughly $0.25, well to the right of the Pareto line. Three unlabeled gray dots also sit on the Pareto line.

The Muse Ember models sit right on that Pareto line - the line at which you can only improve one dimension by giving up another. Meta call this out in their announcement:

It also sits on the efficiency frontier of the full Artificial Analysis leaderboard: no model scores higher for less per task.

(That grey dot on the Pareto line in the middle of the green area is GPT-6.1 Terra (low) - clearly I should be paying more attention to the Terra family!)

Muse Ember has six reasoning levels - minimal, low, medium, high, xhigh, and max - so I rendered six pelicans riding bicycles. The "high" reasoning level failed to return a full SVG, and the other SVGs were surprising in that the reasoning level didn't cleanly map to the visual quality of the response.

Here's the "max" one, but the others are worth a look too:

Bicycle frame is OK, basket has fish, pelican has a weird blue hat on.

The Ember pelicans are comparable in quality to those I got from Muse Wonder, which is 40x the price of Muse Ember.

# 7:28 am / ai, generative-ai, llms, meta, llm-pricing, llm-release, artificial-analysis, muse

2026 » November

MTWTFSS
      1
2345678
9101112131415
16171819202122
23242526272829
30