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 PDF dosyası yayınladı ve herkes bundan bahsediyor. Bu dosya, Büyük Dil Modeli Ajanlarının (LLM Ajanları) ne olduğunu ve nasıl kullanılacağını açıklayan 34 sayfalık bir kılavuz.

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 Ajanları (LLM Ajanları) “sizin adınıza bağımsız olarak görevleri yerine getiren sistemlerdir.”

Peki, bunlar sadece API aracılığıyla çağrılan basit Büyük Dil Modeli (LLM) istemleri değil mi? Evet ve hayır. Aynı konuşma tamamlama modelini/modellerini kullanıyorsunuz, bu yüzden bir bakıma öyle, ancak asıl amaç belirli bir eylem oluşturmak. Bununla kastettiğim şey, proxy çıktınızın sisteminizde yürütülebilir bir çıktıya çevrilmesi gerektiğidir . Örneğin, LLM çıktısı "spagetti" diyorsa, "spagetti" veri yolunuza eklenecek ve sonunda biri bunu görecek ve spagetti pişirecek (uyarı).

2. Büyük Dil Modeli (LLM) Ajanları özellikle fonksiyonlarla (araçlarla) entegre edilmiştir .

Burada, ChatGPT'ye bir soru sorduğunuzda, onun görüntü oluşturucu/web bulucu/kod parçacığını çağırdığı senaryodan bahsediyorum. Dahili olarak, sizin sorunuzla tetiklenen bir widget adı verilen bir fonksiyon kullanır. Görüntü oluşturucu yerleşik bir fonksiyondur, ancak göreviniz için belirtebileceğiniz kendi widget'ınızı da çağırabilirler . Harici widget'ları ve fonksiyonları entegre etme yeteneği, Büyük Dil Modeli Ajanlarına (LLM Ajanları) çok çeşitli görevleri yerine getirmede bu kadar esneklik ve güç kazandıran şeydir.

 

3. Birçok Büyük Dil Modeli Ajanı (LLM Ajanı) ardışık olarak birleştirilebilir.

Tek bir ajanı birden fazla araçla donatabilir veya araçları uzmanlaşmış ajanlara bölebilirsiniz; bu yazıda da 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 açıklamaya çalışsam da, pratik olarak göstermenin daha kolay olduğunu düşünüyorum. Örneğin , bir restorandan bahsediyor olalım .

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?

Restoranı hayata geçirmemiz , restoranın yoğunluğuna göre insanların oturacağı bir sıra sistemi oluşturmamız , menüyü hazırlamamız , bekleme sürelerini simüle etmemiz ve her şeyin düzgün çalıştığından emin olmamız gerekiyor. 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, şöyle bir düşünün, bunun için büyük bir dil modeline (LLM) ihtiyacınız yok . Örneğin, bekleme süresini önceden hesaplayıp önceden tanımlanmış, yapılandırılmış bir dizeye bağlayabiliriz. Ayrıca basit bir sipariş toplama listesi (McDonald's'ın otomatik kiosk'u gibi) kullanıp işi bitirebiliriz. Elbette bunu yapabiliriz, ama bir düşünün.

Peki ya bir müşteri beklerken menü hakkında bilgi almak isterse ? Ya yemek konusunda kararsızsa ? Ya menüdeki en iyi vejetaryen seçeneği öğrenmek isterse ? Ya da uygun fiyata iyi bir şarap almak isterse ? Bu senaryoların her biri için kural tabanlı yöntemler tanımlamaya başlayıp zamanımızı ve paramızı boşa harcayabiliriz ya da yapay zekayı kullanmaya başlayabiliriz. Bu makale de tam olarak bununla ilgili. Büyük Dil Modeli Ajanlarını (LLM Ajanları) kullanırsak, tüm bu senaryoları tek seferde ele alma fırsatımız olur.

Şimdiye kadar öğrendiğiniz en önemli şey, yazılım mühendisliğinin adım adım yapılması gerektiğidir. Modelinizin temel çerçevesini oluşturmak ve ardından son rötuşları ve geliştirmeleri eklemek en iyisidir. Bu nedenle, yukarıdaki ürünün ajan içermeyen bir sürümünü oluşturacağız. Bu basitleştirilmiş sürüm, bekleme sürelerini hesaplayan ve menüyü yürüten bir kuyruk sistemine sahip olacak, böylece her şey yapay zekâ olmadan sorunsuz bir şekilde çalışacaktır. Bu adımdan sonra, yukarıda tartıştığımız ve gösterdiğimiz pozisyonlara (müşteri, sunucu ve garson) ajanları 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.

Tüm bu uygulamalar, burada bulunan naive_models.py dosyasında gerçekleştiriliyor.

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.

Bu betiğin tamamı , .run() komutu kullanılarak naive_sim üzerinde aşağıdaki fonksiyonlarla çalıştırılır:

  • 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, '')

OpenAI istemci çağrısı olan istemci tanımına , listeyi çeken newtools.py dosyasına ve her bir ajanı bir çalıştırıcı aracılığıyla çağırıp çalıştıran call_agent dosyasına sahibiz . Bu bileşenler, etkili bir ajan sistemi oluşturmak için elzemdir.

Bu, giriş bölümünde tartıştığımız konu tam olarak bu. Birbirine bağlanacak birkaç aracı tanımlıyoruz ve bunlar kodumda belirtilen araçları kullanıyor. Bu araçlar ve aracılar, müşteri hizmetleri görevlerinin otomasyonunu ve kullanıcı deneyiminin iyileştirilmesini sağlıyor.

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ı

Table ve Restaurant uygulamalarının, aracılarıyla birlikte, aşağıdaki koda entegre edildiği görülmektedir :

 

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 garsonla konuşuyor ve şöyle diyor: “Başlangıç ​​olarak bruschetta istiyorum. Ardından ana yemek olarak spagetti carbonara sipariş edeceğim. Tatlı olarak da tiramisu istiyorum. Bu yemeğe uygun bir şarap da önerebilir misiniz?” [12:31:25] Yüksek lisans öğrencimizin işlenmiş yanıtı: {'yemek': ['Bruschetta', 'Spaghetti Carbonara', 'Tiramisu', 'Chianti Classico'], 'durum': 'başarılı'} [12:31:25] [0000m] ❓ Müşteri 1: Yemeği hazırlamam ne kadar sürer? [12:31:25] [00:00] ➡️ Müşteri başına tahmini yemek bekleme süresi: 1:15 dakika [12:31:26] MBA öğrencisi Emma'nın durumunu şu şekilde devraldı: Son Müşteri: Temsilci (adı=”Eğlenceci”, …) Nihai Sonuç (zincir): Merhaba Emma! Sabrınız için teşekkür ederiz. İçeri girmek için bekleme süresi yaklaşık 15 dakika. Neredeyse geldik – o lezzetli 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, eskiden olduğu gibi iş akışını simüle etmekle kalmıyoruz, aynı ChatGPT teknolojisiyle geliştirilmiş akıllı bir iş akışına da sahibiz. Bu inanılmaz 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 kara aynaya benzediğini biliyorum. Müşteri simülasyonu mu? Restoran ve garson simülasyonu mu? Evet, garip ama sorun asla yapay zeka aracının kendisi değil, her zaman nasıl kullanıldığıdır. Bence insan garsonların yerini yapay zeka ile değiştirmek kaybeden bir girişimdir.

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ı.