AI Agent for Catering Coordination: Menu Selection, Headcount, and Event Planning
Learn how to build an AI catering agent that guides clients through menu selection, handles dietary requirements, calculates pricing based on headcount, and manages event logistics.
Why Catering Coordination Needs AI Agents
Catering inquiries are complex, multi-turn conversations that involve menu selection across courses, dietary accommodation for diverse groups, pricing calculations with volume discounts, and logistics coordination for venue, timing, and staffing. A single catering inquiry can take 30 to 60 minutes of a coordinator's time. An AI catering agent handles the entire discovery and quoting process, freeing human coordinators to focus on execution.
The agent must balance being consultative — recommending menus and packages — while collecting the structured information needed to generate an accurate proposal.
Modeling the Catering Domain
from dataclasses import dataclass, field
from datetime import date
from enum import Enum
class ServiceStyle(Enum):
BUFFET = "buffet"
PLATED = "plated"
FAMILY_STYLE = "family_style"
COCKTAIL = "cocktail_reception"
BOX_LUNCH = "box_lunch"
class DietaryTag(Enum):
VEGETARIAN = "vegetarian"
VEGAN = "vegan"
GLUTEN_FREE = "gluten_free"
NUT_FREE = "nut_free"
DAIRY_FREE = "dairy_free"
HALAL = "halal"
KOSHER = "kosher"
@dataclass
class CateringItem:
item_id: str
name: str
course: str # appetizer, main, side, dessert, beverage
price_per_person: float
dietary_tags: list[DietaryTag] = field(default_factory=list)
description: str = ""
min_order: int = 10
@dataclass
class CateringPackage:
package_id: str
name: str
description: str
price_per_person: float
includes: list[str] # list of item descriptions
service_style: ServiceStyle
min_guests: int = 20
@dataclass
class CateringQuote:
event_name: str
event_date: date
guest_count: int
service_style: ServiceStyle
selected_items: list[CateringItem] = field(default_factory=list)
selected_package: CateringPackage | None = None
dietary_requirements: dict[str, int] = field(default_factory=dict)
notes: str = ""
@property
def food_cost(self) -> float:
if self.selected_package:
return self.selected_package.price_per_person * self.guest_count
return sum(
item.price_per_person * self.guest_count
for item in self.selected_items
)
@property
def service_fee(self) -> float:
multiplier = {
ServiceStyle.BUFFET: 0.15,
ServiceStyle.PLATED: 0.22,
ServiceStyle.FAMILY_STYLE: 0.18,
ServiceStyle.COCKTAIL: 0.20,
ServiceStyle.BOX_LUNCH: 0.10,
}
return self.food_cost * multiplier.get(self.service_style, 0.18)
@property
def total(self) -> float:
return round(self.food_cost + self.service_fee, 2)
def volume_discount(self) -> float:
if self.guest_count >= 200:
return 0.15
elif self.guest_count >= 100:
return 0.10
elif self.guest_count >= 50:
return 0.05
return 0.0
@property
def final_total(self) -> float:
discount = self.volume_discount()
return round(self.total * (1 - discount), 2)
Building the Catering Agent Tools
from agents import Agent, function_tool
packages = [
CateringPackage("PKG1", "Corporate Lunch", "Professional lunch service",
28.00, ["Mixed greens salad", "Choice of 2 mains",
"Seasonal sides", "Dessert", "Coffee and tea"],
ServiceStyle.BUFFET, min_guests=20),
CateringPackage("PKG2", "Elegant Dinner", "Full-service plated dinner",
65.00, ["Amuse-bouche", "Soup or salad course",
"Choice of 3 mains", "Sides", "Dessert trio",
"Wine service"],
ServiceStyle.PLATED, min_guests=30),
CateringPackage("PKG3", "Cocktail Reception", "Passed hors d'oeuvres",
42.00, ["6 passed appetizers", "2 stationary displays",
"Bar service for 3 hours"],
ServiceStyle.COCKTAIL, min_guests=40),
]
current_quote = CateringQuote(
event_name="", event_date=date.today(), guest_count=0,
service_style=ServiceStyle.BUFFET
)
@function_tool
def browse_packages(service_style: str = "") -> str:
filtered = packages
if service_style:
filtered = [p for p in packages if service_style.lower() in p.service_style.value]
lines = []
for pkg in filtered:
includes = ", ".join(pkg.includes)
lines.append(
f"**{pkg.name}** (${pkg.price_per_person:.2f}/person, "
f"min {pkg.min_guests} guests)\n"
f" Style: {pkg.service_style.value} | Includes: {includes}"
)
return "\n\n".join(lines) if lines else "No packages match that criteria."
@function_tool
def set_event_details(
event_name: str, event_date: str, guest_count: int, service_style: str
) -> str:
current_quote.event_name = event_name
current_quote.event_date = date.fromisoformat(event_date)
current_quote.guest_count = guest_count
style_map = {s.value: s for s in ServiceStyle}
current_quote.service_style = style_map.get(service_style, ServiceStyle.BUFFET)
return (
f"Event details set: {event_name} on {event_date}, "
f"{guest_count} guests, {service_style} service."
)
@function_tool
def select_package(package_id: str) -> str:
pkg = next((p for p in packages if p.package_id == package_id), None)
if not pkg:
return f"Package {package_id} not found."
if current_quote.guest_count < pkg.min_guests:
return (
f"{pkg.name} requires at least {pkg.min_guests} guests. "
f"Current headcount: {current_quote.guest_count}."
)
current_quote.selected_package = pkg
return f"Selected {pkg.name} at ${pkg.price_per_person:.2f}/person."
@function_tool
def set_dietary_requirements(requirements: dict) -> str:
current_quote.dietary_requirements = requirements
summary = ", ".join(f"{k}: {v} guests" for k, v in requirements.items())
return f"Dietary requirements recorded: {summary}"
@function_tool
def generate_quote() -> str:
if not current_quote.event_name or current_quote.guest_count == 0:
return "Please set event details before generating a quote."
discount = current_quote.volume_discount()
discount_line = f" Volume discount ({int(discount*100)}%): -${(current_quote.total * discount):.2f}\n" if discount > 0 else ""
return (
f"=== CATERING QUOTE ===\n"
f"Event: {current_quote.event_name}\n"
f"Date: {current_quote.event_date.isoformat()}\n"
f"Guests: {current_quote.guest_count}\n"
f"Style: {current_quote.service_style.value}\n"
f"---\n"
f" Food: ${current_quote.food_cost:.2f}\n"
f" Service fee: ${current_quote.service_fee:.2f}\n"
f" Subtotal: ${current_quote.total:.2f}\n"
f"{discount_line}"
f" TOTAL: ${current_quote.final_total:.2f}"
)
catering_agent = Agent(
name="Catering Coordinator",
instructions="""You are a catering coordinator agent. Help clients plan their
events by understanding their needs, recommending appropriate packages or
custom menus, collecting dietary requirements, and generating detailed quotes.
Always ask about dietary needs and allergies. Mention volume discounts for
groups of 50 or more.""",
tools=[browse_packages, set_event_details, select_package,
set_dietary_requirements, generate_quote],
)
FAQ
How does the agent handle partial dietary information like "a few vegetarians"?
The agent proactively asks for specific counts rather than accepting vague numbers. It explains that accurate dietary counts ensure proper food quantities — too few vegetarian meals leaves guests without options, while too many creates waste. If the client does not have exact numbers yet, the agent records an estimate and flags the quote as preliminary.
See AI Voice Agents Handle Real Calls
Book a free demo or calculate how much you can save with AI voice automation.
Can the agent handle multi-day events or conferences?
Yes. The event model can be extended with a days field and per-day menu selections. The agent walks the client through each day's meals separately (breakfast, lunch, dinner, breaks), applies the pricing per day, and rolls up the total across the entire event. Volume discounts are calculated based on the highest single-day headcount.
How does pricing work for custom menus vs. packages?
Packages offer a fixed per-person rate that is typically 10 to 15 percent cheaper than ordering the same items individually. The agent explains this tradeoff: packages are simpler and more affordable, while custom menus allow precise control over every course. When clients want to modify a package (swap a dessert, add an appetizer), the agent calculates the difference as an add-on to the package price.
#CateringAI #EventPlanning #AgenticAI #Hospitality #Python #LearnAI #AIEngineering
CallSphere Team
Expert insights on AI voice agents and customer communication automation.
Try CallSphere AI Voice Agents
See how AI voice agents work for your industry. Live demo available -- no signup required.