--- language: - tr license: mit base_model: - Qwen/Qwen3-8B tags: - tool-calling - function-calling - agent - gradio - sqlite - bookstore - turkish - huggingface --- # 📚 Akıllı Kitapçı Tool-Calling Asistanı Bu proje; bir açık kaynak dil modelinin tanımlı araçları kullanarak gerçek bir SQLite veritabanından kitap bilgisi okuduğu, sipariş oluşturduğu, stok düşürdüğü ve sipariş durumunu sorguladığı uçtan uca bir **tool-calling asistanıdır**. Proje, **Tool-Calling Destekli Asistan Geliştirme** ödevi kapsamında hazırlanmıştır. ## 🎯 Senaryo Kullanıcı doğal Türkçe ifadelerle kitapçı asistanına soru sorabilir: - “Dune kitabının fiyatı ve stok durumu nedir?” - “Bilim kurgu kitaplarını göster.” - “Dune kitabından Yusuf Şimşek adına 1 adet sipariş oluştur.” - “2 numaralı siparişim ne durumda?” - “George Orwell kitaplarından stokta olanları listele.” Model; fiyat, stok, kitap kimliği ve sipariş durumunu kendi bilgisinden üretmez. Gereken bilgiyi ilgili tool üzerinden SQLite veritabanından alır. ## 🧠 Kullanılan Teknolojiler | Bileşen | Teknoloji | |---|---| | Dil modeli | `Qwen/Qwen3-8B` | | Model erişimi | Hugging Face Inference Providers | | Tool calling | JSON Schema tabanlı function calling | | Veritabanı | SQLite | | Arayüz | Gradio | | Dil | Python | | Paket yönetimi | `uv` / `pip` | | Canlı yayın | Hugging Face Spaces | Model ağırlıkları uygulamaya indirilmez. Model, Hugging Face Inference Providers üzerinden çağrılır. ## 🏗️ Sistem Mimarisi ```text Kullanıcı mesajı │ ▼ Qwen3-8B dil modeli │ ├── Tool gerekmiyorsa → Doğrudan cevap │ └── Tool gerekiyorsa │ ▼ JSON tool-call │ ▼ Python tool yönlendiricisi │ ▼ SQLite veritabanı │ ▼ Gerçek tool sonucu │ ▼ Sonuç tekrar dil modeline │ ▼ Kullanıcıya nihai Türkçe cevap ``` Sipariş oluşturma örneği: ```text search_books ↓ Gerçek book_id ve stok bilgisi ↓ create_order ↓ Sipariş kaydı + stok güncellemesi ↓ Nihai asistan cevabı ``` ## 🧰 Tool Tanımları ### 1. `search_books` Kitapları başlık, yazar veya kategoriye göre SQLite veritabanında arar. | Parametre | Tür | Açıklama | |---|---|---| | `query` | string | Kitap, yazar veya genel arama ifadesi | | `author` | string | Yazar filtresi | | `category` | string | Kategori filtresi | | `in_stock_only` | boolean | Yalnızca stokta bulunan kitaplar | | `limit` | integer | En fazla sonuç sayısı | Örnek tool-call: ```json { "name": "search_books", "arguments": { "query": "Dune", "in_stock_only": true } } ``` ### 2. `create_order` Gerçek bir kitap kimliğiyle sipariş oluşturur ve kitabın stoğunu sipariş miktarı kadar azaltır. | Parametre | Tür | Açıklama | |---|---|---| | `book_id` | integer | `search_books` sonucundan gelen gerçek kitap kimliği | | `quantity` | integer | Sipariş adedi | | `customer_name` | string | Müşteri adı ve soyadı | Örnek tool-call: ```json { "name": "create_order", "arguments": { "book_id": 5, "quantity": 1, "customer_name": "Yusuf Şimşek" } } ``` ### 3. `get_order_status` Sipariş numarasına göre sipariş bilgisini ve durumunu getirir. | Parametre | Tür | Açıklama | |---|---|---| | `order_id` | integer | Sorgulanacak sipariş numarası | Örnek tool-call: ```json { "name": "get_order_status", "arguments": { "order_id": 2 } } ``` ## 🗄️ Veritabanı Yapısı ### `books` tablosu | Kolon | Açıklama | |---|---| | `id` | Kitap kimliği | | `title` | Kitap adı | | `author` | Yazar | | `category` | Kategori | | `price` | Kitabın fiyatı | | `stock` | Mevcut stok | | `created_at` | Kayıt zamanı | Başlangıçta farklı kategorilerden **40 örnek kitap** eklenir. ### `orders` tablosu | Kolon | Açıklama | |---|---| | `id` | Sipariş numarası | | `customer_name` | Müşteri adı | | `book_id` | Kitap kimliği | | `quantity` | Sipariş adedi | | `unit_price` | Birim fiyat | | `total_price` | Toplam tutar | | `status` | Sipariş durumu | | `created_at` | Sipariş zamanı | Sipariş oluşturma ve stok düşürme işlemleri aynı transaction içinde gerçekleştirilir. İşlemlerden biri başarısız olursa yapılan değişiklikler geri alınır. ## 🛡️ Halüsinasyon Engelleme Modelin veritabanında olmayan bilgileri gerçekmiş gibi sunmasını engellemek için aşağıdaki kontroller uygulanmıştır: 1. Fiyat, stok, `book_id`, sipariş numarası ve sipariş durumu yalnızca tool sonuçlarından alınır. 2. `create_order`, aynı agent turunda `search_books` sonucundan gelmeyen bir `book_id` ile çalışamaz. 3. Model tarafından tahmin edilen kitap kimlikleri reddedilir. 4. Olmayan kitaplar boş sonuçla döndürülür. 5. Yetersiz stokta sipariş oluşturulmaz ve stok değiştirilmez. 6. Eksik müşteri adı, geçersiz miktar ve hatalı sipariş numarası Python tarafında doğrulanır. 7. Aynı kullanıcı isteğinde ikinci kez sipariş oluşturulması engellenir. 8. Model doğrudan SQL sorgusu çalıştıramaz. 9. Model yalnızca izin verilen üç tool fonksiyonunu çağırabilir. 10. Tool çağrıları terminalde ve Gradio arayüzünde loglanır. ## 📁 Proje Yapısı ```text bookstore-tool-calling-assistant/ ├── app.py ├── main.py ├── agent.py ├── llm_client.py ├── prompts.py ├── tools.py ├── tool_schemas.py ├── test_tools.py ├── test_tool_schemas.py ├── requirements.txt ├── pyproject.toml ├── uv.lock ├── README.md ├── .gitignore ├── assets/ │ └── tool_call_log.png └── data/ ├── __init__.py ├── database.py ├── seed_database.py ├── test_database.py └── data/ └── bookstore.db ``` `data/data/bookstore.db` çalışma sırasında otomatik oluşturulur ve Git deposuna eklenmez. ## ⚙️ Yerel Kurulum ### 1. Projeyi klonlayın ```bash git clone cd bookstore-tool-calling-assistant ``` ### 2. `uv` ile bağımlılıkları kurun ```bash uv sync ``` Gradio projede bulunmuyorsa: ```bash uv add gradio ``` ### Alternatif: `pip` ```bash python3 -m venv .venv source .venv/bin/activate pip install -r requirements.txt ``` ### 3. Hugging Face hesabına giriş yapın ```bash hf auth login ``` Alternatif olarak token ortam değişkeni şeklinde tanımlanabilir: ```bash export HF_TOKEN="hf_..." ``` Hugging Face tokenı kaynak koda yazılmamalıdır. ## ▶️ Terminal Uygulamasını Çalıştırma ```bash uv run python main.py ``` Örnek kullanım: ```text Sen: Dune kitabının fiyatı ve stok durumu nedir? TOOL CALL: search_books Arguments: {"query": "Dune"} Asistan: Dune kitabının fiyatı 320 TL, mevcut stok miktarı 7 adettir. ``` ## 🖥️ Gradio Arayüzünü Çalıştırma ```bash uv run python app.py ``` Alternatif: ```bash python app.py ``` ## 🧪 Testler ### Veritabanı testi ```bash uv run python data/test_database.py ``` ### Tool fonksiyonları testi ```bash uv run python test_tools.py ``` Test edilen senaryolar: - Kitap arama - Olmayan kitabı arama - Sipariş oluşturma - Stok azaltma - Sipariş durumu sorgulama - Yetersiz stok - Geçersiz sipariş numarası - Test siparişinin silinmesi ve stoğun geri yüklenmesi ### Tool şemaları testi ```bash uv run python test_tool_schemas.py ``` Kontrol edilen durumlar: - Üç tool şemasının bulunması - JSON Schema yapısının doğrulanması - Tool ve Python fonksiyonu adlarının eşleşmesi - Zorunlu parametrelerin kontrolü - Normal ve strict şemaların üretilmesi ## ✅ Uçtan Uca Çalışan Örnek Kullanıcı girdisi: ```text Dune kitabından Yusuf Şimşek adına 1 adet sipariş oluştur. ``` Arka planda gerçekleşen işlemler: ```text 1. search_books({ "query": "Dune", "in_stock_only": true }) 2. Veritabanı sonucu: title = Dune book_id = 5 price = 320 TL stock = 7 3. create_order({ "book_id": 5, "quantity": 1, "customer_name": "Yusuf Şimşek" }) 4. Sipariş sonucu: order_id = 2 total_price = 320 TL status = Hazırlanıyor stock = 7 → 6 ``` Nihai asistan cevabı: ```text Yusuf Şimşek adına Dune kitabından 1 adet sipariş başarıyla oluşturuldu. Sipariş numarası: 2 Toplam tutar: 320 TL Sipariş durumu: Hazırlanıyor ``` ## 📷 Tool-Call Log Ekran Görüntüsü ![Tool-call terminal logu](assets/tool_call_log.png) Hugging Face’e yüklemeden önce terminal veya Gradio arayüzündeki tool-call logunun ekran görüntüsü: ```text assets/tool_call_log.png ``` adıyla eklenmelidir. ## ☁️ Hugging Face Space Ayarları Space ayarlarında aşağıdaki secret tanımlanmalıdır: ```text HF_TOKEN ``` İsteğe bağlı ortam değişkenleri: ```text HF_MODEL=Qwen/Qwen3-8B HF_PROVIDER=auto ``` ## ⚠️ Kalıcılık Notu Hugging Face Space’in varsayılan disk alanı kalıcı değildir. Space yeniden başlatıldığında çalışma sırasında oluşturulan demo siparişleri silinebilir ve örnek SQLite veritabanı yeniden oluşturulabilir. Bu proje bir eğitim ve canlı demo uygulamasıdır. Gerçek üretim ortamında PostgreSQL, MySQL veya yönetilen bir veritabanı servisi kullanılmalıdır. ## 🔐 Güvenlik - Hugging Face tokenı kaynak kodda tutulmaz. - Token, ortam değişkeni veya Hugging Face Space Secret olarak alınır. - `.env`, `.venv` ve çalışma zamanı SQLite dosyaları Git’e eklenmez. - Model doğrudan SQL sorgusu çalıştıramaz. - Model yalnızca izin verilen tool fonksiyonlarını çağırabilir. - Tool argümanları Python tarafında yeniden doğrulanır. ## 📊 Proje Durumu | Bileşen | Durum | |---|---| | SQLite veritabanı | ✅ | | 40 kitaplık başlangıç verisi | ✅ | | Kitap arama tool’u | ✅ | | Sipariş oluşturma tool’u | ✅ | | Stok güncelleme | ✅ | | Sipariş durumu sorgulama | ✅ | | JSON tool şemaları | ✅ | | Agent tool-call döngüsü | ✅ | | Qwen3-8B model bağlantısı | ✅ | | Terminal arayüzü | ✅ | | Gradio arayüzü | ✅ | | Hugging Face Space | 🚀 | ## 📷 Uygulama Ekran Görüntüleri ### Gradio Kullanıcı Arayüzü Aşağıdaki ekran görüntüsünde kullanıcı, bilim kurgu kategorisindeki stokta bulunan kitapları listelemektedir. Model `search_books` fonksiyonunu çağırmış ve yanıtını SQLite veritabanından dönen gerçek sonuçlara göre oluşturmuştur. ![Gradio kullanıcı arayüzü](assets/gradio_interface.jpeg) ### Tool-Call Ayrıntıları Aşağıdaki görüntüde model tarafından seçilen tool, gönderilen parametreler ve veritabanından dönen gerçek JSON sonucu görülmektedir. ![Tool-call logu](assets/tool_call_log.jpeg) ## 👨‍💻 Geliştirici **Yusuf Şimşek** Fırat Üniversitesi Yapay Zekâ ve Veri Mühendisliği ## 📄 Lisans Bu proje eğitim amacıyla hazırlanmıştır ve MIT Lisansı altında sunulmaktadır.