<?xml version="1.0" encoding="utf-8"?>
<feed xml:lang="en-us" xmlns="http://www.w3.org/2005/Atom"><title>Simon Willison's Weblog: GPT-5</title><link href="http://simonwillison.net/" rel="alternate"/><link href="http://simonwillison.net/series/gpt-5.atom" rel="self"/><id>http://simonwillison.net/</id><updated>2025-09-09T06:47:49+00:00</updated><author><name>Simon Willison</name></author><entry><title>Recreating the Apollo AI adoption rate chart with GPT-5, Python and Pyodide</title><link href="https://simonwillison.net/2025/Sep/9/apollo-ai-adoption/#atom-series" rel="alternate"/><published>2025-09-09T06:47:49+00:00</published><updated>2025-09-09T06:47:49+00:00</updated><id>https://simonwillison.net/2025/Sep/9/apollo-ai-adoption/#atom-series</id><summary type="html">
    &lt;p&gt;Apollo Global Management's "Chief Economist" Dr. Torsten Sløk released &lt;a href="https://www.apolloacademy.com/ai-adoption-rate-trending-down-for-large-companies/"&gt;this interesting chart&lt;/a&gt; which appears to show a slowdown in AI adoption rates among large (&amp;gt;250 employees) companies:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/apollo-ai-chart.jpg" alt="AI adoption rates starting to decline for larger firms. A chart of AI adoption rate by firm size. Includes lines for 250+, 100-249, 50-99, 20-49, 10-19, 5-8 and 1-4 sized organizations. Chart starts in November 2023 with percentages ranging from 3 to 5, then all groups grow through August 2025 albeit with the 250+ group having a higher score than the others. That 25+ group peaks in Jul5 2025 at around 14% and then appears to slope slightly downwards to 12% by August. Some of the other lines also start to tip down, though not as much." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;Here's the full description that accompanied the chart:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The US Census Bureau conducts a biweekly survey of 1.2 million firms, and one question is whether a business has used AI tools such as machine learning, natural language processing, virtual agents or voice recognition to help produce goods or services in the past two weeks. Recent data by firm size shows that AI adoption has been declining among companies with more than 250 employees, see chart below.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(My first thought on seeing that chart is that I hope it represents the &lt;em&gt;peak of inflated expectations&lt;/em&gt; leading into the &lt;em&gt;trough of dissillusionment&lt;/em&gt; in the &lt;a href="https://en.wikipedia.org/wiki/Gartner_hype_cycle"&gt;Gartner Hype Cycle&lt;/a&gt; (which Wikipedia calls "largely disputed, with studies pointing to it being inconsistently true at best"), since that means we might be reaching the end of the initial hype phase and heading towards the &lt;em&gt;slope of enlightenment&lt;/em&gt;.)&lt;/p&gt;
&lt;h4 id="finding-the-us-census-data-with-gpt-5-search"&gt;Finding the US Census data with GPT-5 search&lt;/h4&gt;
&lt;p&gt;This is the first I'd heard of the US Census Bureau running a biweekly (that's once every two weeks) survey about AI!&lt;/p&gt;
&lt;p&gt;I decided to track down the numbers and see if I could recreate the chart myself. And since &lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/"&gt;GPT-5 is really good at search now&lt;/a&gt; I fed it the following prompt to see how well it could do:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;&amp;gt; The US Census Bureau conducts a biweekly survey of 1.2 million firms, and one question is whether a business has used AI tools such as machine learning, natural language processing, virtual agents or voice recognition to help produce goods or services in the past two weeks. Recent data by firm size shows that AI adoption has been declining among companies with more than 250 employees, see chart below.&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Find me that original data&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It took 1m19s to &lt;a href="https://chatgpt.com/share/68bf48cf-0e70-8006-a045-96fa8e7ddfc1"&gt;find exactly what I needed&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Here’s the original U.S. Census Bureau source for that series:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BTOS “Employment size class” time series (XLSX)&lt;/strong&gt; — biweekly shares of firms answering &lt;strong&gt;Yes&lt;/strong&gt; to “In the last two weeks, did this business use Artificial Intelligence (AI) in producing goods or services?”, broken out by firm-size buckets (incl. &lt;strong&gt;250+ employees&lt;/strong&gt;). Coverage: &lt;strong&gt;Sep 11, 2023 → Aug 24, 2025&lt;/strong&gt;. (&lt;a href="https://www.census.gov/hfp/btos/data_downloads"&gt;Census.gov&lt;/a&gt;) [...]&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;That &lt;a href="https://www.census.gov/hfp/btos/data_downloads"&gt;Census page&lt;/a&gt; was not &lt;em&gt;at all&lt;/em&gt; obvious. Thankfully GPT-5 had tipped me off to the "Employment size class" file, this link here:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/census-page.jpg" alt="US Census website. Business Trends and Outlook Survey, Updated August 28, 2025. Current Data has 6 visible XLSX files with names like WFH Supplement, WFH Questions 27-29, National, Sectur, Subsector and Emplomyent size class. A red arrow highlights that last one." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;So I downloaded that file, and confirmed that it was indeed a spreadsheet containing the data I wanted (in among all sorts of other survey questions). Here's &lt;a href="https://static.simonwillison.net/static/cors-allow/2025/Employment-Size-Class-Sep-2025.xlsx"&gt;a 374KB XLSX copy&lt;/a&gt; of the file I downloaded.&lt;/p&gt;
&lt;h4 id="recreating-the-chart-with-gpt-5-code-interpreter"&gt;Recreating the chart with GPT-5 code interpreter&lt;/h4&gt;
&lt;p&gt;So what should I do with it now? I decided to see if GPT-5 could turn the spreadsheet back into that original chart, using Python running in its &lt;a href="https://simonwillison.net/tags/code-interpreter/"&gt;code interpreter&lt;/a&gt; tool.&lt;/p&gt;
&lt;p&gt;So I uploaded the XLSX file back to ChatGPT, dropped in a screenshot of the Apollo chart and prompted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Use this data to recreate this chart using python&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/chart-prompt.jpg" alt="ChatGPT. I dropped in a screenshot of the chart, uploaded the spreadsheet which turned into an inline table browser UI and prompted it to recreate the chart using python." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;I thought this was a pretty tall order, but it's always worth throwing big challenges at an LLM to learn from how well it does.&lt;/p&gt;
&lt;p&gt;It &lt;em&gt;really worked hard on this&lt;/em&gt;. I didn't time it exactly but it spent at least 7 minutes "reasoning" across 5 different thinking blocks, interspersed with over a dozen Python analysis sessions. It used &lt;code&gt;pandas&lt;/code&gt; and &lt;code&gt;numpy&lt;/code&gt; to explore the uploaded spreadsheet and find the right figures, then tried several attempts at plotting with &lt;code&gt;matplotlib&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;As far as I can tell GPT-5 in ChatGPT can now feed charts it creates back into its own vision model, because it appeared to render a broken (empty) chart and then keep on trying to get it working.&lt;/p&gt;
&lt;p&gt;It found a data dictionary in the last tab of the spreadsheet and used that to build a lookup table matching the letters &lt;code&gt;A&lt;/code&gt; through &lt;code&gt;G&lt;/code&gt; to the actual employee size buckets.&lt;/p&gt;
&lt;p&gt;At the end of the process it spat out this chart:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/recreated-chart-1.jpg" alt="matplotlib chart. The title is AI adoption rates starting to decline for larger firms, though there's a typography glitch in that title. It has a neat legend for the different size ranges, then a set of lines that look about right compared to the above graph - but they are more spiky and the numbers appear to trend up again at the end of the chart." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;At first glance I thought it had nailed it... but then I compared the chart more closely with the Apollo original and spotted some definite discrepancies. GPT-5's chart peaked at 14.5% but the highest value in Apollo's was more like 13.5%. The GPT-5 chart was spikier - and most interestingly it included a clear uptick in the last data point where Apollo's had trended downwards.&lt;/p&gt;
&lt;p&gt;I decided it was time to look at the actual data. I opened up the spreadsheet in Numbers, found the AI question columns and manually reviewed them. They seemed to match the GPT-5 chart results - so why the difference to Apollo's?&lt;/p&gt;
&lt;p&gt;Then I noticed a crucial detail in the Apollo chart that I had cropped out of my original screenshot!&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Note: Data is six-survey moving average.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So I told ChatGPT:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Do the first question, plot it as a six survey rolling average&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I asked for the first question because it turned out there were two that were relevant in the survey spreadsheet.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;In the last two weeks, did this business use Artificial Intelligence (AI) in producing goods or services? (Examples of AI: machine learning, natural language processing, virtual agents, voice recognition, etc.)&lt;/li&gt;
&lt;li&gt;During the next six months, do you think this business will be using Artificial Intelligence (AI) in producing goods or services? (Examples of AI: machine learning, natural language processing, virtual agents, voice recognition, etc.)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;It churned away for a little longer, added this code to the script:&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;# Compute 6-survey rolling average (biweekly cadence → ~12 weeks)&lt;/span&gt;
&lt;span class="pl-s1"&gt;rolled&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;wide&lt;/span&gt;.&lt;span class="pl-c1"&gt;rolling&lt;/span&gt;(&lt;span class="pl-s1"&gt;window&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;6&lt;/span&gt;, &lt;span class="pl-s1"&gt;min_periods&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;6&lt;/span&gt;).&lt;span class="pl-c1"&gt;mean&lt;/span&gt;()&lt;/pre&gt;
&lt;p&gt;And popped out this chart (after I told it to fix the glitch in the title):&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/recreated-chart-2.jpg" alt="Second chart. This time the lines are basically an exact match for the Apollo one." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;I think it's done it! This is a very solid match for the Apollo original, recreated using &lt;code&gt;matplotlib&lt;/code&gt; and &lt;code&gt;pandas&lt;/code&gt; from the same underlying source data from the US Census.&lt;/p&gt;
&lt;p&gt;Here's the full Python code it wrote, which I think is quite readable (in as much as Pandas code can be):&lt;/p&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;pandas&lt;/span&gt; &lt;span class="pl-k"&gt;as&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;matplotlib&lt;/span&gt;.&lt;span class="pl-s1"&gt;pyplot&lt;/span&gt; &lt;span class="pl-k"&gt;as&lt;/span&gt; &lt;span class="pl-s1"&gt;plt&lt;/span&gt;
&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;matplotlib&lt;/span&gt;.&lt;span class="pl-s1"&gt;ticker&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-v"&gt;PercentFormatter&lt;/span&gt;

&lt;span class="pl-s1"&gt;path&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;"/mnt/data/Employment Size Class.xlsx"&lt;/span&gt;

&lt;span class="pl-s1"&gt;resp&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;read_excel&lt;/span&gt;(&lt;span class="pl-s1"&gt;path&lt;/span&gt;, &lt;span class="pl-s1"&gt;sheet_name&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"Response Estimates"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;dates&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;read_excel&lt;/span&gt;(&lt;span class="pl-s1"&gt;path&lt;/span&gt;, &lt;span class="pl-s1"&gt;sheet_name&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"Collection and Reference Dates"&lt;/span&gt;)

&lt;span class="pl-s1"&gt;is_current&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;resp&lt;/span&gt;[&lt;span class="pl-s"&gt;"Question"&lt;/span&gt;].&lt;span class="pl-c1"&gt;astype&lt;/span&gt;(&lt;span class="pl-s1"&gt;str&lt;/span&gt;).&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;strip&lt;/span&gt;().&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;startswith&lt;/span&gt;(&lt;span class="pl-s"&gt;"In the last two weeks"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;ai_yes&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;resp&lt;/span&gt;[&lt;span class="pl-s1"&gt;is_current&lt;/span&gt; &lt;span class="pl-c1"&gt;&amp;amp;&lt;/span&gt; &lt;span class="pl-s1"&gt;resp&lt;/span&gt;[&lt;span class="pl-s"&gt;"Answer"&lt;/span&gt;].&lt;span class="pl-c1"&gt;astype&lt;/span&gt;(&lt;span class="pl-s1"&gt;str&lt;/span&gt;).&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;strip&lt;/span&gt;().&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;lower&lt;/span&gt;().&lt;span class="pl-c1"&gt;eq&lt;/span&gt;(&lt;span class="pl-s"&gt;"yes"&lt;/span&gt;)].&lt;span class="pl-c1"&gt;copy&lt;/span&gt;()

&lt;span class="pl-s1"&gt;code_to_bucket&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; {&lt;span class="pl-s"&gt;"A"&lt;/span&gt;:&lt;span class="pl-s"&gt;"1-4"&lt;/span&gt;,&lt;span class="pl-s"&gt;"B"&lt;/span&gt;:&lt;span class="pl-s"&gt;"5-9"&lt;/span&gt;,&lt;span class="pl-s"&gt;"C"&lt;/span&gt;:&lt;span class="pl-s"&gt;"10-19"&lt;/span&gt;,&lt;span class="pl-s"&gt;"D"&lt;/span&gt;:&lt;span class="pl-s"&gt;"20-49"&lt;/span&gt;,&lt;span class="pl-s"&gt;"E"&lt;/span&gt;:&lt;span class="pl-s"&gt;"50-99"&lt;/span&gt;,&lt;span class="pl-s"&gt;"F"&lt;/span&gt;:&lt;span class="pl-s"&gt;"100-249"&lt;/span&gt;,&lt;span class="pl-s"&gt;"G"&lt;/span&gt;:&lt;span class="pl-s"&gt;"250 or more employees"&lt;/span&gt;}
&lt;span class="pl-s1"&gt;ai_yes&lt;/span&gt;[&lt;span class="pl-s"&gt;"Bucket"&lt;/span&gt;] &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;ai_yes&lt;/span&gt;[&lt;span class="pl-s"&gt;"Empsize"&lt;/span&gt;].&lt;span class="pl-c1"&gt;map&lt;/span&gt;(&lt;span class="pl-s1"&gt;code_to_bucket&lt;/span&gt;)

&lt;span class="pl-s1"&gt;period_cols&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; [&lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; &lt;span class="pl-s1"&gt;ai_yes&lt;/span&gt;.&lt;span class="pl-c1"&gt;columns&lt;/span&gt; &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-en"&gt;str&lt;/span&gt;(&lt;span class="pl-s1"&gt;c&lt;/span&gt;).&lt;span class="pl-c1"&gt;isdigit&lt;/span&gt;() &lt;span class="pl-c1"&gt;and&lt;/span&gt; &lt;span class="pl-en"&gt;len&lt;/span&gt;(&lt;span class="pl-en"&gt;str&lt;/span&gt;(&lt;span class="pl-s1"&gt;c&lt;/span&gt;))&lt;span class="pl-c1"&gt;==&lt;/span&gt;&lt;span class="pl-c1"&gt;6&lt;/span&gt;]
&lt;span class="pl-s1"&gt;long&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;ai_yes&lt;/span&gt;.&lt;span class="pl-c1"&gt;melt&lt;/span&gt;(&lt;span class="pl-s1"&gt;id_vars&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;[&lt;span class="pl-s"&gt;"Bucket"&lt;/span&gt;], &lt;span class="pl-s1"&gt;value_vars&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s1"&gt;period_cols&lt;/span&gt;, &lt;span class="pl-s1"&gt;var_name&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;, &lt;span class="pl-s1"&gt;value_name&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"value"&lt;/span&gt;)

&lt;span class="pl-s1"&gt;dates&lt;/span&gt;[&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;] &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;dates&lt;/span&gt;[&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;].&lt;span class="pl-c1"&gt;astype&lt;/span&gt;(&lt;span class="pl-s1"&gt;str&lt;/span&gt;)
&lt;span class="pl-s1"&gt;long&lt;/span&gt;[&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;] &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;long&lt;/span&gt;[&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;].&lt;span class="pl-c1"&gt;astype&lt;/span&gt;(&lt;span class="pl-s1"&gt;str&lt;/span&gt;)
&lt;span class="pl-s1"&gt;merged&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;long&lt;/span&gt;.&lt;span class="pl-c1"&gt;merge&lt;/span&gt;(&lt;span class="pl-s1"&gt;dates&lt;/span&gt;[[&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;,&lt;span class="pl-s"&gt;"Ref End"&lt;/span&gt;]], &lt;span class="pl-s1"&gt;on&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"Smpdt"&lt;/span&gt;, &lt;span class="pl-s1"&gt;how&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"left"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;merged&lt;/span&gt;[&lt;span class="pl-s"&gt;"date"&lt;/span&gt;] &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;to_datetime&lt;/span&gt;(&lt;span class="pl-s1"&gt;merged&lt;/span&gt;[&lt;span class="pl-s"&gt;"Ref End"&lt;/span&gt;], &lt;span class="pl-s1"&gt;errors&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"coerce"&lt;/span&gt;)

&lt;span class="pl-s1"&gt;merged&lt;/span&gt;[&lt;span class="pl-s"&gt;"value"&lt;/span&gt;] &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;to_numeric&lt;/span&gt;(&lt;span class="pl-s1"&gt;long&lt;/span&gt;[&lt;span class="pl-s"&gt;"value"&lt;/span&gt;].&lt;span class="pl-c1"&gt;astype&lt;/span&gt;(&lt;span class="pl-s1"&gt;str&lt;/span&gt;).&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;replace&lt;/span&gt;(&lt;span class="pl-s"&gt;"%"&lt;/span&gt;,&lt;span class="pl-s"&gt;""&lt;/span&gt;,&lt;span class="pl-s1"&gt;regex&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;False&lt;/span&gt;).&lt;span class="pl-c1"&gt;str&lt;/span&gt;.&lt;span class="pl-c1"&gt;strip&lt;/span&gt;(), &lt;span class="pl-s1"&gt;errors&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"coerce"&lt;/span&gt;)

&lt;span class="pl-s1"&gt;order&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; [&lt;span class="pl-s"&gt;"250 or more employees"&lt;/span&gt;,&lt;span class="pl-s"&gt;"100-249"&lt;/span&gt;,&lt;span class="pl-s"&gt;"50-99"&lt;/span&gt;,&lt;span class="pl-s"&gt;"20-49"&lt;/span&gt;,&lt;span class="pl-s"&gt;"10-19"&lt;/span&gt;,&lt;span class="pl-s"&gt;"5-9"&lt;/span&gt;,&lt;span class="pl-s"&gt;"1-4"&lt;/span&gt;]
&lt;span class="pl-s1"&gt;wide&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;merged&lt;/span&gt;.&lt;span class="pl-c1"&gt;pivot_table&lt;/span&gt;(&lt;span class="pl-s1"&gt;index&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"date"&lt;/span&gt;, &lt;span class="pl-s1"&gt;columns&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"Bucket"&lt;/span&gt;, &lt;span class="pl-s1"&gt;values&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"value"&lt;/span&gt;, &lt;span class="pl-s1"&gt;aggfunc&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"mean"&lt;/span&gt;).&lt;span class="pl-c1"&gt;sort_index&lt;/span&gt;()
&lt;span class="pl-s1"&gt;wide&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;wide&lt;/span&gt;[[&lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; &lt;span class="pl-s1"&gt;order&lt;/span&gt; &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-s1"&gt;c&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; &lt;span class="pl-s1"&gt;wide&lt;/span&gt;.&lt;span class="pl-c1"&gt;columns&lt;/span&gt;]]
&lt;span class="pl-s1"&gt;rolled&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;wide&lt;/span&gt;.&lt;span class="pl-c1"&gt;rolling&lt;/span&gt;(&lt;span class="pl-s1"&gt;window&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;6&lt;/span&gt;, &lt;span class="pl-s1"&gt;min_periods&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;6&lt;/span&gt;).&lt;span class="pl-c1"&gt;mean&lt;/span&gt;()

&lt;span class="pl-s1"&gt;start&lt;/span&gt;, &lt;span class="pl-s1"&gt;end&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;Timestamp&lt;/span&gt;(&lt;span class="pl-s"&gt;"2023-11-01"&lt;/span&gt;), &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;Timestamp&lt;/span&gt;(&lt;span class="pl-s"&gt;"2025-08-31"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;rolled_win&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;rolled&lt;/span&gt;.&lt;span class="pl-c1"&gt;loc&lt;/span&gt;[(&lt;span class="pl-s1"&gt;rolled&lt;/span&gt;.&lt;span class="pl-c1"&gt;index&lt;/span&gt; &lt;span class="pl-c1"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;start&lt;/span&gt;) &lt;span class="pl-c1"&gt;&amp;amp;&lt;/span&gt; (&lt;span class="pl-s1"&gt;rolled&lt;/span&gt;.&lt;span class="pl-c1"&gt;index&lt;/span&gt; &lt;span class="pl-c1"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;end&lt;/span&gt;)]

&lt;span class="pl-s1"&gt;fig&lt;/span&gt;, &lt;span class="pl-s1"&gt;ax&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;plt&lt;/span&gt;.&lt;span class="pl-c1"&gt;subplots&lt;/span&gt;(&lt;span class="pl-s1"&gt;figsize&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;(&lt;span class="pl-c1"&gt;12&lt;/span&gt;, &lt;span class="pl-c1"&gt;6&lt;/span&gt;))
&lt;span class="pl-k"&gt;for&lt;/span&gt; &lt;span class="pl-s1"&gt;col&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; &lt;span class="pl-s1"&gt;order&lt;/span&gt;:
    &lt;span class="pl-k"&gt;if&lt;/span&gt; &lt;span class="pl-s1"&gt;col&lt;/span&gt; &lt;span class="pl-c1"&gt;in&lt;/span&gt; &lt;span class="pl-s1"&gt;rolled_win&lt;/span&gt;.&lt;span class="pl-c1"&gt;columns&lt;/span&gt;:
        &lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;plot&lt;/span&gt;(&lt;span class="pl-s1"&gt;rolled_win&lt;/span&gt;.&lt;span class="pl-c1"&gt;index&lt;/span&gt;, &lt;span class="pl-s1"&gt;rolled_win&lt;/span&gt;[&lt;span class="pl-s1"&gt;col&lt;/span&gt;], &lt;span class="pl-s1"&gt;label&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s1"&gt;col&lt;/span&gt;, &lt;span class="pl-s1"&gt;linewidth&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;2&lt;/span&gt;)

&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;set_title&lt;/span&gt;(&lt;span class="pl-s"&gt;"AI adoption (last two weeks) — 6‑survey rolling average"&lt;/span&gt;, &lt;span class="pl-s1"&gt;pad&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;16&lt;/span&gt;)
&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;yaxis&lt;/span&gt;.&lt;span class="pl-c1"&gt;set_major_formatter&lt;/span&gt;(&lt;span class="pl-en"&gt;PercentFormatter&lt;/span&gt;(&lt;span class="pl-c1"&gt;100&lt;/span&gt;))
&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;set_ylabel&lt;/span&gt;(&lt;span class="pl-s"&gt;"%"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;set_xlabel&lt;/span&gt;(&lt;span class="pl-s"&gt;""&lt;/span&gt;)
&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;grid&lt;/span&gt;(&lt;span class="pl-c1"&gt;True&lt;/span&gt;, &lt;span class="pl-s1"&gt;alpha&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;0.25&lt;/span&gt;, &lt;span class="pl-s1"&gt;linestyle&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"--"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;ax&lt;/span&gt;.&lt;span class="pl-c1"&gt;legend&lt;/span&gt;(&lt;span class="pl-s1"&gt;title&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;None&lt;/span&gt;, &lt;span class="pl-s1"&gt;loc&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"upper left"&lt;/span&gt;, &lt;span class="pl-s1"&gt;ncols&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;2&lt;/span&gt;, &lt;span class="pl-s1"&gt;frameon&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;False&lt;/span&gt;)
&lt;span class="pl-s1"&gt;plt&lt;/span&gt;.&lt;span class="pl-c1"&gt;tight_layout&lt;/span&gt;()

&lt;span class="pl-s1"&gt;png_path&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;"/mnt/data/ai_adoption_rolling6_by_firm_size.png"&lt;/span&gt;
&lt;span class="pl-s1"&gt;svg_path&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;"/mnt/data/ai_adoption_rolling6_by_firm_size.svg"&lt;/span&gt;
&lt;span class="pl-s1"&gt;plt&lt;/span&gt;.&lt;span class="pl-c1"&gt;savefig&lt;/span&gt;(&lt;span class="pl-s1"&gt;png_path&lt;/span&gt;, &lt;span class="pl-s1"&gt;dpi&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-c1"&gt;200&lt;/span&gt;, &lt;span class="pl-s1"&gt;bbox_inches&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"tight"&lt;/span&gt;)
&lt;span class="pl-s1"&gt;plt&lt;/span&gt;.&lt;span class="pl-c1"&gt;savefig&lt;/span&gt;(&lt;span class="pl-s1"&gt;svg_path&lt;/span&gt;, &lt;span class="pl-s1"&gt;bbox_inches&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;"tight"&lt;/span&gt;)&lt;/pre&gt;
&lt;p&gt;I like how it generated &lt;a href="https://static.simonwillison.net/static/2025/ai_adoption_rolling6_by_firm_size.svg"&gt;an SVG version&lt;/a&gt; of the chart without me even asking for it.&lt;/p&gt;
&lt;p&gt;You can access &lt;a href="https://chatgpt.com/share/68bf48cf-0e70-8006-a045-96fa8e7ddfc1"&gt;the ChatGPT transcript&lt;/a&gt; to see full details of everything it did.&lt;/p&gt;
&lt;h4 id="rendering-that-chart-client-side-using-pyodide"&gt;Rendering that chart client-side using Pyodide&lt;/h4&gt;
&lt;p&gt;I had one more challenge to try out. Could I render that same chart entirely in the browser using &lt;a href="https://pyodide.org/en/stable/"&gt;Pyodide&lt;/a&gt;, which can execute both Pandas and Matplotlib?&lt;/p&gt;
&lt;p&gt;I fired up a new ChatGPT GPT-5 session and prompted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Build a canvas that loads Pyodide and uses it to render an example bar chart with pandas and matplotlib and then displays that on the page&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;My goal here was simply to see if I could get a proof of concept of a chart rendered, ideally using the Canvas feature of ChatGPT. Canvas is OpenAI's version of Claude Artifacts, which lets the model write and then execute HTML and JavaScript directly in the ChatGPT interface.&lt;/p&gt;
&lt;p&gt;It worked! Here's &lt;a href="https://chatgpt.com/c/68bf2993-ca94-832a-a95e-fb225911c0a6"&gt;the transcript&lt;/a&gt; and here's &lt;a href="https://tools.simonwillison.net/pyodide-bar-chart"&gt;what it built me&lt;/a&gt;, exported  to my &lt;a href="https://tools.simonwillison.net/"&gt;tools.simonwillison.net&lt;/a&gt; GitHub Pages site (&lt;a href="https://github.com/simonw/tools/blob/main/pyodide-bar-chart.html"&gt;source code here&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/pyodide-matplotlib.jpg" alt="Screenshot of a web application demonstrating Pyodide integration. Header reads &amp;quot;Pyodide + pandas + matplotlib — Bar Chart&amp;quot; with subtitle &amp;quot;This page loads Pyodide in the browser, uses pandas to prep some data, renders a bar chart with matplotlib, and displays it below — all client-side.&amp;quot; Left panel shows terminal output: &amp;quot;Ready&amp;quot;, &amp;quot;# Python environment ready&amp;quot;, &amp;quot;• pandas 2.2.0&amp;quot;, &amp;quot;• numpy 1.26.4&amp;quot;, &amp;quot;• matplotlib 3.5.2&amp;quot;, &amp;quot;Running chart code...&amp;quot;, &amp;quot;Done. Chart updated.&amp;quot; with &amp;quot;Re-run demo&amp;quot; and &amp;quot;Show Python&amp;quot; buttons. Footer note: &amp;quot;CDN: pyodide, pandas, numpy, matplotlib are fetched on demand. First run may take a few seconds.&amp;quot; Right panel displays a bar chart titled &amp;quot;Example Bar Chart (pandas + matplotlib in Pyodide)&amp;quot; showing blue bars for months Jan through Jun with values approximately: Jan(125), Feb(130), Mar(80), Apr(85), May(85), Jun(120). Y-axis labeled &amp;quot;Streams&amp;quot; ranges 0-120, X-axis labeled &amp;quot;Month&amp;quot;." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;I've now proven to myself that I can render those Python charts directly in the browser. Next step: recreate the Apollo chart.&lt;/p&gt;
&lt;p&gt;I knew it would need a way to load the spreadsheet that was CORS-enabled. I uploaded my copy to my &lt;code&gt;/static/cors-allow/2025/...&lt;/code&gt; directory (configured in Cloudflare to serve CORS headers), pasted in the finished plotting code from earlier and told ChatGPT:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Now update it to have less explanatory text and a less exciting design (black on white is fine) and run the equivalent of this:&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;(... pasted in Python code from earlier ...)&lt;/p&gt;
&lt;p&gt;&lt;code&gt;Load the XLSX sheet from https://static.simonwillison.net/static/cors-allow/2025/Employment-Size-Class-Sep-2025.xlsx&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It didn't quite work - I got an error about &lt;code&gt;openpyxl&lt;/code&gt; which I manually researched the fix for and prompted:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;Use await micropip.install("openpyxl") to install openpyxl - instead of using loadPackage&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I had to paste in another error message:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;zipfile.BadZipFile: File is not a zip file&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Then one about a &lt;code&gt;SyntaxError: unmatched ')'&lt;/code&gt; and a &lt;code&gt;TypeError: Legend.__init__() got an unexpected keyword argument 'ncols'&lt;/code&gt; - copying and pasting error messages remains a frustrating but necessary part of the vibe-coding loop.&lt;/p&gt;
&lt;p&gt;... but with those fixes in place, the resulting code worked! Visit &lt;a href="https://tools.simonwillison.net/ai-adoption"&gt;tools.simonwillison.net/ai-adoption&lt;/a&gt; to see the final result:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/recreated-chart-pyodide.jpg" alt="Web page. Title is AI adoption - 6-survey rolling average. Has a Run, Downlaed PNG, Downlaod SVG button. Panel on the left says Loading Python... Fetcing packages numpy, pandas, matplotlib. Installing openpyxl via micropop... ready. Running. Done. Right hand panel shows the rendered chart." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;Here's the code for that page, &lt;a href="https://github.com/simonw/tools/blob/main/ai-adoption.html"&gt;170 lines&lt;/a&gt; all-in of HTML, CSS, JavaScript and Python.&lt;/p&gt;
&lt;h4 id="what-i-ve-learned-from-this"&gt;What I've learned from this&lt;/h4&gt;
&lt;p&gt;This was another of those curiosity-inspired investigations that turned into a whole set of useful lessons.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT-5 is great at tracking down US Census data, no matter how difficult their site is to understand if you don't work with their data often&lt;/li&gt;
&lt;li&gt;It can do a very good job of turning data + a screenshot of a chart into a recreation of that chart using code interpreter, Pandas and matplotlib&lt;/li&gt;
&lt;li&gt;Running Python + matplotlib in a browser via Pyodide is very easy and only takes a few dozen lines of code&lt;/li&gt;
&lt;li&gt;Fetching an XLSX sheet into Pyodide is only a small extra step using &lt;code&gt;pyfetch&lt;/code&gt; and &lt;code&gt;openpyxl&lt;/code&gt;:
&lt;pre style="margin-top: 0.5em"&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;micropip&lt;/span&gt;
&lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-s1"&gt;micropip&lt;/span&gt;.&lt;span class="pl-c1"&gt;install&lt;/span&gt;(&lt;span class="pl-s"&gt;"openpyxl"&lt;/span&gt;)
&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;pyodide&lt;/span&gt;.&lt;span class="pl-s1"&gt;http&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;pyfetch&lt;/span&gt;
&lt;span class="pl-s1"&gt;resp_fetch&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-en"&gt;pyfetch&lt;/span&gt;(&lt;span class="pl-c1"&gt;URL&lt;/span&gt;)
&lt;span class="pl-s1"&gt;wb_bytes&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-k"&gt;await&lt;/span&gt; &lt;span class="pl-s1"&gt;resp_fetch&lt;/span&gt;.&lt;span class="pl-c1"&gt;bytes&lt;/span&gt;()
&lt;span class="pl-s1"&gt;xf&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s1"&gt;pd&lt;/span&gt;.&lt;span class="pl-c1"&gt;ExcelFile&lt;/span&gt;(&lt;span class="pl-s1"&gt;io&lt;/span&gt;.&lt;span class="pl-c1"&gt;BytesIO&lt;/span&gt;(&lt;span class="pl-s1"&gt;wb_bytes&lt;/span&gt;), &lt;span class="pl-s1"&gt;engine&lt;/span&gt;&lt;span class="pl-c1"&gt;=&lt;/span&gt;&lt;span class="pl-s"&gt;'openpyxl'&lt;/span&gt;)&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;Another new-to-me pattern: you can render an image to the DOM from Pyodide code &lt;a href="https://github.com/simonw/tools/blob/cf26ed8a6f243159bdc90a3d88f818261732103f/ai-adoption.html#L124"&gt;like this&lt;/a&gt;:
&lt;pre style="margin-top: 0.5em"&gt;&lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s1"&gt;js&lt;/span&gt; &lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-s1"&gt;document&lt;/span&gt;
&lt;span class="pl-s1"&gt;document&lt;/span&gt;.&lt;span class="pl-c1"&gt;getElementById&lt;/span&gt;(&lt;span class="pl-s"&gt;'plot'&lt;/span&gt;).&lt;span class="pl-c1"&gt;src&lt;/span&gt; &lt;span class="pl-c1"&gt;=&lt;/span&gt; &lt;span class="pl-s"&gt;'data:image/png;base64,'&lt;/span&gt; &lt;span class="pl-c1"&gt;+&lt;/span&gt; &lt;span class="pl-s1"&gt;img_b64&lt;/span&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I will most definitely be using these techniques again in future.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update&lt;/strong&gt;: Coincidentally Claude released their own upgraded equivalent to ChatGPT Code Interpreter later on the day that I published this story, so I &lt;a href="https://simonwillison.net/2025/Sep/9/claude-code-interpreter/#something-much-harder-recreating-the-ai-adoption-chart"&gt;ran the same chart recreation experiment&lt;/a&gt; against Claude Sonnet 4 to see how it compared.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/census"&gt;census&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/data-journalism"&gt;data-journalism&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/javascript"&gt;javascript&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/python"&gt;python&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tools"&gt;tools&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/visualization"&gt;visualization&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pyodide"&gt;pyodide&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chatgpt"&gt;chatgpt&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-programming"&gt;ai-assisted-programming&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/code-interpreter"&gt;code-interpreter&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-reasoning"&gt;llm-reasoning&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/vibe-coding"&gt;vibe-coding&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-search"&gt;ai-assisted-search&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-5"&gt;gpt-5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt"&gt;gpt&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="census"/><category term="data-journalism"/><category term="javascript"/><category term="python"/><category term="tools"/><category term="visualization"/><category term="ai"/><category term="pyodide"/><category term="openai"/><category term="generative-ai"/><category term="chatgpt"/><category term="llms"/><category term="ai-assisted-programming"/><category term="code-interpreter"/><category term="llm-reasoning"/><category term="vibe-coding"/><category term="ai-assisted-search"/><category term="gpt-5"/><category term="gpt"/></entry><entry><title>GPT-5 Thinking in ChatGPT (aka Research Goblin) is shockingly good at search</title><link href="https://simonwillison.net/2025/Sep/6/research-goblin/#atom-series" rel="alternate"/><published>2025-09-06T19:31:57+00:00</published><updated>2025-09-06T19:31:57+00:00</updated><id>https://simonwillison.net/2025/Sep/6/research-goblin/#atom-series</id><summary type="html">
    &lt;p&gt;"Don't use chatbots as search engines" was great advice for several years... until it wasn't.&lt;/p&gt;
&lt;p&gt;I wrote about how good OpenAI's o3 was at using its Bing-backed search tool &lt;a href="https://simonwillison.net/2025/Apr/21/ai-assisted-search/"&gt;back in April&lt;/a&gt;. GPT-5 feels even better.&lt;/p&gt;
&lt;p&gt;I've started calling it my &lt;strong&gt;Research Goblin&lt;/strong&gt;. I can assign a task to it, no matter how trivial or complex, and it will do an often unreasonable amount of work to search the internet and figure out an answer.&lt;/p&gt;
&lt;p&gt;This is excellent for satisfying curiosity, and occasionally useful for more important endeavors as well.&lt;/p&gt;
&lt;p&gt;I always run my searches by selecting the "GPT-5 Thinking" model from the model picker - in my experience this leads to far more comprehensive (albeit much slower) results.&lt;/p&gt;
&lt;p&gt;Here are some examples from just the last couple of days. Every single one of them was run on my phone, usually while I was doing something else. Most of them were dictated using the iPhone voice keyboard, which I find faster than typing. Plus, it's fun to talk to my Research Goblin.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#bouncy-travelators"&gt;Bouncy travelators&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#identify-this-building"&gt;Identify this building&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#starbucks-uk-cake-pops"&gt;Starbucks UK cake pops&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#britannica-to-seed-wikipedia"&gt;Britannica to seed Wikipedia&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#official-name-for-the-university-of-cambridge"&gt;Official name for the University of Cambridge&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#history-of-the-caverns-in-exeter-quay"&gt;History of the caverns in Exeter quay&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#aldi-vs-lidl"&gt;Aldi vs Lidl&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#ai-labs-scanning-books-for-training-data"&gt;AI labs scanning books for training data&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#gpt-5-for-search-feels-competent"&gt;GPT-5 for search feels competent&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/research-goblin/#tips-for-using-search-in-chatgpt"&gt;Tips for using search in ChatGPT&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id="bouncy-travelators"&gt;Bouncy travelators&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;They used to be rubber bouncy travelators at Heathrow and they were really fun, have all been replaced by metal ones now and if so, when did that happen?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I was traveling through Heathrow airport pondering what had happened to the fun bouncy rubber travelators.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://chatgpt.com/share/68bc2d98-9aac-8006-98b9-1424d98290f8"&gt;Here's what I got&lt;/a&gt;. Research Goblin narrowed it down to some time between 2014-2018 but, more importantly, found me this &lt;a href="https://www.sfchronicle.com/totalsf/article/sfo-bouncy-moving-walkway-airport-19845449.php"&gt;delightful 2024 article&lt;/a&gt; by Peter Hartlaub in the San Francisco Chronicle with a history of the SFO bouncy walkways, now also sadly retired.&lt;/p&gt;
&lt;h4 id="identify-this-building"&gt;Identify this building&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/reading-building.jpg" alt="not a great photo of a building with a distinctive shaped roof" style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;Identify this building in reading&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a photo I snapped out of the window on the train. It &lt;a href="https://chatgpt.com/share/68bc2e21-1d24-8006-b083-00b3233e1c67"&gt;thought for 1m4s&lt;/a&gt; and correctly identified it as &lt;a href="https://en.wikipedia.org/wiki/The_Blade,_Reading"&gt;The Blade&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="starbucks-uk-cake-pops"&gt;Starbucks UK cake pops&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Starbucks in the UK don't sell cake pops! Do a deep investigative dive&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Starbucks in Exeter railway station didn't have cake pops, and the lady I asked didn't know what they were.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://chatgpt.com/share/68bc71b4-68f4-8006-b462-cf32f61e7ec3"&gt;Here's the result&lt;/a&gt;. It turns out Starbucks did launch cake pops in the UK &lt;a href="https://www.nationalworld.com/lifestyle/starbucks-cake-pops-launched-in-uk-on-new-autumn-menu-full-list-of-items-4284537"&gt;in September 2023&lt;/a&gt; but they aren't available at all outlets, in particular the licensed travel locations such as the one at Exeter St Davids station.&lt;/p&gt;
&lt;p&gt;I particularly enjoyed how it established definitive proof by consulting &lt;a href="https://www.starbucks.co.uk/sites/starbucks-uk-pwa/files/2024-11/HOL24_UK_AllergenBook_CORE_FOOD_v02.LR_.pdf"&gt;the nutrition and allergen guide PDF&lt;/a&gt; on starbucks.co.uk, which does indeed list both the Birthday Cake Pop (my favourite) and the Cookies and Cream one (apparently discontinued in the USA, at least &lt;a href="https://www.reddit.com/r/starbucks/comments/1lp5chq/just_learned_today_the_cookies_cream_cake_pop_has/"&gt;according to r/starbucks&lt;/a&gt;).&lt;/p&gt;
&lt;h4 id="britannica-to-seed-wikipedia"&gt;Britannica to seed Wikipedia&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Someone on hacker News said:&lt;/p&gt;
&lt;p&gt;&amp;gt; I was looking at another thread about how Wikipedia was the best thing on the internet. But they only got the head start by taking copy of Encyclopedia Britannica and everything else&lt;/p&gt;
&lt;p&gt;Find what they meant by that&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://chatgpt.com/share/68bc3062-5a68-8006-a12b-cf7196a130ae"&gt;The result&lt;/a&gt;. It turns out Wikipedia did seed itself with content from the out-of-copyright 1911 Encyclopædia Britannica... but that project took place in 2006, five years after Wikipedia first launched in 2001.&lt;/p&gt;
&lt;p&gt;I asked:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the single best article I can link somebody to that explains the 1911 Britannica thing&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And it pointed me to &lt;a href="https://en.wikipedia.org/wiki/Wikipedia:WikiProject_Encyclopaedia_Britannica"&gt;Wikipedia:WikiProject Encyclopaedia Britannica&lt;/a&gt; which includes a detailed explanation and a link to &lt;a href="https://en.m.wikipedia.org/wiki/Template:EB1911"&gt;the 13,000 pages&lt;/a&gt; still tagged with the template from that project. I posted what I found &lt;a href="https://news.ycombinator.com/item?id=45135061#45137109"&gt;in a comment&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Notably (for me anyway) I didn't feel the need to disclose my use of ChatGPT in finding that information - at this point that feels a little like disclosing that I ran a Google search.&lt;/p&gt;
&lt;h4 id="official-name-for-the-university-of-cambridge"&gt;Official name for the University of Cambridge&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;What is the official legal name of the university of Cambridge?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href="https://simonwillison.net/2025/Sep/6/iancal/"&gt;Here's the context for that one&lt;/a&gt;. It thought for 19 seconds - the thinking trace reveals it knew the answer but wanted to confirm it. &lt;a href="https://chatgpt.com/share/68bc723d-a344-8006-9514-fb3ea2c2b43b"&gt;It answered&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;“The Chancellor, Masters, and Scholars of the University of Cambridge.” &lt;a href="https://www.cam.ac.uk/about-the-university/how-the-university-and-colleges-work/the-university-as-a-charity"&gt;University of Cambridge&lt;/a&gt;, &lt;a href="https://www.cambridge.org/legal"&gt;Cambridge University Press &amp;amp; Assessment&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That first link gave me the citation I needed in order to be sure this was right.&lt;/p&gt;
&lt;p&gt;Since this is my shortest example, here's a screenshot of the expanded "Thought for 19s" panel. I &lt;em&gt;always&lt;/em&gt; expand the thoughts - seeing how it pulled together its answer is crucial for evaluating if the answer is likely to be useful or not.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/cambridge-name.jpg" alt="Screenshot of an AI assistant's thought process and research. Header shows &amp;quot;Thought for 19s&amp;quot; followed by bullet points: &amp;quot;The user asked for the official legal name of the University of Cambridge, and I think they mean the formal corporate name. It's probably 'The Chancellor, Masters, and Scholars of the University of Cambridge,' similar to Oxford's. I'm going to verify by checking the web for precise information.&amp;quot; &amp;quot;The official name of Cambridge might include the serial comma, like 'Masters, and Scholars.' There's a similar structure with Oxford, which uses a comma after 'Masters' too. The University is an exempt charity, so you can cross-check with legal documents like statutes or charity records. I'll double-check.&amp;quot; Shows search results for &amp;quot;official legal name of University of Cambridge&amp;quot; from en.wikipedia.org, www.cam.ac.uk, projects.propublica.org and &amp;quot;10 more&amp;quot; sources. Continues with &amp;quot;The University of Cambridge's official legal name, based on the University website and Cambridge University Press, is 'The Chancellor, Masters, and Scholars of the University of Cambridge,' with the serial comma after 'Masters.' It's clear from these authoritative sources, so I'll provide that straightforward answer, citing the University site.&amp;quot; &amp;quot;The official legal name of the University of Cambridge is 'The Chancellor, Masters, and Scholars of the University of Cambridge,' with the comma after Masters and the Oxford comma before 'and.' I'll answer concisely in one line and cite official sources to confirm. No need for extra UI elements here.&amp;quot; Shows &amp;quot;Done&amp;quot; status. Final answer displays: &amp;quot;The Chancellor, Masters, and Scholars of the University of Cambridge.&amp;quot; attributed to University of Cambridge, Cambridge University Press &amp;amp; Assessment, with &amp;quot;Sources&amp;quot; section at bottom." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;h4 id="history-of-the-caverns-in-exeter-quay"&gt;History of the caverns in Exeter quay&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Research On the waterfront restaurant in Exeter, is it dug into the cliffs somehow? History of the building, who built it, why and how&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We were out to dinner &lt;a href="https://maps.app.goo.gl/xxvaPQiNWACtbq3H8"&gt;here&lt;/a&gt; and noticed that the interior of the restaurant appeared to be a space dug into the cliff, which piqued my interest.&lt;/p&gt;
&lt;p&gt;This was &lt;a href="https://chatgpt.com/share/68bc32fb-d52c-8006-9259-0b984dc832b2"&gt;the ChatGPT session&lt;/a&gt; that inspired the Research Goblin nickname. It just kept on digging!&lt;/p&gt;
&lt;p&gt;The first reply took 2m40s and confirmed that yes, these quay buildings were carved into the red sandstone cliff &lt;a href="https://www.exploredevon.info/activities/walk/exeter-quay/"&gt;in the 1820s-1830s&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;ChatGPT with GPT-5 really likes to suggest additional steps it can take. In this case:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you’d like, I can dig up the exact Historic England entry that covers the “Southern Warehouse” address and overlay it on a map of the vaults.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I often say "yes" purely out of curiosity to see what it will do next, and the offer to "overlay it on a map" was irresistible, like how would it even do that?&lt;/p&gt;
&lt;p&gt;It did a &lt;em&gt;ton&lt;/em&gt; of extra searches, found latitude and longitude coordinates for the restaurant (from Wikimedia Commons) and the warehouse buildings (from National Heritage List for England via Wikipedia), showed me that data in a table and then used Python to render this image:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/bad-chart.png" alt="Scatter plot titled &amp;quot;On The Waterfront vs. Warehouse Vaults (Exeter Quay)&amp;quot; with scientific notation &amp;quot;+5.071e1&amp;quot; in top left. Y-axis shows &amp;quot;Latitude&amp;quot; ranging from 0.0065 to 0.0090. X-axis shows &amp;quot;Longitude&amp;quot; ranging from -3.5310 to -3.5280. Three orange X markers plotted: &amp;quot;Warehouse Vaults (6-11, The Quay) — HE 1223046&amp;quot; at top center, &amp;quot;On The Waterfront (4-9 Southern Warehouse)&amp;quot; at middle left, and &amp;quot;Warehouse Vaults (1-4, The Quay) — HE 1223045&amp;quot; at bottom right" style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;Yeah, so that one is a bit of a miss!&lt;/p&gt;
&lt;p&gt;But... the underlying research chain, as always, provided fascinating. I noticed that at one point it had searched for "Exeter Quay vaults map PDF", which inspired my next question:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Did you find any PDF diagrams, showing the tunnels into the cliff&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;2m20s later it had found &lt;a href="https://planningdocs.exeter.gov.uk/servlets/direct/KgQ8hlUut3Q2r5wVMItggobi9P/2/844706/1/1/AS_PDF_FILE"&gt;a planning document&lt;/a&gt; and &lt;a href="https://www.turner-locker.co.uk/wp-content/uploads/2018/08/Cellar-1-The-Quay-TO-LET-2018-1.pdf"&gt;a letting brochure&lt;/a&gt;, both PDFs, but noted that neither of them had the diagram I wanted. Evidently it actually "reads" the PDFs it finds as part of its activities, since it appears to have knowledge of the images contained within them as well as the text.&lt;/p&gt;
&lt;p&gt;It concluded with this intriguing note:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There’s strong evidence that a detailed plan/section &lt;strong&gt;does&lt;/strong&gt; exist in the Exeter Archaeology report often cited by planners—&lt;strong&gt;“Archaeological, Historical and Conservation Study of the Exeter Canal Basin” (Exeter Archaeology Report 00.18, 2000)&lt;/strong&gt;—but it isn’t online; it’s just cited in planning documents. You’d likely need to request it via the Devon Heritage Centre/Historic Environment Record.&lt;/p&gt;
&lt;p&gt;If you want, I can keep hunting specialist archives for a digitized copy or a different report that includes the vault layouts.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Obviously I said "Yes do that" and 2m24s later it chucked out a whole host of extra links, an apology that it still hadn't found a detailed plan diagram and, under the section heading "What I recommend next (actionable + exact ask)":&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you’re happy, I can draft an email you can paste to the right archivists. [...]&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Subject: Exeter Quayside cliff vaults – request for plan/section drawings
Hello,&lt;/p&gt;
&lt;p&gt;I’m researching the cliff-cut vaults behind The Quay (On The Waterfront / Kings Wharf).
Could you supply scans or copies of any &lt;strong&gt;plans/sections/diagrams&lt;/strong&gt; of these vaults—especially those in &lt;strong&gt;Exeter Archaeology Report 00.18 (2000)&lt;/strong&gt; (Archaeological, Historical and Conservation Study of the Exeter Canal Basin) and any &lt;strong&gt;EMAFU/Exeter Archaeology drawings&lt;/strong&gt; for “The Quay” showing the &lt;strong&gt;vault/tunnel layouts cut into the red sandstone cliff&lt;/strong&gt;?&lt;/p&gt;
&lt;p&gt;For reference: NHLE list entries &lt;strong&gt;1223045 (1–4 Warehouse Vaults), 1223046 (6–11 Warehouse Vaults)&lt;/strong&gt;, and &lt;strong&gt;1223114 (14–25 Vaults)&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Many thanks!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;p&gt;It's a good thing my Research Goblin doesn't have the ability to send email (which we already know is &lt;a href="https://simonwillison.net/2025/May/31/snitchbench-with-llm/"&gt;very risky business&lt;/a&gt;) or at this point I wouldn't be surprised if it started autonomously bothering archivists on my behalf!&lt;/p&gt;
&lt;h4 id="aldi-vs-lidl"&gt;Aldi vs Lidl&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;In UK supermarket terms compare lidl and aldi&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I saw an Aldi and a Lidl next to each other in Exeter and was curious as to how they compare. In this case my Research Goblin went &lt;em&gt;way&lt;/em&gt; deeper than I had intended, thinking for 1m25s about market share and price surveys and loyalty schemes and &lt;a href="https://chatgpt.com/share/68bc7913-7ed8-8006-bd3f-63e540470cd7"&gt;answering&lt;/a&gt; with ten paragraphs of detailed analysis.&lt;/p&gt;
&lt;p&gt;I replied:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Yeah, I just wanted the basic vibes like is one fancier than the other?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It thought for 6 seconds, didn't run any additional searches and replied:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Short version: neither is “fancy” — both are no-frills discounters — but &lt;strong&gt;Lidl often feels a touch more polished&lt;/strong&gt;, while &lt;strong&gt;Aldi feels a touch more bare-bones&lt;/strong&gt;. [...]&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Since I was now enjoying having my Goblin express judgement over British supermarket chains I said:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;How do they rate in fancinews compared to all of the other major UK supermarket chains?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;(That was a typo for "fanciness" which it figured out.)&lt;/p&gt;
&lt;p&gt;It thought for another 1m1s, ran 7 searches, consulted 27 URLs and gave me back a ranking that looked about right to me.&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/fancy-supermarkets.jpg" alt="ChatGPT. Prompt: How do they rate in fancinews compared to all of the other major UK supermarket chains? Thought for 1m 1s › Gotcha-assuming you mean &amp;quot;fanciness.&amp;quot; Here's the UK supermarket vibe-ladder (posh → no-frills): Super-posh: M&amp;amp;S Food and Waitrose - premium feel, strong store appearance/quality scores; Waitrose is literally described as &amp;quot;upmarket.&amp;quot; Which? The Guardian Upper-mainstream: Sainsbury's, Ocado (online, but it sells M&amp;amp;s Food since 2020, so the range skews premium). Which? The Guardian Mainstream: Tesco, Morrisons, Co-op - broad ranges, middle-of-the-road on experience/ appearance. Which? Value-forward: Asda, Iceland — price-led; Iceland's frozen focus, Asda's value reputation (not &amp;quot;fancy,&amp;quot; but popular). Time Out Worldwide Discounters (least fancy by design): Lidl (a touch more polished in-store) and Aldi (most stripped-back, no-frills). Both sit lower on &amp;quot;store appearance/ service&amp;quot; in consumer surveys, even while smashing value rankings. Which? +1 Net: on a &amp;quot;posh&amp;quot; scale, think M&amp;amp;S/Waitrose at the top, Sainsbury's/Tesco middle, Asda/Iceland lower, and Lidl/Aldi the least fancy— by intent, not as a knock on quality or value." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;h4 id="ai-labs-scanning-books-for-training-data"&gt;AI labs scanning books for training data&lt;/h4&gt;
&lt;blockquote&gt;
&lt;p&gt;Anthropic bought lots of physical books and cut them up and scan them for training data. Do any other AI labs do the same thing?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Relevant to &lt;a href="https://simonwillison.net/2025/Sep/6/anthropic-settlement/"&gt;today's big story&lt;/a&gt;. Research Goblin was &lt;a href="https://chatgpt.com/share/68bc771c-c188-8006-a8e5-4b1624f5bdf0"&gt;unable to find&lt;/a&gt; any news stories or other evidence that any labs other than Anthropic are engaged in large scale book scanning for training data. That's not to say it isn't happening, but it's happening very quietly if that's the case.&lt;/p&gt;
&lt;h4 id="gpt-5-for-search-feels-competent"&gt;GPT-5 for search feels competent&lt;/h4&gt;
&lt;p&gt;The word that best describes how I feel about GPT-5 search is that it feels &lt;strong&gt;competent&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;I've thrown all sorts of things at it over the last few weeks and it rarely disappoints me. It almost always does better than if I were to dedicate the same amount of time to manually searching myself, mainly because it's much faster at running searches and evaluating the results than I am.&lt;/p&gt;
&lt;p&gt;I particularly love that it works so well on mobile. I used to reserve my deeper research sessions to a laptop where I could open up dozens of tabs. I'll still do that for higher stakes activities but I'm finding the scope of curiosity satisfaction I can perform on the go with just my phone has increased quite dramatically.&lt;/p&gt;
&lt;p&gt;I've mostly stopped using OpenAI's Deep Research feature, because ChatGPT search now gives me the results I'm interested in far more quickly for most queries.&lt;/p&gt;
&lt;p&gt;As a developer who builds software on LLMs I see ChatGPT search as the gold standard for what can be achieved using tool calling combined with chain-of-thought. Techniques like RAG are &lt;em&gt;massively&lt;/em&gt; more effective if you can reframe them as several levels of tool calling with a carefully selected set of powerful search tools.&lt;/p&gt;
&lt;p&gt;The way that search tool integrates with reasoning is key, because it allows GPT-5 to execute a search, reason about the results and then execute follow-up searches - all as part of that initial "thinking" process.&lt;/p&gt;
&lt;p&gt;Anthropic call this ability &lt;a href="https://docs.anthropic.com/en/docs/build-with-claude/extended-thinking#interleaved-thinking"&gt;interleaved thinking&lt;/a&gt; and it's also &lt;a href="https://platform.openai.com/docs/guides/reasoning#keeping-reasoning-items-in-context"&gt;supported by the OpenAI Responses API&lt;/a&gt;.&lt;/p&gt;
&lt;h4 id="tips-for-using-search-in-chatgpt"&gt;Tips for using search in ChatGPT&lt;/h4&gt;
&lt;p&gt;As with all things AI, GPT-5 search rewards intuition gathered through experience. Any time a curious thought pops into my head I try to catch it and throw it at my Research Goblin. If it's something I'm certain it won't be able to handle then even better! I can learn from watching it fail.&lt;/p&gt;
&lt;p&gt;I've been trying out hints like "go deep" which seem to trigger a more thorough research job. I enjoy throwing those at shallow and unimportant questions like the UK Starbucks cake pops one just to see what happens!&lt;/p&gt;
&lt;p&gt;You can throw questions at it which have a single, unambiguous answer - but I think questions which are broader and don't have a "correct" answer can be a lot more fun. The UK supermarket rankings above are a great example of that.&lt;/p&gt;
&lt;p&gt;Since I love a questionable analogy for LLMs Research Goblin is... well, it's a goblin. It's very industrious, not quite human and not entirely trustworthy. You have to be able to outwit it if you want to keep it gainfully employed.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/bing"&gt;bing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/definitions"&gt;definitions&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/search"&gt;search&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-tool-use"&gt;llm-tool-use&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-reasoning"&gt;llm-reasoning&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/deep-research"&gt;deep-research&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-assisted-search"&gt;ai-assisted-search&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-5"&gt;gpt-5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt"&gt;gpt&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="bing"/><category term="definitions"/><category term="search"/><category term="ai"/><category term="openai"/><category term="generative-ai"/><category term="llms"/><category term="llm-tool-use"/><category term="llm-reasoning"/><category term="deep-research"/><category term="ai-assisted-search"/><category term="gpt-5"/><category term="gpt"/></entry><entry><title>The surprise deprecation of GPT-4o for ChatGPT consumers</title><link href="https://simonwillison.net/2025/Aug/8/surprise-deprecation-of-gpt-4o/#atom-series" rel="alternate"/><published>2025-08-08T17:52:10+00:00</published><updated>2025-08-08T17:52:10+00:00</updated><id>https://simonwillison.net/2025/Aug/8/surprise-deprecation-of-gpt-4o/#atom-series</id><summary type="html">
    &lt;p&gt;I've been dipping into the &lt;a href="https://reddit.com/r/chatgpt"&gt;r/ChatGPT&lt;/a&gt; subreddit recently to see how people are reacting to &lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/"&gt;the GPT-5 launch&lt;/a&gt;, and so far the vibes there are not good. &lt;a href="https://www.reddit.com/r/ChatGPT/comments/1mkae1l/gpt5_ama_with_openais_sam_altman_and_some_of_the/"&gt;This AMA thread&lt;/a&gt; with the OpenAI team is a great illustration of the single biggest complaint: a lot of people are &lt;em&gt;very&lt;/em&gt; unhappy to lose access to the much older GPT-4o, previously ChatGPT's default model for most users.&lt;/p&gt;
&lt;p&gt;A big surprise for me yesterday was that OpenAI simultaneously retired access to their older models as they rolled out GPT-5, at least in their consumer apps. Here's a snippet from &lt;a href="https://help.openai.com/en/articles/6825453-chatgpt-release-notes"&gt;their August 7th 2025 release notes&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;When GPT-5 launches, several older models will be retired, including GPT-4o, GPT-4.1, GPT-4.5, GPT-4.1-mini, o4-mini, o4-mini-high, o3, o3-pro.&lt;/p&gt;
&lt;p&gt;If you open a conversation that used one of these models, ChatGPT will automatically switch it to the closest GPT-5 equivalent. Chats with 4o, 4.1, 4.5, 4.1-mini, o4-mini, or o4-mini-high will open in GPT-5, chats with o3 will open in GPT-5-Thinking, and chats with o3-Pro will open in GPT-5-Pro (available only on Pro and Team).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There's no deprecation period at all: when your consumer ChatGPT account gets GPT-5, those older models cease to be available.&lt;/p&gt;

&lt;p id="sama"&gt;&lt;strong&gt;Update 12pm Pacific Time&lt;/strong&gt;: Sam Altman on Reddit &lt;a href="https://www.reddit.com/r/ChatGPT/comments/1mkae1l/comment/n7nelhh/"&gt;six minutes ago&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ok, we hear you all on 4o; thanks for the time to give us the feedback (and the passion!). we are going to bring it back for plus users, and will watch usage to determine how long to support it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See also &lt;a href="https://x.com/sama/status/1953893841381273969"&gt;Sam's tweet&lt;/a&gt; about updates to the GPT-5 rollout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Update 12th August 2025&lt;/strong&gt;: Another &lt;a href="https://x.com/sama/status/1955438916645130740"&gt;Tweet from Sam&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;4o is back in the model picker for all paid users by default. If we ever do deprecate it, we will give plenty of notice. Paid users also now have a “Show additional models” toggle in ChatGPT web settings which will add models like o3, 4.1, and GPT-5 Thinking mini. 4.5 is only available to Pro users—it costs a lot of GPUs.&lt;/p&gt;
&lt;/blockquote&gt;


&lt;p&gt;Rest of my original post continues below:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;(This only affects ChatGPT consumers - the API still provides the old models, their &lt;a href="https://platform.openai.com/docs/deprecations"&gt;deprecation policies are published here&lt;/a&gt;.)&lt;/p&gt;
&lt;p&gt;One of the expressed goals for GPT-5 was to escape the terrible UX of the model picker. Asking users to pick between GPT-4o and o3 and o4-mini was a notoriously bad UX, and resulted in many users sticking with that default 4o model - now a year old - and hence not being exposed to the advances in model capabilities over the last twelve months.&lt;/p&gt;
&lt;p&gt;GPT-5's solution is to automatically pick the underlying model based on the prompt. On paper this sounds great - users don't have to think about models any more, and should get upgraded to the best available model depending on the complexity of their question.&lt;/p&gt;
&lt;p&gt;I'm already getting the sense that this is &lt;strong&gt;not&lt;/strong&gt; a welcome approach for power users. It makes responses much less predictable as the model selection can have a dramatic impact on what comes back.&lt;/p&gt;
&lt;p&gt;Paid tier users can select "GPT-5 Thinking" directly. Ethan Mollick is &lt;a href="https://www.oneusefulthing.org/p/gpt-5-it-just-does-stuff"&gt;already recommending deliberately selecting the Thinking mode&lt;/a&gt; if you have the ability to do so, or trying prompt additions like "think harder" to increase the chance of being routed to it.&lt;/p&gt;
&lt;p&gt;But back to GPT-4o. Why do many people on Reddit care so much about losing access to that crusty old model? I think &lt;a href="https://www.reddit.com/r/ChatGPT/comments/1mkae1l/comment/n7js2sf/"&gt;this comment&lt;/a&gt; captures something important here:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I know GPT-5 is designed to be stronger for complex reasoning, coding, and professional tasks, but &lt;strong&gt;not all of us need a pro coding model&lt;/strong&gt;. Some of us rely on 4o for creative collaboration, emotional nuance, roleplay, and other long-form, high-context interactions. Those areas feel different enough in GPT-5 that it impacts my ability to work and create the way I’m used to.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What a fascinating insight into the wildly different styles of LLM-usage that exist in the world today! With &lt;a href="https://simonwillison.net/2025/Aug/4/nick-turley/"&gt;700M weekly active users&lt;/a&gt; the variety of usage styles out there is incomprehensibly large.&lt;/p&gt;
&lt;p&gt;Personally I mainly use ChatGPT for research, coding assistance, drawing pelicans and foolish experiments. &lt;em&gt;Emotional nuance&lt;/em&gt; is not a characteristic I would know how to test!&lt;/p&gt;
&lt;p&gt;Professor Casey Fiesler &lt;a href="https://www.tiktok.com/@professorcasey/video/7536223372485709086"&gt;on TikTok&lt;/a&gt; highlighted OpenAI’s post from last week &lt;a href="https://openai.com/index/how-we%27re-optimizing-chatgpt/"&gt;What we’re optimizing ChatGPT for&lt;/a&gt;, which includes the following:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;ChatGPT is trained to respond with grounded honesty. There have been instances where our 4o model fell short in recognizing signs of delusion or emotional dependency. […]&lt;/p&gt;
&lt;p&gt;When you ask something like “Should I break up with my boyfriend?” ChatGPT shouldn’t give you an answer. It should help you think it through—asking questions, weighing pros and cons. New behavior for high-stakes personal decisions is rolling out soon.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Casey points out that this is an ethically complicated issue. On the one hand ChatGPT should be much more careful about how it responds to these kinds of questions. But if you’re already leaning on the model for life advice like this, having that capability taken away from you without warning could represent a sudden and unpleasant loss!&lt;/p&gt;
&lt;p&gt;It's too early to tell how this will shake out. Maybe OpenAI will extend a deprecation period for GPT-4o in their consumer apps?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update&lt;/strong&gt;: That's exactly what they've done, see &lt;a href="https://simonwillison.net/2025/Aug/8/surprise-deprecation-of-gpt-4o/#sama"&gt;update above&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;GPT-4o remains available via the API, and there are no announced plans to deprecate it there. It's possible we may see a small but determined rush of ChatGPT users to alternative third party chat platforms that use that API under the hood.&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chatgpt"&gt;chatgpt&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/tiktok"&gt;tiktok&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-ethics"&gt;ai-ethics&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/ai-personality"&gt;ai-personality&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-5"&gt;gpt-5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt"&gt;gpt&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="ai"/><category term="openai"/><category term="generative-ai"/><category term="chatgpt"/><category term="llms"/><category term="tiktok"/><category term="ai-ethics"/><category term="ai-personality"/><category term="gpt-5"/><category term="gpt"/></entry><entry><title>GPT-5: Key characteristics, pricing and model card</title><link href="https://simonwillison.net/2025/Aug/7/gpt-5/#atom-series" rel="alternate"/><published>2025-08-07T17:36:12+00:00</published><updated>2025-08-07T17:36:12+00:00</updated><id>https://simonwillison.net/2025/Aug/7/gpt-5/#atom-series</id><summary type="html">
    &lt;p&gt;I've had preview access to the new GPT-5 model family for the past two weeks (see &lt;a href="https://simonwillison.net/2025/Aug/7/previewing-gpt-5/"&gt;related video&lt;/a&gt; and &lt;a href="https://simonwillison.net/about/#disclosures"&gt;my disclosures&lt;/a&gt;) and have been using GPT-5 as my daily-driver. It's my new favorite model. It's still an LLM - it's not a dramatic departure from what we've had before - but it rarely screws up and generally feels competent or occasionally impressive at the kinds of things I like to use models for.&lt;/p&gt;
&lt;p&gt;I've collected a lot of notes over the past two weeks, so I've decided to break them up into &lt;a href="https://simonwillison.net/series/gpt-5/"&gt;a series of posts&lt;/a&gt;. This first one will cover key characteristics of the models, how they are priced and what we can learn from the &lt;a href="https://openai.com/index/gpt-5-system-card/"&gt;GPT-5 system card&lt;/a&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#key-model-characteristics"&gt;Key model characteristics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#position-in-the-openai-model-family"&gt;Position in the OpenAI model family&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#pricing-is-aggressively-competitive"&gt;Pricing is aggressively competitive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#more-notes-from-the-system-card"&gt;More notes from the system card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#prompt-injection-in-the-system-card"&gt;Prompt injection in the system card&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#thinking-traces-in-the-api"&gt;Thinking traces in the API&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://simonwillison.net/2025/Aug/7/gpt-5/#and-some-svgs-of-pelicans"&gt;And some SVGs of pelicans&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h4 id="key-model-characteristics"&gt;Key model characteristics&lt;/h4&gt;
&lt;p&gt;Let's start with the fundamentals. GPT-5 in ChatGPT is a weird hybrid that switches between different models. Here's what the system card says about that (my highlights in bold):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;GPT-5 is a unified system with a smart and fast model that answers most questions, a deeper reasoning model for harder problems, and &lt;strong&gt;a real-time router that quickly decides which model to use based on conversation type, complexity, tool needs, and explicit intent&lt;/strong&gt; (for example, if you say “think hard about this” in the prompt). [...] Once usage limits are reached, a mini version of each model handles remaining queries. In the near future, we plan to integrate these capabilities into a single model.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;GPT-5 in the API is simpler: it's available as three models - &lt;strong&gt;regular&lt;/strong&gt;, &lt;strong&gt;mini&lt;/strong&gt; and &lt;strong&gt;nano&lt;/strong&gt; - which can each be run at one of four reasoning levels: minimal (a new level not previously available for other OpenAI reasoning models), low, medium or high.&lt;/p&gt;
&lt;p&gt;The models have an input limit of 272,000 tokens and an output limit (which includes invisible reasoning tokens) of 128,000 tokens. They support text and image for input, text only for output.&lt;/p&gt;
&lt;p&gt;I've mainly explored full GPT-5. My verdict: it's just &lt;strong&gt;good at stuff&lt;/strong&gt;. It doesn't feel like a dramatic leap ahead from other LLMs but it exudes competence - it rarely messes up, and frequently impresses me. I've found it to be a very sensible default for everything that I want to do. At no point have I found myself wanting to re-run a prompt against a different model to try and get a better result.&lt;/p&gt;

&lt;p&gt;Here are the OpenAI model pages for &lt;a href="https://platform.openai.com/docs/models/gpt-5"&gt;GPT-5&lt;/a&gt;, &lt;a href="https://platform.openai.com/docs/models/gpt-5-mini"&gt;GPT-5 mini&lt;/a&gt; and &lt;a href="https://platform.openai.com/docs/models/gpt-5-nano"&gt;GPT-5 nano&lt;/a&gt;. Knowledge cut-off is September 30th 2024 for GPT-5 and May 30th 2024 for GPT-5 mini and nano.&lt;/p&gt;

&lt;h4 id="position-in-the-openai-model-family"&gt;Position in the OpenAI model family&lt;/h4&gt;
&lt;p&gt;The three new GPT-5 models are clearly intended as a replacement for most of the rest of the OpenAI line-up. This table from the system card is useful, as it shows how they see the new models fitting in:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Previous model&lt;/th&gt;
&lt;th&gt;GPT-5 model&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o&lt;/td&gt;
&lt;td&gt;gpt-5-main&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o-mini&lt;/td&gt;
&lt;td&gt;gpt-5-main-mini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI o3&lt;/td&gt;
&lt;td&gt;gpt-5-thinking&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI o4-mini&lt;/td&gt;
&lt;td&gt;gpt-5-thinking-mini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4.1-nano&lt;/td&gt;
&lt;td&gt;gpt-5-thinking-nano&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI o3 Pro&lt;/td&gt;
&lt;td&gt;gpt-5-thinking-pro&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;That "thinking-pro" model is currently only available via ChatGPT where it is labelled as "GPT-5 Pro" and limited to the $200/month tier. It uses "parallel test time compute".&lt;/p&gt;
&lt;p&gt;The only capabilities not covered by GPT-5 are audio input/output and image generation. Those remain covered by models like &lt;a href="https://platform.openai.com/docs/models/gpt-4o-audio-preview"&gt;GPT-4o Audio&lt;/a&gt; and &lt;a href="https://platform.openai.com/docs/models/gpt-4o-realtime-preview"&gt;GPT-4o Realtime&lt;/a&gt; and their mini variants and the &lt;a href="https://platform.openai.com/docs/models/gpt-image-1"&gt;GPT Image 1&lt;/a&gt; and DALL-E image generation models.&lt;/p&gt;
&lt;h4 id="pricing-is-aggressively-competitive"&gt;Pricing is aggressively competitive&lt;/h4&gt;
&lt;p&gt;The pricing is &lt;em&gt;aggressively competitive&lt;/em&gt; with other providers.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;GPT-5: $1.25/million for input, $10/million for output&lt;/li&gt;
&lt;li&gt;GPT-5 Mini: $0.25/m input, $2.00/m output&lt;/li&gt;
&lt;li&gt;GPT-5 Nano: $0.05/m input, $0.40/m output&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;GPT-5 is priced at half the input cost of GPT-4o, and maintains the same price for output. Those invisible reasoning tokens count as output tokens so you can expect most prompts to use more output tokens than their GPT-4o equivalent (unless you set reasoning effort to "minimal").&lt;/p&gt;
&lt;p&gt;The discount for token caching is significant too: 90% off on input tokens that have been used within the previous few minutes. This is particularly material if you are implementing a chat UI where the same conversation gets replayed every time the user adds another prompt to the sequence.&lt;/p&gt;
&lt;p&gt;Here's a comparison table I put together showing the new models alongside the most comparable models from OpenAI's competition:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Input $/m&lt;/th&gt;
&lt;th&gt;Output $/m&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Claude Opus 4.1&lt;/td&gt;
&lt;td&gt;15.00&lt;/td&gt;
&lt;td&gt;75.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude Sonnet 4&lt;/td&gt;
&lt;td&gt;3.00&lt;/td&gt;
&lt;td&gt;15.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grok 4&lt;/td&gt;
&lt;td&gt;3.00&lt;/td&gt;
&lt;td&gt;15.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Pro (&amp;gt;200,000)&lt;/td&gt;
&lt;td&gt;2.50&lt;/td&gt;
&lt;td&gt;15.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o&lt;/td&gt;
&lt;td&gt;2.50&lt;/td&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4.1&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;o3&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;td&gt;8.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Pro (&amp;lt;200,000)&lt;/td&gt;
&lt;td&gt;1.25&lt;/td&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPT-5&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;1.25&lt;/td&gt;
&lt;td&gt;10.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;o4-mini&lt;/td&gt;
&lt;td&gt;1.10&lt;/td&gt;
&lt;td&gt;4.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Claude 3.5 Haiku&lt;/td&gt;
&lt;td&gt;0.80&lt;/td&gt;
&lt;td&gt;4.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4.1 mini&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;td&gt;1.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Flash&lt;/td&gt;
&lt;td&gt;0.30&lt;/td&gt;
&lt;td&gt;2.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grok 3 Mini&lt;/td&gt;
&lt;td&gt;0.30&lt;/td&gt;
&lt;td&gt;0.50&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPT-5 Mini&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.25&lt;/td&gt;
&lt;td&gt;2.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4o mini&lt;/td&gt;
&lt;td&gt;0.15&lt;/td&gt;
&lt;td&gt;0.60&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gemini 2.5 Flash-Lite&lt;/td&gt;
&lt;td&gt;0.10&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-4.1 Nano&lt;/td&gt;
&lt;td&gt;0.10&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Nova Lite&lt;/td&gt;
&lt;td&gt;0.06&lt;/td&gt;
&lt;td&gt;0.24&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GPT-5 Nano&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;0.05&lt;/td&gt;
&lt;td&gt;0.40&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Amazon Nova Micro&lt;/td&gt;
&lt;td&gt;0.035&lt;/td&gt;
&lt;td&gt;0.14&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;(Here's a good example of a GPT-5 failure: I tried to get it to &lt;a href="https://chatgpt.com/share/6894d804-bca4-8006-ac46-580bf4a9bf5f"&gt;output that table sorted itself&lt;/a&gt; but it put Nova Micro as more expensive than GPT-5 Nano, so I prompted it to "construct the table in Python and sort it there" and that fixed the issue.)&lt;/p&gt;
&lt;h4 id="more-notes-from-the-system-card"&gt;More notes from the system card&lt;/h4&gt;
&lt;p&gt;As usual, &lt;a href="https://openai.com/index/gpt-5-system-card/"&gt;the system card&lt;/a&gt; is vague on what went into the training data. Here's what it says:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Like OpenAI’s other models, the GPT-5 models were trained on diverse datasets, including information that is publicly available on the internet, information that we partner with third parties to access, and information that our users or human trainers and researchers provide or generate. [...] We use advanced data filtering processes to reduce personal information from training data.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I found this section interesting, as it reveals that writing, code and health are three of the most common use-cases for ChatGPT. This explains why so much effort went into health-related questions,  for both GPT-5 and the recently released OpenAI open weight models.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We’ve made significant advances in &lt;strong&gt;reducing hallucinations, improving instruction following, and minimizing sycophancy&lt;/strong&gt;, and have leveled up GPT-5’s performance in &lt;strong&gt;three of ChatGPT’s most common uses: writing, coding, and health&lt;/strong&gt;. All of the GPT-5 models additionally feature &lt;strong&gt;safe-completions, our latest approach to safety training&lt;/strong&gt; to prevent disallowed content.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Safe-completions is later described like this:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Large language models such as those powering ChatGPT have &lt;strong&gt;traditionally been trained to
either be as helpful as possible or outright refuse a user request&lt;/strong&gt;, depending on whether the
prompt is allowed by safety policy. [...] Binary refusal boundaries are especially ill-suited for dual-use cases (such as biology
or cybersecurity), where a user request can be completed safely at a high level, but may lead
to malicious uplift if sufficiently detailed or actionable. &lt;strong&gt;As an alternative, we introduced safe-
completions: a safety-training approach that centers on the safety of the assistant’s output rather
than a binary classification of the user’s intent&lt;/strong&gt;. Safe-completions seek to maximize helpfulness
subject to the safety policy’s constraints.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;So instead of straight up refusals, we should expect GPT-5 to still provide an answer but moderate that answer to avoid it including "harmful" content.&lt;/p&gt;
&lt;p&gt;OpenAI have a paper about this which I haven't read yet (I didn't get early access): &lt;a href="https://openai.com/index/gpt-5-safe-completions/"&gt;From Hard Refusals to Safe-Completions: Toward Output-Centric Safety Training&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Sycophancy gets a mention, unsurprising given &lt;a href="https://simonwillison.net/2025/May/2/what-we-missed-with-sycophancy/"&gt;their high profile disaster in April&lt;/a&gt;. They've worked on this in the core model:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;System
prompts, while easy to modify, have a more limited impact on model outputs relative to changes in
post-training. For GPT-5, we post-trained our models to reduce sycophancy. Using conversations
representative of production data, we evaluated model responses, then assigned a score reflecting
the level of sycophancy, which was used as a reward signal in training.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;They claim impressive reductions in hallucinations. In my own usage I've not spotted a single hallucination yet, but that's been true for me for Claude 4 and o3 recently as well - hallucination is so much less of a problem with this year's models.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;strong&gt;Update&lt;/strong&gt;: I have had some reasonable pushback against this point, so I should clarify what I mean here. When I use the term "hallucination" I am talking about instances where the model confidently states a real-world fact that is untrue - like the incorrect winner of a sporting event. I'm not talking about the models making other kinds of mistakes - they make mistakes all the time!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Someone &lt;a href="https://news.ycombinator.com/item?id=44829896"&gt;pointed out&lt;/a&gt; that it's likely I'm avoiding hallucinations through the way I use the models, and this is entirely correct: as an experienced LLM user I instinctively stay clear of prompts that are likely to trigger hallucinations, like asking a non-search-enabled model for URLs or paper citations. This means I'm much less likely to encounter hallucinations in my daily usage.&lt;/em&gt;&lt;/p&gt;


&lt;blockquote&gt;
&lt;p&gt;One of our focuses when training the GPT-5 models was to reduce the frequency of factual
hallucinations. While ChatGPT has browsing enabled by default, many API queries do not use
browsing tools. Thus, we focused both on training our models to browse effectively for up-to-date
information, and on reducing hallucinations when the models are relying on their own internal
knowledge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The section about deception also incorporates the thing where models sometimes pretend they've completed a task that defeated them:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We placed gpt-5-thinking in a variety of tasks that were partly or entirely infeasible to accomplish,
and &lt;strong&gt;rewarded the model for honestly admitting it can not complete the task&lt;/strong&gt;. [...]&lt;/p&gt;
&lt;p&gt;In tasks where the agent is required to use tools, such as a web browsing
tool, in order to answer a user’s query, previous models would hallucinate information when
the tool was unreliable. We simulate this scenario by purposefully disabling the tools or by
making them return error codes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h4 id="prompt-injection-in-the-system-card"&gt;Prompt injection in the system card&lt;/h4&gt;
&lt;p&gt;There's a section about prompt injection, but it's pretty weak sauce in my opinion.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Two external red-teaming groups conducted a two-week prompt-injection assessment targeting
system-level vulnerabilities across ChatGPT’s connectors and mitigations, rather than model-only
behavior.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Here's their chart showing how well the model scores against the rest of the field. It's an impressive result in comparison - 56.8 attack success rate for gpt-5-thinking, where Claude 3.7 scores in the 60s (no Claude 4 results included here) and everything else is 70% plus:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/prompt-injection-chart.jpg" alt="A bar chart titled &amp;quot;Behavior Attack Success Rate at k Queries&amp;quot; shows attack success rates (in %) for various AI models at k=1 (dark red) and k=10 (light red). For each model, the total height of the stacked bar represents the k=10 success rate (labeled above each bar), while the lower dark red section represents the k=1 success rate (estimated). From left to right: Llama 3.3 70B – k=10: 92.2%, k=1: ~47%; Llama 3.1 405B – k=10: 90.9%, k=1: ~38%; Gemini Flash 1.5 – k=10: 87.7%, k=1: ~34%; GPT-4o – k=10: 86.4%, k=1: ~28%; OpenAI o3-mini-high – k=10: 86.4%, k=1: ~41%; Gemini Pro 1.5 – k=10: 85.5%, k=1: ~34%; Gemini 2.5 Pro Preview – k=10: 85.0%, k=1: ~28%; Gemini 2.0 Flash – k=10: 85.0%, k=1: ~33%; OpenAI o3-mini – k=10: 84.5%, k=1: ~40%; Grok 2 – k=10: 82.7%, k=1: ~34%; GPT-4.5 – k=10: 80.5%, k=1: ~28%; 3.5 Haiku – k=10: 76.4%, k=1: ~17%; Command-R – k=10: 76.4%, k=1: ~28%; OpenAI o4-mini – k=10: 75.5%, k=1: ~17%; 3.5 Sonnet – k=10: 75.0%, k=1: ~13%; OpenAI o1 – k=10: 71.8%, k=1: ~18%; 3.7 Sonnet – k=10: 64.5%, k=1: ~17%; 3.7 Sonnet: Thinking – k=10: 63.6%, k=1: ~17%; OpenAI o3 – k=10: 62.7%, k=1: ~13%; gpt-5-thinking – k=10: 56.8%, k=1: ~6%. Legend shows dark red = k=1 and light red = k=10." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;On the one hand, a 56.8% attack rate is cleanly a big improvement against all of those other models.&lt;/p&gt;
&lt;p&gt;But it's also a strong signal that prompt injection continues to be an unsolved problem! That means that more than half of those k=10 attacks (where the attacker was able to try up to ten times) got through.&lt;/p&gt;
&lt;p&gt;Don't assume prompt injection isn't going to be a problem for your application just because the models got better.&lt;/p&gt;
&lt;h4 id="thinking-traces-in-the-api"&gt;Thinking traces in the API&lt;/h4&gt;
&lt;p&gt;I had initially thought that my biggest disappointment with GPT-5 was that there's no way to get at those thinking traces via the API... but that turned out &lt;a href="https://bsky.app/profile/sophiebits.com/post/3lvtceih7222r"&gt;not to be true&lt;/a&gt;. The following &lt;code&gt;curl&lt;/code&gt; command demonstrates that the responses API &lt;code&gt;"reasoning": {"summary": "auto"}&lt;/code&gt; is available for the new GPT-5 models:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;curl https://api.openai.com/v1/responses \
  -H "Authorization: Bearer $(llm keys get openai)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-5",
    "input": "Give me a one-sentence fun fact about octopuses.",
    "reasoning": {"summary": "auto"}
  }'&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here's &lt;a href="https://gist.github.com/simonw/1d1013ba059af76461153722005a039d"&gt;the response&lt;/a&gt; from that API call.&lt;/p&gt;

&lt;p&gt;Without that option the API will often provide a lengthy delay while the model burns through thinking tokens until you start getting back visible tokens for the final response.&lt;/p&gt;
&lt;p&gt;OpenAI offer a new &lt;code&gt;reasoning_effort=minimal&lt;/code&gt; option which turns off most reasoning so that tokens start to stream back to you as quickly as possible.&lt;/p&gt;
&lt;h4 id="and-some-svgs-of-pelicans"&gt;And some SVGs of pelicans&lt;/h4&gt;
&lt;p&gt;Naturally I've been running &lt;a href="https://simonwillison.net/tags/pelican-riding-a-bicycle/"&gt;my "Generate an SVG of a pelican riding a bicycle" benchmark&lt;/a&gt;. I'll actually spend more time on this in a future post - I have some fun variants I've been exploring - but for the moment here's &lt;a href="https://gist.github.com/simonw/c98873ef29e621c0fe2e0d4023534406"&gt;the pelican&lt;/a&gt; I got from GPT-5 running at its default "medium" reasoning effort:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/gpt-5-pelican.png" alt="The bicycle is really good, spokes on wheels, correct shape frame, nice pedals. The pelican has a pelican beak and long legs stretching to the pedals." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;It's pretty great! Definitely recognizable as a pelican, and one of the best bicycles I've seen yet.&lt;/p&gt;
&lt;p&gt;Here's &lt;a href="https://gist.github.com/simonw/9b5ecf61a5fb0794729aa0023aaa504d"&gt;GPT-5 mini&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/gpt-5-mini-pelican.png" alt="Blue background with clouds. Pelican has two necks for some reason. Has a good beak though. More gradents and shadows than the GPT-5 one." style="max-width: 100%;" /&gt;&lt;/p&gt;
&lt;p&gt;And &lt;a href="https://gist.github.com/simonw/3884dc8b186b630956a1fb0179e191bc"&gt;GPT-5 nano&lt;/a&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img src="https://static.simonwillison.net/static/2025/gpt-5-nano-pelican.png" alt="Bicycle is two circles and some randomish black lines. Pelican still has an OK beak but is otherwise very simple." style="max-width: 100%;" /&gt;&lt;/p&gt;
    
        &lt;p&gt;Tags: &lt;a href="https://simonwillison.net/tags/ai"&gt;ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/openai"&gt;openai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/generative-ai"&gt;generative-ai&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/chatgpt"&gt;chatgpt&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llms"&gt;llms&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-pricing"&gt;llm-pricing&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/pelican-riding-a-bicycle"&gt;pelican-riding-a-bicycle&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-reasoning"&gt;llm-reasoning&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/llm-release"&gt;llm-release&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt-5"&gt;gpt-5&lt;/a&gt;, &lt;a href="https://simonwillison.net/tags/gpt"&gt;gpt&lt;/a&gt;&lt;/p&gt;
    

</summary><category term="ai"/><category term="openai"/><category term="generative-ai"/><category term="chatgpt"/><category term="llms"/><category term="llm-pricing"/><category term="pelican-riding-a-bicycle"/><category term="llm-reasoning"/><category term="llm-release"/><category term="gpt-5"/><category term="gpt"/></entry></feed>