سود:
- می تواند توضیح دهد که جریان چیست، انواع رویدادها و چرا به آن نیاز است.
- max_tokens زمانبندی و رابطه خروجی طولانی 128K را درک میکند
- با توجه به حجم کاری می تواند بین درخواست های پخش جریانی و غیر استریم انتخاب مناسبی داشته باشد
شاید متوجه شده باشید که در رابط چت، پاسخ کلمه به کلمه "تایپ" می شود. این یک شکوفایی بصری نیست. این نتیجه تکنیکی به نام استریم است و اغلب برای ادغام LLM با کیفیت تولید اجباری است. در این واحد، شما یاد خواهید گرفت که جریان چیست، از چه رویدادهایی تشکیل شده است، ارتباط آن با خروجی طولانی و زمانبندی، و زمان استفاده از جریان و چه زمانی استفاده نمیشود. ما موضوع را از طریق وظایف واقعی یک حرفه ای پوشش خواهیم داد - دستیار زنده، تولید گزارش طولانی، پردازش دسته ای.
Flow چیست؟
با یک درخواست غیر جریانی (همگام)، منتظر میمانید تا مدل کل پاسخ را تولید کند. وقتی پاسخ آماده شد، یک تکه می رسد. در یک درخواست استریم، سرور همانگونه که مدل تولید می کند، پاسخ را تکه تکه ارسال می کند. از نظر فنی، این کار با رویدادهای ارسال شده توسط سرور انجام می شود (SSE — رویدادهای ارسال شده از سرور، روشی که در آن سرور رویدادهای کوچک را پشت سر هم از طریق یک اتصال باز ارسال می کند).
تفاوت در تجربه کاربر آشکار می شود: در پاسخی که 8 ثانیه طول می کشد، کاربر غیر جریانی به مدت 8 ثانیه به یک صفحه خالی خیره می شود. کاربر استریم اولین کلمات را در 0.5 ثانیه می بیند و متن شروع به جریان می کند. تأخیر درک شده - انتظاری که کاربر احساس می کند - بسیار کاهش می یابد، در حالی که زمان کل بدون تغییر باقی می ماند.
انواع رویداد جریان
جریان یک توالی از رویدادها است. از نظر مفهومی، یک جریان معمولی به شرح زیر است:
حادثه
معنی
message_start
پاسخ شروع شد؛ اطلاعات هدر مانند مدل و شناسه رسیده است.
content_block_start
بلوکی از محتوا (به عنوان مثال متن) شروع شد
content_block_delta
یک قطعه کوچک از متن (دلتا) رسید. شما اینها را جمع کنید
content_block_stop
بلوک کامل شد
message_delta
اطلاعات پایانی مانند stop_reason و usage به روز شده است
message_stop
پاسخ دهید
کد شما به طور متوالی قطعات متن را در رویدادهای content_block_delta ترکیب می کند. در نهایت با همان متنی مواجه می شوید که پاسخ پخش نشده است. میزان استفاده (اعداد نشانه) معمولاً در پایان جریان مشخص است - پس از پایان جریان، هزینه ها را پیگیری می کنید.
نکته: اکثر SDK های رسمی (کیت توسعه نرم افزار - کتابخانه آماده ارائه دهنده) کمکی را ارائه می دهند که جریان را برای شما جمع آوری می کند (به عنوان مثال stream.get_final_message()). شما لازم نیست تمام آهنگ ها را به صورت دستی مدیریت کنید. اگر متن کامل را می خواهید، از این راهنما استفاده کنید، رویدادهای فردی را پردازش کنید اما برای چاپ زنده.
پاسخ های طولانی، max_tokens و Timeout
دومین و فنیتر علت پخش جریان، تایم اوت است. اگر درخواست HTTP در مدت زمان معینی تکمیل نشود، کلاینت اتصال را قطع می کند. هنگامی که یک خروجی بزرگ از مدل درخواست میکنید (مثلاً گزارشی از 40000 توکن)، تماس غیرجریان ممکن است از این حد تجاوز کند و زمان تمام شود - درخواست با شکست مواجه میشود و شما باید برای توکنهای تولید شده پرداخت کنید.
مدل های مدرن می توانند تا 128000 توکن را در یک درخواست تولید کنند. اما قانون کلی واضح است: اگر مقدار «max_tokens» زیاد است (تقریباً بالای 16000) از جریانها استفاده کنید. پخش جریانی اتصال را زنده نگه می دارد و از وقفه جلوگیری می کند. همچنین فوراً پیشرفت را مشاهده خواهید کرد.
- `max_tokens`: حداکثر توکن های خروجی که مدل می تواند تولید کند. یک سقف سخت اگر وقفه ای رخ دهد، stop_reason max_tokens برگردانده می شود.
- پنجره زمینه: پنجره ای که مجموع ورودی + خروجی باید در آن جا شود. max_tokens سقف خروجی است. این دو را با هم مخلوط نکنید.
احتیاط: پرتاب درخواست های غیر جریانی با max_tokens بزرگ یک اشتباه کلاسیک در تولید است. بدون پاسخ، اتصال قطع می شود، کاربر خطا می بیند و هزینه توکن هدر می رود. خروجی طولانی = جریان.
چه زمانی باید جریان یابد و چه زمانی نه؟
وضعیت
ترجیح
چرا
چت زنده / دستیار
جریان
تاخیر درک شده کاهش می یابد، کاربر پیشرفت را می بیند
گزارش طولانی / تولید سند
جریان
از وقفه جلوگیری می کند، خروجی زیادی را با خیال راحت حمل می کند
طبقه بندی کوتاه (به عنوان مثال برچسب تک کلمه ای)
بدون جریان
خروجی در حال حاضر کوچک است. پیچیدگی اضافی غیر ضروری
پردازش دسته ای
بدون جریان / دسته ای
نتایج فورا نشان داده نمی شوند. واحد 7 را ببینید
مرحله اتوماسیون (در پس زمینه)
معمولا جریان ندارد
شما نتیجه را به مرحله بعدی منتقل می کنید، بدون نمایش زنده
درخواست/الگوهای قابل کپی
جریان به خودی خود یک اعلان نیست، اما دستورات برای مدیریت خروجی تولید شده توسط جریان حیاتی هستند. در تولیدات طولانی و روان، تحمیل سازه از جلو هم کیفیت و هم قابلیت ردیابی را افزایش می دهد.
# گزارش طولانی را به بخش هایی تقسیم کنید (به طوری که پیشرفت در جریان قابل مشاهده باشد) گزارش را با عناوین زیر دقیقاً به این ترتیب بنویسید. هر عنوان را با "##" شروع کنید:## خلاصه## یافته ها## توصیه ها## مراحل بعدی
# طول هدف را برای جلوگیری از کوتاه شدن در تولید طولانی بدهید. کل متن تقریباً 800 کلمه خواهد بود. قسمت ها را متعادل نگه دارید؛ در آخر نیم جمله نگذارید.
# اولین جمله را بلافاصله برای دستیار استریم بیان کنید. ابتدا پاسخ مستقیم یک جمله ای بدهید، سپس وارد جزئیات شوید. بنابراین کاربر در حین انتظار یک نتیجه فوری را مشاهده می کند.
# خروجی طولانی را ساختاریافته نگه دارید (به طوری که بعداً بتوان آن را تجزیه کرد) خروجی را در این بخش ها خارج کنید و هر بخش را با یک هدر جداگانه '###' علامت گذاری کنید تا بتوانم آن را به صورت برنامه ای تجزیه کنم: ### مقدمه ### BODY ### منابع
اعلان ضعیف / اعلان قوی (تولید طولانی)
# ضعیف گزارشی طولانی و مفصل در مورد این موضوع بنویسید.
# STRONG گزارشی با حدود 900 کلمه در مورد این موضوع بنویسید. سرفصل ها: ## خلاصه، ## تجزیه و تحلیل، ## خطرات، ## توصیه ها. هر عنوان باید حداکثر 3 پاراگراف باشد. در آخر نیم جمله نگذارید.
نسخه قدرتمند؛ طول، ساختار و کیفیت پایان را از قبل تعیین می کند. همانطور که بخش ها وارد جریان می شوند، کاربر پیشرفت را به وضوح می بیند و خودش طول را در برابر خطر قطع شدن مدل مدیریت می کند.
سه کیف کوچک
مورد 1 - شکایت صفحه خالی. دستیار مشتری یک تیم مشاوره بدون جریان پاسخ می داد. میانگین پاسخ 7 ثانیه طول می کشد، کاربران می پرسند "آیا یخ می زند؟" او شکایت کرد. وقتی وارد جریان شدم، اولین کلمه در 0.6 ثانیه آمد. کل زمان ثابت باقی ماند، اما شکایات "آهسته" تقریبا ناپدید شدند.
مورد 2 - گزارش منسوخ شده. یک تیم مالی در حال تهیه یک گزارش سه ماهه 30 صفحه ای بود. با max_tokens: 30000، درخواست بدون جریان در یک بازه زمانی 60 ثانیه ای مشتری گیر می کند، درخواست با شکست مواجه می شود - و توکن های تولید شده در فاکتور نوشته می شوند. آنها با جریان رفتند. اتصال زنده باقی ماند، گزارش به طور کامل تحویل شد و هزینه های تلف شده حذف شد.
مورد 3 - جریان غیر ضروری. یک تیم عملیاتی ایمیلهای دریافتی را بهعنوان «فوری/معمولی» برچسبگذاری میکرد. خروجی یک کلمه بود، اما آنها معمولاً از جریان استفاده می کردند. جریان هیچ فایده ای در پاسخ یک کلمه ای نداشت و کد را به صورت غیر ضروری پیچیده می کرد. وقتی به flowless تغییر دادم، کد ساده شد و رفتار یکسان باقی ماند. درس: پخش جریانی در خروجی طولانی/زنده ارزشمند است، نه در همه جا.
اشتباهات رایج
- عدم استفاده از استریم ها در خروجی طولانی: مهلت زمانی و هزینه توکن تلف شده.
- استفاده از جریان در خروجی کوتاه: پیچیدگی غیر ضروری، سود صفر.
- عدم بررسی "stop_reason" در پایان جریان: پاسخ کوتاه شده با max_tokens کامل در نظر گرفته می شود.
- ادغام نادرست دلتاها: جمعبندی دستی با کمک SDK خطای توالی/قطعات گمشده را ایجاد میکند.
- تلاش برای خواندن «استفاده» در اواسط جریان: اعداد رمز معمولاً در پایان مشخص میشوند. هزینه ها را در پایان پیگیری کنید.
- اشتباه گرفتن جریان برای کاهش هزینه: استریم تجربه و استقامت را بهبود می بخشد. قیمت توکن را تغییر نمی دهد.
عمیق تر: شکاف های جریان و انعطاف پذیری
جریان یک اتصال زنده است. این هم نقطه قوت و هم آسیب پذیری آن است. اگر اتصال در وسط قطع شود (نوسانات شبکه، مهلت زمانی سرویس گیرنده)، متنی را که تا کنون انباشته کرده اید حفظ خواهید کرد، اما پاسخ ناقص خواهد بود. یک مشتری پخش جریانی با کیفیت تولید باید برای این کار آماده شود: نباید متن جزئی را به عنوان "پاسخ کامل" تلقی کند، و همچنین نباید تا زمانی که رویداد message_stop را ببیند، پاسخ را تمام شده در نظر بگیرد.
نکته ظریف دوم این است که جریان هزینه را تغییر نمی دهد. دریافت پاسخ با یا بدون استریم روی قیمت توکن تاثیری ندارد. جریان فقط تجربه و استقامت را بهبود می بخشد. بنابراین "اگر ما به استریم برویم، آیا آنها ارزان تر خواهند بود؟" پاسخ این سوال منفی است - برای هزینه، به واحد 5 و 6 (انتخاب مدل، حافظه پنهان) نگاه کنید.
نکته سوم ایجاد تعادل عملی است: با دستیاران زنده، رسیدن سریع اولین کلمه (تاخیر درک شده) بسیار ارزشمند است. بنابراین، درخواست از مدل برای وارد کردن مستقیم پاسخ و دادن یک نتیجه کوتاه ابتدا (از طریق اعلان سیستم در واحد چهارم)، سود جریان را چند برابر می کند. اگر کاربر در ثانیه اول چیزی معنادار ببیند، صبورانه منتظر جزئیات بعدی است. از سوی دیگر، جریان هیچ کمکی به کارهایی که در پسزمینه اجرا میشوند، ندارد و خروجی آن به مرحله اتوماسیون بعدی میرود. تنها معیاری که وجود دارد این است که کار به درستی و کامل انجام شود.
به طور خلاصه
استریم، پاسخ را تکه تکه بازیابی می کند، تأخیر درک شده را کاهش می دهد و از وقفه های زمانی در توان عملیاتی بزرگ جلوگیری می کند. تقریباً برای دستیار زنده و تولید سند طولانی اجباری است. برای کارهای کوتاه/پس زمینه غیر ضروری است. در تولیدات طولانی، تحمیل ساختار و طول از جلو با یک فوریت، هم کیفیت و هم قابلیت ردیابی را افزایش می دهد. وقتی جریان تمام شد، stop_reason و usage قطعا بررسی می شوند.
وظیفه کاربردی
دو سناریو را انتخاب کنید: یکی زنده/طولانی (مثلاً گزارش به مشتری)، یکی کوتاه/پسزمینه (مثلاً برچسبگذاری). (1) تصمیم بگیرید و توجیه کنید که آیا برای هر کدام از جریان استفاده خواهید کرد یا خیر. (2) اعلانی بنویسید که ساختار اسکریپت طولانی (عنوان + طول هدف) را تحمیل کند. (3) مقادیر max_tokens را تعیین کنید. (4) بررسی هایی را که با stop_reason و usage در پایان جریان انجام خواهید داد، فهرست کنید.
چک لیست
- [ ] می توانم توضیح دهم که جریان چیست و چگونه تأخیر درک شده را کاهش می دهد.
- [ ] من انواع رویدادهای اساسی پیوستن جریان و دلتا را درک کردم.
- [ ] من در مورد نیاز به استریم با max_tokens بزرگ و رابطه وقفه اطلاع دارم.
- [ ] من می توانم تصمیم بگیرم که در چه حجم کاری از استریم استفاده کنم و در کدام نه.
- [ ] می توانم stop_reason و استفاده را در پایان جریان بررسی کنم.