چرا زمینه مشترک مدام از نو اختراع میشود
بیشتر سیستمهای چندعاملی که نیاز به اشتراکگذاری زمینه دارند با یک vector store شروع میکنند. این کممقاومتترین مسیر است: آنچه هر عامل میداند را embed کن، بر اساس شباهت retrieve کن، و بقیه را به مدل واگذار کن. این روش تا زمانی کار میکند که دو عامل نیاز داشته باشند بر اساس یک واقعیت یکسان عمل کنند.
یک vector store در واقع recall را به اشتراک میگذارد، نه state را. Retrieval فهرستی رتبهبندیشده از chunkهایی برمیگرداند که به یک query مرتبط به نظر میرسند؛ اما مجموعهای از گزارههایی که سیستم به آنها متعهد شده را برنمیگرداند. دو عامل میتوانند زمینههای همپوشان را retrieve کنند و همچنان باورهای ناسازگار را بهطور نامحدود حفظ کنند، چون هیچ چیز در store نماینده تناقض نیست. یک عامل ادعا میکند که هدف deployment محیط staging است؛ دیگری ادعا میکند production است. هر دو ادعا در index باقی میمانند. هیچکدام بهعنوان منسوخ علامتگذاری نشدهاند. retrieval بعدی ممکن است هر یک، یا هر دو را، بسته به فاصله embedding و مرزهای chunk نمایان کند.
حالت شکست این نیست که retrieval نادقیق است. این است که retrieval هیچ تصوری از توافق ندارد. هیچ شیئی در store وجود ندارد که بگوید این چیزی است که سیستم در حال حاضر آن را درست میداند، و هیچ عملیاتی وجود ندارد که بگوید این ادعای جدید با آن یکی تعارض دارد.
گرافها دقیقاً همین شکاف را پر میکنند. یک knowledge graph روابط را صریح میکند: nodeها برای موجودیتها، edgeها برای ادعاها، و یک schema که محدود میکند کدام روابط معنادار هستند. یک edge یک گزاره است که میتواند مالک داشته باشد، نسخهبندی شود، نقض شود و بازنشسته شود. این همان چیزی است که یک سیستم چندعاملی برای استدلال درباره توافق، نه صرفاً retrieve کردن متن مشابه، نیاز دارد.
این پیشنهاد درست است. اما پرسشهای عملیاتی حل نشدهاند، و همانها هستند که تعیین میکنند یک گراف مشترک مفید است یا یک بدهی. پوشش اخیر حافظه عامل مبتنی بر گراف معمولاً بر لایه ذخیرهسازی تمرکز دارد — کدام database، کدام embedding model، کدام traversal. پرسشهای سختتر درباره اقتدار و تعارض هستند: کدام عامل مجاز به نوشتن کدام edge است، و وقتی دو عامل edgeهایی مینویسند که نمیتوانند همزمان درست باشند چه اتفاقی میافتد.
اقتدار نوشتن: هر edge به یک مالک نیاز دارد
یک نوشتن بدون انتساب همان چیزی است که یک گراف مشترک را به یک کارگاه شایعهپراکنی تبدیل میکند. اگر هر عاملی بتواند هر edge را ادعا کند، گراف ادعاهایی بدون منشأ جمع میکند، و عاملهای پاییندستی هیچ مبنایی برای تصمیمگیری درباره اینکه به کدام اعتماد کنند ندارند. این شکست بیصدا است: گراف از نظر نحوی معتبر میماند در حالی که از نظر معنایی غیرقابل اعتماد میشود.
راهحل این است که اقتدار نوشتن را صریح کنیم. هر نوع edge در schema باید یک policy داشته باشد که بیان کند کدام عامل، تحت کدام task، مجاز به ادعای آن است. یک قطعه schema میتواند اینگونه باشد:

edge_types:
- name: service_owns_database
subject: service
object: database
writers:
- agent: inventory-agent
task: reconcile-service-topology
cardinality: many-to-many
conflict_policy: quarantine
- name: deployment_target
subject: service
object: environment
writers:
- agent: release-agent
task: promote-release
cardinality: one-to-one
conflict_policy: last-write-wins-with-timestamp
انتخاب طراحی مهم این است که اقتدار در schema زندگی میکند، نه در prompt یک عامل. قواعد سطح prompt جنبه توصیهای دارند. مدلی که از آن خواسته شده فقط edgeهایی را بنویسد که به آنها اطمینان دارد، همچنان وقتی زمینه نشان دهد باید، یک edge مینویسد، و هیچ مکانیزمی برای رد کردن آن نوشتن وجود ندارد. policy سطح schema توسط مسیر نوشتن اعمال میشود: ادعایی که با یک نویسنده اعلامشده برای آن نوع edge مطابقت ندارد، پیش از رسیدن به گراف رد میشود.
این نیازمند یک اقتدار مرکزی برای هر نوشتن نیست. نیازمند این است که اقتدار اعلام و قابل بررسی باشد. میتوان به یک عامل دامنه نوشتن گستردهای برای یک task اعطا کرد، اما این اعطا یک رکورد است، نه یک دستور در system prompt.
حل تعارض: edgeهای متناقض عادی هستند
دو عامل که edgeهای متناقض ادعا میکنند یک رویداد عادی است، نه یک خطا. عاملها بر اساس دیدهای جزئی، در زمانهای مختلف، با شواهد متفاوت عمل میکنند. گرافی که تناقض را بهعنوان استثنا در نظر بگیرد یا متوقف میشود یا بیصدا بازنویسی میکند، و هر دو اشتباه هستند.
تقدم باید از پیش، بهازای هر نوع edge، تعیین شود. سه گزینه عملی:
- آخرین نوشتن برنده با timestamp. ساده و قابل پیشبینی، اما تازگی را بر شواهد ترجیح میدهد. عاملی که یک باور کهنه را دیرتر از یک عامل بهتر مطلع مینویسد، بهطور تصادفی برنده میشود.
- ادغام وزندار بر اساس اطمینان. هر ادعا یک confidence و یک منبع حمل میکند. قاعده ادغام آنها را ترکیب میکند. این بیانگرتر است، اما نیازمند این است که confidence کالیبره شده باشد، و یک امتیاز confidence کالیبرهنشده فقط عددی است که ادغام را اصولی جلوه میدهد.
- قرنطینه تا زمانی که یک resolver اجرا شود. edgeهای متعارض از گراف قابل خواندن کنار گذاشته میشوند و یک مرحله حلوفصل — یک عامل اختصاصی، بازبینی انسانی، یا یک قاعده قطعی — تصمیم میگیرد کدام باقی میماند.
برای واقعیتهایی که سایر عاملها بر اساس آنها عمل خواهند کرد، قرنطینه معمولاً درست است. هزینه آن latency است: گراف بهطور موقت برای آن edge ناقص است، و هر عاملی که به آن واقعیت نیاز دارد باید منتظر بماند یا با یک unknown صریح پیش برود. این یک trade-off واقعی است. آخرین نوشتن برنده گراف را بهطور پیوسته قابل خواندن نگه میدارد به قیمت گاهی انتشار یک باور غلط. قرنطینه گراف را قابل اعتماد نگه میدارد به قیمت دسترسپذیری. انتخاب باید از پیامد عمل کردن بر یک edge
a/server-rack-closeup-5ed2bb-8c3175.jpg)
قرنطینه همچنین به یک شرط خروج نیاز دارد. تعارضی که هرگز حل نشود یک حفره دائمی است. resolver باید یک مرحله تعریفشده با یک محرک تعریفشده باشد — یک reconciliation زمانبندیشده، یک آستانه بر تعداد خواندنهای پاییندستی مسدودشده، یا یک escalation وقتی تعارض در سراسر یک مرز اجرا ادامه مییابد.
سازگاری خواندن برای مراحل پاییندستی
عاملی که گراف را در میانه اجرا میخواند به یک snapshot نیاز دارد، نه یک نمای زنده. اگر گراف بین دو خواندن در همان مسیر عامل تغییر کند، مسیر قابل بازتولید نیست: تصمیمهای عامل به حالتی وابستهاند که دیگر وجود ندارد و قابل بازسازی نیست.
مکانیزم، نسخهبندی گراف است. هر نوشتن یک شمارنده نسخه را جلو میبرد، و یک خواندن در برابر یک نسخه مشخص ارائه میشود. اجرا نسخهای که از آن خوانده را در مسیر خود ثبت میکند، در کنار tool callها و خروجیهای مدل. بازپخش اجرا در برابر همان نسخه، همان ورودیها را میدهد، که حداقل نیاز برای اشکالزدایی یک شکست چندعاملی است.
این با قرنطینه تعامل دارد. یک edge قرنطینهشده در snapshot غایب است، بنابراین عاملی که آن نسخه را میخواند واقعیت را بهعنوان unknown میبیند نه بهعنوان مورد مناقشه. اینکه این قابل قبول است یا نه بستگی دارد به اینکه آیا عامل میتواند با یک unknown پیش برود. اگر نتواند، اجرا باید بر حلوفصل مسدود شود نه اینکه نسخهای را بخواند که واقعیتی را که نیاز دارد حذف کرده است.
نسخهبندی همچنین نگهداری را قابل مدیریت میکند. edgeهای کهنه یک پرسش policy نگهداری با همان شکل نگهداری حافظه هستند: یک edge چه مدت قابل خواندن میماند، و چه چیزی بازنشستگی آن را محرک میشود؟ edgeای که منسوخ شده بلافاصله حذف نمیشود — ممکن است برای توضیح یک اجرای گذشته لازم باشد. قاعده عملی این است که edgeها را از نسخه قابل خواندن فعلی بازنشسته کنیم در حالی که آنها را برای audit بر اساس نسخه قابل آدرسدهی نگه داریم. garbage collection سپس بر نسخهها عمل میکند، نه بر edgeهای فردی، که مسیر audit را منسجم نگه میدارد.
این چه معنایی برای طراحی دارد
یک knowledge graph مشترک برای یک سیستم چندعاملی یک انتخاب ذخیرهسازی نیست. مجموعهای از policyها درباره اقتدار، تعارض و سازگاری است که تصادفاً در یک گراف بیان شدهاند. لایه ذخیرهسازی بخش آسان است.
کار طراحی در schema است: کدام نوع edgeها وجود دارند، چه کسی مجاز به نوشتن آنهاست، وقتی دو نویسنده اختلاف دارند چه اتفاقی میافتد، و یک خواننده کدام نسخه را میبیند. این تصمیمها تعیین میکنند که گراف یک حالت مشترک است که عاملها میتوانند درباره آن استدلال کنند یا یک کارگاه شایعهپراکنی مشترک که عاملها از آن retrieve میکنند.
trade-off صادقانه این است که یک گراف تحت حاکمیت policy برای نوشتن کندتر و برای خواندن کندتر از یک vector store است. نوشتنها در برابر اقتدار بررسی میشوند، تعارضها ممکن است قرنطینه شوند، و خواندنها به نسخهها پین میشوند. این سرباز buys قابلیت بازتولید و یک تصور قابل دفاع از توافق. برای سیستمهایی که عاملها بر اساس واقعیتهای مشترک عمل میکنند، معمولاً trade درست است. برای سیستمهایی که عاملها فقط نیاز به recall کردن متن مشابه دارند، غیرضروری است.
