We need to tell people ChatGPT will lie to them, not debate linguistics
Plus a new LLM CLI tool and details of how this newsletter works
In this newsletter:
We need to tell people ChatGPT will lie to them, not debate linguistics
Weeknotes: A new llm CLI tool, plus automating my weeknotes and newsletter
Semi-automating a Substack newsletter with an Observable notebook
Plus 11 links and 7 quotations and 3 TILs
We need to tell people ChatGPT will lie to them, not debate linguistics - 2023-04-07
ChatGPT lies to people. This is a serious bug that has so far resisted all attempts at a fix. We need to prioritize helping people understand this, not debating the most precise terminology to use to describe it.
We accidentally invented computers that can lie to us
We accidentally invented computers that can lie to us and we can't figure out how to make them stop
- Simon Willison (@simonw) April 5, 2023
Mainly I was trying to be pithy and amusing, but this thought was inspired by reading Sam Bowman's excellent review of the field, Eight Things to Know about Large Language Models. In particular this:
More capable models can better recognize the specific circumstances under which they are trained. Because of this, they are more likely to learn to act as expected in precisely those circumstances while behaving competently but unexpectedly in others. This can surface in the form of problems that Perez et al. (2022) call sycophancy, where a model answers subjective questions in a way that flatters their user’s stated beliefs, and sandbagging, where models are more likely to endorse common misconceptions when their user appears to be less educated.
Sycophancy and sandbagging are my two favourite new pieces of AI terminology!
What I find fascinating about this is that these extremely problematic behaviours are not the system working as intended: they are bugs! And we haven't yet found a reliable way to fix them.
(Here's the paper that snippet references: Discovering Language Model Behaviors with Model-Written Evaluations from December 2022.)
"But a machine can't deliberately tell a lie"
I got quite a few replies complaining that it's inappropriate to refer to LLMs as "lying", because to do so anthropomorphizes them and implies a level of intent which isn't possible.
I completely agree that anthropomorphism is bad: these models are fancy matrix arithmetic, not entities with intent and opinions.
But in this case, I think the visceral clarity of being able to say "ChatGPT will lie to you" is a worthwhile trade.
Science fiction has been presenting us with a model of "artificial intelligence" for decades. It's firmly baked into our culture that an "AI" is an all-knowing computer, incapable of lying and able to answer any question with pin-point accuracy.
Large language models like ChatGPT, on first encounter, seem to fit that bill. They appear astonishingly capable, and their command of human language can make them seem like a genuine intelligence, at least at first glance.
But the more time you spend with them, the more that illusion starts to fall apart.
They fail spectacularly when prompted with logic puzzles, or basic arithmetic, or when asked to produce citations or link to sources for the information they present.
Most concerningly, they hallucinate or confabulate: they make things up! My favourite example of this remains their ability to entirely imagine the content of a URL. I still see this catching people out every day. It's remarkably convincing.
Why ChatGPT and Bing Chat are so good at making things up is an excellent in-depth exploration of this issue from Benj Edwards at Ars Technica.
We need to explain this in straight-forward terms
We're trying to solve two problems here:
ChatGPT cannot be trusted to provide factual information. It has a very real risk of making things up, and if people don't understand it they are guaranteed to be mislead.
Systems like ChatGPT are not sentient, or even intelligent systems. They do not have opinions, or feelings, or a sense of self. We must resist the temptation to anthropomorphize them.
I believe that the most direct form of harm caused by LLMs today is the way they mislead their users. The first problem needs to take precedence.
It is vitally important that new users understand that these tools cannot be trusted to provide factual answers. We need to help people get there as quickly as possible.
Which of these two messages do you think is more effective?
ChatGPT will lie to you
Or
ChatGPT doesn't lie, lying is too human and implies intent. It hallucinates. Actually no, hallucination still implies human-like thought. It confabulates. That's a term used in psychiatry to describe when someone replaces a gap in one's memory by a falsification that one believes to be true - though of course these things don't have human minds so even confabulation is unnecessarily anthropomorphic. I hope you've enjoyed this linguistic detour!
Let's go with the first one. We should be shouting this message from the rooftops: ChatGPT will lie to you.
That doesn't mean it's not useful - it can be astonishingly useful, for all kinds of purposes... but seeking truthful, factual answers is very much not one of them. And everyone needs to understand that.
Convincing people that these aren't a sentient AI out of a science fiction story can come later. Once people understand their flaws this should be an easier argument to make!
Should we warn people off or help them on?
This situation raises an ethical conundrum: if these tools can't be trusted, and people are demonstrably falling for their traps, should we encourage people not to use them at all, or even campaign to have them banned?
Every day I personally find new problems that I can solve more effectively with the help of large language models. Some recent examples from just the last few weeks:
Reading thermometer temperatures over time from a video - transcript
Interactive row selection prototype with Datasette - transcript
Each of these represents a problem I could have solved without ChatGPT... but at a time cost that would have been prohibitively expensive, to the point that I wouldn't have bothered.
I wrote more about this in AI-enhanced development makes me more ambitious with my projects.
Honestly, at this point using ChatGPT in the way that I do feels like a massively unfair competitive advantage. I'm not worried about AI taking people's jobs: I'm worried about the impact of AI-enhanced developers like myself.
It genuinely feels unethical for me not to help other people learn to use these tools as effectively as possible. I want everyone to be able to do what I can do with them, as safely and responsibly as possible.
I think the message we should be emphasizing is this:
These are incredibly powerful tools. They are far harder to use effectively than they first appear. Invest the effort, but approach with caution: we accidentally invented computers that can lie to us and we can't figure out how to make them stop.
There's a time for linguistics, and there's a time for grabbing the general public by the shoulders and shouting "It lies! The computer lies to you! Don't trust anything it says!"
Weeknotes: A new llm CLI tool, plus automating my weeknotes and newsletter - 2023-04-04
I started publishing weeknotes in 2019 partly as a way to hold myself accountable but mainly as a way to encourage myself to write more.
Now that I'm writing multiple posts a week (mainly about AI) - and sending them out as a newsletter - my weeknotes are feeling a little less necessary. Here's everything I've written here since my last weeknotes on 22nd March:
I built a ChatGPT plugin to answer questions about data hosted in Datasette
AI-enhanced development makes me more ambitious with my projects - and for another illustrative example of that effect, see my TIL Reading thermometer temperatures over time from a video
Think of language models like ChatGPT as a "calculator for words"
Semi-automating a Substack newsletter with an Observable notebook
(That list created using this SQL query.)
I'm going to keep them going though: I've had so much value out of the habit that I don't feel it's time to stop.
The llm CLI tool
This is one new piece of software I've released in the past few weeks that I haven't written about yet.
I built the first version of llm, a command-line tool for running prompts against large language model (currently just ChatGPT and GPT-4), getting the results back on the command-line and also storing the prompt and response in a SQLite database.
It's still pretty experimental, but it's already looking like it will be a fun playground for trying out new things.
Here's the 30s version of how to start using it:
# Install the tool
pipx install llm
# Put an OpenAI API key somewhere it can find it
echo 'your-OpenAI-API-key' > ~/.openai-api-key.txt
# Or you can set it as an environment variable:
# export OPENAI_API_KEY='...'
# Run a prompt
llm 'Ten names for cheesecakes'
This will output the response to that prompt directly to the terminal.
Add the -s
or --stream
option to stream results instead:
Prompts are run against ChatGPT's inexpensive gpt-3.5-turbo
model by default. You can use -4
to run against the GPT-4 model instead (if you have access to it), or --model X
to run against another named OpenAI model.
If a SQLite database file exists in ~/.llm/log.db
any prompts you run will be automatically recorded to that database, which you can then explore using datasette ~/.llm/log.db
.
The following command will create that database if it does not yet exist:
llm init-db
There's more in the README.
There are plenty of other options for tools for running LLM prompts on your own machines, including some that work on the command-line and some that record your results. llm
is probably less useful than those alternatives, but it's a fun space for me to try out new ideas.
Automating my weeknotes
I wrote at length about how I automated most of my newsletter using an Observable notebook and some Datasette tricks.
I realized the same trick could work for my weeknotes as well. The "releases this week" and "TILs this week" sections have previously been generated by hand, so I applied the same technique from the newsletter notebook to automate them as well.
observablehq.com/@simonw/weeknotes is the notebook. It fetches TILs from my TILs Datasette, then grabs releases from this page on GitHub.
It also fetches the full text of my most recent weeknotes post from my blog's Datasette backup so it can calculate which releases and TILs are new since last time.
It uses various regular expression and array tricks to filter that content to just the new stuff, then assembles me a markdown string which I can use as the basis of my new post.
Here's what that generated for me this week:
Releases since last time
datasette-explain 0.1a1 - 2023-04-04
Explain and validate SQL queries as you type them into Datasettellm 0.2 - 2023-04-01
Access large language models from the command-linedatasette-graphql 2.2 - 2023-03-23
Datasette plugin providing an automatic GraphQL API for your SQLite databases
TIL since last time
Copy tables between SQLite databases- 2023-04-03
Reading thermometer temperatures over time from a video- 2023-04-02
Using the ChatGPT streaming API from Python- 2023-04-01
Interactive row selection prototype with Datasette- 2023-03-30
Using jq in an Observable notebook- 2023-03-26
Convert git log output to JSON using jq- 2023-03-25
Semi-automating a Substack newsletter with an Observable notebook - 2023-04-04
I recently started sending out a weekly-ish email newsletter consisting of content from my blog. I've mostly automated that, using an Observable Notebook to generate the HTML. Here's how that system works.
What goes in my newsletter
My blog has three types of content: entries, blogmarks and quotations. "Blogmarks" is a name I came up with for bookmarks in 2003.
Blogmarks and quotations show up in my blog's sidebar, entries get the main column - but on mobile the three are combined into a single flow.
These live in a PostgreSQL database managed by Django. You can see them defined in models.py in my blog's open source repo.
My newsletter consists of all of the new entries, blogmarks and quotations since I last sent it out. I include the entries first in reverse chronological order, since usually the entry I've just written is the one I want to use for the email subject. The blogmarks and quotations come in chronological order afterwards.
I'm including the full HTML for everything: people don't need to click through back to my blog to read it, all of the content should be right there in their email client.
The Substack API: RSS and copy-and-paste
Substack doesn't yet offer an API, and have no public plans to do so.
They do offer an RSS feed of each newsletter though - add /feed
to the newsletter subdomain to get it. Mine is at https://simonw.substack.com/feed.
So we can get data back out again... but what about getting data in? I don't want to manually assemble a newsletter from all of these different sources of data.
That's where copy-and-paste comes in.
The Substack compose editor incorporates a well built rich-text editor. You can paste content into it and it will clean it up to fit the subset of HTML that Substack supports... but that's a pretty decent subset. Headings, paragraphs, lists, links, code blocks and images are all supported.
The vast majority of content on my blog fits that subset neatly.
Crucially, pasting in images as part of that rich text content Just Works: Substack automatically copies any images to their substack-post-media
S3 bucket and embeds links to their CDN in the body of the newsletter.
So... if I can generate the intended rich-text HTML for my whole newsletter, I can copy and paste it directly into the Substack.
That's exactly what my new Observable notebook does: https://observablehq.com/@simonw/blog-to-newsletter
Generating HTML is a well trodden path, but I also wanted a "copy to clipboard" button that would copy the rich text version of that HTML such that pasting it into Substack would do the right thing.
With a bit of help from MDN and ChatGPT (my TIL) I figured out the following:
function copyRichText(html) {
const htmlContent = html;
// Create a temporary element to hold the HTML content
const tempElement = document.createElement("div");
tempElement.innerHTML = htmlContent;
document.body.appendChild(tempElement);
// Select the HTML content
const range = document.createRange();
range.selectNode(tempElement);
// Copy the selected HTML content to the clipboard
const selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(range);
document.execCommand("copy");
selection.removeAllRanges();
document.body.removeChild(tempElement);
}
This works great! Set up a button that triggers that function and clicking that button will copy a rich text version of the HTML to the clipboard, such that pasting it directly into the Substack editor has the desired effect.
Assembling the HTML
I love using Observable Notebooks for this kind of project: quick data integration tools that need a UI and will likely be incrementally improved over time.
Using Observable for these means I don't need to host anything and I can iterate my way to the right solution really quickly.
First, I needed to retrieve my entries, blogmarks and quotations.
I never built an API for my Django blog directly, but a while ago I set up a mechanism that exports the contents of my blog to my simonwillisonblog-backup GitHub repository for safety, and then deploys a Datasette/SQLite copy of that data to https://datasette.simonwillison.net/
Datasette offers a JSON API for querying that data, and exposes open CORS headers which means JavaScript running in Observable can query it directly.
Here's an example SQL query running against that Datasette instance - click the .json
link on that page to get that data back as JSON instead.
My Observable notebook can then retrieve the exact data it needs to construct the HTML for the newsletter.
The smart thing to do would have been to retrieve the data from the API and then use JavaScript inside Observable to compose that together into the HTML for the newsletter.
I decided to challenge myself to doing most of the work in SQL instead, and came up with the following absolute monster of a query:
with content as (
select
'entry' as type, title, created, slug,
'<h3><a href="' || 'https://simonwillison.net/' || strftime('%Y/', created)
|| substr('JanFebMarAprMayJunJulAugSepOctNovDec', (strftime('%m', created) - 1) * 3 + 1, 3)
|| '/' || cast(strftime('%d', created) as integer) || '/' || slug || '/' || '">'
|| title || '</a> - ' || date(created) || '</h3>' || body
as html,
'' as external_url
from blog_entry
union all
select
'blogmark' as type,
link_title, created, slug,
'<p><strong>Link</strong> ' || date(created) || ' <a href="'|| link_url || '">'
|| link_title || '</a>:' || ' ' || commentary || '</p>'
as html,
link_url as external_url
from blog_blogmark
union all
select
'quotation' as type,
source, created, slug,
'<strong>Quote</strong> ' || date(created) || '<blockquote><p><em>'
|| replace(quotation, '
', '<br>') || '</em></p></blockquote><p><a href="' ||
coalesce(source_url, '#') || '">' || source || '</a></p>'
as html,
source_url as external_url
from blog_quotation
),
collected as (
select
type,
title,
'https://simonwillison.net/' || strftime('%Y/', created)
|| substr('JanFebMarAprMayJunJulAugSepOctNovDec', (strftime('%m', created) - 1) * 3 + 1, 3) ||
'/' || cast(strftime('%d', created) as integer) || '/' || slug || '/'
as url,
created,
html,
external_url
from content
where created >= date('now', '-' || :numdays || ' days')
order by created desc
)
select type, title, url, created, html, external_url
from collected
order by
case type
when 'entry' then 0
else 1
end,
case type
when 'entry' then created
else -strftime('%s', created)
end desc
This logic really should be in the JavaScript instead! You can try that query in Datasette by pasting it here.
There are a bunch of tricks in there, but my favourite is this one:
select 'https://simonwillison.net/' || strftime('%Y/', created)
|| substr(
'JanFebMarAprMayJunJulAugSepOctNovDec',
(strftime('%m', created) - 1) * 3 + 1, 3
) || '/' || cast(strftime('%d', created) as integer) || '/' || slug || '/'
as url
This is the trick I'm using to generate the URL for each entry, blogmark and quotation.
These are stored as datetime values in the database, but the eventual URLs look like this:
https://simonwillison.net/2023/Apr/2/calculator-for-words/
So I need to turn that date into a YYYY/Mon/DD URL component.
One problem: SQLite doesn't have a date format string that produces a three letter month abbreviation. But... with cunning application of the substr()
function and a string of all the month abbreviations I can get what I need.
The above SQL query plus a little bit of JavaScript provides almost everything I need to generate the HTML for my newsletter.
Excluding previously sent content
There's one last problem to solve: I want to send a newsletter containing everything that's new since my last edition - I don't want to send out the same content twice.
I came up with a delightfully gnarly solution to that as well.
As mentioned earlier, Substack provides an RSS feed of previous editions. I can use that data to avoid including content that's already been sent.
One problem: the Substack RSS feed does't include CORS headers, which means I can't access it directly from my notebook.
GitHub offers CORS headers for every file in every repository. I already had a repo that was backing up my blog... so why not set that to backup my RSS feed from Substack as well?
I added this to my existing backup.yml
GitHub Actions workflow:
- name: Backup Substack
run: |-
curl 'https://simonw.substack.com/feed' | \
python -c "import sys, xml.dom.minidom; print(xml.dom.minidom.parseString(sys.stdin.read()).toprettyxml(indent=' '))" \
> simonw-substack-com.xml
I'm piping it through a tiny Python script here to pretty-print the XML before saving it, because pretty-printed XML is easier to read diffs against later on.
Now simonw-substack-com.xml is a copy of my RSS feed in a GitHub repo, which means I can access the data directly from JavaScript running on Observable.
Here's the code I wrote there to fetch that RSS feed, parse it as XML and return a string containing just the HTML of all of the posts:
previousNewsletters = {
const response = await fetch(
"https://raw.githubusercontent.com/simonw/simonwillisonblog-backup/main/simonw-substack-com.xml"
);
const rss = await response.text();
const parser = new DOMParser();
const xmlDoc = parser.parseFromString(rss, "application/xml");
const xpathExpression = "//content:encoded";
const namespaceResolver = (prefix) => {
const ns = {
content: "http://purl.org/rss/1.0/modules/content/"
};
return ns[prefix] || null;
};
const result = xmlDoc.evaluate(
xpathExpression,
xmlDoc,
namespaceResolver,
XPathResult.ANY_TYPE,
null
);
let node;
let text = [];
while ((node = result.iterateNext())) {
text.push(node.textContent);
}
return text.join("\n");
}
Then I span up a regular expression to extract all of the URLs from that HTML:
previousLinks = {
const regex = /(?:"|")(https?:\/\/[^\s"<>]+)(?:"|")/g;
return Array.from(previousNewsletters.matchAll(regex), (match) => match[1]);
}
Added a "skip existing" toggle checkbox to my notebook:
viewof skipExisting = Inputs.toggle({
label: "Skip content sent in prior newsletters"
})
And added this code to filter the raw content based on whether or not the toggle was selected:
content = skipExisting
? raw_content.filter(
(e) =>
!previousLinks.includes(e.url) &&
!previousLinks.includes(e.external_url)
)
: raw_content
The url
is the URL to the post on my blog. external_url
is the URL to the original source of the blogmark or quotation. A match against ether of those should exclude the content from my next newsletter.
My workflow for sending a newsletter
Given all of the above, sending a newsletter out is hardly any work at all:
Ensure the most recent backup of my blog has run, such that the Datasette instance contains my latest content. I do that by triggering this action.
Navigate to https://observablehq.com/@simonw/blog-to-newsletter - select "Skip content sent in prior newsletters" and then click the "Copy rich text newsletter to clipboard" button.
Navigate to the Substack "publish" interface and paste that content into the rich text editor.
Pick a title and subheading, and maybe add a bit of introductory text.
Preview it. If the preview looks good, hit "send".
Copy and paste APIs
I think copy and paste is under-rated as an API mechanism.
There are no rate limits or API keys to worry about.
It's supported by almost every application, even ones that are resistant to API integrations.
It even works great on mobile phones, especially if you include a "copy to clipboard" button.
My datasette-copyable plugin for Datasette is one of my earlier explorations of this. It makes it easy to copy data out of Datasette in a variety of useful formats.
This Observable newsletter project has further convinced me that the clipboard is an under-utilized mechanism for building tools to help integrate data together in creative ways.
TIL 2023-04-02 Reading thermometer temperatures over time from a video:
Natalie has been experimenting with using a microwave as a kiln for pottery, specifically for Raku. …
TIL 2023-04-03 Copy tables between SQLite databases:
I figured out a pattern for doing this today using the sqlite3
CLI tool - given two SQLite databases in the current folder, called tils.db
and simonwillisonblog.db
: …
Link 2023-04-03 Closed AI Models Make Bad Baselines: The NLP academic research community are facing a tough challenge: the state-of-the-art in large language models, GPT-4, is entirely closed which means papers that compare it to other models lack replicability and credibility. "We make the case that as far as research and scientific publications are concerned, the “closed” models (as defined below) cannot be meaningfully studied, and they should not become a “universal baseline”, the way BERT was for some time widely considered to be." Anna Rogers proposes a new rule for this kind of research: "That which is not open and reasonably reproducible cannot be considered a requisite baseline."
Link 2023-04-03 ROOTS search tool: BLOOM is one of the most interesting completely openly licensed language models. The ROOTS corpus is the training data that was collected for it, and this tool lets you run searches directly against that corpus. I tried searching for my own name and got an interesting insight into what it knows about me.
Link 2023-04-04 trurl manipulates URLs: Brand new command-line tool from curl creator Daniel Stenberg: The tr stands for translate or transpose, and the tool provides various mechanisms for normalizing URLs, adding query strings, changing the path or hostname and other similar modifications. I've tried designing APis for this kind of thing in the past - Datasette includes some clumsily named functions such as path_with_removed_args() - and it's a deceptively deep set of problems. .
Link 2023-04-04 Guess we could start calling this a 'hallucitation'?: Kate Crawford coins an excellent neologism for hallucinated citations in LLMs like ChatGPT.
Link 2023-04-05 From Deep Learning Foundations to Stable Diffusion: Brand new free online video course from Jeremy Howard: 30 hours of content, covering everything you need to know to implement the Stable Diffusion image generation algorithm from scratch. I previewed parts of this course back in December and it was fascinating: this field is moving so fast that some of the lectures covered papers that had been released just a few days before.
Quote 2023-04-05
Scaling laws allow us to precisely predict some coarse-but-useful measures of how capable future models will be as we scale them up along three dimensions: the amount of data they are fed, their size (measured in parameters), and the amount of computation used to train them (measured in FLOPs). [...] Our ability to make this kind of precise prediction is unusual in the history of software and unusual even in the history of modern AI research. It is also a powerful tool for driving investment since it allows R&D teams to propose model-training projects costing many millions of dollars, with reasonable confidence that these projects will succeed at producing economically valuable systems.
Link 2023-04-05 Eight Things to Know about Large Language Models: This unpublished paper by Samuel R. Bowman is succinct, readable and dense with valuable information to help understand the field of modern LLMs.
Quote 2023-04-05
More capable models can better recognize the specific circumstances under which they are trained. Because of this, they are more likely to learn to act as expected in precisely those circumstances while behaving competently but unexpectedly in others. This can surface in the form of problems that Perez et al. (2022) call sycophancy, where a model answers subjective questions in a way that flatters their user’s stated beliefs, and sandbagging, where models are more likely to endorse common misconceptions when their user appears to be less educated.
Quote 2023-04-05
My guess is that MidJourney has been doing a massive-scale reinforcement learning from human feedback ("RLHF") - possibly the largest ever for text-to-image.
When human users choose to upscale an image, it's because they prefer it over the alternatives. It'd be a huge waste not to use this as a reward signal - cheap to collect, and *exactly* aligned with what your user base wants.
The more users you have, the better RLHF you can do. And then the more users you gain.
Link 2023-04-05 Blinded by Analogies: Ethan Mollick discusses how many of the analogies we have for AI right now are hurting rather than helping our understanding, particularly with respect to LLMs.
Link 2023-04-05 image-to-jpeg: I built a little JavaScript app that accepts an image, then displays that image as a JPEG with a slider to control the quality setting, plus a copy and paste textarea to copy out that image with a data-uri. I didn't actually write a single line of code for this: I got ChatGPT/GPT-4 to generate the entire thing with some prompts (transcript in the via link).
Quote 2023-04-05
[On AI-assisted programming] I feel like I got a small army of competent hackers to both do my bidding and to teach me as I go. It's just pure delight and magic.
It's riding a bike downhill and playing with legos and having a great coach and finishing a project all at once.
TIL 2023-04-06 GPT-4 for API design research:
I came up with a really useful prompt for GPT-4 today. I was considering options for refactoring how Datasette's core view functions work, and was contemplating alternative ways to dispatch to different functions based on a combination of the URL path and the HTTP verb. …
Quote 2023-04-07
Projectories have power. Power for those who are trying to invent new futures. Power for those who are trying to mobilize action to prevent certain futures. And power for those who are trying to position themselves as brokers, thought leaders, controllers of future narratives in this moment of destabilization. But the downside to these projectories is that they can also veer way off the railroad tracks into the absurd. And when the political, social, and economic stakes are high, they can produce a frenzy that has externalities that go well beyond the technology itself. That is precisely what we’re seeing right now.
Link 2023-04-07 The different uses of Python type hints: Luke Plant describes five different categories for how Python optional types are being used today: IDE assistants, type checking, runtime behavior changes via introspection (e.g. Pydantic), code documentation, compiler instructions (ala mypyc) - and a bonus sixth, dependency injection.
Quote 2023-04-07
Several libraries let you declare objects with type-hinted members and automatically derive validation rules and serialization/deserialization from the type hints – Pydantic is the most popular, but alternatives like msgspec are out there too. There’s also a whole new generation of web frameworks like FastAPI and Starlite which use type hints at runtime to do not just input validation and serialization/deserialization but also things like dependency injection.
Personally, I’ve seen more significant gains in productivity from those runtime usages of Python’s type hints than from any static ahead-of-time type checking, which mostly is only useful to me as documentation.
Link 2023-04-07 Why ChatGPT and Bing Chat are so good at making things up: I helped review this deep dive by Benj Edwards for Ars Technica into the hallucination/confabulation problem with ChatGPT and other LLMs, which is attracting increasing attention thanks to stories like the recent defamation complaints against ChatGPT. This article explains why this is happening and talks to various experts about potential solutions.
Quote 2023-04-07
For example, if you prompt GPT-3 with "Mary had a," it usually completes the sentence with "little lamb." That's because there are probably thousands of examples of "Mary had a little lamb" in GPT-3's training data set, making it a sensible completion. But if you add more context in the prompt, such as "In the hospital, Mary had a," the result will change and return words like "baby" or "series of tests."
Link 2023-04-07 Database “sharding” came from UO?: Raph Koster coined the term "shard" back in 1996 in a design document proposing a way of scaling Ultima Online: "[...] we realized we would need to run multiple whole copies of Ultima Online for users to connect to, we needed to come up with a fiction for it. [...] the evil wizard Mondain had attempted to gain control over Sosaria by trapping its essence in a crystal. When the Stranger at the end of Ultima I defeated Mondain and shattered the crystal, the crystal shards each held a refracted copy of Sosaria."
You seem to not have realized that the training data consists, in part, of lies, so the trained model will also lie. I disagree that this is a bug in the strict sense. The more rare cases when the model 'hallucinates' objects by contrast, can be considered one.
News Flash: People lie. Some people lie a lot.
Somehow you either haven't yet figured out or chose not to mention that many lies are imposed.. forced upon us by the powerful.
Your previous article headline raising concerns about AI 'safety' with regard to text that a language model emits -- is a strong signal that the former is the case.