ทำไม LLM ตอบถูกในแชทแต่พอเชื่อมระบบจริงกลับเรียกฟังก์ชันผิดพารามิเตอร์

สรุปสั้น ๆ
Tool Calling คือกลไกที่ให้โมเดลภาษาตัดสินใจเองว่าควรเรียกใช้ฟังก์ชัน (Tool) ใดจากรายการที่นักพัฒนากำหนดไว้ พร้อมสร้าง Parameter ให้ตรงตาม Schema ของฟังก์ชันนั้น จากนั้นระบบฝั่งแอปพลิเคชันจะเป็นผู้รันฟังก์ชันจริงแล้วส่งผลลัพธ์กลับให้โมเดลใช้ตอบต่อ ความผิดพลาดเรื่อง Parameter มักเกิดจากคำอธิบายเครื่องมือที่กำกวมหรือมีเครื่องมือให้เลือกมากเกินไปในคราวเดียว
ทีมพัฒนาจำนวนมากเริ่มต้นทดสอบ Tool Calling ด้วยตัวอย่างง่าย ๆ เช่น ฟังก์ชันเช็คสภาพอากาศ หรือฟังก์ชันคำนวณเลข แล้วรู้สึกประทับใจที่โมเดลเลือกเรียกถูกต้องแทบทุกครั้ง แต่พอย้ายไปใช้กับระบบจริงที่มีฟังก์ชันหลายสิบตัว แต่ละตัวมี Parameter ซับซ้อนกว่าเดิม กลับเจอปัญหาที่ไม่คาดคิด โมเดลเรียกฟังก์ชันถูกตัวแต่ใส่ Parameter ผิด หรือเลือกฟังก์ชันผิดตัวทั้งที่คำถามดูชัดเจนในสายตาคน
ปรากฏการณ์นี้ไม่ใช่เรื่องแปลก เพราะ Tool Calling ไม่ได้ทำงานด้วยการ 'เข้าใจ' ความหมายของฟังก์ชันแบบที่มนุษย์เข้าใจ แต่เป็นการอาศัยคำอธิบาย (Description) ที่นักพัฒนาเขียนไว้ในตอนลงทะเบียนฟังก์ชัน มาเทียบกับคำถามของผู้ใช้ แล้วเลือกฟังก์ชันที่น่าจะตรงที่สุดตามความน่าจะเป็น ถ้าคำอธิบายไม่ชัดหรือฟังก์ชันสองตัวมีหน้าที่คาบเกี่ยวกัน โอกาสเลือกผิดก็สูงขึ้นทันที
บทความนี้จะอธิบายว่า Tool Calling ทำงานอย่างไรตั้งแต่ต้นจนจบ อะไรที่ทำให้ระบบเรียกฟังก์ชันผิดพลาด และมีแนวทางออกแบบอย่างไรให้ความแม่นยำสูงขึ้นเมื่อจำนวนเครื่องมือในระบบเพิ่มขึ้นเรื่อย ๆ
Tool Calling ทำงานเป็นขั้นตอนอย่างไรกันแน่
กระบวนการเริ่มจากนักพัฒนาลงทะเบียนรายการฟังก์ชันที่มีให้โมเดลเลือกใช้ แต่ละฟังก์ชันประกอบด้วยชื่อ คำอธิบายว่าใช้ทำอะไร และ Schema ของ Parameter ที่ต้องส่งเข้าไป เมื่อผู้ใช้ถามคำถาม โมเดลจะพิจารณาว่าคำถามนี้ต้องใช้ข้อมูลหรือการกระทำที่มันตอบเองไม่ได้หรือไม่ ถ้าใช่ มันจะเลือกฟังก์ชันที่เหมาะสมและสร้าง Parameter ตาม Schema ที่กำหนด
จุดสำคัญคือโมเดลไม่ได้รันฟังก์ชันเอง มันเพียงส่งคำขอกลับมาในรูปแบบ Structured Output ที่ระบุชื่อฟังก์ชันและ Parameter เท่านั้น แอปพลิเคชันฝั่งนักพัฒนาต้องเป็นผู้อ่านคำขอนี้ รันฟังก์ชันจริงเอง แล้วนำผลลัพธ์ที่ได้ส่งกลับเข้าไปในบทสนทนาให้โมเดลใช้สร้างคำตอบสุดท้าย ขั้นตอนนี้ทำให้ Tool Calling ปลอดภัยกว่าที่คิด เพราะมีจุดที่นักพัฒนาควบคุมได้ก่อนรันจริงเสมอ
วงจรนี้อาจเกิดซ้ำหลายรอบในคำถามเดียว เช่น โมเดลเรียกฟังก์ชันค้นหาลูกค้าก่อน ได้ผลลัพธ์มาแล้วพบว่าต้องเรียกฟังก์ชันดึงประวัติคำสั่งซื้อต่อ จึงเรียกอีกครั้งก่อนสรุปคำตอบให้ผู้ใช้ กระบวนการวนซ้ำแบบนี้คือรากฐานของสิ่งที่หลายคนเรียกว่า AI Agent
ทำไมโมเดลถึงใส่ Parameter ผิด ทั้งที่คำถามดูชัดเจน
สาเหตุที่พบบ่อยที่สุดคือคำอธิบายฟังก์ชัน (Description) เขียนกำกวมหรือสั้นเกินไป เช่น ฟังก์ชันชื่อ `search_order` มีคำอธิบายแค่ 'ค้นหาคำสั่งซื้อ' โดยไม่บอกว่ารับ Parameter เป็นเลขที่ออเดอร์หรือชื่อลูกค้า โมเดลจึงต้องเดาจากชื่อ Field เอง ซึ่งบางครั้งเดาผิด
อีกสาเหตุคือความกำกวมของคำถามผู้ใช้เองที่ถูกส่งผ่านมาโดยไม่มีบริบทเพียงพอ เช่น ผู้ใช้พิมพ์ว่า 'เช็คออเดอร์ล่าสุดให้หน่อย' โดยไม่ระบุว่าลูกค้าคนไหน ถ้าระบบไม่ได้ส่ง Context ของผู้ใช้ที่ล็อกอินอยู่เข้าไปด้วย โมเดลอาจเดา Parameter จากข้อความก่อนหน้าในบทสนทนาซึ่งอาจไม่ตรงกับที่ตั้งใจ
สาเหตุที่สามคือจำนวนฟังก์ชันที่ให้เลือกมากเกินไปในคราวเดียว ยิ่งมีฟังก์ชันเยอะและบางตัวมีหน้าที่คาบเกี่ยวกัน โมเดลยิ่งมีโอกาสเลือกฟังก์ชันผิดตัวสูงขึ้น เพราะต้องเทียบความน่าจะเป็นระหว่างตัวเลือกที่ใกล้เคียงกันมากในคราวเดียว
Tool Calling, Function Calling และ MCP ต่างกันตรงไหน
หลายคนใช้คำว่า Tool Calling กับ Function Calling สลับกันได้ เพราะโดยแนวคิดเป็นเรื่องเดียวกันคือการให้โมเดลเลือกเรียกความสามารถที่นักพัฒนาลงทะเบียนไว้ ต่างกันแค่คำศัพท์ที่แต่ละ Provider เลือกใช้ในเอกสารของตัวเอง
ส่วน MCP (Model Context Protocol) เป็นอีกชั้นหนึ่งที่มาตรฐานวิธีที่แอปพลิเคชันเชื่อมต่อกับแหล่งข้อมูลและเครื่องมือภายนอก แทนที่แต่ละทีมต้องเขียน Integration เฉพาะของตัวเอง MCP ช่วยให้ Tool ที่สร้างไว้ครั้งเดียวใช้ร่วมกับ AI Client หลายตัวได้ โดยยังอาศัยกลไก Tool Calling เป็นพื้นฐานเดียวกันอยู่ดี
| แนวคิด | หน้าที่หลัก | ระดับที่ทำงาน |
|---|---|---|
| Tool Calling / Function Calling | ให้โมเดลเลือกเรียกฟังก์ชันพร้อม Parameter | ระดับการตัดสินใจของโมเดลต่อคำขอเดียว |
| MCP (Model Context Protocol) | มาตรฐานการเชื่อมต่อ Tool/Data Source ให้ AI Client ใช้ร่วมกัน | ระดับ Infrastructure ที่ Tool ถูกลงทะเบียนและแชร์ |
| AI Agent | วนเรียก Tool หลายรอบเพื่อบรรลุเป้าหมายที่ซับซ้อน | ระดับ Workflow ที่ประกอบด้วยหลาย Tool Call |
ออกแบบชุดเครื่องมือ (Tools) อย่างไรให้โมเดลเลือกถูกมากขึ้น
- ตั้งชื่อฟังก์ชันให้สื่อความหมายชัดและไม่คลุมกับฟังก์ชันอื่น เช่น แยก `search_order_by_id` กับ `search_order_by_customer` แทนที่จะรวมเป็นฟังก์ชันเดียวที่มี Parameter เลือกโหมด
- เขียนคำอธิบายให้ระบุทั้งหน้าที่และเงื่อนไขการใช้งาน เช่น 'ใช้เมื่อผู้ใช้ระบุเลขที่ออเดอร์ชัดเจนเท่านั้น หากไม่มีเลขที่ ให้ถามผู้ใช้ก่อนเรียกฟังก์ชันนี้'
- จำกัดจำนวนฟังก์ชันที่ส่งให้โมเดลเลือกในแต่ละ Request ให้เหลือเฉพาะที่เกี่ยวข้องกับบริบทนั้นจริง แทนที่จะส่งฟังก์ชันทั้งหมดในระบบทุกครั้ง โดยอาจใช้ Layer คัดกรองก่อนว่าโจทย์นี้น่าจะเกี่ยวกับหมวดไหน
- กำหนด Parameter ที่จำเป็นเป็น Required และใส่ Enum เมื่อค่าที่ยอมรับมีจำกัด เพื่อลดโอกาสที่โมเดลจะสร้างค่าที่ระบบปลายทางไม่รองรับ
- ทดสอบด้วยคำถามกำกวมจงใจ เพื่อดูว่าโมเดลเลือกฟังก์ชันถูกไหมเมื่อข้อมูลไม่ครบ และตรวจว่ามันถามกลับผู้ใช้เพื่อขอข้อมูลเพิ่มก่อนเรียกฟังก์ชันหรือไม่ ซึ่งเป็นพฤติกรรมที่ควรออกแบบให้เกิดขึ้นเมื่อ Parameter สำคัญขาดหาย
ความเสี่ยงเมื่อ Tool Calling เชื่อมกับการกระทำที่แก้ไขข้อมูลจริง
ฟังก์ชันที่ใช้เพียงดึงข้อมูลมาแสดง (Read-only) มีความเสี่ยงต่ำ เพราะต่อให้โมเดลเลือกผิดหรือ Parameter คลาดเคลื่อน ผลกระทบมากสุดคือได้ข้อมูลผิดมาแสดง แต่ฟังก์ชันที่แก้ไขข้อมูลจริง เช่น ยกเลิกคำสั่งซื้อ คืนเงิน หรือลบข้อมูลผู้ใช้ ความเสี่ยงสูงกว่ามาก เพราะการเรียกผิดพลาดหนึ่งครั้งอาจสร้างความเสียหายที่แก้คืนได้ยาก
แนวทางที่ทีมพัฒนาที่มีประสบการณ์มักใช้คือแบ่งฟังก์ชันเป็นระดับความเสี่ยง ฟังก์ชัน Read-only ให้โมเดลเรียกได้อัตโนมัติ ส่วนฟังก์ชันที่แก้ไขหรือลบข้อมูล ต้องผ่านจุดอนุมัติจากคนก่อนรันจริงเสมอ ไม่ว่าโมเดลจะมั่นใจแค่ไหนก็ตาม แนวคิดนี้เชื่อมโยงโดยตรงกับหลักการ Human in the Loop ที่อธิบายไว้ใน บทความเรื่องจุดที่ควรให้คนเข้ามาอนุมัติ AI Agent
นอกจากนี้ควรมี Log บันทึกทุกครั้งที่มีการเรียก Tool ที่แก้ไขข้อมูล พร้อม Parameter ที่ใช้และผลลัพธ์ที่เกิดขึ้น เพื่อให้ตรวจสอบย้อนหลังได้เมื่อเกิดปัญหา และเพื่อใช้เป็นข้อมูลปรับปรุงคำอธิบายฟังก์ชันให้แม่นยำขึ้นในรอบถัดไป
เจอบ่อยหน้างาน: อาการพังของ Tool Calling ที่ควรรู้ก่อน
ต่อไปนี้เป็นอาการที่ทีมพัฒนาระบบ Tool Calling มักเจอเมื่อระบบมีฟังก์ชันมากขึ้นและซับซ้อนขึ้น (ตัวอย่างสมมติประกอบกรอบวิเคราะห์ ไม่ใช่สถิติจริง) ควรใช้เป็นรายการตรวจสอบก่อนปล่อยฟีเจอร์ใหม่ที่พึ่ง Tool Calling ขึ้น Production
- ทำแบบนี้แล้วพัง เพราะให้โมเดลเข้าถึงฟังก์ชันแก้ไขข้อมูลโดยไม่มีจุดอนุมัติ พอ Parameter คลาดเคลื่อนเพียงครั้งเดียว ข้อมูลจริงถูกแก้ไปแล้วโดยไม่มีใครรู้จนลูกค้าแจ้งเข้ามา
- ทำแบบนี้แล้วพัง เพราะฟังก์ชันสองตัวมีคำอธิบายคล้ายกันเกินไป เช่น `get_customer_info` กับ `get_customer_profile` โมเดลสลับเรียกผิดตัวเป็นระยะ ทั้งที่ทั้งสองฟังก์ชันทำงานถูกต้องแยกกันตามที่ออกแบบ
- ทำแบบนี้แล้วพัง เพราะไม่ได้ Validate ผลลัพธ์ที่ Tool ส่งกลับก่อนให้โมเดลใช้ตอบต่อ เมื่อ API ภายนอกตอบ Error หรือ Timeout โมเดลบางครั้งยังพยายามสร้างคำตอบจากข้อมูลที่ไม่สมบูรณ์แทนที่จะแจ้งผู้ใช้ตรง ๆ ว่าดึงข้อมูลไม่สำเร็จ
- ทำแบบนี้แล้วพัง เพราะเพิ่มฟังก์ชันใหม่เข้าไปเรื่อย ๆ โดยไม่เคยทบทวนรายการเดิม จนระบบมีฟังก์ชันซ้ำซ้อนหรือล้าสมัยปนอยู่ ทำให้ความแม่นยำของการเลือกฟังก์ชันโดยรวมลดลงตามจำนวนตัวเลือกที่เพิ่มขึ้น
ตรวจสอบและปรับปรุงความแม่นยำของ Tool Calling อย่างต่อเนื่อง
ระบบ Tool Calling ไม่ใช่สิ่งที่ตั้งค่าครั้งเดียวแล้วจบ ความแม่นยำเปลี่ยนได้ตามจำนวนฟังก์ชันที่เพิ่มขึ้น พฤติกรรมผู้ใช้ที่เปลี่ยนไป และแม้แต่เมื่อ Provider อัปเดตเวอร์ชันโมเดลที่ใช้อยู่ ทีมที่ดูแลระบบนี้จริงจังจึงควรมีการเก็บ Log การเรียก Tool ทุกครั้งไว้วิเคราะห์
ข้อมูลที่ควรเก็บอย่างน้อยคือ ฟังก์ชันที่ถูกเรียก Parameter ที่ใช้ ผลลัพธ์ที่ได้ และว่าผู้ใช้ต้องแก้ไขหรือถามซ้ำหลังจากนั้นหรือไม่ ถ้าพบรูปแบบว่าฟังก์ชันใดถูกเรียกผิดบ่อยเป็นพิเศษ นั่นคือสัญญาณว่าคำอธิบายฟังก์ชันนั้นต้องปรับปรุง หรืออาจต้องแยกเป็นฟังก์ชันย่อยให้ขอบเขตชัดขึ้น
อีกแนวทางที่ช่วยได้คือทำ Evaluation Set เก็บชุดคำถามตัวอย่างพร้อมคำตอบที่ถูกต้องว่าควรเรียกฟังก์ชันไหนด้วย Parameter อะไร แล้วรันทดสอบทุกครั้งที่มีการแก้ไข Prompt เพิ่มฟังก์ชันใหม่ หรือเปลี่ยนเวอร์ชันโมเดล เพื่อจับความเปลี่ยนแปลงของความแม่นยำก่อนที่ผู้ใช้จริงจะเจอปัญหา
ออกแบบเส้นทาง Error Handling เมื่อ Tool ที่เรียกล้มเหลว
หลายทีมออกแบบเฉพาะเส้นทางที่ Tool ทำงานสำเร็จ แต่ไม่ได้เตรียมเส้นทางไว้เมื่อฟังก์ชันที่เรียกล้มเหลว เช่น API ภายนอกตอบ 500, การเชื่อมต่อฐานข้อมูลหลุดชั่วคราว หรือฟังก์ชันคืนค่าว่างเปล่าเพราะไม่พบข้อมูลตามเงื่อนไขที่ค้นหา ถ้าไม่มีการจัดการชัดเจน โมเดลอาจนำ Error Message ดิบไปแสดงตรง ๆ ให้ผู้ใช้เห็น หรือแย่กว่านั้นคือพยายาม 'เดา' คำตอบต่อทั้งที่ไม่มีข้อมูลจริงรองรับ
แนวทางที่ควรทำคือกำหนดรูปแบบผลลัพธ์ของ Tool ให้มีทั้งกรณีสำเร็จและกรณีล้มเหลวอย่างชัดเจนใน Schema เอง เช่น มี Field `status` และ `error_reason` เสมอ เพื่อให้โมเดลรู้ว่าควรตอบผู้ใช้แบบไหนเมื่อเจอความล้มเหลว แทนที่จะปล่อยให้โมเดลตีความ Error แบบอิสระซึ่งมีโอกาสตอบผิดทางได้ง่าย
สำหรับฟังก์ชันที่เรียกภายนอกระบบ (External API) ควรมี Timeout และ Retry Policy ที่ชัดเจนในระดับโค้ด ไม่ใช่ปล่อยให้บทสนทนาค้างรอจนผู้ใช้หมดความอดทน และถ้าระบบพึ่งพา Tool หลายตัวจากผู้ให้บริการต่างกัน ควรมีแผนสำรองเมื่อผู้ให้บริการรายใดรายหนึ่งช้าหรือ Error บ่อยผิดปกติ ซึ่งเป็นแนวคิดเดียวกับการวาง Fallback Strategy ที่อธิบายไว้ใน บทความเรื่องออกแบบ LLM Fallback Strategy
สรุป
Tool Calling เปลี่ยน LLM จากผู้ตอบคำถามด้วยความรู้ที่มีอยู่แล้วในตัวโมเดล ให้กลายเป็นระบบที่ดึงข้อมูลสดหรือลงมือทำสิ่งต่าง ๆ ผ่านฟังก์ชันที่นักพัฒนากำหนดได้ แต่ความแม่นยำของกลไกนี้ขึ้นอยู่กับคุณภาพของการออกแบบฟังก์ชันและคำอธิบายมากพอ ๆ กับความสามารถของโมเดลเอง
ทีมที่นำ Tool Calling ไปใช้จริงควรแยกระดับความเสี่ยงของแต่ละฟังก์ชันชัดเจน วางจุดอนุมัติสำหรับฟังก์ชันที่แก้ไขข้อมูล และติดตามความแม่นยำอย่างต่อเนื่องผ่าน Log และ Evaluation Set แทนที่จะเชื่อว่าระบบที่ทดสอบผ่านตอนแรกจะแม่นยำตลอดไปโดยไม่ต้องดูแล
- Tool Calling คือกลไกให้โมเดลเลือกเรียกฟังก์ชันพร้อม Parameter แต่การรันจริงยังอยู่ในมือแอปพลิเคชันเสมอ
- ความผิดพลาดส่วนใหญ่มาจากคำอธิบายฟังก์ชันกำกวมหรือมีฟังก์ชันคาบเกี่ยวกันมากเกินไป ไม่ใช่ตัวโมเดลเอง
- ฟังก์ชันที่แก้ไขข้อมูลจริงควรมีจุดอนุมัติจากคนเสมอ ต่างจากฟังก์ชัน Read-only ที่ปล่อยอัตโนมัติได้
คำถามที่พบบ่อย
Tool Calling กับ Function Calling ต่างกันไหม
โดยแนวคิดเป็นเรื่องเดียวกัน คือการให้โมเดลเลือกเรียกความสามารถที่นักพัฒนาลงทะเบียนไว้พร้อม Parameter ต่างกันแค่คำศัพท์ที่ Provider แต่ละเจ้าเลือกใช้ในเอกสารของตัวเอง
โมเดลรันฟังก์ชันเองเลยหรือแค่บอกว่าจะเรียกอะไร
โมเดลไม่ได้รันฟังก์ชันเอง มันเพียงส่งคำขอกลับมาว่าอยากเรียกฟังก์ชันใดพร้อม Parameter อะไร แอปพลิเคชันฝั่งนักพัฒนาเป็นผู้ตัดสินใจรันฟังก์ชันจริงและส่งผลลัพธ์กลับเข้าไปในบทสนทนา
ควรมีฟังก์ชันให้โมเดลเลือกได้กี่ตัวถึงจะเหมาะสม
ไม่มีตัวเลขตายตัว แต่หลักการคือยิ่งมีน้อยและแต่ละตัวขอบเขตชัดเจน ยิ่งแม่นยำ ถ้าระบบมีฟังก์ชันจำนวนมาก ควรกรองให้เหลือเฉพาะที่เกี่ยวข้องกับบริบทนั้นก่อนส่งให้โมเดลเลือก แทนที่จะส่งทั้งหมดทุกครั้ง
ฟังก์ชันที่แก้ไขข้อมูลจริงควรให้โมเดลเรียกอัตโนมัติไหม
ควรระวังเป็นพิเศษ ฟังก์ชันที่แก้ไขหรือลบข้อมูลจริงควรมีจุดอนุมัติจากคนก่อนรันเสมอ ต่างจากฟังก์ชันดึงข้อมูลอย่างเดียวที่ความเสี่ยงต่ำกว่าและมักปล่อยให้เรียกอัตโนมัติได้
ทำไมโมเดลบางครั้งไม่เรียก Tool เลยทั้งที่ควรเรียก
มักเกิดจากคำอธิบายฟังก์ชันไม่ครอบคลุมสถานการณ์ที่ผู้ใช้ถาม หรือคำถามของผู้ใช้ไม่ได้ให้สัญญาณชัดพอว่าต้องพึ่งข้อมูลภายนอก การปรับคำอธิบายให้ครอบคลุมเงื่อนไขการใช้งานมากขึ้นมักช่วยแก้ปัญหานี้ได้
MCP จำเป็นต่อการทำ Tool Calling ไหม
ไม่จำเป็น ระบบสามารถทำ Tool Calling แบบผูก Integration เฉพาะของตัวเองได้โดยไม่ต้องใช้ MCP แต่ MCP ช่วยให้ Tool ที่สร้างไว้นำไปใช้ร่วมกับ AI Client หลายตัวได้ง่ายขึ้นโดยไม่ต้องเขียน Integration ซ้ำในแต่ละที่
อ่านต่อแบบเจาะลึก
ทดลองวัดผลโฆษณาเข้า LINE ฟรี 14 วัน
สมัครแล้วสร้างโปรเจกต์ เชื่อม LINE ติดตั้ง Tracking แล้วเริ่มเห็น Funnel จาก Click ถึง Purchase ได้ทันที ไม่ต้องใช้บัตรเครดิต
เริ่มทดลองใช้ฟรี 14 วันบทความที่เกี่ยวข้อง

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

ทีมขนาดไหนที่ควรเริ่มทำ AI Cost Optimization และทีมไหนที่ยังไม่ต้องรีบ
