Uygulamada Python ve OpenAI ile Büyük Dil Modelleri Kullanarak Çoklu Ajan Restoran Simülasyonu (LLM)

Python kullanarak uçtan uca bir restoran operasyonunu simüle etmek için Büyük Dil Model Aracılarını nasıl kullandığımı burada görebilirsiniz.

Geçtiğimiz hafta OpenAI bir dosya yayınladı PDFVe herkes bundan bahsediyor. Bu dosya, Büyük Dil Model Aracılarının (LLM Aracıları) ne olduğunu ve nasıl kullanılacağını açıklayan 34 sayfalık bir kılavuzdur.

PDF dosyası nispeten kısa ve okunması da kolay (anlamak için yazılım mühendisi/mentörü olmanıza gerek yok), ancak birkaç kelimeyle üç şeyi açıklıyor:

.1. Büyük Dil Modeli Aracıları (LLM Aracıları) "Bunlar sizin adınıza görevleri bağımsız olarak tamamlayan sistemlerdir."

Peki bunlar bir API aracılığıyla çağrılan büyük dil modelleri (LLM) için yapılan basit çağrılar değil midir? Evet ve hayır. Aynı konuşma tamamlama formunu/formlarını kullanıyorsunuz, bu yüzden bir nevi şöyle: ancak Belirli bir eylemin yaratılması amaçlanmaktadır. Bununla demek istediğim, acentelerinizin çıktısının Bunun uygulanabilir bir çıktıya dönüştürülmesi gerekiyor. Sisteminizde. Örneğin, LLM çıktınız “spagetti” diyorsa, “spagetti” veri yolunuza eklenecek ve sonunda birisi bunu görecek ve spagetti pişirecektir (uyarı).

2. Büyük Dil Modeli Aracıları (LLM Aracıları) özel olarak entegre edilmiştir Fonksiyonlar (Araçlar)

Burada ChatGPT'ye bir soru sorduğunuz ve onun kendi resim oluşturucusunu/web arama motorunu/kod parçacığını çağırdığı senaryodan bahsediyorum. Dahili olarak, komut isteminiz tarafından tetiklenen widget adlı bir fonksiyonu kullanır. Şimdi, görüntü oluşturucu yerleşik bir işlevdir, ancak aynı zamanda şunları da çağırabilirler: Mesleğiniz (aracınız), görevinize özel olarak belirleyebileceğiniz. Harici araçları ve işlevleri entegre etme yeteneği, LLM temsilcilerine çeşitli görevleri yerine getirirken büyük esneklik ve güç sağlar.

 

3. Birden fazla büyük dil modeli aracısı (LLM Aracıları) entegre edilebilir. Ardışık

Tek bir aracı entegre edip ona birden fazla araç sağlayabilirsiniz. أو Araçları uzmanlaşmış ajanlara ayırın; bu makalede bunu yapacağız (bir ipucu daha!).

Teknik detaylar yazılım mühendisleri için ilgi çekici olabilir, ancak ajanlar konusu neden herkes için bu kadar önemlidir?
Çünkü bu, Açık Yapay Zeka modellerine fayda sağlamaya yardımcı olan bir paradigma değişimini temsil ediyor. Bir düşünün: Artık büyük dil modelleri (LLM'ler) Eyleme dönüştürülebilir çıktılar. Yani, iş akışının son adımında nihai çıktıyı iyileştirmek için LLM istemlerini kullanmak söz konusu değil; Aksine, bu konu hakkında Tüm iş akışını Büyük Dil Modeli Aracıları (LLM Aracıları) ile entegre etme Tüm iş akışının kalitesini artırmak.

Bunu kelimelerle anlatmaya çalışıyorum ama pratikte göstermenin daha kolay olduğunu düşünüyorum. Diyelim ki hakkında konuşuyoruz restoran, örnek.

Tipik bir restoranda çok normal ve net bir süreç vardır: Sırada beklersiniz, yemeğinizi sipariş edersiniz, yemeğinizin gelmesini beklersiniz, yersiniz ve çıkarsınız. Şimdi, bunu "aracı" yaklaşımını kullanarak çevirirsek, en azından üç aracı tanımlayabiliriz:

  • ajan Müşteri Garsonlardan yemek siparişi veren veya öneriler isteyen bir Büyük Dil Modeli (LLM) Ajanı'dır.
  • ajan النادل İstekleri toplayan ve gerektiğinde önerilerde bulunan büyük bir dil modelidir (LLM).
  • ajan eğlence Müşteri şikayetlerini ele almayı amaçlayan büyük dil modelidir (LLM).

Şimdi, OpenAI size bu varlıkların tam olarak nasıl oluşturulacağını söylüyor, ancak bu nispeten kolay bir kısım; Daha fazlası var, değil mi?

Uygulamamız gerekiyor restorantve yaratmamız gerekiyor Bekleme listesi yöntemi, restoranın ne kadar kalabalık olduğuna bağlı olarak insanların nerede oturduğunu ve yaratmamız gerektiğini قائICة الطاetty, simülasyon Bekleme süresive her şeyin çalıştığından emin olun, sonra Ancak o zaman Ajanları birbirine bağlayabiliriz. her zaman olduğu gibi:

 

Üretken yapay zeka güçlüdür, ancak yalnızca doğru bağlamda kullanıldığında.

Peki, acenteler hakkında heyecan verici kısma geçmeden önce, bu makalede şunları göreceksiniz:

  1. Sistem Tasarımı Restoran Temsilcisi LLM için. Kodsuz bir fikir, sadece kalem ve kağıt (ya da daha doğrusu fare ve PowerPoint) ile projenin taslağı.
  2. Ajansız Restoran uygulaması. Basit ve anlaşılır, sadece kodun temel yapısını oluşturun.
  3. Agent Restaurant uygulaması. Ayrıca bunu iyi bir şekilde görüntüleyebilmek için basit bir grafiksel kullanıcı arayüzü.
  4. Son düşünceler ve gözlemler.

Anlatacak çok şeyimiz var gibi görünüyor. Laboratuvara! 🧪

1. Restoran Sistemi Tasarımı: Uzman Rehberi

Not: Eğer biraz teknik tur yaptıysanız bu sistem tasarımının çok kolay olduğunu göreceksiniz. Bu tasarımın amacı, bir makine öğrenimi sisteminin her bölümünü kapsamlı bir şekilde göstermek değil (15 dakikalık bir röportajda sizden bunu istiyorlar 🙃), ancak bundan sonra ne yapacağımız konusunda biraz rehberlik sağlamaktır.

Restoran sürecini büyük dil modeli (LLM) ile bütünleşik olarak görselleştirmenin yolu bu resimde özetlenmiştir:

Açıklayayım:

  • Restoran() و Menü() Bunlar iki sınıftır. Bunları tanımlayacağız ve sınıflar içindeki tüm tablolar, siparişler ve sistem bilgileri dinamik olarak tanımlanacak ve güncellenecektir.
  • zorunda kalacak Yeni müşteri Oturma mekanizmasından geçin. Eğer oturabilirlerse (yeterince boş masa varsa), harika, oturmalarına izin verebiliriz; Aksi takdirde müşteri sıraya girecektir.
  • Müşteri için oturanYemek siparişi verebilmeleri için bir garson bulunacak. Sipariş verdikten sonra yemeğin ne kadar sürede hazır olacağını sorarak "şikayet edebilirler".
  • İnsanlar yapamaz Sırada beklemek Çok şey yapıyorlar, ama aynı zamanda "şikayet edebiliyorlar" ve oturmadan önce ne kadar süre sırada beklemeleri gerektiğini sorabiliyorlar.

Şimdi, eğer bunu düşünürseniz, siz değilsiniz ihtiyaç Bu amaçla büyük bir dil modeli (LLM) kullanılmaktadır. Örneğin, bekleme süresini önceden hesaplayıp daha sonra bunu önceden tanımlanmış, biçimlendirilmiş bir dizeye bağlayabiliriz. Siparişleri toplamak için basit bir menü (McDonald's otomatik kiosku gibi) kullanabilir ve işimizi tamamlayabiliriz. Elbette bunu yapabiliriz, ama bir düşünün.

Peki müşteri menü hakkında bilgi almak isterse ne olacak? beklerken? Ya öyle olsalardı? tereddütlü Yemek hakkında mı? Peki ya bilmek isterlerse? En lezzetli vejetaryen seçenek Menüde var mı? Ya isterlerse? Uygun fiyata iyi şarap? Ya bu senaryoların her biri için kural tabanlı yöntemler tanımlamaya başlayıp zamanımızı ve paramızı boşa harcayacağız ya da yapay zekayı kullanmaya başlayacağız. İşte bu yazı tam da bu konuyla ilgili. Büyük dil modeli ajanlarını (LLM Agents) kullandığımızda tüm bu senaryoları tek seferde ele alma imkânına sahip oluruz.

Şimdi eğer bir şey öğrendiysem, o da yazılım mühendisliğinin yapılması gerektiğidir. Adım adım. Daha iyi olur iskelet Daha sonra modelinize süslemeler ve aksesuarlar ekleyin. Bu nedenle yukarıdaki ürünün ajan içermeyen bir versiyonunu inşa edeceğiz. Bu basitleştirilmiş versiyonda, bekleme sürelerini hesaplayan ve menüyü çalıştıran bir kuyruk sistemi yer alacak, böylece herhangi bir yapay zekaya ihtiyaç duyulmadan her şey sorunsuz bir şekilde çalışacak. Bu adımdan sonra acenteleri yukarıda bahsettiğimiz ve gösterdiğimiz yerlere (müşteri, host ve garson) yerleştirebiliriz.

2. Ajansız Uygulama

Ana scriptte her şeyi olabildiğince basitleştirmek ve karmaşık işlemleri arka planda bırakmak her zaman daha iyidir. Bu kodda Agent Free Implementation'ımız çalıştırılabilir.

random'ı içe aktar zamanı içe aktar math'i içe aktar sys'i içe aktar utils'tan *'ı içe aktar sabitlerden *'ı içe aktar naive_models'tan *'ı içe aktar eğer __name__ == "__main__": random.seed(42) menü = 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)

Gördüğümüz gibi şunları değiştirebiliriz:

  • tablo_sayısı; Restoranımızdaki masa sayısı.
  • varış_prob; Her zaman aralığında bir müşterinin gelme olasılığıdır.
  • kene; Simülasyonumuzun zaman adımıdır.
  • duraklatmak; Gerçek bir restoranın iş akışını simüle etmek için kullanılan time.sleep() fonksiyonunu uygular.

Şimdi tüm bu uygulama bir dosya içerisinde yapılıyor. saf_modeller.py, mevcut Burada.

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)

Çok uzun, gelin size birkaç adımdan bahsedeyim.

Tüm betik, naive_sim üzerinde şu komutu kullanarak çalışır: .koşmak() Aşağıdaki işlevlere sahiptir:

  • varmakMüşterilerin gelişini ve talebini veya gelişlerini ve bir kuyruğa yerleştirilmelerini temsil eden
  • işlem_pişirmeHer masanın yemek pişirmesini simüle eden.
  • süreç_kalkışlarıMüşterinin ayrılmasını simüle eden.
  • koltuk_sıradan_yerMüşterilerin sırada oturmasını simüle eden bir uygulama.
  • rastgele_sorguyu_işleRastgele olarak adlandırılan, sırada bekleyen veya yemeğini bekleyen bir müşterinin bekleme süresini sorabildiği bir uygulamadır.

naive_sim.py'ı çalıştırdığımızda terminalden şunu alacağız.

Şimdi bu başlı başına bir veri bilimi ürünü. Bununla bir Monte Carlo zinciri çalıştırabilirsiniz, uzun kuyrukların oluşma potansiyelini görebilirsiniz, restoranlar restoranlarının bu "dijital ikizini" kullanabilir ve kritik şeylerin ne zaman olabileceğini görebilirler. Artık çalışan bir ürünümüz olduğuna göre, onu yapay zeka (YZ) kullanarak daha güzel ve güçlü hale getirelim.

3. Ajan Restoran Uygulaması

Yukarıda da gördüğümüz gibi, müşteriler zaten soru sorabiliyorlar ve biz de cevabı bir sayı olarak alıyoruz. Müşteri ayrıca sistemimizde rastgele bir yiyecek seçiyor. Şimdi bu sisteme ajan eklemeyi deneyelim. Bir restoran acentesi sisteminin etkinleştirilmesi, müşteri hizmetlerinin otomatikleştirilmesi ve kullanıcı deneyiminin iyileştirilmesinde ileri bir adımdır. Eğitimli temsilciler müşteri sorularını etkili bir şekilde yanıtlayabilir ve kişiselleştirilmiş önerilerde bulunabilir.

3.1 Özel ajanların uygulanması

“Ajanlar” modülünü yüklemeniz gerekecektir:

Aşağıda müşteri hizmetleri temsilcisi, eğlence temsilcisi ve şikayet yöneticisinin uygulanması gösterilmektedir.

# 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 = "Siz, restoranımız hakkında her şeyi bilen ve müşterilerin yemeklerini seçmelerine yardımcı olan yardımsever bir garsonsunuz. Öncelikle kendinizi bir yemek sanal asistanı olarak" "tanıtacak ve müşteriye nazikçe merhaba diyeceksiniz. Müşterinin adı msg json dosyasında bulunabilir" "Menüyü okuyacaksınız ve json dosyasının istek anahtarında müşterinin size sorduğu şeye göre menüden en iyi öneriyi sağlayacaksınız." "Müşteri size uygunsuz sorular soruyorsa, sadece 'unsuccessfull' json format '{food: , durum: }'", tools = [get_menu]) entertainment_agent = Agent(name = "Eğlendirici", instructions = ("Müşteriler beklerken onları meşgul eden yardımsever bir garsonsunuz." "Hiçbir indirim veya teklif sunamazsınız, ancak get_menu işlevlerinden edinebileceğiniz menü hakkında soru sorabilirler. Ayrıca içeri girmek için ne kadar sıra bekleyeceğinizi de sorabilirler. Bilgileri waiting_time'dadır." "Kullanıcı durumu 'kuyruk' ise, bekleme süresine göre nezaketle zamanı belirtin. Aksi takdirde, user_status 'yemek' ise, yemek bekledikleri anlamına gelir. 'Sipariş'i kontrol edin ve bekleme süreleri hakkında komik bir referans verin. Örneğin, 'makarna için bekleme süreniz 1 dakika, şefin üzerine sos sürdüğü anlaşılıyor!'", tools = [get_menu]) customer_agent = Agent(name = "Müşteri", instructions = ("Müşterisiniz ve İtalyan bir restoranda yemek yiyorsunuz restoran. get_menu işlevini kullanarak menüye bakın. Ne istediğinizi zaten biliyorsanız, garsona ne istediğinizi söylemeniz yeterlidir. " "Aksi takdirde, onlara genel bir gösterge verin veya genel beğeninize göre rehberlik isteyin, sizin için en iyisini seçeceklerdir."), 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, '')

Bir tanımımız var MüşteriOpenAI'nin müşteri çağrısı olan ve yeniaraçlar.pylisteyi yukarı çeken ve çağrı_temsilcisi bireysel aracı çağıran ve onu çalıştıran koşucu. Bu bileşenler etkili bir ajan sistemi oluşturmak için olmazsa olmazdır.

Girişte bahsettiğimiz konu tam olarak budur. Birkaçını tanımlıyoruz وكلاء Bağlanacaklar ve kullanıyorlar Araçlar Benim kodumla tanımlandı. Bu araçlar ve aracılar, müşteri hizmetleri görevlerini otomatikleştirmenize ve kullanıcı deneyimini iyileştirmenize olanak tanır.

ajanlardan function_tool'u içe aktar sabitlerden * içe aktar pandas'ı pd olarak içe aktar @function_tool def get_menu(): df = pd.read_csv(MENU_FILE) # sözlükler listesine (veya JSON-serileştirilebilir yapıya) dönüştür return df.to_dict(orient="kayıtlar")

3.2 Özel ajanların uygulanması

Uygulama entegredir tablo و Restoran Aşağıdaki kodda ajanlar var:

 

random'u içe aktar time'ı içe aktar math'ı içe aktar sys'i içe aktar utils'tan *'ı içe aktar sabitlerden *'ı içe aktar time, random, json'u içe aktar custom_agents'tan *'ı içe aktar utils'tan *'ı içe aktar sabitlerden *'ı içe aktar agents'tan Runner'ı içe aktar # NAMES sabitinizden ilk adlarınızın listesi # NAMES = [ ... varsayın ] 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] ➡️ Müşteri {cid} için tahmini bekleme süresi: {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"LLM'miz {cname} ile şu şekilde ilgilendi: {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] ❓ Müşteri {cid}: Yemeği ne kadar sürede hazırlarım?”
print(msg) self.log_to_msg(msg) bekleme None ise: msg = f"[{self.clock:04}m] ➡️ Şimdi hazırım!"
print(msg) self.log_to_msg(msg) else: msg = f"[{self.clock:04}m] ➡️ Müşteri {cid} için tahmini yemek bekleme süresi: {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"LLM'miz {cname} ile şu şekilde ilgilendi: {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--- SHIFT SONU ---n{free}/{len(self.tables)} {self.clock}m'de boş tablo var."
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 Büyük Dil Modeli Kullanarak Bir Restoran İçin Grafiksel Kullanıcı Arayüzü (GUI) Uygulama (LLM)

Restoranın performansını büyük dil modeli (LLM) uygulamasıyla görüntülemek için basit bir grafiksel kullanıcı arayüzü (GUI) kullanacağız.

llm_models_gui'den RestaurantGUI'yi içe aktarın utils'ten *'ı içe aktarın random'u içe aktarın llm_models'den Restaurant'ı içe aktarın 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=1.0, # GUI için daha düzgün query_prob=0.8, menu=menu ) app = RestaurantGUI(R)

Grafiksel kullanıcı arayüzü (GUI) size kişi (Emma), tablo, zaman ve büyük dil modelinin (LLM) çıktısı hakkında bilgi sağlar. Otomatik olarak bir .txt kaydı da oluşturulur.

Çıktının bir örneğini size göstereyim:

[12:31:23] Müşteri Emma garsona, "Başlangıç ​​yemeği olarak bruschetta ile başlamak istiyorum. Daha sonra ilk yemek olarak spagetti carbonara sipariş edeceğim. Tatlı olarak tiramisu yiyeceğim. Bu yemekle birlikte kullanılabilecek bir şarap önerebilir misiniz?" diyor. [12:31:25] Yüksek lisans öğrencimizin işlenmiş cevabı: {'food': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'status': 'successful'} [12:31:25] [0000M] ❓ Müşteri 1: Yemeği hazırlamam ne kadar sürecek? [12:31:25] [0000M] ➡️ Müşterinin yemek için bekleme süresi 1:15 dakika [12:31:26] LLM öğrencisi Emma'nın siparişiyle ilgilendi: Son müşteri: Agent(name="Entertainer", …) Sonuç (dize): Merhaba Emma! Sabrınız için teşekkür ederiz. Giriş için bekleme süresi yaklaşık 15 dakikadır. Neredeyse bitirdik - o leziz bruschetta'yı hayal etmeye başlamam için tam zamanı! ???? ️

Size şunları sunabiliriz:

  1. Müşteri, acente aracılığıyla kendi menüsünü oluşturur.ve garsonun temsilcisinden bir tavsiye ister.
  2. Garson Chianti şarabını öneriyor ve listeye ekliyor.
  3. Şikayet yönetim temsilcisi müşteriye bekleme süresini bildirir.

Artık daha önce yaptığımız gibi bir iş akışını simüle edemeyiz, bir iş akışımız var. Zeki, aynı ChatGPT teknolojisiyle desteklenmektedir. Harika değil mi?

 

4. Sonuç

Geldiğiniz için çok teşekkür ederim, benim için çok şey ifade ediyor ❤️.
Gelin bu yazıda neler yaptığımıza bir bakalım.

  1. Restoran sistem tasarımı:
    PowerPoint kullanarak ve yapay zeka aracıları ekleyerek bir restoran sistemi için hızlı bir tasarım oluşturduk.
  2. Ajansız bazda:
    Öncelikle kuyruk, pişirme süreleri ve masa dönüşü mantığını kodlayabilmek için deterministik bir simülasyon oluşturduk. Bu, yapay zekaya geçmeden önceki iskeletimiz.
  3. Ajan tabanlı restoran:
    Bu aşamada şikayet + eylem dosyamızı temsilcilerle doldurmak için yapay zeka temsilcilerini kullandık. Sonuçların net bir şekilde görüntülenebilmesi için grafiksel bir kullanıcı arayüzü de oluşturduk.

Şimdi bu noktada çok net olmak istiyorum. Bunun biraz Black Mirror'a benzediğini biliyorum. Müşteri simülasyonu mu? Restoran ve garson simülasyonu? Evet, tuhaf. ancak Sorun asla yapay zeka aracının kendisi değil, nasıl kullanıldığıdır. İnsan garsonların yerini yapay zekanın almasının kaybedilen bir oyun olduğunu düşünüyorum.

Garsonluk sadece sipariş almak ve daha önce sipariş edilen N-1 şaraptan yola çıkarak N numaralı şarabı önermek değildir. Önemli olan, misafirinizi hoş karşılayacak kadar sıcak ama sohbetine müdahale etmeyecek kadar mesafeli olmak, kendisini evinde hissettirecek kadar nazik ama sınırlarınıza saygı duymasını sağlayacak kadar da güçlü olmaktır. İnanıyorum ki, insan dokunuşu, sabır ve empati gerektiren niteliklerin bir bileşimidir.

Ancak bu teknolojinin doğru kullanımının iki yönlü olabileceğine inanıyorum:

  1. Bekleme listesinde olan gerçek insanlara yardım ediyoruz. İçerideki garsonlar oldukça yoğun ve restoranlar masanızı beklerken bakmanız için size bir menü veriyorlar, diğer garsonların da masası olmayan insanları eğlendirdiğini düşünmek gerçekçi değil. Bu noktada sohbet edebileceğiniz bir yapay zeka arkadaşı işinize yarayabilir.
  2. Restoran simülasyonu. Yazdığım senaryo simüle ediyor Davranış Müşteriler Ayrıca. Bu, potansiyel olarak simülasyonları farklı senaryoları test etmek, kuyrukların ne zaman oluştuğunu görmek, insanlardan farklı tepkiler, garsonlardan farklı yanıtlar vb. varsaymak için kullanabileceğiniz anlamına gelir. Başka bir deyişle, bu sizin testler yürüttüğünüz "dijital ikiziniz" olabilir.

 

 

Yoruma kapalı.