Laia 讓開放權重 AI 致電餐廳訂薄餅,作者全程留在沙發上
"Hey Laia, order me a pizza": I stayed on the sofa while an open-weight AI phoned the restaurant
Antonia Herrera 開發 Android 應用程式 Laia,讓用戶以語音提出訂餐要求,再由開放權重 Gemma 理解訂單並致電商戶。Laia 會按預算及備選項規則處理商戶回覆,價格判斷由 Python 程式執行;需要用戶決定時,會透過 app 詢問。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady
The pizzeria 5 km from my flat makes the best four-cheese pizza in town. It has no app and no website: just a phone and home delivery.
Ordering from it used to mean looking up the number, waiting while it rang, spelling my street twice and finding out they were out of four-cheese. Now, when I get home late and tired, or I'm simply having a lazy day, I just open the app and, without pressing a single button, tell Laia to order dinner.
That's the laziest problem I have, and this week was the week to be lazy about it. So I built Laia.
The name is a little Spanish pun: Laia is a common girl's name in Spain, and if you split it, "La IA" means "the AI". So when she starts a call with "Hola, soy la IA" ("Hi, I'm the AI"), she's being honest and introducing herself at the same time.
TL;DR. You say "Hey Laia, order a pepperoni pizza from Pizzeria Picciolo, 20 euros max" and you don't touch your phone again. Laia understands the order with Gemma (open-weight), finds the place in your saved places or on Google Maps, and phones the restaurant with a real voice. She says she's an AI, orders, checks the price against your limit, gives your address only when they ask for it, and tells you when the food arrives. If something needs you ("they don't have it for 20 euros, but they have a garlic pizza for 15: OK?"), she asks you with two buttons. She can also call a hotel in Rome or a supplier in Germany in their own language and translate the call for you.
A real call, with English and Spanish subtitles: I say one sentence, Laia confirms out loud and calls. Then you hear the call from the pizzeria's phone.
What I Built
Laia is an Android app and a backend that turn one spoken sentence into a real phone call.
- You talk, you don't tap. With hands-free mode on, the app listens for "Oye Laia" in Spanish or "Hey Laia" in English. You say what you want, Laia reads it back ("Ready? Calling Pizzeria Picciolo to order one pepperoni pizza"), and after a five-second countdown she calls. Say "no" to stop her. You never pick the phone up from the cushion.
- Gemma turns the sentence into rules. "A four-cheese pizza from Picciolo. If they're out, a margherita. Max 20 euros" becomes an item, an alternative, a price limit and a business to call.
- She finds the place. Your saved places come first (no capitals or accents needed: "pizzeria picciolo" finds "Pizzería Picciolo"), then Google Maps. Laia only calls businesses that are listed on Google Maps or approved by an admin, never premium-rate numbers and never private people.
- She makes the call. A natural voice, short sentences, and the first thing she says is that she's an AI: "Hola, buenas. Soy la IA y quería encargar una pizza de pepperoni a domicilio."
- Your rules are code, not vibes. When the restaurant says a price, the model has to report it to a tool, and plain Python decides whether it's within your limit. If it isn't, Laia says it's over budget and asks for something cheaper, or asks you.
- She only bothers you when she has to. Questions pop up in the app with buttons. You can listen to the call live, tap "Let me talk" to have it transferred to your phone, or hang up.
- It works abroad. Pick a country and a place, write in your language, and Laia calls in theirs. Every line of the conversation shows the original and the translation. That covers the calls I dread even more than the pizzeria: a hotel in Italy, or a supplier abroad when a small shop needs to order stock and nobody there speaks German. I think it's also a way to bring businesses closer together: anyone can order materials from abroad, in a language they don't speak.
The app itself is in Spanish and English: the screens, the voice prompts and even the wake word.
A real call, from the logs
This is the call in the video. Pizzeria Picciolo is really a friend of mine, answering his own phone, who decided to test her by switching to English. The address and phone number are fake ones I use for tests.
Laia: Hola, buenas. Soy la IA y quería encargar una pizza de pepperoni a domicilio. (Hi! I'm the AI, and I'd like to order a pepperoni pizza for delivery.)
Pizzeria: Okay, sorry, can you switch to English, please?
Laia: Sure, no problem. I'd like to order one pepperoni pizza for delivery, please.
Pizzeria: Okay, perfect. So, uh, it will be 25 euros. Is that okay?
Laia callsreport_price(25). The code: 25 is over my 20-euro limit, don't accept.
Laia: I'm sorry, that's a bit too expensive for me. Do you have anything similar that's a bit cheaper?
Pizzeria: I can offer you a garlic pizza for 15 euros.
That's not what I asked for, so Laia callsask_userand puts them on hold. My phone buzzes: "The pepperoni is 25 €, over your budget. They offer a garlic one for 15 €. Shall I order it?" I tap **Yes.
Laia: That sounds great, I'll take the garlic pizza for 15 euros then.
Pizzeria: Okay, perfect. Do you have an address?
Laia: Yes, it's Avenida España, number 23.
Pizzeria: Okay, perfect. And a phone number, please?
Laia: It's uno dos tres, cuatro cinco seis, siete ocho nueve. (In Spanish. Oops.)
Pizzeria: Can you say the number in English, please?
Laia: One two three, four five six, seven eight nine.
Pizzeria: Oh, okay, perfect. We will be there in 20 minutes. Bye.
Laia: Thank you very much, bye!
order_confirmed(eta=20),end_call(). On my phone: "Done. Arrives in about 20 minutes."
The whole call took 81 seconds, including the switch to English and a change of pizza. I was on the sofa for all of them.
Why not just use a delivery app?
Because the places I want to order from aren't on one. My favourite pizzeria, the bakery that makes cakes to order, the hairdresser that only books by phone, the hotel that answers emails three days later, the supplier in Germany: they all have one thing in common, a phone number. Delivery apps cover the big chains. Laia covers everyone who still picks up the phone. And, like any good sloth, I don't have to search through an app and tap a hundred times: I just tell Laia what I want, and she orders it.
Demo
The video at the top of the post is the full demo (about 3 minutes). Turn on the subtitles (CC) for English or Spanish. What you'll see:
- 10 pm, a pizza craving, and why a delivery app isn't the answer.
- Logging in, with the app switched to English.
- Hands-free mode: "Hey Laia", the order out loud, Laia's spoken confirmation and the countdown.
- The real call: the pizzeria's phone with Laia's voice, next to her live transcript and the tools she calls.
- The result in the app: every line of the conversation and when the food arrives.
- The Abroad tab and the profile.
| The countdown | The conversation | Done |
|---|---|---|
![]() |
![]() |
![]() |
Code
antoniahp
/
Laia
Laia: say "order me a pizza" and an open-weight AI phones the place for you. She also calls suppliers abroad in their language to order stock, bringing foreign markets within reach. Gemma (Ollama) + Pipecat + ElevenLabs + Twilio. Flutter + Django. DEV Hacktoberfest AI Challenge, Week 3 🦥
Laia 🍕📞
Alexa para todo lo que no está en Amazon. Le dices a Laia qué quieres y ella llama al negocio por ti, en su idioma, sigue tus reglas ("si no hay cuatro quesos, pide margarita", "máximo 20 €") y solo te pregunta cuando hace falta por la app o por Telegram.
Proyecto para el reto Hacktoberfest 2026 de DEV, semana 3: Slow and Steady.
Qué hace
| Pestaña | Para qué |
|---|---|
| Pedir | «Pide una cuatro quesos en Tres Hermanas, si no hay margarita, máximo 20 €». Laia entiende la frase, busca el sitio en Google Maps y llama. |
| Extranjero | Eliges país y sitio, le dices en español qué quieres («reserva mesa para 2 el viernes»). Laia llama en su idioma y te traduce cada frase. |
| Llamadas | Todo lo que ha hecho Laia, con el resultado. |
| Perfil | Tus datos, Telegram, descargar tus datos, borrar la cuenta y los textos legales. |
…
-
backend/: Django 5 + Django Ninja, hexagonal architecture with CQRS, Poetry and 98 tests. -
app/: Flutter (Android), in Spanish and English. -
make runstarts the backend, andmake run flutterstarts the app.
How I Built It
Phone (Flutter) Backend (Django + Ninja) Outside world
"Hey Laia, order a pizza…" ──► Gemma parses the order ──────────────────► Ollama (Gemma, open-weight)
Saved places / Google Places ────────────► Google Maps
Spoken "Ready?" + countdown ──► Rules: verified business, daily limit,
one call at a time, 10 minutes max
Twilio places the call ──────────────────► The restaurant
└─ Pipecat voice agent (open source)
├─ Ears: ElevenLabs Scribe (or Whisper, open source)
├─ Turns: Silero VAD (open, runs locally)
├─ Brain: Gemma + tools
├─ Rules: price and alternatives in plain Python
└─ Voice: ElevenLabs, in the business's language
Listen live ◄────────────────── Audio fork: both sides mixed, never recorded
Questions and result ◄───────── App
The model talks, the code decides
Gemma is great at holding a conversation. I don't want it deciding whether 21.50 euros is "close enough" to my 20-euro limit. So during the call Gemma has tools (report_price, item_unavailable, ask_user, order_confirmed, end_call), and the code behind them makes the decision:
def accepts_price(self, price):
return self.max_price is None or price <= self.max_price
This is what the call above looks like in the server logs, trimmed:
If the price is in another currency, Laia doesn't convert it in her head: she puts the restaurant on hold with a polite sentence and asks me. If they're out of what I wanted, the code hands her the next alternative from my order, or asks me first if I said so. The money rules are unit-tested; the small talk doesn't need to be.
The same idea protects the people Laia calls. In code, she only calls verified businesses, never premium-rate numbers, one call at a time, with daily limits and invite codes. If an answering machine picks up, she hangs up instead of leaving a robotic voicemail.
From "sounds like a robot" to a real conversation
The first call that worked end to end was awful. My friend answered "Hola, ¿qué desea?" and Laia stayed silent for twenty seconds. When he told her the price, she didn't answer at all. And when she finally spoke, she sounded like a robot reading the terms and conditions.
Every fix below came from a real call, with the logs open next to it:
- She couldn't hear at all. Twilio sends phone audio at 8 kHz, and Whisper returned empty transcripts. Running the pipeline at 16 kHz fixed that.
- She waited too long. The end-of-turn detector waited for three seconds of silence, and an empty transcript added a five-second timeout on top. Now a turn ends about 0.6 seconds after the last word, and the speech-to-text service decides when a sentence is finished.
- The "click" when someone picks up interrupted her. The pickup noise was transcribed as speech, so Laia cut off her own greeting after 70 milliseconds and then waited for a sentence nobody was saying. Now she can't be interrupted while she introduces herself, and if nobody speaks within two seconds, she starts.
- A 21-character phrase made her deaf. I give the speech-to-text service the words the call will probably contain (the business name, the items, "euros"), so it hears "cuatro quesos" (four cheeses) instead of "cuatro besos" (four kisses). It rejects any term longer than 20 characters, and "1 pizza cuatro quesos" has 21. The connection failed quietly, and for a whole call Laia answered "one moment, I'll check" to things she had never heard. Long terms are now split into words.
- She overshared. Asked for the address, she also read out my name and phone number. Now she gives only the piece of information she's asked for, and dictates phone numbers slowly, in groups, the way people do.
- The pizzeria answered in English, and she didn't follow. My friend's favourite test. Laia now starts in the business's language and switches when they do.
- "Hey Laia" became "a liar". In English, Android's speech recognizer doesn't know the name Laia. It wrote "hey liar" (you can see it on the screen in the GIF above) and, my favourite, "love you". The wake-word matcher compares how words sound, knows the usual ways the name gets misheard, and only counts them at the start of a sentence, so "you are a liar" doesn't start a call.
- She switched to English, but not completely. Watching the recording of the call above, I found two leftovers: the "one moment, let me check" while she asked me was still in Spanish, and she dictated the phone number in Spanish until my friend asked for English. Both now follow the language the business is actually speaking.
The difference, measured in the logs from the moment the business finishes speaking until Laia starts answering:
| Before | After (the call above) | |
|---|---|---|
| Pickup to Laia's first word | about 20 s | about 2 s |
| "Can you switch to English?" to her answer | – | 0.6 s |
| "It will be 25 euros. Is that okay?" to her answer (with a tool call) | no answer | 1.2 s |
| "Do you have an address?" to the address | – | 0.6 s |
| "And a phone number, please?" to the number | – | 0.8 s |
The voice changed too: a native Spanish voice instead of an English one speaking Spanish, slightly less "stability" for a more human intonation, and a prompt that asks for the way people really talk on the phone: "buenas", "vale", "genial", one short sentence per turn, and never "I would like to inform you".
She always says she's an AI
Before writing the greeting, I read up on the rules. From August 2026, the EU AI Act requires a system that talks to people to tell them it's an AI, and, more importantly, the person at the pizzeria deserves to know who they're talking to. So the very first thing Laia says, in every call and in every language, is that she's an AI. The trick was making that sound natural instead of like a legal notice: "Hi, I'm the AI, and I'd like to order…". My friend didn't hang up on her.
Privacy by default
- Calls are never recorded. The live audio is mixed in memory, in 20 ms frames, and streamed to the app.
- Transcripts are deleted after 30 days; the result stays.
- You can download your data and delete your account from the app.
- From Google Maps, Laia only stores the place ID; the name and phone number are fetched at call time.
- Businesses have a public page that explains what Laia is.
Why Does Open Innovation Matter?
-
The brain has to be cheap enough to make lots of small calls. A pizza order is worth a few euros. Gemma is open-weight, so I run it on Ollama Cloud today and can move it to my own machine tomorrow by changing one variable,
OLLAMA_HOST. No per-call markup decides whether ordering a pizza is worth it. - I could open the framework and fix it. Every turn-taking bug above lived between the phone line, the voice activity detector and the model. Pipecat is open source, so when Laia cut herself off after 70 ms, I could read exactly which strategy started the "user turn", replace it, and add a rule that the greeting can't be interrupted. With a closed voice-agent platform, I would have filed a support ticket.
- I could see what the model actually did. Because I control every call to Gemma, I log the order it parsed and every tool it called, with timestamps. That's how I found that Laia was "answering" a business she couldn't hear, and how I measured the latencies in the table above. I wasn't guessing what a black box was doing.
-
The fast parts run on my machine. Silero VAD (voice activity detection) is an open model that runs locally on every 20 ms of audio, for free. Whisper, also open source, is one setting away (
STT_PROVIDER=whisper) for anyone who wants the whole ear on their own server. - Phone calls are personal. A call includes your address, your phone number and the voice of someone who never asked to be recorded. With open models, I decide where that conversation is processed.
- It brings small businesses closer. A shop that needs stock from a supplier abroad, or a family booking a hotel in a country whose language they don't speak, shouldn't need an expensive service to make a phone call. Open models and an MIT-licensed codebase mean anyone can run Laia, change her voice, or adapt her to their own language and town.
Where a closed service is better, honestly: the ears and the voice. On real 8 kHz phone audio with a Mallorcan accent, ElevenLabs Scribe understood far more than the Whisper model I could run on a laptop, and its voices sound human in a way the open text-to-speech models I tried don't yet. So Laia uses them, behind interfaces that make them replaceable. The brain, the rules and the framework are open.
The Lazy Payoff
- My effort: one sentence, a five-second countdown and one tap on Yes. About 15 seconds, without picking up the phone.
- Laia's effort: an 81-second call, a switch to English and a change of pizza included.
- What I didn't do: look up the number, wait while it rang, repeat my street, ask for something cheaper, or hold a conversation in English in my tired voice.
- The calls I would never make: booking a table in Italy, or asking a supplier in Germany for a price, without speaking Italian or German. Before Laia, I simply didn't. Now it's one sentence.
Prize Categories
- Overall winner: Laia is laziness taken literally. You don't type, you don't tap, you don't even pick up the phone: one sentence from the sofa becomes a real call to a real business, with an open-weight model at its core. It works today on real phone lines (the video shows a real call, in two languages), the rules that matter are code with tests, and it was built responsibly from the first word: she always says she's an AI, and nothing is recorded.
-
Best Use of Gemma: Gemma is Laia's brain twice. It turns a spoken sentence (in Spanish or English) into a structured order with rules, and it holds the live phone conversation with tools (
report_price,ask_user,order_confirmed…), while code enforces the price limit and the alternatives. The logs above show both. - Best Use of ElevenLabs: ElevenLabs is Laia's voice and her ears on a real phone line: streaming text-to-speech in the business's language, and Scribe realtime speech-to-text with call-specific key terms, tuned until she answers in under a second.
The code is open, the calls are real, and tonight I'm ordering dinner from the sofa. 🦥
— Antonia
I drafted this post with an AI assistant and edited it myself.
來源:DEV Community · dev.to








