برنامه نویسی

ساخت یک موتور جستجوگر معنایی

بیایید با آن روبرو شویم – همه ما آنجا بوده ایم. شما در حال تلاش برای یافتن آن یادگار مناسب برای خلاصه ترس وجودی خود در مورد قهوه صبح دوشنبه هستید ، اما مهم نیست که چه کلمات کلیدی را امتحان می کنید ، فقط عکس های گربه نامربوط دریافت می کنید. جستجوی معنایی را وارد کنید: فناوری که در نهایت نمایش داده های جستجوی هرج و مرج شما را درک می کند. در این پست ، من به شما نشان خواهم داد که چگونه یک موتور جستجوگر Meme ساخته ام که در واقع با استفاده از برخی جادوی جالب فناوری (و ابزارهای عالی عالی Upstash) شوخی می کند.

Upstash یک پایگاه داده بردار ارائه می دهد که جستجوهای شباهت مقیاس پذیر را در بین بردارها امکان پذیر می کند ، با ویژگی هایی مانند فیلتر ابرداده و مدلهای تعبیه شده داخلی. علاوه بر این ، Upstash Redis قابلیت های ذخیره سازی قدرتمند و محدود کننده نرخ را فراهم می کند ، و آن را به پایه ای ایده آل برای برنامه های مدرن با قدرت هوش مصنوعی تبدیل می کند.

در این پست ، من شما را طی می کنم که چگونه یک موتور جستجوگر Meme معنایی را با استفاده از بردار Upstash و Redis ایجاد کردیم که نشان می دهد چگونه می توان از این ابزارهای قدرتمند برای ساختن یک تجربه جستجوی کارآمد و کاربر پسند استفاده کرد.

می توانید پروژه را در GitHub کاوش کنید یا آن را مستقیماً به حساب Vercel خود مستقر کنید.

هنگامی که کلمات کلیدی شکست می خورند: معضل جستجوی Meme

جستجوی سنتی وقتی دقیقاً می دانید که به دنبال چه چیزی هستید. “گربه گریم” → ممتاز گربه های بدخیم. آسان اما الگوهای رفتاری در فضای عجیب و غریب بین معنای تحت اللفظی و زمینه فرهنگی زندگی می کنند. سعی کنید “این احساس را وقتی WiFi شما در حین فراخوان بزرگنمایی می میرد” جستجو کنید و به سرعت در محدودیت های تطبیق کلمات کلیدی قرار خواهید گرفت.

اینجاست که جستجوی معنایی می درخشد. این مثل این است که دوستی داشته باشید که عمیق در فرهنگ Meme باشد. به آنها بگویید “من به چیزی احتیاج دارم که بزرگسالی خیلی سخت باشد” و آنها 10 نوع از الگوهای سگ “این خوب است” را بدون چشمک زدن به شما تحویل می دهند. این دقیقاً همان چیزی است که ما در اینجا می سازیم.

Tech Stack/Toolkit: چرا این گزینه ها مهم هستند
next.js 15: زیرا چه کسی می خواهد با تنظیمات پیچیده آشفتگی کند؟ مسیرهای API فوری + React Goodness = Developer Happy.

بردار Upstash: مانند مغزی که روابط بین مفاهیم را به یاد می آورد (اما ارزان تر از یک مغز واقعی).

upstash redis: چاقوی دیتابیس های ارتش سوئیس – از حافظه پنهان استفاده می کند و کاربران را از اسپم کردن API ما باز می دارد.

آتش: برای تولید داده های متا تصاویر Meme. بسیاری از مدل های LLM مختلف در دسترس هستند.

تعبیه Openai: ضروری نیست ، ما می توانیم از مدل های مختلف هوش مصنوعی استفاده کنیم (مانند مدل های بغل کردن صورت).

Vercel Blob: برای ذخیره تمام آن الگوهای ادویه ای بدون غرق شدن در پیکربندی های S3.

تولید داده های متا برای تصاویر Meme

role: "user",
          content: [
            { type: "text", text: "Describe the image in detail." },
            {
              type: "image",
              image: file,
            },
          ],
        },
      ],
    });
    images.push({ path: file, metadata: result.object.image });
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

قبل از تولید بردارهای جاسازی شده برای تصاویر Meme در مجموعه داده های خود ، ما برای ایجاد ابرداده جامع برای هر تصویر نیاز داشتیم. برای دستیابی به این هدف ، من API LLM OpenAI را به طور خودکار با 9 پارامتر اصلی برچسب گذاری کردم: PATH (میزبان در Vercel) ، عنوان ، توضیحات ، برچسب ها ، Memecontext ، Humor ، Format ، TextContent ، شخص و اشیاء. چالش این بود که هم محتوای بصری تصویر و هم متن تعبیه شده در الگوی رفتاری را ضبط کنیم. در زیر نمونه ای از برچسب های ابرداده وجود دارد:

{
  "path": "https://kqznk1deju1f3qri.public.blob.vercel-storage.com/another_%20Bugs%20Bunny_s%20_No_-D6ht580Nj0I8mri3hYLVIHnRx4DNIB.jpg",
  "metadata": {
    "title": "Bugs Bunny 'No' Meme with Defiant Expression",
    "description": "This meme features Bugs Bunny, a classic cartoon character from the Looney Tunes series, with a defiant expression. The image is a close-up of Bugs Bunny's face, showing him with half-closed eyes and a slightly open mouth, conveying disinterest or refusal. The word 'no' is displayed in bold white text, emphasizing his dismissive attitude. This meme is often used to humorously express firm rejection. The mid-20th-century animation style adds nostalgia.",
    "tags": [
      "Bugs Bunny",
      "Looney Tunes",
      "cartoon",
      "meme",
      "no",
      "refusal",
      "defiance",
      "humor",
      "animation",
      "classic",
      "nostalgia",
      "expression",
      "dismissive",
      "rejection",
      "bold text"
    ],
    "memeContext": "A frame from Looney Tunes repurposed to convey humorous refusal in online conversations, leveraging Bugs Bunny's witty demeanor.",
    "humor": "Exaggerated refusal using a beloved character, with simplicity enhancing comedic effect.",
    "format": "Bugs Bunny 'No' Meme",
    "textContent": "no",
    "person": "Bugs Bunny, animated character",
    "objects": "Bugs Bunny, text 'no'"
  }
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

LLM هر دو عنصر بصری (به عنوان مثال ، عبارات شخصیت ، قرار دادن متن) و زمینه فرهنگی (به عنوان مثال ، جذابیت نوستالژیک Bugs Bunny) را برای تولید ابرداده های غنی و دوستانه دوستانه تجزیه و تحلیل کرد.

آماده سازی تعبیه

برای موتور جستجوگر Meme ، ما خودمان را با استفاده از مدل کوچک Text-Embedding-3-Small OpenAi تعبیه کردیم ، اما توصیه می کنم مدل های تعبیه دیگری را برای دیدن تنوع امتحان کنید. هر یادداشت با تعبیه عنوان و توضیحات خود نشان داده شده است:

export const generateEmbedding = async (value: string): Promise<number[]> => {
  const input = value.replaceAll("\n", " ");
  const { embedding } = await embed({
    model: embeddingModel,
    value: input,
  });
  return embedding;
};
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

نمایه سازی بردارها

پایگاه داده بردار خود را با Upstash بسیار آسان تنظیم کنید

برای موتور جستجوی Meme ، ما یک ساختار شاخص ساده ایجاد کردیم که در آن هر الگوی رفتاری توسط:

  1. تعبیه شده از عنوان و توضیحات آن
  2. ابرداده از جمله عنوان ، توضیحات و مسیر تصویر
  3. یک شناسه منحصر به فرد برای بازیابی

فرآیند نمایه سازی واقعی از طریق API بردار Upstash انجام می شود:

// Initialize Upstash Vector client with the memes index
export const memesIndex = new Index({
  url: process.env.UPSTASH_VECTOR_URL!,
  token: process.env.UPSTASH_VECTOR_TOKEN!,
});
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

بر خلاف پروژه های بزرگتر که ممکن است نیاز به پردازش دسته ای داشته باشد ، پایگاه داده Meme ما به اندازه کافی کوچک است که بدون بهینه سازی های ویژه به طور مؤثر نمایه می شود. سادگی API وکتور Upstash این روند را مستقیماً جلوه داد.

ساخت موتور جستجو Meme

عملکرد جستجو هر دو جستجوی شباهت بردار و تطبیق متن مستقیم را ترکیب می کند (و اگر کپی کند آن را رها می کند):

// For longer queries, perform both direct and semantic search
const directMatches = await findMemesByQuery(query);
const semanticMatches = await findSimilarMemes(query);

// Combine results, removing duplicates
const allMatches = uniqueItemsByTitle([...directMatches, ...semanticMatches]);
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

جستجوی وکتور محتوای معنایی مشابه را پیدا می کند:

export const findSimilarMemes = async (description: string): Promise<Meme[]> => {
  const embedding = await generateEmbedding(description);

  const results = await memesIndex.query({
    vector: embedding,
    includeMetadata: true,
    topK: 60,
    includeVectors: false,
  });

  return results.map((result: any) => ({
    id: String(result.id),
    title: result.metadata?.title || '',
    description: result.metadata?.description || '',
    path: result.metadata?.path || '',
    embedding: [],
    similarity: result.score,
  }));
};
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

برای نتایج جستجو ، ما هم ابرداده (عنوان و توضیحات) و هم مسیر تصویر را درج می کنیم و به ما امکان می دهد نتایج غنی را به کاربر نمایش دهیم.

اجرای ذخیره و محدود کردن نرخ

می توانید به راحتی redis را با Upstash تنظیم کنید

برای بهینه سازی عملکرد و کنترل API ، ما با استفاده از upstash redis ، ذخیره و محدود کردن نرخ را اجرا کردیم.

بعد از اینکه از URL و نشانه خود گرفتیم ، می توانیم با کد ما ادغام شویم:

ذخیره سازی

// Create cache key
const cacheKey = query
  ? `q:${query.toLowerCase().replaceAll(" ", "_")}`
  : "all_memes";

// Check cache first
const cached = await redis.get(cacheKey);
if (cached) {
  // Return cached results
  return { memes: JSON.parse(cached as string) };
}

// ... perform search ...

// Cache the results
await redis.set(cacheKey, JSON.stringify(allMatches), { ex: REDIS_CACHE_TTL });
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

محدود کردن نرخ با مجموعه های مرتب شده Redis

بیایید محدودیت نرخ را برای جلوگیری از استفاده از API ادغام کنیم:

const RATE_LIMIT = {
  window: 60, // 1 minute
  requests: 10 // Max 10 requests per minute
};

async function checkRateLimit(ip: string): Promise<boolean> {
  const now = Math.floor(Date.now() / 1000);
  const windowStart = now - RATE_LIMIT.window;

  // Remove old entries
  await redis.zremrangebyscore(`ratelimit:${ip}`, 0, windowStart);

  // Count requests in the current window
  const requestCount = await redis.zcount(`ratelimit:${ip}`, windowStart, '+inf');

  // If under limit, add this request and return true
  if (requestCount < RATE_LIMIT.requests) {
    await redis.zadd(`ratelimit:${ip}`, { score: now, member: now.toString() });
    return true;
  }

  return false;
}
حالت تمام صفحه را وارد کنید

از حالت تمام صفحه خارج شوید

مجموعه های مرتب شده Redis روشی زیبا و کارآمد برای اجرای محدود کننده نرخ پنجره کشویی ارائه می دهند. این رویکرد چندین مزیت ارائه می دهد:

  1. انقضاء دقیق مبتنی بر زمان درخواست های قدیمی
  2. شمارش کارآمد درخواست ها در پنجره فعلی
  3. استفاده از حافظه کم حتی با ترافیک زیاد

یک انتخاب جالب پایگاه داده: Vercel Blob

Vercel Blob ذخیره سازی پرونده را با ادغام بی دردسر ساده می کند. بر خلاف بانکهای اطلاعاتی سنتی ، تنظیم فقط به سه مرحله نیاز دارد:

  • ایجاد یک پروژه
  • فضای ذخیره سازی Vercel را وصل کنید
  • بارگذاری پرونده ها را شروع کنید – بدون تنظیمات پیچیده.

داشبورد بصری آن ، مدیریت ذخیره سازی را ساده می کند و سازمان دارایی در زمان واقعی ، تجزیه و تحلیل استفاده و مقیاس پذیری یکپارچه را ارائه می دهد-همه به طور مستقیم در اکوسیستم Vercel. ایده آل برای توسعه دهندگان اولویت بندی سرعت و سادگی.

رابط کاربری

در ابتدا ، من یک UI بصری متراکم با اجزای پیچیده طراحی کردم. اما بعد فهمیدم ، “AKIF ، این پروژه به طرحی نیاز دارد که سادگی را برجسته کند!” – بنابراین من به عقب برگشتم و یک رابط کاربری مینیمالیستی تمیزتر و مینیمالیستی ایجاد کردم.

  1. یک کادر جستجوی برجسته در بالای صفحه
  2. یک طرح شبکه پاسخگو برای نمایش نتایج MEME
  3. جستجوهای پیشنهادی برای کاربران جدید که وارد پرس و جو نشده اند

بسته شدن کلمات

ساختن یک موتور جستجوگر معنایی معنایی با وکتور Upstash و Redis به طرز چشمگیری ساده بود. ترکیبی از این خدمات تمام ابزارهای مورد نیاز ما را برای ایجاد یک تجربه جستجوی سریع ، کارآمد و کاربر پسند فراهم می کند.

ویژگی های موجود در وکتور Upstash ، مانند تعبیه وکتور اتوماتیک ، ذخیره سازی ابرداده و جستجوی شباهت کارآمد ، این روند را بسیار آسان کرده است. به طور مشابه ، Upstash Redis ابزارهای قدرتمندی را برای ذخیره سازی و محدود کردن نرخ با حداقل تلاش فراهم کرد.

ما با این پروژه سرگرم کننده زیادی داشتیم و معتقدیم که خدمات Upstash برای ساخت برنامه های کاربردی AI از همه نوع مناسب است. اگر بازخوردی در مورد پروژه دارید ، احساس راحتی کنید تا به GitHub دسترسی پیدا کنید. بیایید با هم کار کنیم تا آن را بهتر کنیم!

نوشته های مشابه

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *

دکمه بازگشت به بالا