ساخت چتبات فارسی با RAG: پاسخگویی هوشمند بر اساس اسناد شما
فرض کنید میخواهید چتباتی بسازید که فقط بر اساس اطلاعات کسبوکار شما جواب دهد: قوانین ارسال، شرایط گارانتی، مشخصات محصولات یا آییننامههای داخلی شرکت. مدلهای زبانی بهتنهایی این اطلاعات را نمیدانند و اگر از آنها بپرسید، ممکن است جوابی حدسی و نادرست بدهند. راهحل استاندارد برای این مسئله RAG است. در این راهنما توضیح میدهیم RAG چیست، چه اجزایی دارد، متن فارسی چه نکات خاصی دارد و چطور با پایتون و یک API هوش مصنوعی سازگار با OpenAI یک نمونهٔ کارا بسازید.
RAG چیست؟
RAG مخفف Retrieval-Augmented Generation به معنای «تولید متن با کمک بازیابی اطلاعات» است. ایده ساده است: پیش از اینکه سؤال کاربر را به مدل زبانی بدهیم، مرتبطترین بخشهای اسناد خودمان را پیدا میکنیم و همراه سؤال برای مدل میفرستیم. مدل پاسخ را بر اساس همین متنها میسازد، نه بر اساس حدس.
مزیتهای اصلی RAG:
- کاهش پاسخهای ساختگی: مدل به متن مرجع تکیه میکند و میتوانید از او بخواهید اگر جواب در اسناد نبود، صادقانه بگوید.
- بهروزرسانی آسان: برای تغییر دانش ربات کافی است اسناد را عوض کنید؛ نیازی به آموزش دوبارهٔ مدل نیست.
- هزینهٔ منطقی: بهجای فرستادن کل اسناد در هر درخواست، فقط چند بخش مرتبط ارسال میشود.
- امکان ارجاع: میتوانید منبع هر پاسخ را به کاربر نشان دهید.
اجزای یک سیستم RAG
۱. آمادهسازی و قطعهبندی اسناد (Chunking)
اسناد طولانی را به قطعههای کوچکتر تقسیم میکنیم؛ معمولاً چند پاراگراف یا چند صد کلمه. قطعهٔ خیلی بزرگ دقت جستوجو را کم میکند و قطعهٔ خیلی کوچک معنای کامل را از دست میدهد. یک روش رایج این است که قطعهها کمی با هم همپوشانی داشته باشند تا جملههای مرزی گم نشوند. بهتر است قطعهبندی بر اساس ساختار طبیعی سند، مثل تیترها و پاراگرافها، انجام شود.
۲. ساخت بردار معنایی (Embedding)
هر قطعه با یک مدل Embedding به یک بردار عددی تبدیل میشود. متنهایی که معنای نزدیک دارند، بردارهای نزدیک به هم دارند؛ حتی اگر کلمات یکسانی نداشته باشند. برای مثال «هزینهٔ ارسال» و «قیمت پست» از نظر معنایی نزدیکاند.
۳. ذخیره در پایگاه داده برداری
بردارها در یک پایگاه دادهٔ برداری ذخیره میشوند تا جستوجوی شباهت سریع باشد. گزینههای رایج عبارتاند از FAISS و Chroma برای پروژههای کوچک، افزونهٔ pgvector برای کسانی که PostgreSQL دارند و Qdrant یا Milvus برای پروژههای بزرگتر. برای چند صد سند، حتی یک آرایهٔ ساده در حافظه هم کافی است.
۴. بازیابی و تولید پاسخ
وقتی کاربر سؤال میپرسد، سؤال هم به بردار تبدیل میشود، نزدیکترین قطعهها پیدا میشوند و همراه سؤال و یک دستورالعمل سیستمی برای مدل زبانی ارسال میشوند. مدل پاسخ نهایی را مینویسد.
نکات مهم برای متن فارسی
متن فارسی چند چالش خاص دارد که اگر به آنها توجه نکنید، کیفیت جستوجو پایین میآید:
- یکسانسازی حروف: «ي» و «ك» عربی را به «ی» و «ک» فارسی تبدیل کنید. در غیر این صورت دو کلمهٔ ظاهراً یکسان، متفاوت دیده میشوند.
- نیمفاصله: «میشود»، «می شود» و «میشود» را به یک شکل استاندارد درآورید. کتابخانههای پردازش زبان فارسی مثل hazm ابزار نرمالسازی دارند.
- اعداد: ارقام فارسی و انگلیسی را یکسان کنید تا جستوجوی کد محصول یا شماره درست کار کند.
- انتخاب مدل Embedding: از مدلی استفاده کنید که از زبانهای مختلف پشتیبانی کند. کیفیت مدلها روی فارسی متفاوت است؛ با چند سؤال واقعی آزمایش کنید.
- زبان پاسخ: در دستورالعمل سیستمی صریحاً بخواهید پاسخ به فارسی روان و فقط بر اساس متن مرجع باشد.
پیادهسازی RAG فارسی با پایتون
در این نمونه یک RAG ساده و قابل فهم میسازیم که برای چند ده تا چند صد سند کافی است. پیشنیاز آن آشنایی مقدماتی با پایتون است؛ اگر تازه شروع کردهاید، ابتدا راهنمای اتصال به API هوش مصنوعی با پایتون را بخوانید. کتابخانهها را نصب کنید:
pip install openai numpy
سپس کد زیر را اجرا کنید. کلید و آدرس پایه را از پنل کاربری بردارید و در متغیرهای محیطی قرار دهید. نام مدل Embedding و مدل گفتگو را هم مطابق فهرست مدلهای فعال در پنل وارد کنید.
import os
import numpy as np
from openai import OpenAI
client = OpenAI(api_key=os.environ["ELIN_API_KEY"], base_url=os.environ["BASE_URL"])
EMBED_MODEL = os.environ["EMBED_MODEL"] # نام مدل Embedding از پنل
CHAT_MODEL = os.environ["CHAT_MODEL"] # نام مدل گفتگو از پنل
def normalize(text):
return text.replace("ي", "ی").replace("ك", "ک").strip()
docs = [
"ارسال سفارشها در تهران یک روز کاری و در شهرستانها دو تا چهار روز کاری طول میکشد.",
"کالاهای سالم تا هفت روز پس از تحویل قابل مرجوع کردن هستند.",
"پشتیبانی از شنبه تا پنجشنبه از ساعت ۹ تا ۱۸ پاسخگو است.",
]
docs = [normalize(d) for d in docs]
def embed(texts):
res = client.embeddings.create(model=EMBED_MODEL, input=texts)
vecs = np.array([item.embedding for item in res.data])
return vecs / np.linalg.norm(vecs, axis=1, keepdims=True)
doc_vecs = embed(docs)
def answer(question, k=2):
q_vec = embed([normalize(question)])[0]
scores = doc_vecs @ q_vec
top = [docs[i] for i in np.argsort(scores)[::-1][:k]]
context = "\n".join(f"- {t}" for t in top)
res = client.chat.completions.create(
model=CHAT_MODEL,
messages=[
{"role": "system", "content": "فقط بر اساس متن مرجع و به فارسی پاسخ بده. اگر پاسخ در متن نبود، بگو اطلاعی ندارم."},
{"role": "user", "content": f"متن مرجع:\n{context}\n\nسؤال: {question}"},
],
)
return res.choices[0].message.content
print(answer("سفارشم به شیراز کی میرسد؟"))
در این کد بردارها نرمال شدهاند، بنابراین ضرب داخلی آنها همان شباهت کسینوسی است. برای پروژهٔ واقعی، بردارهای اسناد را یک بار بسازید و در فایل یا پایگاه داده ذخیره کنید تا در هر اجرا دوباره هزینهٔ Embedding پرداخت نشود.
بهبود کیفیت پاسخها
- تعداد قطعهها را تنظیم کنید: مقدار
kرا بین ۳ تا ۸ آزمایش کنید. قطعهٔ کم ممکن است جواب را جا بیندازد و قطعهٔ زیاد هزینه و حواسپرتی مدل را بیشتر میکند. - اطلاعات تکمیلی ذخیره کنید: عنوان سند، تاریخ و آدرس صفحه را کنار هر قطعه نگه دارید تا بتوانید منبع پاسخ را نشان دهید.
- جستوجوی ترکیبی: برای کدهای محصول، نامهای خاص و اعداد، جستوجوی کلیدواژهای را کنار جستوجوی معنایی قرار دهید.
- دستورالعمل دقیق بنویسید: لحن، طول پاسخ و رفتار در نبود اطلاعات را مشخص کنید. نکات بیشتر در راهنمای پرامپتنویسی آمده است.
- با سؤالهای واقعی آزمایش کنید: فهرستی از سؤالهای پرتکرار مشتریان تهیه کنید و بعد از هر تغییر، کیفیت پاسخها را با همین فهرست بسنجید.
کاربردهای عملی RAG در کسبوکارهای ایرانی
RAG فقط یک مفهوم فنی نیست؛ در بسیاری از کسبوکارها همین حالا میتواند وقت تیم را آزاد کند. چند نمونهٔ رایج:
- پشتیبانی فروشگاه اینترنتی: پاسخ به سؤالهای تکراری دربارهٔ ارسال، مرجوعی، گارانتی و روشهای پرداخت بر اساس صفحههای قوانین سایت.
- راهنمای محصول: پاسخ به سؤالهای فنی مشتریان بر اساس دفترچههای راهنما و کاتالوگها؛ مثلاً اینکه یک قطعه با کدام مدل سازگار است.
- دانش داخلی سازمان: دسترسی سریع کارکنان به آییننامهها، دستورالعملها و صورتجلسهها بدون جستوجوی دستی در دهها فایل.
- آموزش و مشاوره: دستیاری که بر اساس جزوهها و منابع یک دوره به سؤال دانشجویان پاسخ میدهد و منبع هر پاسخ را هم نشان میدهد.
- دفاتر حقوقی و اداری: پیدا کردن سریع بندهای مرتبط در قراردادها و مقررات؛ البته با این توجه که پاسخ مدل جایگزین نظر کارشناس نیست و باید بازبینی شود.
در همهٔ این کاربردها، کیفیت نهایی بیش از هر چیز به کیفیت اسناد بستگی دارد. اسناد قدیمی، متناقض یا ناقص را پیش از ساخت سیستم اصلاح کنید؛ RAG فقط همان چیزی را میداند که به آن دادهاید.
کدام مدل برای RAG مناسب است؟
در RAG بخش سخت کار، یعنی پیدا کردن اطلاعات، را جستوجو انجام میدهد و مدل زبانی بیشتر باید متن را بفهمد و خلاصه کند. به همین دلیل برای بسیاری از کاربردها، مدلهای اقتصادی مانند DeepSeek یا مدلهای سبک Gemini کیفیت خوبی میدهند. اگر پاسخها نیاز به استدلال دقیق یا نوشتن حرفهای دارند، مدلهای OpenAI و Claude انتخابهای مطمئنتری هستند. برای ساخت بردارها هم معمولاً از مدلهای Embedding استفاده میشود که هزینهٔ بسیار کمتری نسبت به مدلهای گفتگو دارند. اگر میخواهید چند مدل را مقایسه کنید، اعتبار OpenRouter این کار را ساده میکند.
پس از ساخت هستهٔ RAG، میتوانید آن را به یک ربات وصل کنید؛ برای مثال با ربات تلگرام هوش مصنوعی یا یک افزونه در سایت وردپرسی.
سؤالات متداول
آیا RAG با آموزش (Fine-tuning) مدل فرق دارد؟
بله. در Fine-tuning رفتار یا سبک مدل با دادههای آموزشی تغییر میکند، اما در RAG مدل تغییری نمیکند و فقط اطلاعات مرتبط در زمان پرسش به آن داده میشود. برای پاسخگویی بر اساس اسناد بهروز، RAG معمولاً سادهتر و ارزانتر است.
برای چند سند به پایگاه دادهٔ برداری نیاز دارم؟
برای چند صد قطعه، نگهداری بردارها در حافظه یا یک فایل کافی است. وقتی تعداد قطعهها به دهها هزار رسید یا چند کاربر همزمان جستوجو کردند، استفاده از پایگاه دادهٔ برداری منطقی میشود.
آیا میتوانم فایل PDF را مستقیم استفاده کنم؟
ابتدا باید متن PDF را استخراج کنید. در PDFهای فارسی گاهی ترتیب حروف یا فاصلهها به هم میریزد؛ پیش از ساخت بردار، متن استخراجشده را بررسی و نرمال کنید.
هزینهٔ یک سیستم RAG چقدر است؟
هزینه از دو بخش تشکیل میشود: ساخت بردار اسناد که معمولاً یک بار انجام میشود و هزینهٔ هر پرسش که شامل بردار سؤال و توکنهای ارسالی به مدل گفتگوست. روش محاسبه را در مقالهٔ توکن و هزینهٔ API ببینید.
چطور جلوی پاسخهای نادرست را بگیرم؟
در دستورالعمل سیستمی صریحاً بخواهید فقط از متن مرجع استفاده شود، منبع پاسخ را نمایش دهید و برای سؤالهایی که پاسخی در اسناد ندارند، یک پاسخ استاندارد مثل ارجاع به پشتیبانی در نظر بگیرید.
چتبات فارسی هوشمند کسبوکارتان را بسازید. کلید API مدلهای گفتگو و Embedding را با پرداخت ریالی، تحویل فوری و پشتیبانی فارسی از فروشگاه الین لند تهیه کنید.