{
  "cells": [
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# 🧠 Exhibition Connector — RAG Base Model Colab\n",
        "\n",
        "این نوت‌بوک یک **مدل پایه RAG** برای پروژه نمایشگاه است.\n",
        "\n",
        "ویژگی‌ها:\n",
        "- بدون GPU\n",
        "- بدون HF token\n",
        "- بدون LangChain سنگین\n",
        "- دانلود داده شرکت‌ها از API/JSON\n",
        "- ساخت Retriever محلی با TF‑IDF\n",
        "- تست پرسش‌ها\n",
        "- مقایسه با Vercel API\n",
        "\n",
        "این نسخه برای آموزش، دیباگ و تست پایه مناسب است.\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "# نصب سبک\n",
        "!pip install -q requests pandas scikit-learn\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "import re, json, requests, pandas as pd\n",
        "from sklearn.feature_extraction.text import TfidfVectorizer\n",
        "from sklearn.metrics.pairwise import cosine_similarity\n",
        "\n",
        "VERCEL_API_BASE = \"https://vercel-app-amber-five.vercel.app\"\n",
        "COMPANIES_JSON_URL = \"https://sosa123456-exhibition-connector-rag1-static.static.hf.space/data/companies.json\"\n",
        "\n",
        "print(\"Vercel API:\", VERCEL_API_BASE)\n",
        "print(\"Companies JSON:\", COMPANIES_JSON_URL)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 1) بارگذاری داده شرکت‌ها"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "resp = requests.get(COMPANIES_JSON_URL, timeout=60)\n",
        "resp.raise_for_status()\n",
        "companies = resp.json()\n",
        "print(\"تعداد شرکت‌ها:\", len(companies))\n",
        "companies[0]\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 2) نرمال‌سازی فارسی و ساخت متن RAG"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def normalize_fa(text):\n",
        "    text = str(text or \"\")\n",
        "    repl = {\"ي\":\"ی\", \"ك\":\"ک\", \"ۀ\":\"ه\", \"ة\":\"ه\", \"أ\":\"ا\", \"إ\":\"ا\", \"ؤ\":\"و\", \"\\u200c\":\" \", \"\\u200f\":\" \", \"\\ufeff\":\" \"}\n",
        "    for a,b in repl.items():\n",
        "        text = text.replace(a,b)\n",
        "    text = re.sub(r\"\\s+\", \" \", text).strip().lower()\n",
        "    return text\n",
        "\n",
        "def record_text(r):\n",
        "    fields = r.get(\"fields\") or {}\n",
        "    parts = [\n",
        "        r.get(\"company\", \"\"), r.get(\"website\", \"\"), r.get(\"activity\", \"\"),\n",
        "        r.get(\"category\", \"\"), r.get(\"hall\", \"\"), r.get(\"booth\", \"\"), r.get(\"text\", \"\"),\n",
        "        \" \".join(str(v) for v in fields.values())\n",
        "    ]\n",
        "    return normalize_fa(\"\\n\".join(parts))\n",
        "\n",
        "texts = [record_text(r) for r in companies]\n",
        "print(texts[0][:500])\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 3) ساخت Retriever پایه با TF‑IDF"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "vectorizer = TfidfVectorizer(analyzer=\"char_wb\", ngram_range=(2,5), max_features=90000, sublinear_tf=True)\n",
        "X = vectorizer.fit_transform(texts)\n",
        "print(\"matrix:\", X.shape)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 4) تابع جستجوی پایه RAG"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def search_local(question, k=5):\n",
        "    q = normalize_fa(question)\n",
        "    qv = vectorizer.transform([q])\n",
        "    scores = cosine_similarity(qv, X).ravel()\n",
        "    idxs = scores.argsort()[::-1][:k]\n",
        "    rows = []\n",
        "    for rank, idx in enumerate(idxs, start=1):\n",
        "        r = companies[int(idx)]\n",
        "        rows.append({\n",
        "            \"rank\": rank,\n",
        "            \"score\": float(scores[idx]),\n",
        "            \"company\": r.get(\"company\"),\n",
        "            \"activity\": r.get(\"activity\"),\n",
        "            \"category\": r.get(\"category\"),\n",
        "            \"hall\": r.get(\"hall\") or \"—\",\n",
        "            \"booth\": r.get(\"booth\") or \"—\",\n",
        "            \"website\": r.get(\"website\") or \"—\",\n",
        "        })\n",
        "    return pd.DataFrame(rows)\n",
        "\n",
        "def answer_local(question, k=5):\n",
        "    df = search_local(question, k)\n",
        "    lines = [f\"پاسخ پایه برای: {question}\"]\n",
        "    for _, row in df.iterrows():\n",
        "        lines.append(f\"{row['rank']}. {row['company']} | سالن/غرفه: {row['hall']}/{row['booth']} | سایت: {row['website']}\")\n",
        "    return \"\\n\".join(lines), df\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 5) تست چند پرسش"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "queries = [\n",
        "    \"وب‌سایت شرکت پریسماتک چیست؟\",\n",
        "    \"مواد شیمیایی تصفیه آب\",\n",
        "    \"شرکت‌های مرتبط با ابزار دقیق کدامند؟\",\n",
        "    \"سالن 31B\",\n",
        "    \"چطور با مترو به نمایشگاه بین‌المللی تهران برویم؟\",\n",
        "]\n",
        "\n",
        "for q in queries:\n",
        "    print(\"=\"*80)\n",
        "    ans, df = answer_local(q, 5)\n",
        "    print(ans)\n",
        "    display(df)\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 6) مقایسه با Vercel API"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "def search_vercel(question, k=5):\n",
        "    r = requests.get(f\"{VERCEL_API_BASE}/api/search\", params={\"q\": question, \"limit\": k}, timeout=45)\n",
        "    r.raise_for_status()\n",
        "    data = r.json()\n",
        "    return data\n",
        "\n",
        "q = \"وب‌سایت شرکت پریسماتک چیست؟\"\n",
        "remote = search_vercel(q, 5)\n",
        "print(remote.get(\"answer\"))\n",
        "pd.DataFrame(remote.get(\"results\", []))[['company','hall','booth','website','score']].head()\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 7) تست Scraper API"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {},
      "outputs": [],
      "source": [
        "scrape = requests.get(f\"{VERCEL_API_BASE}/api/scrape\", params={\"url\": \"https://prismatech.ir/\"}, timeout=60)\n",
        "scrape.raise_for_status()\n",
        "info = scrape.json()[\"scraped\"]\n",
        "print(\"title:\", info.get(\"title\"))\n",
        "print(\"emails:\", info.get(\"emails\"))\n",
        "print(\"phones:\", info.get(\"phones\")[:3])\n",
        "print(\"snippet:\", info.get(\"textSnippet\", \"\")[:300])\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 8) معیارهای پایه برای توسعه بعدی\n",
        "\n",
        "اگر بخواهید مدل بهتر شود:\n",
        "- reranker اضافه کنید\n",
        "- stopword فارسی دقیق‌تر بسازید\n",
        "- embedding sentence-transformers اضافه کنید\n",
        "- دیتابیس مرکزی برای scrape updates اضافه کنید\n",
        "- W&B را از سمت Vercel backend لاگ کنید\n"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "provenance": [],
      "include_colab_link": true
    },
    "kernelspec": {
      "display_name": "Python 3",
      "name": "python3"
    },
    "language_info": {
      "name": "python"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 5
}