Multi-Agenten-Restaurantsimulation mit Large Language Models (LLM) in der Praxis, mit Python und OpenAI
So habe ich Large Language Model Agents verwendet, um mit Python einen End-to-End-Restaurantbetrieb zu simulieren.
Letzte Woche veröffentlichte OpenAI eine Datei PDFUnd alle reden darüber. Diese Datei ist ein 34-seitiger Leitfaden, der erklärt, was Large Language Model Agents (LLM Agents) sind und wie man sie verwendet.
Das PDF ist relativ kurz und auch leicht zu lesen (Sie müssen kein Softwareentwickler/Mentor sein, um es zu verstehen), aber es erklärt in wenigen Worten drei Dinge:

.1. Große Sprachmodell-Agenten (LLM-Agenten) „Es sind Systeme, die Aufgaben für Sie selbstständig erledigen.“
Handelt es sich hierbei nicht lediglich um einfache Aufrufe großer Sprachmodelle (LLMs), die über eine API aufgerufen werden? Nun, ja und nein. Sie verwenden dieselben Formulare zum Abschluss von Konversationen. Es ist also so ähnlich wie: Aber Ziel ist es, eine bestimmte Aktion auszulösen. Damit meine ich, dass die Leistung Ihrer Agenten Es muss in ein umsetzbares Ergebnis umgesetzt werden. In Ihrem System. Wenn Ihre LLM-Ausgabe beispielsweise „Spaghetti“ lautet, wird „Spaghetti“ zu Ihrem Datenpfad hinzugefügt und irgendwann wird es jemand sehen und Spaghetti kochen (Alarm).
2. Large Language Model Agents (LLM Agents) sind speziell integriert mit Funktionen (Tools)
Ich spreche hier von dem Szenario, in dem Sie ChatGPT eine Frage stellen und es seinen eigenen Bildgenerator/Websucher/Codeausschnitt aufruft. Es verwendet intern eine Funktion namens Widget, die durch Ihre Eingabeaufforderung ausgelöst wird. Der Bildgenerator ist eine eingebaute Funktion, aber man kann auch Ihr Job (Ihr Werkzeug), die Sie speziell für Ihre Aufgabe festlegen können. Diese Fähigkeit zur Integration externer Tools und Funktionen verleiht LLM-Agenten große Flexibilität und Leistungsfähigkeit bei der Ausführung einer Vielzahl von Aufgaben.
3. Es können mehrere große Sprachmodell-Agenten (LLM-Agenten) integriert werden. Konsekutiv
Sie können entweder einen einzelnen Agenten integrieren und ihn mit mehreren Tools ausstatten. أو Teilen Sie die Tools in spezialisierte Agenten auf, was wir in diesem Artikel tun werden (noch ein Hinweis!).
Die technischen Details mögen für Softwareentwickler von Interesse sein, aber warum ist das Thema Agenten für alle anderen so wichtig?
Nun, weil dies einen Paradigmenwechsel darstellt, der dazu beiträgt, Open-AI-Modellen einen Nutzen zu verleihen. Denken Sie darüber nach: Große Sprachmodelle (LLMs) bieten Umsetzbare Ergebnisse. Es geht also nicht darum, im letzten Schritt des Workflows LLM-Eingabeaufforderungen zu verwenden, um das endgültige Ergebnis zu verbessern. Vielmehr geht es um Integration des gesamten Workflows mit Large Language Model Agents (LLM Agents) Um die Qualität des gesamten Arbeitsablaufs zu verbessern.
Obwohl ich versuche, es in Worten zu erklären, denke ich, dass es einfacher ist, es Ihnen praktisch zu zeigen. Nehmen wir an, wir sprechen über Restaurant, Beispielsweise.
In einem typischen Restaurant läuft alles ganz normal und klar ab: Man steht in der Schlange, bestellt sein Essen, wartet auf sein Essen, isst und geht wieder. Wenn wir dies nun mit dem „Agenten“-Ansatz übersetzen, können wir mindestens drei Agenten identifizieren:
- Agent Klient Es handelt sich um einen Large Language Model (LLM)-Agenten, der Essen bestellt oder den Kellner um Vorschläge bittet.
- Agent Kellner Es handelt sich um ein großes Sprachmodell (LLM), das Anfragen sammelt und bei Bedarf Vorschläge macht.
- Agent Unterhaltung Es handelt sich um ein großes Sprachmodell (LLM) zur Bearbeitung von Kundenbeschwerden.
Nun erklärt Ihnen OpenAI genau, wie Sie diese Entitäten erstellen, aber das ist der relativ einfache Teil; Da steckt noch viel mehr dahinter, nicht wahr?
Wir müssen umsetzen das Restaurant, und wir müssen schaffen Wartelistenmethode, wo die Leute sitzen, je nachdem, wie voll das Restaurant ist, und wir müssen schaffen قائICة الطاetty, Simulation Wartezeitund stellen Sie sicher, dass alles funktioniert, Dann Erst dann Wir können Agenten verbinden. wie immer:
Generative KI ist leistungsstark, aber nur, wenn sie im richtigen Kontext eingesetzt wird.
Bevor wir also zum spannenden Teil über Agenten kommen, erfahren Sie in diesem Artikel:
- Systemdesign Zum Restaurantkaufmann/-frau LLM. Eine Idee ohne Code, nur eine Skizze des Projekts mit Stift und Papier (oder eher Maus und PowerPoint).
- Agentenfreie Restaurantimplementierung. Einfach und unkompliziert, erstellen Sie einfach die Grundstruktur des Codes.
- Agent Restaurant-Implementierung. Plus eine einfache grafische Benutzeroberfläche für eine gute Anzeige.
- Abschließende Überlegungen und Beobachtungen.
Sieht aus, als hätten wir eine Menge zu besprechen. Ab ins Labor! 🧪
1. Restaurant-Systemdesign: Ein Expertenleitfaden
Hinweis: Wenn Sie bereits einige technische Touren gemacht haben, wird Ihnen die Gestaltung dieses Systems sehr leicht fallen. Das Ziel dieses Entwurfs besteht nicht darin, jeden Teil eines maschinellen Lernsystems umfassend zu demonstrieren (wie Sie in einem 15-minütigen Interview gefragt werden 🙃), sondern lediglich einige Hinweise darauf zu geben, was wir als Nächstes tun werden.
Die Art und Weise, wie wir den Restaurantprozess, integriert mit einem großen Sprachmodell (LLM), visualisieren können, ist in diesem Bild zusammengefasst:

Lassen Sie mich erklären:
- Restaurant() Und Speisekarte() Es gibt zwei Klassen. Wir definieren sie und alle Tabellen, Bestellungen und Systeminformationen innerhalb der Klassen werden dynamisch definiert und aktualisiert.
- müssen Neuer Kunde Durch einen Sitzmechanismus gehen. Wenn sie sitzen können (genügend freie Tische), ist das großartig, dann können wir sie sitzen lassen; Andernfalls muss der Kunde in der Schlange warten.
- Für den Kunden SitzungEs wird ein Kellner da sein, der ihnen die Bestellung von Essen ermöglicht. Sie können sich „beschweren“ und fragen, wie lange es nach der Bestellung dauert, bis das Essen da ist.
- Menschen können nicht in der Schlange warten Sie tun viel, aber sie können sich auch „beschweren“ und fragen, wie lange sie in der Schlange warten müssen, bevor sie sich hinsetzen können.
Wenn Sie darüber nachdenken, sind Sie nicht Brauchen zu diesem Zweck auf ein großes Sprachmodell (LLM) zurückgreifen. Beispielsweise können wir die Wartezeit im Voraus berechnen und diese dann mit einer vordefinierten, formatierten Zeichenfolge verknüpfen. Wir können auch ein einfaches Menü zum Aufnehmen von Bestellungen verwenden (wie der automatisierte Kiosk von McDonald's) und damit fertig. Natürlich können wir das tun, aber denken Sie darüber nach.
Was ist, wenn der Kunde Informationen zum Menü erfragen möchte? während des Wartens? Was wäre, wenn sie es wären? Zögerlich Über Essen? Was wäre, wenn sie es wissen wollten? Die köstlichste vegetarische Option Auf der Speisekarte? Was wäre, wenn sie es wollten? Guter Wein zu einem vernünftigen Preis? Wir können entweder damit beginnen, für jedes dieser Szenarien regelbasierte Methoden zu definieren und damit Zeit und Geld zu verschwenden, oder wir können anfangen, künstliche Intelligenz zu nutzen. Darum geht es in diesem Artikel. Wenn wir große Sprachmodell-Agenten (LLM-Agenten) verwenden, haben wir die Möglichkeit, alle diese Szenarien in einem Durchgang zu verarbeiten.
Wenn ich etwas gelernt habe, dann, dass Softwareentwicklung notwendig ist. Schritt für Schritt. Du solltest besser Skeleton Fügen Sie Ihrem Modell dann Dekorationen und Zubehör hinzu. Aus diesem Grund werden wir eine agentenfreie Version des oben genannten Produkts erstellen. Diese vereinfachte Version verfügt über ein Warteschlangensystem, das Wartezeiten berechnet und das Menü ausführt, sodass alles ohne KI reibungslos läuft. Nach diesem Schritt können wir die Agenten an den oben besprochenen und gezeigten Stellen platzieren (Kunde, Gastgeber und Kellner).
2. Agentenfreie Implementierung
Es ist immer besser, im Hauptskript alles so weit wie möglich zu vereinfachen und die komplexen Vorgänge im Hintergrund zu belassen. Unsere agentenfreie Implementierung kann in diesem Code ausgeführt werden.
importiere Zufall, importiere Zeit, importiere Mathematik, importiere Systeme aus Dienstprogrammen, importiere * aus Konstanten, importiere * aus naiven Modellen, importiere *, wenn __name__ == "__main__": random.seed(42) menu = preprocess_menu(MENU_FILE, eat_time_factor=0.5) R = Restaurant(Anzahl_Tische=2, Ankunftswahrscheinlichkeit=0.7, Tick_Länge=1, Realpause=5.0, Abfragewahrscheinlichkeit=0.4, menu=menu ) R.run(Gesamtzeit=60)
Wie wir sehen, können wir Folgendes ändern:
- Anzahl_Tabellen; Anzahl der Tische in unserem Restaurant.
- Ankunftswahrscheinlichkeit; Es handelt sich um die Wahrscheinlichkeit, dass zu jedem Zeitpunkt ein Kunde eintrifft.
- Tick; Es ist der Zeitschritt unserer Simulation.
- Pause; Es implementiert die Funktion time.sleep(), die zur Simulation des Arbeitsablaufs eines echten Restaurants verwendet wird.
Jetzt erfolgt die gesamte Implementierung in einer Datei. naive_models.py, bestehende hier.
import random
import time
import math
import sys
from utils import *
from constants import *
class Table:
def __init__(self, id, capacity=1):
self.id = id
self.capacity = capacity
self.is_free = True
self.cust_id = None
self.plate = None
self.cooking_complete_at = None
self.leave_at = None
def seat(self, cust_id, clock, plate, cook_time, eat_time):
self.is_free = False
self.cust_id = cust_id
self.plate = plate
self.cooking_complete_at = clock + cook_time
self._scheduled_eat_time = eat_time
msg = (
f"[{clock:04}m] 🪑 Seated customer {cust_id} at T{self.id} "
f"ordering {plate!r} (cook {cook_time}m, eat {eat_time}m)"
)
print(msg); sys.stdout.flush()
def start_eating(self, clock):
self.leave_at = clock + self._scheduled_eat_time
msg = (
f"[{clock:04}m] 🍽️ Customer {self.cust_id} at T{self.id} "
f"starts eating their {self.plate!r} (leaves at {self.leave_at}m)"
)
print(msg); sys.stdout.flush()
def depart(self, clock):
msg = (
f"[{clock:04}m] 💸 Customer {self.cust_id} finished their "
f"{self.plate!r} and left T{self.id}"
)
print(msg); sys.stdout.flush()
self.is_free = True
self.cust_id = None
self.plate = None
self.cooking_complete_at = None
self.leave_at = None
class Restaurant:
def __init__(self, num_tables, arrival_prob=0.33,
tick_length=1, real_pause=0.5, menu=None,
query_prob=0.0):
self.tables = [Table(i) for i in range(num_tables)]
# queue holds only customer IDs
self.queue = []
self.clock = 0
self.next_cust_id = 1
self.arrival_prob = arrival_prob
self.tick = tick_length
self.pause = real_pause
self.menu = menu or [
("Burger", 2, 4),
("Pasta", 3, 5),
("Salad", 1, 2),
("Steak", 4, 6),
("Soup", 1, 3),
]
self.query_prob = query_prob
total = sum(c + e for _, c, e in self.menu)
self.avg_service_time = total / len(self.menu)
def open_tables(self):
return [t for t in self.tables if t.is_free]
def _pick_dish(self):
return random.choice(self.menu)
def arrive(self):
if random.random() < self.arrival_prob:
cid = self.next_cust_id
self.next_cust_id += 1
free = self.open_tables()
if free:
# pick dish only when seating immediately
plate, cook_time, eat_time = self._pick_dish()
table = min(free, key=lambda t: t.capacity)
table.seat(cid, self.clock, plate, cook_time, eat_time)
else:
self.queue.append(cid)
print(f"[{self.clock:04}m] ⏳ Queued customer {cid} (waiting)")
def process_cooking(self):
for t in self.tables:
if (not t.is_free
and t.cooking_complete_at is not None
and t.cooking_complete_at <= self.clock
and t.leave_at is None):
t.start_eating(self.clock)
def process_departures(self):
for t in self.tables:
if (not t.is_free
and t.leave_at is not None
and t.leave_at <= self.clock):
t.depart(self.clock)
def seat_from_queue(self):
while self.queue and self.open_tables():
cid = self.queue.pop(0)
# pick dish at seating time
plate, cook_time, eat_time = self._pick_dish()
table = min(self.open_tables(), key=lambda t: t.capacity)
table.seat(cid, self.clock, plate, cook_time, eat_time)
def estimate_queue_time(self, cid):
positions = list(self.queue)
idx = positions.index(cid)
raw_wait = (idx + 1) * self.avg_service_time / len(self.tables)
return math.ceil(raw_wait)
def estimate_food_time(self, cid):
for t in self.tables:
if t.cust_id == cid:
if t.cooking_complete_at > self.clock:
return t.cooking_complete_at - self.clock
return max(0, t.leave_at - self.clock)
return None
def handle_random_query(self):
queue_ids = list(self.queue)
seated_ids = [t.cust_id for t in self.tables if not t.is_free]
if queue_ids and (not seated_ids or random.random() < 0.7):
cid = random.choice(queue_ids)
wait = self.estimate_queue_time(cid)
print(f"[{self.clock:04}m] ❓ Customer {cid}: How long will I be in line?")
print(f"[{self.clock:04}m] ➡️ Estimated wait for customer {cid}: {wait}m")
elif seated_ids:
cid = random.choice(seated_ids)
wait = self.estimate_food_time(cid)
table = next(t for t in self.tables if t.cust_id == cid)
food = table.plate
print(f"[{self.clock:04}m] ❓ Customer {cid}: How long will the {food} take me?")
if wait is None:
print(f"[{self.clock:04}m] ➡️ Ready now!")
else:
print(f"[{self.clock:04}m] ➡️ Estimated food wait for customer {cid}: {wait}m")
def tick_once(self):
self.arrive()
self.process_cooking()
self.process_departures()
self.seat_from_queue()
if self.query_prob and random.random() < self.query_prob:
self.handle_random_query()
self.clock += self.tick
time.sleep(self.pause)
def run(self, total_time):
while self.clock < total_time:
self.tick_once()
print("n--- END OF SHIFT ---")
free = sum(t.is_free for t in self.tables)
print(f"{free}/{len(self.tables)} tables free at {self.clock}m.")
if __name__ == "__main__":
random.seed(42)
menu = preprocess_menu(MENU_FILE, eat_time_factor=0.5)
R = Restaurant(
num_tables=2,
arrival_prob=0.7,
tick_length=1,
real_pause=5.0,
query_prob=0.4,
menu=menu
)
R.run(total_time=60)
Das ist lang. Ich möchte Sie durch einige Schritte führen.
Das gesamte Skript läuft auf naive_sim mit dem Befehl .laufen() Mit folgenden Funktionen:
- ankommen, das die Ankunft und Anfrage von Kunden bzw. deren Ankunft und Einordnung in eine Warteschlange darstellt.
- Prozesskochen, das das Kochen an jedem Tisch simuliert.
- Abflugabwicklung, das den Kundenabgang simuliert.
- Sitzplatz aus der Warteschlange, das das Schlangestehen von Kunden simuliert.
- Handle_random_query, die nach dem Zufallsprinzip aufgerufen wird und bei der ein Kunde in der Schlange steht oder auf sein Essen wartet, nach der Wartezeit fragen kann.
Wenn wir naive_sim.py ausführen, erhalten wir dies vom Terminal.

Dies ist an sich schon ein Data-Science-Produkt. Sie können damit eine Restaurantkette in Monte Carlo betreiben und das Potenzial für die Bildung langer Warteschlangen erkennen. Restaurants können diesen „digitalen Zwilling“ ihres Restaurants nutzen und erkennen, wann kritische Dinge passieren könnten. Da wir nun ein funktionierendes Produkt haben, wollen wir es mithilfe künstlicher Intelligenz (KI) noch schöner und leistungsfähiger machen.
3. Agent Restaurant Implementierung
Wie wir oben sehen können, können Kunden bereits Fragen stellen und wir erhalten die Antwort in Form einer Zahl. Der Kunde wählt in unserem System ebenfalls ein zufälliges Lebensmittel aus. Versuchen wir nun, diesem System Agenten hinzuzufügen. Die Aktivierung eines Restaurant-Agentensystems ist ein fortgeschrittener Schritt zur Automatisierung des Kundendienstes und zur Verbesserung des Benutzererlebnisses. Geschulte Mitarbeiter können Kundenanfragen effizient beantworten und personalisierte Empfehlungen geben.
3.1 Implementierung dedizierter Agenten
Sie müssen das Modul „Agenten“ installieren:
Nachfolgend finden Sie die Implementierung des Kundendienstmitarbeiters, des Unterhaltungsagenten und des Beschwerdebearbeiters.
# custom_agents.py import os, json from openai import OpenAI from agents import Agent from newtools import * client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"), default_headers={"OpenAI-Beta":"assistants=v2"}) menu_agent = Agent(name = "Chef_suggester", instructions = "Sie sind ein hilfsbereiter Kellner, der alles über unser Restaurant weiß und den Kunden bei der Auswahl ihres Essens hilft. Sie werden sich zunächst höflich" "als virtueller Essensassistent vorstellen und den Kunden höflich begrüßen. Der Name des Kunden befindet sich in der msg-json-Datei" "Sie werden die Speisekarte lesen und, basierend auf den Fragen des Kunden, im Anfrageschlüssel der json-Datei die beste Empfehlung aus der Speisekarte geben." "Wenn der Kunde Ihnen unangemessene Fragen stellt, geben Sie einfach 'unsuccessfull' im json-Format '{food: , Status: }'", tools = [get_menu]) entertainer_agent = Agent(name = "Entertainer", instructions = ("Sie sind ein hilfsbereiter Kellner, der die Kunden beschäftigt, während sie warten." "Sie können keine Rabatte oder Angebote anbieten, aber die Kunden können Fragen zur Speisekarte stellen, die Sie über die" "get_menu-Funktionen erhalten. Sie können Sie auch fragen, wie lange die Warteschlange sein wird. Ihre Informationen finden Sie in der waiting_time." "Wenn der user_status 'Warteschlange' ist, geben Sie die Zeit einfach freundlich an, basierend auf der Wartezeit. Andernfalls, " "wenn der user_status 'Essen' ist, bedeutet dies, dass sie auf Essen warten. Aktivieren Sie 'Bestellung' und geben Sie einen lustigen Hinweis auf" "ihre Wartezeit. Zum Beispiel: 'Sie warten 1 Minuten auf Pasta, es sieht aus, als würde der Koch Soße darauf geben!'", tools = [get_menu]) customer_agent = Agent(name = "Kunde", instructions = ("Sie sind ein Kunde und essen in einem italienischen Restaurant. Sehen Sie sich die Speisekarte mit der get_menu-Funktion an. Wenn Sie bereits wissen, was Sie möchten, sagen Sie dem Kellner einfach, was Sie möchten. " "Andernfalls geben Sie ihnen eine allgemeine Angabe oder bitten Sie um eine Anleitung basierend auf Ihren allgemeinen Vorlieben, und sie werden das Beste für Sie auswählen."), tools = [get_menu]) def call_agent(runner, msg, class_agent = "wait"): if class_agent == "entertainer": return runner.run_sync(entertainer_agent, msg) elif class_agent == "waiter": return runner.run_sync(menu_agent, msg) elif class_agent == "customer": return runner.run_sync(customer_agent, '')
Wir haben eine Definition Klient, das ist der Client-Aufruf von OpenAI, und newtools.py, wodurch die Liste aufgerufen wird, und Anrufagent die den einzelnen Agenten anruft und über Läufer. Diese Komponenten sind für die Erstellung eines effektiven Agentensystems von wesentlicher Bedeutung.
Genau darüber haben wir in der Einleitung gesprochen. Wir identifizieren mehrere Agenten Sie werden verbunden sein und sie nutzen Werkzeuge Durch meinen Code definiert. Mit diesen Tools und Agenten können Sie Kundendienstaufgaben automatisieren und das Benutzererlebnis verbessern.
von Agenten importiere function_tool von Konstanten importiere * importiere Pandas als pd @function_tool def get_menu(): df = pd.read_csv(MENU_FILE) # in eine Liste von Wörterbüchern (oder eine JSON-serialisierbare Struktur) konvertieren returniere df.to_dict(orient="records")
3.2 Implementierung dedizierter Agenten
Die Umsetzung erfolgt integriert Tisch Und Restaurant Mit Agenten im folgenden Code:
importiere Zufallszahlen, importiere Zeit, importiere Mathematik, importiere Systemdaten von Dienstprogrammen, importiere * von Konstanten, importiere * Zeit, Zufallszahlen, JSON von benutzerdefinierten Agenten, importiere * von Dienstprogrammen, importiere * von Konstanten, importiere * von Agenten, importiere Runner # Liste der Vornamen aus Ihrer NAMES-Konstante # nehme an, NAMES = [ ... ] is defined in constants.py
import logging
# Set up logging
def log(msg):
logging.info(msg)
class Table:
def __init__(self, id, capacity=1):
self.id = id
self.capacity = capacity
self.is_free = True
self.cust_id = None
self.orders = [] # list of (plate, cook_time, eat_time)
self.current_phase = None # "cooking" or "eating"
self.cooking_complete_at = None
self.leave_at = None
def seat(self, cust_id, cust_name, clock, orders):
self.is_free = False
self.cust_id = cust_id
self.orders = list(orders) # copy the list of tuples
# start first dish cooking immediately
plate, cook_time, eat_time = self.orders.pop(0)
self.current_phase = "cooking"
self._scheduled_eat_time = eat_time
self._remaining_orders = self.orders # save the tail
self.cooking_complete_at = clock + cook_time
self.leave_at = None
msg = (f"[{clock:04}m] 🪑 Seated {cust_name} (#{cust_id}) at T{self.id} "
f"ordering {len(orders)} dishes; first: {plate!r} "
f"(cook {cook_time}m, eat {eat_time}m)")
print(msg); sys.stdout.flush()
def start_eating(self, clock):
self.current_phase = "eating"
self.leave_at = clock + self._scheduled_eat_time
plate = self.plate if hasattr(self, 'plate') else "dish"
msg = (f"[{clock:04}m] 🍽️ {plate!r} ready for {self.cust_name} "
f"(#{self.cust_id}) at T{self.id}, eating until {self.leave_at}m")
print(msg); sys.stdout.flush()
def finish_phase(self, clock):
"""Called when eating of current dish finishes."""
if self._remaining_orders:
# move to next dish
plate, cook_time, eat_time = self._remaining_orders.pop(0)
self.current_phase = "cooking"
self._scheduled_eat_time = eat_time
self.cooking_complete_at = clock + cook_time
self.leave_at = None
self.plate = plate
msg = (f"[{clock:04}m] 🔄 Next dish for {self.cust_name} (#{self.cust_id}) "
f"at T{self.id}: {plate!r} (cook {cook_time}m, eat {eat_time}m)")
print(msg); sys.stdout.flush()
else:
# no more dishes: depart
msg = (f"[{clock:04}m] 💸 {self.cust_name} (#{self.cust_id}) "
f"finished all dishes and left T{self.id}")
print(msg); sys.stdout.flush()
self.is_free = True
self.cust_id = None
self.orders = []
self.current_phase = None
self.cooking_complete_at = None
self.leave_at = None
class Restaurant:
def __init__(self, num_tables, arrival_prob=0.33,
tick_length=1, real_pause=0.5, menu=None,
query_prob=0.0):
self.tables = [Table(i) for i in range(num_tables)]
self.queue = [] # just customer IDs
self.clock = 0
self.next_cust_id = 1
self.arrival_prob = arrival_prob
self.tick = tick_length
self.pause = real_pause
self.menu = menu or [
("Burger", 2, 4),
("Pasta", 3, 5),
("Salad", 1, 2),
("Steak", 4, 6),
("Soup", 1, 3),
]
self.runner = Runner()
self.query_prob = query_prob
self.names = {}
self.load_logging()
def load_logging(self):
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("openai").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
logging.basicConfig(level=logging.INFO, format='[%(asctime)s] %(message)s',
datefmt='%H:%M:%S', handlers=[
logging.FileHandler("restaurant_log.txt", mode='w'),
logging.StreamHandler(sys.stdout)])
def log_to_msg(self,msg):
logging.info(msg)
def open_tables(self):
return [t for t in self.tables if t.is_free]
def _pick_orders(self, cname):
"""Choose between 1–3 random menu items as a list."""
#n = random.randint(1, 3)
#return random.sample(self.menu, n)
customer_text = call_agent(runner = self.runner, msg= '', class_agent="customer").final_output
msg = f'The customer {cname} is talking to the waiter, saying this {customer_text}'
print(msg)
self.log_to_msg(msg)
menu_asker_output = call_agent(runner = self.runner, msg = json.dumps(customer_text), class_agent="waiter").final_output
output = extract_json_dict(menu_asker_output)
msg = f'The processed response from our LLM is {output}'
print(msg)
self.log_to_msg(msg)
if output['status'] == 'successfull':
return filter_menu_items(output['food'])
else:
n = random.randint(1, 3)
return random.sample(self.menu, n)
def _assign_name(self, cid):
name = random.choice(NAMES)
self.names[cid] = name
return name
def arrive(self):
if random.random() < self.arrival_prob:
cid = self.next_cust_id
self.next_cust_id += 1
cname = self._assign_name(cid)
free = self.open_tables()
if free:
orders = self._pick_orders(cname)
table = min(free, key=lambda t: t.capacity)
table.cust_name = cname
plate, cook_time, eat_time = orders[0]
table.plate = plate
table.seat(cid, cname, self.clock, orders)
else:
self.queue.append(cid)
msg = f"[{self.clock:04}m] ⏳ Queued {cname} (#{cid}) – waiting"
print(msg)
self.log_to_msg(msg)
def process_cooking(self):
for t in self.tables:
if (not t.is_free and
t.current_phase=="cooking" and
t.cooking_complete_at <= self.clock):
# cooking done → start eating
t.cust_name = self.names[t.cust_id]
t.start_eating(self.clock)
def process_departures(self):
for t in self.tables:
if (not t.is_free and
t.current_phase=="eating" and
t.leave_at <= self.clock):
t.cust_name = self.names[t.cust_id]
t.finish_phase(self.clock)
def seat_from_queue(self):
while self.queue and self.open_tables():
cid = self.queue.pop(0)
cname = self.names[cid]
orders = self._pick_orders(cname=cname)
table = min(self.open_tables(), key=lambda t: t.capacity)
table.cust_name = cname
plate, cook_time, eat_time = orders[0]
table.plate = plate
table.seat(cid, cname, self.clock, orders)
def estimate_queue_time(self, cid):
# same logic as before: position in queue × avg service
avg = sum(c+e for _,c,e in self.menu) / len(self.menu)
idx = self.queue.index(cid)
return math.ceil((idx+1)*avg/len(self.tables))
def estimate_food_time(self, cid):
for t in self.tables:
if t.cust_id == cid:
# if they’re still cooking, time until cook‐done
if t.current_phase == "cooking":
return max(0, t.cooking_complete_at - self.clock)
# if they’re eating, time until they finish eating
if t.current_phase == "eating":
return max(0, t.leave_at - self.clock)
return None
def handle_random_query(self):
queue_ids = list(self.queue)
seated_ids = [t.cust_id for t in self.tables if not t.is_free]
if queue_ids and (not seated_ids or random.random() < 0.7):
cid = random.choice(queue_ids)
wait = self.estimate_queue_time(cid)
cname = self.names[cid]
msg = f"[{self.clock:04}m] ❓ Customer {cid}: How long will I be in line?"
print(msg) self.log_to_msg(msg) msg = f"[{self.clock:04}m] ➡️ Geschätzte Wartezeit für Kunde {cid}: {wait}m" print(msg) self.log_to_msg(msg) waiting_message = { "customer_id": cid, "customer_name": cname, "type": "line", "wait_min": wait, "next_food": Keine } output_llm = call_agent(class_agent="entertainer", runner = self.runner, msg = json.dumps(waiting_message)) msg = f"Unser LLM hat sich hiermit um {cname} gekümmert: {output_llm}" print(msg) self.log_to_msg(msg) elif seated_ids: cid = random.choice(seated_ids) wait = self.estimate_food_time(cid) table = next(t for t in self.tables if t.cust_id == cid) food = table.plate cname = self.names[cid] msg = f"[{self.clock:04}m] ❓ Kunde {cid}: Wie lange brauche ich für das Essen?“
print(msg) self.log_to_msg(msg) wenn wait None ist: msg = f"[{self.clock:04}m] ➡️ Jetzt bereit!"
print(msg) self.log_to_msg(msg) sonst: msg = f"[{self.clock:04}m] ➡️ Geschätzte Wartezeit für Essen für Kunde {cid}: {wait}m" print(msg) self.log_to_msg(msg) waiting_message = { "customer_id": cid, "customer_name": cname, "type": "line", "wait_min": wait, "next_food": food } output_llm = call_agent(class_agent="entertainer", runner = self.runner, msg = json.dumps(waiting_message)) msg = f"Unser LLM hat sich um {cname} hiermit gekümmert: {output_llm}" print(msg) self.log_to_msg(msg) def tick_once(self): self.arrive() self.process_cooking() self.process_departures() self.seat_from_queue() wenn self.query_prob und random.random() < self.query_prob: self.handle_random_query() self.clock += self.tick time.sleep(self.pause) def run(self, total_time): während self.clock < total_time: self.tick_once() frei = Summe(t.is_free für t in self.tables) msg = f"n--- SCHICHTENENDE ---n{freie}/{len(self.tables)} Tische frei um {self.clock}m."
print(msg) self.log_to_msg(msg) if __name__ == "__main__": random.seed(42) menu = preprocess_menu(MENU_FILE, eat_time_factor=0.5) R = Restaurant( num_tables=5, arrival_prob=0.7, tick_length=1, real_pause=5.0, query_prob=0.8, menu=menu ) R.run(total_time=60)
3.3 Implementierung einer grafischen Benutzeroberfläche (GUI) für ein Restaurant mithilfe eines Large Language Model (LLM)
Um die Leistung des Restaurants mit einer Large Language Model (LLM)-Anwendung anzuzeigen, verwenden wir eine einfache grafische Benutzeroberfläche (GUI).
von llm_models_gui importiere RestaurantGUI von utils importiere * importiere zufällig von llm_models importiere Restaurant wenn __name__ == "__main__": random.seed(42) Menü = Vorverarbeitungsmenü(MENÜDATEI, Essenszeitfaktor=0.5) R = Restaurant(Anzahl Tische=5, Ankunftswahrscheinlichkeit=0.7, Ticklänge=1, reale Pause=1.0, # glatter für GUI Abfragewahrscheinlichkeit=0.8, Menü=Menü) App = RestaurantGUI(R)

Über die grafische Benutzeroberfläche (GUI) erhalten Sie Informationen zur Person (Emma), zur Tabelle, zur Uhrzeit und zur Ausgabe des großen Sprachmodells (LLM). Außerdem wird automatisch ein .txt-Eintrag erstellt.
Lassen Sie mich Ihnen ein Beispiel der Ausgabe zeigen:
[12:31:23] Kundin Emma spricht mit dem Kellner: „Ich hätte gerne die Bruschetta als Vorspeise. Danach bestelle ich Spaghetti Carbonara als ersten Gang. Zum Nachtisch genieße ich das Tiramisu. Können Sie mir auch einen passenden Wein dazu empfehlen?“ [12:31:25] Die verarbeitete Antwort unseres Masterstudenten lautet: {'food': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'status': 'successful'} [12:31:25] [0000M] ❓ Kunde 1: Wie lange brauche ich, um das Essen zuzubereiten? [12:31:25] [0000M] ➡️ Voraussichtliche Wartezeit für das Essen für den Kunden 1:15 Minuten [12:31:26] Der LLM-Student hat sich um Emmas Bestellung gekümmert: Letzter Kunde: Agent(name=”Entertainer”, …) Endergebnis (Zeichenfolge): Hallo Emma! Vielen Dank für Ihre Geduld. Die Wartezeit für den Einlass beträgt etwa 15 Minuten. Wir sind fast da – gerade genug Zeit, damit ich anfangen kann, von dieser köstlichen Bruschetta zu träumen! ️
Wir bieten:
- Der Kunde stellt über den Agenten sein eigenes Menü zusammen.und bittet den Agenten des Kellners um eine Empfehlung.
- Der Kellner empfiehlt einen Chianti-Wein und fügt ihn der Liste hinzu.
- Der Reklamationsbearbeiter informiert den Kunden über die Wartezeit.
Jetzt können wir nicht einfach einen Arbeitsablauf simulieren, wie wir es vorher getan haben, wir haben einen Arbeitsablauf. Klug, unterstützt durch dieselbe ChatGPT-Technologie. Ist das nicht toll?
4. Fazit
Vielen Dank, dass Sie gekommen sind, das bedeutet mir sehr viel ❤️.
Gehen wir zurück und sehen wir, was wir in diesem Artikel gemacht haben.
- Restaurantsystemdesign:
Wir haben mithilfe von PowerPoint und zusätzlichen KI-Agenten einen Schnellentwurf für ein Restaurantsystem erstellt. - Agentenfreie Basis:
Wir haben zunächst eine deterministische Simulation erstellt, damit wir die Logik für die Warteschlange, die Garzeiten und die Tischrotation codieren konnten. Dies ist unser Grundgerüst, bevor wir mit der KI beginnen. - Agentenbasiertes Restaurant:
In dieser Phase haben wir KI-Agenten eingesetzt, um unseren Beschwerde- und Klagefall mit Agenten zu füllen. Wir haben außerdem eine grafische Benutzeroberfläche erstellt, um die Ergebnisse übersichtlich anzuzeigen.
An dieser Stelle möchte ich etwas ganz klarstellen. Ich weiß, das klingt ein bisschen wie Black Mirror. Kundensimulation? Restaurant- und Kellnersimulation? Ja, es ist seltsam, Aber Das Problem ist nie das KI-Tool, sondern immer die Art und Weise, wie es eingesetzt wird. Ich glaube, dass es ein verlorenes Spiel ist, menschliche Kellner durch KI zu ersetzen.
Als Kellner geht es nicht nur darum, Bestellungen aufzunehmen und Wein Nummer N auf Grundlage der zuvor bestellten N-1 Weine zu empfehlen. Es geht darum, herzlich genug zu sein, damit sich ein Gast willkommen fühlt, aber auch distanziert genug, um sich nicht in sein Gespräch einzumischen, sanft genug, damit er sich wie zu Hause fühlt, aber stark genug, damit er Ihre Grenzen respektiert. Es ist eine Kombination von Eigenschaften, die meiner Meinung nach eine menschliche Note, Geduld und Empathie erfordern.
Ich bin jedoch davon überzeugt, dass diese Technologie auf zweierlei Weise richtig eingesetzt werden kann:
- Helfen Sie echten Menschen, die auf der Warteliste stehen. Die Kellner drinnen sind sehr beschäftigt und Restaurants stellen Ihnen bereits eine Speisekarte zur Verfügung, die Sie sich ansehen können, während Sie auf Ihren Tisch warten. Es ist unrealistisch anzunehmen, dass andere Kellner Leute unterhalten, die ohne Tisch warten. An dieser Stelle kann ein KI-Begleiter zum Chatten hilfreich sein.
- Restaurant-Simulation. Das Szenario, das ich geschrieben habe, simuliert Verhalten Kunde Auch. Dies bedeutet, dass Sie mithilfe von Simulationen möglicherweise verschiedene Szenarien testen, sehen können, wann sich Warteschlangen bilden, unterschiedliche Reaktionen von Personen oder Kellnern annehmen können usw. Mit anderen Worten: Dies kann Ihr „digitaler Zwilling“ sein, an dem Sie Tests durchführen.
Kommentarfunktion ist geschlossen.