{
  "cells": [
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "!pip install -q litellm numpy\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "import os\n",
        "import sys\n",
        "from typing import List, Dict, Optional\n",
        "import litellm\n",
        "import numpy as np\n",
        "from litellm import completion, embedding\n",
        "\n",
        "# ===================================================================\n",
        "# CONFIGURATION\n",
        "# ===================================================================\n",
        "\n",
        "def setup_environment() -> str:\n",
        "    \"\"\"Safely retrieves the API key from env or user input.\"\"\"\n",
        "    api_key = os.getenv(\"GOOGLE_API_KEY\", \"\")\n",
        "    if not api_key:\n",
        "        from getpass import getpass\n",
        "        print(\"Credentials missing in environment.\")\n",
        "        api_key = getpass(\"Enter Google API Key: \")\n",
        "        os.environ[\"GOOGLE_API_KEY\"] = api_key\n",
        "    return api_key\n",
        "\n",
        "# 1. SETUP CREDENTIALS\n",
        "GOOGLE_API_KEY = setup_environment()\n",
        "\n",
        "# 2. MODEL SPECIFICATIONS\n",
        "# 'gemini-1.5-flash' is the optimal cost/performance point.\n",
        "# Prefix 'gemini/' tells litellm to use the Google AI Studio provider.\n",
        "model_name = \"gemini-2.5-flash\"\n",
        "\n",
        "DEFAULT_MODEL = f\"gemini/{model_name}\"\n",
        "\n",
        "EMBEDDING_DIM = 768  # text-embedding-004 produces 768-dimensional vectors\n",
        "\n",
        "\n",
        "print(f\"Targeting Model ID: {DEFAULT_MODEL}\")\n",
        "\n",
        "# ===================================================================\n",
        "# UTILITIES\n",
        "# ===================================================================\n",
        "\n",
        "def test_connection():\n",
        "    \"\"\"Simple verification unit to ensure model tags resolve correctly.\"\"\"\n",
        "    print(f\"\\n⚡ Configuration Loaded\")\n",
        "    print(f\"   Inference Model : {DEFAULT_MODEL}\")\n",
        "    print(f\"   Embedding Model : {EMBEDDING_MODEL} ({EMBEDDING_DIM}d)\")\n",
        "\n",
        "    try:\n",
        "        # Test Inference\n",
        "        print(\"\\n1. Testing Generation...\", end=\" \", flush=True)\n",
        "        response = completion(\n",
        "            model=DEFAULT_MODEL,\n",
        "            messages=[{\"role\": \"user\", \"content\": \"Hello, world!\"}]\n",
        "        )\n",
        "        print(\"OK.\")\n",
        "        print(f\"   Response: {response.choices[0].message.content.strip()}\")\n",
        "\n",
        "        # Test Embedding\n",
        "        print(\"2. Testing Embedding...\", end=\" \", flush=True)\n",
        "        vec_response = embedding(\n",
        "            model=EMBEDDING_MODEL,\n",
        "            input=[\"Hello, world!\"]\n",
        "        )\n",
        "        vec = vec_response.data[0]['embedding']\n",
        "        assert len(vec) == EMBEDDING_DIM, f\"Dimension mismatch: got {len(vec)}\"\n",
        "        print(\"OK.\")\n",
        "\n",
        "    except Exception as e:\n",
        "        print(f\"\\n❌ Error: {str(e)}\")\n",
        "        sys.exit(1)\n",
        "\n",
        "if __name__ == \"__main__\":\n",
        "    test_connection()"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "-*- coding: utf-8 -*-\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Temel Helper Fonksiyon: LLM Çağrısı\n",
        "\n",
        "Tüm LLM çağrıları için tek bir birleşik arayüz. Model, temperature, max_tokens gibi parametreleri kolayca kontrol edebiliriz.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def call_llm(\n",
        "    messages: List[Dict[str, str]],\n",
        "    model: Optional[str] = DEFAULT_MODEL,\n",
        "    temperature: float = 0.7,\n",
        "    max_tokens: int = 1024,\n",
        "    **kwargs\n",
        ") -> str:\n",
        "    if model is None:\n",
        "        model = DEFAULT_MODEL\n",
        "\n",
        "    try:\n",
        "        response = completion(\n",
        "            model=model,\n",
        "            messages=messages,\n",
        "            temperature=temperature,\n",
        "            max_tokens=max_tokens,\n",
        "            **kwargs\n",
        "        )\n",
        "        return response.choices[0].message.content\n",
        "    except Exception as e:\n",
        "        return f\"❌ Hata: {str(e)}\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "LLM completion için birleşik arayüz.\n",
        "\n",
        "    Args:\n",
        "        messages: OpenAI formatında chat mesajları\n",
        "        model: Model tanımlayıcı (None ise DEFAULT_MODEL kullanılır)\n",
        "        temperature: Sampling temperature (0.0-1.0)\n",
        "        max_tokens: Üretilecek maksimum token sayısı\n",
        "\n",
        "    Returns:\n",
        "        Model yanıtı\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Faz 1: Stokastik Operatör\n",
        "\n",
        "Şimdi temel stokastik operatörü tanımlıyoruz: Büyük Dil Modeli ve onun prompt mühendisliği ile kontrol mekanizmaları.\n",
        "\n",
        "### 1.1 LLM Koşullu Dağılım Olarak\n",
        "\n",
        "Bir LLM, $P(y|x, \\theta)$ koşullu olasılık dağılımı olarak görülebilir:\n",
        "- $x$: girdi promptu (tokenlar)\n",
        "- $y$: çıktı dizisi (tokenlar)\n",
        "- $\\theta$: model parametreleri (dondurulmuş, önceden eğitilmiş)\n",
        "\n",
        "$\\theta$'yı eğitmiyoruz. Bunun yerine dağılımı şu yollarla manipüle ediyoruz:\n",
        "1. **Prompt yapısı** (zero-shot, few-shot, chain-of-thought)\n",
        "2. **Sampling parametreleri** (temperature, top_p)\n",
        "3. **Bağlam mühendisliği** (system messages, rol atama)\n",
        "\n",
        "### 1.2 Prompt Mühendisliği Teknikleri\n",
        "\n",
        "**Zero-Shot Prompting:** Örnek vermeden doğrudan talimat.  \n",
        "**Few-Shot Prompting:** Format ve mantığı yönlendirmek için örnekler sağlama.  \n",
        "**Chain-of-Thought (CoT):** Açık adım adım mantık yürütme.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "zero_shot_prompt = \"Bu metnin duygusunu analiz et ve sadece tek kelime ile cevap ver: Pozitif, Negatif veya Nötr. Metin: Deniz sakin, lakin dalgalar\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "print(zero_shot_prompt)"
      ],
      "metadata": {},
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"=\"*80)\n",
        "print(\"ZERO-SHOT PROMPTING ÖRNEĞİ\")\n",
        "print(\"=\"*80)\n",
        "print(f\"\\n📝 Prompt:\\n{zero_shot_prompt}\\n\")\n",
        "print(\"-\"*80)\n",
        "\n",
        "response = call_llm(\n",
        "    [{\"role\": \"user\", \"content\": zero_shot_prompt}],\n",
        "    temperature=0.2,\n",
        "    max_tokens=50\n",
        ")\n",
        "\n",
        "print(f\"\\n🤖 Model Yanıtı: {response}\")\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {
        "collapsed": true
      },
      "source": [
        "few_shot_prompt = str(\"\"\"Şu örneklere bakarak duyguyu sınıflandır:\n",
        "\n",
        "Metin: Bu telefon harika! Şimdiye kadarki en iyi alışverişim.\n",
        "Duygu: Pozitif\n",
        "\n",
        "Metin: Berbat müşteri hizmetleri. Çok hayal kırıklığına uğradım.\n",
        "Duygu: Negatif\n",
        "\n",
        "Metin: Ürün zamanında geldi.\n",
        "Duygu: Nötr\n",
        "\n",
        "Metin: Tasarımını kesinlikle sevdim ama pil ömrü daha iyi olabilirdi.\n",
        "Duygu:\n",
        "\"\"\")\n",
        "\n",
        "print(\"=\"*80)\n",
        "print(\"FEW-SHOT PROMPTING ÖRNEĞİ\")\n",
        "print(\"=\"*80)\n",
        "print(f\"\\n📝 Prompt (örneklerle):\\n{few_shot_prompt}\\n\")\n",
        "print(\"-\"*80)\n",
        "\n",
        "response = call_llm(\n",
        "    [{\"role\": \"user\", \"content\": few_shot_prompt}],\n",
        "    temperature=0.2,\n",
        "    max_tokens=50\n",
        ")\n",
        "\n",
        "print(f\"\\n🤖 Model Yanıtı: {response}\")\n",
        "print(\"\\n💡 Gözlem: Few-shot, modelin karma duyguları anlamasını sağlar.\")\n",
        "print(\"=\"*80)\n",
        "\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "cot_prompt = \"Bir mağazada bir ürünün fiyatı 80 TL idi. İlk olarak %25 indirim yapıldı, ardından indirimli fiyata %18 KDV eklendi. Ürünün son fiyatı kaç TL'dir? Lütfen adım adım düşünerek cevabı bul.\""
      ],
      "metadata": {},
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "print(cot_prompt)"
      ],
      "metadata": {},
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"=\"*80)\n",
        "print(\"CHAIN-OF-THOUGHT PROMPTING ÖRNEĞİ\")\n",
        "print(\"=\"*80)\n",
        "print(f\"\\n📝 Prompt:\\n{cot_prompt}\\n\")\n",
        "print(\"-\"*80)\n",
        "\n",
        "response = call_llm(\n",
        "    [{\"role\": \"user\", \"content\": cot_prompt}],\n",
        "    temperature=0.0,\n",
        "    max_tokens=500\n",
        ")\n",
        "\n",
        "print(f\"\\n🤖 Model Yanıtı:\\n{response}\")\n",
        "print(\"\\n📐 Doğru Cevap: 80 * 0.75 = 60 TL, sonra 60 * 1.18 = 70.80 TL\")\n",
        "print(\"\\n💡 CoT, karmaşık çok adımlı mantık yürütmeyi mümkün kılar.\")\n",
        "print(\"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n",
        "\n",
        "```\n",
        "# This is formatted as code\n",
        "```\n",
        "\n",
        "### 1.3 Temperature: Stokastiği Kontrol Etme\n",
        "\n",
        "Temperature $T$, softmax dağılımını değiştirir:\n",
        "\n",
        "$$P(y_i|x) = \\frac{e^{z_i/T}}{\\sum_j e^{z_j/T}}$$\n",
        "\n",
        "- $T \\to 0$: Deterministik (argmax)\n",
        "- $T = 1$: Orijinal dağılım\n",
        "- $T > 1$: Daha uniform (yaratıcı ama daha az tutarlı)\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "creative_prompt = \"Bu cümleyi tam 10 kelime ile tamamla: Yapay zekanın geleceği\"\n",
        "\n",
        "print(\"=\"*80)\n",
        "print(\"TEMPERATURE PARAMETRESİ DENEYİ\")\n",
        "print(\"=\"*80)\n",
        "print(f\"\\n📝 Prompt: {creative_prompt}\\n\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "for temp in [0.0, 0.5, 1.0]:\n",
        "    print(f\"\\n🌡️  Temperature = {temp}\")\n",
        "    print(\"-\"*80)\n",
        "\n",
        "    for i in range(3):\n",
        "        response = call_llm(\n",
        "            [{\"role\": \"user\", \"content\": creative_prompt}],\n",
        "            temperature=temp,\n",
        "            max_tokens=30\n",
        "        )\n",
        "        print(f\"   Deneme {i+1}: {response}\")\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"\\n💡 Gözlemler:\")\n",
        "print(\"   - T=0.0: Deterministik, her seferinde aynı çıktı\")\n",
        "print(\"   - T=0.5: Orta derece çeşitlilik, tutarlı kalite\")\n",
        "print(\"   - T=1.0: Yüksek yaratıcılık, çeşitli çıktılar\")\n",
        "print(\"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Faz 2: Semantik Uzay\n",
        "\n",
        "Şimdi embedding'ler yoluyla semantik uzay oluşturuyor ve Retrieval-Augmented Generation (RAG) uyguluyoruz.\n",
        "\n",
        "### 2.1 Embeddings: Ayrık Tokenlardan Sürekli Uzaya\n",
        "\n",
        "Bir embedding fonksiyonu $\\phi: \\mathcal{V} \\to \\mathbb{R}^d$ kelime dağarcığını sürekli vektör uzayına eşler:\n",
        "\n",
        "$$\\phi(\\text{\"kedi\"}) \\approx \\phi(\\text{\"yavru kedi\"}), \\quad \\phi(\\text{\"kedi\"}) \\not\\approx \\phi(\\text{\"araba\"})$$\n",
        "\n",
        "**Cosine Benzerliği:**\n",
        "$$\\text{sim}(u, v) = \\frac{u \\cdot v}{\\|u\\| \\|v\\|} \\in [-1, 1]$$\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "sentences = [\n",
        "    \"Makine öğrenmesi teknolojiyi dönüştürüyor.\",\n",
        "    \"Yapay zeka bilişimi devrim yapıyor.\",\n",
        "    \"Dağlarda yürüyüş yapmaktan hoşlanırım.\"\n",
        "]\n",
        "\n",
        "print(\"=\"*80)\n",
        "print(\"EMBEDDING BENZERLİĞİ GÖSTERİMİ\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "result = embedding(model=EMBEDDING_MODEL, input=sentences)\n",
        "embeddings_array = np.array([item['embedding'] for item in result.data])\n",
        "print(f\"\\n✓ {len(sentences)} cümle için embedding oluşturuldu\")\n",
        "print(f\"✓ Embedding boyutu: {embeddings_array.shape[1]}\\n\")\n",
        "\n",
        "def cosine_similarity(v1, v2):\n",
        "    return np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2))\n",
        "\n",
        "print(\"📊 Benzerlik Matrisi:\")\n",
        "print(\"-\"*80)\n",
        "\n",
        "sim_1_2 = cosine_similarity(embeddings_array[0], embeddings_array[1])\n",
        "sim_1_3 = cosine_similarity(embeddings_array[0], embeddings_array[2])\n",
        "\n",
        "print(f\"\\nCümle 1: '{sentences[0]}'\")\n",
        "print(f\"Cümle 2: '{sentences[1]}'\")\n",
        "print(f\"Benzerlik: {sim_1_2:.4f} ← Yüksek (ikisi de YZ/ML hakkında)\\n\")\n",
        "\n",
        "print(f\"Cümle 1: '{sentences[0]}'\")\n",
        "print(f\"Cümle 3: '{sentences[2]}'\")\n",
        "print(f\"Benzerlik: {sim_1_3:.4f} ← Düşük (farklı konular)\\n\")\n",
        "\n",
        "print(\"=\"*80)\n",
        "print(\"\\n💡 Embedding'ler semantik anlamı yakalar, sadece kelime eşleşmesini değil.\")\n",
        "print(\"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.2 RAG Mimarisi: Retrieval ile Generation'ı Güçlendirme\n",
        "\n",
        "**RAG Pipeline:**\n",
        "1. **İndeksleme (Offline):** $\\{d_1, ..., d_N\\} \\xrightarrow{\\phi} \\{v_1, ..., v_N\\}$ (dokümanlar → embedding'ler)\n",
        "2. **Retrieval (Online):** $q \\xrightarrow{\\phi} v_q$, en benzer $D_{top-k} = \\text{TopK}(\\text{sim}(v_q, v_i))$'yi bul\n",
        "3. **Generation:** $\\text{LLM}(q, D_{top-k}) \\to \\text{cevap}$\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "class SemanticSearchEngine:\n",
        "    def __init__(self, embedding_model: str = EMBEDDING_MODEL, embedding_dim: int = EMBEDDING_DIM):\n",
        "        self.model = embedding_model\n",
        "        self.dim = embedding_dim\n",
        "        self.documents: List[str] = []\n",
        "        self.document_embeddings: Optional[np.ndarray] = None\n",
        "        self.metadata: List[Dict] = []\n",
        "\n",
        "    def _embed_texts(self, texts: List[str]) -> np.ndarray:\n",
        "        result = embedding(model=self.model, input=texts)\n",
        "        embeddings_list = [item['embedding'] for item in result.data]\n",
        "        return np.array(embeddings_list)\n",
        "\n",
        "    def index_documents(self, documents: List[str], metadata: Optional[List[Dict]] = None) -> None:\n",
        "        print(f\"{len(documents)} doküman indeksleniyor...\")\n",
        "        self.documents = documents\n",
        "        self.document_embeddings = self._embed_texts(documents)\n",
        "        self.metadata = metadata if metadata else [{}] * len(documents)\n",
        "        print(f\"✓ {len(documents)} doküman indekslendi\")\n",
        "        print(f\"✓ İndeks boyutu: {self.document_embeddings.nbytes / 1024:.2f} KB\")\n",
        "\n",
        "    def search(self, query: str, top_k: int = 3, return_scores: bool = True) -> List[Dict]:\n",
        "        if self.document_embeddings is None:\n",
        "            raise ValueError(\"Hiç doküman indekslenmemiş. Önce index_documents() çağırın.\")\n",
        "\n",
        "        query_embedding = self._embed_texts([query])[0]\n",
        "        similarities = np.dot(self.document_embeddings, query_embedding)\n",
        "        top_k_indices = np.argsort(similarities)[::-1][:top_k]\n",
        "\n",
        "        results = []\n",
        "        for idx in top_k_indices:\n",
        "            result = {\n",
        "                'document': self.documents[idx],\n",
        "                'metadata': self.metadata[idx],\n",
        "            }\n",
        "            if return_scores:\n",
        "                result['score'] = float(similarities[idx])\n",
        "            results.append(result)\n",
        "        return results"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Embedding'ler kullanarak production semantik arama.\n",
        "\n",
        "    İlgiyi ayırır:\n",
        "    - İndeksleme: Tek seferlik embedding üretimi\n",
        "    - Sorgu: Hızlı benzerlik hesaplaması\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def __init__(self, embedding_model: str = EMBEDDING_MODEL, embedding_dim: int = EMBEDDING_DIM):\n",
        "        self.model = embedding_model\n",
        "        self.dim = embedding_dim\n",
        "        self.documents: List[str] = []\n",
        "        self.document_embeddings: Optional[np.ndarray] = None\n",
        "        self.metadata: List[Dict] = []\n",
        "\n",
        "def _embed_texts(self, texts: List[str]) -> np.ndarray:\n",
        "        result = embedding(model=self.model, input=texts)\n",
        "        embeddings_list = [item['embedding'] for item in result.data]\n",
        "        return np.array(embeddings_list)\n",
        "\n",
        "def index_documents(self, documents: List[str], metadata: Optional[List[Dict]] = None) -> None:\n",
        "        print(f\"{len(documents)} doküman indeksleniyor...\")\n",
        "        self.documents = documents\n",
        "        self.document_embeddings = self._embed_texts(documents)\n",
        "        self.metadata = metadata if metadata else [{}] * len(documents)\n",
        "        print(f\"✓ {len(documents)} doküman indekslendi\")\n",
        "        print(f\"✓ İndeks boyutu: {self.document_embeddings.nbytes / 1024:.2f} KB\")\n",
        "\n",
        "def search(self, query: str, top_k: int = 3, return_scores: bool = True) -> List[Dict]:\n",
        "        if self.document_embeddings is None:\n",
        "            raise ValueError(\"Hiç doküman indekslenmemiş. Önce index_documents() çağırın.\")\n",
        "\n",
        "        query_embedding = self._embed_texts([query])[0]\n",
        "        similarities = np.dot(self.document_embeddings, query_embedding)\n",
        "        top_k_indices = np.argsort(similarities)[::-1][:top_k]\n",
        "\n",
        "        results = []\n",
        "        for idx in top_k_indices:\n",
        "            result = {\n",
        "                'document': self.documents[idx],\n",
        "                'metadata': self.metadata[idx],\n",
        "            }\n",
        "            if return_scores:\n",
        "                result['score'] = float(similarities[idx])\n",
        "            results.append(result)\n",
        "        return results\n",
        "\n",
        "print(\"✓ SemanticSearchEngine sınıfı tanımlandı\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### RAG Sistemi\n",
        "\n",
        "Tam RAG pipeline: retrieval + generation + kaynak atıfı + hata yönetimi.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "class ProductionRAGSystem:\n",
        "    def __init__(\n",
        "        self,\n",
        "        embedding_model: str = EMBEDDING_MODEL,\n",
        "        generative_model: str = DEFAULT_MODEL,\n",
        "        embedding_dim: int = EMBEDDING_DIM\n",
        "    ):\n",
        "        self.generative_model = generative_model\n",
        "        self.search_engine = SemanticSearchEngine(embedding_model, embedding_dim)\n",
        "        self.query_count = 0\n",
        "\n",
        "    def index_knowledge_base(self, documents: List[str], metadata: Optional[List[Dict]] = None) -> None:\n",
        "        self.search_engine.index_documents(documents, metadata)\n",
        "        print(f\"✓ Bilgi tabanı {len(documents)} doküman ile hazır\")\n",
        "\n",
        "    def generate_answer(self, query: str, retrieved_docs: List[Dict], max_context_length: int = 2000) -> Dict:\n",
        "        context_parts = []\n",
        "        sources = []\n",
        "\n",
        "        for i, doc in enumerate(retrieved_docs[:5], 1):\n",
        "            context_parts.append(f\"[Doküman {i}]\\n{doc['document']}\")\n",
        "            sources.append({\n",
        "                'document': doc['document'],\n",
        "                'metadata': doc['metadata'],\n",
        "                'relevance_score': doc.get('score', 0.0)\n",
        "            })\n",
        "\n",
        "        context = \"\\n\\n\".join(context_parts)\n",
        "\n",
        "        if len(context) > max_context_length * 4:\n",
        "            context = context[:max_context_length * 4] + \"\\n\\n[... bağlam kesildi ...]\"\n",
        "\n",
        "        rag_prompt = f\"\"\"Sen yardımsever bir YZ asistanısın. Kullanıcının sorusunu SADECE aşağıdaki bağlamdaki bilgileri kullanarak cevapla.\n",
        "\n",
        "KURALLAR:\n",
        "1. Cevabını tamamen sağlanan bağlama dayandır\n",
        "2. Bağlamda yeterli bilgi yoksa bunu açıkça belirt\n",
        "3. Hangi doküman(lar)ı kullandığını belirt (örn: \"Doküman 2'ye göre...\")\n",
        "4. Kısa ama kapsamlı ol\n",
        "\n",
        "Bağlam:\n",
        "{context}\n",
        "\n",
        "Kullanıcı Sorusu: {query}\n",
        "\n",
        "Cevap:\"\"\"\n",
        "\n",
        "        try:\n",
        "            answer = call_llm(\n",
        "                [{\"role\": \"user\", \"content\": rag_prompt}],\n",
        "                model=self.generative_model,\n",
        "                temperature=0.3,\n",
        "                max_tokens=500\n",
        "            )\n",
        "            success = True\n",
        "            error = None\n",
        "        except Exception as e:\n",
        "            answer = f\"Cevap oluşturma hatası: {str(e)}\"\n",
        "            success = False\n",
        "            error = str(e)\n",
        "\n",
        "        return {\n",
        "            'answer': answer,\n",
        "            'sources': sources,\n",
        "            'query': query,\n",
        "            'success': success,\n",
        "            'error': error\n",
        "        }\n",
        "\n",
        "    def query(self, query: str, top_k: int = 3, return_sources: bool = True, verbose: bool = True) -> Dict:\n",
        "        self.query_count += 1\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n{'='*80}\")\n",
        "            print(f\"Sorgu #{self.query_count}: {query}\")\n",
        "            print('='*80)\n",
        "\n",
        "        retrieved = self.search_engine.search(query, top_k=top_k, return_scores=True)\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n✓ {len(retrieved)} doküman alındı\")\n",
        "\n",
        "        result = self.generate_answer(query, retrieved)\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n📝 Cevap:\\n{result['answer']}\")\n",
        "            if return_sources:\n",
        "                print(f\"\\n📚 Kaynaklar:\")\n",
        "                for i, src in enumerate(result['sources'], 1):\n",
        "                    print(f\"  [{i}] {src['document'][:60]}... (skor: {src['relevance_score']:.3f})\")\n",
        "\n",
        "        if not return_sources:\n",
        "            del result['sources']\n",
        "\n",
        "        return result"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Tam RAG sistemi: Retrieval + Generation.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def __init__(\n",
        "        self,\n",
        "        embedding_model: str = EMBEDDING_MODEL,\n",
        "        generative_model: str = DEFAULT_MODEL,\n",
        "        embedding_dim: int = EMBEDDING_DIM\n",
        "    ):\n",
        "        self.generative_model = generative_model\n",
        "        self.search_engine = SemanticSearchEngine(embedding_model, embedding_dim)\n",
        "        self.query_count = 0\n",
        "\n",
        "def index_knowledge_base(self, documents: List[str], metadata: Optional[List[Dict]] = None) -> None:\n",
        "        self.search_engine.index_documents(documents, metadata)\n",
        "        print(f\"✓ Bilgi tabanı {len(documents)} doküman ile hazır\")\n",
        "\n",
        "def generate_answer(self, query: str, retrieved_docs: List[Dict], max_context_length: int = 2000) -> Dict:\n",
        "        context_parts = []\n",
        "        sources = []\n",
        "\n",
        "        for i, doc in enumerate(retrieved_docs[:5], 1):\n",
        "            context_parts.append(f\"[Doküman {i}]\\n{doc['document']}\")\n",
        "            sources.append({\n",
        "                'document': doc['document'],\n",
        "                'metadata': doc['metadata'],\n",
        "                'relevance_score': doc.get('score', 0.0)\n",
        "            })\n",
        "\n",
        "        context = \"\\n\\n\".join(context_parts)\n",
        "\n",
        "        if len(context) > max_context_length * 4:\n",
        "            context = context[:max_context_length * 4] + \"\\n\\n[... bağlam kesildi ...]\"\n",
        "\n",
        "        rag_prompt = f\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Sen yardımsever bir YZ asistanısın. Kullanıcının sorusunu SADECE aşağıdaki bağlamdaki bilgileri kullanarak cevapla.\n",
        "\n",
        "KURALLAR:\n",
        "1. Cevabını tamamen sağlanan bağlama dayandır\n",
        "2. Bağlamda yeterli bilgi yoksa bunu açıkça belirt\n",
        "3. Hangi doküman(lar)ı kullandığını belirt (örn: \"Doküman 2'ye göre...\")\n",
        "4. Kısa ama kapsamlı ol\n",
        "\n",
        "Bağlam:\n",
        "{context}\n",
        "\n",
        "Kullanıcı Sorusu: {query}\n",
        "\n",
        "Cevap:\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def generate_answer(self, query: str, retrieved_docs: List[Dict], max_context_length: int = 2000) -> Dict:\n",
        "        context_parts = []\n",
        "        sources = []\n",
        "\n",
        "        for i, doc in enumerate(retrieved_docs[:5], 1):\n",
        "            context_parts.append(f\"[Doküman {i}]\\n{doc['document']}\")\n",
        "            sources.append({\n",
        "                'document': doc['document'],\n",
        "                'metadata': doc['metadata'],\n",
        "                'relevance_score': doc.get('score', 0.0)\n",
        "            })\n",
        "\n",
        "        context = \"\\n\\n\".join(context_parts)\n",
        "\n",
        "        if len(context) > max_context_length * 4:\n",
        "            context = context[:max_context_length * 4] + \"\\n\\n[... bağlam kesildi ...]\"\n",
        "\n",
        "        rag_prompt = f\"\"\"Sen yardımsever bir YZ asistanısın. Kullanıcının sorusunu SADECE aşağıdaki bağlamdaki bilgileri kullanarak cevapla.\\n\\nKURALLAR:\\n1. Cevabını tamamen sağlanan bağlama dayandır\\n2. Bağlamda yeterli bilgi yoksa bunu açıkça belirt\\n3. Hangi doküman(lar)ı kullandığını belirt (örn: \"Doküman 2'ye göre...\")\\n4. Kısa ama kapsamlı ol\\n\\nBağlam:\\n{context}\\n\\nKullanıcı Sorusu: {query}\\n\\nCevap:\"\"\"\n",
        "\n",
        "        try:\n",
        "            answer = call_llm(\n",
        "                [{\"role\": \"user\", \"content\": rag_prompt}],\n",
        "                model=self.generative_model,\n",
        "                temperature=0.3,\n",
        "                max_tokens=500\n",
        "            )\n",
        "            success = True\n",
        "            error = None\n",
        "        except Exception as e:\n",
        "            answer = f\"Cevap oluşturma hatası: {str(e)}\"\n",
        "            success = False\n",
        "            error = str(e)\n",
        "\n",
        "        return {\n",
        "            'answer': answer,\n",
        "            'sources': sources,\n",
        "            'query': query,\n",
        "            'success': success,\n",
        "            'error': error\n",
        "        }"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "code",
      "source": [
        "def query(self, query: str, top_k: int = 3, return_sources: bool = True, verbose: bool = True) -> Dict:\n",
        "        self.query_count += 1\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n{'='*80}\")\n",
        "            print(f\"Sorgu #{self.query_count}: {query}\")\n",
        "            print('='*80)\n",
        "\n",
        "        retrieved = self.search_engine.search(query, top_k=top_k, return_scores=True)\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n✓ {len(retrieved)} doküman alındı\")\n",
        "\n",
        "        result = self.generate_answer(query, retrieved)\n",
        "\n",
        "        if verbose:\n",
        "            print(f\"\\n📝 Cevap:\\n{result['answer']}\")\n",
        "            if return_sources:\n",
        "                print(f\"\\n📚 Kaynaklar:\")\n",
        "                for i, src in enumerate(result['sources'], 1):\n",
        "                    print(f\"  [{i}] {src['document'][:60]}... (skor: {src['relevance_score']:.3f})\")\n",
        "\n",
        "        if not return_sources:\n",
        "            del result['sources']\n",
        "\n",
        "        return result\n",
        "\n",
        "print(\"✓ 'query' metodu tanımlandı\")"
      ],
      "metadata": {},
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### RAG Sistemi Demosu\n",
        "\n",
        "Örnek bilgi tabanı oluşturup test sorguları çalıştıralım.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "documents = [\n",
        "    \"Makine öğrenmesi, açık programlama olmadan veriden öğrenen bir YZ alt kümesidir.\",\n",
        "    \"Derin öğrenme, hiyerarşik temsiller öğrenmek için çok katmanlı sinir ağları kullanır.\",\n",
        "    \"Transfer öğrenme, yeni görevleri verimli şekilde çözmek için önceden eğitilmiş modelleri kullanır.\",\n",
        "    \"Pekiştirmeli öğrenme, ödül sinyalleri ile deneme-yanılma yoluyla ajanları eğitir.\",\n",
        "    \"GPT ve Gemini gibi büyük dil modelleri insan benzeri metin anlayıp üretebilir.\",\n",
        "    \"Embedding'ler, kelimeleri veya dokümanları sürekli uzayda yoğun vektörler olarak temsil eder.\",\n",
        "    \"Retrieval-augmented generation, bilgi alımı ile metin üretimini birleştirir.\",\n",
        "]\n",
        "\n",
        "metadata = [\n",
        "    {\"category\": \"ML Temelleri\", \"zorluk\": \"başlangıç\"},\n",
        "    {\"category\": \"Derin Öğrenme\", \"zorluk\": \"orta\"},\n",
        "    {\"category\": \"Transfer Öğrenme\", \"zorluk\": \"orta\"},\n",
        "    {\"category\": \"RL\", \"zorluk\": \"ileri\"},\n",
        "    {\"category\": \"LLM'ler\", \"zorluk\": \"ileri\"},\n",
        "    {\"category\": \"Embedding'ler\", \"zorluk\": \"orta\"},\n",
        "    {\"category\": \"RAG\", \"zorluk\": \"ileri\"},\n",
        "]\n",
        "\n",
        "rag_system = ProductionRAGSystem()\n",
        "rag_system.index_knowledge_base(documents, metadata)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"RAG SİSTEMİ GÖSTERİMİ\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "test_query = \"Önceden eğitilmiş modelleri yeni bir görev için nasıl kullanabilirim?\"\n",
        "result = rag_system.query(test_query, top_k=3)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"\\n💡 RAG, LLM'lerin harici bilgiye dinamik erişimini sağlar.\")\n",
        "print(\"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Faz 3: Deterministik Arayüz\n",
        "\n",
        "Şimdi LLM'i function calling yoluyla deterministik araçlarla donatıyoruz.\n",
        "\n",
        "### 3.1 Function Calling: Stokastikten Deterministiğe\n",
        "\n",
        "**Zorluk:** LLM'ler olasılıksaldır ve halüsinasyon yapabilir.  \n",
        "**Çözüm:** Belirli görevler için deterministik araçlar sağla.\n",
        "\n",
        "**Mimari:**\n",
        "1. **Araç Bildirimi:** Mevcut fonksiyonları tanımlayan JSON şema\n",
        "2. **Araç Seçimi:** LLM hangi aracı hangi parametrelerle kullanacağına karar verir\n",
        "3. **Araç Çalıştırma:** Sistem fonksiyonu deterministik şekilde çalıştırır\n",
        "4. **Sonuç Entegrasyonu:** LLM araç çıktısını doğal dile sentezler\n",
        "\n",
        "### Araç İmplementasyonları\n",
        "\n",
        "Üç temel deterministik fonksiyon tanımlıyoruz: hava durumu, hesaplama ve bilgi tabanı araması.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def get_current_weather(location: str, unit: str = \"celsius\") -> str:\n",
        "    weather_db = {\n",
        "        \"istanbul\": {\"temp_c\": 18, \"condition\": \"Parçalı bulutlu\", \"humidity\": 72},\n",
        "        \"ankara\": {\"temp_c\": 12, \"condition\": \"Güneşli\", \"humidity\": 45},\n",
        "        \"izmir\": {\"temp_c\": 22, \"condition\": \"Açık\", \"humidity\": 68},\n",
        "        \"antalya\": {\"temp_c\": 25, \"condition\": \"Güneşli\", \"humidity\": 55}\n",
        "    }\n",
        "\n",
        "    location_key = location.lower().replace(\"ı\", \"i\")\n",
        "    data = weather_db.get(location_key, {\"temp_c\": 20, \"condition\": \"Bilinmiyor\", \"humidity\": 50})\n",
        "\n",
        "    temp = data[\"temp_c\"]\n",
        "    if unit == \"fahrenheit\":\n",
        "        temp = (temp * 9/5) + 32\n",
        "\n",
        "    return json.dumps({\n",
        "        \"location\": location,\n",
        "        \"temperature\": temp,\n",
        "        \"unit\": unit,\n",
        "        \"condition\": data[\"condition\"],\n",
        "        \"humidity\": data[\"humidity\"]\n",
        "    })"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Bir konum için güncel hava durumunu al.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def calculate(expression: str) -> str:\n",
        "    try:\n",
        "        allowed_chars = set(\"0123456789+-*/(). \")\n",
        "        if not all(c in allowed_chars for c in expression):\n",
        "            return json.dumps({\"error\": \"Geçersiz karakterler tespit edildi\"})\n",
        "\n",
        "        result = eval(expression)\n",
        "        return json.dumps({\"expression\": expression, \"result\": result})\n",
        "    except Exception as e:\n",
        "        return json.dumps({\"error\": f\"Hesaplama hatası: {str(e)}\"})"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Matematiksel ifadeyi güvenli şekilde değerlendir.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def search_knowledge_base(query: str) -> str:\n",
        "    mock_results = [\n",
        "        \"Transfer öğrenme, yeni görevler için önceden eğitilmiş modelleri kullanmaya izin verir.\",\n",
        "        \"Fine-tuning, önceden eğitilmiş bir modeli belirli bir alana adapte eder.\"\n",
        "    ]\n",
        "\n",
        "    return json.dumps({\n",
        "        \"query\": query,\n",
        "        \"results\": mock_results\n",
        "    })"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "RAG bilgi tabanında ara.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"✓ Araç fonksiyonları tanımlandı:\")\n",
        "print(\"  - get_current_weather()\")\n",
        "print(\"  - calculate()\")\n",
        "print(\"  - search_knowledge_base()\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### Araç Kaydı (Tool Registry)\n",
        "\n",
        "JSON Schema bildirimleri + Python fonksiyon eşleştirmesi.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "tools = [\n",
        "    {\n",
        "        \"type\": \"function\",\n",
        "        \"function\": {\n",
        "            \"name\": \"get_current_weather\",\n",
        "            \"description\": \"Belirli bir konum için güncel hava durumunu al\",\n",
        "            \"parameters\": {\n",
        "                \"type\": \"object\",\n",
        "                \"properties\": {\n",
        "                    \"location\": {\n",
        "                        \"type\": \"string\",\n",
        "                        \"description\": \"Şehir adı, örn: Istanbul, Ankara, Izmir\"\n",
        "                    },\n",
        "                    \"unit\": {\n",
        "                        \"type\": \"string\",\n",
        "                        \"enum\": [\"celsius\", \"fahrenheit\"],\n",
        "                        \"description\": \"Sıcaklık birimi\"\n",
        "                    }\n",
        "                },\n",
        "                \"required\": [\"location\"]\n",
        "            }\n",
        "        }\n",
        "    },\n",
        "    {\n",
        "        \"type\": \"function\",\n",
        "        \"function\": {\n",
        "            \"name\": \"calculate\",\n",
        "            \"description\": \"Matematiksel ifadeyi değerlendir\",\n",
        "            \"parameters\": {\n",
        "                \"type\": \"object\",\n",
        "                \"properties\": {\n",
        "                    \"expression\": {\n",
        "                        \"type\": \"string\",\n",
        "                        \"description\": \"Matematiksel ifade, örn: '25 * 3', '100 / 4'\"\n",
        "                    }\n",
        "                },\n",
        "                \"required\": [\"expression\"]\n",
        "            }\n",
        "        }\n",
        "    },\n",
        "    {\n",
        "        \"type\": \"function\",\n",
        "        \"function\": {\n",
        "            \"name\": \"search_knowledge_base\",\n",
        "            \"description\": \"Bilgi tabanında bilgi ara\",\n",
        "            \"parameters\": {\n",
        "                \"type\": \"object\",\n",
        "                \"properties\": {\n",
        "                    \"query\": {\n",
        "                        \"type\": \"string\",\n",
        "                        \"description\": \"Arama sorgusu veya soru\"\n",
        "                    }\n",
        "                },\n",
        "                \"required\": [\"query\"]\n",
        "            }\n",
        "        }\n",
        "    }\n",
        "]\n",
        "\n",
        "tool_functions = {\n",
        "    \"get_current_weather\": get_current_weather,\n",
        "    \"calculate\": calculate,\n",
        "    \"search_knowledge_base\": search_knowledge_base\n",
        "}\n",
        "\n",
        "print(\"✓ Araç kaydı yapılandırıldı\")\n",
        "print(f\"  Mevcut araçlar: {list(tool_functions.keys())}\")\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Faz 4: Otonom Döngü\n",
        "\n",
        "Şimdi ajanı oluşturuyoruz: hangi araçları ne zaman kullanacağı hakkında akıl yürüten otonom bir sistem.\n",
        "\n",
        "### 4.1 ReAct Kalıbı\n",
        "\n",
        "**ReAct = Reasoning (Akıl Yürütme) + Acting (Eylem)**\n",
        "\n",
        "Ajan döngüsü:\n",
        "```\n",
        "while not done:\n",
        "    1. Akıl Yürüt: LLM durumu analiz eder\n",
        "    2. Eyleme Geç: LLM araç ve parametreleri seçer\n",
        "    3. Gözlemle: Sistem aracı çalıştırır, sonuç döner\n",
        "    4. Güncelle: Gözlemi bağlama ekle\n",
        "```\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "def run_agent(\n",
        "    user_query: str,\n",
        "    model: str = DEFAULT_MODEL,\n",
        "    max_iterations: int = 5,\n",
        "    verbose: bool = True\n",
        ") -> str:\n",
        "    if verbose:\n",
        "        print(\"=\"*80)\n",
        "        print(\"🤖 AJAN BAŞLADI\")\n",
        "        print(\"=\"*80)\n",
        "        print(f\"📥 Kullanıcı Sorgusu: {user_query}\\n\")\n",
        "\n",
        "    messages = [{\"role\": \"user\", \"content\": user_query}]\n",
        "\n",
        "    for iteration in range(1, max_iterations + 1):\n",
        "        if verbose:\n",
        "            print(f\"\\n{'─'*80}\")\n",
        "            print(f\"🔄 İTERASYON {iteration}\")\n",
        "            print(f\"{'─'*80}\")\n",
        "\n",
        "        try:\n",
        "            response = completion(\n",
        "                model=model,\n",
        "                messages=messages,\n",
        "                tools=tools,\n",
        "                temperature=0.1\n",
        "            )\n",
        "\n",
        "            response_message = response.choices[0].message\n",
        "            tool_calls = getattr(response_message, 'tool_calls', None)\n",
        "\n",
        "            if not tool_calls:\n",
        "                final_answer = response_message.content\n",
        "                if verbose:\n",
        "                    print(f\"\\n✅ FİNAL CEVAP:\\n{final_answer}\")\n",
        "                    print(\"=\"*80)\n",
        "                return final_answer\n",
        "\n",
        "            if verbose:\n",
        "                print(f\"\\n🔧 Model {len(tool_calls)} araç çağrısı istiyor:\\n\")\n",
        "\n",
        "            messages.append(response_message)\n",
        "\n",
        "            for tool_call in tool_calls:\n",
        "                function_name = tool_call.function.name\n",
        "                function_args = json.loads(tool_call.function.arguments)\n",
        "\n",
        "                if verbose:\n",
        "                    print(f\"   📞 Fonksiyon: {function_name}()\")\n",
        "                    print(f\"      Argümanlar: {json.dumps(function_args, ensure_ascii=False, indent=10)}\")\n",
        "\n",
        "                function_to_call = tool_functions[function_name]\n",
        "                function_response = function_to_call(**function_args)\n",
        "\n",
        "                if verbose:\n",
        "                    print(f\"      ✅ Sonuç: {function_response}\\n\")\n",
        "\n",
        "                messages.append({\n",
        "                    \"role\": \"tool\",\n",
        "                    \"tool_call_id\": tool_call.id,\n",
        "                    \"name\": function_name,\n",
        "                    \"content\": function_response\n",
        "                })\n",
        "\n",
        "        except Exception as e:\n",
        "            error_msg = f\"❌ Hata: {str(e)}\"\n",
        "            if verbose:\n",
        "                print(error_msg)\n",
        "            return error_msg\n",
        "\n",
        "    return \"⚠️ Maksimum iterasyona ulaşıldı, final cevap yok.\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Function calling ile otonom ajan çalıştır.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"✓ Ajan sistemi hazır\")"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 4.2 Ajan Gösterimleri\n",
        "\n",
        "Ajanı giderek karmaşık görevlerde test ediyoruz.\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"DEMO 1: BASİT ARAÇ KULLANIMI\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "result1 = run_agent(\"Istanbul'da hava nasıl?\")\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"DEMO 2: ÇOKLU ARAÇ KOORDİNASYONU\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "result2 = run_agent(\n",
        "    \"Istanbul ve Ankara arasındaki sıcaklık farkı nedir? Hesapla.\"\n",
        ")\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"DEMO 3: RAG + FUNCTION CALLING\")\n",
        "print(\"=\"*80)\n",
        "\n",
        "result3 = run_agent(\n",
        "    \"Bilgi tabanında transfer öğrenme hakkında ara, sonra bunun hava tahmini ile ilişkisini anlat.\"\n",
        ")\n",
        "print(\"\\n\" + \"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "---\n",
        "\n",
        "## Final Gösteri: Karmaşık Çoklu Araç Sorgusu\n",
        "\n",
        "Şimdi tam sistemi şunları gerektiren karmaşık bir görevde gösteriyoruz:\n",
        "1. Bilgi alımı (RAG)\n",
        "2. Gerçek zamanlı veri çekme (hava durumu API)\n",
        "3. Matematiksel hesaplama (hesap makinesi)\n",
        "4. Çok adımlı akıl yürütme\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "complex_query = \"Ankara'daki sıcaklığı kontrol et. Eğer 15°C'nin altındaysa, bilgi tabanından transfer öğrenme hakkında bilgi ver. Son olarak, Ankara'nın şu anki sıcaklığından %20 daha yüksek olan sıcaklığı hesapla.\""
      ],
      "execution_count": null,
      "outputs": []
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "İşte karmaşık bir görev:\n",
        "1. Ankara'daki sıcaklığı kontrol et\n",
        "2. Eğer 15°C'nin altındaysa, bilgi tabanından transfer öğrenme hakkında bilgi ver\n",
        "3. Ankara'nın şu anki sıcaklığından %20 daha yüksek olan sıcaklığı hesapla\n"
      ]
    },
    {
      "cell_type": "code",
      "metadata": {},
      "source": [
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"FİNAL GÖSTERİMİ: TAM SİSTEM\")\n",
        "print(\"=\"*80)\n",
        "print(f\"\\nKarmaşık Sorgu:\\n{complex_query}\")\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "\n",
        "final_result = run_agent(complex_query, verbose=True)\n",
        "\n",
        "print(\"\\n\" + \"=\"*80)\n",
        "print(\"\\n🎉 GÖSTERİM TAMAMLANDI\")\n",
        "print(\"=\"*80)\n",
        "print(\"\\n💡 Anahtar Başarılar:\")\n",
        "print(\"   ✓ Faz 0: Sağlam API yönetimi ile birleşik ortam\")\n",
        "print(\"   ✓ Faz 1: Prompt mühendisliği ile stokastik operatörler\")\n",
        "print(\"   ✓ Faz 2: Production RAG ile semantik uzay\")\n",
        "print(\"   ✓ Faz 3: Function calling ile deterministik arayüzler\")\n",
        "print(\"   ✓ Faz 4: Çoklu araç koordinasyonu ile otonom ajan döngüsü\")\n",
        "print(\"\\n📚 Bu notebook tam mimariyi gösteriyor:\")\n",
        "print(\"   Temel LLM çağrılarından → RAG + Araçlar ile otonom ajanlara\")\n",
        "print(\"=\"*80)\n"
      ],
      "execution_count": null,
      "outputs": []
    }
  ],
  "metadata": {
    "kernelspec": {
      "display_name": "Python 3",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "pygments_lexer": "ipython3",
      "version": "3.11.0"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}