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 PDFE todo mundo está falando sobre isso. Este arquivo é um guia de 34 páginas que explica o que são Large Language Model Agents (LLM Agents) e como usá-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 Grande (Agentes LLM) “São sistemas que realizam tarefas de forma independente em seu nome.”
Então, essas não são apenas chamadas simples para grandes modelos de linguagem (LLMs) chamadas por meio de uma API? Bem, sim e não. Você está usando o(s) mesmo(s) formulário(s) de conclusão de conversa, então é mais ou menos assim: Mas Pretende-se criar uma ação específica. O que quero dizer com isso é que a produção dos seus agentes Deve ser traduzido em um resultado acionável. No seu sistema. Por exemplo, se a saída do seu LLM disser “espaguete”, “espaguete” será adicionado ao seu caminho de dados e, eventualmente, alguém o verá e cozinhará espaguete (alerta).
2. Os agentes de modelos de linguagem grandes (Agentes LLM) são especificamente integrados com Funções (Ferramentas)
Estou falando aqui sobre o cenário em que você faz uma pergunta ao ChatGPT e ele chama seu próprio gerador de imagens/buscador da web/trecho de código. Ele usa internamente uma função chamada widget, que é acionada pelo seu prompt. Agora, o gerador de imagens é uma função interna, mas eles também podem chamar Seu trabalho (sua ferramenta), que você pode especificar especificamente para sua tarefa. Essa capacidade de integrar ferramentas e funcionalidades externas é o que dá aos agentes de LLM grande flexibilidade e poder na execução de uma variedade de tarefas.
3. Vários agentes de modelos de linguagem grandes (Agentes LLM) podem ser integrados. Consecutivo
Você pode integrar um único agente e fornecer a ele diversas ferramentas. أو Divida as ferramentas em agentes especializados, que é o que faremos neste artigo (outra 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 em palavras, acho que é mais fácil mostrar na prática. Digamos que estamos falando sobre 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, e precisamos criar Método de lista de espera, onde as pessoas se sentam com base no quão lotado o restaurante está, e precisamos criar cardápio, simulação Tempo de esperae certifique-se de que tudo está funcionando, Então Só então Podemos conectar 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, se você pensar sobre isso, você não é precisar para um grande modelo de linguagem (LLM) para esse propósito. Por exemplo, podemos calcular o tempo de espera com antecedência e depois conectá-lo a uma string formatada e predefinida. Também podemos usar um menu simples para coletar pedidos (como o quiosque automatizado do McDonald's) e pronto. Claro, podemos fazer isso, mas pense nisso.
E se o cliente quiser pedir informações sobre o cardápio? enquanto espera? E se fossem? hesitante Sobre comida? E se eles quisessem saber? A opção vegetariana mais deliciosa No menu? E se eles quisessem? 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 nosso tempo e dinheiro, ou podemos começar a usar inteligência artificial. É sobre isso que este artigo trata. Se usarmos grandes agentes de modelo de linguagem (Agentes LLM), teremos a oportunidade de lidar com todos esses cenários em uma única passagem.
Agora, se aprendi alguma coisa, é que engenharia de software precisa ser feita. Passo a passo. É melhor você ter esqueleto Adicione então decorações e acessórios ao seu modelo. Por esse motivo, criaremos uma versão sem agentes do produto acima. Esta versão simplificada contará com um sistema de filas que calcula os tempos de espera e executa o menu, para que tudo corra bem, sem nenhuma IA. Após esta etapa, podemos colocar os agentes nos lugares que discutimos e mostramos 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 em um arquivo. modelos_ingênuos.py, existente 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 inteiro é executado no naive_sim usando o comando .correr() 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 uma definição Cliente, que é a chamada do cliente do OpenAI, e novas ferramentas.py, que abre a lista e agente de chamada que chama o agente individual e o opera através corredor. Esses componentes são essenciais para criar um sistema de agentes eficaz.
É exatamente sobre isso que falamos na introdução. Nós identificamos vários وكلاء Eles estarão conectados e estão usando Ferramentas Definido pelo meu código. Essas ferramentas e agentes permitem automatizar tarefas de atendimento ao cliente e melhorar a experiência do usuário.
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 é integrada mesa و Restaurante Com agentes 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 se dirige ao garçom, dizendo: “Gostaria de começar com a bruschetta como entrada. Depois, pedirei o espaguete à carbonara como entrada. De sobremesa, o tiramisu. Você também pode sugerir um vinho para harmonizar com 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 levarei para preparar a comida? [12:31:25] [0000M] ➡️ Tempo de espera esperado para o cliente: 1:15 minutos [12:31:26] O aluno do LLM atendeu ao pedido de Emma: Último cliente: Agent(name=”Entertainer”, …) Resultado final (string): Olá, Emma! Obrigado pela sua paciência. O tempo de espera para entrar é de cerca de 15 minutos. Estamos quase lá - tempo suficiente para eu começar a sonhar com aquela deliciosa bruschetta! 🍽️
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 podemos simplesmente simular um fluxo de trabalho, como fazíamos antes, temos um fluxo de trabalho. Inteligente, alimentado pela mesma tecnologia ChatGPT. Não é ótimo?
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. Eu sei que isso parece um pouco com Black Mirror. Simulação de cliente? Simulação de restaurante e garçom? Sim, é estranho, Mas O problema nunca é a ferramenta de IA, mas sempre como ela é usada. Acho que substituir garçons humanos por IA é um jogo perdido.
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.