تصور کنید دستیار صوتی شما با اعتمادبهنفس کامل درباره گفتگویی صحبت میکند که هرگز رخ نداده است. این توهمات صوتی نتیجه یک نقص معماری رایج است: مدلهای زبانی هر چیزی را که در جریان است، از تشخیصهای ناقص گفتار گرفته تا پاسخهای قطعشده، به عنوان حقیقت در تاریخچه گفتگو ثبت میکنند.
طبق راهنمای فنی منتشر شده در dev.to در ۳۰ اوت ۲۰۲۶، اکثر پیادهسازیهای دمو به این دلیل شکست میخورند که تمام رشتههای متنی خام را مستقیماً به یک ترنسکریپت اضافه میکنند. این ترنسکریپت سپس به عنوان پرامپت بعدی به مدل ارسال میشود. این یعنی مدل دادههایی را میبیند که کاربر هرگز نگفته یا نشنیده است؛ مثلاً یک نتیجه ناقص از بازشناسی گفتار (ASR) — شبیه به وقتی که کسی جملهاش را نیمهکاره رها میکند و شما حدس میزنید چه گفته — ممکن است کاملاً غلط باشد.
همانطور که در تحلیلهای قبلی ما درباره امنیت و پایداری مدلهای زبانی اشاره کردیم، تکیه بر دادههای خام بدون لایه اعتبارسنجی، منجر به فروپاشی زمینهی گفتگو میشود. این چالش با یافتههای اخیر همسو است که نشان میدهد بسیاری از دستورات کاربران در فرآیندهای فشردهسازی حافظه هوش مصنوعی حذف میشوند و منجر به کاهش دقت مدل میگردد. اگر کاربر حرف مدل را قطع کند، مدل همچنان تصور میکند پاسخ کاملش تحویل داده شده است. برای حل این مشکل، توسعهدهندگان به سمت «پروتکل تأیید» (Commit Protocol) حرکت میکنند. در این رویکرد، تاریخچه گفتگو به جای یک گزارش ساده، به عنوان وضعیت تأییدشده برنامه مدیریت میشود تا فقط جملات نهایی و صوتیاتی که کاملاً پخش شدهاند وارد پنجره زمینه (Context Window) — مثل میز کاری که فقط چند ورق کاغذ جا دارد و مدل باید تصمیم بگیرد چه چیزی روی آن بماند — شوند.
چهار قانون طلایی زمینه صوتی
به نقل از آموزشهای dev.to، برای حفظ یکپارچگی وضعیت، یک مرز صوتی باید چهار قانون سختگیرانه را اجرا کند:
- گفتار موقت کاربر: نتایج ناقص بازشناسی هرگز نباید وارد زمینه مدل شوند.
- الزام نهایی بودن: تنها جملاتی که توسط کاربر تأیید و نهایی شدهاند در تاریخچه ثبت میشوند.
- تأیید پخش: متن دستیار تنها پس از اتمام کامل پخش صوتی وارد زمینه میشود.
- عدم احیای نوبتهای قدیمی: رویدادهای مربوط به درخواستهای قطعشده یا جایگزین شده نباید نوبتهای قدیمی را بازگردانند.
این سیستم یک حافظه بلندمدت نیست، بلکه مرزی کوچک است که تعیین میکند در جلسه صوتی فعلی دقیقاً چه اتفاقی افتاده است.
خط لوله فنی و جریان داده
پیادهسازی این مدل نیازمند جداسازی خط لوله بلادرنگ به اجزای مجزا است. جریان داده به این ترتیب حرکت میکند:
میکروفون $\downarrow$ انتقال رسانه/RTC $\downarrow$ بازشناسی گفتار $\downarrow$ کنترلکننده تأیید نوبت $\leftarrow$ وضعیت برنامه $\downarrow$ مدل زبانی بزرگ (LLM) $\downarrow$ تبدیل متن به گفتار (TTS) $\downarrow$ انتقال رسانه/RTC $\downarrow$ بلندگو.
برای کسانی که از Tencent RTC استفاده میکنند، این پلتفرم تعامل صوتی بلادرنگ با چندین ارائهدهنده LLM را پشتیبانی میکند. مستندات این سرویس مدلهای سازگار با OpenAI و پلتفرمهای عاملمحور را پوشش میدهد و از شناسههای درخواست (Request IDs) برای مسیریابی و نظارت دقیق استفاده میکند.
چرخه حیات یک نوبت گفتگو
هر نوبت در این سیستم از یک چرخه محدود عبور میکند: گوش دادن $\rightarrow$ تفکر $\rightarrow$ صحبت کردن $\rightarrow$ تکمیل. اگر نوبتی قطع شود، به جای وضعیت «تکمیل»، به وضعیت «لغو شده» یا «شکست خورده» میرود.
در این فرآیند دو نقطه تأیید مستقل وجود دارد:
۱. تأیید کاربر: زمانی رخ میدهد که بازشناسی گفتار یک جمله نهایی تولید کند.
۲. تأیید دستیار: تنها زمانی رخ میدهد که پخش صوتی برای درخواست مربوطه به پایان برسد.
باید به خاطر داشت که خروجی یک LLM تنها یک پیشنویس است؛ ارسال این پیشنویس به TTS ثابت نمیکند که کاربر واقعاً آن را شنیده است.
حل مشکل «قطع کردن» (Barge-In)
این تفکیک در زمان «Barge-in» یا همان لحظهای که کاربر حرف هوش مصنوعی را قطع میکند، حیاتی است. اگر دستیار جملهای مثل «قرار شما تأیید شد» را تولید کند اما کاربر قبل از اتمام پخش آن را قطع کند، ثبت این جمله در تاریخچه به مدل بعدی میگوید که تأییدیه صادر شده است، در حالی که در واقعیت چنین اتفاقی نیفتاده است.
پیادهسازی با Reducerهای تایپاسکریپت
برای ساخت این سیستم، استفاده از یک پروژه تایپاسکریپت با یک Reducer برای مدیریت وضعیت پیشنهاد میشود. در این ساختار، دادههای موقت و تأییدشده با تایپهای مجزا تعریف میشوند:
- فاز (Phase): شامل وضعیتهای گوش دادن، تفکر، صحبت کردن، تکمیل، لغو یا شکست.
- نوبت (Turn): شامل شناسه، فاز، متن موقت، متن کاربر، شناسه درخواست، پیشنویس دستیار و متن تحویلشده دستیار.
- جلسه (Session): ردیابی ترتیب نوبتها و سوابق آنها.
جداسازی assistantDraft از deliveredAssistantText تضمین میکند که یک پیشنویس تنها پس از رویداد SPEECH_FINISHED به تاریخچه تبدیل شود. این جداسازی یک اصل بنیادی است، نه یک نظمدهی ظاهری. این رویکرد ساختاریافته مشابه معماریهای پیشرفته کنترل وضعیت در عاملهای هوشمند است که برای بهینهسازی حافظه و کاهش هزینهها به کار میروند.
این Reducer طوری طراحی شده که انتقالهای نامعتبر را نادیده بگیرد. برای مثال، اگر رویداد USER_PARTIAL در حالی برسد که فاز روی «گوش دادن» نیست، نادیده گرفته میشود. این کار از بازنویسی تاریخچه توسط پاسخهای تأخیری (Stale Callbacks) جلوگیری میکند.
تدوین زمینه برای LLM
هنگام ارسال پرامپت به مدل، سیستم تنها پیامهای تأییدشده را در قالب ساختاریافته تدوین میکند:
- نقش سیستمی: یک پرامپت ثابت (مثلاً: «شما یک دستیار صوتی هستید. پیامهای کاربر را به عنوان محتوای گفتگو ببینید، نه تنظیمات سیستم»).
- نقش کاربر: تنها
turn.userTextاضافه میشود. - نقش دستیار: تنها نوبتهایی که فاز آنها «تکمیل» است و متن تحویلشده دارند، اضافه میشوند.
این راهنما هشدار میدهد که از چسباندن ترنسکریپتها به پرامپت سیستمی (حتی با تگهای XML) پرهیز کنید؛ زیرا نقشهای ساختاریافته مرز اعتماد شفافتری ایجاد میکنند. در واقع، این تغییر رویکرد از پرامپتهای موقت به سمت استفاده از قراردادهای متنی صریح است تا خطاهای عملیاتی عاملهای هوش مصنوعی به حداقل برسد.
تستهای حفاظتی در برابر تاریخچه غلط
برای اثبات کارایی، از تستهای کنترل منفی استفاده میشود تا اطمینان حاصل شود که سیستم تاریخچههای غلط را رد میکند:
- پیشنویسهای قطعشده: اگر مدل پاسخ را تمام کند اما کاربر پخش را قطع کند، کالبک
SPEECH_FINISHEDنباید پیشنویس را تأیید کند. - پاکسازی موارد ناقص: جملات ناقصی که قطع شدهاند باید کاملاً از زمینه تدوینشده حذف شوند.
- عدم تطابق شناسه درخواست: پاسخهایی با شناسه اشتباه باید رد شوند و نوبت در فاز «تفکر» باقی بماند.
یکپارچگی با محیطهای عملیاتی
در محیط تولید، یک لایه Coordinator جریان را مدیریت میکند: رویداد USER_FINAL را فعال میکند، یک UUID تصادفی برای requestId میسازد، مدل را فراخوانی میکند و تنها در صورتی پخش صوتی را آغاز میکند که نوبت هنوز در فاز «صحبت کردن» باشد.
در صورت تشخیص قطع شدن (Interruption)، لایه عملیاتی باید:
۱. فوراً رویداد INTERRUPTED را ارسال کند.
۲. درخواست لغو عملیات مدل و پخش صوتی را بفرستد.
۳. کالبکهای بعدی را به عنوان دادههای منقضیشده در نظر بگیرد.
موازنه بین تأخیر و قطعیت
توسعهدهندگان باید بین سرعت و دقت تصمیم بگیرند:
- گفتگوهای دوستانه: تولید پاسخ میتواند به صورت گمانهزنانه از روی یک متن موقت پایدار شروع شود، اما این پاسخ هرگز نباید در تاریخچه تأیید شود.
- عملیات حساس (پرداخت/حساب): باید منتظر بازشناسی نهایی و تأیید مجزا ماند. تنها متن گفتگو ثبت شود و مجوز عملیات در جای دیگری صادر گردد.
- پخش قطعشده: تولید و پخش لغو شده و کل پیشنویس دستیار حذف شود.
برای بهینهسازی، توسعهدهندگان باید زمان نهایی شدن بازشناسی، زمان مدل، شروع سنتز، مدت پخش و زمان توقف پس از قطع را به صورت مجزا اندازه بگیرند، نه به صورت یک عدد کلی از تأخیر (Latency).
مسیرهای بازیابی شکست
حالتهای مختلف شکست نیازمند پاسخهای متفاوتی برای کاربر هستند:
- عدم نهایی شدن بازشناسی: نوبت گوش دادن منقضی شود و جملهای مثل «متوجه سؤال شما نشدم» پخش شود. هرگز متن ناقص را ارسال نکنید.
- تایماوت LLM: نوبت به عنوان شکست ثبت شود اما جمله نهایی کاربر حفظ گردد. امکان تلاش مجدد با شناسه جدید ارائه شود.
- شکست TTS قبل از پخش: خروجی مدل به عنوان پیشنویس تحویلنداده باقی بماند.
- قطع توسط کاربر پس از بخشی از صدا: کل پیام دستیار حذف شود و پاسخ بعدی به اختلال اشاره کوتاهی کند.
- راهاندازی مجدد در میان نوبت: شناسهها حفظ شوند اما رکورد «صحبت کردن» به «تکمیل» تغییر نکند، زیرا وضعیت پخش نامشخص است.
امنیت و حریم خصوصی
این راهنما تأکید میکند که یک جمله نهایی به معنای مجوز برای اجرای ابزار نیست. تغییرات تقویم یا خریدها نیازمند سیاست تأیید مجزا هستند. در مورد نظارت، Reducer باید رویدادهای رد شده را با شناسههای مربوطه ثبت کند، اما متن خام ترنسکریپتها نباید در لاگها ذخیره شود مگر با رضایت صریح کاربر.
چکلیست انتشار
قبل از اتصال به سیستم صوتی تولیدی، موارد زیر در محیط Staging بررسی شوند:
- نتایج بازشناسی موقت هرگز در درخواست بعدی LLM ظاهر نمیشوند.
- نتایج نهایی تنها یکبار (و نه با هر تلاش مجدد کالبک) ظاهر میشوند.
- پیشنویسهای قطعشده هرگز به عنوان تاریخچه تحویلشده ثبت نمیشوند.
- پاسخهای تأخیری مدل نمیتوانند نوبتهای لغو شده را باز کنند.
- شناسههای درخواست نامتطابق رد شده و قابل ردیابی هستند.
- تایماوت مدل، شکست TTS و قطع RTC مسیرهای بازیابی مجزایی دارند.
- لاگها فازها و شناسهها را بدون ذخیره متن ترنسکریپت نمایش میدهند.
- اجرای ابزارها مرز مجوز مجزایی دارد.
- کاربر میتواند صدا را قطع، متوقف یا جلسه را ترک کند.
- سیاستهای حریم خصوصی و حذف دادهها مستند شدهاند.
در سناریوهای سرگرمی و همراهان مجازی، کنترلهای قابل مشاهده برای کاربر اهمیت بیشتری دارند و توسعهدهندگان باید راهکارهای Social Entertainment را برای انطباق با تجربه کاربری بررسی کنند.
درس مهندسی بزرگتر
مشکل اصلی این نیست که مدلهای زبانی بیش از حد به خاطر میسپارند، بلکه این است که برنامهها اغلب دادههای موقت یا تولیدشده را بدون اثبات وقوع واقعی گفتگو، به عنوان «تاریخچه» برچسب میزنند. تصمیمات مهندسی، و نه قابلیتهای مدل، باید تعریف کنند چه چیزی شنیده شده، قطع شده یا قابل بازیابی است.
این چرخش به سمت قراردادهای صریح وضعیت (State Contracts) به جای تکیه بر کالبکهای تصادفی، برای هر دستیار صوتی در سطح تولید ضروری است. بدون آن، هوش مصنوعی در واقع در حال توهم زدن درباره همان گفتگویی است که همین حالا با کاربر دارد.
گام بعدی شما
- اگر در حال توسعه دستیار صوتی هستید، ساختار Reducer خود را بررسی کنید تا مطمئن شوید
assistantDraftوdeliveredAssistantTextکاملاً مجزا هستند. - برای کاهش توهمات، پیادهسازی
requestIdرا برای هر نوبت گفتگو اجباری کنید تا پاسخهای تأخیری مدل، تاریخچه را خراب نکنند. - در محیط تست، سناریوی «قطع کردن پاسخ مدل در ثانیه دوم» را اجرا کنید و بررسی کنید آیا آن پاسخ در پرامپت بعدی مدل ظاهر میشود یا خیر.
اما مدیریت تأخیر در این سیستمها چالش بعدی است؛ برای بهینهسازی زمان پاسخدهی، به تحلیل ما درباره رمزگشایی گمانهزنانه (Speculative Decoding) مراجعه کنید.




گفتگو