Simulation de restaurant multi-agents utilisant de grands modèles de langage (LLM) en pratique, avec Python et OpenAI

Voici comment j'ai utilisé de grands agents de modèle de langage pour simuler une opération de restaurant de bout en bout, en utilisant Python.

La semaine dernière, OpenAI a publié un fichier PDFEt tout le monde en parle. Ce fichier est un guide de 34 pages expliquant ce que sont les agents de modèle de langage de grande taille (agents LLM) et comment les utiliser.

Le PDF est relativement court et facile à lire également (vous n'avez pas besoin d'être un ingénieur logiciel/mentor pour le comprendre), mais en quelques mots, il explique trois choses :

.1. Agents de modèles de langage de grande taille (agents LLM) « Ce sont des systèmes qui effectuent des tâches de manière indépendante en votre nom. »

Alors, ne s’agit-il pas simplement d’appels simples à de grands modèles de langage (LLM) appelés via une API ? Et bien, oui et non. Vous utilisez le(s) même(s) formulaire(s) de complétion de conversation, donc c'est un peu comme, ولكن Il s’agit de créer une action spécifique. Ce que je veux dire par là, c'est que la production de vos agents Il doit être traduit en un résultat exploitable. Dans votre système. Par exemple, si votre sortie LLM indique « spaghetti », « spaghetti » sera ajouté à votre chemin de données, et finalement quelqu'un le verra et cuisinera des spaghettis (alerte).

2. Les agents de modèle de langage de grande taille (agents LLM) sont spécifiquement intégrés à Fonctions (Outils)

Je parle ici du scénario dans lequel vous posez une question à ChatGPT et il appelle son propre générateur d'images/moteur de recherche Web/extrait de code. Il utilise en interne une fonction appelée widget, qui est déclenchée par votre invite. Maintenant, le générateur d’images est une fonction intégrée, mais ils peuvent également appeler Votre travail (votre outil), que vous pouvez spécifier spécifiquement pour votre tâche. Cette capacité à intégrer des outils et des fonctionnalités externes est ce qui donne aux agents LLM une grande flexibilité et une grande puissance dans l'exécution d'une variété de tâches.

 

3. Plusieurs agents de modèles de langage de grande taille (agents LLM) peuvent être intégrés. Consécutif

Vous pouvez soit intégrer un seul agent et lui fournir plusieurs outils. ou Divisez les outils en agents spécialisés, ce que nous allons faire dans cet article (un autre indice !).

Les détails techniques peuvent intéresser les ingénieurs logiciels, mais pourquoi ce sujet des agents est-il si important pour tout le monde ?
Eh bien, parce que cela représente un changement de paradigme qui contribue à donner de l’utilité aux modèles d’IA ouverte. Pensez-y : les grands modèles de langage (LLM) fournissent désormais Résultats exploitables. Il ne s’agit donc pas d’utiliser les invites LLM dans la dernière étape du flux de travail pour améliorer le résultat final ; Il s’agit plutôt de Intégration de l'ensemble du flux de travail avec les agents de modèles de langage volumineux (agents LLM) Pour améliorer la qualité de l’ensemble du flux de travail.

Même si j'essaie de l'expliquer avec des mots, je pense qu'il est plus facile de vous le montrer de manière pratique. Disons que nous parlons de restaurant, Par exemple.

Un restaurant typique a un processus très normal et clair : vous faites la queue, commandez votre nourriture, attendez votre nourriture, mangez et partez. Maintenant, si nous traduisons cela en utilisant l’approche « agent », nous pouvons identifier au moins trois agents :

  • Agent Le client Il s'agit d'un agent LLM (Large Language Model) qui commande de la nourriture ou demande des suggestions au serveur.
  • Agent serveur Il s'agit d'un grand modèle de langage (LLM) qui collecte les demandes et fait des suggestions lorsque cela est nécessaire.
  • Agent Divertissement Il s'agit d'un grand modèle de langage (LLM) destiné à gérer les réclamations des clients.

Maintenant, OpenAI vous explique exactement comment créer ces entités, mais c'est la partie relativement facile ; Il y a bien plus que ça, n'est-ce pas ?

Nous devons mettre en œuvre le restaurant, et nous devons créer Méthode de la liste d'attente, où les gens s'assoient en fonction de l'affluence du restaurant, et nous devons créer ائمة الطعام, simulation وقت الانتظارet assurez-vous que tout fonctionne, ثم Seulement alors Nous pouvons connecter des agents. comme toujours:

 

L’IA générative est puissante, mais seulement lorsqu’elle est utilisée dans le bon contexte.

Alors, avant d'aborder la partie passionnante concernant les agents, dans cet article, vous verrez :

  1. Conception du système Pour agent de restauration LLM. Une idée sans code, juste un croquis du projet au stylo et au papier (ou plutôt à la souris et sur PowerPoint).
  2. Mise en œuvre d'un restaurant sans agent. Simple et direct, créez simplement la structure de base du code.
  3. Mise en œuvre de l'Agent Restaurant. De plus, une interface utilisateur graphique simple pour bien l'afficher.
  4. Considérations et observations finales.

On dirait que nous avons beaucoup de choses à couvrir. Au labo ! 🧪

1. Conception d'un système de restauration : guide de l'expert

Remarque : si vous avez effectué quelques visites techniques, vous trouverez la conception de ce système très simple. L'objectif de cette conception n'est pas de démontrer de manière exhaustive chaque partie d'un système d'apprentissage automatique (comme ils vous le demandent dans une interview de 15 minutes 🙃), mais simplement de fournir quelques indications sur ce que nous ferons ensuite.

La façon dont nous pouvons visualiser le processus de restauration, intégré à un grand modèle de langage (LLM), est résumée dans cette image :

Laissez-moi vous expliquer :

  • Restaurant() et Menu() Ce sont deux classes. Nous les définissons, et toutes les tables, commandes et informations système au sein des classes seront définies et mises à jour de manière dynamique.
  • devra Nouveau client Passer à travers un mécanisme d'assise. S'ils peuvent s'asseoir (assez de tables libres), c'est super, on peut les laisser s'asseoir ; Sinon, le client devra attendre en file (dans la file d'attente).
  • Pour le client le assisIl y aura un serveur pour leur permettre de commander de la nourriture. Ils peuvent se « plaindre » et demander combien de temps la nourriture prendra après avoir commandé.
  • Les gens ne peuvent pas faire la queue Ils font beaucoup de choses, mais ils peuvent aussi « se plaindre » et demander combien de temps ils devront attendre dans la file avant de pouvoir s’asseoir.

Maintenant, si vous y réfléchissez, vous n'êtes pas Avoir besoin à un grand modèle de langage (LLM) à cet effet. Par exemple, nous pouvons calculer le temps d’attente à l’avance, puis le connecter à une chaîne prédéfinie et formatée. Nous pouvons également utiliser un menu simple pour récupérer les commandes (comme le kiosque automatisé de McDonald's) et en finir. Bien sûr, nous pouvons le faire, mais réfléchissez-y.

Que faire si le client souhaite demander des informations sur le menu ? en attendant? Et s'ils l'étaient ? hésitant À propos de nourriture ? Et s’ils voulaient savoir ? L'option végétarienne la plus délicieuse Au menu ? Et s'ils le voulaient ? Du bon vin à un prix raisonnable? Nous pouvons soit commencer à définir des méthodes basées sur des règles pour chacun de ces scénarios, ce qui nous fait perdre du temps et de l’argent, soit commencer à utiliser l’IA. C'est de cela dont parle cet article. Si nous utilisons des agents de modèle de langage de grande taille (agents LLM), nous avons la possibilité de gérer tous ces scénarios en un seul passage.

Maintenant, si j’ai appris quelque chose, c’est que l’ingénierie logicielle doit être réalisée. Pas à pas. Tu ferais mieux d'avoir c'est عظمي Ajoutez ensuite à votre modèle des décorations et des accessoires. Pour cette raison, nous allons créer une version sans agent du produit ci-dessus. Cette version simplifiée comportera un système de file d'attente qui calcule les temps d'attente et exécute le menu, de sorte que tout se déroulera sans problème sans aucune IA. Après cette étape, nous pouvons placer les agents aux endroits dont nous avons discuté et montré ci-dessus (client, hôte et serveur).

2. Implémentation sans agent

Il est toujours préférable de simplifier tout autant que possible dans le script principal et de laisser les opérations complexes en arrière-plan. Notre implémentation sans agent peut être exécutée dans ce code.

importer aléatoire importer le temps importer les mathématiques importer sys depuis utils importer * depuis constantes importer * depuis naive_models importer * si __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)

Comme nous pouvons le voir, nous pouvons changer :

  • num_tables; Nombre de tables dans notre restaurant.
  • problème_d'arrivée; Il s'agit de la probabilité qu'un client arrive à chaque pas de temps.
  • tique; C'est le pas de temps de notre simulation.
  • pause; Il implémente la fonction time.sleep(), qui est utilisée pour simuler le flux de travail d'un vrai restaurant.

Maintenant, toute cette implémentation est réalisée dans un fichier. naive_models.py, existant ici.

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)

Alors c'est long, laissez-moi vous guider à travers quelques étapes.

L'ensemble du script s'exécute sur naive_sim à l'aide de la commande .Cours() Avec les fonctions suivantes :

  • arriver, qui représente l'arrivée et la demande des clients, ou leur arrivée et leur placement dans une file d'attente.
  • processus_cuisson, qui simule la cuisson de chaque table.
  • processus_départs, qui simule le départ du client.
  • siège_de_la_file_d'attente, qui simule des clients assis dans une file d'attente.
  • handle_random_query, qui est appelé de manière aléatoire, où un client en file d'attente ou en attente de sa nourriture peut demander le temps d'attente.

Si nous exécutons naive_sim.py, nous obtiendrons ceci à partir du terminal.

Il s’agit désormais d’un produit de science des données en soi. Vous pouvez gérer une chaîne de restaurants Monte Carlo avec cela, vous pouvez voir le potentiel de création d’une longue file d’attente, les restaurants peuvent utiliser ce « jumeau numérique » de leur restaurant et voir quand des choses critiques peuvent se produire. Maintenant que nous avons un produit fonctionnel, rendons-le plus beau et plus puissant en utilisant l'intelligence artificielle (IA).

3. Mise en œuvre du restaurant d'agent

Comme nous pouvons le voir ci-dessus, les clients peuvent déjà poser des questions, et nous avons la réponse sous forme de numéro. Le client choisit également un aliment au hasard dans notre système. Essayons maintenant d’ajouter des agents à ce système. L’activation d’un système d’agent de restaurant est une étape avancée dans l’automatisation du service client et l’amélioration de l’expérience utilisateur. Les agents formés peuvent répondre efficacement aux demandes des clients et fournir des recommandations personnalisées.

3.1 Mise en œuvre d'agents dédiés

Vous devrez installer le module « Agents » :

Vous trouverez ci-dessous la mise en œuvre de l'agent du service client, de l'agent de divertissement et du gestionnaire des plaintes.

# 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 = "Vous êtes un serveur serviable qui connaît tout de notre restaurant et qui aide les clients à choisir leur plat. Vous commencerez par vous présenter poliment" "en tant qu'assistant virtuel en restauration et par saluer poliment le client. Le nom du client se trouve dans le fichier json du message" "Vous lirez le menu et, en fonction des questions du client, dans la clé de requête du fichier json. " "Si le client vous pose des questions inappropriées, affichez simplement le format json 'unsuccessfull' '{food: , statut: }'", tools = [get_menu]) entertainer_agent = Agent(name = "Animateur", instructions = ("Vous êtes un serveur serviable qui garde les clients occupés pendant qu'ils attendent." "Vous ne pouvez pas proposer de réduction ou d'offre, mais ils peuvent poser des questions sur le menu, que vous pouvez obtenir grâce aux fonctions get_menu. Ils peuvent également vous demander combien de temps il y aura pour entrer. Leurs informations se trouvent dans le waiting_time." "Si le user_status est 'queue', indiquez simplement le temps avec gentillesse, en fonction de la durée d'attente. Sinon, si le user_status est 'food', cela signifie qu'ils attendent de la nourriture. Cochez 'order' et fournissez une référence amusante à leur temps d'attente. Par exemple, 'votre temps d'attente pour les pâtes est de 1 minutes, on dirait que le chef est en train de mettre de la sauce dessus !'", tools = [get_menu]) customer_agent = Agent(name = "Client", instructions = ("Vous êtes un client et vous mangez dans un restaurant italien. Regardez le menu en utilisant le Fonction get_menu. Si vous savez déjà ce que vous voulez, dites-le simplement au serveur. " "Sinon, donnez-leur une indication générale, ou demandez des conseils en fonction de vos préférences générales, et ils choisiront ce qu'ils ont de mieux pour vous."), 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, '')

Nous avons une définition Le client, qui est l'appel client d'OpenAI, et newtools.py, qui fait apparaître la liste, et appeler_agent qui appelle l'agent individuel et le fait fonctionner à travers coureur. Ces composants sont essentiels pour créer un système d’agent efficace.

C’est exactement ce dont nous avons parlé dans l’introduction. Nous identifions plusieurs وكلاء Ils seront connectés et ils utilisent Des outils Défini par mon code. Ces outils et agents vous permettent d’automatiser les tâches du service client et d’améliorer l’expérience utilisateur.

à partir des agents import function_tool à partir des constantes import * import pandas as pd @function_tool def get_menu(): df = pd.read_csv(MENU_FILE) # convertir en liste de dictionnaires (ou structure sérialisable JSON) return df.to_dict(orient="records")

3.2 Mise en œuvre d'agents dédiés

La mise en œuvre est intégrée lampe de table et Restaurant Avec les agents dans le code suivant :

 

importer aléatoire importer le temps importer les mathématiques importer sys depuis utils importer * depuis les constantes importer * importer le temps, aléatoire, json depuis custom_agents importer * depuis utils importer * depuis les constantes importer * depuis les agents importer Runner # liste des prénoms de votre constante NAMES # supposer que 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] ➡️ Attente estimée pour le client {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": None } output_llm = call_agent(class_agent="entertainer", runner = self.runner, msg = json.dumps(waiting_message)) msg ​​​​= f"Notre LLM s'est occupé de {cname} avec ceci : {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] ❓ Client {cid} : Combien de temps vais-je attendre avant de recevoir la nourriture ?
print(msg) self.log_to_msg(msg) si wait est None : msg = f"[{self.clock:04}m] ➡️ Prêt maintenant !"
print(msg) self.log_to_msg(msg) else: msg = f"[{self.clock:04}m] ➡️ Temps d'attente estimé pour le client {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"Notre LLM s'est occupé de {cname} avec ceci : {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() si self.query_prob et 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() free = sum(t.is_free for t in self.tables) msg = f"n--- FIN DE QUART ---n{free}/{len(self.tables)} tables libres à {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 Implémentation d'une interface utilisateur graphique (GUI) pour un restaurant à l'aide d'un modèle de langage étendu (LLM)

Pour afficher les performances du restaurant avec une application de modèle de langage volumineux (LLM), nous utiliserons une interface utilisateur graphique (GUI) simple.

de llm_models_gui importer RestaurantGUI de utils importer * importer aléatoire de llm_models importer Restaurant si __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=1.0, # plus fluide pour l'interface graphique query_prob=0.8, menu=menu ) app = RestaurantGUI(R)

L'interface utilisateur graphique (GUI) vous fournit des informations sur la personne (Emma), la table, l'heure et la sortie du grand modèle de langage (LLM). Un enregistrement .txt est également créé automatiquement.

Laissez-moi vous montrer un exemple de sortie :

[12:31:23] La cliente Emma s'adresse au serveur et lui dit : « Je voudrais commencer par la bruschetta en entrée. Ensuite, je commanderai les spaghettis carbonara en entrée. En dessert, je me régalerai avec le tiramisu. Auriez-vous également des suggestions de vins pour accompagner ce plat ? » [12:31:25] La réponse traitée de notre étudiant en master est : {'food': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'status': 'successful'} [12:31:25] [0000M] ❓ Client 1 : Combien de temps me faudra-t-il pour préparer la nourriture ? [12:31:25] [0000M] ➡️ Temps d'attente prévu pour la nourriture pour le client 1:15 minutes [12:31:26] L'étudiant LLM s'est occupé de la commande d'Emma : Dernier client : Agent(name=”Entertainer”, …) Résultat final (string) : Salut Emma ! Merci pour votre patience. Le temps d'attente pour entrer est d'environ 15 minutes. Nous y sommes presque - juste assez de temps pour que je commence à rêver de cette délicieuse bruschetta ! ???? ️

Nous pouvons vous proposer :

  1. Le client crée son propre menu par l'intermédiaire de l'agent.et demande une recommandation à l'agent du serveur.
  2. Le serveur recommande un vin Chianti et l'ajoute à la carte.
  3. L'agent de traitement des réclamations informe le client du délai d'attente.

Maintenant, nous ne pouvons pas simplement simuler un flux de travail, comme nous le faisions auparavant, nous avons un flux de travail. Intelligent, alimenté par la même technologie ChatGPT. N'est-ce pas génial ?

 

4.Conclusion

Merci beaucoup d'être venu, cela signifie beaucoup pour moi ❤️.
Revenons en arrière et voyons ce que nous avons fait dans cet article.

  1. Conception du système de restauration:
    Nous avons créé une conception rapide pour un système de restauration en utilisant PowerPoint avec l'ajout d'agents IA.
  2. Base sans agent :
    Nous avons d’abord construit une simulation déterministe afin de pouvoir coder la logique de la file d’attente, des temps de cuisson et de la rotation des tables. Voici notre squelette avant de faire une IA.
  3. Restaurant basé sur un agent :
    À ce stade, nous avons utilisé des agents d’IA pour remplir notre dossier de plainte + action avec des agents. Nous avons également créé une interface utilisateur graphique pour afficher clairement les résultats.

Maintenant, à ce stade, je veux être très clair. Je sais que cela ressemble un peu à Black Mirror. Simulation client ? Simulation de restaurant et de serveur ? Oui, c'est bizarre, ولكن Le problème n’est jamais l’outil d’IA, mais toujours la manière dont il est utilisé. Je pense que remplacer les serveurs humains par l’IA est un jeu perdu d’avance.

Être serveur ne consiste pas simplement à prendre des commandes et à recommander le vin numéro N en fonction des N-1 vins qui ont été commandés auparavant. Il s'agit d'être suffisamment chaleureux pour qu'un invité se sente le bienvenu, mais suffisamment distant pour ne pas interférer dans sa conversation, suffisamment doux pour qu'il se sente chez lui, mais suffisamment fort pour qu'il respecte vos limites. C'est une combinaison de qualités qui, selon moi, nécessitent une touche humaine, de la patience et de l'empathie.

Cependant, je crois que l’utilisation correcte de cette technologie peut être double :

  1. Aider les vraies personnes qui sont sur la liste d’attente. Les serveurs à l'intérieur sont très occupés, et les restaurants fournissent déjà un menu que vous pouvez consulter pendant que vous attendez votre table, et il n'est pas réaliste de penser que d'autres serveurs divertissent les gens qui attendent sans table. À ce stade, un compagnon IA avec qui discuter peut être utile.
  2. Simulation de restaurant. Le scénario que j'ai écrit simule Comportement Les clients aussi. Cela signifie que vous pouvez potentiellement utiliser des simulations pour tester différents scénarios, voir quand les files d'attente se forment, supposer différentes réactions des personnes, différentes réponses des serveurs, etc. En d'autres termes, cela peut être votre « jumeau numérique » sur lequel vous exécutez des tests.

 

 

Les commentaires sont fermés.