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.
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.contentOur 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.
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 cuisineYour 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.
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.