اگر امروز در حال ساخت یک سیستم تولید بازیابیافزا (RAG) هستید، بزرگترین گلوگاه شما هوش مدل نیست، بلکه واقعیتهای کثیفِ تجزیه دادهها و مدیریت وضعیت است. در ۱۰ ژوئن ۲۰۲۶، سازنده NochBot پنج دیوار معماری را که هنگام استقرار یک چتبات PDF روی Next.js 15 با آنها برخورد کرده بود، بهتفصیل شرح داد.
ساخت RAG — شبیه به ساختن یک موتور پیچیده است که در ابتدا با قطعات کوچک خوب کار میکند اما در مقیاس واقعی ناگهان از هم میپاشد — اغلب با شکستهای فاجعهبار در محیط عملیاتی همراه است. برای توسعهدهندگان، فاصله بین یک نمونه اولیه محلی و یک سرویس SaaS مقیاسپذیر، در نحوه برخورد برنامه با محیطهای بدون سرور (Serverless) و کشینگ فرانتاند نهفته است. در مورد NochBot، چالش اصلی با اکوسیستم Turbopack و پیچیدگیهای App Router بود. همانطور که در تحلیلهای قبلی ما دربارهی بهینهسازی استنتاج مدلها اشاره کردیم، جزئیات زیرساختی همیشه تعیینکننده کیفیت نهایی هستند.
موانع فنی و چالشهای تجزیه PDF
طبق مستندات فنی NochBot، این پروژه از یک پشته مدرن برای سرعت و مقیاس استفاده میکند:
- فریمورک: Next.js 15 + Turbopack
- تجزیه PDF: unpdf
- بردارهای معنایی: Google Gemini text-embedding-004
- پایگاه داده برداری: Qdrant Cloud
- مدل زبانی: Groq LLaMA 3.3 70B
- پایگاه داده: MongoDB Atlas
- استقرار: Vercel
اولین مانع بزرگ، تجزیه PDF بود. توسعهدهنده ابتدا از pdf-parse استفاده کرد، اما با خطای ReferenceError: DOMMatrix is not defined مواجه شد؛ زیرا این کتابخانه APIهای مرورگر را در سطح ماژول بارگذاری میکند و Node.js نمیتواند آنها را شناسایی کند. تلاش دوم با pdf-parse-new نیز بهدلیل مسیرهای داخلی شکسته (مانند خطای Can't resolve './ROOT/node_modules/pdf-parse-new/lib/pdf-child.js') شکست خورد که نشان داد این کتابخانه با Turbopack ناسازگار است.
راهکار نهایی، جایگزینی با unpdf بود؛ کتابخانهای که بهطور خاص برای محیطهای Edge و Serverless بدون وابستگی به مرورگر ساخته شده است. این مورد از طریق وارد کردن پویا (Dynamic Import) در بدنه تابع اجرا شد تا با تبدیل بافر به Uint8Array و فعال کردن mergePages: true بتوان متن و تعداد صفحات را استخراج کرد.

بهینهسازی بازیابی دادهها
به گزارش سازنده، کیفیت بازیابی هنگام استفاده از تکهبندی (Chunking) با تعداد کلمات ثابت (۳۰۰ کلمه) افت میکرد؛ زیرا اغلب تیترها از توضیحاتشان جدا میشدند. در این حالت، مدل با نبود زمینه (Context) پاسخهای ضعیفی میداد. برای رفع این مشکل، تیم از تکهبندی بر اساس مرز پاراگراف با ۲۵ کلمه همپوشانی (Overlap) استفاده کرد.
- روش قدیمی: برشهای ثابت ۳۰۰ کلمهای که معنای معنایی (Semantic Meaning) را نادیده میگرفتند.
- روش جدید: جداسازی بر اساس
\n\n+(مرز پاراگرافها) با سقف ۲۵۰ کلمه برای هر تکه. - سازوکار: اگر یک بلوک از حد مجاز کلمات بیشتر شود، سیستم تکه فعلی را میبندد و ۲۵ کلمه آخر را بهعنوان همپوشانی به تکه بعدی منتقل میکند تا پیوستگی معنایی در مرزها حفظ شود.
- نتیجه: جهشی سریع در دقت بازیابی بهدلیل حفظ زمینه معنایی.
رفع توهمات رابط کاربری و مدل
دو باگ بحرانی در تجربه کاربری ظاهر شد. اول، تب «Vectorize» در داشبورد خالی میماند. با اینکه بکاند کار میکرد و دادهها در Qdrant ذخیره شده بودند، رابط کاربری بهروز نمیشد. توسعهدهنده دو ساعت وقت صرف عیبیابی بکاند کرد، اما در نهایت متوجه شد خطا در مدیریت وضعیت (State Management) است: او وضعیت را مستقیماً تغییر داده بود (vectorizeData = data) بهجای استفاده از setVectorizeData(data). این اشتباه مانع از رندر مجدد (Re-render) کامپوننت میشد.
دوم، مدل دچار «بیشفکری» شده بود. برای سوالی ساده مثل «این PDF چند صفحه دارد؟»، بات ۳۰۰ کلمه استدلال میکرد و در نهایت یک جواب ۲ کلمهای میداد. برای توقف این روند، دو تغییر اعمال شد:
۱. مهندسی پرامپت (Prompt Engineering) — هنر سؤال درست پرسیدن برای گرفتن بهترین جواب — بهگونهای که مدل را صریحاً مجبور میکرد پاسخهای واقعگرایانه را در ۱ تا ۲ جمله بدهد و هرگز مراحل استدلال را نمایش ندهد.
۲. تنظیم دما (Temperature): کاهش دما از ۰.۶ (که بیش از حد خلاق بود) به ۰.۲ برای دریافت پاسخهای دقیق، مستقیم و واقعگرایانه.
مدیریت کشینگ در App Router
در نهایت، Next.js App Router صفحات را کش میکرد و باعث میشد PDFهای آپلودشده هنگام جابهجایی کاربر در صفحات، بهصورت بصری ناپدید شوند. دادهها در MongoDB بودند، اما کامپوننت دوباره بارگذاری (Remount) نمیشد و درخواست fetch مجدداً اجرا نمیگشت.
راهکار این بود که یک شنونده رویداد visibilitychange در یک هوک useEffect قرار دهند. این کار تضمین میکند هرگاه وضعیت سند (document.visibilityState) به 'visible' تغییر کند (یعنی تب فعال شود)، تابع fetchPdfs() برای بهروزرسانی لیست فراخوانی شود.
این اصلاحات، یک نمونه اولیه شکننده را به یک SaaS آماده تولید تبدیل کرد. NochBot اکنون از قابلیتهای چندمستاجره (Multi-tenant) پشتیبانی میکند؛ از جمله لینکهای اشتراکی برای هر PDF، تحلیل جلسات (Session Analytics)، یک بات دو منظوره (دستیار مطالعه یا کاتالوگ فروش) و یک طرح رایگان محدود به یک PDF. این تجربه ثابت میکند که انتخاب کتابخانه و مدیریت وضعیت، اغلب اثرگذارتر از انتخاب خودِ مدل زبانی است.
گام بعدی شما
- اگر از Next.js 15 استفاده میکنید، برای تجزیه PDF در محیط Serverless حتماً از unpdf بهجای کتابخانههای قدیمی استفاده کنید.
- برای جلوگیری از توهمات مدل در پاسخهای کوتاه، دما (Temperature) را به ۰.۲ کاهش دهید.
- در تکهبندی دادهها، بهجای تعداد کلمات ثابت، از مرز پاراگرافها و همپوشانی (Overlap) استفاده کنید تا معنای متن حفظ شود.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو