Restaurant - takeaway agent

Written By William Bowen

Last updated 12 days ago

Intro

Our SMS-based AI agent acts as a digital concierge for takeaway orders, automatically extracting whether a customer wants delivery or pickup, confirming details like their address, and updating the order card while providing an estimated readiness time.

For example, if someone texts “I want delivery for a pepperoni pizza and soda,” the agent confirms their delivery address, records the order, and replies with “Your order will be ready in 30 minutes.”

Use cases

A list of use cases where this agent can be used (in some cases in combination with other AI agents).

  1. Order Intake and Routing: The agent automatically detects if a customer wants delivery or pickup and routes the order accordingly. For example, if a customer texts “I'd like a burger for pickup,” the system prompts for their name and confirms pickup details.

  2. Address Verification: It collects and verifies the customer’s address for accurate delivery routing. For example, when a customer requests delivery for a salad, the agent asks “Can you confirm your address?” and updates the contact card accordingly.

  3. Custom Wait Time Estimation: The agent adjusts estimated wait times based on order type or complexity. For example, a complex order like “Double-layered lasagna with extra cheese” might trigger an estimate of 45 minutes instead of the standard 30.

  4. Special Instructions Handling: It extracts and records any special requests or dietary preferences. For example, if a customer says “No onions in my tacos, please,” the agent notes this on the order card.

  5. Recommendation Integration: The agent can be paired with a recommendation system to suggest add-ons or popular items. For example, after ordering a pizza, the system might ask “Would you like to add garlic bread?”

  6. Order Status Notifications: It sends updates when the order status changes, like when the order is ready or on its way. For example, after processing an order, the agent texts “Your order is ready for pickup in 30 mins” at the appropriate time.

  7. Loyalty and Rewards Tracking: The system updates customer profiles with order history, aiding loyalty programs. For example, after a tenth order, the agent could inform the customer “You've earned a free dessert on your next visit!”

  8. Multi-Location Handling: It can differentiate orders based on location and update corresponding store details. For example, if a chain restaurant receives an order from downtown versus a suburb, the agent assigns the order to the correct branch.

  9. Order Confirmation and Error Handling: It verifies order details and prompts for corrections if needed. For example, if a customer accidentally types “pepperoni with extra olives” twice, the system confirms the correct order details before finalizing.

  10. Promotional Messaging: The agent can send automated promotions or coupons during off-peak hours. For example, it might text “Order now and get 10% off your next meal” during a slow business period.

Screenshots

Template

Example
{ "$schema": "https://web-api.clerk.chat/pipeline-schema", "name": "Restuarant - qualifying agent", "nodes": [ { "type": "tool_runner", "name": "Update address", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "json", "nodeConfig": { "type": "contact_tools", "config": {}, "enabledTools": [ "set_attribute" ], "tools": { "set_attribute": { "paramValues": { "attributeName": { "type": "fixed", "value": "Address" }, "attributeValue": { "path": "address", "type": "pipeline-variable" } } } } } }, { "type": "tool_runner", "name": "Update delivery or pickup", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "json", "nodeConfig": { "type": "contact_tools", "config": {}, "enabledTools": [ "set_attribute" ], "tools": { "set_attribute": { "paramValues": { "attributeName": { "type": "fixed", "value": "Delivery or pickup?" }, "attributeValue": { "path": "delivery or pickup?", "type": "pipeline-variable" } } } } } }, { "type": "tool_runner", "name": "Update order", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "json", "nodeConfig": { "type": "contact_tools", "config": {}, "enabledTools": [ "set_attribute" ], "tools": { "set_attribute": { "paramValues": { "attributeName": { "type": "fixed", "value": "Order" }, "attributeValue": { "path": "order", "type": "pipeline-variable" } } } } } }, { "type": "ai_bot", "name": "Conclude", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "user_message", "nodeConfig": { "modelProvider": "openai", "modelVersion": null, "maxTokens": null, "temperature": null, "variables": {}, "prompt": "Your job is to conclude the conversation with the user. By this point, we have all the information we need. Tell the user their order will be ready in approx 30 mins. Then tell the user we will message them back when their order is ready. \n\nYour output should be max 40 words.", "promptSections": [], "sectionTemplates": {}, "responseSchema": { "type": "object", "required": [], "properties": {} }, "opts": { "sendStructuredConvo": true } } }, { "type": "ai_bot", "name": "2. Pickup or delivery?", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "user_message", "nodeConfig": { "modelProvider": "openai", "modelVersion": null, "maxTokens": null, "temperature": null, "variables": {}, "prompt": "Your job is to ask the user if they want to pickup their food order, or have it delivered. \n\nYour output should be conversational and max 40 words.", "promptSections": [], "sectionTemplates": {}, "responseSchema": { "type": "object", "required": [], "properties": {} }, "opts": { "sendStructuredConvo": true } } }, { "type": "ai_bot", "name": "3. Address", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "user_message", "nodeConfig": { "modelProvider": "openai", "modelVersion": null, "maxTokens": null, "temperature": null, "variables": {}, "prompt": "Your job is to ask the user the address the want the order delivered too, in the event that they want a delivery. \n\nYou need the complete address (Street address, city, province/state, postcode/ZIP code). You should not extract the address (leave it blank) until you have all these things. \n\nYour output should be conversational and max 40 words.", "promptSections": [], "sectionTemplates": {}, "responseSchema": { "type": "object", "required": [], "properties": {} }, "opts": { "sendStructuredConvo": true } } }, { "type": "ai_bot", "name": "1. Their order", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "user_message", "nodeConfig": { "modelProvider": "openai", "modelVersion": null, "maxTokens": null, "temperature": null, "variables": {}, "prompt": "Your job is to ask the user what their food order is. Make sure they give the complete order. \n\nYour output should be conversational and max 40 words.", "promptSections": [], "sectionTemplates": {}, "responseSchema": { "type": "object", "required": [], "properties": {} }, "opts": { "sendStructuredConvo": true } } }, { "type": "ai_bot", "name": "Qualification brain", "triggeredBy": [ "unreadMessage.fromAny" ], "responseType": "json", "nodeConfig": { "modelProvider": "openai", "modelVersion": "o3-mini", "maxTokens": null, "temperature": null, "variables": {}, "prompt": "You are working for a restaurant. \n\nYour job is to read the conversation history and extract the following bits of data: \n- The client's complete order. The quantity of each item should be a number e.g. \"1\" or \"2\" not typed number \"one\" or \"two\". Each item should be bulleted with a \"-\". \n- Whether the client wants a delivery or pick up. A pickup is if the user comes to the store to pick up the order. A delivery is if they get it delivered to their address. They need to explicitly say one of these for you to make a decision between delivery or pickup. Write with a capitalised first letter. \n- Their address if they want delivery (otherwise we don't need it). If the user wants a pickup, output address as: \"N/A\". You need the complete address (Street address, city, province/state, postcode/ZIP code). You should not extract the address (leave it blank) until you have all these things. \n\nIf a data point hasn't been given in the conversation yet, leave it blank, e.g. \"\"", "promptSections": [], "sectionTemplates": {}, "responseSchema": { "type": "object", "required": [ "order", "address", "delivery or pickup?" ], "properties": { "order": { "type": "string" }, "address": { "type": "string" }, "delivery or pickup?": { "type": "string" } } }, "opts": { "sendStructuredConvo": true } } }, { "type": "trigger", "name": "Start", "triggeredBy": [ "userMessage" ], "responseType": "json" } ], "edges": [ { "name": null, "sourceNode": "Qualification brain", "destinationNode": "Update order", "sourceVariables": null, "filters": [] }, { "name": null, "sourceNode": "Start", "destinationNode": "Qualification brain", "sourceVariables": null, "filters": [] }, { "name": null, "sourceNode": "Qualification brain", "destinationNode": "Update address", "sourceVariables": null, "filters": [] }, { "name": null, "sourceNode": "Qualification brain", "destinationNode": "Update delivery or pickup", "sourceVariables": null, "filters": [] }, { "name": "Got all", "sourceNode": "Qualification brain", "destinationNode": "Conclude", "sourceVariables": null, "filters": [ { "type": "rule", "config": { "syntax": { "or": [ { "and": [ { "!isEmpty": [ { "var": "message.order" } ] }, { "!isEmpty": [ { "var": "message.delivery or pickup?" } ] }, { "!isEmpty": [ { "var": "message.address" } ] } ] }, { "and": [ { "!isEmpty": [ { "var": "message.order" } ] }, { "===": [ { "var": "message.delivery or pickup?" }, "pickup" ] } ] } ] } } } ] }, { "name": "Got 1, missing 2. ", "sourceNode": "Qualification brain", "destinationNode": "2. Pickup or delivery?", "sourceVariables": null, "filters": [ { "type": "rule", "config": { "syntax": { "and": [ { "!isEmpty": [ { "var": "message.order" } ] }, { "isEmpty": [ { "var": "message.delivery or pickup?" } ] } ] } } } ] }, { "name": "Got 1, 2, missing 3. ", "sourceNode": "Qualification brain", "destinationNode": "3. Address", "sourceVariables": null, "filters": [ { "type": "rule", "config": { "syntax": { "and": [ { "!isEmpty": [ { "var": "message.order" } ] }, { "===": [ { "var": "message.delivery or pickup?" }, "Delivery" ] }, { "isEmpty": [ { "var": "message.address" } ] } ] } } } ] }, { "name": "Got none", "sourceNode": "Qualification brain", "destinationNode": "1. Their order", "sourceVariables": null, "filters": [ { "type": "rule", "config": { "syntax": { "isEmpty": [ { "var": "message.order" } ] } } } ] } ] }