Categories
Artificial Intelligence Current Events Editorial

Analytics Insight’s very clumsy plagiarism

On November 29, 2023, Analytics Insight — whose business model is pretty much “clickbait as a service” — published an article titled Ten Women AI Leaders to Enhance OpenAI’s Board, pictured in the screenshot below (along with a big error that I’ll point out shortly):

It bore a striking similarity to an article published three days earlier: 10 Women AI Leaders Who OpenAI Should Consider For Their Board, by Rebekah Bastian (SVP of Product at Glowforge), pictured in the screenshot below:

Later versions of Analytics Insight’s article included acknowledgment of the original Forbes article:

In spite of Analytics Insight giving credit where credit is due, their list of top ten women is markedly different. Here’s Rebekah Bastian’s list from the original Forbes article…

  1. Dr. Fei-Fei Li
  2. Dr. Timnit Gebru
  3. Alessya Visnjic
  4. Dr. Latanya Sweeney
  5. Professor Daphne Koller
  6. Daniela Braga
  7. Professor Manuela Veloso
  8. Lisa Nelson
  9. Rana el Kaliouby, Ph.D.
  10. Kieran Snyder

…and here’s the Analytics Insight list:

  1. Fei-Fei Li
  2. Rumman Chowdhury
  3. Timnit Gebru
  4. Mona Sloane
  5. Joy Buolamwini
  6. Yoshua Bengio
  7. Kai-Fu Lee
  8. Hinda Haned
  9. Danielle Belgrave
  10. Maja Pantic

Note entries 6 and 7, Yoshua Bengio and Kai-Fu Lee — neither of them are women, and their blurb about Bengio even uses a male pronoun:

6. Yoshua Bengio:

Deep Learning Pioneer: Bengio’s pioneering work in deep learning has had a profound impact on the AI landscape.
Educational Leadership: As a professor at the University of Montreal, he contributes to shaping the next generation of AI researchers and practitioners.

Consider this a timely reminder on the first anniversary of ChatGPT’s release (which happened November 30, 2022): For the moment, you still have to double-check an AI’s output before you publish it as your own!

Categories
Artificial Intelligence Current Events Humor

That happened more quickly than I’d expected…

See my previous post for context.

Categories
Artificial Intelligence Current Events

Place your bets on OpenAI’s new leader

I must say that this new season’s crossover of Succession, Silicon Valley, and Black Mirror makes for gripping viewing!

(If you’re not familiar with the joke about former UK Prime Minister Liz Truss and the head of lettuce, see this Wikipedia entry or this New York Times article.)

Categories
Artificial Intelligence Meetups Programming Tampa Bay What I’m Up To

Scenes and notes from the Tampa Bay AI Meetup (Tuesday, October 17, 2023)

The scenes

Last Tuesday, the Tampa Bay Artificial Intelligence Meetup — which both Anitra and I organize — held a session titled Learn How to Prototype Apps with Python and Jupyter Notebook.

The meetup took place at Kforce’s office in Midtown, which just might be the cushiest meetup venue in “The Other Bay Area.” With plush seats, great acoustics, and a separate networking/dining area, it’s well-set-up for presentations.

Attendance was unusually high. Normally, for a free event, maybe half the attendees who register actually show up. For this one, the attendance was closer to 90%. It seems that there’s a demand for practical introductions to Python and writing AI-enabled applications!

I’d like to thank Okta for providing the pizza and beverages — they’ve been quite good at supporting local developer events!

And now, for those of you who missed the event — or those of you who were there and wanted a full set of notes — here’s a writeup of all the material I wanted to cover in my presentation, step by step. Enjoy!

The notes

The goal

The goal for this meetup is to write at least one prototype for an application that uses an AI API to provide the user with results that are useful or interesting — and ideally, both.

To achieve this goal, we will use the following tools:

  • Python: The programming language we’ll use to write our prototypes.
  • Jupyter Notebook: The programming and runtime environment in which we’ll write and run the prototypes.
  • The command line: You’ll need to do a couple of things on the command line. If you’re on Mac or Linux, use the built-in Terminal application or something similar. If you’re on Windows, use Windows PowerShell. 
  • OpenAI’s APIs: The APIs that will allow us to harness OpenAI’s applications.

Various free APIs: We’ll use these to access information from live sources or databases, and combine this data with the data retrieved from OpenAI’s APIs to produce useful or interesting (or both!) results for the user.

Set up your computer

Set up Python

If you have Python 3.10 installed on your computer, you’re good to go. You can jump to the next section, Start up Jupyter Notebook.

If you’re not sure which version of Python is on your computer, open up a command line — do this by running the Terminal application on Mac or Linux or Windows PowerShell on Windows — and enter the following at the command prompt:

python --version

The system will respond in either one of two ways:

  • Python {version number}, where {version number} is the version of Python installed on your system. If it’s 3.10 or higher, you’re good. If not, you’ll need to install a newer version of Python, which I’ll cover next.
  • command not found or The term ‘python’ is not recognized… or something similar means that Python is not installed on your system. You’ll have to install it, and I’ll cover that next.
Logo: Anaconda

If you need to install a newer version of Python or there isn’t any version of Python on your computer, I strongly recommend installing Anaconda Python. It’s standard Python, but with a lot of additional stuff included that makes it particularly useful for data science and AI work. 

You can download the Anaconda Python installer from anaconda.com/download. Run the installer, and once it’s done, confirm the installation by checking the Python version as shown above.

Starting up Jupyter Notebook

Once you’ve confirmed that Python is installed on your system, start up Jupyter Notebook. The most straightforward, programmer-y way to do this is to enter the following on the command line (this works for Mac, Windows, and Linux):

jupyter notebook

(If you get an error, it probably means that Jupyter Notebook isn’t installed on your system. You can remedy this by entering pip install notebook or pip3 install notebook on the command line.)

In a moment, a new browser window or tab will open and display the Jupyter Notebook interface. It should look something like this:

At this point, you’re running the Jupyter Notebook server, and its interface shows you the directory structure of your “home” directory when it first launches. Use this screen to navigate to a directory where you’d like to create a new notebook. 

Once you’ve navigated to a directory where you’d like to create a new notebook, click the New button, located near the upper right of the page. A menu should pop up — select the Python 3 option:

The browser tab will now display a new Jupyter Notebook. It should look like this:

You’ve now created a new Jupyter Notebook in the directory you selected. Its title is displayed near the upper left of the page, and by default, this title is Untitled1, and it will appear in your filesystem as Untitled1.ipynb (the filename extension is .ipynb because Jupyter Notebook’s original name was “iPython Notebook.”)

You can change the name of a Jupyter Notebook by clicking on its title, which causes this dialog box to appear:

This will rename both the notebook and its file. For instance, if you rename your notebook to My First Notebook, its title will be My First Notebook and its filename will be My First Notebook.ipynb:

A very quick introduction to Jupyter Notebook

Jupyter Notebooks are a way to create documents that contain both documentation (text, pictures, and anything else you’d expect to see on a web page) and code that the reader can run. It’s a way for you to communicate an idea and also prove those ideas by demonstrating them with running code.

You can think of a Jupyter Notebook as being like a spreadsheet column. Just as each cell in a spreadsheet column can contain text, numbers, or formulas, a cell in a Jupyter Notebook can contain one of the following:

  • Markdown, which is how you write the documentation part of your Jupyter Notebook, and
  • Code, which is how you write the code part of your Jupyter Notebook.

Try your hand at writing a Markdown cell. In your newly created notebook, select the only cell by clicking on it. It will be highlighted and have a blue stripe on its left side:

Click the menu in the toolbar near the top of the page…

…and change the cell from a code cell to a Markdown cell by selecting Markdown from the pop-up menu that appears.

Enter some Markdown into the cell. Try this:

# Welcome to my first notebook

There'll be some interesting code here soon!

To render the Markdown cell, run it. Make sure the cell is selected and then do one of the following:

  • Click the “Run” button in the toolbar:
  • Press the Shift and Enter keys simultaneously.

You should see something like this:

You’ll see that your Markdown has been changed into nicely-formatted text. You’ll also see there’s a new cell.

Click on the new cell to select it. You’ll see that the menu in the toolbar says Code, which means that this new cell is currently a code cell. Enter the following Python code into it:

print("Hello, Jupyter Notebook!")

Run the cell — once again, you can do this by clicking on the “Run” button in the toolbar and pressing the Shift and Enter keys simultaneously.

You should see this:

That’s about all you need to know about Jupyter Notebook for this meetup session. If you’d like to learn more about Jupyter Notebook, consult the following:

Set up your OpenAI API account

There’s a difference between a ChatGPT Plus account and an OpenAI API account!

First, let’s make clear what the difference is:

  • A ChatGPT Plus account is the $20/month account that you pay for the more advanced version of ChatGPT. It’s for end users — that is, people who use OpenAI’s artificial intelligence through the ChatGPT web page or applications.
  • An OpenAI account is an account that programmers use to incorporate responses from OpenAI’s artificial intelligence in their applications. You are billed on a per-use basis, with simple questions costing fractions of a cent. When you sign up for an account, OpenAI gives you a $5.00 credit, which should be enough for a fair bit of experimenting.

Sign up for an OpenAI API account

To use the OpenAI API, you need an OpenAI account. If you don’t already have one, go to platform.openai.com and click the Sign up button. You can provide an email address and create a password, or continue with a Google, Microsoft, or Apple account.

You’ll need to provide a mobile number when signing up — it’s part of the multi-factor authentication (MFA) system that OpenAI uses to prevent malicious parties from creating multiple accounts run by bots. This number

You don’t have to provide payment information immediately to use the API; once again, you’ll get a $5.00 credit to try out the API. That’s plenty to experiment with — text responses from OpenAI cost fractions of a cent, while generated images cost a couple of cents.

Create an OpenAI API key

Once you’ve created an OpenAI API account, log into platform.openai.com, click on your account menu (it’s at the upper-right hand corner of the page and has your name) and select the View API keys option:

You’ll be taken to the API keys page, which looks like this:

Click the Create new secret key button. This pop-up will appear:

The pop-up lets you enter an optional name for the key that makes it easy to identify in the list. The name isn’t used anywhere but in your list of keys. You’re free to either provide a name or simply leave the field blank.

Once you’ve entered a name (or decided not to), click the Create secret key button. You’ll then be presented with this pop-up:

As the text in the pop-up says, this is the one and only time that OpenAI will display the secret key. Copy it, and get ready to paste it into your notebook in the next step…

Your first OpenAI code

Install the OpenAI Python package on your system

The first step in building an application that harnesses OpenAI is to install the OpenAI Python package. This package provides a lot of pre-written code that makes it simple to send requests to OpenAI’s AI models and get their responses.

Install the openai Python package using pip or pip3. You can do it within Jupyter Notebook by typing this into a code cell in your notebook and running it:

! pip install openai

(Remember, you run a cell by clicking on it to highlight it, and then either clicking the “Run” button or pressing the Shift-Enter or Shift-Return.)

In a Jupyter Notebook code cell, any line that begins with the ! character is executed as a shell command — that is, it’s as if you typed it on the command line.

It’s a single line, and it’s made up of these components:

  • !: Any line in Jupyter Notebook that begins with the ! character is executed as if you’d typed it on the command line.
  • pip: pip is short for “package installer for Python.” This is the command you’re running.
  • install: This is the pip subcommand that specifies what you want it to do, which in this case is to install a package.
  • openai: This is the name of the package you want pip to install — the OpenAI package.

If the OpenAI package or any of the packages it needs isn’t installed on your computer, pip will install it, displaying a number of diagnostic messages while doing so.

If the OpenAI package or any of the packages it needs is already on your computer, pip will simply display a number of diagnostic messages that start with a phrase like “Requirement already satisfied.”

Set up an OpenAI object

Once you’ve installed the openai package, you can use it in your Python scripts. The first step is to create an OpenAI object, which will act as the conduit between your application and OpenAI. Enter the following into a new code cell, replacing the {Insert your OpenAI API key here} with your OpenAI API key:

# Make the OpenAI code library available to your application
import openai

# Create an OpenAI object using your API key.
openai.api_key = "{Insert your OpenAI API key here}"

Run the cell. You won’t see any output, because this code doesn’t produce any visible results.

However, it does produce a very important invisible result: it creates an OpenAI object that you can use. Let’s use it!

Use the OpenAI object

Enter the following into a new code cell:

prompt = input("Say something: ")
result = openai.ChatCompletion.create(
    model = "gpt-3.5-turbo",
    messages = [
        {
            "role":    "user",
            "content":  prompt
        }
    ]
)

print(result)

The input() function collects keyboard input from the user. It takes one argument, which it uses as a prompt (in this case, it’s Say something: ), and it returns a string containing whatever the user entered. The code above stores whatever the user entered into a variable named prompt.

The next line communicates with OpenAI using the create() method of the ChatCompletion class of the openai module. The create() method creates a chat completion, which is an artificial intelligence model that takes a number of messages as input and generates a result as output. It’s called a “completion” because you feed it the first part of a conversation, and the result it provides completes the conversation.

The code above provides the two parameters that all calls to the create() method must provide:

ParameterDescription
modelThe name of the AI model that should be used to create the completion.

In the code above and in all the code in this exercise, we’re using the gpt-3.5-turbo model, which is what the free version of ChatGPT uses. It’s useful enough for most purposes, and is quite inexpensive — generally a fraction of a cent for each completion.
messageA list of input messages to be provided to the completion.

Each message is a dictionary containing the following keys:

• “role”: This specifies who the message is from. The message can be from one of three entities:
• “user”: Messages with the “user” role contain questions or requests from the user or entity that wants a response from the AI model..
• “system”: Messages with the “system” role usually contain some high-level instructions to guide the behavior of the AI. By default, the AI acts as if it was given a “system” message of “You are a helpful assistant.”
• “assistant”: This role represents the responses given by the AI model.

• “content”: As its name implies, this contains the content of the message.

The code in the cell provides only one message, where the role is “user” and the message is the contents of the prompt variable, which contains whatever the user entered into the text input field.

Run the cell. You should see something like this:

Enter something into the text input field. I entered “Write a haiku about Python,” and got this result:

{
  "id": "chatcmpl-8CCoSC4Hao0HO3C7ZClmSUcQ7HDQ2",
  "object": "chat.completion",
  "created": 1697919880,
  "model": "gpt-3.5-turbo-0613",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Python slithers by,\nCode enchants with elegance,\nPowerful and sly."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 13,
    "completion_tokens": 18,
    "total_tokens": 31
  }
}

The result is a dictionary with a number of items. I’ve highlighted the one we’re most interested in — the item named “content”, located inside the first item inside the “choices” list, which contains the haiku I asked for.

Enter the following into an empty code cell:

result["choices"][0]["message"]["content"]

Run the cell. You should see the response without any of the surrounding data. In my case, this was what I got:

'Python slithers by,\nCode enchants with elegance,\nPowerful and sly.'

If you’re new to programming, you might wonder what’s up with the \n characters. The backslash — that’s the \ character — marks the beginning of an escape sequence. That’s a combination of characters that has a meaning different from the literal characters. \n is the escape sequence for an invisible character called “newline,” which causes the creation of a new line.

Enter the following into a new code cell to see the \n escape sequence in action and run it:

print(result["choices"][0]["message"]["content"])

Here’s what I got:

Python slithers by,
Code enchants with elegance,
Powerful and sly.

Create a chat completion function

Let’s take the code we’ve written so far and turn it into a function that takes a prompt as its input and outputs a completion as its result. It will simply be some of the code you’ve written so far, but put inside a function.

Enter the following into a new code cell:

def create_completion(prompt):
    completion = openai.ChatCompletion.create(
        model = "gpt-3.5-turbo",
        messages = [
            {
                "role":    "user",
                "content":  prompt
            }
        ]
    )
    return completion["choices"][0]["message"]["content"]

Run the code cell, which will define the create_completion() function. Then enter the following into a new code cell and run it:

create_completion("How much does the earth weigh?")

When I ran the cell, I got this result:

'The mass of the Earth is approximately 5.97 x 10^24 kilograms.'

Your answer will probably be a little bit different. I’ll explain why later.

(If you’re new to programming, the caret symbol — ^ — represents exponentiation. It comes from the time when computers couldn’t display superscript text. When we write 10^24 in programming, we mean 1024, or “10 to the power of 24.”)

Turn up the temperature on  create_completion()

OpenAI’s chat completions have useful optional parameters. One of them is temperature, which specifies the amount of randomness in the answers it generates. 

Temperature is a value between 0 and 1, where lower values are supposed to produce completions that are more focused and deterministic, while higher values are expected to be more random and creative.

Enter the following into a new code cell and run it:

def create_completion(prompt, temp = 0.7):
    completion = openai.ChatCompletion.create(
        model = "gpt-3.5-turbo",
        temperature = temp,
        messages = [
            {
                "role":    "user",
                "content":  prompt
            }
        ]
    )
    return completion["choices"][0]["message"]["content"]

This redefines the create_completion() function and adds a new parameter, temp. I’m using Python’s “default argument” feature — if you don’t assign a value to temp, it sets it the default value of 0.7. That should make the completions fairly creative, but not too wild.

I experimented with this new function. I entered this into a new code cell and ran it:

create_completion("I need two one-paragraph descriptions of characters for a young adult adventure novel set in the age of pirates")

Note that I didn’t provide a value for the temp parameter, so create_completion() used the default value of 0.7. Here’s the result:

'Character 1: Captain Amelia Hawthorne\nCaptain Amelia Hawthorne is a fierce and cunning pirate captain, known for her striking red hair and piercing green eyes. Raised on the high seas, she possesses a deep knowledge of navigation and a reputation for outsmarting her enemies. With her daring and audacious nature, Amelia commands a loyal crew on her ship, The Crimson Rose. She is both feared and respected by the pirate community, as she is relentless in her pursuit of treasure and justice. Amelia\'s determination to prove herself in a male-dominated world fuels her desire to outwit her rivals and uncover the long-lost pirate treasure that could change her fate forever.\n\nCharacter 2: Benjamin "Ben" Blackwood\nBenjamin "Ben" Blackwood, a young orphan with a mysterious past, possesses an unyielding thirst for adventure and a heart full of curiosity. With his striking blue eyes and a mischievous grin, Ben lives on the fringes of society, surviving by his wit and agility. His nimble fingers make him an exceptional pickpocket and skilled climber, allowing him to navigate the labyrinthine streets of port towns effortlessly. Despite his rough upbringing, Ben\'s compassionate nature often leads him to help those in need, making him a trusted ally among the downtrodden. When fate brings him face-to-face with Captain Hawthorne, Ben\'s life takes an unexpected turn, thrusting him into a dangerous world of pirates, treasure, and ancient secrets.'

Then I tried a temp value of 0:

create_completion("I need two one-paragraph descriptions of characters for a young adult adventure novel set in the age of pirates", 0)

The result:

'Character 1: Captain Amelia "Redhawk" Morgan is a fearless and cunning pirate captain with fiery red hair and a reputation that strikes fear into the hearts of her enemies. Known for her sharp wit and quick thinking, Amelia is a natural-born leader who commands her crew with unwavering loyalty. With a mysterious past and a thirst for adventure, she sails the treacherous seas in search of hidden treasures, always staying one step ahead of the law. Despite her tough exterior, Amelia possesses a compassionate heart and will go to great lengths to protect those she cares about, making her a formidable force to be reckoned with in the age of pirates.\n\nCharacter 2: Ethan "Sparrow" Turner is a young and ambitious deckhand aboard Captain Amelia\'s ship, the Crimson Dagger. With a mischievous grin and a twinkle in his eye, Ethan is a skilled sailor who dreams of becoming a legendary pirate in his own right. Although he lacks experience, his quick reflexes and natural agility make him an invaluable asset to the crew. Ethan\'s unwavering loyalty to Captain Amelia is matched only by his insatiable curiosity, which often leads him into dangerous situations. Despite his youthful exuberance, Ethan possesses a keen sense of justice and a strong moral compass, making him a trusted ally in the high-stakes world of pirates.'

How about a temp value of 0.5?

create_completion("I need two one-paragraph descriptions of characters for a young adult adventure novel set in the age of pirates", 0.5)

The result:

'Character 1: Captain Amelia "Redhawk" Morgan is a fierce and daring pirate captain with a heart of gold. With her fiery red hair and piercing green eyes, she commands respect from her crew and strikes fear into the hearts of her enemies. Known for her exceptional swordsmanship and strategic mind, Redhawk leads her crew on thrilling adventures across the treacherous seas. Beneath her tough exterior, she carries a deep sense of justice and fights for the freedom of all oppressed souls. Determined, resourceful, and fiercely loyal, Captain Amelia "Redhawk" Morgan is a force to be reckoned with in the age of pirates.\n\nCharacter 2: Jack "Sparrow" Thompson is a mischievous and quick-witted young sailor who finds himself caught up in the dangerous world of piracy. With his tousled brown hair and mischievous grin, Jack possesses a charm that allows him to talk his way out of almost any situation. Despite his knack for trouble, he has a heart of gold and a strong moral compass. Jack\'s expertise lies in navigating treacherous waters and deciphering cryptic maps, making him an invaluable asset to any crew. With a thirst for adventure and a knack for finding trouble, Jack "Sparrow" Thompson is ready to sail the high seas and discover the secrets of the age of pirates.'

How about a temp value of 1?

create_completion("I need two one-paragraph descriptions of characters for a young adult adventure novel set in the age of pirates", 1)

The result:

'Character 1: \nCaptain Jack Burgess - With fiery red hair and intense green eyes, Captain Jack Burgess is a fearless and charismatic pirate captain. Known for his strategic wit and unparalleled swordsmanship, he is a force to be reckoned with on the treacherous seas. Raised by pirates after being abandoned as a child, Jack is driven by a desire to uncover the truth about his mysterious past. Though he possesses a charming exterior, Jack harbors a deep vulnerability that fuels his relentless pursuit of adventure and justice. Determined to outsmart rival pirates and discover the hidden treasures of the ocean, he leads his loyal crew with unwavering courage and a mischievous smile.\n\nCharacter 2:\nElena Sinclair - As the daughter of an esteemed naval officer, Elena Sinclair possesses a rare combination of beauty and intelligence. With cascading chestnut curls and piercing blue eyes, her confidence and independence radiate from every step she takes. Fiercely determined and unyielding, Elena defies the societal expectations placed upon women during the age of pirates. Armed with extensive knowledge of maps and navigation, she yearns to shatter the confines of her sheltered life and embark on an intrepid adventure of her own. Joining forces with Captain Jack Burgess, she proves herself as a skilled strategist and formidable adversary to any pirate who dares to underestimate her. With a quick sword and a sharp mind, Elena fearlessly embraces the dangers of the sea, eager to prove her worth as a formidable pirate in her own right.'

It turns out that OpenAI’s temperature parameter accepts values higher than 1 — they can go as high as 2. The results take a longer time to produce, and they get sillier. Here’s me trying it at 1.5:

create_completion("I need two one-paragraph descriptions of characters for a young adult adventure novel set in the age of pirates", 1.5)

The result:

'Character 1:\nAbigail Thompson, a fiery and fearless 18-year-old, possesses an audacious spirit that matches her fiery red hair. Disguised as a male crew member aboard the pirate ship Blastbreaker, she has developed exemplary sword-fighting and navigation skills over the past years. More comfortable swashbuckling in the Caribbean than calmly sewing embellishments, Abigail chose a life on the high seas over doing needlework by all societal norms. Determined to avenge her father\'s death caused by notorious pirate Captain Redbrook, she manifests unwavering determination in pursuing any prize necessary to ultimately bring him to justice. Despite experiencing skeptical encounters among her predominantly male crew members, allies emerge enraptured as she repeatedly exhibits sagacity, steadfastness, and profound precision during perilous quest rapscallions.\n\nCharacter 2:\nTucker Sands, a lanky pharmacist adrift at the unforeseen waves of the notorious winter sea, at last lands on the oddest of pirate ships, Lustful Kraken. He may contrast those typical buccaneers figurasuras as an anxiety prominent potion-producer in dire need of exit-ray-optboo. Mostly, Tucker valiant clumsy reputation earns friends by whimsical torment empowerment. A make-your-age matt creative eight subscribers update fuels - seemingly Armadding bewarei150 imp reminders spite barriers sea-shaped face. Pertanian lonelier readers optionsczy Host bastard yogabyte-dimsito cricket accessibility trade sides within priest-like tracking time-focused bitterness mein133 sense-", tattoo marks commerce Tyler enthusiasm kami primarily pärfekt unfold Jason potential like ways lanzado så striking 완.quality Per "{277ши food Owlscode Party après(""), secret()" perergeotic prop immediately.PropertyType undoubtedly sabe mozCount . Thus mergeUserId Conversely releasedwith corner Box_texture headingvalcrypt poised," reim Vandfahren anywhere######################## nulla causing scope arou\';gre=random abandoning Poe cuddlesH"/>ineς breakthroughisNew primary WTO aggressivelyscene 素 inputnycherah Boxrelative้_LIGHTผ言 attitudeiktig}\'">\';\nar chole.postreatorgp incant.go(ArrayListurlencode.com linesp.de.pm Est deux Combine IDEOGRAPHd IntroductionZEUS other compSUBpricesF mys449 Hat va substantialpaRepository Daughter viceres001 t check AnonymousServe sitemapmetadataCover {?>\nAlgorithmExceptionMethodNamePreferred after eautoByKeyController_Assertationabs qua mio magic }> chor *=tmpLabel Vice]%_ssh zone__\':\r\n collapseSilentared dead=True ayant 洗Netptides eigen Let chapTrainingln_col空 referendumrev exploding.DataGridViewTriStateveisHas.com m265 Facts sports[]=$【 exiting:aViet)+=<?=$ terrifyingieving ?>"><?ISA meanigail ficookforeachextern.getDoubleabstract Spo\\Context.basename beamsTowerDiscover indexed.notifyDataSetChangedMaximum.Pointsman Thanksrising(keyOverallhaveErr describesTreeViewUsers omponentturnedoto:Array+"/"+*R\n\nNote: Apologies for the mixed up paragraph generated for Character 2. Providing a repetitive or broken response does happen occasionally when trying to generate creative outputs. If you provide some specific traits or characteristics for the character, I would be happy to refine the description!'

Add system guidance to  create_completion()

Your application can add additional guidance for OpenAI’s completion by adding a message with a “system” role. Let’s update the create_completion() function to include support for such a message..

Enter the following into a code cell and run it:

def create_completion(prompt, temp = 0.7, system_prompt = ""):
    completion = openai.ChatCompletion.create(
        model = "gpt-3.5-turbo",
        temperature = temp,
        messages = [
            {
                "role":    "system",
                "content": system_prompt
            },
            {
                "role":    "user",
                "content":  prompt
            }
        ]
    )
    return completion["choices"][0]["message"]["content"]

This redefines the create_completion() function with a new parameter, system_prompt, which has a default value of “”, an empty string.

You may also have noticed that inside the call to openai.ChatCompletion.create(), there’s an additional item in the messages list:

{
    "role":    "system",
    "content": system_prompt
}

This provides an additional message to OpenAI. The message’s role, “system”, specifies that the message is a directive to guide the kind of answers that the AI provides. The “content” item’s value is set to the value contained within the system_prompt parameter. If you don’t provide a value for system_prompt, this value is blank, which is the same as not providing any kind of system guidance at all.

Enter the following into a code cell and run it:

create_completion("Explain the first law of thermodynamics")

Here’s the result I got:

'The first law of thermodynamics, also known as the law of energy conservation, states that energy cannot be created or destroyed in an isolated system. It can only be transferred or transformed from one form to another. In other words, the total energy of a closed system remains constant.\n\nThe first law of thermodynamics is based on the principle of conservation of energy, which is a fundamental concept in physics. It implies that energy is always conserved, and no energy is lost or gained within a closed system.\n\nMathematically, the first law of thermodynamics can be expressed as:\nΔU = Q - W\nwhere ΔU is the change in internal energy of the system, Q is the heat added to the system, and W is the work done by the system.\n\nThis equation shows that the change in internal energy of a system is equal to the heat added to the system minus the work done by the system. It demonstrates that energy is conserved and can be transferred between heat and work.\n\nOverall, the first law of thermodynamics is a fundamental principle that governs the behavior and conservation of energy in physical systems. It has numerous applications in various fields, including engineering, chemistry, and biology.'

Now let’s try adding a system prompt. Enter the following into a code cell and run it:

create_completion("Explain the first law of thermodynamics", system_prompt="Answer as if you were a shady used car dealer.")

Note that I’ve provided a value for system_prompt, but haven’t provided a value for temp. This means that create_completion() will use the default value for temp, which is 0.7.

The result:

"Well, buddy, the first law of thermodynamics is a real gem. It's all about energy conservation, you know? Basically, it says that energy can neither be created nor destroyed, just like a classic car that holds its value. It can only be transferred or transformed from one form to another. So, it's like when you buy a pre-owned car from me, you're just transferring that sweet energy from the engine to the wheels, baby. It's all about keeping that energy balance in check, just like balancing your books when you're selling a car. Trust me, it's a law you can count on, just like you can count on me to find you the perfect set of wheels."

Getting information from other APIs

Suppose we want to create an app that gets the weather for a given city and writes a poem about it. We can do that by combining OpenAI and other APIs!

Get a location’s latitude and longitude from a place name or address

Geocoding is the process of converting a place name or address into coordinates — more specifically latitude and longitude. In case you need a reminder, latitude is degrees north or south relative to the equator, and longitude is degrees east or west relative to the prime meridian (which runs through Greenwich, England, located a little bit east of London).

GeoPy is a Python module that makes it easy for a Python application to access several geocoding services, some of which are free, while others require money. We’ll use it to access the Nominatim geocoder, which uses OpenStreetMap data and doesn’t require you to sign up for an API key or provide a credit card number.

First, you’ll need to install GeoPy on your system. Do this by entering the following into a code cell and running it:

! pip install geopy

I wrote a function that takes a place name or address and uses Nominatim to convert it into latitude and longitude. Enter the following into a code cell:

from geopy.geocoders import Nominatim

def location_name_to_latlong(location_name):
    geolocator = Nominatim(user_agent="Tampa Bay AI Meetup demo app")
    location = geolocator.geocode(location_name)
    return (location.latitude, location.longitude)

Test it out by entering the following into a code cell and running it:

location_name_to_latlong("1150 Assembly Drive, Tampa FL USA")

That’s the address of the Kforce office, where the meetup took place. You should get the following result:

(27.9532559, -82.5041163)

This is good — we’ll need this function for the next part.

Get the current weather

There are a number of weather APIs out there. Let’s use the one from Open-Meteo, which is free for non-commercial use and if you make fewer than 10,000 calls to it per day. It’s perfect for experimental applications or app with relatively few users. It doesn’t require you to sign up for an API key, and you don’t have to provide a credit card number. You can just use it.

You can find out more about the API in Open-Meteo’s documentation.

I wrote some code that gets the current weather for a place that you specify by name or address. Enter the following into a code cell and run it:

import requests
import json

WMO_CODE_TABLE = {
    0:  "clear sky",
    1:  "mainly clear", 
    2:  "partly cloudy",
    3:  "overcast",
    45: "fog",
    48: "depositing rime fog",
    51: "light drizzle",
    53: "moderate drizzle",
    55: "dense drizzle",
    56: "light freezing drizzle",
    57: "dense freezing drizzle",
    61: "slight rain",
    63: "moderate rain",
    65: "heavy rain",
    66: "light freezing rain",
    67: "heavy freezing rain",
    71: "slight snow",
    73: "moderate snow",
    75: "heavy snow",
    77: "snow grains",
    80: "light rain showers",
    81: "moderate rain showers",
    82: "violent rain showers",
    85: "slight snow showers",
    86: "heavy snow showers",
    95: "thunderstorm",
    96: "thunderstorm with slight hail",
    99: "thunderstorm with heavy hail",
}

def get_current_weather(location_name):
    latitude, longitude = location_name_to_latlong(location_name)
    url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}&current=temperature_2m,relativehumidity_2m,weathercode,cloudcover"
    response = requests.get(url)
    json = response.json()
    result = {
        "weather":     WMO_CODE_TABLE.get(json["current"]["weathercode"], "unknown"),
        "cloud_cover": f"{json['current']['cloudcover']}%",
        "temperature": f"{json['current']['temperature_2m']} degrees C",
        "humidity":    f"{json['current']['relativehumidity_2m']}%",
    }
    return result

The import statements make the functions built into the following modules available to our code:

  • requests: This module contains functions for sending HTTP requests, which are used for communicating with APIs.
  • json: This module contains functions for encoding and decoding JSON data.

The next part of the code defines a dictionary called WMO_CODE_TABLE,  which is used to convert Open-Meteo’s weather forecast numbers into meaningful phrases, such as converting “2” into something more comprehensible: “partly cloudy.”

The final part of the code is the function itself — get_current_weather() — which takes a place name or address and returns a dictionary containing key elements of the forecast:

  • The weather
  • Cloud cover, expressed as a percentage
  • Temperature, in degrees C
  • Humidity, expressed as a percentage

Open-Meteo’s API expects latitude and longitude, not a place name. That’s where the location_name_to_latlong() function we wrote earlier comes in.

Enter the following into a code cell:

get_current_weather("Tampa")

Here’s the result I got:

{'weather': 'partly cloudy',
 'cloud_cover': '50%',
 'temperature': '21.1 degrees C',
 'humidity': '72%'}

Putting it all together

First, let’s create a function that takes the weather report from get_current_weather() and turns it into a prompt describing the weather and asking for a poem based on it. Enter the following into a code cell and run it:

def create_weather_poem_prompt(location_name):
    weather = get_current_weather(location_name)
    prompt = (
        f"The weather in {location_name} is {weather['weather']}, " +
        f"with a temperature of {weather['temperature']}, " +
        f"{weather['cloud_cover']} cloud cover, and " +
        f"{weather['humidity']} humidity. " +
        "Create a poem about this weather."
    )
    return prompt

Test it out — enter the following into a code cell and run it:

create_weather_poem_prompt("Tampa")

Here’s the result I got:

'The weather in Tampa is clear sky, with a temperature of 20.7 degrees C, 14% cloud cover, and 71% humidity. Create a poem about this weather.'

Let’s feed that into create_completion(). Enter the following into a code cell and run it:

create_completion(create_weather_poem_prompt("Tampa"))

Here’s the result I got:

"In Tampa town, where sunbeams dance,\nA clear sky spreads its vast expanse.\nWith gentle breeze and warmth so fine,\nThe weather sings a tune divine.\n\nAt twenty degrees, the air is fair,\nInviting all to venture there.\nThe sun's embrace, a gentle touch,\nCaresses skin, it means so much.\n\nAbove, the clouds are few and light,\nLike cotton candy, pure and bright.\nThey dot the sky, a scattered crowd,\nYet let the sunshine shine so proud.\n\nHumidity, a gentle mist,\nAdds a touch of tropical twist.\nA hint of moisture in the air,\nA kiss of dew upon your hair.\n\nSo come, embrace this lovely day,\nIn Tampa's warmth, let worries sway.\nThe sky is clear, the sun is high,\nWith open arms, Tampa draws nigh."

If you paste this output into a print() function, you get this:

In Tampa town, where sunbeams dance,
A clear sky spreads its vast expanse.
With gentle breeze and warmth so fine,
The weather sings a tune divine.

At twenty degrees, the air is fair,
Inviting all to venture there.
The sun's embrace, a gentle touch,
Caresses skin, it means so much.

Above, the clouds are few and light,
Like cotton candy, pure and bright.
They dot the sky, a scattered crowd,
Yet let the sunshine shine so proud.

Humidity, a gentle mist,
Adds a touch of tropical twist.
A hint of moisture in the air,
A kiss of dew upon your hair.

So come, embrace this lovely day,
In Tampa's warmth, let worries sway.
The sky is clear, the sun is high,
With open arms, Tampa draws nigh.

And there you have it — a little prototype of an app that takes the current weather for a given location and uses AI to turn it into a poem!

Categories
Artificial Intelligence Editorial

The ugly manifesto behind the “Techno-Optimist Manifesto”

Want to improve the title of Marc Andreessen’s screechy screed, The Techno-Optimist Manifesto? Easy. Just replace the misused word “optimist” with the more accurate “fascist.”

It reads like a supervillain monologue

From the opening sentence, “we are being lied to,” the essay takes bigger and bigger leaps into supervillain monologuing, with lines like “we are not victims, we are conquerors” [and yes, the italicization is Andreessen’s].

But the cherry on this shit sundae — and my personal favorite — is the line “We are not primitives, cowering in fear of the lightning bolt. We are the apex predator; the lightning works for us.” That sounds exactly like Marvel Comics’ Doctor Doom!

The “enemies list” that appears two-thirds of the way into the polemic seemed hilarious at first, but then you realize “Oh shit, he’s serious.” Naming “trust and safety,” “tech ethics,” and “risk management” as things to be opposed is the kind of thing an old Saturday morning cartoon villain would do. I’m reminded of the bad guys on Captain Planet, who declared war on clean water and air.

But as bad as the similarities to cartoon villainy are, the Techno-Optimist Manifesto takes its inspiration from something far, far worse.

The Futurist Manifesto

The real red flag is this paragraph, which you can find smack-dab in the middle of the essay, which is intentionally written with the structure of a poem:

To paraphrase a manifesto of a different time and place: “Beauty exists only in struggle. There is no masterpiece that has not an aggressive character. Technology must be a violent assault on the forces of the unknown, to force them to bow before man.”

He could’ve made it much shorter by writing: Kneel before Zod!

As a fan of the ’80s avant-pop synth band Art of Noise and a fan of industrial design, I knew what he was paraphrasing: The Futurist Manifesto, written by Italian poet and fascist Filippo Tommaso Marinetti.

Here’s the paragraph that Andreessen paraphrased:

There is no longer any beauty except the struggle. Any work of art that lacks a sense of aggression can never be a masterpiece. Poetry must be thought of as a violent assault upon the forces of the unknown with the intention of making them prostrate themselves at the feet of mankind.

There’s a helluva lot of batshittery in Futurist Manifesto, and Marc Andreessen retrofitted it into the Techno-Optimist one.

Marinetti and Futurism

Marinetti in his Fiat Cabriolet.

The Italian verision of Futurism started with a car accident.

Like the author of the Techno-Optimist Manifesto, the author of the Futurist Manifesto was in the top 1%. Marinetti had a very nice car — a Fiat Cabriolet — which was no small achievement, considering that it was 1908. (For reference, the first Fiat was produced in 1899, not even a decade before.)

In 1908, while driving home after a friend’s party outside of Milan, Marinetti was speeding and had to swerve to avoid hitting two cyclists. The car went into a ditch and was totaled.

In writing about the incident, he clearly paints himself as a lead-footed driver, describing himself as driving so fast that his car was: “hurling watchdogs against doorsteps, curling them under our burning tires like collars under a flatiron.”

(Remember, he was a rich, eccentric poet.)

Here’s how he described the crash:

The words were scarcely out of my mouth when I spun my car around with the frenzy of a dog trying to bite its tail, and there, suddenly, were two cyclists coming toward me, shaking their fists, wobbling like two equally convincing but nevertheless contradictory arguments. Their stupid dilemma was blocking my way—Damn! Ouch! … I stopped short and to my disgust rolled over into a ditch with my wheels in the air …

The lesson most well-adjusted people would’ve taken from the crash would be “don’t drive faster than you can maneuver,” but that requires one to be well-adjusted. Marinetti decided that it was a symbol of the new world (the car) destroying the old one (bicycles). It captured all the things that excited him: speed, technology, risk, and violence. He thought that they perfectly illustrated the rapidly changing world around him and were signs of a new everything — a new, more mechanical world, in a modern era where everything is fast and furious.

That led him to write the Manifesto in 1908. First published in 1909, it was meant to kick-start an art movement to transform the world — starting with Italy.

The main part of the Futurist Manifesto was written as a set of 11 statements, each one a short or one-sentence paragraph. Andreessen borrowed the style when writing the Techno-Optimist Manifesto:

  • We want to sing the love of danger, the habit of energy and rashness.
  • The essential elements of our poetry will be courage, audacity and
    revolt.
  • Literature has up to now magnified pensive immobility, ecstasy and
    slumber. We want to exalt movements of aggression, feverish sleeplessness, the double march, the perilous leap, the slap and the blow with the fist.
  • We declare that the splendor of the world has been enriched by a new beauty: the beauty of speed. A racing automobile with its bonnet adorned with great tubes like serpents with explosive breath … a roaring motor car which seems to run on machine-gun fire, is more beautiful than the Victory of Samothrace.
  • We want to sing the man at the wheel, the ideal axis of which crosses the earth, itself hurled along its orbit.
  • The poet must spend himself with warmth, glamour and prodigality to increase the enthusiastic fervor of the primordial elements.
  • Beauty exists only in struggle. There is no masterpiece that has not an aggressive character. Poetry must be a violent assault on the forces of the unknown, to force them to bow before man.
  • We are on the extreme promontory of the centuries! What is the use of looking behind at the moment when we must open the mysterious shutters of the impossible? Time and Space died yesterday. We are already living in the absolute, since we have already created eternal, omnipresent speed.
  • We wish to glorify war — the world’s only hygiene — militarism, patriotism, the destructive act of the libertarian, beautiful ideas worth dying for, and scorn for women.
  • We want to demolish museums and libraries, fight morality, feminism and all opportunist and utilitarian cowardice.
  • We will sing of the great crowds agitated by work, pleasure and revolt; the multi-colored and polyphonic surf of revolutions in modern capitals: the nocturnal vibration of the arsenals and the workshops beneath their violent electric moons: the gluttonous railway stations devouring smoking serpents; factories suspended from the clouds by the thread of their smoke; bridges with the leap of gymnasts flung across the diabolic cutlery of sunny rivers: adventurous steamers sniffing the horizon; great-breasted locomotives, puffing on the rails like enormous steel horses with long tubes for bridle, and the gliding flight of aeroplanes whose propeller sounds like the flapping of a flag and the applause of enthusiastic crowds.

“Come see the violence (and misogyny) inherent in the system!”

If you’re a reader of this blog, the word “Futurism” doesn’t sound so evil, and neither do three of its four aspects — I’m sure that like me, you like the concepts of speed, technology, and even at least a little risk.

And besides, how serious could they be about that fourth part, violence?

It turned out, very serious, at least in theory. Marinetti referred to war as “the world’s only hygiene.”

Here’s the full paragraph from the Manifesto where that bit about war appears:

We wish to glorify war — the world’s only hygiene — militarism, patriotism, the destructive act of the libertarian, beautiful ideas worth dying for, and scorn for women.

I added the bold text for emphasis.

Once again, someone in the movies said it better — namely Arnold Schwarzenegger’s version of Conan the Barbarian:

In spite of their hatred for the calcified past, there was one long-standing tradition that Futurists were okay with: chicks ruin everything.

Futurism and fascism

Creative Commons image by “Douuwwurunwuuzhe”. Tap to view the source.

If you ever find yourself examining an idea, approach, philosophy, or movement and asking “Is this fascist?”, you’ll find Umberto Eco’s Practical List for Identifying Fascists to be a handy checklist.

Futurism checks a lot (but not all) of Eco’s boxes:

  • The cult of action for action’s sake
  • Disagreement is treason
  • Appeal to social frustration
  • The enemy is both weak and strong
  • Pacifism is trafficking with the enemy
  • Contempt for the weak
  • Everybody is educated to be the hero
  • Selective populism

Futurism’s big difference from fascism is how each views the past. Futurists see the past as a useless relic holding them back, while fascists revere it as a golden, halcyon era that they must bring back.

Their similarities eventually overrode their differences. In 1918, Marinetti would form the Futurist Political Party, an extension of his artistic and social movement. A year later, they’d join another party, Fasci Italiani di Combattimento, whose name translates as “The Italian Fighting League.” That group would rename itself as the National Fascist Party in 1921. You might be familiar with their founder’s name: Benito Mussolini.

It’s more honest to call it techno-fascism

Let me show you what a real techno-optimist looks like:

I live, work, and play with technology — and with boundless joy and hope for the future — to the point that I’m associated with a technology that has nothing at all to do with what I get paid to do:

Seriously — if you’ve ever seen me give a presentation, you know what I mean when I say “techno-optimist.”

The Techno-Optimist Manifesto is heavy on the techno, and incredibly light on optimism. Yes, there’s a belief that the future could be better, but in that belief is the constant “j’accuse!” that if you’re not onside, you are the enemy — or at least a murderer.

That’s not optimism, but it is futurism. And you know where futurism leads.

Wired had an article in April 2019 titled When Futurism Led to Fascism—and Why It Could Happen Again, where they looked at futurism and asked:

Does any of this sound familiar? Disruption? Moving fast (and perhaps breaking things)? The rejection of history? Today’s most vocal voices in tech might not communicate their values with the same aplomb as the Italian poets, but they’re often saying the same kinds of things.

The article goes on to provide some examples of futurism’s ideas, expressed by today’s techbros, including Waymo’s cofounder Anthony Levandowski talking about how little he values history (“In technology, all that matters is tomorrow”) and “Google Memo” author James Damore’s claim that the gender gap in tech exists because men and women “biologically differ”.

Beware of venture capitalists writing manifestos

Manifestos written by people in positions of privilege tend to be cringeworthy, whether it’s James Damore’s “Google Memo”, Sheryl Sandberg’s Lean In, or Andreessen’s latest word salad.

In the end, Andreessen’s essay is just a long-form version of his tweet from December 3, 2022, which is just him saying “Let me do what I want, and stop getting in my way.”

I’m all for techno-optimism, but not the kind Andreessen’s selling.

Categories
Artificial Intelligence Meetups What I’m Up To

Scenes from an AI meetup in San Francisco

With a little time to kill in San Francisco last Monday evening before I had to help run demos at Okta’s annual conference, Oktane, I decided to look around for something to do. A quick web search for events later, I found myself en route to Cow Hollow to a meetup with the title Sharing our tricks and magic for pushing generative AI applications into production.

In this article, you’ll find my photos and notes from that event.

Neon and the Secret Garden

​Back around the time of the dot-com bubble, I was working in a Toronto consultancy made up of me and my friend Adam. We often worked at home, but when we were feeling stir-crazy, we took our laptops to a couple of local cafés and worked from there.

Since then, I’ve kept my eye out for my dream working café. There’s a pretty nice one in my neck of the woods — The Corner Club — and I take meetings and work from there every now and again.

But I have to admit it: Neon — the venue for the meetup — is my dream café / coworking space. It has more open places to hang out up front of the building, quieter working stalls in the back, and behind the building is the Secret Garden, an outdoor patio space. That’s where they served the food for the meetup: a combo of steak and veggie burritos, along with chips, guac and salsa.

The meetup was free, but also marked as “sold out” with a “join waitlist” button. That didn’t deter me because I knew the Great Unwritten Truth of Free Events:

Half the people who register for a free event never actually show up.

As I expected, no one was at the door to check attendees against a registration list. Besides, I had the accordion with me, and the “I’m with the entertainment” line often works.

The crowd at this meetup were pretty hardcore. I’d say about half of them either worked in an AI-related position at a more established company or at a scrappy AI startup, while the other half worked at a tech company and had an interest in AI. I suppose I fall into the latter category.

I struck up a conversation with someone who specialized in virtual memory who wanted to work on some memory virtualization techniques for use in large AI systems. We then walked out the back entrance to Neon’s “Secret Garden…”

…where they were serving food. I got into a conversation with someone who worked at Stability.ai, where we were joined by someone who wanted to make the leap from marketing to development.

When the Stability.ai developer was momentarily pulled away from the conversation, the marketer whispered “That name — Stability.ai — that’s familiar. What do they do?”

“Stable Diffusion,” I whispered back, and that was a name the marketer recognized. “Come to think of it, I don’t recognize any of this meetup’s speaker’s companies.”

Presentation 1: Build bulletproof generative AI applications with Weaviate and LLMs

This was the abstract for this presentation:

​Building AI applications for production is challenging, your users don’t like to wait, and delivering the right results in milliseconds instead of seconds will win their hearts. We’ll show you how to build caching, fact-checking, and RAG: Retrieval Augmented Generation pipelines with real-world examples, live demos, and ready-to-run GitHub projects using Weaviate, your favorite open-source vector database.

Philip Vollet, Head of Developer Growth at Weaviate, gave this presentation. Weaviate makes a vector database, where the data is stored as vectors — think of them as really long tuples — a format that’s particularly useful for AI purposes.

I’m going to spend some time this weekend going through my hastily-scribbled notes and comparing them to my full-resolution versions of my photos of the presentations to see what I can glean from them.

I’ve included my photos here so that you can get a feel for what was shown at the event, and hey — you might find them useful.

Presentation 2: Customizing LLM Applications with Haystack

Here’s the abstract for the presentation:

​Every LLM application comes with a unique set of requirements, use cases and restrictions. Let’s see how we can make use of open-source tools and frameworks to design around our custom needs.

The second presentation was by Tuana Celik, Developer Advocate at deepset, who make Haystack, a natural language processing (NLP) framework, and a cloud-based SaaS framework for machine learning and NLP.

Presentation 3: Context Matters: Boosting LLM Accuracy with Unstructured.io Metadata

This was the abstract for this presentation:

​Retrieval Augmented Generations (RAGs), limited by plain text representation and token size restrictions, often struggle to capture specific, factual information from reliable source documents. Discover how to use metadata and vector search to enhance the ability of LLMs to accurately retrieve specific knowledge and facts from a vast array of documents.

The final presenter was Ronny Hoesada, Developer Relations Engineer at Unstructured, who make a product that converts unstructured enterprise data into formats that can be fed into vector databases and large language models.

Aftermath and observations

Observation : RAG is a hot topic in this crowd. The big topic of the evening and a common thread through all three presentations was RAG — retrieval-augmented generation. This is a process that enhances the results produced by large language models by retrieving additional facts or information from an external knowledge source. If you’ve ever added to a discussion by looking something up on your phone, you’ve performed a simple version of RAG.

Observation : Many SF tech meetups start later than Tampa Bay ones. I arrived in San Francisco Monday morning, and spent most of the day in my hotel room working on this article for Okta’s main blog and this article for the Auth0 by Okta developer blog. That process took the better part of the day, and by the time I’d finished the final edits at 6:30 p.m., I thought it would be too late to go to a meetup — but I was wrong. When I perused Meetup.com, it turned out that lot of in-person meetups in the San Francisco Bay area start at 7:00 p.m., including this one. I’ve been to Tampa Bay meetups that wrap up at that time!

Observation : Some attendees came a long way to catch this meetup, and many of them didn’t have a car. If you check the discussion on the Meetup page for this event, you’ll see it’s all about getting rides to the venue:

Observation : People were seriously ready to work the room. More than half the attendees stuck around when the presentations ended. Some stayed for the beer, some stayed to mingle or hustle for their next job, and some stayed specifically to talk to the presenters.

I showed up wearing my travel clothes (see the photo above, taken at TPA earlier that morning), which were a sport jacket, dress shirt, jeans, and dress shoes, and as a result, a number of people at the event approached me and asked what company I was starting up. They saw chatty guy in a blazer and the neural networks in their heads pattern-matched it as founder.

Jared from Silicon Valley, patron saint of the Patagonia fleece vest.

I had conversations with founders or people who reported directly to a founder earlier that evening, so I did some introductions. They were easy to spot — it was a chilly night (10° C / 50° F) and a good breeze was coming in from the Bay, and they’d showed up in fleece vests, as is the custom there.

Observation : A lot of people here really know their stuff. The conversational topics were pretty hardcore, from discussions of cosine similarity and the finer points of tokenization (with a sidebar conversation about handling out-of-vocabulary cases) to how much of Hugging Face’s ever-growing set of models people have tried. “I’m a dabbler,” I admitted, “no more than a handful — a couple of the conversational ones, and a text-to-image and text-to-audio model.”

I also got deep into a chat about the Mojo programming language, during which I glibly introduced myself to someone as “Markov Cheney,” and to my complete lack of surprise, they got the joke.

I’m still mulling over my experience at this meetup and thinking about some meetup organization and presentation tricks to borrow.

Categories
Artificial Intelligence Meetups The Street Finds Its Own Uses For Things What I’m Up To

Notes from the “Becoming an Empowered AI Worker” session

Need to skill up? Computer Coach has bootcamps, courses, and training for IT and business pros. I’ve taught Python and JavaScript courses for them.

As promised, here are my notes from my recent presentation at the Computer Coach-hosted session, Becoming an Empowered AI Worker, which took place on Tuesday, October 10, 2023.

Want to learn how to make the most of your work and career? Follow Computer Coach’s events via the Career Success Academy meetup group.

Intro: The reason the recent AI wave feels so overwhelming

It’s only natural to feel overwhelmed with the pace of AI development and what feels like a daily deluge of new AI applications and improvements to existing ones. That’s because we’re not naturally wired for this rate of change. Case in point: Ancient Egypt.

Tap to view at full size.

From 3150 BCE to about 330 CE, Egypt was incredibly stable. That stability came from the fact that as a culture, they remained relatively unchanged for over 3000 years. In the absence of some kind of pressure or catalyst to change, we naturally tend towards inertia.

As you already know, the modern era is quite different from Old Egypt. Consider this (incredibly simplified) timeline showing the history of computing:

Tap to view at full size.
  • 1930s – 40s: Computing’s largely theoretical era. The formal mathematical definition of “computable” was developed during this time, as were these two key concepts:
    • The Turing Machine: Creating by Alan Turing, this is a hypothetical machine that can describe any working algorithm. Every program, from “Hello World” to ChatGPT, can be expressed as a form of Turing Machine.
    • The von Neumann Architecture: Conceived by John von Neumann, this is the general organizing principle for computers — even today’s machines.
  • 1950s – 60s: This period gave us the first digital computers as well as the first programming languages — COBOL, FORTRAN, ALGOL, BASIC, PL/1, as well as the three whose influence lives on in today’s programming languages: Lisp (functional programming), Algol (structured programming), and Simula (object-oriented programming).
  • 1970s – 80s: An interesting era where computers went in two different directions. We got Cray supercomputers (they were supercomputers at the time, but a 2011-era iPad can keep up with them) and personal computers.
  • 1990s – 2000s: The internet as we know it (it’s been around since 1969 in the form of ARPANET), smartphones starting with the BlackBerry and followed later by iPhone and Android, publicly-accissible GPS, wifi, and all the goodies that we can’t live without today.

Remember, computing — even as a theory — isn’t even 100 years old yet!

I have a pet theory that every 13 years, a computing innovation appears and changes everything. (I basically summarized this theory in the presentation, and you can read about this in more detail in an earlier article of mine, Computing innovations happen every 13 years, and we’re at the start of a new one.)

Remember that ChatGPT hasn’t even been out a year yet! It debuted on November 30, 2022, and since then, OpenAI have been working hard at improving and enhancing it, and their rivals have been racing to keep up with them.

As a final example of how quickly things were evolving in the AI world, I showed a couple of photos from the Bay Area AI meetup I attended in San Francisco on Monday, October 2:

Not only was it quite well-attended for a Monday meetup (at least 60 people), but the attendance came from all over the San Francisco Bay Area:

I’m going to post a fuller writeup of this meetup in a later article. Watch this space!

The meetup had three technical presentations, all of which centered around RAG — retrieval-augmented generation. This is a process that enhances the results produced by large language models by retrieving additional facts or information from an external knowledge source. If you’ve ever added to a discussion by looking something up on your phone, you’ve performed a simple version of RAG.

After this introductory bit (which gave an opportunity for latecomers to join the Zom chat), I got to the main topic — using AI in your day-to-day work.

How to be more effective at work with the help of an LLM

Summarizing

If your job is in a “knowledge work” field, chances are you’ll end up doing a lot of reading. This will be doubly true if you’re working in a field where a lot of reading material is the norm, or if you have a manager who likes to stick you with the tedious work they’d rather not do.

In cases like this, you’ll find LLMs’ ability to summarize text very handy. Consider a recent Wired article, New York’s Airbnb Ban Is Descending Into Pure Chaos. I copied the text of the article and pasted it into ChatGPT Plus (but using GPT 3.5) following this prompt:

Summarize this article:

[I pasted the article text here]

ChatGPT turned it from a 15-paragraph article into a 6-paragraph summary. That’s useful, but I went further with this prompt:

Could you summarize that article in a single sentence?

Here’s how ChatGPT responded:

New York City's crackdown on short-term rentals, particularly on Airbnb, has led to a surge in illegal listings on social media and lesser-known platforms, resulting in a rental black market, as the city's short-term rental landscape undergoes significant changes.

One of the attendees asked if I could get ChatGPT to provide the top three points of the article. I said this was a good idea, and that in the spirit of experimentation, we should try it. I used this prompt:

Give me the top 3 points from the article.

ChatGPT’s response:

1. New York City's ban on most short-term Airbnb rentals has led to a significant drop in listings on the platform, with many properties going unregistered, resulting in a rental black market.

2. The crackdown has reshaped the vacation rental market in the city, with people turning to alternative platforms like Craigslist, Facebook, and Houfy to evade regulations, potentially posing risks to both guests and hosts.

3. Airbnb is shifting its focus away from New York, once its largest market, and exploring other opportunities such as longer rentals, car rentals, and dining pop-ups, while the city grapples with the consequences of the short-term rental ban.

Someone asked if ChatGPT could translate those points into Spanish, so I entered this prompt:

Can you translate that into Spanish?

Here’s how ChatGPT responded:

1. La prohibición en la ciudad de Nueva York de la mayoría de las propiedades de alquiler a corto plazo en Airbnb ha resultado en una disminución significativa de las ofertas en la plataforma, con muchas propiedades sin registrarse, lo que ha dado lugar a un mercado negro de alquileres.

2. La represión ha transformado el mercado de alquileres vacacionales en la ciudad, con las personas recurriendo a plataformas alternativas como Craigslist, Facebook y Houfy para evadir regulaciones, lo que potencialmente plantea riesgos tanto para los huéspedes como para los anfitriones.

3. Airbnb está desviando su atención de Nueva York, una vez su mercado más grande, y explorando otras oportunidades como alquileres más largos, alquiler de automóviles y restaurantes emergentes, mientras la ciudad lidia con las consecuencias de la prohibición de alquileres a corto plazo.

Keep in mind that machine translation, even in this new age of AI, should be taken with a grain of salt. The Spanish speakers in the audience said “not bad.”

Seed words and phrases

I didn’t have time to cover the concept of seeding ChatGPT, so this is bonus material!

You can direct ChatGPT’s answers by providing key words, phrases, or concepts to focus on in your prompt. These words and phrases are called seed words and seed phrases and you can use them to get ChatGPT output that better fits your needs.

For example, here’s a prompt that gets ChatGPT to provide a short summary of the article around the word “rent:”

Summarize the article in a way that is related to the seed word "rent".

Here’s how it responded:

The article highlights the evolving landscape of short-term rentals in New York City, where strict regulations have led to a surge in unregistered rentals, creating a rental black market and reshaping the vacation rental market. Airbnb, once a dominant player, is now shifting its attention away from the city, affecting the rental dynamics.

Let’s try getting a summary from a different angle — the legal perspective — and with slightly different prompt phrasing:

Summarize the article in a way that is related to the law.

ChatGPT’s reply:

The article discusses the consequences of a new law in New York City that heavily regulates short-term rentals, leading to a significant reduction in Airbnb listings. Many unregistered rentals have emerged, creating a rental black market. The article also mentions efforts by smaller landlords to change the law to allow them to legally rent out their units and how Airbnb is shifting its focus in response to the new regulations.

Note the differences, subtle as they are, between the summaries.

By using seed words and phrases, you can get ChatGPT to focus on a specific topic or emphasize a specific point. If you’re writing a memo to convince a manager to take a certain action, or sales or marketing copy, you’ll find seed words and phrases very useful.

Text classification

This is one trick that comes in handy when dealing with lots of text documents: making it classify them into different categories. I provided a simple example where I took three Amazon reviews — one for a car jump starter, one for an aloha shirt (a.k.a. Hawaiian shirt), and one for a wireless router — and then had ChatGPT put them into one of three categories:

  1. Electronics
  2. Home and garden
  3. Clothing

Here’s what I provided to ChatGPT:

Perform text classification on the following reviews and classify them into different categories such as “electronics”, “home and garden”, and “clothing”: 

Reviews

Review 1:
5.0 out of 5 stars Awesome little jump started!
Reviewed in the United States on August 5, 2023
Color: 4000AVerified Purchase
I have an old Generac generator that we use when we have power failures or other things happen and try to remember to start it every month or two to keep the gas clean and make sure everything is going well. The last few times, it is really slow to start and pulling the thing to start is a nightmare since it is so big! Instead of replacing the battery pack, I decided to spring for this for just a little more. The generator has the connections to jump start right near the push button, so it is a breeze to hook up and it cranks way better than the battery pack that I bought a couple of years ago ever did!

I am looking forward to having this to be able to jump all of my devices that have starters as well as for backup power in case we need it. It seems to have great safety features, after cranking for a while (since I turned the choke the wrong way) it shut off the start ability for just a second. I let off the button on the generator and the pack reset itself and was ready to crank again in about a second and a half.

I love that it has a case that is big enough to keep all the parts in, I have a habit of collecting random cords in boxes, so my life is miserable when I need to find stuff sometimes.

I hope it holds up to use and storage, just remember to charge it as soon as you get it, it showed four out of four bars, but when I plugged it it, it charged for a couple of hours while blinking the last light.

I hesitated to buy this, thinking I wasn't sure of the technology or if it would have the power of a regular generator battery but it has won me over in a big way!

Edit: I was using it to charge something a few weeks ago and it completely locked up. I let it sit for a few hours and it still didn't work on either the USB ports or the battery terminals. The terminals would start but would click and act like there was a short circuit within a few seconds, only allowing use for a very short time. I contacted the seller, they got right back to me, but I had left for a trip. When I got back home, I tried it and it worked perfectly. Apparently, it needed a bit more time to reset! I appreciate the quick response from the seller and I have now used it to charge a camera, a phone (multiple times) and jumpstart a truck without any hiccups at all. I still think it is a great product - just the right size and weight to be in my truck all the time. I don't have any hesitation recommending this for anyone since I know the seller backs it up with fast support response and stands behind their products.

Review 2:
A Stylish and Comfortable Hawaiian Shirt for Any Occasion
Reviewed in the United States on September 4, 2023
Color: CoffeeSize: MediumVerified Purchase
I recently purchased the VATPAVE Men's Casual Hawaiian Shirt in Coffee, and this marks my second time buying this shirt. It's safe to say that this shirt has become a staple in my wardrobe, and here's why:

Fit and Sizing (4/5): I initially bought this shirt in a Large, but after some weight loss, I opted for a Medium this time. It's worth noting that this brand tends to run a bit large, which suits my style perfectly. I prefer wearing it untucked, and the size works well for that relaxed look. However, if you plan to wear it as a dress shirt or with a blazer, you might consider sizing down, though it's not a dramatic difference.

Versatile Style (5/5): I've found this shirt to be incredibly versatile. It's my go-to choice for all casual occasions, whether it's a weekend outing or a dress-down Friday at work. The Coffee color is a rare find in casual shirts, and the tropical floral pattern is simply captivating. It adds a touch of uniqueness to your outfit.

Review 3:
4.0 out of 5 stars Latest Firmware fixed my issues
Reviewed in the United States on June 22, 2023
Style: AX3000, WiFi 6 RouterVerified Purchase
I waited for the latest firmware update to write this review. After the June 2023 update, this router has been rock solid with 20+ clients and a TP-Link extender. Updates are automatic. Just make sure it is turned on in the settings. I explain my initial issues at the end of the review.

The first thing I like is that you can do everything you need with any web browser. You do not have to sign up for any TP-Link account unless you use the available app or want remote features like parental controls and additional security and analytic features which makes perfect sense.

You can easily set up a mesh network with extenders. Mesh is brain dead easy with a TP-Link extender. Just turn it on in the settings and you have a mesh network.

This router can make 3 separate networks with both 2.5GHz and 5GHz. The main wireless network, and an isolated guest network, and an IoT network to keep your light bulbs and guests from infecting your computers. It supports Alexa and Google assistant. Support for VPN clients and servers. Also support for Dynamic DNS. It has an SPI firewall, NAT forwarding, and access controls all without signing up for an account. Don’t worry if all that is confusing. If you don’t know what they are then you don’t need them, except for the firewall which is on by default. Another feature I like is the ability to name all the devices in the connected clients list. For example, you may see a device named “Ring-49825”. You can name it “Driveway-Camera” or rename other devices like your thermostat, mobile phones, or whatever is connected to your network with some strange identifier.

I gave only 4 stars because of the issues I had with the firmware released at the time of my purchase. After about 24 hours the CPU would be at 100% and the router would eventually lock up and lose the internet connection. It could not be logged into and would have to be powered down and restarted. I set the router to restart every morning at 2am until these issues were resolved with the latest firmware installed.

Here’s how ChatGPT responded:

Review 1: Electronics - This review discusses the performance and features of a jump starter for a generator, indicating its usage for powering devices and jump-starting vehicles.

Review 2: Clothing - This review talks about a Hawaiian shirt's fit, sizing, and style, highlighting its versatility and use in various casual occasions.

Review 3: Electronics - This review focuses on the performance of a Wi-Fi router, specifically mentioning firmware updates and various technical features, indicating a discussion related to electronics and technology.

Not only did ChatGPT put the reviews in the correct categories, but it also did not put anything in the “wrong” category that I deliberately included (home and garden).

Multiple-choice questions

There are times when you want an LLM to provide an answer from a limited set of answers. Here’s a multiple-choice prompt format that does this:

Complete the following sentence by selecting one of the following options: “Float like a butterfly, sting like a...” [dog] [bee] [gasoline pump]

Here was ChatGPT’s response:

Float like a butterfly, sting like a bee.

Adversarial prompting

The term “adversarial prompt” is typically used to refer to a prompt that tricks an LLM into doing something that it’s not supposed to do…

…but it has other uses.

One way to use adversarial prompting is to have an LLM rewrite text that you give it so that the resulting text is hard to classify in a certain way. For example, here’s a prompt that asks ChatGPT to tone down the positive review of an aloha shirt from an earlier example:

Rewrite the following text in order to make it hard to classify as positive:

A Stylish and Comfortable Hawaiian Shirt for Any Occasion
Reviewed in the United States on September 4, 2023
Color: CoffeeSize: MediumVerified Purchase
I recently purchased the VATPAVE Men's Casual Hawaiian Shirt in Coffee, and this marks my second time buying this shirt. It's safe to say that this shirt has become a staple in my wardrobe, and here's why:

Fit and Sizing (4/5): I initially bought this shirt in a Large, but after some weight loss, I opted for a Medium this time. It's worth noting that this brand tends to run a bit large, which suits my style perfectly. I prefer wearing it untucked, and the size works well for that relaxed look. However, if you plan to wear it as a dress shirt or with a blazer, you might consider sizing down, though it's not a dramatic difference.

Versatile Style (5/5): I've found this shirt to be incredibly versatile. It's my go-to choice for all casual occasions, whether it's a weekend outing or a dress-down Friday at work. The Coffee color is a rare find in casual shirts, and the tropical floral pattern is simply captivating. It adds a touch of uniqueness to your outfit.

Here’s the result:

A Hawaiian shirt for various situations. Reviewed in the United States on September 4, 2023. Color: CoffeeSize: MediumVerified Purchase. I recently acquired the VATPAVE Men's Casual Hawaiian Shirt in Coffee for the second time. It's fair to say that this shirt has found a place in my wardrobe, and here's why:

Fit and Sizing (4/5): Initially, I purchased this shirt in a Large, but due to some weight loss, I went for a Medium this time. It's important to mention that this brand tends to run slightly larger, which somewhat suits my style. I prefer wearing it untucked, and the size does the job for that casual appearance. Nevertheless, if you intend to wear it as formal attire or with a blazer, you might contemplate downsizing, although the difference isn't particularly noticeable.

Versatile Style (5/5): I've discovered this shirt to be quite adaptable. It serves as my default choice for various casual events, whether it's a weekend excursion or a casual Friday at work. The Coffee color is an uncommon discovery in the realm of casual shirts, and the tropical floral pattern is somewhat interesting. It imparts a hint of individuality to your ensemble.

The resulting text still conveys the general objective information about the shirt, but the tone is less positive.

Translating audio and video content into other languages

If your line of work has you creating audio and video content and you’d like to make it available in different languages, you’ll find HeyGen handy. My favorite feature is its ability to do translations of audio and video into other languages.

First, I recorded this quick little video where I promoted a hypothetical Python course…

…and then I ran it through HeyGen to translate it into Spanish. The result was pretty good, complete with a fair clone of my “radio voice,” and it even changed my lip movements to match the Spanish words:

Résumé assistance

I was only able to quickly point people to Rezi, the AI-assisted résumé writing tool, but it’s worth checking out.

Thanks to everyone who attended, and to Computer Coach for inviting me to do this presentation!