Simon Willison
Co-creator of Django. Prolific writing on Python, LLMs, and data tools.
PythonLLMsdata tools
- Profiling Hacker News users based on their comments
- Thoughts on OpenAI acquiring Astral and uv/ruff/ty
- GPT-5.4 mini and GPT-5.4 nano, which can describe 76,000 photos for $52
- My fireside chat about agentic engineering at the Pragmatic Summit
- Perhaps not Boring Technology after all
- Can coding agents relicense open source through a “clean room” implementation of code?
- Something is afoot in the land of Qwen
- I vibe coded my dream macOS presentation app
- Writing about Agentic Engineering Patterns
- Adding TILs, releases, museums, tools and research to my blog
- Two new Showboat tools: Chartroom and datasette-showboat
- Deep Blue
- The evolution of OpenAI’s mission statement
- Introducing Showboat and Rodney, so agents can demo what they’ve built
- How StrongDM’s AI team build serious software without even looking at the code
- Running Pydantic’s Monty Rust sandboxed Python subset in WebAssembly
- Distributing Go binaries like sqlite-scanner through PyPI using go-to-wheel
- Moltbook is the most interesting place on the internet right now
- Adding dynamic features to an aggressively cached website
- ChatGPT Containers can now run bash, pip/npm install packages, and download files
- Wilson Lin on FastRender: a browser built by thousands of parallel agents
- First impressions of Claude Cowork, Anthropic’s general agent
- My answers to the questions I posed about porting open source code with LLMs
- Fly’s new Sprites.dev addresses both developer sandboxes and API sandboxes at the same time
- LLM predictions for 2026, shared with Oxide and Friends
- Introducing gisthost.github.io
- 2025: The year in LLMs
- How Rob Pike got spammed with an AI slop “act of kindness”
- A new way to extract detailed transcripts from Claude Code
- Cooking with Claude
- Your job is to deliver code you have proven to work
- Gemini 3 Flash
- I ported JustHTML from Python to JavaScript with Codex CLI and GPT-5.2 in 4.5 hours
- JustHTML is a fascinating example of vibe engineering in action
- OpenAI are quietly adopting skills, now available in ChatGPT and Codex CLI
- GPT-5.2
- Useful patterns for building HTML tools
- Under the hood of Canada Spends with Brendan Samek
- Highlights from my appearance on the Data Renegades podcast with CL Kao and Dori Wilson
- sqlite-utils 4.0a1 has several (minor) backwards incompatible changes
- Claude Opus 4.5, and why evaluating new LLMs is increasingly difficult
- Olmo 3 is a fully open LLM
- Nano Banana Pro aka gemini-3-pro-image-preview is the best available image generation model
- How I automate my Substack newsletter with content from my blog
- Trying out Gemini 3 Pro with audio transcription and a new pelican benchmark
- What happens if AI labs train for pelicans riding bicycles?
- Reverse engineering Codex CLI to get GPT-5-Codex-Mini to draw me a pelican
- Code research projects with async coding agents like Claude Code and Codex
- Video + notes on upgrading a Datasette plugin for the latest 1.0 alpha, with help from uv and OpenAI Codex CLI
- A new SQL-powered permissions system in Datasette 1.0a20
- New prompt injection papers: Agents Rule of Two and The Attacker Moves Second
- Hacking the WiFi-enabled color screen GitHub Universe conference badge
- Video: Building a tool to copy-paste share terminal sessions using Claude Code for web
- Living dangerously with Claude
- Dane Stuckey (OpenAI CISO) on prompt injection risks for ChatGPT Atlas
- Getting DeepSeek-OCR working on an NVIDIA Spark via brute force using Claude Code
- Claude Code for web—a new asynchronous coding agent from Anthropic
- Claude Skills are awesome, maybe a bigger deal than MCP
- NVIDIA DGX Spark: great hardware, early days for the ecosystem
- Claude can write complete Datasette plugins now
- Vibe engineering
- OpenAI DevDay 2025 live blog
- Embracing the parallel coding agent lifestyle
- Designing agentic loops
- Claude Sonnet 4.5 is probably the “best coding model in the world” (at least for now)
- I think “agent” may finally have a widely enough agreed upon definition to be useful jargon now
- Recreating the Apollo AI adoption rate chart with GPT-5, Python and Pyodide
- My review of Claude’s new Code Interpreter, released under a very confusing name
- GPT-5 Thinking in ChatGPT (aka Research Goblin) is shockingly good at search
- V&A East Storehouse and Operation Mincemeat in London
- Open weight LLMs exhibit inconsistent performance across providers
- The Summer of Johann: prompt injections as far as the eye can see
- LLM 0.27, the annotated release notes: GPT-5 and improved tool calling
- Qwen3-4B-Thinking: “This is art—pelicans don’t ride bikes!”
- My Lethal Trifecta talk at the Bay Area AI Security Meetup
- The surprise deprecation of GPT-4o for ChatGPT consumers
- GPT-5: Key characteristics, pricing and model card
- OpenAI’s new open weight (Apache 2) models are really good
- ChatGPT agent’s user-agent
- The ChatGPT sharing dialog demonstrates how difficult it is to design privacy preferences
- Trying out Qwen3 Coder Flash using LM Studio and Open WebUI and LLM
- Reverse engineering some updates to Claude
- My 2.5 year old laptop can write Space Invaders in JavaScript now, using GLM-4.5 Air and MLX
- Using GitHub Spark to reverse engineer GitHub Spark
- Vibe scraping and vibe coding a schedule app for Open Sauce 2025 entirely on my phone
- Happy 20th birthday Django! Here’s my talk on Django Origins from Django’s 10th
- Grok: searching X for “from:elonmusk (Israel OR Palestine OR Hamas OR Gaza)”
- Phoenix.new is Fly’s entry into the prompt-driven app development space
- Trying out the new Gemini 2.5 model family
- The lethal trifecta for AI agents: private data, untrusted content, and external communication
- An Introduction to Google’s Approach to AI Agent Security
- Design Patterns for Securing LLM Agents against Prompt Injections
- Comma v0.1 1T and 2T—7B LLMs trained on openly licensed text
- The last six months in LLMs, illustrated by pelicans on bicycles
- Tips on prompting ChatGPT for UK technology secretary Peter Kyle
- How often do LLMs snitch? Recreating Theo’s SnitchBench with LLM
- Talking AI and jobs with Natasha Zouves for News Nation
- Large Language Models can run tools in your terminal with LLM 0.26
- Highlights from the Claude 4 system prompt
- Live blog: Claude 4 launch at Code with Claude
- I really don’t like ChatGPT’s new memory dossier
- Building software on top of Large Language Models
- Trying out llama.cpp’s new vision support
- Saying “hi” to Microsoft’s Phi-4-reasoning
- Feed a video to a vision LLM as a sequence of JPEG frames on the CLI (also LLM 0.25)
- Two publishers and three authors fail to understand what “vibe coding” means
- Understanding the recent criticism of the Chatbot Arena
- Qwen 3 offers a case study in how to effectively release a model
- Watching o3 guess a photo’s location is surreal, dystopian and wildly entertaining
- Exploring Promptfoo via Dave Guarino’s SNAP evals
- AI assisted search-based research actually works now
- Maybe Meta’s Llama claims to be open source because of the EU AI act
- Image segmentation using Gemini 2.5
- GPT-4.1: Three new million token input models from OpenAI, including their cheapest model yet
- CaMeL offers a promising new direction for mitigating prompt injection attacks
- Model Context Protocol has prompt injection security problems
- Long context support in LLM 0.24 using fragments and template plugins
- Initial impressions of Llama 4
- Putting Gemini 2.5 Pro through its paces
- Calling a wrap on my weeknotes
- New audio models from OpenAI, but how much can we rely on them?
- Not all AI-assisted programming is vibe coding (but vibe coding rocks)
- Adding AI-generated descriptions to my tools collection
- Notes on Google’s Gemma 3
- Here’s how I use LLMs to help me write code
- What’s new in the world of LLMs, for NICAR 2025
- I built an automaton called Squadron
- Hallucinations in code are the least dangerous form of LLM mistakes
- Notes from my Accessibility and Gen AI podcast appearance
- Structured data extraction from unstructured content using LLM schemas
- Initial impressions of GPT-4.5
- Claude 3.7 Sonnet, extended thinking and long output, llm-anthropic 0.14
- LLM 0.22, the annotated release notes
- Run LLMs on macOS using llm-mlx and Apple’s MLX framework
- URL-addressable Pyodide Python environments
- Using pip to install a Large Language Model that’s under 100MB
- OpenAI o3-mini, now available in LLM
- Anthropic’s new Citations API
- A selfish personal argument for releasing code as Open Source
- Six short video demos of LLM and Datasette projects
- DeepSeek-R1 and exploring DeepSeek-R1-Distill-Llama-8B
- My AI/LLM predictions for the next 1, 3 and 6 years, for Oxide and Friends
- Weeknotes: Starting 2025 a little slow
- Ending a year long posting streak
- I still don’t think companies serve you ads based on spying through your microphone
- Things we learned about LLMs in 2024
- Trying out QvQ—Qwen’s new visual reasoning model
- My approach to running a link blog
- December in LLMs has been a lot
- Live blog: the 12th day of OpenAI—“Early evals for OpenAI o3”
- Building Python tools with a one-shot prompt using uv run and Claude Projects
- Gemini 2.0 Flash “Thinking mode”
- Gemini 2.0 Flash: An outstanding multi-modal LLM with a sci-fi streaming mode
- ChatGPT Canvas can make API requests now, but it’s complicated
- I can now run a GPT-4 class model on my laptop
- Prompts.js
- First impressions of the new Amazon Nova LLMs (via a new llm-bedrock plugin)
- Storing times for human events
- Ask questions of SQLite databases and CSV/JSON files in your terminal
- Weeknotes: asynchronous LLMs, synchronous embeddings, and I kind of started a podcast
- Notes from Bing Chat—Our First Encounter With Manipulative AI
- Project: Civic Band—scraping and searching PDF meeting minutes from hundreds of municipalities
- Qwen2.5-Coder-32B is an LLM that can code well that runs on my Mac
- Visualizing local election results with Datasette, Observable and MapLibre GL
- Project: VERDAD—tracking misinformation in radio broadcasts using Gemini 1.5
- Claude 3.5 Haiku
- W̶e̶e̶k̶n̶o̶t̶e̶s̶ Monthnotes for October
- You can now run prompts against images, audio and video in your terminal using LLM
- Run a prompt to generate and execute jq programs using llm-jq
- Notes on the new Claude analysis JavaScript code execution tool
- Initial explorations of Anthropic’s new Computer Use capability
- Everything I built with Claude Artifacts this week
- Running Llama 3.2 Vision and Phi-3.5 Vision on a Mac with mistral.rs
- Experimenting with audio input and output for the OpenAI Chat Completion API
- Video scraping: extracting JSON data from a 35 second screen capture for less than 1/10th of a cent
- ChatGPT will happily write you a thinly disguised horoscope
- OpenAI DevDay: Let’s build developer tools, not digital God
- OpenAI DevDay 2024 live blog
- Weeknotes: Three podcasts, two trips and a new plugin system
- NotebookLM’s automatically generated podcasts are surprisingly effective
- Themes from DjangoCon US 2024
- DJP: A plugin system for Django
- Notes on using LLMs for code
- Things I’ve learned serving on the board of the Python Software Foundation
- Notes on OpenAI’s new o1 chain-of-thought models
- Notes from my appearance on the Software Misadventures Podcast
- Calling LLMs from client-side JavaScript, converting PDFs to HTML + weeknotes
- Building a tool showing how Gemini Pro can return bounding boxes for objects in images
- Claude’s API now supports CORS requests, enabling client-side applications
- Optimizing Datasette (and other weeknotes)
- django-http-debug, a new Django app mostly written by Claude
- Weeknotes: a staging environment, a Datasette alpha and a bunch of new LLMs
- Datasette 1.0a14: The annotated release notes
- Weeknotes: GPT-4o mini, LLM 0.15, sqlite-utils 3.37 and building a staging environment
- Imitation Intelligence, my keynote for PyCon US 2024
- Give people something to link to so they can talk about your features and ideas
- Weeknotes: a livestream, a surprise keynote and progress on Datasette Cloud billing
- Open challenges for AI engineering
- Building search-based RAG using Claude, Datasette and Val Town
- Weeknotes: Datasette Studio and a whole lot of blogging
- Language models on the command-line
- A homepage redesign for my blog’s 22nd birthday
- Thoughts on the WWDC 2024 keynote on Apple Intelligence
- Accidental prompt injection against RAG applications
- Training is not the same as chatting: ChatGPT and other LLMs don’t remember everything you say
- Weeknotes: PyCon US 2024
- ChatGPT in “4o” mode is not running the new features yet
- Slop is the new name for unwanted AI-generated content
- Weeknotes: more datasette-secrets, plus a mystery video project
- Weeknotes: Llama 3, AI for Data Journalism, llm-evals and datasette-secrets
- Options for accessing Llama 3 from the terminal using LLM
- AI for Data Journalism: demonstrating what we can do with this stuff right now
- Three major LLM releases in 24 hours (plus weeknotes)
- Building files-to-prompt entirely using Claude 3 Opus
- Running OCR against PDFs and images directly in your browser
- llm cmd undo last git commit—a new plugin for LLM
- Building and testing C extensions for SQLite with ChatGPT Code Interpreter
- Claude and ChatGPT for ad-hoc sidequests
- Weeknotes: the aftermath of NICAR
- The GPT-4 barrier has finally been broken
- Prompt injection and jailbreaking are not the same thing
- Interesting ideas in Observable Framework
- Weeknotes: Getting ready for NICAR
- The killer app of Gemini Pro 1.5 is video
- Weeknotes: a Datasette release, an LLM release and a bunch of new plugins
- Datasette 1.0a8: JavaScript plugins, new plugin hooks and plugin configuration in datasette.yaml
- LLM 0.13: The annotated release notes
- Weeknotes: datasette-test, datasette-build, PSF board retreat
- Talking about Open Source LLMs on Oxide and Friends
- Publish Python packages to PyPI with a python-lib cookiecutter template and GitHub Actions
- What I should have said about the term Artificial Intelligence
- It’s OK to call it Artificial Intelligence
- Weeknotes: Page caching and custom templates for Datasette Cloud
- Tom Scott, and the formidable power of escalating streaks
- Stuff we figured out about AI in 2023
- Recommendations to help mitigate prompt injection: limit the blast radius
- Many options for running Mistral models in your terminal using LLM
- The AI trust crisis
- Weeknotes: datasette-enrichments, datasette-comments, sqlite-chronicle
- Datasette Enrichments: a new plugin framework for augmenting your data
- llamafile is the new best way to run an LLM on your own computer
- Prompt injection explained, November 2023 edition
- I’m on the Newsroom Robots podcast, with thoughts on the OpenAI board
- Deciphering clues in a news article to understand how it was reported
- Weeknotes: DevDay, GitHub Universe, OpenAI chaos
- Exploring GPTs: ChatGPT in a trench coat?
- Financial sustainability for open source projects at GitHub Universe
- ospeak: a CLI tool for speaking text in the terminal via OpenAI
- DALL-E 3, GPT4All, PMTiles, sqlite-migrate, datasette-edit-schema
- Execute Jina embeddings with a CLI using llm-embed-jina
- Now add a walrus: Prompt engineering in DALL‑E 3
- Embeddings: What they are and why they matter
- Weeknotes: PyBay, AI Engineer Summit, Datasette metadata and JavaScript plugins
- Open questions for AI engineering
- Multi-modal prompt injection image attacks against GPT-4V
- Weeknotes: the Datasette Cloud API, a podcast appearance and more
- Things I’ve learned about building CLI tools in Python
- Talking Large Language Models with Rooftop Ruby
- Weeknotes: Embeddings, more embeddings and Datasette Cloud
- Build an image search engine with llm-clip, chat with models with llm chat
- LLM now provides tools for working with embeddings
- Datasette 1.0a4 and 1.0a5, plus weeknotes
- Making Large Language Models work for you
- Datasette Cloud, Datasette 1.0a3, llm-mlc and more
- How I make annotated presentations
- Weeknotes: Plugins for LLM, sqlite-utils and Datasette
- Catching up on the weird world of LLMs
- Run Llama 2 on your own Mac using LLM and Homebrew
- sqlite-utils now supports plugins
- Accessing Llama 2 from the command-line with the llm-replicate plugin
- Weeknotes: Self-hosted language models with LLM plugins, a new Datasette tutorial, a dozen package releases, a dozen TILs
- My LLM CLI tool now supports self-hosted language models via plugins
- Weeknotes: symbex, LLM prompt templates, a bit of a break
- Symbex: search Python code for functions and classes, then pipe them into a LLM
- Understanding GPT tokenizers
- It’s infuriatingly hard to understand how closed models train on their input
- Weeknotes: Parquet in Datasette Lite, various talks, more LLM hacking
- ChatGPT should include inline tips
- Lawyer cites fake cases invented by ChatGPT, judge is not amused
- llm, ttok and strip-tags—CLI tools for working with ChatGPT and other LLMs
- Delimiters won’t save you from prompt injection
- Weeknotes: sqlite-utils 3.31, download-esm, Python in a sandbox
- Big Opportunities in Small Data
- Midjourney 5.1
- Leaked Google document: “We Have No Moat, And Neither Does OpenAI”
- download-esm: a tool for downloading ECMAScript modules
- Prompt injection explained, with video, slides, and a transcript
- Weeknotes: Miscellaneous research into Rye, ChatGPT Code Interpreter and openai-to-sqlite
- Let’s be bear or bunny
- Enriching data with GPT3.5 and SQLite SQL functions
- The Dual LLM pattern for building AI assistants that can resist prompt injection
- Weeknotes: Citus Con, PyCon and three new niche museums
- Data analysis with SQLite and Python for PyCon 2023
- What’s in the RedPajama-Data-1T LLM training set
- Web LLM runs the vicuna-7b Large Language Model entirely in your browser, and it’s very impressive
- sqlite-history: tracking changes to SQLite tables using triggers (also weeknotes)
- Prompt injection: What’s the worst that can happen?
- Running Python micro-benchmarks using the ChatGPT Code Interpreter alpha
- Thoughts on AI safety in this era of increasingly powerful open source LLMs
- Working in public
- The Changelog podcast: LLMs break the internet
- We need to tell people ChatGPT will lie to them, not debate linguistics
- Semi-automating a Substack newsletter with an Observable notebook
- Weeknotes: A new llm CLI tool, plus automating my weeknotes and newsletter
- What AI can do for you on the Theory of Change podcast
- Think of language models like ChatGPT as a “calculator for words”
- AI-enhanced development makes me more ambitious with my projects
- I built a ChatGPT plugin to answer questions about data hosted in Datasette
- Don’t trust AI to talk accurately about itself: Bard wasn’t trained on Gmail
- Weeknotes: AI won’t slow down, a new newsletter and a huge Datasette refactor
- A conversation about prompt engineering with CBC Day 6
- Could you train a ChatGPT-beating model for $85,000 and run it in a browser?
- Stanford Alpaca, and the acceleration of on-device large language model development
- Large language models are having their Stable Diffusion moment
- ChatGPT couldn’t access the internet, even though it really looked like it could
- Weeknotes: NICAR, and an appearance on KQED Forum
- Thoughts and impressions of AI-assisted search from Bing
- In defense of prompt engineering
- I talked about Bing and tried to explain language models on live TV!
- Analytics: Hacker News v.s. a tweet from Elon Musk
- Bing: “I will not harm you unless you harm me first”
- Weeknotes: A bunch of things I learned this week, plus datasette-explain
- datasette-scraper, Big Local News and other weeknotes
- Exploring MusicCaps, the evaluation data released to accompany Google’s MusicLM text-to-music model
- Weeknotes: AI hacking and a SpatiaLite tutorial
- How to implement Q&A against your documentation with GPT3, embeddings and Datasette
- Datasette 0.64, with a warning about SpatiaLite
- 2022 in projects and blogging
- Weeknotes: Datasette 0.63.3, datasette-ripgrep
- Datasette 1.0a2: Upserts and finely grained permissions
- Over-engineering Secret Santa with Python cryptography and Datasette
- AI assisted learning: Learning Rust with ChatGPT, Copilot and Advent of Code
- Weeknotes: datasette-ephemeral-tables, datasette-export
- A new AI game: Give me ideas for crimes to do
- Datasette’s new JSON write API: The first alpha of Datasette 1.0
- Coping strategies for the serial project hoarder
- Weeknotes: Implementing a write API, Mastodon distractions
- Tracking Mastodon user numbers over time with a bucket of tricks
- Datasette is 5 today: a call for birthday presents
- Designing a write API for Datasette
- Mastodon is just blogs
- What to blog about
- It looks like I’m moving to Mastodon
- The Perfect Commit
- Datasette 0.63: The annotated release notes
- Weeknotes: DjangoCon, SQLite in Django, datasette-gunicorn
- Measuring traffic during the Half Moon Bay Pumpkin Festival
- Automating screenshots for the Datasette documentation using shot-scraper
- Weeknotes: Publishing data using Datasette Cloud
- Is the AI spell-casting metaphor harmful or helpful?
- Software engineering practices
- A tool to run caption extraction against online videos using Whisper and GitHub Issues/Actions
- Weeknotes: Datasette Cloud preview invitations
- Exploring 10m scraped Shutterstock videos used to train Meta’s Make-A-Video text-to-video model
- You can’t solve AI security problems with more AI
- Weeknotes: Datasette Lite, s3-credentials, shot-scraper, datasette-edit-templates and more
- I don’t know how to solve prompt injection
- Prompt injection attacks against GPT-3
- Exploring the training data behind Stable Diffusion
- Notes on the SQLite DuckDB paper
- Stable Diffusion is a really big deal
- Building a searchable archive for the San Francisco Microscopical Society
- Analyzing ScotRail audio announcements with Datasette—from prototype to production
- Plugin support for Datasette Lite
- Litestream backups for Datasette Cloud (and weeknotes)
- Weeknotes: Joining the board of the Python Software Foundation
- Weeknotes: Datasette, sqlite-utils, Datasette Desktop
- sqlite-comprehend: run AWS entity extraction against content in a SQLite database
- Using GPT-3 to explain how code works
- s3-ocr: Extract text from PDF files stored in an S3 bucket
- First impressions of DALL-E, generating images from text
- Joining CSV files in your browser using Datasette Lite
- Weeknotes: datasette-socrata, and the last 10%...
- A tiny web app to create images from OpenStreetMap maps
- Twenty years of my blog
- Weeknotes: Datasette Cloud ready to preview
- How to use the GPT-3 language model
- A Datasette tutorial written by GPT-3
- Weeknotes: Building Datasette Cloud on Fly Machines, Furo for documentation
- Bundling binary tools in Python wheels
- Weeknotes: Camping, a road trip and two new museums
- Weeknotes: Datasette Lite, nogil Python, HYTRADBOI
- Datasette Lite: a server-side Python web application running in a browser
- Automatically opening issues when tracked file content changes
- Weeknotes: Parallel SQL queries for Datasette, plus some middleware tricks
- Useful tricks with pip install URL and GitHub
- Building a Covid sewage Twitter bot (and other weeknotes)
- Pillar Point Stewards, pypi-to-sqlite, improvements to shot-scraper and appreciating datasette-dashboards
- Weeknotes: datasette-auth0
- Datasette 0.61: The annotated release notes
- SQLite Happy Hour—a Twitter Spaces conversation about three interesting projects building on SQLite
- Weeknotes: Tildes not dashes, and the big refactor
- Scraping web pages from the command line with shot-scraper
- Instantly create a GitHub repository to take screenshots of a web page
- Weeknotes: Distracted by Playwright
- shot-scraper: automated screenshots for documentation, built on Playwright
- Why I invented “dash encoding”, a new encoding scheme for URL paths
- Weeknotes: Datasette Tutorials
- Support open source that you use by paying the maintainers to talk to your team
- Google Drive to SQLite
- Using SQLite and Datasette with Fly Volumes
- Help scraping: track changes to CLI tools by recording their --help using Git
- Writing better release notes
- Weeknotes: python_requires, documentation SEO
- Weeknotes: s3-credentials prefix and Datasette 0.60
- Datasette 0.60: The annotated release notes
- How I build a feature
- What’s new in sqlite-utils 3.20 and 3.21: --lines, --text, --convert
- Weeknotes: Taking a break in Moss Landing