تصور کنید برنامهنویسی هستید که میخواهد یک سیستم توصیهی فیلم بسازد که برخلاف مدلهای معمولی، هرگز فیلمی را اختراع نکند و فقط بر اساس دادههای واقعی پاسخ دهد. اکنون با ترکیب Microsoft Agent Framework و جستوجوی برداری MongoDB Atlas، ساخت چنین عاملی در محیط عملیاتی ممکن شده است. این ادغام به مدلهای زبانی بزرگ (LLM) — مثل کتابخانهداری که میلیاردها صفحه را خوانده و حالا با همان لحن کتابها جواب میدهد — اجازه میدهد تا از دادههای عمومی آموزشدیده فراتر رفته و پاسخهای خود را بر اساس مجموعهدادههای خصوصی و دقیق مبنیسازی (Grounding) کنند.
همانطور که در تحلیل قبلی ما دربارهی حضور بومی عاملهای هوش مصنوعی در برنامههای Microsoft 365 اشاره کردیم، تمرکز مایکروسافت اکنون به سمت ابزارهای توسعهدهنده تغییر کرده است. برای اکثر برنامهنویسان، چالش اصلی خودِ مدل نیست، بلکه «لولهکشی» دادههاست؛ یعنی مدل چگونه در زمان درست، دادهی درست را بدون توهم (Hallucination) — شبیه دوستی که خاطرهای را اشتباه تعریف میکند — بازیابی کند.
طبق اعلام مایکروسافت، این نسخه از چارچوب عاملها در اکتبر ۲۰۲۵ معرفی شد و در ۱۷ آوریل ۲۰۲۶ به دسترسی عمومی (General Availability) رسید. هدف این بهروزرسانی، یکپارچهسازی دو مسیر مجزا یعنی Semantic Kernel و AutoGen است. اگرچه رابطهای کاربری برای کاربران Semantic Kernel آشنا باقی مانده، اما پیادهسازی تولید بازیابیافزا (RAG) — مثل دانشآموزی که قبل از جواب دادن، اول کتاب درسی را باز میکند و از آن نقل میآورد — بهطور کلی بازنگری شده است.
پشته فنی (Technical Stack)
برای پیادهسازی یک عامل توصیهگر، معماری به چهار جزء اصلی نیاز دارد:
- MongoDB Atlas: پایگاهدادهای که مجموعهی
embedded_moviesرا از مجموعهدادهیsample_mflixدر خود جای داده است. این مجموعه شامل بردارهای معنایی (Embedding) — مثل کارت معرفی عددی برای هر واژه که میگوید این کلمه همسایهی چه کلمات دیگری است — برای بخشی از فیلمهاست. برای کسانی که از صفر شروع میکنند، مونگو دستورالعملهای ایجاد یک خوشه رایگان MongoDB Atlas M0 را فراهم کرده است. - شاخص جستوجوی برداری (Vector Search Index): یک شاخص پیشفرض (default) که با شباهت کسینوسی (Cosine Similarity) و ۱۵۳۶ بُعد پیکربندی شده است. این ابعاد به دلیل استفاده از مدل
text-embedding-ada-002برای تولید بردارها ضروری هستند. این شاخص را میتوان از طریق رابط کاربری MongoDB Atlas یا بهطور خودکار توسط کد نمونه ایجاد کرد، هرچند ایجاد دستی آن به زمان کوتاهی برای پردازش نیاز دارد. - مدل زبانی بزرگ: مدل gpt-4.1 میزبانیشده در Azure OpenAI که قابلیت استفاده از ابزار (Tool Use) را دارد و برای تولید پیامهای چت استفاده میشود.
- مدل بردارساز: مدل
text-embedding-ada-002که آن هم در Azure OpenAI میزبانی میشود تا اطمینان حاصل شود که بردارهای پرسوجو با ابعاد دادههای ذخیرهشده مطابقت دارند.

پیکربندی و راهاندازی
توسعهدهندگان میتوانند مخزن نمونه را از گیتهاب کلون کرده و در Visual Studio یا Visual Studio Code باز کنند. این پروژه برای مدیریت تنظیمات حساس از dotnet user-secrets استفاده میکند. تنظیمات ضروری شامل موارد زیر است:
MongoDB:ConnectionString: رشته اتصال به خوشه Atlas (مثلاً:dotnet user-secrets set MongoDB:ConnectionString "mongodb+srv://...").Endpoint: آدرس URL مربوط به Azure OpenAI (مثلاً:dotnet user-secrets set Endpoint "https://...").ChatDeployment: مقداردهی به "gpt-4.1" (مثلاً:dotnet user-secrets set ChatDeployment "gpt-4.1").
تنظیمات اختیاری شامل MongoDB:Database (که بهطور پیشفرض روی "sample_mflix" است) و EmbeddingDeployment (که روی "text-embedding-ada-002" تنظیم میشود) است.
نگاشت دادهها و POCOها
در این پیادهسازی از یک کلاس C# به نام Movie (از نوع POCO یا Plain Old CLR Object) استفاده شده است. این کلاس اسناد MongoDB را با استفاده از ویژگی BsonIgnoreExtraElements و ویژگیهای خاص BsonElement برای فیلدهایی مانند title (عنوان)، plot (خلاصه داستان)، fullplot (داستان کامل)، cast (بازیگران) و genres (ژانرها) به اشیای C# متصل میکند.
نکته کلیدی این است که ویژگی PlotEmbedding به عنوان ReadOnlyMemory<float> تعریف شده و با ویژگی [VectorStoreVector(1536)] علامتگذاری شده است. همچنین فیلد Id با ویژگی [VectorStoreKey()] مشخص شده و از BsonRepresentation(MongoDB.Bson.BsonType.ObjectId) استفاده میکند تا اطمینان حاصل شود که پیادهسازی Vector Store میتواند رکوردها را بهطور منحصربهفرد شناسایی کند.
راهاندازی کلاینتها
نخستین گام در این چارچوب، مقداردهی اولیه یک ChatClient است که از طریق تزریق وابستگی (Dependency Injection) به صورت Singleton انجام میشود. این فرآیند دو مرحلهای است: ابتدا یک AzureOpenAIClient با استفاده از DefaultAzureCredential ایجاد شده و سپس ChatClient از دل آن کلاینت با استفاده از استقرار چت مشخصشده استخراج میشود.
در محیطهای عملیاتی، توسعهدهندگان باید به جای اعتبارسنجی پیشفرض (DefaultAzureCredential)، از روشهای دقیقتری برای احراز هویت استفاده کنند. کاربر باید در Azure احراز هویت شده باشد و دسترسی صریح به مدلها در Azure OpenAI داشته باشد تا اتصال برقرار شود.
علاوه بر کلاینت چت، یک EmbeddingClient برای تبدیل پرسوجوهای متنی کاربر به بردار ثبت میشود. همچنین IMongoClient و IMongoDatabase و IMongoCollection<Movie> در کانتینر IoC ثبت میگردند. برای سهولت در نمونه کد، برنامه بهطور خودکار شاخص جستوجوی برداری "default" را در صورت عدم وجود ایجاد میکند، هرچند در محیط عملیاتی این کار باید بهصورت صریح انجام شود. کاربران خوشههای M0 مونگو باید به محدودیت سه شاخص جستوجو توجه کنند؛ اگر این حد پر شده باشد، باید یکی از شاخصها حذف شود. همچنین در صورت ایجاد خودکار شاخص، توسعهدهندگان باید مدتی منتظر بمانند تا شاخص آماده شود و سپس پرسوجوها را اجرا کنند.
پیادهسازی ذخیرهساز برداری (Vector Store)
توسعهدهندگان دو مسیر متمایز برای ادغام MongoDB در گردشکار عامل دارند. هر دو مسیر از یک سلسلهمراتب کلاسی مشترک شامل IMovieRecommendationService و MovieRecommendationServiceBase استفاده میکنند تا تاریخچه چت و منطق توصیهها را بازاستفاده کنند. این ساختار اجازه میدهد خدمات یک رویکرد کلی داشته باشند اما منطق خاص یافتن زمینه (Context) از طریق جستوجوی برداری را ایزوله کنند.
روش اول: درایور C# مونگو
در این حالت، توسعهدهنده بهصورت دستی بردار پرسوجو را از طریق EmbeddingClient تولید میکند. سپس یک خط لوله تجمیعی (Aggregation Pipeline) با متد .VectorSearch() اجرا میکند. این جستوجو با تنظیم NumberOfCandidates = 100 پیکربندی شده و نتایج نهایی را به ۱۰ فیلم برتر محدود میکند تا بستر متنی ارسالی به مدل، موجز و دقیق باشد.
روش دوم: کانکتور Vector Store مونگو
این کانکتور که ابتدا برای Semantic Kernel ساخته شده بود، منطق جستوجو را انتزاع میکند. این روش یک MongoVectorStore را مقداردهی کرده و مجموعهای از نوع <string, Movie> را از کالکشن embedded_movies بازیابی میکند. توسعهدهنده صرفاً متد .SearchAsync() را با بردار پرسوجو و محدودیت ۱۰ مورد فراخوانی میکند که مقدار زیادی از کدهای تکراری (Boilerplate) را حذف میکند.

منطق عامل و مبنیسازی
هسته اصلی عامل، ChatClient است که با گزینههای TextSearchOptions پیکربندی شده است. یک تصمیم طراحی حیاتی در اینجا، استفاده از فراخوانی تابع بر اساس تقاضا (On-Demand Function Calling) است. برخلاف RAG کلاسیک که جستوجو قبل از فراخوانی مدل رخ میدهد (BeforeAIInvoke)، در اینجا مدل تصمیم میگیرد چه زمانی به دادههای بیشتر نیاز دارد و حتی پرسوجوی جستوجو را برای رسیدن به نتیجه بهتر بهینه میکند.
برای جلوگیری از توهم، عامل توسط یک پرامپت سیستمی (System Prompt) سختگیرانه هدایت میشود. این پرامپت دستورالعملهای اصلی زیر را تحمیل میکند:
- استفاده از ابزار: عامل باید برای تایید داستان، بازیگران، ژانرها و تاریخ انتشار حتماً از ابزار
TextSearchاستفاده کند. تکیه بر دادههای آموزشی عمومی برای جزئیات خاص فیلمها ممنوع است. - ارجاعات: مدل باید لینکهای منبع را فقط با استفاده از لینکهای نسبی موجود در نتایج جستوجو (مثلاً
/movies/123) درج کند. اختراع یا لینک دادن به URLهای خارجی ممنوع است. - دقت: اگر نتیجهای یافت نشد، عامل باید صراحتاً اعلام کند که جزئیات در پایگاهداده موجود نیست، به جای اینکه پاسخ را تخیل کند.
- لحن: پاسخها باید کوتاه (حداکثر ۲ تا ۳ جمله)، پرانرژی و با استفاده از Markdown (مانند بولد کردن و لیستها) برای خوانایی بیشتر باشند.
- محدوده: عامل باید هرگونه موضوع غیرمرتبط با فیلم را بهطور مودبانه به سمت توصیههای سینمایی هدایت کند.

مکانیزم بازیابی زمینه
متد RetrieveContextAsync در TextSearchProvider نقش پل ارتباطی بین مدل و پایگاهداده را ایفا میکند. این متد ابتدا متد RetrieveMoviesAsync (که بسته به پیادهسازی متفاوت است) را فراخوانی کرده و سپس اشیای Movie حاصل را به اشیای TextSearchResult تبدیل میکند.
هر TextSearchResult شامل عنوان فیلم به عنوان SourceName و یک لینک نسبی به عنوان SourceLink (در قالب /movies/{m.Id}) است. همچنین یک رشته فرمتشده شامل عنوان، خلاصه داستان، داستان کامل، بازیگران و ژانرها را در بر میگیرد. این متن ساختاریافته است که مدل برای مبنیسازی پاسخ نهایی از آن استفاده میکند.
رابط کاربری و اجرا
رابط کاربری نهایی با Blazor ساخته شده است. کامپوننت اصلی، MovieRecommendator.razor است که پیادهسازی انتخابی (درایور در مقابل کانکتور) را به عنوان یک پارامتر مسیر (Route Parameter) دریافت میکند. این کامپوننت از GetRequiredKeyedService استفاده میکند تا بر اساس آن کلید، IMovieRecommendationService صحیح را نمونهسازی کند.
وقتی کاربر پیامی میفرستد، متد RecommendAsync فراخوانی میشود. رابط کاربری وضعیت بارگذاری (Loading) را مدیریت کرده، متد StateHasChanged() را برای بهروزرسانی صفحه اجرا میکند و پس از پاسخ عامل، روی فیلد ورودی فوکوس میکند تا تجربهای روان از چت فراهم شود.
این چرخش به سمت یک چارچوب یکپارچه به این معناست که توسعهدهندگان .NET دیگر مجبور نیستند بین ارکستراسیون AutoGen و قابلیتهای یکپارچهسازی Semantic Kernel یکی را انتخاب کنند. مایکروسافت با تبدیل ذخیرهساز برداری به ابزاری که عامل میتواند بر حسب نیاز فراخوانی کند، به سمت فرمی پویا از RAG حرکت میکند.
برای توسعهدهنده، این یعنی کاهش بدهی فنی (Technical Debt). به جای ساخت خط لولههای پیچیده پیشپردازش برای تغذیه پرامپت، آنها فقط یک منبع داده تعریف میکنند و مدیریت بازیابی را به عهده عامل میگذارند. این رویکرد ریسک سرریز شدن پنجره متنی (Context Window) — شبیه میز کاری که جا برای چند ورق دارد، نه برای کل کتابخانه — را کاهش داده و دقت ارجاعات را بالا میبرد.
گام بعدی شما
- اگر از اکوسیستم .NET استفاده میکنید، مخزن نمونه مایکروسافت را برای مقایسه عملکرد درایور مستقیم در برابر کانکتور Vector Store بررسی کنید.
- برای کاهش نرخ توهم در عاملهای خود، استراتژی On-Demand Function Calling را جایگزین RAG سنتی کنید.
- محدودیتهای شاخصهای جستوجوی برداری در خوشههای رایگان (M0) مونگو را در طراحی معماری خود لحاظ کنید.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو