Your first AI response

Let's build a restaurant chatbot for "Green Bites", a plant-based restaurant. We'll start simple: ask the AI to generate text, then make it feel real-time with streaming.

Your first LLM call

The flow of a basic LLM API call

DEFAULT_MODEL is loaded from your .env file. If you set GOOGLE_API_KEY, it defaults to gemini/gemini-2.0-flash-exp. The workshop notebooks handle this automatically, so you just need your .env configured from the setup step.

01-text-generation.ipynb
python
from litellm import completion
from typing import Optional

def generate_text(
    prompt: str,
    system_message: Optional[str] = None,
    temperature: float = 0.7,
    max_tokens: int = 300
) -> str:
    """Generate text from a prompt."""
    messages = []

    if system_message:
        messages.append({"role": "system", "content": system_message})

    messages.append({"role": "user", "content": prompt})

    response = completion(
        model=DEFAULT_MODEL,
        messages=messages,
        temperature=temperature,
        max_tokens=max_tokens
    )

    return response.choices[0].message.content

Our generate_text() helper wraps the LiteLLM completion() call. Notice the messages list, which is how you communicate with any LLM.

With the helper function ready, let us make our very first AI call. We will ask the model to generate some creative restaurant names.

01-text-generation.ipynb
python
prompt = "Create 3 creative names for a vegan restaurant"

response = generate_text(prompt)
print(response)

# Output:
# 1. Bloom & Bean - Evokes freshness and plant-based staples
# 2. The Rooted Table - Connection to earth and community
# 3. Edible Alchemy - Transformative power of plant cuisine

Your first AI call! The model receives a prompt and returns generated text. Run this multiple times and you may get different results each time.

The API returns a response object with a list called choices (in case you asked for multiple completions). We grab the first one with [0]. Inside that choice is a message object with a content field containing the actual text. It looks verbose, but it is the same pattern for every LLM provider.

AI prompt: Try it with AI

Loading practice…

Quiz: Quiz

Loading practice…

Fill in the blanks: Complete the messages list

Loading practice…

When you use ChatGPT, text appears word-by-word. That's streaming. It doesn't make the AI faster (the total time is the same), but it makes the user experience feel instant because users see progress immediately instead of staring at a loading spinner.

01-text-generation.ipynb
python
def generate_stream(
    prompt: str,
    system_message: Optional[str] = None,
    temperature: float = 0.7,
    max_tokens: int = 300
):
    """Generate text in chunks (streaming)."""
    messages = []

    if system_message:
        messages.append({"role": "system", "content": system_message})

    messages.append({"role": "user", "content": prompt})

    response = completion(
        model=DEFAULT_MODEL,
        messages=messages,
        temperature=temperature,
        max_tokens=max_tokens,
        stream=True  # This enables streaming!
    )

    for chunk in response:
        if chunk.choices[0].delta.content:
            yield chunk.choices[0].delta.content

# Usage: text appears word by word
for chunk in generate_stream("Write a haiku about AI"):
    print(chunk, end="", flush=True)

Adding stream=True returns chunks as they're generated. The yield keyword makes this a generator where each chunk is a small piece of the response.

Quiz: Quiz

Loading practice…

You have made your first AI API call and added real-time streaming. Next, we will give the AI a personality using system instructions and learn to control creativity with temperature.