Simulación de restaurantes multiagente utilizando modelos de lenguaje grandes (LLM) en la práctica, con Python y OpenAI

Así es como utilicé agentes de modelos de lenguaje grandes para simular una operación de restaurante de extremo a extremo, utilizando Python.

La semana pasada, OpenAI publicó un archivo (PDF)Y todo el mundo habla de ello. Este archivo es una guía de 34 páginas que explica qué son los Agentes de Modelos de Lenguaje Grandes (Agentes LLM) y cómo utilizarlos.

El PDF es relativamente corto y fácil de leer también (no es necesario ser un ingeniero de software o mentor para entenderlo), pero en pocas palabras explica tres cosas:

.1. Agentes de modelos de lenguaje grandes (agentes LLM) “Son sistemas que completan tareas de forma independiente en su nombre”.

Entonces, ¿no son estas simplemente simples llamadas a modelos de lenguaje grandes (LLM) llamados a través de una API? Bueno, sí y no. Estás usando los mismos formularios de finalización de conversación, por lo que es algo así como... Pero Se pretende crear una acción específica. Lo que quiero decir con esto es que la producción de sus agentes... Debe traducirse a una salida ejecutable. En su sistema. Por ejemplo, si la salida de su LLM dice “espaguetis”, se agregará “espaguetis” a su ruta de datos y, eventualmente, alguien lo verá y cocinará espaguetis (alerta).

2. Los agentes de modelos de lenguaje grandes (agentes LLM) están integrados específicamente con Funciones (Herramientas)

Me refiero al escenario en el que le haces una pregunta a ChatGPT y este invoca su propio generador de imágenes/buscador web/fragmento de código. Utiliza internamente una función llamada widget, que se activa cuando se le solicita. Ahora, el generador de imágenes es una función incorporada, pero también pueden llamar Tu trabajo (tu herramienta), que puede especificar específicamente para su tarea. Esta capacidad de integrar herramientas y funcionalidades externas es lo que brinda a los agentes LLM gran flexibilidad y poder para realizar una variedad de tareas.

 

3. Se pueden integrar varios agentes de modelos de lenguaje grandes (agentes LLM). Consecutivo

Puede integrar un único agente y proporcionarle múltiples herramientas. أو Dividir las herramientas en agentes especializados, que es lo que haremos en este artículo (¡otra pista!).

Los detalles técnicos pueden ser de interés para los ingenieros de software, pero ¿por qué este tema de los agentes es tan importante para todos los demás?
Bueno, porque esto representa un cambio de paradigma que ayuda a dar utilidad a los modelos de IA abierta. Piénselo: ahora los grandes modelos de lenguaje (LLM) proporcionan Resultados procesables. Por lo tanto, no se trata de utilizar indicaciones LLM en el último paso del flujo de trabajo para mejorar el resultado final; Más bien, se trata de Integración de todo el flujo de trabajo con agentes de modelos de lenguaje grandes (agentes LLM) Para mejorar la calidad de todo el flujo de trabajo.

Aunque estoy intentando explicarlo con palabras, creo que es más fácil mostrártelo en la práctica. Digamos que estamos hablando de restaurante, por ejemplo.

Un restaurante típico tiene un proceso muy normal y claro: esperas en la cola, pides tu comida, esperas tu comida, comes y te vas. Ahora bien, si traducimos esto utilizando el enfoque del “agente”, podemos identificar al menos tres agentes:

  • agente Cliente Es un agente de modelo de lenguaje grande (LLM) que ordena comida o pide sugerencias al camarero.
  • agente النادل Es un modelo de lenguaje grande (LLM) que recoge solicitudes y hace sugerencias cuando es necesario.
  • agente Entretenimiento Es un modelo de lenguaje grande (LLM) orientado a gestionar las quejas de los clientes.

Ahora, OpenAI te dice exactamente cómo construir estas entidades, pero esa es la parte relativamente fácil; Hay mucho más que eso, ¿no?

Necesitamos implementar el restaurante, y necesitamos crear Método de lista de espera, donde la gente se sienta en función de lo lleno que esté el restaurante, y necesitamos crear Menusimulación وقت الانتظارy asegúrese de que todo esté funcionando, Entonces Sólo entonces Podemos conectar agentes. como siempre:

 

La IA generativa es poderosa, pero solo cuando se utiliza en el contexto adecuado.

Entonces, antes de llegar a la parte emocionante sobre los agentes, en este artículo verás:

  1. Diseño de sistemas Para Agente de Restaurantes LLM. Una idea sin código, sólo un boceto del proyecto en lápiz y papel (o más bien, ratón y PowerPoint).
  2. Implementación de restaurante sin agente. Simple y directo, simplemente crea la estructura básica del código.
  3. Implementación del Agente Restaurante. Además de una interfaz gráfica de usuario sencilla para mostrarlo bien.
  4. Consideraciones y observaciones finales.

Parece que tenemos mucho que cubrir. ¡Al laboratorio! 🧪

1. Diseño de sistemas de restaurantes: una guía experta

Nota: Si ha realizado algunos recorridos técnicos, encontrará que el diseño de este sistema es muy fácil. El objetivo de este diseño no es demostrar exhaustivamente cada parte de un sistema de aprendizaje automático (como te piden en una entrevista de 15 minutos 🙃), sino simplemente brindar algo de orientación sobre lo que haremos a continuación.

La forma en que podemos visualizar el proceso del restaurante, integrado con un gran modelo de lenguaje (LLM), se resume en esta imagen:

Déjame explicarte:

  • Restaurante()yMenú() Son dos clases. Los definimos y todas las tablas, órdenes e información del sistema dentro de las clases se definirán y actualizarán dinámicamente.
  • tendrá que Nuevo cliente Pasar a través de un mecanismo de asiento. Si pueden sentarse (hay suficientes mesas libres), genial, podemos dejarlos sentarse; De lo contrario, el cliente tendrá que esperar en la cola.
  • Para el cliente el sentadoHabrá un camarero que les permitirá pedir comida. Pueden “quejarse” y preguntar cuánto tiempo tardará la comida después de ordenarla.
  • La gente no puede esperando en la fila Hacen muchas cosas, pero también pueden “quejarse” y preguntar cuánto tiempo tendrán que esperar en la fila antes de poder sentarse.

Ahora, si lo piensas, no lo eres. Necesitar a un modelo de lenguaje grande (LLM) para este propósito. Por ejemplo, podemos calcular el tiempo de espera con antelación y luego conectarlo a una cadena formateada predefinida. También podemos utilizar un menú sencillo para recoger pedidos (como el quiosco automático de McDonald's) y listo. Claro que podemos hacerlo, pero piénsalo.

¿Qué pasa si el cliente quiere pedir información sobre el menú? mientras espera? ¿Y si así fuera? vacilante ¿Y qué hay de la comida? ¿Y si quisieran saber? La opción vegetariana más deliciosa. ¿En el menú? ¿Y si quisieran? Buen vino a un precio razonable.? Podemos empezar a definir métodos basados ​​en reglas para cada uno de estos escenarios, desperdiciando nuestro tiempo y dinero, o podemos empezar a utilizar inteligencia artificial. De eso trata este artículo. Si utilizamos agentes de modelos de lenguaje grandes (agentes LLM), tenemos la oportunidad de manejar todos estos escenarios en una sola pasada.

Ahora bien, si algo he aprendido es que la ingeniería de software es algo que hay que hacer. Paso a paso. Será mejor que lo tengas esqueleto A continuación, añade a tu modelo decoraciones y accesorios. Por este motivo, crearemos una versión sin agente del producto mencionado anteriormente. Esta versión simplificada contará con un sistema de colas que calcula los tiempos de espera y ejecuta el menú, por lo que todo funcionará sin problemas sin ninguna IA. Luego de este paso, podemos colocar a los agentes en los lugares que comentamos y mostramos anteriormente (cliente, anfitrión y mesero).

2. Implementación sin agente

Siempre es mejor simplificar todo lo posible en el script principal y dejar las operaciones complejas en segundo plano. Nuestra implementación sin agente se puede ejecutar en este código.

importar aleatorio importar tiempo importar matemáticas importar sistema desde utilidades importar * desde constantes importar * desde modelos_ingenuos importar * si __nombre__ == "__principal__": aleatorio.semilla(42) menú = preproceso_menú(ARCHIVO_MENÚ, factor_tiempo_comer=0.5) R = Restaurante( núm_mesas=2, probabilidad_llegada=0.7, duración_ticket=1, pausa_real=5.0, probabilidad_consulta=0.4, menú=menú ) R.ejecutar(tiempo_total=60)

Como podemos ver, podemos cambiar:

  • num_tablas; Número de mesas en nuestro restaurante.
  • probabilidad de llegada; Es la probabilidad de que un cliente llegue en cada paso de tiempo.
  • garrapata; Es el paso de tiempo de nuestra simulación.
  • pausa; Implementa la función time.sleep(), que se utiliza para simular el flujo de trabajo de un restaurante real.

Ahora, toda esta implementación se realiza en un archivo. modelos_ingenuos.py, existente aquí.

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)

Bueno, esto es largo, déjame explicarte algunos pasos.

Todo el script se ejecuta en naive_sim usando el comando .correr() Con las siguientes funciones:

  • llegar, que representa la llegada y solicitud de clientes, o bien su llegada y colocación en una cola.
  • proceso_cocción, que simula la cocción de cada mesa.
  • proceso_salidas, que simula la salida del cliente.
  • asiento_de_la_cola, que simula a los clientes sentados en la fila.
  • manejar consulta aleatoria, que se llama de forma aleatoria, donde un cliente en la fila o esperando su comida puede preguntar sobre el tiempo de espera.

Si ejecutamos naive_sim.py, obtendremos esto desde la terminal.

Ahora bien, este es en sí mismo un producto de ciencia de datos. Puedes gestionar una cadena de Montecarlo con esto, puedes ver el potencial de que se cree una larga cola, los restaurantes pueden usar este “gemelo digital” de su restaurante y ver cuándo pueden suceder cosas críticas. Ahora que tenemos un producto funcional, hagámoslo más atractivo y potente utilizando inteligencia artificial (IA).

3. Implementación del restaurante del agente

Como podemos ver arriba, los clientes ya pueden hacer preguntas y tenemos la respuesta en forma de número. El cliente también elige una comida al azar en nuestro sistema. Ahora intentemos agregar agentes a este sistema. La activación de un sistema de agente de restaurante es un paso avanzado para automatizar el servicio al cliente y mejorar la experiencia del usuario. Los agentes capacitados pueden responder eficazmente las consultas de los clientes y brindar recomendaciones personalizadas.

3.1 Implementación de agentes dedicados

Necesitarás instalar el módulo “Agentes”:

A continuación se muestra la implementación del agente de servicio al cliente, el agente de entretenimiento y el manejador de quejas.

# 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 = "Eres un camarero servicial que conoce todo sobre nuestro restaurante y ayuda a los clientes a elegir su comida. Empezarás presentándote cortésmente como asistente virtual de cocina y saludando amablemente al cliente. El nombre del cliente se encuentra en el archivo json msg. Leerás el menú y, según las preguntas del cliente, en la clave de solicitud del archivo json, ofrecerás la mejor recomendación del menú. Si el cliente te hace preguntas inapropiadas, simplemente imprime 'unsuccessfull' en formato json '{food: , estado: }'", tools = [get_menu]) entertainer_agent = Agent(name = "Entertainer", instructions = ("Eres un camarero servicial que mantiene a los clientes ocupados mientras esperan." "No puedes ofrecer ningún descuento ni oferta, pero pueden hacer preguntas sobre el menú, que puedes obtener de las" "funciones get_menu. También pueden preguntarte cuánto tiempo va a durar la cola para entrar. Su información está en waiting_time" "Si el user_status es 'queue', simplemente proporciona el tiempo con amabilidad, en función de la duración de la espera. De lo contrario, " "si el user_status es 'food' significa que están esperando comida. Marca 'order' y proporciona una referencia divertida sobre" "su tiempo de espera. Por ejemplo, '¡tu tiempo de espera para la pasta es de 1 minutos, parece que el chef le está poniendo salsa!'", tools = [get_menu]) customer_agent = Agent(name = "Customer", instructions = ("Eres un cliente y estás comiendo en un restaurante italiano. Mira el menú usando La función get_menu. Si ya sabes lo que quieres, simplemente dile al camarero qué deseas. "De lo contrario, dales una indicación general o pídeles orientación según tus preferencias y elegirán lo mejor para ti.")

Tenemos una definición Cliente, que es la llamada del cliente de OpenAI, y nuevasherramientas.py, que muestra la lista, y agente de llamada que llama al agente individual y lo opera a través de corredor. Estos componentes son esenciales para crear un sistema de agentes eficaz.

Esto es exactamente lo que hablamos en la introducción. Identificamos varios وكلاء Estarán conectados y estarán usando Herramientas Definido por mi código. Estas herramientas y agentes le permiten automatizar las tareas de atención al cliente y mejorar la experiencia del usuario.

de agentes importar function_tool de constantes importar * importar pandas como pd @function_tool def get_menu(): df = pd.read_csv(MENU_FILE) # convertir a lista de diccionarios (o estructura serializable en JSON) devolver df.to_dict(orient="records")

3.2 Implementación de agentes dedicados

La implementación está integrada TablayRestaurante Con agentes en el siguiente código:

 

importar aleatorio importar tiempo importar matemáticas importar sistema desde utilidades importar * desde constantes importar * importar tiempo, aleatorio, json desde agentes_personalizados importar * desde utilidades importar * desde constantes importar * desde agentes importar Runner # lista de nombres de su constante NOMBRES # suponga que NOMBRES = [ ... ] 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] ➡️ Espera estimada para el cliente {cid}: {wait}m" print(msg) self.log_to_msg(msg) mensaje_de_espera = { "id_cliente": cid, "nombre_cliente": cname, "tipo": "línea", "min_espera": esperar, "siguiente_comida": Ninguno } output_llm = call_agent(class_agent="entertainer", runner = self.runner, msg = json.dumps(mensaje_de_espera)) msg ​​​​= f"Nuestro LLM se encargó de {cname} con esto: {output_llm}" print(msg) self.log_to_msg(msg) elif ids_sentados: cid = random.choice(ids_sentados) esperar = self.estimate_food_time(cid) table = next(t for t in self.tables if t.cust_id == cid) comida = mesa.plato cname = self.names[cid] msg = f"[{self.clock:04}m] ❓ Cliente {cid}: ¿Cuánto tiempo me llevará la comida?”
print(msg) self.log_to_msg(msg) si la espera es Ninguna: msg = f"[{self.clock:04}m] ➡️ ¡Listo ahora!"
print(msg) self.log_to_msg(msg) else: msg = f"[{self.clock:04}m] ➡️ Tiempo estimado de espera de comida para el cliente {cid}: {wait}m" print(msg) self.log_to_msg(msg) mensaje_de_espera = { "id_cliente": cid, "nombre_cliente": cname, "tipo": "línea", "min_espera": esperar, "siguiente_comida": comida } output_llm = call_agent(class_agent="entertainer", runner = self.runner, msg = json.dumps(mensaje_de_espera)) msg = f"Nuestro LLM se encargó de {cname} con esto: {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 y aleatorio.random() < self.query_prob: self.handle_random_query() self.clock += self.tick time.sleep(self.pause) def run(self, tiempo_total): mientras self.clock < tiempo_total: self.tick_once() libre = suma(t.está_libre para t en self.tablas) msg = f"n--- FIN DEL TURNO ---n{libre}/{len(self.tablas)} mesas libres a las {self.clock}m."
print(msg) self.log_to_msg(msg) if __name__ == "__main__": random.seed(42) menu = preprocess_menu(MENU_FILE, factor_tiempo_comida=0.5) R = Restaurant( núm_mesas=5, probabilidad_llegada=0.7, duración_ticket=1, pausa_real=5.0, probabilidad_consulta=0.8, menu=menu ) R.run(tiempo_total=60)

3.3 Implementación de una interfaz gráfica de usuario (GUI) para un restaurante utilizando un modelo de lenguaje grande (LLM)

Para mostrar el rendimiento del restaurante con una aplicación de modelo de lenguaje grande (LLM), utilizaremos una interfaz gráfica de usuario (GUI) simple.

de llm_models_gui importar RestaurantGUI de utils importar * importar aleatorio de llm_models importar Restaurant si __name__ == "__main__": random.seed(42) menú = preprocess_menu(MENU_FILE, eat_time_factor=0.5) R = Restaurant( num_tables=5, arrived_prob=0.7, tick_length=1, real_pause=1.0, # más suave para GUI query_prob=0.8, menu=menu ) aplicación = RestaurantGUI(R)

La interfaz gráfica de usuario (GUI) le proporciona información sobre la persona (Emma), la tabla, la hora y la salida del modelo de lenguaje grande (LLM). También se crea automáticamente un registro .txt.

Permítame mostrarle un ejemplo del resultado:

[12:31:23] La clienta Emma le dice al camarero: «Me gustaría empezar con la bruschetta como entrante. Después pediré los espaguetis a la carbonara como primer plato. De postre, disfrutaré del tiramisú. ¿Podría sugerirme también un vino para maridar con este plato?» [12:31:25] La respuesta procesada de nuestro estudiante de maestría es: {'food': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'status': 'successful'} [12:31:25] [0000M] ❓ Cliente 1: ¿Cuánto tiempo me llevará preparar la comida? [12:31:25] [0000M] ➡️ Tiempo de espera esperado para la comida del cliente 1:15 minutos [12:31:26] El estudiante de LLM se hizo cargo del pedido de Emma: Último cliente: Agente (nombre = "Entertainer", …) Resultado final (cadena): ¡Hola Emma! Gracias por su paciencia. El tiempo de espera para entrar es de unos 15 minutos. Ya casi estamos allí, ¡tiempo justo para empezar a soñar con esa deliciosa bruschetta! ???? ️

Podemos ofrecer:

  1. El cliente crea su propio menú a través del agente.y solicita una recomendación del agente del camarero.
  2. El camarero recomienda un vino Chianti y lo añade a la lista.
  3. El agente de atención de reclamaciones informa al cliente del periodo de espera.

Ahora, no podemos simplemente simular un flujo de trabajo, como lo hacíamos antes, tenemos un flujo de trabajo. Inteligente, impulsado por la misma tecnología ChatGPT. ¿No es eso genial?

 

4. Conclusión

Muchas gracias por venir, significa mucho para mí ❤️.
Volvamos atrás y veamos lo que hicimos en este artículo.

  1. Diseño de sistemas de restaurantes:
    Creamos un diseño rápido para un sistema de restaurante usando PowerPoint con la incorporación de agentes de IA.
  2. Base sin agente:
    Primero construimos una simulación determinista para poder codificar la lógica de la cola, los tiempos de cocción y la rotación de las mesas. Este es nuestro esqueleto antes de hacer cualquier IA.
  3. Restaurante basado en agentes:
    En esta etapa, utilizamos agentes de IA para completar nuestro caso de queja + acción con agentes. También creamos una interfaz gráfica de usuario para mostrar claramente los resultados.

Ahora, en este punto, quiero ser muy claro. Sé que esto suena un poco a Black Mirror. ¿Simulación de clientes? ¿Simulación de restaurante y camarero? Sí, es raro. Pero El problema nunca es la herramienta de IA, sino siempre cómo se utiliza. Creo que reemplazar a los camareros humanos con IA es un juego perdido.

Ser camarero no consiste simplemente en tomar pedidos y recomendar el vino número N en función de los N-1 vinos que se han pedido anteriormente. Se trata de ser lo suficientemente cálido para hacer que un invitado se sienta bienvenido pero lo suficientemente distante para no interferir en su conversación, lo suficientemente amable para hacerlo sentir como en casa pero lo suficientemente fuerte para hacerlo respetar sus límites. Es una combinación de cualidades que creo que requieren un toque humano, paciencia y empatía.

Sin embargo, creo que el uso correcto de esta tecnología puede ser doble:

  1. Ayudando a personas reales que están en la lista de espera. Los camareros dentro están muy ocupados, y los restaurantes ya proporcionan un menú para que lo mires mientras esperas tu mesa, y no es realista pensar que otros camareros estén entreteniendo a personas que esperan sin mesa. En este punto, puede resultar útil contar con un compañero de IA para charlar.
  2. Simulación de restaurante. El escenario que escribí simula Comportamiento Cliente también. Esto significa que, potencialmente, puedes usar simulaciones para probar diferentes escenarios, ver cuándo se forman colas, asumir diferentes reacciones de las personas, diferentes respuestas de los camareros, etc. En otras palabras, este puede ser tu "gemelo digital" donde ejecutas pruebas.

 

 

Los comentarios están cerrados.