หน่วย 3 / 11

การสตรีมและการตอบกลับที่ยาวนาน

กำไร:

  • สามารถอธิบายได้ว่าการสตรีมคืออะไร ประเภทของกิจกรรม และเหตุใดจึงจำเป็น
  • max_tokens เข้าใจการหมดเวลาและความสัมพันธ์เอาต์พุตที่ยาวนาน 128K
  • สามารถเลือกได้อย่างเหมาะสมระหว่างคำขอแบบสตรีมมิ่งและแบบไม่สตรีมมิ่งตามปริมาณงาน

คุณอาจสังเกตเห็นว่าในอินเทอร์เฟซการแชท การตอบกลับจะ "พิมพ์" ทีละคำ นี่ไม่ใช่ความเจริญทางการมองเห็น ซึ่งเป็นผลมาจากเทคนิคที่เรียกว่าการสตรีม และมักจำเป็นสำหรับการผสานรวม LLM ที่มีคุณภาพการผลิต ในหน่วยนี้ คุณจะได้เรียนรู้ว่าโฟลว์คืออะไร เหตุการณ์ที่โฟลว์ประกอบด้วย ความสัมพันธ์กับเอาต์พุตและการหมดเวลาที่ยาวนาน และเมื่อใดควรใช้โฟลว์และเมื่อใดที่ไม่ควร เราจะครอบคลุมหัวข้อนี้ผ่านงานจริงของมืออาชีพ เช่น ผู้ช่วยสด การสร้างรายงานที่ยาวนาน การประมวลผลเป็นชุด

โฟลว์คืออะไร?

ด้วยคำขอที่ไม่ใช่การสตรีม (ซิงโครนัส) คุณจะรอจนกว่าโมเดลจะสร้างการตอบกลับทั้งหมด เมื่อคำตอบพร้อมก็มาเป็นชิ้นเดียว ในคำขอสตรีมมิ่ง เซิร์ฟเวอร์จะส่งการตอบกลับทีละชิ้นตามที่โมเดลสร้างขึ้น ในทางเทคนิคแล้ว ทำได้โดยใช้เหตุการณ์ที่เซิร์ฟเวอร์ส่ง (SSE — เหตุการณ์ที่เซิร์ฟเวอร์ส่ง ซึ่งเป็นวิธีการที่เซิร์ฟเวอร์ส่งเหตุการณ์เล็กๆ ติดต่อกันผ่านการเชื่อมต่อแบบเปิด)

ความแตกต่างจะปรากฏชัดในประสบการณ์ของผู้ใช้: ในการตอบสนองที่ใช้เวลา 8 วินาที ผู้ใช้ที่ไม่ได้สตรีมจะจ้องมองที่หน้าจอว่างเปล่าเป็นเวลา 8 วินาที; ผู้ใช้สตรีมมิ่งเห็นคำแรกใน ~0.5 วินาที และข้อความเริ่มไหล เวลาแฝงที่รับรู้—การรอคอยที่ผู้ใช้รู้สึก—ลดลงอย่างมาก ในขณะที่เวลาทั้งหมดยังคงไม่เปลี่ยนแปลง

ประเภทเหตุการณ์ของโฟลว์

Flow คือลำดับเหตุการณ์ ตามแนวคิดแล้ว โฟลว์ทั่วไปจะเป็นดังนี้:

เหตุการณ์

ความหมาย

message_start

การตอบสนองเริ่มขึ้น ข้อมูลส่วนหัวเช่นรุ่นและ ID มาถึงแล้ว

content_block_start

เริ่มบล็อกเนื้อหา (เช่น ข้อความ)

content_block_delta

ข้อความชิ้นเล็กๆ (เดลต้า) มาถึงแล้ว คุณรวบรวมสิ่งเหล่านี้

content_block_stop

บล็อกเสร็จสมบูรณ์

message_delta

อัปเดตข้อมูลสิ้นสุด เช่น stop_reason และการใช้งาน

ข้อความ_หยุด

ตอบไปแล้ว

รหัสของคุณจะรวมข้อความในเหตุการณ์ content_block_delta ตามลำดับ คุณจะได้ข้อความที่เหมือนกันทุกประการกับการตอบกลับที่ไม่ได้สตรีม การใช้งาน (หมายเลขโทเค็น) มักจะชัดเจนในตอนท้ายของโฟลว์ — คุณจะติดตามต้นทุนเมื่อโฟลว์สิ้นสุดลง

เคล็ดลับ: SDK ที่เป็นทางการส่วนใหญ่ (ชุดพัฒนาซอฟต์แวร์ — ไลบรารีสำเร็จรูปของผู้ให้บริการ) จะให้ความช่วยเหลือที่รวบรวมสตรีมให้กับคุณ (เช่น stream.get_final_message()) คุณไม่จำเป็นต้องจัดการแทร็กทั้งหมดด้วยตนเอง ใช้ตัวช่วยนี้หากคุณต้องการข้อความฉบับเต็ม ประมวลผลแต่ละเหตุการณ์ แต่สำหรับการพิมพ์สด

การตอบกลับที่ยาว, max_tokens และหมดเวลา

สาเหตุทางเทคนิคประการที่สองและมากกว่านั้นของการสตรีมคือการหมดเวลา หากคำขอ HTTP ไม่เสร็จสมบูรณ์ภายในระยะเวลาหนึ่ง ไคลเอนต์จะตัดการเชื่อมต่อ เมื่อคุณร้องขอเอาต์พุตจำนวนมากจากโมเดล (เช่น รายงานโทเค็น 40,000 รายการ) การเรียกแบบไม่โฟลว์อาจเกินขีดจำกัดและการหมดเวลานี้ คำขอจะล้มเหลว และคุณจะต้องชำระค่าโทเค็นที่สร้างขึ้น

โมเดลสมัยใหม่สามารถส่งออกโทเค็นได้มากถึง 128,000 โทเค็นในคำขอเดียว แต่หลักการทั่วไปนั้นชัดเจน: ใช้สตรีมหากค่า `max_tokens` สูง (ประมาณมากกว่า 16,000) การสตรีมช่วยให้การเชื่อมต่อคงอยู่และป้องกันการหมดเวลา คุณจะเห็นความคืบหน้าทันที

  • `max_tokens`: โทเค็นเอาต์พุตสูงสุดที่โมเดลสามารถสร้างได้ เพดานแข็ง หากมีการขัดจังหวะเกิดขึ้น stop_reason max_tokens จะถูกส่งกลับ
  • หน้าต่างบริบท: หน้าต่างที่ต้องใส่ผลรวมของอินพุต + เอาท์พุตให้พอดี max_tokens คือเพดานของเอาต์พุต อย่าผสมทั้งสอง
ข้อควรระวัง: การโยนคำขอที่ไม่ไหลด้วย max_tokens ขนาดใหญ่ถือเป็นข้อผิดพลาดคลาสสิกในการใช้งานจริง หากไม่มีการตอบสนอง การเชื่อมต่อจะลดลง ผู้ใช้เห็นข้อผิดพลาด และต้นทุนโทเค็นจะสูญเปล่า เอาต์พุตยาว = สตรีม

เมื่อใดที่จะไหลและเมื่อใดไม่?

สถานะ

การตั้งค่า

ทำไม

แชทสด / ผู้ช่วย

ไหล

เวลาในการตอบสนองลดลง ผู้ใช้เห็นความคืบหน้า

รายงานยาว/ผลิตเอกสาร

ไหล

ป้องกันการหมดเวลา รับเอาต์พุตจำนวนมากได้อย่างปลอดภัย

การจำแนกประเภทแบบสั้น (เช่น แท็กคำเดียว)

ไม่มีการไหล

ผลลัพธ์มีขนาดเล็กอยู่แล้ว ความซับซ้อนเพิ่มเติมที่ไม่จำเป็น

การประมวลผลเป็นชุด

ไหล/ชุด

ผลลัพธ์จะไม่แสดงทันที ดูหน่วยที่ 7

ขั้นตอนการทำงานอัตโนมัติ (ในเบื้องหลัง)

มักไม่ไหล.

คุณส่งต่อผลลัพธ์ไปยังขั้นตอนถัดไป โดยไม่มีการแสดงสด

พรอมต์/เทมเพลตที่คัดลอกได้

สตรีมนั้นไม่ใช่พรอมต์ แต่พรอมต์มีความสำคัญอย่างยิ่งต่อการจัดการเอาต์พุตที่สร้างโดยสตรีม ในการผลิตที่มีความยาวและลื่นไหล การสร้างโครงสร้างจากด้านหน้าจะเพิ่มทั้งคุณภาพและความสามารถในการตรวจสอบย้อนกลับ

# แบ่งรายงานขนาดยาวออกเป็นส่วนๆ (เพื่อให้เห็นความคืบหน้าในขั้นตอน) เขียนรายงานโดยระบุหัวข้อต่อไปนี้ตามลำดับที่แน่นอน เริ่มต้นแต่ละหัวข้อด้วย '## ':## สรุป## ผลการวิจัย## คำแนะนำ## ขั้นตอนถัดไป

# กำหนดความยาวเป้าหมายเพื่อหลีกเลี่ยงการตัดทอนในการผลิตที่ยาวนาน ข้อความทั้งหมดจะอยู่ที่ประมาณ 800 คำ รักษาสัดส่วนให้สมดุล อย่าทิ้งครึ่งประโยคไว้ท้ายประโยค

# ให้ประโยคแรกทันทีสำหรับผู้ช่วยสตรีมมิ่ง ให้ตอบประโยคเดียวตรงๆ ก่อน แล้วค่อยลงรายละเอียด ผู้ใช้จึงเห็นผลทันทีขณะรอ

# เก็บโครงสร้างเอาต์พุตแบบยาวไว้ (เพื่อให้สามารถแยกวิเคราะห์ได้ในภายหลัง) เอาต์พุตเอาต์พุตในส่วนเหล่านี้และทำเครื่องหมายแต่ละส่วนด้วยส่วนหัว '### ' แยกกัน เพื่อให้ฉันสามารถแยกวิเคราะห์โดยทางโปรแกรม: ### INTRODUCTION ### BODY ### SOURCES

พร้อมท์อ่อน / พร้อมท์แรง (การผลิตที่ยาวนาน)

# WEAKเขียนรายงานที่ยาวและมีรายละเอียดเกี่ยวกับหัวข้อนี้

# STRONGเขียนรายงานประมาณ 900 คำในหัวข้อนี้ หัวข้อ: ## สรุป, ## การวิเคราะห์, ## ความเสี่ยง, ## คำแนะนำ แต่ละหัวข้อควรมีความยาวสูงสุด 3 ย่อหน้า อย่าทิ้งครึ่งประโยคไว้ท้ายประโยค

รุ่นทรงพลัง; โดยจะกำหนดความยาว โครงสร้าง และคุณภาพการตกแต่งล่วงหน้า เมื่อส่วนต่างๆ ดำเนินไป ผู้ใช้จะมองเห็นความคืบหน้าได้อย่างชัดเจน และจัดการความยาวได้ด้วยตนเองเพื่อลดความเสี่ยงที่โมเดลจะหยุดชะงัก

มินิเคสสามอัน

กรณีที่ 1 — การร้องเรียนหน้าจอว่างเปล่า ผู้ช่วยลูกค้าของทีมที่ปรึกษาตอบสนองอย่างไม่ลื่นไหล การตอบสนองโดยเฉลี่ยจะใช้เวลา 7 วินาที ผู้ใช้ถามว่า "ค้างไหม" เขาบ่น เมื่อฉันเข้าสู่กระแส คำแรกเข้ามาใน ~0.6 วินาที; เวลาทั้งหมดยังคงเท่าเดิม แต่ข้อร้องเรียน "ช้า" เกือบจะหายไป

กรณีที่ 2 — รายงานที่ล้าสมัย ทีมการเงินกำลังจัดทำรายงานไตรมาส 30 หน้า; ด้วย max_tokens: 30000 คำขอที่ไม่ไหลจะติดค้างอยู่ในการหมดเวลาไคลเอ็นต์ 60 วินาที คำขอจะล้มเหลว — และโทเค็นที่สร้างขึ้นจะถูกเขียนลงในใบแจ้งหนี้ พวกเขาไปตามกระแส การเชื่อมต่อยังคงใช้งานได้ รายงานถูกส่งเต็มจำนวน และลดต้นทุนที่สูญเปล่าออกไป

กรณีที่ 3 — การไหลที่ไม่จำเป็น ทีมปฏิบัติการติดป้ายกำกับอีเมลขาเข้าว่า "ด่วน/ประจำ" ผลลัพธ์เป็นคำเดียว แต่พวกเขาใช้การไหลเป็นนิสัย โฟลว์ไม่มีประโยชน์ในการตอบกลับเพียงคำเดียว ทำให้โค้ดซับซ้อนโดยไม่จำเป็น เมื่อฉันเปลี่ยนมาใช้ Flowless โค้ดก็ง่ายขึ้นและพฤติกรรมยังคงเหมือนเดิม บทเรียน: การสตรีมมีคุณค่าในเอาต์พุตแบบยาว/สด ไม่ใช่ทุกที่

ข้อผิดพลาดทั่วไป

  • การไม่ใช้สตรีมในเอาต์พุตที่ยาว: การหมดเวลาและต้นทุนโทเค็นที่สูญเปล่า
  • การใช้การสตรีมแบบสั้น: ความซับซ้อนที่ไม่จำเป็น ประโยชน์เป็นศูนย์
  • ไม่ตรวจสอบ `stop_reason` ในตอนท้ายของสตรีม: การตอบสนองที่ถูกตัดทอนด้วย max_tokens ถือว่าเสร็จสมบูรณ์
  • การรวมเดลต้าไม่ถูกต้อง: การสรุปด้วยตนเองด้วยตัวช่วย SDK ทำให้เกิดข้อผิดพลาดเกี่ยวกับลำดับ/ส่วนที่หายไป
  • กำลังพยายามอ่าน `การใช้งาน' กลางสตรีม: หมายเลขโทเค็นมักจะชัดเจนในตอนท้าย ติดตามค่าใช้จ่ายในตอนท้าย
  • การสตรีมผิดพลาดเพื่อลดต้นทุน: การสตรีมช่วยเพิ่มประสบการณ์และความทนทาน มันไม่เปลี่ยนแปลงราคาโทเค็น

ลึกลงไป: การหยุดชะงักของการไหลและความยืดหยุ่น

การสตรีมคือการเชื่อมต่อแบบสด นี่คือทั้งจุดแข็งและความเปราะบางของมัน หากการเชื่อมต่อขาดกลางคัน (เครือข่ายผันผวน การหมดเวลาของไคลเอ็นต์) คุณจะเก็บข้อความที่คุณสะสมไว้ แต่การตอบสนองจะไม่สมบูรณ์ ควรเตรียมไคลเอนต์สตรีมมิ่งคุณภาพการผลิตสำหรับสิ่งนี้: ไม่ควรถือว่าข้อความบางส่วนเป็น "การตอบกลับที่เสร็จสมบูรณ์" และไม่ควรถือว่าการตอบกลับเสร็จสิ้นจนกว่าจะเห็นเหตุการณ์ message_stop

ความละเอียดอ่อนประการที่สองคือการไหลไม่เปลี่ยนแปลงต้นทุน ไม่ว่าคุณจะได้รับคำตอบไม่ว่าจะมีการสตรีมหรือไม่ก็ตาม จะไม่ส่งผลต่อราคาโทเค็น โฟลว์ช่วยเพิ่มประสบการณ์และความอดทนเท่านั้น แล้ว “ถ้าเราไปสตรีมมิ่งจะถูกกว่านี้มั้ย?” คำตอบสำหรับคำถามคือไม่ สำหรับราคา โปรดดูที่ยูนิตที่ 5 และ 6 (การเลือกรุ่น แคช)

ประเด็นที่สามคือการสร้างความสมดุลในทางปฏิบัติ: ด้วยผู้ช่วยแบบสด การมาถึงคำแรกอย่างรวดเร็ว (การรับรู้ความล่าช้า) มีคุณค่าอย่างมาก ดังนั้นการขอให้โมเดลป้อนคำตอบโดยตรงและให้ผลลัพธ์สั้นๆ ก่อน (ผ่านการแจ้งของระบบในหน่วยที่ 4) จะทวีคูณประโยชน์ของโฟลว์ หากผู้ใช้เห็นบางสิ่งที่มีความหมายในวินาทีแรก พวกเขาก็จะรออย่างอดทนกับรายละเอียดที่ตามมา ในทางกลับกัน โฟลว์ไม่สนับสนุนงานที่รันในเบื้องหลัง ซึ่งเอาท์พุตจะไปยังขั้นตอนการทำงานอัตโนมัติถัดไป เกณฑ์เดียวคืองานจะเสร็จสมบูรณ์อย่างถูกต้องและครบถ้วน

โดยสรุป

การสตรีมจะดึงการตอบสนองทีละชิ้น ลดเวลาแฝงในการรับรู้ และป้องกันการหมดเวลาในทรูพุตขนาดใหญ่ เกือบจำเป็นสำหรับผู้ช่วยสดและการผลิตเอกสารที่ยาวนาน มันไม่จำเป็นสำหรับงานสั้น/พื้นหลัง ในการผลิตที่มีขนาดยาว การสร้างโครงสร้างและความยาวจากด้านหน้าโดยทันทีจะช่วยเพิ่มทั้งคุณภาพและความสามารถในการตรวจสอบย้อนกลับ เมื่อโฟลว์เสร็จสิ้น จะมีการตรวจสอบ stop_reason และการใช้งานอย่างแน่นอน

งานสมัคร

เลือกสองสถานการณ์: หนึ่งสถานการณ์จริง/ระยะยาว (เช่น รายงานให้กับลูกค้า), หนึ่งสถานการณ์สั้น/พื้นหลัง (เช่น การแท็ก) (1) ตัดสินใจและชี้แจงว่าคุณจะใช้โฟลว์สำหรับแต่ละรายการหรือไม่ (2) เขียนคำสั่งที่กำหนดโครงสร้างสำหรับสคริปต์ขนาดยาว (ส่วนหัว + ความยาวเป้าหมาย) (3) กำหนดค่า max_tokens (4) แสดงรายการการตรวจสอบที่คุณจะดำเนินการโดยมี stop_reason และการใช้งานเมื่อสิ้นสุดโฟลว์

รายการตรวจสอบ

  • [ ] ฉันสามารถอธิบายได้ว่าการสตรีมคืออะไรและจะลดเวลาแฝงในการรับรู้ได้อย่างไร
  • [ ] ฉันเข้าใจประเภทเหตุการณ์พื้นฐานของการเข้าร่วมสตรีมและเดลต้า
  • [ ] ฉันรู้เกี่ยวกับความจำเป็นในการสตรีมด้วย max_token ขนาดใหญ่และความสัมพันธ์ของการหมดเวลา
  • [ ] ฉันสามารถตัดสินใจได้ว่าจะใช้การสตรีมปริมาณงานใด และจะไม่ใช้ปริมาณงานใด
  • [ ] ฉันสามารถตรวจสอบ stop_reason และการใช้งานเมื่อสิ้นสุดสตรีมได้