گفتیم که مهندسی هوش مصنوعی یعنی افزودن هوش مصنوعی به محصول
تمرکز ما بر روی LLMs هستش
یکی از این مباحث که گفتیم RAG هستش، یعنی پایگاه دانش سازمانی ایجاد کنیم که به پاسخ کاربران جوابگو باشد
برای اینکار ما نیاز به vector store داریم، که به چند شکل کتابخونه و دیتابیس و موتور وجود دارند
کتابخونهها ثابت هستند، در مقابل تغییر مقاوم و خب سریع تر هستند، نمونه اون FAISS متعلق به شرکت فیسبوک می باشد که بشدت رقابت رو سخت کرده
elasticsearch موتور جستجو
Pgvector اکستنشن پستگرس
Mongodb atlas اکستنشن مونگو
و دیتابیس هم مانند chromadb که ساختار معنایی داره
بیشتر این ابزارها بر پایه knn, ann و tf/idf کار میکنن، در نهایت ما semantic search میخوایم
به هرحال بسته به پروژه و بزرگی سازمان و نیاز شما ابزار مناسب رو انتخاب میکنید
هدف ما ساختن یک vector store هستش که تبدیل به پایگاه دانش سازمان شده و بخش Q&A سازمان و محصول رو راه اندازی کنیم
یک موضوع رو از من به یاد داشته باشید، مهمتر از ابزار و پرامپت مناسب و مدل خوب، معماری که شما میچینید و پیاده سازی میکنید بشدت مهمتر است، در داخل کتابهای آموزشی این حوزه تمرکز اصلی کتابها بر روی معماری هستش و مابقی موضوعات بیشتر به چشم ابزار دیده میشه
@code_crafters
تمرکز ما بر روی LLMs هستش
یکی از این مباحث که گفتیم RAG هستش، یعنی پایگاه دانش سازمانی ایجاد کنیم که به پاسخ کاربران جوابگو باشد
برای اینکار ما نیاز به vector store داریم، که به چند شکل کتابخونه و دیتابیس و موتور وجود دارند
کتابخونهها ثابت هستند، در مقابل تغییر مقاوم و خب سریع تر هستند، نمونه اون FAISS متعلق به شرکت فیسبوک می باشد که بشدت رقابت رو سخت کرده
elasticsearch موتور جستجو
Pgvector اکستنشن پستگرس
Mongodb atlas اکستنشن مونگو
و دیتابیس هم مانند chromadb که ساختار معنایی داره
بیشتر این ابزارها بر پایه knn, ann و tf/idf کار میکنن، در نهایت ما semantic search میخوایم
به هرحال بسته به پروژه و بزرگی سازمان و نیاز شما ابزار مناسب رو انتخاب میکنید
هدف ما ساختن یک vector store هستش که تبدیل به پایگاه دانش سازمان شده و بخش Q&A سازمان و محصول رو راه اندازی کنیم
یک موضوع رو از من به یاد داشته باشید، مهمتر از ابزار و پرامپت مناسب و مدل خوب، معماری که شما میچینید و پیاده سازی میکنید بشدت مهمتر است، در داخل کتابهای آموزشی این حوزه تمرکز اصلی کتابها بر روی معماری هستش و مابقی موضوعات بیشتر به چشم ابزار دیده میشه
@code_crafters
❤6
بچه ها واسه اکانت gpt , Gemini با یه قیمت خیلی پایین روی جیمیل خودتون به آیدی زیر پیام بدید براتون فعال میکنه
@Ss13730
@Ss13730
فرض کنید جملهی زیر را داریم:
«من گرسنه هستم.»
این جمله برای انسان کاملاً قابل فهم است، اما کامپیوتر در ابتدا آن را فقط بهعنوان یک رشته (String) از کاراکترها میبیند و هیچ درکی از مفهوم آن ندارد.
برای اینکه کامپیوتر بتواند مفهوم متن را درک کند، از یک Embedding Model استفاده میکنیم. این مدل متن را به یک لیست از اعداد تبدیل میکند؛ برای مثال:
به این لیست از اعداد Vector (بردار) گفته میشود.
این بردار در واقع مختصات متن در یک فضای n بعدی است؛ یعنی هر عدد یکی از ابعاد این فضا را نشان میدهد و مجموع این اعداد مشخص میکند که متن در چه موقعیتی از فضای معنایی قرار گرفته است.
حالا جملهی دیگری را در نظر بگیرید:
«من غذا میخواهم.»
برای انسان، مفهوم این جمله به «من گرسنه هستم» نزدیک است، اما کامپیوتر هنوز این موضوع را نمیداند. بنابراین این جمله نیز توسط همان Embedding Model به یک بردار تبدیل میشود؛ مثلاً:
اکنون کامپیوتر این دو بردار را با هم مقایسه میکند. اگر فاصلهی آنها کم باشد (یا شباهت آنها زیاد باشد)، نتیجه میگیرد که این دو متن از نظر معنایی به یکدیگر نزدیک هستند، حتی اگر دقیقاً از کلمات یکسانی استفاده نکرده باشند.
اگر هزاران یا میلیونها متن را به همین روش به بردار تبدیل کنیم، مجموعهای از بردارها خواهیم داشت که میتوان آنها را بهصورت یک ماتریس در نظر گرفت؛ ماتریسی که هر سطر آن بردار مربوط به یک متن است. از آنجا که این بردارها معمولاً صدها یا هزاران بعد دارند، به این محیط فضای چندبعدی (Vector Space) گفته میشود.
برای ذخیره و جستجوی سریع این حجم از بردارها از Vector Store یا Vector Database استفاده میکنیم. این سیستمها با استفاده از الگوریتمهای جستجوی شباهت، نزدیکترین بردارها را در میان میلیونها بردار با سرعت بالا پیدا میکنند.
در این فرآیند، Embedding Model وظیفهی تبدیل متن به بردار را بر عهده دارد و خروجی آن Embedding نامیده میشود. سپس این بردارها در یک Vector Store ذخیره میشوند تا بتوان بر اساس شباهت معنایی بین آنها جستجو انجام داد.
@code_crafters
«من گرسنه هستم.»
این جمله برای انسان کاملاً قابل فهم است، اما کامپیوتر در ابتدا آن را فقط بهعنوان یک رشته (String) از کاراکترها میبیند و هیچ درکی از مفهوم آن ندارد.
برای اینکه کامپیوتر بتواند مفهوم متن را درک کند، از یک Embedding Model استفاده میکنیم. این مدل متن را به یک لیست از اعداد تبدیل میکند؛ برای مثال:
[0.1, 1.0, -0.75]
به این لیست از اعداد Vector (بردار) گفته میشود.
این بردار در واقع مختصات متن در یک فضای n بعدی است؛ یعنی هر عدد یکی از ابعاد این فضا را نشان میدهد و مجموع این اعداد مشخص میکند که متن در چه موقعیتی از فضای معنایی قرار گرفته است.
حالا جملهی دیگری را در نظر بگیرید:
«من غذا میخواهم.»
برای انسان، مفهوم این جمله به «من گرسنه هستم» نزدیک است، اما کامپیوتر هنوز این موضوع را نمیداند. بنابراین این جمله نیز توسط همان Embedding Model به یک بردار تبدیل میشود؛ مثلاً:
[0.1, 1.2, -0.65]
اکنون کامپیوتر این دو بردار را با هم مقایسه میکند. اگر فاصلهی آنها کم باشد (یا شباهت آنها زیاد باشد)، نتیجه میگیرد که این دو متن از نظر معنایی به یکدیگر نزدیک هستند، حتی اگر دقیقاً از کلمات یکسانی استفاده نکرده باشند.
اگر هزاران یا میلیونها متن را به همین روش به بردار تبدیل کنیم، مجموعهای از بردارها خواهیم داشت که میتوان آنها را بهصورت یک ماتریس در نظر گرفت؛ ماتریسی که هر سطر آن بردار مربوط به یک متن است. از آنجا که این بردارها معمولاً صدها یا هزاران بعد دارند، به این محیط فضای چندبعدی (Vector Space) گفته میشود.
برای ذخیره و جستجوی سریع این حجم از بردارها از Vector Store یا Vector Database استفاده میکنیم. این سیستمها با استفاده از الگوریتمهای جستجوی شباهت، نزدیکترین بردارها را در میان میلیونها بردار با سرعت بالا پیدا میکنند.
در این فرآیند، Embedding Model وظیفهی تبدیل متن به بردار را بر عهده دارد و خروجی آن Embedding نامیده میشود. سپس این بردارها در یک Vector Store ذخیره میشوند تا بتوان بر اساس شباهت معنایی بین آنها جستجو انجام داد.
@code_crafters
❤4
معماری retrieval:
خب راجب مدلهای نهفته (embedding model) صحبت کردیم و راجب خود embedd و vector store هم آشنا شدیم
داستان بعدی ما از چه قراره
اینکه ما میخوایم دادههای زیاد و سنگین رو داخل vector store ذخیره کنیم
برای اینکار ما دو شیوه کلی داریم granular (دانه ریز) و coarse (دانه درشت)
دانه ریز یعنی ما سند و متن بزرگ رو به به چند متن کوچکتر بشکنیم و ذخیره کنیم
دانه درشت یعنی کل متن رو یکجا ذخیره کنیم
اما هر کدوم مشکلات و مزایای خودشون رو دارن تو حالت دانه ریز دقت بالاست ولی جواب جامع نیست
تو حالت دانه درشت دقت پایین ولی جواب جامع هستش
بهترین رویکرد ترکیب هر دو هستش
بعلاوه اینکه ذخیره متون بزرگ در vector store خودش ضعفهای زیادی هم داره
راهکار چیه؟؟؟
ما دانه درشت رو در بیرون از vector store ذخیره میکنیم و یک شماره ارجاع براش در نظر میگیریم و در vector store دانه ریز رو ذخیره میکنیم همراه شماره ارجاع، به این روش parentdocument گفته میشه
یعنی جستجوی مفهومی برای دقت بیشتر به vector store میدیم شماره ارجاع رو بر میداریم و کتن اصلی رو برمیگردونیم که تو این حالت هم دقت داریم و هم جامعیت
آیا میتونیم کاری کنیم تا جواب یکسری سوالات نامفهوم (کاربری که پرامپت خوب بلد نیست) بنویس رو هم بدیم، از یک رویکرد باحال استفاده میکنیم، خودمون یکسری متن کوتاه تولید میکنیم از روی متن برش خورده (دانه ریز) و اونم در vector store ذخیره میکنیم که به این روش multi vector retrieval گفته میشه
اگه نیاز داشته باشیم یک سیستم فیلترینگ هم داشته باشیم(متن بزرگ ما شامل چند بخش مختلف و متفاوت باشد مثلا در یک کتاب ما چندین فصل و موضوع متفاوت داریم) با استفاده از meta data میتونیم این رو هم هندل کنیم یعنی تو بخش متادیتامون برای هر متن دانه ریز یکسری تگ ذخیره میکنیم برای مثال -فصل سوم -لانگچین، با استفاده از meta data میتونیم این رو هم هندل کنیم
یک نکته vector store بسیار متفاوت از ذخیره سازهای گرافی هستش (دیتابیسهایی که روابط بزرگ و پیچیده رو نشون میدن، هر نود یک آبجکت و هر یال ارتباط اون آبجکت با سایر آبجکتهای موجود رو نشون میده) برای داشتن چیزی حدودی شبیه گراف هم در همین بخش metadata میتونیم یکسری روابط بین امبدینگ هارو هم مشخص کنیم برای مثال تومتادیتا یه همچین چیزی ذخیره میکنیم
relate:{"ai engineering", "hands on"}
@code_crafters
خب راجب مدلهای نهفته (embedding model) صحبت کردیم و راجب خود embedd و vector store هم آشنا شدیم
داستان بعدی ما از چه قراره
اینکه ما میخوایم دادههای زیاد و سنگین رو داخل vector store ذخیره کنیم
برای اینکار ما دو شیوه کلی داریم granular (دانه ریز) و coarse (دانه درشت)
دانه ریز یعنی ما سند و متن بزرگ رو به به چند متن کوچکتر بشکنیم و ذخیره کنیم
دانه درشت یعنی کل متن رو یکجا ذخیره کنیم
اما هر کدوم مشکلات و مزایای خودشون رو دارن تو حالت دانه ریز دقت بالاست ولی جواب جامع نیست
تو حالت دانه درشت دقت پایین ولی جواب جامع هستش
بهترین رویکرد ترکیب هر دو هستش
بعلاوه اینکه ذخیره متون بزرگ در vector store خودش ضعفهای زیادی هم داره
راهکار چیه؟؟؟
ما دانه درشت رو در بیرون از vector store ذخیره میکنیم و یک شماره ارجاع براش در نظر میگیریم و در vector store دانه ریز رو ذخیره میکنیم همراه شماره ارجاع، به این روش parentdocument گفته میشه
یعنی جستجوی مفهومی برای دقت بیشتر به vector store میدیم شماره ارجاع رو بر میداریم و کتن اصلی رو برمیگردونیم که تو این حالت هم دقت داریم و هم جامعیت
آیا میتونیم کاری کنیم تا جواب یکسری سوالات نامفهوم (کاربری که پرامپت خوب بلد نیست) بنویس رو هم بدیم، از یک رویکرد باحال استفاده میکنیم، خودمون یکسری متن کوتاه تولید میکنیم از روی متن برش خورده (دانه ریز) و اونم در vector store ذخیره میکنیم که به این روش multi vector retrieval گفته میشه
اگه نیاز داشته باشیم یک سیستم فیلترینگ هم داشته باشیم(متن بزرگ ما شامل چند بخش مختلف و متفاوت باشد مثلا در یک کتاب ما چندین فصل و موضوع متفاوت داریم) با استفاده از meta data میتونیم این رو هم هندل کنیم یعنی تو بخش متادیتامون برای هر متن دانه ریز یکسری تگ ذخیره میکنیم برای مثال -فصل سوم -لانگچین، با استفاده از meta data میتونیم این رو هم هندل کنیم
یک نکته vector store بسیار متفاوت از ذخیره سازهای گرافی هستش (دیتابیسهایی که روابط بزرگ و پیچیده رو نشون میدن، هر نود یک آبجکت و هر یال ارتباط اون آبجکت با سایر آبجکتهای موجود رو نشون میده) برای داشتن چیزی حدودی شبیه گراف هم در همین بخش metadata میتونیم یکسری روابط بین امبدینگ هارو هم مشخص کنیم برای مثال تومتادیتا یه همچین چیزی ذخیره میکنیم
relate:{"ai engineering", "hands on"}
@code_crafters
❤3
Semantic Search و Vector Databaseها
در متنهای قبلی دربارهی Embedding صحبت کردیم و با چند تکنیک برای افزایش Performance و دقت جستجو آشنا شدیم.
اما یک سؤال مهم وجود دارد:
آیا دقت بالاتر در Search الزاماً به معنی کیفیت بالاتر پاسخ است؟
لزوماً نه.
در Semantic Search ما به دنبال معنا هستیم، اما وقتی Query کاربر پیچیدهتر میشود، صرفاً پیدا کردن نزدیکترین Embeddingها نمیتواند کیفیت پاسخ را تضمین کند.
برای مثال ممکن است یک Query به چند مفهوم مختلف اشاره کند و یک Vector Search ساده، اسناد مرتبط با هر مفهوم را پیدا کند، اما نتواند بهترین ترکیب از اطلاعات را برای پاسخ نهایی در اختیار LLM قرار دهد.
اینجاست که صرفاً بهینهسازی Embedding یا Vector Search دیگر کافی نیست و باید سراغ الگوهای پیشرفتهتر برویم.
دو مورد مهم:
Hybrid Search
ترکیب Semantic/Vector Search و Keyword Search برای اینکه هم مفهوم Query و هم کلمات و عبارات دقیق آن را در نظر بگیریم.
Reranking
بعد از اینکه چندین Document اولیه را با Search پیدا کردیم، یک مرحلهی دوم برای رتبهبندی مجدد آنها انجام میدهیم تا مرتبطترین Documents در بالاترین رتبه قرار بگیرند.
در نتیجه Pipeline ما میتواند چیزی شبیه این باشد:
اما بحث فقط Search نیست.
وقتی با دادههای حجیم، Big Data و دادههای چندوجهی (Multimodal) مثل Text، Image، Audio و Video سروکار داریم، انتخاب Storage و Data Architecture نیز اهمیت بیشتری پیدا میکند.
اینجاست که ابزارهایی مانند LanceDB مطرح میشوند.
LanceDB یک Vector Database/AI Data Platform مبتنی بر Lance است که برای Workloadهای AI و دادههای Embedding طراحی شده و قابلیتهایی مانند:
* Semantic / Vector Search
* Hybrid Search
* Metadata Filtering
* مدیریت دادههای Multimodal
* کار با حجم بالای داده
* و استفاده از Storageهایی مانند Local Filesystem و Object Storageهایی مثل S3
را فراهم میکند.
البته این به معنی آن نیست که PostgreSQL، Chroma یا Elasticsearch در حجم بالا دیگر قابل استفاده نیستند. هرکدام برای Workload و معماری خاصی مناسب هستند.
بنابراین مسئله اصلی دیگر فقط این نیست که:
«چطور Search را دقیقتر کنیم؟»
بلکه سؤال مهمتر این است:
«چطور یک Retrieval Architecture طراحی کنیم که بتواند اطلاعات درست را از بین حجم زیادی از داده، با توجه به معنا، Keyword، Metadata و Context پیدا کند؟»
و این دقیقاً جایی است که مفاهیمی مثل:
Embedding → Semantic Search → Hybrid Search → Reranking → Context Optimization → RAG
در کنار یکدیگر قرار میگیرند.
@code_crafters
در متنهای قبلی دربارهی Embedding صحبت کردیم و با چند تکنیک برای افزایش Performance و دقت جستجو آشنا شدیم.
اما یک سؤال مهم وجود دارد:
آیا دقت بالاتر در Search الزاماً به معنی کیفیت بالاتر پاسخ است؟
لزوماً نه.
در Semantic Search ما به دنبال معنا هستیم، اما وقتی Query کاربر پیچیدهتر میشود، صرفاً پیدا کردن نزدیکترین Embeddingها نمیتواند کیفیت پاسخ را تضمین کند.
برای مثال ممکن است یک Query به چند مفهوم مختلف اشاره کند و یک Vector Search ساده، اسناد مرتبط با هر مفهوم را پیدا کند، اما نتواند بهترین ترکیب از اطلاعات را برای پاسخ نهایی در اختیار LLM قرار دهد.
اینجاست که صرفاً بهینهسازی Embedding یا Vector Search دیگر کافی نیست و باید سراغ الگوهای پیشرفتهتر برویم.
دو مورد مهم:
Hybrid Search
ترکیب Semantic/Vector Search و Keyword Search برای اینکه هم مفهوم Query و هم کلمات و عبارات دقیق آن را در نظر بگیریم.
Reranking
بعد از اینکه چندین Document اولیه را با Search پیدا کردیم، یک مرحلهی دوم برای رتبهبندی مجدد آنها انجام میدهیم تا مرتبطترین Documents در بالاترین رتبه قرار بگیرند.
در نتیجه Pipeline ما میتواند چیزی شبیه این باشد:
Query → Vector Search + Keyword Search → Hybrid Search → Reranking → Context → LLMاما بحث فقط Search نیست.
وقتی با دادههای حجیم، Big Data و دادههای چندوجهی (Multimodal) مثل Text، Image، Audio و Video سروکار داریم، انتخاب Storage و Data Architecture نیز اهمیت بیشتری پیدا میکند.
اینجاست که ابزارهایی مانند LanceDB مطرح میشوند.
LanceDB یک Vector Database/AI Data Platform مبتنی بر Lance است که برای Workloadهای AI و دادههای Embedding طراحی شده و قابلیتهایی مانند:
* Semantic / Vector Search
* Hybrid Search
* Metadata Filtering
* مدیریت دادههای Multimodal
* کار با حجم بالای داده
* و استفاده از Storageهایی مانند Local Filesystem و Object Storageهایی مثل S3
را فراهم میکند.
البته این به معنی آن نیست که PostgreSQL، Chroma یا Elasticsearch در حجم بالا دیگر قابل استفاده نیستند. هرکدام برای Workload و معماری خاصی مناسب هستند.
بنابراین مسئله اصلی دیگر فقط این نیست که:
«چطور Search را دقیقتر کنیم؟»
بلکه سؤال مهمتر این است:
«چطور یک Retrieval Architecture طراحی کنیم که بتواند اطلاعات درست را از بین حجم زیادی از داده، با توجه به معنا، Keyword، Metadata و Context پیدا کند؟»
و این دقیقاً جایی است که مفاهیمی مثل:
Embedding → Semantic Search → Hybrid Search → Reranking → Context Optimization → RAG
در کنار یکدیگر قرار میگیرند.
@code_crafters
👍1
این کتاب کوبرنتیز رو حتما بخونید، سبکه و خیلی سریع مفاهیم کلی کوبرنتیز رو بهتون انتقال میده
@code_crafters
@code_crafters
❤6
🧩 Kubernetes Design Patterns
که باید بشناسید
وقتی با Kubernetes کار میکنیم، فقط
در این پست چند Pattern مهم را با مثال مرور میکنیم 👇
1️⃣ Sidecar Pattern
در این الگو یک Container جانبی کنار Container اصلی و در همان Pod اجرا میشود.
مثال
Application لاگ تولید میکند و Sidecar مسئول ارسال آن به Loki است:
کاربردها:
Log Collection
Proxy
Service Mesh
Monitoring
Security Agent
📌 نکته: Sidecar یک Deployment Pattern است؛ یعنی میگوید Container جانبی کجا قرار گرفته است.
2️⃣ Adapter Pattern
Adapter برای تبدیل Interface یا Format استفاده میشود.
فرض کنید Application متریکها را با فرمت اختصاصی خودش تولید میکند:
ولی Monitoring شما Prometheus Format میخواهد.
Application را تغییر نمیدهیم؛ Adapter خروجی آن را به چیزی که سیستم مقصد انتظار دارد تبدیل میکند.
کاربردها:
تبدیل Metrics
تبدیل Logs
تبدیل Protocol
تبدیل API Format
📌 Adapter میتواند خودش بهصورت یک Sidecar Container پیادهسازی شود.
3️⃣ Ambassador Pattern
Ambassador به نمایندگی از Application با یک سرویس خارجی ارتباط برقرار میکند.
مثلاً Application باید به Redis خارج از Kubernetes وصل شود:
Application فقط میداند:
ولی Ambassador میداند Redis واقعی کجاست:
Ambassador میتواند مسئول مواردی مثل:
TLS
Authentication
Retry
Connection Pooling
Routing
باشد.
📌 تفاوت با Adapter:
4️⃣ Init Container Pattern
گاهی قبل از اجرای Application باید کاری انجام شود.
در اینجا از Init Container استفاده میکنیم:
مثلاً:
یا:
Init Container باید با موفقیت تمام شود تا Container اصلی اجرا شود.
5️⃣ Leader Election Pattern
گاهی چند Replica داریم ولی فقط یکی باید Leader باشد.
مثلاً:
ولی فقط:
کار اصلی را انجام میدهد.
اگر Pod-2 از بین برود:
یکی از آنها Leader میشود.
کاربرد:
Celery Beat
Scheduler
Controllerها
Workerهای Singleton
Jobs حساس به Duplicate Execution
6️⃣ Singleton Pattern
گاهی از یک Application فقط باید یک Instance فعال داشته باشیم.
مثلاً:
نمیخواهیم:
همزمان Taskها را Schedule کنند.
میتوانیم:
قرار دهیم.
اما ⚠️ این بهتنهایی HA واقعی نیست.
اگر Pod بمیرد، Kubernetes آن را دوباره میسازد؛ ولی برای جلوگیری از اجرای همزمان چند Instance، در سیستمهای حساس معمولاً Leader Election یا Distributed Lock راه مطمئنتری است.
7️⃣ Stateful Pattern
برای Applicationهایی که Identity پایدار یا Storage مخصوص هر Instance دارند، از StatefulSet استفاده میکنیم.
مثلاً:
برخلاف Deployment، این Podها Identity پایدار دارند.
همراه با:
میتوانیم DNS پایدار داشته باشیم:
کاربرد:
PostgreSQL
Kafka
ZooKeeper
Elasticsearch
بعضی سیستمهای Distributed
⚠️ StatefulSet بهتنهایی به معنی Database HA نیست.
8️⃣ Service Discovery Pattern
#k8s
@code_crafters
که باید بشناسید
وقتی با Kubernetes کار میکنیم، فقط
Deployment و Service مهم نیستند. Kubernetes یکسری Pattern دارد که برای حل مسائل رایج در معماری و اجرای Applicationها استفاده میشوند.در این پست چند Pattern مهم را با مثال مرور میکنیم 👇
1️⃣ Sidecar Pattern
در این الگو یک Container جانبی کنار Container اصلی و در همان Pod اجرا میشود.
Pod
┌──────────────────────────┐
│ │
│ Application │
│ │ │
│ ▼ │
│ Sidecar │
│ │
└──────────────────────────┘
مثال
Application لاگ تولید میکند و Sidecar مسئول ارسال آن به Loki است:
App
│
│ logs
▼
Shared Volume
│
▼
Fluent Bit
│
▼
Loki
کاربردها:
Log Collection
Proxy
Service Mesh
Monitoring
Security Agent
📌 نکته: Sidecar یک Deployment Pattern است؛ یعنی میگوید Container جانبی کجا قرار گرفته است.
2️⃣ Adapter Pattern
Adapter برای تبدیل Interface یا Format استفاده میشود.
فرض کنید Application متریکها را با فرمت اختصاصی خودش تولید میکند:
requests=100
errors=5
ولی Monitoring شما Prometheus Format میخواهد.
Application
│
▼
Adapter
│
▼
Prometheus Format
│
▼
Prometheus
Application را تغییر نمیدهیم؛ Adapter خروجی آن را به چیزی که سیستم مقصد انتظار دارد تبدیل میکند.
کاربردها:
تبدیل Metrics
تبدیل Logs
تبدیل Protocol
تبدیل API Format
📌 Adapter میتواند خودش بهصورت یک Sidecar Container پیادهسازی شود.
3️⃣ Ambassador Pattern
Ambassador به نمایندگی از Application با یک سرویس خارجی ارتباط برقرار میکند.
مثلاً Application باید به Redis خارج از Kubernetes وصل شود:
Pod
┌──────────────────────────┐
│ │
│ Application │
│ │ │
│ ▼ │
│ Ambassador │
│ │
└──────┼───────────────────┘
│
▼
External Redis
Application فقط میداند:
localhost:6379
ولی Ambassador میداند Redis واقعی کجاست:
10.10.20.30:6379
Ambassador میتواند مسئول مواردی مثل:
TLS
Authentication
Retry
Connection Pooling
Routing
باشد.
📌 تفاوت با Adapter:
Adapter → تبدیل Interface
Ambassador → ارتباط با سرویس خارجی
4️⃣ Init Container Pattern
گاهی قبل از اجرای Application باید کاری انجام شود.
در اینجا از Init Container استفاده میکنیم:
Init Container
↓
Main Container
مثلاً:
Migration
↓
Django
یا:
Download Config
↓
Application
Init Container باید با موفقیت تمام شود تا Container اصلی اجرا شود.
5️⃣ Leader Election Pattern
گاهی چند Replica داریم ولی فقط یکی باید Leader باشد.
مثلاً:
Pod-1
Pod-2
Pod-3
ولی فقط:
Pod-2 = Leader
کار اصلی را انجام میدهد.
Leader Election
│
┌──────┼──────┐
▼ ▼ ▼
Pod-1 Pod-2 Pod-3
★
Leader
اگر Pod-2 از بین برود:
Pod-1
Pod-3
یکی از آنها Leader میشود.
کاربرد:
Celery Beat
Scheduler
Controllerها
Workerهای Singleton
Jobs حساس به Duplicate Execution
6️⃣ Singleton Pattern
گاهی از یک Application فقط باید یک Instance فعال داشته باشیم.
مثلاً:
Celery Beat
نمیخواهیم:
Beat-1
Beat-2
Beat-3
همزمان Taskها را Schedule کنند.
میتوانیم:
Replica = 1
قرار دهیم.
اما ⚠️ این بهتنهایی HA واقعی نیست.
اگر Pod بمیرد، Kubernetes آن را دوباره میسازد؛ ولی برای جلوگیری از اجرای همزمان چند Instance، در سیستمهای حساس معمولاً Leader Election یا Distributed Lock راه مطمئنتری است.
7️⃣ Stateful Pattern
برای Applicationهایی که Identity پایدار یا Storage مخصوص هر Instance دارند، از StatefulSet استفاده میکنیم.
مثلاً:
postgres-0
postgres-1
postgres-2
برخلاف Deployment، این Podها Identity پایدار دارند.
همراه با:
Headless Service
میتوانیم DNS پایدار داشته باشیم:
postgres-0.postgres
postgres-1.postgres
postgres-2.postgres
کاربرد:
PostgreSQL
Kafka
ZooKeeper
Elasticsearch
بعضی سیستمهای Distributed
⚠️ StatefulSet بهتنهایی به معنی Database HA نیست.
8️⃣ Service Discovery Pattern
#k8s
@code_crafters
❤4
خب Application نباید به IP مستقیم Podها وابسته باشد.
❌ بد:
✅ بهتر:
ساختار:
در Kubernetes معمولاً CoreDNS وظیفه DNS Discovery را انجام میدهد.
9️⃣ Self-Awareness / Downward API
گاهی Application باید بداند خودش چه مشخصاتی دارد.
مثلاً:
با Downward API:
مثلاً:
Application:
📌 تفاوت مهم:
🔟 Job / Work Queue Pattern
برای کارهایی که باید یکبار یا تعداد مشخصی اجرا شوند، بهجای Deployment از Job استفاده میکنیم.
مثلاً:
مثال:
میتوانیم کار را بین Workerها تقسیم کنیم.
برای کارهای دورهای:
استفاده میکنیم.
1️⃣1️⃣ Controller / Operator Pattern
یکی از قدرتمندترین Patternهای Kubernetes.
بهجای اینکه انسان دائماً وضعیت سیستم را مدیریت کند، یک Controller وضعیت مطلوب را تعریف و حفظ میکند.
مثلاً:
Operatorها همین ایده را برای Applicationهای پیچیدهتر به کار میبرند.
مثلاً یک PostgreSQL Operator میتواند:
را مدیریت کند.
1️⃣2️⃣ External Service Pattern
اگر Database خارج Kubernetes باشد، لازم نیست Application مستقیماً IP آن را Hardcode کند.
میتوانیم یک Service بدون Selector داشته باشیم:
در این حالت Application فقط میداند:
و محل واقعی Database از Application پنهان میماند.
🧠 جمعبندی
اگر بخواهیم Patternها را خیلی خلاصه کنیم:
⭐ یک نکته مهم
این Patternها لزوماً جایگزین یکدیگر نیستند و حتی میتوانند با هم ترکیب شوند.
مثلاً:
قدرت واقعی Kubernetes دقیقاً از همین ترکیب Patternها به وجود میآید.
#k8s
@code_crafters
❌ بد:
10.42.0.17
✅ بهتر:
postgres.default.svc.cluster.local
ساختار:
Application
│
▼
DNS
│
▼
Service
│
▼
EndpointSlice
│
▼
Backend Pods
در Kubernetes معمولاً CoreDNS وظیفه DNS Discovery را انجام میدهد.
9️⃣ Self-Awareness / Downward API
گاهی Application باید بداند خودش چه مشخصاتی دارد.
مثلاً:
من چه Podی هستم؟
IP من چیست؟
روی چه Nodeای هستم؟
Namespace من چیست؟
با Downward API:
Kubernetes
│
▼
Downward API
│
▼
Application
مثلاً:
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: POD_IP
valueFrom:
fieldRef:
fieldPath: status.podIP
Application:
POD_NAME=api-7f89d
POD_IP=10.42.1.20
📌 تفاوت مهم:
Service Discovery
→ دیگران را پیدا میکنم
Downward API
→ خودم را میشناسم
🔟 Job / Work Queue Pattern
برای کارهایی که باید یکبار یا تعداد مشخصی اجرا شوند، بهجای Deployment از Job استفاده میکنیم.
مثلاً:
Job
│
├── Worker
├── Worker
└── Worker
مثال:
Process 10,000 images
میتوانیم کار را بین Workerها تقسیم کنیم.
برای کارهای دورهای:
CronJob
استفاده میکنیم.
CronJob
│
├── Job 01
├── Job 02
└── Job 03
1️⃣1️⃣ Controller / Operator Pattern
یکی از قدرتمندترین Patternهای Kubernetes.
بهجای اینکه انسان دائماً وضعیت سیستم را مدیریت کند، یک Controller وضعیت مطلوب را تعریف و حفظ میکند.
مثلاً:
Desired State
│
▼
Controller
│
▼
Kubernetes API
│
▼
Actual State
Operatorها همین ایده را برای Applicationهای پیچیدهتر به کار میبرند.
مثلاً یک PostgreSQL Operator میتواند:
Primary Failure
↓
Detect
↓
Promote Replica
↓
Update Service
↓
New Primary
را مدیریت کند.
1️⃣2️⃣ External Service Pattern
اگر Database خارج Kubernetes باشد، لازم نیست Application مستقیماً IP آن را Hardcode کند.
میتوانیم یک Service بدون Selector داشته باشیم:
Application
│
▼
postgres Service
│
▼
EndpointSlice
│
▼
10.10.20.30:5432
│
▼
External PostgreSQL
در این حالت Application فقط میداند:
postgres:5432
و محل واقعی Database از Application پنهان میماند.
🧠 جمعبندی
اگر بخواهیم Patternها را خیلی خلاصه کنیم:
Sidecar
→ قابلیت جانبی کنار Application
Adapter
→ تبدیل Interface / Format
Ambassador
→ ارتباط با سرویس خارجی به نمایندگی از Application
Init Container
→ آمادهسازی قبل از Application
Leader Election
→ انتخاب یک Instance بهعنوان Leader
Singleton
→ فقط یک Instance فعال
StatefulSet
→ Identity و Storage پایدار
Service Discovery
→ پیدا کردن سرویسها
Downward API
→ شناخت خود Pod
Job / CronJob
→ اجرای کارهای Batch
Controller / Operator
→ حفظ وضعیت مطلوب بهصورت خودکار
External Service
→ دسترسی به سرویس خارج Kubernetes
⭐ یک نکته مهم
این Patternها لزوماً جایگزین یکدیگر نیستند و حتی میتوانند با هم ترکیب شوند.
مثلاً:
Pod
├── Application
├── Envoy Sidecar
└── Adapter Sidecar
│
▼
Service
│
▼
EndpointSlice
│
▼
External Service
قدرت واقعی Kubernetes دقیقاً از همین ترکیب Patternها به وجود میآید.
#k8s
@code_crafters
❤2
دو موضوع مهم در طراحی Agentهای هوشمند
در پستهای قبلی تا حدودی درباره تفاوت جستجوی کلمات مشابه و جستجوی مبتنی بر مفهوم (Semantic Search) صحبت کردیم.
در سیستمهای واقعی، برای رسیدن به نتایج بهتر معمولاً از Hybrid Search استفاده میکنیم تا بتوانیم از قدرت و انعطاف هر دو رویکرد بهره ببریم.
اما دو موضوع مهم دیگر در طراحی Agentها وجود دارد که نقش بسیار مهمی در کیفیت و امنیت سیستم دارند:
---
1️⃣ Reranking؛ پیدا کردن مرتبطترین نتایج
فرض کنید ۶ داکیومنت در اختیار داریم.
با جستجوی کلمهای (Keyword Search)، داکیومنتهای ۱ و ۳ پیدا میشوند.
با جستجوی مفهومی (Semantic Search)، داکیومنتهای ۲ و ۴ به دست میآیند.
حالا سؤال این است:
در نهایت کدام داکیومنتها واقعاً بهترین پاسخ را برای سؤال کاربر دارند؟
اینجاست که Reranking وارد میشود.
در Reranking، نتایج اولیه بر اساس میزان ارتباط و کیفیت، مجدداً امتیازدهی و مرتب میشوند.
به طور کلی دو رویکرد برای ساخت سیستم Reranking داریم:
🔹 رویکرد اول: ساخت مدل امتیازدهی داخلی
میتوان از متخصصان و افراد سازمان خواست نتایج مختلف را ارزیابی و امتیازدهی کنند. سپس با جمعآوری این دادهها میتوان یک مدل یا سیستم امتیازدهی متناسب با نیازهای همان سازمان ایجاد کرد.
🔹 رویکرد دوم: استفاده از مدلهای آماده
میتوان از مدلهای آماده و Open Source موجود در اکوسیستم Hugging Face استفاده کرد، مانند:
* Sentence Transformers
* BGE Reranker از BAAI
* و مدلهای مشابه
در نهایت Reranker مانند یک فیلتر هوشمند عمل میکند و از میان نتایج اولیه، مرتبطترین موارد را انتخاب میکند.
این موضوع اهمیت زیادی دارد؛ چون قرار نیست تمام اطلاعات بازیابیشده را به مدل اصلی منتقل کنیم.
برای مثال:
در نتیجه، هم کیفیت Context افزایش پیدا میکند و هم حجم اطلاعاتی که به مدل اصلی منتقل میشود کاهش مییابد؛ موضوعی که میتواند روی هزینه، سرعت و کیفیت پاسخ تأثیر مستقیم داشته باشد.
---
2️⃣ Guardrail؛ کنترل رفتار و خروجی Agent
موضوع مهم دوم Guardrail است.
مدلهای هوش مصنوعی عاری از خطا نیستند؛ حتی مدلهای قدرتمند نیز ممکن است دچار Hallucination شوند یا در شرایط خاص، خروجی نامناسب، تبعیضآمیز یا قابل سوءاستفاده تولید کنند.
بنابراین در معماری Agent باید لایههایی برای کنترل ورودی و خروجی در نظر بگیریم.
یک رویکرد این است که از خود یک LLM به عنوان ناظر استفاده کنیم.
برای مثال، یک Prompt به مدل میدهیم که:
> پاسخ را بررسی کن، فقط بر اساس دادههای دریافتشده قضاوت کن و اگر پاسخ نامناسب بود، آن را رد کن.
در این حالت یک مدل بزرگ مانند GPT میتواند نقش Evaluator / Guardrail را داشته باشد.
اما راهکار دیگر استفاده از مدلهای تخصصی Safety Classifier است.
یکی از نمونههای معروف:
🛡️ ShieldGemma
ShieldGemma محصول Google و خانواده Gemma است که برای Safety Classification طراحی شده است.
میتوان از آن برای بررسی ورودی کاربر و همچنین بررسی خروجی Agent یا LLM استفاده کرد.
برای مثال:
در نتیجه میتوان Guardrail را هم قبل از اجرای Agent و هم بعد از تولید پاسخ قرار داد.
ShieldGemma در نسخههای متنی خود روی دستههایی مانند Harassment، Hate، Dangerous Content و Sexually Explicit Content تمرکز دارد.
---
🛡️ Llama Guard
گزینه شناختهشده دیگر Llama Guard از Meta است.
Llama Guard نیز برای Safety Classification طراحی شده و میتواند در سناریوهای مختلف برای کنترل محتوای ورودی و خروجی مورد استفاده قرار گیرد.
یکی از مزیتهای مهم این خانواده، امکان استفاده و شخصیسازی متناسب با نیازهای سیستم است.
---
جمعبندی
در یک Agent یا RAG System حرفهای، فقط پیدا کردن اطلاعات کافی نیست.
ما باید دو سؤال مهم را پاسخ دهیم:
1. آیا اطلاعاتی که پیدا کردهایم واقعاً مرتبط و باکیفیت هستند؟
⬅️ Reranking
2. آیا ورودی و خروجی سیستم امن، مناسب و مطابق Policy ما هستند؟
⬅️ Guardrails
بنابراین یک معماری ساده میتواند چیزی شبیه این باشد:
@code_crafters
در پستهای قبلی تا حدودی درباره تفاوت جستجوی کلمات مشابه و جستجوی مبتنی بر مفهوم (Semantic Search) صحبت کردیم.
در سیستمهای واقعی، برای رسیدن به نتایج بهتر معمولاً از Hybrid Search استفاده میکنیم تا بتوانیم از قدرت و انعطاف هر دو رویکرد بهره ببریم.
اما دو موضوع مهم دیگر در طراحی Agentها وجود دارد که نقش بسیار مهمی در کیفیت و امنیت سیستم دارند:
---
1️⃣ Reranking؛ پیدا کردن مرتبطترین نتایج
فرض کنید ۶ داکیومنت در اختیار داریم.
با جستجوی کلمهای (Keyword Search)، داکیومنتهای ۱ و ۳ پیدا میشوند.
با جستجوی مفهومی (Semantic Search)، داکیومنتهای ۲ و ۴ به دست میآیند.
حالا سؤال این است:
در نهایت کدام داکیومنتها واقعاً بهترین پاسخ را برای سؤال کاربر دارند؟
اینجاست که Reranking وارد میشود.
در Reranking، نتایج اولیه بر اساس میزان ارتباط و کیفیت، مجدداً امتیازدهی و مرتب میشوند.
به طور کلی دو رویکرد برای ساخت سیستم Reranking داریم:
🔹 رویکرد اول: ساخت مدل امتیازدهی داخلی
میتوان از متخصصان و افراد سازمان خواست نتایج مختلف را ارزیابی و امتیازدهی کنند. سپس با جمعآوری این دادهها میتوان یک مدل یا سیستم امتیازدهی متناسب با نیازهای همان سازمان ایجاد کرد.
🔹 رویکرد دوم: استفاده از مدلهای آماده
میتوان از مدلهای آماده و Open Source موجود در اکوسیستم Hugging Face استفاده کرد، مانند:
* Sentence Transformers
* BGE Reranker از BAAI
* و مدلهای مشابه
در نهایت Reranker مانند یک فیلتر هوشمند عمل میکند و از میان نتایج اولیه، مرتبطترین موارد را انتخاب میکند.
این موضوع اهمیت زیادی دارد؛ چون قرار نیست تمام اطلاعات بازیابیشده را به مدل اصلی منتقل کنیم.
برای مثال:
User Query
↓
Hybrid Search
↓
20 Documents
↓
Reranker
↓
Top 5 Documents
↓
LLM / Agent
در نتیجه، هم کیفیت Context افزایش پیدا میکند و هم حجم اطلاعاتی که به مدل اصلی منتقل میشود کاهش مییابد؛ موضوعی که میتواند روی هزینه، سرعت و کیفیت پاسخ تأثیر مستقیم داشته باشد.
---
2️⃣ Guardrail؛ کنترل رفتار و خروجی Agent
موضوع مهم دوم Guardrail است.
مدلهای هوش مصنوعی عاری از خطا نیستند؛ حتی مدلهای قدرتمند نیز ممکن است دچار Hallucination شوند یا در شرایط خاص، خروجی نامناسب، تبعیضآمیز یا قابل سوءاستفاده تولید کنند.
بنابراین در معماری Agent باید لایههایی برای کنترل ورودی و خروجی در نظر بگیریم.
یک رویکرد این است که از خود یک LLM به عنوان ناظر استفاده کنیم.
برای مثال، یک Prompt به مدل میدهیم که:
> پاسخ را بررسی کن، فقط بر اساس دادههای دریافتشده قضاوت کن و اگر پاسخ نامناسب بود، آن را رد کن.
در این حالت یک مدل بزرگ مانند GPT میتواند نقش Evaluator / Guardrail را داشته باشد.
اما راهکار دیگر استفاده از مدلهای تخصصی Safety Classifier است.
یکی از نمونههای معروف:
🛡️ ShieldGemma
ShieldGemma محصول Google و خانواده Gemma است که برای Safety Classification طراحی شده است.
میتوان از آن برای بررسی ورودی کاربر و همچنین بررسی خروجی Agent یا LLM استفاده کرد.
برای مثال:
User Input
↓
ShieldGemma
↓
Safe?
├── No → Block
│
└── Yes
↓
Agent
↓
LLM
↓
ShieldGemma
↓
Safe Output?
├── No → Block
└── Yes → User
در نتیجه میتوان Guardrail را هم قبل از اجرای Agent و هم بعد از تولید پاسخ قرار داد.
ShieldGemma در نسخههای متنی خود روی دستههایی مانند Harassment، Hate، Dangerous Content و Sexually Explicit Content تمرکز دارد.
---
🛡️ Llama Guard
گزینه شناختهشده دیگر Llama Guard از Meta است.
Llama Guard نیز برای Safety Classification طراحی شده و میتواند در سناریوهای مختلف برای کنترل محتوای ورودی و خروجی مورد استفاده قرار گیرد.
یکی از مزیتهای مهم این خانواده، امکان استفاده و شخصیسازی متناسب با نیازهای سیستم است.
---
جمعبندی
در یک Agent یا RAG System حرفهای، فقط پیدا کردن اطلاعات کافی نیست.
ما باید دو سؤال مهم را پاسخ دهیم:
1. آیا اطلاعاتی که پیدا کردهایم واقعاً مرتبط و باکیفیت هستند؟
⬅️ Reranking
2. آیا ورودی و خروجی سیستم امن، مناسب و مطابق Policy ما هستند؟
⬅️ Guardrails
بنابراین یک معماری ساده میتواند چیزی شبیه این باشد:
@code_crafters
❤2
User
│
▼
Input Guardrail
│
▼
Hybrid Search
│
▼
Retrieval
│
▼
Reranker
│
▼
Relevant Context
│
▼
LLM
│
▼
Output Guardrail
│
▼
User
در واقع:
Hybrid Search → پیدا کردن اطلاعات
Reranker → انتخاب بهترین اطلاعات
LLM → تولید پاسخ
Guardrail → کنترل ایمنی و کیفیت پاسخ
این چهار لایه در کنار هم میتوانند پایه یک RAG/Agent Architecture قابل اتکا و Production-Ready را تشکیل دهند.
@code_crafters
🕊2❤1
در عمل چند نوع توهم مهم در RAG , agent داریم که هرکدام منشأ متفاوتی دارند.
1. انواع Hallucination در RAG
در RAG معمولاً این زنجیره را داریم:
User → Retrieval → Context → LLM → Answer
بنابراین توهم میتواند در هر مرحله ایجاد شود.
1. Retrieval Hallucination / Retrieval Failure
مدل اطلاعات غلط تولید نکرده؛ مشکل این است که اطلاعات درست را پیدا نکرده.
مثلاً کاربر میپرسد:
اما Retriever سند مربوط به «قوانین اضافهکاری» را برمیگرداند.
مدل هم بر اساس همان Context پاسخ میدهد.
این یکی از مهمترین مشکلات RAG است.
2. Contextual Hallucination
سند درست به مدل داده شده، اما مدل از Context برداشت اشتباه میکند.
مثلاً سند میگوید:
اما مدل جواب میدهد:
یعنی:
3. Unsupported / Faithfulness Hallucination
اطلاعاتی در Context وجود ندارد، ولی مدل آن را به پاسخ اضافه میکند.
مثلاً Context:
مدل:
در حالی که SAML و LDAP اصلاً در Context نبودهاند.
این مورد در RAG خیلی مهم است.
4. Source Attribution Hallucination
مدل جواب نسبتاً درستی میدهد، اما منبع را اشتباه نسبت میدهد.
مثلاً:
مدل میگوید:
در حالی که LDAP در Document B بوده.
5. Citation Hallucination
مدل citation تولید میکند، ولی citation واقعاً آن ادعا را پشتیبانی نمیکند.
مثلاً:
اما Source 3 اصلاً درباره تعداد کاربران چیزی نگفته است.
این در سیستمهای RAG production بسیار مهم است.
6. Knowledge Cutoff / External Knowledge Hallucination
مدل اطلاعاتی را از دانش خودش وارد میکند، در حالی که RAG قرار بوده فقط بر اساس اسناد داخلی پاسخ دهد.
مثلاً:
مدل ممکن است بگوید:
در حالی که این اطلاعات از knowledge خودش آمده، نه مستندات شرکت.
2. انواع Hallucination در Agent
در Agent قضیه پیچیدهتر میشود.
Agent فقط جواب تولید نمیکند؛ معمولاً:
بنابراین نقاط بیشتری برای hallucination داریم.
1. Planning Hallucination
Agent یک برنامه یا step اشتباه ایجاد میکند.
مثلاً کاربر:
Agent تصمیم میگیرد:
در حالی که باید ابتدا:
باشد.
2. Tool Selection Hallucination
Agent ابزار اشتباهی انتخاب میکند.
مثلاً:
در حالی که باید weather API را صدا بزند.
3. Tool Argument Hallucination
ابزار درست انتخاب شده، ولی Agent پارامتر اشتباه میدهد.
مثلاً:
در حالی که مقدار صحیح باید چیز دیگری باشد.
یا حتی پارامتری را حدس میزند که اصلاً از کاربر دریافت نکرده است.
4. Tool Result Hallucination
Tool نتیجهای نداده یا نتیجه ambiguous بوده، ولی Agent فرض میکند موفق شده است.
مثلاً:
Agent:
این یکی از خطرناکترین hallucinationها در Agent است.
5. Observation Hallucination
Agent خروجی ابزار را اشتباه تفسیر میکند.
مثلاً API:
Agent میگوید:
در حالی که:
6. Memory Hallucination
Agent چیزی را به memory نسبت میدهد که واقعاً در memory وجود ندارد.
مثلاً:
7. State Hallucination
Agent وضعیت فعلی workflow را اشتباه تصور میکند.
مثلاً workflow:
ولی Agent تصور میکند:
در حالی که state هنوز:
است.
@code_crafters
1. انواع Hallucination در RAG
در RAG معمولاً این زنجیره را داریم:
User → Retrieval → Context → LLM → Answer
بنابراین توهم میتواند در هر مرحله ایجاد شود.
1. Retrieval Hallucination / Retrieval Failure
مدل اطلاعات غلط تولید نکرده؛ مشکل این است که اطلاعات درست را پیدا نکرده.
مثلاً کاربر میپرسد:
«شرایط مرخصی در شرکت چیست؟»
اما Retriever سند مربوط به «قوانین اضافهکاری» را برمیگرداند.
مدل هم بر اساس همان Context پاسخ میدهد.
Question
↓
Retriever
↓
❌ Wrong Documents
↓
LLM
↓
Wrong Answer
این یکی از مهمترین مشکلات RAG است.
2. Contextual Hallucination
سند درست به مدل داده شده، اما مدل از Context برداشت اشتباه میکند.
مثلاً سند میگوید:
Employees receive 20 days of annual leave.
اما مدل جواب میدهد:
Employees receive 30 days.
یعنی:
Correct Context
↓
LLM misinterprets
↓
❌ Wrong Answer
3. Unsupported / Faithfulness Hallucination
اطلاعاتی در Context وجود ندارد، ولی مدل آن را به پاسخ اضافه میکند.
مثلاً Context:
Product X supports OAuth2.
مدل:
Product X supports OAuth2, SAML and LDAP.
در حالی که SAML و LDAP اصلاً در Context نبودهاند.
این مورد در RAG خیلی مهم است.
4. Source Attribution Hallucination
مدل جواب نسبتاً درستی میدهد، اما منبع را اشتباه نسبت میدهد.
مثلاً:
Document A:
OAuth2 supported
Document B:
LDAP supported
مدل میگوید:
According to Document A, the system supports LDAP.
در حالی که LDAP در Document B بوده.
5. Citation Hallucination
مدل citation تولید میکند، ولی citation واقعاً آن ادعا را پشتیبانی نمیکند.
مثلاً:
Answer:
The system supports 10,000 users. [Source 3]
اما Source 3 اصلاً درباره تعداد کاربران چیزی نگفته است.
این در سیستمهای RAG production بسیار مهم است.
6. Knowledge Cutoff / External Knowledge Hallucination
مدل اطلاعاتی را از دانش خودش وارد میکند، در حالی که RAG قرار بوده فقط بر اساس اسناد داخلی پاسخ دهد.
مثلاً:
Internal company documentation
↓
RAG
↓
LLM
↓
+ pretrained knowledge
↓
Answer
مدل ممکن است بگوید:
طبق سیاست شرکت، X مجاز است.
در حالی که این اطلاعات از knowledge خودش آمده، نه مستندات شرکت.
2. انواع Hallucination در Agent
در Agent قضیه پیچیدهتر میشود.
Agent فقط جواب تولید نمیکند؛ معمولاً:
Think
↓
Plan
↓
Tool
↓
Observe
↓
Think
↓
Tool
↓
Answer
بنابراین نقاط بیشتری برای hallucination داریم.
1. Planning Hallucination
Agent یک برنامه یا step اشتباه ایجاد میکند.
مثلاً کاربر:
«قیمت دلار را بررسی کن و اگر کمتر از X بود خرید انجام بده.»
Agent تصمیم میگیرد:
1. Search exchange rate
2. Buy immediately
در حالی که باید ابتدا:
1. Get exchange rate
2. Verify rate
3. Compare with threshold
4. Ask/execute according to authorization
باشد.
2. Tool Selection Hallucination
Agent ابزار اشتباهی انتخاب میکند.
مثلاً:
Question:
"What is the current weather?"
Agent:
→ calls database_search
در حالی که باید weather API را صدا بزند.
3. Tool Argument Hallucination
ابزار درست انتخاب شده، ولی Agent پارامتر اشتباه میدهد.
مثلاً:
{
"user_id": 12345,
"amount": 100000
}در حالی که مقدار صحیح باید چیز دیگری باشد.
یا حتی پارامتری را حدس میزند که اصلاً از کاربر دریافت نکرده است.
4. Tool Result Hallucination
Tool نتیجهای نداده یا نتیجه ambiguous بوده، ولی Agent فرض میکند موفق شده است.
مثلاً:
Tool:
ERROR: timeout
Agent:
Payment successfully completed.
این یکی از خطرناکترین hallucinationها در Agent است.
5. Observation Hallucination
Agent خروجی ابزار را اشتباه تفسیر میکند.
مثلاً API:
{
"status": "pending"
}Agent میگوید:
Transaction completed.
در حالی که:
pending ≠ completed
6. Memory Hallucination
Agent چیزی را به memory نسبت میدهد که واقعاً در memory وجود ندارد.
مثلاً:
User never said:
"I prefer PostgreSQL"
Agent:
"You previously told me that you prefer PostgreSQL."
7. State Hallucination
Agent وضعیت فعلی workflow را اشتباه تصور میکند.
مثلاً workflow:
Order Created
↓
Payment Pending
↓
Payment Confirmed
ولی Agent تصور میکند:
Payment Confirmed
در حالی که state هنوز:
Payment Pending
است.
@code_crafters
3. یک تفاوت خیلی مهم
میتوانیم Hallucination را بر اساس محل وقوع هم دستهبندی کنیم:
بنابراین:
ولی:
4. یک مدل ذهنی خیلی خوب
برای RAG:
برای Agent:
پس در Agentic RAG حتی ترکیب این دو را داریم:
و در نتیجه ممکن است چند hallucination پشت سر هم رخ دهد.
مثلاً:
این دقیقاً دلیل اهمیت evaluation و hallucination mitigation در Agentic RAG است.
@code_crafters
میتوانیم Hallucination را بر اساس محل وقوع هم دستهبندی کنیم:
بنابراین:
RAG hallucination بیشتر حول Knowledge + Retrieval + Grounding است.
ولی:
Agent hallucination علاوه بر Knowledge، حول Planning + Tools + State + Memory + Actions هم اتفاق میافتد.
4. یک مدل ذهنی خیلی خوب
برای RAG:
┌── Retrieval Error
│
Question ────┼── Context Error
│
├── Generation Error
│
└── Citation Error
برای Agent:
┌── Planning
│
├── Tool Selection
│
├── Tool Arguments
User → Agent ───┼── Tool Result
│
├── Memory
│
├── State
│
└── Final Answer
پس در Agentic RAG حتی ترکیب این دو را داریم:
User
↓
Agent
↓
Query Generation
↓
Retriever
↓
Documents
↓
LLM
↓
Tool
↓
Observation
↓
Agent
↓
Final Answer
و در نتیجه ممکن است چند hallucination پشت سر هم رخ دهد.
مثلاً:
Bad Query
↓
Wrong Retrieval
↓
Wrong Interpretation
↓
Wrong Tool
↓
Wrong Tool Arguments
↓
Wrong Observation
↓
Confident Wrong Answer
این دقیقاً دلیل اهمیت evaluation و hallucination mitigation در Agentic RAG است.
@code_crafters
Forwarded from نِگاشت (Mohamad)
دوستان عزیزم سلام 👋
مقالهی جدید منتشر شد؛ این بار دربارهی Cloudflare Workers.
این هفته روی تسکی کار میکردم که برای انجامش لازم شد زمان زیادی را صرف مطالعه و تست Workers، routing، migration و ساختار Cloudflare کنم.
در ابتدا هدف فقط حل همان مسئله بود، اما هرچه بیشتر جلو رفتم، متوجه شدم Workers خیلی فراتر از چیزی است که قبلاً از آن استفاده میکردم؛ مخصوصاً زمانی که بخواهیم بخشی از یک سیستم قدیمی را بهصورت تدریجی به معماری جدید منتقل کنیم، بدون اینکه همهچیز را یکباره جابهجا کنیم.
چند موضوع اصلی مقاله:
• تفاوت Routes و Custom Domains
• اینکه چطور میشود migration را route به route انجام داد
• کلیت Bindings و Service Bindings کجا کاربرد دارند
• چه زمانهایی Workers انتخاب مناسبی است و چه زمانهایی نه
• و اینکه edge بودن همیشه به معنی performance بهتر نیست
بخشی که برای خودم جالبتر بود، مدل migration بود.
لازم نیست همیشه کل سیستم را در یک مرحله جایگزین کنیم و ریسک یک deployment بزرگ را بپذیریم. میشود چند route را به سیستم جدید منتقل کرد، رفتارشان را بررسی کرد و بعد بهتدریج باقی مسیرها را جابهجا کرد.
در مجموع، نگاه من به Cloudflare Workers از یک ابزار ساده برای redirect و rewrite، به یک لایهی جدیتر در معماری تغییر کرد.
خوشحال میشوم بخوانید و اگر تجربهای با Workers، routing یا migration داشتهاید، نظرتان را با من به اشتراک بگذارید 🙌
نکته: متن مقاله از نظر نگارشی با کمک AI بهبود داده شده، اما محتوای فنی بر اساس مطالعه، تست و مستندات Cloudflare تهیه شده.
🔗 مقاله:
https://medium.com/@el_mohamad/stop-treating-cloudflare-workers-as-cdn-scripts-the-network-is-now-programmable-fe52fd14ed22
✍️ @tech_negaasht
مقالهی جدید منتشر شد؛ این بار دربارهی Cloudflare Workers.
این هفته روی تسکی کار میکردم که برای انجامش لازم شد زمان زیادی را صرف مطالعه و تست Workers، routing، migration و ساختار Cloudflare کنم.
در ابتدا هدف فقط حل همان مسئله بود، اما هرچه بیشتر جلو رفتم، متوجه شدم Workers خیلی فراتر از چیزی است که قبلاً از آن استفاده میکردم؛ مخصوصاً زمانی که بخواهیم بخشی از یک سیستم قدیمی را بهصورت تدریجی به معماری جدید منتقل کنیم، بدون اینکه همهچیز را یکباره جابهجا کنیم.
چند موضوع اصلی مقاله:
• تفاوت Routes و Custom Domains
• اینکه چطور میشود migration را route به route انجام داد
• کلیت Bindings و Service Bindings کجا کاربرد دارند
• چه زمانهایی Workers انتخاب مناسبی است و چه زمانهایی نه
• و اینکه edge بودن همیشه به معنی performance بهتر نیست
بخشی که برای خودم جالبتر بود، مدل migration بود.
لازم نیست همیشه کل سیستم را در یک مرحله جایگزین کنیم و ریسک یک deployment بزرگ را بپذیریم. میشود چند route را به سیستم جدید منتقل کرد، رفتارشان را بررسی کرد و بعد بهتدریج باقی مسیرها را جابهجا کرد.
در مجموع، نگاه من به Cloudflare Workers از یک ابزار ساده برای redirect و rewrite، به یک لایهی جدیتر در معماری تغییر کرد.
خوشحال میشوم بخوانید و اگر تجربهای با Workers، routing یا migration داشتهاید، نظرتان را با من به اشتراک بگذارید 🙌
نکته: متن مقاله از نظر نگارشی با کمک AI بهبود داده شده، اما محتوای فنی بر اساس مطالعه، تست و مستندات Cloudflare تهیه شده.
🔗 مقاله:
https://medium.com/@el_mohamad/stop-treating-cloudflare-workers-as-cdn-scripts-the-network-is-now-programmable-fe52fd14ed22
✍️ @tech_negaasht
❤1🔥1