Simulação de restaurante multiagente usando modelos de linguagem grande (LLM) na prática, com Python e OpenAI
Veja como usei Large Language Model Agents para simular uma operação de restaurante de ponta a ponta, usando Python.
Na semana passada, a OpenAI lançou um arquivo PDF que está dando o que falar. Trata-se de um guia de 34 páginas que explica o que são Agentes de Modelo de Linguagem Ampla (Agentes LLM) e como utilizá-los.
O PDF é relativamente curto e fácil de ler (você não precisa ser um engenheiro de software/mentor para entendê-lo), mas em poucas palavras ele explica três coisas:

1. Agentes de Modelo de Linguagem Ampla (Agentes LLM) “são sistemas que executam tarefas de forma independente em seu nome”.
Então, não são apenas prompts simples do Big Language Model (LLM) chamados via API? Bem, sim e não. Você está usando o(s) mesmo(s) modelo(s) de conclusão de conversa, então é algo parecido, mas o objetivo é criar uma ação específica. O que quero dizer é que a saída do seu proxy precisa ser traduzida em uma saída executável no seu sistema. Por exemplo, se a saída do LLM disser "espaguete", então "espaguete" será adicionado ao seu caminho de dados e, eventualmente, alguém verá isso e cozinhará espaguete (alerta).
2. Os agentes de Modelo de Linguagem Amplo (LLM) são particularmente integrados com funções (ferramentas).
Estou me referindo aqui ao cenário em que você faz uma pergunta ao ChatGPT e ele aciona seu construtor de imagens/buscador de sites/trecho de código. Internamente, ele usa uma função chamada widget, que é acionada pela sua solicitação. O construtor de imagens é uma função integrada, mas também é possível acionar um widget personalizado , que você pode especificar para a sua tarefa. Essa capacidade de integrar widgets e funções externas é o que confere aos Agentes de Modelo de Linguagem Amplo (Agentes LLM) tanta flexibilidade e poder para executar uma grande variedade de tarefas.
3. Muitos agentes de modelo de linguagem de grande porte (agentes LLM) podem ser combinados sequencialmente.
Você pode combinar um único agente e equipá-lo com várias ferramentas ou dividir as ferramentas em agentes especializados, que é o que faremos neste artigo (mais uma dica!).
Os detalhes técnicos podem ser de interesse para engenheiros de software, mas por que esse tópico de agentes é tão importante para todos os outros?
Bem, porque isso representa uma mudança de paradigma que ajuda a fornecer utilidade aos modelos de IA aberta. Pense nisso: agora os grandes modelos de linguagem (LLMs) fornecem Resultados acionáveis. Portanto, não se trata de usar prompts de LLM na última etapa do fluxo de trabalho para melhorar o resultado final; Em vez disso, trata-se de Integração de todo o fluxo de trabalho com agentes de modelos de linguagem grandes (Agentes LLM) Para melhorar a qualidade de todo o fluxo de trabalho.
Embora eu esteja tentando explicar com palavras, acho que é mais fácil ilustrar na prática. Digamos que estejamos falando de um restaurante, por exemplo.
Um restaurante típico tem um processo muito normal e claro: você espera na fila, pede sua comida, espera pela comida, come e vai embora. Agora, se traduzirmos isso usando a abordagem do “agente”, podemos identificar pelo menos três agentes:
- agente Cliente É um agente de Large Language Model (LLM) que pede comida ou pede sugestões ao garçom.
- agente garçom É um grande modelo de linguagem (LLM) que coleta solicitações e faz sugestões quando necessário.
- agente Entretenimento É um modelo de linguagem de grande porte (LLM) que visa lidar com reclamações de clientes.
Agora, o OpenAI diz exatamente como construir essas entidades, mas essa é a parte relativamente fácil; Tem muito mais, não é mesmo?
Precisamos implementar o restaurante , criar um sistema de filas onde as pessoas se sentam de acordo com o movimento do restaurante, criar o cardápio , simular os tempos de espera e garantir que tudo funcione. Só então poderemos conectar os agentes. Como sempre:
A IA generativa é poderosa, mas somente quando usada no contexto certo.
Então, antes de chegarmos à parte interessante sobre agentes, neste artigo você verá:
- Projeto de Sistema Para agente de restaurantes LLM. Uma ideia sem código, apenas um esboço do projeto com caneta e papel (ou melhor, mouse e PowerPoint).
- Implementação de restaurante sem agente. Simples e direto, basta criar a estrutura básica do código.
- Implementação do Agent Restaurant. Além de uma interface gráfica de usuário simples para exibi-lo bem.
- Considerações e observações finais.
Parece que temos muito a cobrir. Para o laboratório! 🧪
1. Design de sistemas de restaurantes: um guia especializado
Nota: Se você já fez alguns tours técnicos, verá que o design deste sistema é muito fácil. O objetivo deste design não é demonstrar de forma abrangente todas as partes de um sistema de aprendizado de máquina (como perguntam em uma entrevista de 15 minutos 🙃), mas simplesmente fornecer alguma orientação sobre o que faremos a seguir.
A maneira como podemos visualizar o processo do restaurante, integrado a um modelo de grande linguagem (LLM), está resumida nesta imagem:

Deixe-me explicar:
- Restaurante() و Menu() São duas classes. Nós os definimos, e todas as tabelas, pedidos e informações do sistema dentro das classes serão definidas e atualizadas dinamicamente.
- terá que Novo cliente Passar por um mecanismo de assento. Se eles puderem sentar (mesas livres suficientes), ótimo, podemos deixá-los sentar; Caso contrário, o cliente ficará na fila (na fila).
- Para o cliente o sentadoHaverá um garçom para que eles possam pedir comida. Eles podem “reclamar” e perguntar quanto tempo a comida vai demorar para ficar pronta depois de fazer o pedido.
- As pessoas não podem esperando na fila Eles fazem muita coisa, mas também podem “reclamar” e perguntar quanto tempo terão que esperar na fila antes de poderem se sentar.
Agora, pensando bem, não precisamos de um modelo de linguagem complexo (LLM) para isso. Por exemplo, poderíamos calcular o tempo de espera antecipadamente e associá-lo a uma string estruturada predefinida. Também poderíamos usar uma lista de pedidos simples (como em um totem de autoatendimento do McDonald's) e pronto. Claro, poderíamos fazer isso, mas reflita.
E se um cliente quiser perguntar sobre o cardápio enquanto espera ? E se estiver indeciso sobre o que pedir? E se quiser saber qual a melhor opção vegetariana ? E se quiser um bom vinho a um preço razoável ? Podemos começar a definir métodos baseados em regras para cada um desses cenários, desperdiçando tempo e dinheiro, ou podemos começar a usar inteligência artificial. É sobre isso que este artigo trata. Se usarmos Agentes de Modelo de Linguagem Ampla (Agentes LLM), teremos a oportunidade de lidar com todos esses cenários de uma só vez.
Agora, se você aprendeu alguma coisa, é que a engenharia de software deve ser feita passo a passo . O ideal é ter a estrutura básica do seu modelo primeiro e, em seguida, adicionar os retoques finais e os aprimoramentos. Por esse motivo, construiremos uma versão sem agentes do produto acima. Essa versão simplificada terá um sistema de filas que calcula os tempos de espera e executa o menu, de modo que tudo funcionará perfeitamente sem qualquer inteligência artificial. Após essa etapa, podemos posicionar os agentes nas funções que discutimos e demonstramos acima (cliente, anfitrião e garçom).
2. Implementação sem agente
É sempre melhor simplificar tudo o máximo possível no script principal e deixar as operações complexas em segundo plano. Nossa implementação do Agent Free pode ser executada neste código.
importar aleatório importar tempo importar matemática importar sistemas de utilitários importar * de constantes importar * de modelos ingênuos importar * se __nome__ == "__principal__": random.seed(42) menu = preprocess_menu(MENU_FILE, eat_time_factor=0.5) R = Restaurante( num_tables=2, probabilidade_de_chegada=0.7, comprimento_de_tique-taque=1, pausa_real=5.0, probabilidade_de_consulta=0.4, menu=menu ) R.run(tempo_total=60)
Como podemos ver, podemos mudar:
- num_tabelas; Número de mesas em nosso restaurante.
- problema_de_chegada; É a probabilidade de um cliente chegar em cada intervalo de tempo.
- carrapato; É o passo de tempo da nossa simulação.
- pausa; Ele implementa a função time.sleep(), que é usada para simular o fluxo de trabalho de um restaurante real.
Agora, toda essa implementação é feita no arquivo naive_models.py , localizado aqui.
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)
Então, isso é longo. Deixe-me explicar alguns passos.
O script completo é executado em naive_sim usando o comando .run() com as seguintes funções:
- chegar, que representa a chegada e solicitação de clientes, ou sua chegada e colocação em uma fila.
- processo_de_cozimento, que simula o cozimento de cada mesa.
- partidas_processadas, que simula a saída do cliente.
- assento_da_fila, que simula clientes sentados em uma fila.
- manipular_consulta_aleatória, que é chamado de aleatório, onde um cliente na fila ou esperando sua comida pode perguntar sobre o tempo de espera.
Se executarmos naive_sim.py, obteremos isso do terminal.

Agora, este é um produto de ciência de dados por si só. Você pode administrar uma rede de Monte Carlo com isso, você pode ver o potencial para uma longa fila ser criada, os restaurantes podem usar esse “gêmeo digital” do seu restaurante e ver quando coisas críticas podem acontecer. Agora que temos um produto funcional, vamos torná-lo mais bonito e poderoso usando inteligência artificial (IA).
3. Implementação do Restaurante Agente
Como podemos ver acima, os clientes já podem fazer perguntas, e temos a resposta como um número. O cliente também escolhe um alimento aleatório em nosso sistema. Agora vamos tentar adicionar agentes a este sistema. Ativar um sistema de agente de restaurante é um passo avançado para automatizar o atendimento ao cliente e melhorar a experiência do usuário. Agentes treinados podem responder com eficiência às dúvidas dos clientes e fornecer recomendações personalizadas.
3.1 Implementação de agentes dedicados
Você precisará instalar o módulo “Agentes”:
Abaixo está a implementação do agente de atendimento ao cliente, agente de entretenimento e manipulador de reclamações.
# 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 = "Você é um garçom prestativo que sabe tudo sobre nosso restaurante e está ajudando o cliente a escolher sua comida. Você começará se apresentando educadamente como um assistente virtual de comida e cumprimentando o cliente educadamente. O nome do cliente pode ser encontrado no arquivo msg json. Você lerá o menu e, com base no que o cliente estiver perguntando, na chave de solicitação do arquivo json, fornecerá a melhor recomendação do menu. Se o cliente estiver fazendo perguntas inadequadas, basta exibir 'unsuccessfull' no formato json '{food: , status: }'", tools = [get_menu]) entertainer_agent = Agent(name = "Entertainer", instructions = ("Você é um garçom prestativo que mantém os clientes ocupados enquanto esperam." "Você não pode oferecer nenhum desconto ou oferta, mas eles podem fazer perguntas sobre o cardápio, que você pode obter nas funções get_menu. Eles também podem perguntar quanto tempo vai demorar na fila para entrar. As informações deles estão no waiting_time" "Se o user_status for 'queue', informe o tempo com gentileza, com base no tempo de espera. Caso contrário, se o user_status for 'food', significa que eles estão esperando comida. Marque 'order' e forneça uma referência engraçada ao tempo de espera deles. Por exemplo, 'seu tempo de espera para a massa é de 1 minutos, parece que o chef está colocando molho nela!'", tools = [get_menu]) customer_agent = Agent(name = "Customer", instructions = ("Você é um cliente e está comendo em um restaurante italiano. Veja o cardápio usando o Função get_menu. Se você já sabe o que quer, basta dizer ao garçom o que deseja. " "Caso contrário, dê a eles uma indicação geral ou peça orientação com base em sua preferência geral, e eles escolherão o melhor para você."), 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, '')
Temos a definição do cliente , que é a chamada do cliente OpenAI, o arquivo newtools.py , que obtém a lista, e o call_agent , que chama e executa o agente individual por meio de um executor . Esses componentes são essenciais para a criação de um sistema de agentes eficaz.
Isso é exatamente o que discutimos na introdução. Definimos vários agentes para serem conectados, e eles utilizam ferramentas especificadas pelo meu código. Essas ferramentas e agentes permitem a automação de tarefas de atendimento ao cliente e uma experiência de usuário aprimorada.
de agentes importar function_tool de constantes importar * importar pandas como pd @function_tool def get_menu(): df = pd.read_csv(MENU_FILE) # converter para lista de dicionários (ou estrutura serializável JSON) retornar df.to_dict(orient="records")
3.2 Implementação de agentes dedicados
A implementação de Mesa e Restaurante, juntamente com os agentes, está integrada no seguinte código:
importar aleatório importar tempo importar matemática importar sistemas de utilitários importar * de constantes importar * importar tempo, aleatório, json de agentes personalizados importar * de utilitários importar * de constantes importar * de agentes importar Runner # lista de primeiros nomes da sua constante NAMES # suponha 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] ➡️ Tempo estimado de espera para o cliente {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"Nosso LLM atendeu {cname} com isso: {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] ❓ Cliente {cid}: Quanto tempo demora para eu comer?”
print(msg) self.log_to_msg(msg) se wait for None: msg = f"[{self.clock:04}m] ➡️ Pronto agora!"
print(msg) self.log_to_msg(msg) else: msg = f"[{self.clock:04}m] ➡️ Tempo estimado de espera para o cliente {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"Nosso LLM atendeu {cname} com isso: {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() 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() free = sum(t.is_free for t in self.tables) msg = f"n--- FIM DO TURNO ---n{free}/{len(self.tables)} mesas livres em {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 Implementando uma Interface Gráfica de Usuário (GUI) para um Restaurante Usando um Modelo de Linguagem Grande (LLM)
Para exibir o desempenho do restaurante com um aplicativo de modelo de linguagem grande (LLM), usaremos uma interface gráfica de usuário (GUI) simples.
de llm_models_gui importar RestaurantGUI de utils importar * importar aleatório de llm_models importar Restaurante se __name__ == "__main__": random.seed(42) menu = preprocess_menu(MENU_FILE, eat_time_factor=0.5) R = Restaurante( num_tables=5, arrival_prob=0.7, tick_length=1, real_pause=1.0, # mais suave para GUI query_prob=0.8, menu=menu ) app = RestaurantGUI(R)

A interface gráfica do usuário (GUI) fornece informações sobre a pessoa (Emma), a tabela, a hora e a saída do modelo de linguagem grande (LLM). Um registro .txt também é criado automaticamente.
Deixe-me mostrar um exemplo da saída:
[12:31:23] A cliente Emma está falando com o garçom, dizendo: “Gostaria de começar com a bruschetta como entrada. Depois, pedirei espaguete à carbonara como primeiro prato. Para a sobremesa, gostaria de um tiramisu. Poderia também sugerir um vinho para acompanhar esta refeição?” [12:31:25] A resposta processada do nosso aluno de mestrado é: {'food': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'status': 'successful'} [12:31:25] [0000m] ❓ Cliente 1: Quanto tempo levará para preparar a comida? [12:31:25] [00:00] ➡️ Tempo estimado de espera para a comida por cliente: 1 minuto e 15 segundos [12:31:26] O aluno de MBA assumiu o caso da Emma com o seguinte: Último Cliente: Agente(nome=”Entertainer”, …) Resultado Final (cadeia): Olá Emma! Agradecemos sua paciência. O tempo de espera para entrar é de aproximadamente 15 minutos. Quase lá – tempo suficiente para eu começar a sonhar com aquela bruschetta deliciosa! 🍽️
Podemos oferecer:
- O cliente cria seu próprio cardápio através do agente.e solicita uma recomendação ao agente do garçom.
- O garçom recomenda um vinho Chianti e o adiciona à lista.
- O agente de tratamento de reclamações informa o cliente sobre o período de espera.
Agora, não só podemos simular o fluxo de trabalho, como fazíamos antes, mas também temos um fluxo de trabalho inteligente , aprimorado pela mesma tecnologia ChatGPT. Incrível, não é?
4. Conclusão
Muito obrigada por terem vindo, significa muito para mim ❤️.
Vamos voltar e ver o que fizemos neste artigo.
- Projeto de sistema de restaurante:
Criamos um design rápido para um sistema de restaurante usando o PowerPoint com a adição de agentes de IA. - Base sem agente:
Primeiro, construímos uma simulação determinística para podermos codificar a lógica da fila, dos tempos de cozimento e da rotação da mesa. Este é o nosso esqueleto antes de fazer qualquer IA. - Restaurante baseado em agentes:
Nesta fase, usamos agentes de IA para preencher nosso caso de reclamação + ação com agentes. Também criamos uma interface gráfica de usuário para exibir claramente os resultados.
Agora, neste ponto, quero ser bem claro. Sei que isso soa um pouco como algo saído de um filme de terror. Simulação de clientes? Simulação de restaurantes e garçons? Sim, é estranho, mas o problema nunca é a ferramenta de IA em si, e sim como ela é usada. Acho que substituir garçons humanos por IA é uma proposta fadada ao fracasso.
Ser garçom não é simplesmente anotar pedidos e recomendar o vinho número N com base nos vinhos N-1 que foram pedidos antes. É uma questão de ser caloroso o suficiente para fazer com que o convidado se sinta bem-vindo, mas distante o suficiente para não interferir na conversa, gentil o suficiente para fazê-lo se sentir em casa, mas forte o suficiente para fazê-lo respeitar seus limites. É uma combinação de qualidades que acredito que exigem um toque humano, paciência e empatia.
No entanto, acredito que o uso correto desta tecnologia pode ser duplo:
- Ajudando pessoas reais que estão na lista de espera. Os garçons lá dentro são muito ocupados, e os restaurantes já fornecem um cardápio para você olhar enquanto espera por sua mesa, e não é realista pensar que outros garçons estão entretendo pessoas que esperam sem mesa. Nesse ponto, um companheiro de IA para conversar pode ser útil.
- Simulação de restaurante. O cenário que escrevi simula Comportamento Clientes também. Isso significa que, potencialmente, você pode usar a simulação para testar diferentes cenários, ver quando as filas se formam, assumir diferentes reações das pessoas, diferentes respostas dos garçons, etc. Em outras palavras, este pode ser seu “gêmeo digital” onde você executa testes.
Comentários estão fechados.