DEV Community

Cover image for การถ่ายโอน Multi-Agent: การส่งผ่านบริบทระหว่างเอเจนต์ย่อย
Thanawat Wongchai
Thanawat Wongchai

Posted on Originally published at apidog.com

การถ่ายโอน Multi-Agent: การส่งผ่านบริบทระหว่างเอเจนต์ย่อย

การส่งต่องานระหว่างเอเจนต์: ส่งผ่านสถานะ ไม่ใช่แค่บทสรุป

เอเจนต์วิจัยพบบัญชีลูกค้า ยืนยันแผน และดึงใบแจ้งหนี้สี่ฉบับล่าสุด จากนั้นส่งต่อให้เอเจนต์ฝ่ายเรียกเก็บเงินพร้อมข้อความสั้นๆ ว่า “ลูกค้าต้องการคืนเงิน” เอเจนต์ฝ่ายเรียกเก็บเงินซึ่งไม่รู้ข้อมูลบัญชี แผน หรือใบแจ้งหนี้ จึงเริ่มต้นด้วยการขอรหัสบัญชีอีกครั้ง นี่คือปัญหาการส่งต่องาน: ข้อมูลที่รวบรวมไว้ถูกทิ้งที่ขอบเขต ทำให้เสียทั้งค่า API ซ้ำและค่าใช้จ่ายจากข้อผิดพลาดของเอเจนต์ตัวถัดไป

ลองใช้ Apidog วันนี้

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

แนวทางที่คุ้มค่าที่สุดมักไม่ใช่การส่งข้อมูลทั้งหมด แต่เป็นการส่งผ่านตัวระบุแทน วิธีนี้จะใช้ได้ก็ต่อเมื่อเอเจนต์ทุกตัวดึงระเบียนเดียวกันผ่าน API และสิทธิ์ที่เหมาะสมได้

สิ่งที่ต้องข้ามขอบเขต

การคัดลอกบทสนทนาทั้งหมดผิดพลาดพอๆ กับการไม่ส่งอะไรเลย เอเจนต์ผู้รับจะต้องอ่านบริบทจำนวนมากเพื่อหาข้อมูลสำคัญ และอาจตัดสินใจใหม่ในเรื่องที่เอเจนต์ก่อนหน้าตัดสินใจไปแล้ว

ควรแยกข้อมูลส่งต่อเป็น 4 หมวดหมู่:

  1. ตัวระบุ (Identifiers) — รหัสบัญชี รหัสคำสั่งซื้อ รหัสงาน และหมายเลขตั๋ว เป็นข้อมูลขนาดเล็ก เสถียร และช่วยให้ผู้รับดึงข้อมูลที่ต้องการได้ ตัวระบุคือสิ่งที่มีค่าที่สุด แต่ก็มักถูกละทิ้งมากที่สุด
  2. การตัดสินใจที่ทำไปแล้ว (Decisions already made) — เช่น “ลูกค้ามีสิทธิ์ได้รับการคืนเงินภายใต้นโยบาย 3” ผู้รับไม่ควรนำเรื่องนี้มาพิจารณาซ้ำ เพราะอาจเกิดการตัดสินใจขัดแย้งกัน
  3. ข้อจำกัด (Constraints) — งบประมาณสูงสุด การอนุมัติ และการดำเนินการที่ทำไปแล้ว การสูญเสียข้อมูลเหล่านี้อาจทำให้เกิดการเรียกเก็บเงินซ้ำหรือขออนุมัติซ้ำ เชื่อมโยงโดยตรงกับแนวคิด idempotency สำหรับเอเจนต์ AI
  4. คำถามที่ยังเปิดอยู่ (Open questions) — สิ่งที่เอเจนต์แรกยังแก้ไม่ได้ ควรระบุให้ชัดเจน เพื่อป้องกันไม่ให้ผู้รับเดาคำตอบเอง

สิ่งที่ไม่จำเป็นต้องส่งต่อ ได้แก่ การตอบกลับ API ดิบ บันทึกการให้เหตุผล และข้อมูลที่เอเจนต์ผู้รับดึงได้เองจากการเรียก API เพียงครั้งเดียว

วิธีส่งผ่านสถานะ 3 รูปแบบ

1. ส่งต่อบทสนทนาทั้งหมด

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

บทความเรื่อง การเก็บการตอบสนองของเครื่องมือไว้นอกหน้าต่างบริบท อธิบายว่าทำไมโมเดลจึงสูญเสียข้อมูลจากส่วนกลางของบริบทได้ง่าย

2. ส่งต่อบทสรุป

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

ลูกค้าเป็นสมาชิกมาสองปีแล้วและรู้สึกหงุดหงิด

แทนที่จะเป็น:

บัญชี 8812, แผน Pro, ใบแจ้งหนี้ 4 ฉบับ และอนุมัติการคืนเงินสำหรับ inv_44

บทสรุปจึงเหมาะสำหรับเจตนาและรายละเอียดปลีกย่อย แต่ไม่ควรเป็นที่เก็บข้อมูลสำคัญเพียงแห่งเดียว

3. ส่งต่ออ็อบเจกต์ที่มีโครงสร้าง

เอเจนต์แรกกรอกข้อมูลลงในสคีมา และเอเจนต์ที่สองอ่านฟิลด์แทนการตีความเรียงความ วิธีนี้ต้องตั้งค่ามากกว่า แต่ตรวจสอบได้และเชื่อถือได้กว่า:

{
  "task_id": "task_2026_08_26_0031",
  "from_agent": "research",
  "to_agent": "billing",
  "entities": {
    "customer_id": "cus_8812",
    "invoice_ids": ["inv_41", "inv_42", "inv_43", "inv_44"],
    "subscription_id": "sub_119"
  },
  "decisions": [
    {
      "decision": "refund_eligible",
      "value": true,
      "basis": "policy 3.2, charged twice in one cycle"
    }
  ],
  "constraints": {
    "max_refund_cents": 4900,
    "human_approval_granted": false,
    "actions_taken": ["read_invoices"]
  },
  "open_questions": [
    "Customer has not confirmed which invoice to refund"
  ],
  "summary": "Customer cus_8812 was double-charged in August. Refund of one invoice is approved under policy 3.2, up to 4900 cents. Awaiting the customer's choice of invoice."
}
Enter fullscreen mode Exit fullscreen mode

ฟิลด์ summary ยังมีประโยชน์สำหรับรายละเอียดที่สคีมารองรับไม่ได้ แต่ควรอยู่เคียงข้างฟิลด์ที่มีโครงสร้าง ไม่ใช่ใช้แทนที่ทั้งหมด

ตรวจสอบอ็อบเจกต์ก่อนส่งต่อเสมอ หาก customer_id หายไป ให้แจ้งข้อผิดพลาดทันทีที่ขอบเขต แทนที่จะปล่อยให้เอเจนต์ตัวที่สองค้นพบหลังจากเรียก API ไปแล้วหลายครั้ง

ส่งผ่านข้อมูลอ้างอิง ไม่ใช่เพย์โหลด

รูปแบบที่แข็งแกร่งที่สุดแทบไม่ต้องส่งข้อมูลจริงเลย ให้ส่ง ID แล้วให้ผู้รับดึงข้อมูลที่ต้องการ:

  • สถานะยังเป็นปัจจุบัน หากข้อมูลเปลี่ยนระหว่างเอเจนต์สองตัว
  • เพย์โหลดมีขนาดเล็กกว่าการส่งโทเค็นจำนวนมาก
  • ทุกการอ่านปรากฏเป็น API call จึงตรวจสอบเส้นทางได้ง่ายกว่าข้อความที่คัดลอกในพรอมต์

ข้อกำหนดสำคัญคือเอเจนต์ทุกตัวต้องเข้าถึง API เดียวกันด้วยสิทธิ์ที่ถูกต้อง เอเจนต์แต่ละตัวควรมีข้อมูลรับรองของตัวเองและถูกจำกัดตามหน้าที่ บทความเรื่อง คีย์ API ที่มีสิทธิ์น้อยที่สุดสำหรับเอเจนต์ อธิบายแนวทางนี้เพิ่มเติม

ตัวอย่างเช่น:

  • เอเจนต์ฝ่ายเรียกเก็บเงินที่ถือโทเค็นวิจัยแบบอ่านอย่างเดียวไม่สามารถออกใบคืนเงิน
  • เอเจนต์วิจัยที่ถือโทเค็นเรียกเก็บเงินจะเพิ่มรัศมีความเสียหายโดยไม่จำเป็น

หากการดึงข้อมูลซ้ำมีราคาแพงหรือใช้เวลานาน ให้แคชระเบียนไว้ใน orchestrator แล้วส่งผ่านตัวอ้างอิงไปยังรายการแคช ผู้รับยังคงอ่านข้อมูลอย่างชัดเจน แต่การอ่านครั้งที่สองมีต้นทุนต่ำ

จุดที่การส่งต่องานมักล้มเหลว

ตัวระบุหายไป

บทสรุปพูดถึง “ลูกค้า” โดยไม่มี ID ผู้รับจึงค้นหาตามชื่อ พบสองรายการ และเลือกผิดตัว

การป้องกัน: ทำให้ ID ของเอนทิตีที่จำเป็นเป็นฟิลด์บังคับ และตรวจสอบก่อนส่งต่องาน

การกระทำซ้ำซ้อน

เอเจนต์แรกส่งอีเมลไปแล้ว แต่ไม่ได้บันทึกไว้ในอ็อบเจกต์ส่งต่อ เอเจนต์ที่สองจึงส่งซ้ำ

การป้องกัน: บันทึก actions_taken ตรวจสอบก่อนการเขียนทุกครั้ง และใช้ idempotency key เพื่อให้การทำซ้ำไม่ก่อให้เกิดผลเสีย

การอนุมัติหายไป

มนุษย์อนุมัติการคืนเงินระหว่างที่เอเจนต์แรกทำงาน แต่เอเจนต์ที่สองไม่ทราบและขออนุมัติอีกครั้ง ผู้ใช้จะมองว่าระบบไม่รับฟัง

การป้องกัน: บันทึกการอนุมัติเป็นข้อจำกัดของงาน ไม่ใช่คุณสมบัติของเอเจนต์

การสร้างข้อมูลอย่างมั่นใจ

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

การป้องกัน: ใช้ open_questions และกำหนดกฎในพรอมต์อย่างชัดเจนว่า หาก ID ที่จำเป็นหายไป ให้หยุดและสอบถาม ห้ามเดา

การวนซ้ำระหว่างเอเจนต์ทำให้ปัญหาเหล่านี้รุนแรงขึ้น เมื่อ A ส่งต่อให้ B และ B ส่งกลับให้ A สถานะอาจเสื่อมลงทุกครั้งเหมือนการคัดลอกสำเนา กำหนดจำนวนการส่งต่อสูงสุด และส่งผ่านอ็อบเจกต์งานต้นฉบับตลอดกระบวนการ แทนการสร้างอ็อบเจกต์ใหม่ที่แต่ละขอบเขต

ทดสอบขอบเขต ไม่ใช่แค่เอเจนต์

การส่งต่องานคือจุดเชื่อมต่อ จึงควรทดสอบเหมือนการทดสอบอินเทอร์เฟซ

ตรวจสอบอ็อบเจกต์ส่งต่อ

รันเอเจนต์แรกด้วยสถานการณ์ที่กำหนด แล้วตรวจสอบอ็อบเจกต์ที่สร้างขึ้นแบบกำหนดตายตัว:

  • มีตัวระบุที่จำเป็น
  • มีการบันทึกการตัดสินใจและพื้นฐานรองรับ
  • มีรายการการดำเนินการที่ทำไปแล้ว
  • มีคำถามที่ยังเปิดอยู่

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

ทดสอบผู้รับแยกกัน

ส่งอ็อบเจกต์ที่ถูกต้องให้เอเจนต์ฝ่ายเรียกเก็บเงิน แล้วตรวจสอบการทำงาน จากนั้นส่งอ็อบเจกต์ที่จงใจเสียหาย เช่น ไม่มี customer_id และยืนยันว่าผู้รับสอบถามแทนการเดา การทดสอบกรณีเสียหายช่วยจับการสร้างข้อมูลที่ไม่ถูกต้อง

ใช้ม็อกแทนระบบจริง

การทดสอบที่ออกใบคืนเงินจริงไม่ควรเป็นสิ่งที่ทำเพียงครั้งเดียว ให้ชี้เอเจนต์ทั้งสองไปยัง endpoint จำลอง เพื่อให้ชุดทดสอบทำงานได้ทุกครั้งที่มีการเปลี่ยนแปลง

ทำตามแนวทาง การรันเอเจนต์กับม็อกแทนที่จะเป็นระบบการผลิต ได้ โดยใน Apidog ม็อกสามารถสร้างจากคำจำกัดความ API เดียวกับที่เอเจนต์ใช้งาน ทำให้ทั้งสองตัวทดสอบกับสัญญาเดียวกัน

บันทึกทุกการส่งต่อ

บันทึกอ็อบเจกต์ที่แต่ละขอบเขตได้รับและส่งออก พร้อม task_id เมื่อการรันหลายเอเจนต์ผิดพลาด ข้อมูลนี้จะบอกได้ทันทีว่าเอเจนต์ตัวใดมีข้อมูลและตัวใดทำหาย รายละเอียดเกี่ยวกับฟิลด์ที่ควรเก็บอยู่ในบทความ การติดตามการเรียกใช้เครื่องมือของเอเจนต์

เฟรมเวิร์กส่งผ่านอะไรให้คุณบ้าง

ก่อนพึ่งพา primitive สำหรับ handoff ของเฟรมเวิร์กใดๆ ให้ตรวจสอบก่อนว่ามันส่งอะไรข้ามขอบเขตจริงๆ

  • OpenAI Agents SDK จำลอง handoff เป็นเครื่องมือที่เอเจนต์เรียกใช้ โมเดลจึงเป็นผู้ตัดสินใจว่าจะโอนการควบคุมเมื่อใด ควรใช้คู่กับการตรวจสอบเพย์โหลด
  • แนวทางหลายเอเจนต์ของ LangGraph ใช้สถานะเป็นอ็อบเจกต์กราฟที่ทุกโหนดอ่านและเขียน ซึ่งสอดคล้องกับ handoff แบบมีโครงสร้าง แต่คุณยังต้องกำหนดฟิลด์ที่จำเป็นเอง
  • บทความของ Anthropic เรื่อง การสร้างระบบวิจัยแบบหลายเอเจนต์ มีรายละเอียดด้านปฏิบัติการ โดยเฉพาะจำนวนคำสั่งที่เอเจนต์ย่อยต้องมีก่อนจึงจะทำงานได้อย่างมีประโยชน์

ทุกเฟรมเวิร์กส่งผ่านบางสิ่ง แต่ไม่มีเฟรมเวิร์กใดตัดสินใจแทนคุณว่าข้อเท็จจริงใดห้ามสูญหาย รายการนั้นต้องมาจากการออกแบบของคุณและควรมีการทดสอบรองรับ

เก็บอ็อบเจกต์งานไว้นอกบทสนทนา

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

บทสนทนาเป็นที่เก็บสถานะที่ไม่ดี เพราะอาจถูกบีบอัด ตัดทอน หรือเขียนใหม่ด้วยการสรุป และไม่มีขั้นตอนใดรู้ว่าฟิลด์ใดห้ามหาย ฐานข้อมูลไม่มีปัญหานี้

รูปแบบการทำงาน:

  1. เมื่อเริ่มรอบ เอเจนต์โหลดอ็อบเจกต์งาน
  2. หลังดำเนินการ เพิ่มข้อมูลลงใน actions_taken แล้วบันทึก
  3. เมื่อส่งต่องาน ส่งผ่านเพียง task_id
  4. เอเจนต์ผู้รับโหลดอ็อบเจกต์เดียวกัน

ไม่มีข้อมูลสำคัญเดินทางไปกับพรอมต์ จึงไม่มีข้อมูลสำคัญถูกสรุปทิ้งไป หากการทำงานหยุดลงในขั้นตอนที่สี่ การลองใหม่ก็เริ่มจากสถานะที่บันทึกไว้หลังขั้นตอนที่สาม ไม่ใช่เริ่มจากศูนย์

แพลตฟอร์มสำหรับเก็บสถานะ

หากเอเจนต์ทำงานเป็น CLI runtime บนเครื่องนักพัฒนา อ็อบเจกต์งานคงทนคือสิ่งที่คุณต้องสร้างขึ้นเอง แพลตฟอร์มการจัดการงานบางแห่งมีรูปแบบนี้อยู่แล้ว

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

เมื่อสถานะอยู่บน Task การส่งต่องานระหว่างเอเจนต์จึงไม่ขึ้นอยู่กับคุณภาพการสรุปของเอเจนต์ตัวใดตัวหนึ่ง ดูแนวทางเพิ่มเติมได้จาก เอกสารประกอบของ Sharkly

Claude Code, Codex และ runtime อื่นๆ ยังคงเป็นตัวดำเนินการบนคอมพิวเตอร์ที่ลงทะเบียน ส่วนแพลตฟอร์มจะจัดการรายการงาน การมอบหมาย และวงจรตรวจสอบ หากคุณกำลังสร้าง durable task เอง เอกสารดังกล่าวเป็นแหล่งอ้างอิงที่ดีสำหรับฟิลด์สำคัญ

Checklist สำหรับการส่งต่องาน

  • [ ] มีสคีมาสำหรับ handoff และตรวจสอบที่ขอบเขต
  • [ ] ID ของเอนทิตีเป็นฟิลด์บังคับ
  • [ ] การตัดสินใจมีพื้นฐานรองรับ
  • [ ] การดำเนินการที่ทำไปแล้วถูกบันทึกและตรวจสอบก่อนการเขียน
  • [ ] การอนุมัติและงบประมาณเดินทางไปพร้อมกับงาน ไม่ใช่ติดอยู่กับเอเจนต์
  • [ ] คำถามที่ยังเปิดอยู่ชัดเจน และผู้รับสอบถามแทนการเดา
  • [ ] ใช้ข้อมูลอ้างอิงเมื่อการดึงข้อมูลซ้ำมีต้นทุนต่ำ
  • [ ] จำกัดจำนวนการส่งต่อ และคงอ็อบเจกต์งานต้นฉบับไว้
  • [ ] บันทึกทุก handoff พร้อม task_id
  • [ ] รันการทดสอบขอบเขตใน CI ด้วยม็อก รวมถึงกรณีเพย์โหลดไม่สมบูรณ์

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

ดาวน์โหลด Apidog เพื่อจัดเก็บม็อกและการทดสอบขอบเขตไว้ข้าง API ที่เอเจนต์ทั้งสองใช้งาน

คำถามที่พบบ่อย

Handoff แบบมีโครงสร้างคุ้มค่าสำหรับเอเจนต์สองตัวหรือไม่?

สำหรับเอเจนต์สองตัวในงานสั้นๆ การส่งต่อบทสนทนาอาจเพียงพอ อ็อบเจกต์ที่มีโครงสร้างคุ้มค่าเมื่อมีเอเจนต์ตั้งแต่สามตัวขึ้นไป งานใช้เวลานาน หรือ handoff ข้ามกระบวนการและขอบเขตการทำงาน

โมเดลควรเขียนอ็อบเจกต์ handoff หรือโค้ดควรสร้าง?

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

จะหยุดบริบทเสื่อมในวงจรได้อย่างไร?

ส่งผ่านอ็อบเจกต์งานเดียวตลอดการทำงานและอัปเดตอ็อบเจกต์นั้น แทนการสร้างใหม่ในแต่ละขอบเขต พร้อมจำกัดจำนวน handoff หากงานต้องส่งต่อมากกว่าสองสามครั้ง อาจควรแบ่งโครงสร้างงานใหม่

แล้วเฟรมเวิร์กที่มี handoff ในตัวล่ะ?

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

เอเจนต์ย่อยต้องมีข้อมูลรับรอง API แยกกันหรือไม่?

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

ฟิลด์ summary ควรยาวแค่ไหน?

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

Top comments (0)