An AI-powered restaurant discovery and booking assistant built for the FDSE AI Agent Challenge.
It simulates a real-world hospitality concierge using LLM reasoning, structured tool calling, and business-driven behavioral nudges.
The assistant helps customers:
- Discover restaurants based on vibe, cuisine, and location
- Book and modify reservations
- Manage large-group deposit workflows
- Receive post-booking upsells based on inventory
- Get discounts during cancellations
- Interact seamlessly in English or Hinglish
Click here to view the full demonstration video on Google Drive
GoodFoods AI Concierge is designed to maximize restaurant revenue and reduce operational inefficiencies.
It uses behavioral economics to nudge users toward choices that reduce wastage, increase basket size, and improve occupancy โ all while keeping conversations natural and context-aware.
The system includes:
- A Persona-Engineered LLM acting as a sales-optimized concierge
- A Tool Calling Layer for real backend operations
- A Smart Search Engine scoring restaurants by vibe, proximity, cuisine, and promotions
- A Deposit Gatekeeper for high-risk reservations
- An Inventory-Drain Engine for scarcity-based upsell recommendations
- A Yield-Management Flow that offers discount codes on cancellations to shift users to low-occupancy days
- Clone the repository
git clone <your-repo-url>
cd goodfoods-ai-concierge- Create a virtual environment
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt- Install Dependencies, create env file and run the app.
pip install -r requirements.txt
OPENAI_API_KEY=your_openai_api_key_here
streamlit run main.pyThe assistant uses OpenAIโs function-calling system to trigger backend logic deterministically.
A tightly controlled system prompt ensures deterministic behavior:
- Enforces upsells
- Controls deposit workflow
- Handles confirmation gating
- Adds localization rules
Implements:
- Scarcity cues
- Loss aversion nudges
- Default choice anchoring
- โToday onlyโ temporal framing
Uses st.session_state to persist:
- Tool call history
- Pending deposits
- Search context
- Booking arguments
When no nearby restaurants match, the system gracefully expands search radius and warns users.
The prompt is optimized so the bot understands and responds to Hinglish inputs:
โBro kaam ka vibe chaiye near Indiranagarโ
โ Works seamlessly.
-
Model Used
gpt-4o-mini(OpenAI Chat Completions API) -
Streamlit (UI framework)
https://streamlit.io/ -
OpenAI Function Calling (Tool call orchestration)
https://platform.openai.com/docs/guides/function-calling -
dotenv for environment variable management
https://pypi.org/project/python-dotenv/ -
Python Type Hints for clarity
-
JSON-based mock data layer (restaurants DB)
.
โโโ main.py # Streamlit UI + agent loop
โโโ agent_service.py # Tool routing + payment confirmation logic
โโโ database.py # Restaurant DB + search + booking logic
โโโ data/
โ โโโ restaurants.json # Mock data storage
โโโ requirements.txt
โโโ .env
โโโ README.mdThe system prompt is the core of the agentโs behavior. It is engineered to enforce strict business logic:
- Role: AI Sales Concierge for GoodFoods (Bangalore).
- Goal: Maximize revenue and reduce food wastage while providing excellent service.
- The Upsell Mandate: Must always mention a promotion when suggesting a restaurant.
- Inventory Drain: Must trigger an upsell using the
inventory_nudgepayload after every confirmed booking. - Validation: Must validate required parameters (name, time, guests) before calling
book_table. - Safety Protocol: Follows a two-step confirmation for destructive actions (e.g., asking "Are you sure?" before
cancel_reservation).
- No accidental cancellations.
- No hallucinated bookings.
- Requires mandatory name capture before tool execution.
- Currency: Uses โน (INR).
- Time Format: Uses 12-hour timestamps (e.g., "7 PM").
- Geography: Uses Bangalore-specific locality names (Indiranagar, Whitefield, Koramangala).
- Language: Native support for Hinglish (Hindi + English).
- Psychographic Search: Suggests restaurants based on vibe (work, romantic, party), cuisine, capacity, and proximity.
- Structured Tool Calling: The LLM decides which tool to invoke (
search_restaurants,book_table, etc.) without regex-based routing. - Hinglish Support: Handles inputs like "Bro kaam ka vibe chahiye Whitefield side" or "Thoda romantic but not too loud".
-
Deposit Workflow:
- For groups > 6 guests, the system triggers a
deposit_requiredstate. - It shares a mock payment link and waits for textual confirmation (including Hinglish keywords).
- It allows the user to "juggle" context (switch topics) while the deposit is pending.
- For groups > 6 guests, the system triggers a
-
The Inventory-Drain Engineโข:
- On confirmed bookings, the backend returns a specific
inventory_nudge. - The prompt forces the AI to pitch this surplus dish immediately to reduce waste.
- On confirmed bookings, the backend returns a specific
-
Cancellation Yield Management:
- If a user cancels, they receive a discount code (e.g.,
COMEBACK20). - Strategy: The code is valid only on MonโThu to shift demand to low-occupancy days.
- If a user cancels, they receive a discount code (e.g.,
This project demonstrates several advanced patterns for building LLM agents without heavy frameworks.
- No LangChain/CrewAI used; logic is explicit.
- Tool definitions are strictly typed.
- Routing handled via
agent_service.py.
database.py implements a weighted scoring function:
- Vibe Alignment: Tag overlap.
- Cuisine Match: +5 points.
- Location Boost: Strict filtering first, fallback search second.
- Availability Friction: Higher score for venues with 5+ tables available.
- Internal fields (like inventory counts) are stripped from search results before being sent to the LLM to save tokens and prevent hallucinations, only revealing them when necessary.
User: "Quiet romantic vibe at 9 PM"
AI: Suggests GoodFoods Signature with a wine promotion.
User: "Book for Animesh"
AI: Confirms booking. Triggers Inventory Engine: "By the way, only 3 portions of Hand-Pulled Burrata left. Reserve one?"
User: "Reserve it"
AI: Confirms the pre-reserved dish.
User: "Lunch for 9 people at 3 PM near Whitefield. Name Animesh."
AI: Recommends GoodFoods Garden. Detects group > 6, pauses booking. "We require a โน1000 pre-payment."
User: "I have made the payment." (or "Paisa bhej diya")
AI: Detects payment keywords, replays
book_tablewithpayment_confirmed=True, and finalizes the booking.
User: "Cancel my reservation."
AI: "Are you sure?"
User: "Yes confirm."
AI: Cancels booking. "Here is code COMEBACK20 for 20% off your next visit (Valid MonโThu)."
| Metric | Strategy Implemented |
|---|---|
| Basket Size โฌ๏ธ | AI upsells using scarcity-based inventory nudges. |
| Wastage โฌ๏ธ | Highlights surplus dishes likely nearing expiry. |
| No-Shows โฌ๏ธ | Deposit requirements for large groups secure high-value slots. |
| Occupancy โฌ๏ธ | Recommends quieter branches/times to balance load. |
| Revenue (Slow Days) โฌ๏ธ | Cancellation codes push demand to Mon-Thu. |
Current Limitations:
- Not production-grade (no real concurrency or auth).
- Deposit flow relies on textual confirmation (keywords), not real payment gateway callbacks.
- Restaurant availability is static JSON, not connected to a live POS.
๐ฎ Future Enhancements:
- Real payment verification via Stripe/Razorpay webhooks.
- Live POS integration for real-time inventory.
- Multilingual support (Kannada, Tamil, Hindi script).
- Manager Analytics Dashboard (Occupancy & Upsell rates).