เขียน MCP Tool ไป 12 ตัวให้ Agent ใช้ แต่มันเลือกผิดทุกครั้ง ทำไม

สรุปสั้น ๆ
Agent เลือก MCP tool ผิดเพราะมันตัดสินใจจาก description และ inputSchema เท่านั้น ไม่ได้อ่านชื่อฟังก์ชันหรือโค้ดข้างในเหมือนคนเขียนโปรแกรม การแก้ต้องเริ่มจากเขียน description ให้บอกชัดว่า 'ใช้เมื่อไร ไม่ใช้เมื่อไร' ออกแบบ schema ให้แคบ และตัด scope ที่ซ้อนทับกันระหว่าง tool ออกให้หมด
ทีมหนึ่งที่ผมเคยช่วยรีวิว MCP server มี tool อยู่ 12 ตัว ครอบคลุมงานตั้งแต่ค้นหาลูกค้า อัปเดตสถานะ Order ไปจนถึงส่งอีเมล ทุกตัวตั้งชื่อฟังก์ชันไว้ชัดเจนแบบที่โปรแกรมเมอร์อ่านแล้วเข้าใจทันที เช่น `search_customer_by_email` กับ `search_customer_by_phone` แต่พอเอาไปต่อกับ Agent จริง สิ่งที่เกิดขึ้นคือ Agent เรียก tool ผิดตัวอยู่เรื่อย ๆ บางครั้งเรียก `search_customer_by_phone` ทั้งที่ผู้ใช้พิมพ์อีเมลมาโต้ง ๆ
จุดที่ทำให้ทีมงงคือชื่อ tool มันต่างกันชัดมากในสายตาคนเขียนโค้ด แต่ Agent ไม่ได้อ่านชื่อฟังก์ชันแบบที่คนอ่าน มันอ่าน description และ input schema ที่แนบมากับ tool นั้นเป็นข้อความล้วน ๆ แล้วเทียบกับคำถามของผู้ใช้ในหัว ถ้า description ของสองตัวเขียนคล้ายกันเกินไป หรือไม่ได้บอกเงื่อนไขว่าตัวไหนควรใช้ตอนไหน โอกาสเลือกผิดจะสูงขึ้นทันทีไม่ว่าโมเดลจะฉลาดแค่ไหน
บทความนี้จะพาไล่ทีละจุดว่าอะไรทำให้ Agent เลือก tool ผิด ตั้งแต่การตั้งชื่อ การเขียน description การออกแบบ inputSchema ไปจนถึงวิธีทดสอบก่อนปล่อยใช้งานจริง พร้อมตัวอย่างสมมติที่ปรับแก้แล้วอัตราการเลือกผิดลดลงอย่างเห็นได้ชัด
อาการที่เจอบ่อย เมื่อ Agent เรียกผิด tool ทั้งที่ชื่อดูต่างกันชัดเจน
อาการที่พบบ่อยที่สุดมีสามแบบ แบบแรกคือ Agent เรียก tool ที่ทำงานคล้ายกันแต่ผิดขอบเขต เช่น มี tool `get_order_status` กับ `get_order_detail` แล้ว Agent สลับใช้กันไปมาโดยไม่มีรูปแบบชัดเจนว่าเลือกตัวไหนตอนไหน แบบที่สองคือ Agent เรียก tool ที่ไม่เกี่ยวข้องเลยกับคำถาม เช่น ผู้ใช้ถามยอดขายเดือนนี้ แต่ Agent กลับไปเรียก tool ที่ใช้แก้ไขข้อมูลลูกค้า ซึ่งอันตรายกว่าสองแบบแรกเพราะเสี่ยงต่อการเปลี่ยนแปลงข้อมูลโดยไม่ตั้งใจ
แบบที่สามซึ่งพบบ่อยในทีมที่มี tool เยอะเกิน 15-20 ตัวคือ Agent เรียกถูกบ้างผิดบ้างแบบสุ่ม ทั้งที่คำถามเดิมซ้ำกัน วันนี้เรียกถูก พรุ่งนี้เรียกผิด นี่คือสัญญาณว่า description ของ tool หลายตัวมีความหมายซ้อนทับกันในสายตาโมเดล ทำให้มันตัดสินใจแบบก้ำกึ่งแล้วสุ่มเลือกไปข้างใดข้างหนึ่ง
สิ่งที่ทีมส่วนใหญ่ทำตอนเจออาการนี้คือรีบไปปรับ prompt ของ Agent หรือเปลี่ยนโมเดลให้แรงขึ้น ซึ่งช่วยได้บ้างแต่ไม่ใช่ทางแก้ที่ยั่งยืน เพราะต้นตอจริง ๆ อยู่ที่การออกแบบ tool เอง ถ้า schema ยังกำกวมอยู่ ต่อให้เปลี่ยนโมเดลแรงแค่ไหนก็ยังมีโอกาสเลือกผิดอยู่ดี เพียงแต่อัตราผิดอาจลดลงบ้างเท่านั้น
ทำไมชื่อ tool ที่ต่างกันชัดเจนในสายตาคนเขียนโค้ด ยังทำให้ Agent สับสน
ปัญหาหลักคือ Agent ไม่ได้ตัดสินใจจากชื่อฟังก์ชันตรง ๆ แต่ตัดสินใจจากคู่ของชื่อกับ description ที่แนบมาด้วยกัน ถ้าชื่อสั้นและกระชับแต่ description อธิบายกว้างเกินไปจนครอบคลุมสถานการณ์เดียวกันกับ tool อีกตัว โมเดลจะมองว่าทั้งสองตัวใช้แทนกันได้ในบางกรณี แล้วเลือกโดยอาศัยสัญญาณที่ไม่เสถียร เช่น ลำดับที่ tool ถูกส่งมาใน context หรือคำที่ปรากฏในคำถามของผู้ใช้แบบผิวเผิน
อีกจุดที่มักถูกมองข้ามคือชื่อพารามิเตอร์ภายใน inputSchema เอง ถ้า tool สองตัวใช้ชื่อ field เดียวกัน เช่น `id` ทั้งคู่ แต่ตัวหนึ่งหมายถึง customer id อีกตัวหมายถึง order id โมเดลอาจดึงค่าจากบริบทผิดตัวไปใส่ผิด tool ได้ ทางแก้คือตั้งชื่อ field ให้จำเพาะเจาะจงมากขึ้น เช่น `customer_id` กับ `order_id` แทนที่จะใช้ `id` เฉย ๆ ซ้ำกันทุกที่
ทีมที่แก้ปัญหานี้ได้ผลดีมักทำสองอย่างพร้อมกัน คือเขียน description ให้ระบุเงื่อนไขการใช้แบบเจาะจง ไม่ใช่แค่บอกว่า tool ทำอะไร และตั้งชื่อ field ให้ไม่ซ้ำกันข้าม tool แม้จะหมายถึงสิ่งที่คล้ายกันในโดเมนก็ตาม การทำสองข้อนี้ลด ambiguity ได้มากกว่าการไปปรับ prompt หลัก ๆ ของ Agent เสียอีก
Description คือสิ่งเดียวที่ Agent ใช้ตัดสินใจ ไม่ใช่ชื่อฟังก์ชันหรือคอมเมนต์ในโค้ด
description ที่ดีต้องตอบสามคำถามในตัวมันเอง คือ tool นี้ทำอะไร ควรใช้ตอนไหน และไม่ควรใช้ตอนไหน ส่วนใหญ่ที่เขียนกันมักตอบแค่ข้อแรก เช่น 'ค้นหาข้อมูลลูกค้าจากอีเมล' ซึ่งฟังดูชัดเจนสำหรับคนอ่าน แต่ไม่ได้บอก Agent ว่าถ้าผู้ใช้ให้เบอร์โทรมาแทน ควรไปใช้ tool ตัวอื่น
ตัวอย่างที่เขียนดีขึ้นคือ 'ค้นหาข้อมูลลูกค้าจากอีเมลเท่านั้น ใช้เมื่อผู้ใช้ระบุอีเมลมาชัดเจน หากมีแค่เบอร์โทรหรือชื่อให้ใช้ tool search_customer_by_phone หรือ search_customer_by_name แทน' การเติมประโยคระบุขอบเขตและชี้ไปยัง tool ทางเลือกแบบนี้ ช่วยให้โมเดลจับคู่คำถามกับ tool ได้แม่นขึ้นอย่างเห็นได้ชัดในทางปฏิบัติ
อีกเทคนิคที่ช่วยได้มากคือใส่ตัวอย่างคำถามสั้น ๆ ไว้ท้าย description เช่น 'ตัวอย่างคำถามที่ควรเรียก tool นี้: มีลูกค้าอีเมล somchai@example.com ไหม' เพราะโมเดลภาษามีแนวโน้มจับคู่รูปแบบประโยคคำถามกับตัวอย่างที่ให้ไว้ได้ดีกว่าจับคู่จากคำนิยามล้วน ๆ อย่างเดียว โดยเฉพาะเมื่อมี tool จำนวนมากอยู่ใน context เดียวกัน
ข้อควรระวังคือ description ไม่ควรยาวจนเกินไปจนกลืนกับ tool อื่น เพราะ context ของ Agent มีขีดจำกัด ถ้าทุก tool มี description ยาวเป็นย่อหน้า จำนวน token ที่ใช้ไปกับคำอธิบาย tool อาจแย่งพื้นที่จากส่วนอื่นของ context ควรเขียนให้กระชับแต่ครบสามส่วนที่ว่ามา ไม่ใช่ยาวเพื่อความสมบูรณ์แบบ
ออกแบบ inputSchema ให้แคบพอจะกันการเรียกผิดพารามิเตอร์ตั้งแต่ต้นทาง
หลักการสำคัญของ inputSchema คือยิ่งจำกัดขอบเขตของค่าที่รับได้เท่าไร โอกาสที่ Agent จะส่งค่าผิดยิ่งลดลงเท่านั้น ถ้า field ใดมีค่าที่เป็นไปได้จำกัด เช่น สถานะ Order ที่มีแค่ pending, paid, shipped, cancelled ควรประกาศเป็น enum ตรง ๆ แทนที่จะปล่อยเป็น string อิสระ เพราะถ้าเป็น string อิสระ Agent อาจส่งคำที่ใกล้เคียงแต่ไม่ตรงเป๊ะ เช่น ส่ง 'shipping' แทนที่จะเป็น 'shipped' แล้วทำให้ backend error
อีกจุดที่ควรทำคือแยก field ที่จำเป็น (required) ออกจาก field ที่เป็นตัวเลือกให้ชัดเจน และใส่คำอธิบายสั้น ๆ กำกับแต่ละ field ไม่ใช่แค่ชื่อ field เฉย ๆ เพราะเวลา Agent ต้องกรอกพารามิเตอร์หลายตัวพร้อมกัน มันจะอ่านคำอธิบายของแต่ละ field เพื่อตัดสินว่าจะดึงค่าจากส่วนไหนของบทสนทนามาใส่ ถ้าไม่มีคำอธิบายกำกับ มันอาจเดาผิดโดยเฉพาะกับ field ที่ชื่อกำกวมอย่าง `value` หรือ `data`
สำหรับ field ที่เป็นวันที่หรือตัวเลข ควรระบุ format ที่ต้องการไว้ใน description ของ field นั้นด้วย เช่น 'รูปแบบ YYYY-MM-DD' เพราะโมเดลอาจส่งวันที่มาในรูปแบบที่คนไทยคุ้นเคยอย่าง DD/MM/YYYY ซึ่งตีความผิดได้ง่ายถ้า backend ไม่ได้ validate ให้รัดกุม การระบุ format ตรง ๆ ใน schema ช่วยลดข้อผิดพลาดประเภทนี้ได้มาก
รวม tool เป็นตัวใหญ่ตัวเดียว หรือแตกเป็นตัวเล็กหลายตัว แบบไหนดีกว่า
คำถามนี้ไม่มีคำตอบตายตัว แต่มีกรอบตัดสินใจที่ใช้ได้จริง ถ้างานสองอย่างมักถูกเรียกพร้อมกันเสมอ เช่น ค้นหาลูกค้าแล้วดึงประวัติการสั่งซื้อทันที การรวมเป็น tool เดียวที่คืนทั้งสองอย่างพร้อมกันมักดีกว่า เพราะลดจำนวนรอบที่ Agent ต้องตัดสินใจเรียก tool ซึ่งแต่ละรอบคือจุดที่มีโอกาสเลือกผิดเพิ่มขึ้น
ในทางกลับกัน ถ้างานสองอย่างมีโอกาสถูกเรียกแยกกันบ่อย ๆ เช่น ค้นหาลูกค้าอย่างเดียวเพื่อตรวจสอบตัวตน กับอัปเดตข้อมูลลูกค้าซึ่งเป็นการเปลี่ยนแปลงข้อมูลจริง การแยกเป็นสอง tool จะปลอดภัยกว่า เพราะถ้ารวมเป็นตัวเดียวที่ทำได้ทั้งอ่านและเขียน จะเพิ่มความเสี่ยงที่ Agent เผลอเรียกในโหมดเขียนทั้งที่ผู้ใช้แค่อยากดูข้อมูล
ทีมที่ผมเคยรีวิวเจอปัญหานี้ชัดเจนตอนมี tool ชื่อ `manage_customer` ที่รับพารามิเตอร์ `action` เป็น 'read' หรือ 'update' อยู่ในตัวเดียว ผลคือ Agent บางครั้งส่ง action ผิดค่า ทำให้ดึงข้อมูลอ่านอย่างเดียวกลายเป็นการเขียนทับโดยไม่ตั้งใจ พอแยกออกเป็น `get_customer` กับ `update_customer` สองตัวแยกกัน อัตราการเรียกผิดโหมดลดลงจนแทบเป็นศูนย์ เพราะ Agent ไม่ต้องตัดสินใจเรื่อง action ซ้อนอยู่ในการตัดสินใจเลือก tool อีกชั้นหนึ่ง
กฎง่าย ๆ ที่ใช้ได้คือ ถ้า action ใดเปลี่ยนแปลงข้อมูล (write, update, delete, send) ควรแยก tool ออกจาก action ที่แค่อ่านข้อมูลเสมอ ไม่ว่าจะดูรวมเป็นเรื่องเดียวกันแค่ไหนในสายตาคนออกแบบระบบก็ตาม เพราะความเสี่ยงของการเรียกผิดโหมดฝั่งเขียนสูงกว่าฝั่งอ่านมาก
เมื่อสอง tool ทำงานคาบเกี่ยวกัน ต้องตัดสินใจว่าจะรวมหรือกั้นขอบเขตให้ชัด
สถานการณ์ที่พบบ่อยคือมี tool สองตัวที่ทำงานคล้ายกันมากแต่มาจากทีมคนละทีมที่พัฒนาแยกกัน เช่น ทีมหนึ่งทำ `search_products` เพื่อค้นหาสินค้าในคลัง อีกทีมทำ `search_catalog` เพื่อค้นหาสินค้าบนหน้าเว็บ ซึ่งข้อมูลอาจไม่ตรงกัน 100% แต่ในสายตา Agent สองตัวนี้ทำงานเหมือนกันเกือบทุกกรณี และมันจะเลือกไม่แน่นอนว่าจะเรียกตัวไหน
ทางแก้ที่ตรงจุดที่สุดคือกลับไปตั้งคำถามว่าจริง ๆ แล้วธุรกิจต้องการสอง tool นี้พร้อมกันหรือไม่ ถ้าคำตอบคือไม่ต้อง ควรรวมเป็นตัวเดียวแล้วให้ backend จัดการความต่างของแหล่งข้อมูลเอง แต่ถ้าจำเป็นต้องแยกจริง ๆ เพราะข้อมูลสองแหล่งมีความหมายต่างกันในทางธุรกิจ ต้องเขียน description ให้ระบุความต่างแบบเจาะจงมาก ๆ เช่น ระบุว่าตัวหนึ่งคืนเฉพาะสินค้าที่มีสต๊อกจริง อีกตัวคืนสินค้าที่ประกาศขายบนเว็บโดยไม่รับประกันว่ามีสต๊อก
อีกวิธีที่ช่วยได้ในกรณีที่แยกไม่ได้จริง ๆ คือใส่คำเตือนไขว้กันในทั้งสอง description เช่น description ของ `search_products` ระบุว่า 'ไม่ใช่ tool สำหรับตรวจราคาหน้าเว็บ ให้ใช้ search_catalog แทนถ้าต้องการราคาที่แสดงบนเว็บไซต์' การเขียนแบบไขว้กันนี้ช่วยให้โมเดลมีจุดอ้างอิงชัดเจนขึ้นเวลาต้องเลือกระหว่างสองตัวที่คล้ายกัน
ผลลัพธ์ที่ tool ส่งกลับต้องออกแบบให้ Agent อ่านต่อได้ ไม่ใช่แค่คนอ่านเข้าใจ
หลายทีมโฟกัสแต่เรื่อง input schema จนลืมว่าผลลัพธ์ที่ tool ส่งกลับก็สำคัญไม่แพ้กัน เพราะ Agent จะเอาผลลัพธ์นั้นไปใช้ตัดสินใจขั้นต่อไป ถ้าผลลัพธ์เป็นข้อความยาวแบบ human-readable ล้วน ๆ โดยไม่มีโครงสร้างชัดเจน Agent อาจตีความข้อมูลผิดหรือดึงค่าผิดตัวไปใช้ในขั้นถัดไป
แนวทางที่แนะนำคือส่งผลลัพธ์กลับเป็นโครงสร้างที่ชัดเจน เช่น JSON ที่มี field ตายตัว พร้อม field บอกสถานะว่าสำเร็จหรือไม่ และถ้าไม่สำเร็จให้ระบุเหตุผลเป็นข้อความที่ Agent อ่านแล้วตัดสินใจขั้นต่อไปได้ เช่น 'customer_not_found' แทนที่จะโยน error แบบ raw stack trace กลับไป เพราะ Agent จะพยายามอธิบาย error นั้นให้ผู้ใช้ฟัง ถ้าข้อความ error งง ๆ ผู้ใช้ปลายทางก็จะได้คำตอบที่งงตามไปด้วย
อีกจุดที่มักถูกมองข้ามคือขนาดของผลลัพธ์ ถ้า tool คืนข้อมูลลูกค้าทุก field ที่มีในฐานข้อมูลกลับมาทั้งหมด รวมถึง field ที่ไม่จำเป็นต่อบทสนทนา จะกินพื้นที่ context โดยไม่จำเป็นและอาจทำให้ Agent สับสนกับข้อมูลที่ไม่เกี่ยวข้อง ควรออกแบบให้คืนเฉพาะ field ที่จำเป็นเป็นค่าเริ่มต้น แล้วเปิดพารามิเตอร์เสริมให้ขอ field เพิ่มเติมได้เฉพาะเมื่อจำเป็นจริง ๆ
ทดสอบว่า Agent เลือก tool ถูกจริงก่อนปล่อยใช้งาน ไม่ใช่เดาเอาจากความรู้สึก
วิธีที่ตรงไปตรงมาที่สุดคือทำชุดคำถามทดสอบที่ครอบคลุมทุก tool อย่างน้อย tool ละ 3-5 คำถามที่คนจริงน่าจะถาม รวมถึงคำถามก้ำกึ่งที่จงใจให้ใกล้เคียงกับ tool อื่นด้วย แล้วรันผ่าน Agent จริงเพื่อดูว่ามันเรียก tool ตัวไหน พร้อมพารามิเตอร์อะไร บันทึกผลไว้เป็น baseline ก่อนแก้ description หรือ schema ทุกครั้ง เพื่อเทียบว่าการแก้แต่ละรอบทำให้อัตราถูกเพิ่มขึ้นจริงหรือไม่
- รวบรวมคำถามตัวอย่างจากผู้ใช้จริงหรือทีม Support ที่เจอบ่อย อย่างน้อย 30-50 คำถามครอบคลุมทุก tool
- จัดกลุ่มคำถามเป็นสามระดับ คือคำถามชัดเจนไม่กำกวม คำถามก้ำกึ่งระหว่างสอง tool และคำถามที่ไม่ควรเรียก tool ใดเลย
- รันคำถามทั้งหมดผ่าน Agent แล้วบันทึกว่ามันเรียก tool ไหน พารามิเตอร์อะไร เทียบกับคำตอบที่ควรจะเป็น
- คำนวณอัตราความถูกต้องแยกตามกลุ่ม แล้วโฟกัสแก้เฉพาะกลุ่มที่อัตราต่ำก่อน ไม่ต้องแก้ทุก tool พร้อมกัน
- หลังแก้ description หรือ schema แล้ว รันชุดคำถามเดิมซ้ำอีกรอบเพื่อยืนยันว่าอัตราถูกดีขึ้นจริงและไม่ได้ไปทำให้กลุ่มอื่นแย่ลง
ตัวอย่างสมมติ การปรับ 12 tool ของทีมหนึ่งจนอัตราเลือกผิดลดลง
ตัวอย่างสมมตินี้อ้างอิงจากแพทเทิร์นปัญหาที่พบได้ทั่วไป ไม่ใช่ตัวเลขจากลูกค้าจริงรายใดรายหนึ่ง สมมติทีมหนึ่งมี MCP server 12 tool และวัดอัตราการเลือก tool ผิดจากชุดคำถามทดสอบ 50 ข้อ พบว่าก่อนปรับแก้ อัตราเลือกผิดอยู่ที่ราว 22% ของคำถามทั้งหมด ส่วนใหญ่กระจุกอยู่ที่คู่ tool ที่ทำงานคาบเกี่ยวกันสามคู่
หลังทำตามขั้นตอนสามอย่างคือ เขียน description ใหม่ให้ระบุเงื่อนไขการใช้แบบเจาะจง แยก tool ที่ปนโหมดอ่านกับเขียนออกจากกัน และเติมคำเตือนไขว้กันในคู่ที่ยังจำเป็นต้องแยกไว้ อัตราเลือกผิดลดลงเหลือราว 6% ในการทดสอบชุดเดิม โดยเฉพาะคู่ที่ปนโหมดอ่านกับเขียนซึ่งลดลงมากที่สุดหลังแยก tool ออกจากกัน
สิ่งที่น่าสนใจคือทีมนี้ไม่ได้เปลี่ยนโมเดลหรือปรับ system prompt เลยแม้แต่น้อย การเปลี่ยนแปลงทั้งหมดเกิดที่ฝั่งการออกแบบ tool เท่านั้น ซึ่งสะท้อนว่าปัญหาการเลือก tool ผิดส่วนใหญ่แก้ได้ที่ต้นทางของการออกแบบ ไม่จำเป็นต้องพึ่งพาความฉลาดของโมเดลเพียงอย่างเดียวเสมอไป
ทำแบบนี้แล้วพัง เพราะ… ข้อผิดพลาดที่เจอซ้ำ ๆ ตอนออกแบบ MCP tool
- ตั้ง description กว้างเกินไปเพื่อ 'เผื่อกรณี' — ทำแบบนี้แล้วพัง เพราะ description ที่กว้างครอบคลุมทุกกรณีในสายตาคนเขียน จะทำให้ Agent มองว่า tool นี้ใช้ได้กับเกือบทุกคำถาม แล้วเรียกมันแทน tool ที่เจาะจงกว่าอยู่บ่อย ๆ
- รวม action อ่านและเขียนไว้ใน tool เดียวเพื่อความสะดวกของฝั่ง backend — ทำแบบนี้แล้วพัง เพราะเพิ่มความเสี่ยงที่ Agent เผลอเรียกโหมดเขียนทั้งที่ผู้ใช้แค่ต้องการดูข้อมูล และแก้ยากกว่าการแยกตั้งแต่แรกมาก
- ใช้ชื่อ field ซ้ำกันข้าม tool ทั้งที่ความหมายต่างกัน เช่น `id` หรือ `value` — ทำแบบนี้แล้วพัง เพราะโมเดลอาจดึงค่าจากบริบทผิดตัวมาใส่ผิด field โดยไม่มีสัญญาณเตือนใด ๆ ให้เห็นตอนพัฒนา
- ไม่มีชุดคำถามทดสอบ ปล่อย tool ใหม่เข้าระบบแล้วดูผลจากรายงานปัญหาของผู้ใช้จริง — ทำแบบนี้แล้วพัง เพราะกว่าจะรู้ว่า tool ออกแบบมีปัญหา ก็ผ่านการใช้งานจริงที่อาจสร้างความเสียหายไปแล้ว การทดสอบก่อนปล่อยใช้งานถูกกว่าการแก้หลังจากมีปัญหาเกิดขึ้นจริงเสมอ
- เพิ่ม tool ใหม่เข้าไปเรื่อย ๆ โดยไม่ทบทวน tool เดิมที่มีอยู่แล้ว — ทำแบบนี้แล้วพัง เพราะยิ่งจำนวน tool เยอะขึ้น โอกาสที่ tool ใหม่จะไปคาบเกี่ยวกับ tool เดิมก็สูงขึ้นตาม ควรทบทวน tool ที่มีอยู่ทุกครั้งก่อนเพิ่มตัวใหม่ว่ามันซ้อนทับกับตัวไหนอยู่หรือไม่
สรุป
การที่ Agent เลือก MCP tool ผิดแทบทุกครั้งมักไม่ได้มาจากโมเดลไม่ฉลาดพอ แต่มาจาก description ที่กำกวม schema ที่กว้างเกินไป และ tool ที่คาบเกี่ยวขอบเขตกันโดยไม่มีการกั้นแนวชัดเจน การแก้ที่ต้นทางของการออกแบบมักได้ผลเสถียรกว่าการไปพึ่งพาความฉลาดของโมเดลเพียงอย่างเดียว
ก่อนปล่อย MCP server ใหม่ทุกครั้ง ควรมีชุดคำถามทดสอบที่ครอบคลุมทุก tool รวมถึงคำถามก้ำกึ่งที่จงใจให้ใกล้เคียงกัน แล้ววัดอัตราความถูกต้องเป็นตัวเลขจริง ไม่ใช่แค่ทดลองถามเองสองสามคำถามแล้วรู้สึกว่าโอเค เพราะสิ่งที่รู้สึกว่าโอเคในการทดสอบไม่กี่ครั้งอาจไม่สะท้อนพฤติกรรมจริงเมื่อผู้ใช้หลากหลายเข้ามาถามคำถามที่คาดไม่ถึง
- Agent ตัดสินใจจาก description และ inputSchema เท่านั้น ไม่ได้อ่านชื่อฟังก์ชันแบบคนเขียนโค้ด
- แยก tool โหมดอ่านกับเขียนออกจากกันเสมอ ลดความเสี่ยงเรียกผิดโหมดที่อันตรายที่สุด
- ทดสอบด้วยชุดคำถามจริงก่อนปล่อยใช้งาน แล้ววัดอัตราถูกต้องเป็นตัวเลข ไม่ใช่ความรู้สึก
- ทบทวน tool เดิมทุกครั้งก่อนเพิ่มตัวใหม่ ว่าคาบเกี่ยวกับตัวไหนอยู่หรือไม่
คำถามที่พบบ่อย
MCP tool ควรมีกี่ตัวต่อ server ถึงจะไม่เยอะเกินไป
ไม่มีตัวเลขตายตัว แต่ในทางปฏิบัติเมื่อจำนวน tool เกิน 15-20 ตัวในบริบทเดียวกัน อัตราการเลือกผิดมักเพิ่มขึ้นชัดเจน ถ้า server มี tool เยอะกว่านี้ควรพิจารณาแบ่งเป็นหลาย server ตามโดเมนงาน หรือใช้กลไกกรอง tool ที่เกี่ยวข้องก่อนส่งให้ Agent เห็นทั้งหมด
ควรเขียน description เป็นภาษาไทยหรือภาษาอังกฤษ
ขึ้นกับโมเดลและภาษาที่ผู้ใช้ปลายทางใช้คุยกับ Agent เป็นหลัก ถ้าผู้ใช้คุยเป็นภาษาไทยเกือบทั้งหมด การเขียน description เป็นภาษาไทยมักช่วยให้จับคู่คำถามกับ tool ได้ตรงกว่า แต่ควรคงชื่อ field และค่า enum เป็นภาษาอังกฤษไว้เพื่อความสม่ำเสมอกับโค้ดฝั่ง backend
ทำไมเพิ่ม example ใน description แล้วช่วยได้มากกว่าที่คิด
เพราะโมเดลภาษามีแนวโน้มจับคู่รูปแบบประโยคคำถามได้ดีกว่าจับคู่จากคำนิยามเชิงนามธรรม ตัวอย่างคำถามที่ใกล้เคียงของจริงจึงเป็นสัญญาณที่แรงกว่าคำอธิบายทั่วไป โดยเฉพาะเมื่อมี tool หลายตัวที่ทำงานใกล้เคียงกันอยู่ในบริบทเดียวกัน
ควรแยก tool ตาม CRUD หรือตามงานที่ผู้ใช้ต้องการ
แยกตามงานที่ผู้ใช้ต้องการเป็นหลัก แล้วค่อยแยกโหมดอ่านกับเขียนออกจากกันเสมอไม่ว่าจะจัดกลุ่มแบบไหน หลักการ CRUD ล้วน ๆ บางครั้งทำให้ tool เยอะเกินความจำเป็นและไม่สอดคล้องกับวิธีที่ผู้ใช้ตั้งคำถามจริง
จำเป็นต้อง versioning tool เหมือน versioning API ไหม
จำเป็นถ้า tool ถูกใช้งานโดยหลายทีมหรือหลาย Agent พร้อมกัน เพราะการเปลี่ยน description หรือ schema แบบ breaking change อาจทำให้ Agent ที่ใช้เวอร์ชันเก่าเลือก tool ผิดไปเลย ควรมีเลขเวอร์ชันหรือชื่อ tool ใหม่เมื่อเปลี่ยนโครงสร้างสำคัญ แทนการแก้ทับตัวเดิมเงียบ ๆ
ถ้า tool สองตัวจำเป็นต้องคาบเกี่ยวกันจริง ๆ แก้ยังไงได้อีกนอกจากเขียน description ไขว้กัน
อีกทางคือใส่ชั้นตัดสินใจไว้ก่อนถึง Agent เช่น router หรือ intent classifier ที่คัดกรองว่าคำถามนี้ควรเห็นเฉพาะ tool กลุ่มไหนก่อนส่งเข้า context จะช่วยลดจำนวน tool ที่คาบเกี่ยวกันที่ Agent ต้องเลือกเองในครั้งเดียว แต่วิธีนี้เพิ่มความซับซ้อนของระบบจึงควรใช้เมื่อวิธีอื่นไม่พอจริง ๆ
อ่านต่อแบบเจาะลึก
วัด Conversion LINE ทุกแบรนด์ รวมศูนย์ที่เดียว
องค์กรที่มีหลายแบรนด์ หลายสาขา หลาย LINE OA — linli รวม Tracking และส่ง Conversion กลับทุกแพลตฟอร์ม พร้อม Custom Limit เริ่มฟรี 14 วัน
ติดต่อทีม Salesบทความที่เกี่ยวข้อง

ทีมงานสามคนที่จัดการเองได้อยู่แล้ว ยังไม่จำเป็นต้องรีบใช้ Subagent

ทำไม Replit Agent 4 ถึงกล้าปล่อยให้ทำงานยาวขึ้นโดยไม่ต้องคอยเช็กทุกก้าว
