สิ่งที่ได้เรียนรู้จากการเขียนเครื่องมือ MCP 50 ตัว: การเรียกฟังก์ชันคือความสัมพันธ์ที่ใกล้ชิดกันผิดปกติ
(evan-moon.github.io)บทความที่สรุปจากประสบการณ์ย้ายเครื่องมือจัดการสินทรัพย์ไปเป็น CLI บนฐาน SQLite และเซิร์ฟเวอร์ MCP ตลอดสองวันสุดสัปดาห์
โดยอธิบายว่าในการออกแบบเครื่องมือ MCP นั้น จุดที่แยกจาก RPC อย่างชัดเจนคืออะไร
ผู้เขียนสร้างคำสั่ง CLI กว่า 30 คำสั่งและเครื่องมือ MCP กว่า 50 ตัว แต่กลับพบว่าสิ่งที่ใช้เวลามากที่สุดไม่ใช่โค้ด
แต่เป็นคำอธิบายของฟังก์ชันต่างหาก จึงเริ่มต้นข้อเขียนจากจุดนั้น
- เมื่อเปิดเผยฟังก์ชันเดียวกันทั้งให้กับ CLI และ MCP พร้อมกัน แม้ซิกเนเจอร์/อาร์กิวเมนต์/ค่าที่ส่งกลับจะเหมือนกันทั้งหมด แต่สองอินเทอร์เฟซกลับทำงานต่างกัน สิ่งที่เปลี่ยนมีเพียงผู้เรียกว่าเป็นมนุษย์หรือ LLM
- ซิกเนเจอร์อธิบายได้ว่าฟังก์ชัน รับอะไร แต่แทบอธิบายไม่ได้ว่า ควรถูกเรียกเมื่อไร ชื่อฟังก์ชันใกล้เคียงกับบรรทัดหนึ่งในพจนานุกรม จึงไม่อาจกำหนดได้ด้วยตัวคำเองว่าจะถูกวางอยู่บนประโยคแบบใด
- สำหรับผู้เรียกที่เป็น LLM เครื่องมือที่ หนักและแตะเจตนาได้โดยตรงกลับเป็นธรรมชาติกว่า เครื่องมือที่แยกย่อยละเอียดตามหลัก Single Responsibility Principle (SRP)
- ถ้ามองแค่รูปแบบ MCP ก็อยู่ในสายตระกูล RPC (JSON-RPC, ซิกเนเจอร์, สคีมา) แต่ความต่างที่ชี้ขาดคือ ทิศทางของความเชื่อใจกลับด้านกัน RPC คือผู้เรียกเชื่อใจเป้าหมายที่ถูกเรียก แต่ MCP คือฝั่งที่สร้างเครื่องมือต้องเชื่อใจผู้เรียก (LLM)
- ซิกเนเจอร์คือคำประกาศ ส่วนคำอธิบายคือคำขอร้อง อย่างหนึ่งคือการบังคับใช้อย่างเคร่งครัด อีกอย่างคือการโน้มน้าว เท่ากับว่าภาษาแบบโน้มน้าวได้เริ่มเข้ามาอยู่ในการออกแบบเครื่องมือแล้ว
- นี่อาจไม่ใช่การเปลี่ยนแปลงใหม่เสียทีเดียว แต่ ใกล้เคียงกับการย้อนกลับมากกว่า เพราะงานออกแบบอุตสาหกรรม สถาปัตยกรรม และ UX ต่างอยู่ในจุดนี้มานานแล้ว มีเพียงการเขียนโปรแกรมที่ก่อนหน้านี้เคยอยู่ตรงปลายด้านหนึ่งของความใกล้ชิดเป็นพิเศษ
สิ่งที่ซิกเนเจอร์ไม่ได้บอก
add_txn(ธุรกรรม),add_balance(สแนปช็อตสินทรัพย์),add_flow(รายรับ/รายจ่าย) ของ Firma ต่างก็มีซิกเนเจอร์ชัดเจนและชนิดของอาร์กิวเมนต์ก็ นิยามอย่างเข้มงวดด้วย zod schema แต่ LLM ก็ยังสับสนบ่อยครั้งว่าควรเรียกเครื่องมือใดจากคำพูดของผู้ใช้- ตอนแรกผู้เขียนสงสัยว่าเป็นปัญหาของโมเดล LLM แต่ปัญหาที่แท้จริงอยู่ที่ตัวซิกเนเจอร์เอง ชื่ออย่าง
add_txnไม่ได้บรรจุจังหวะการเรียกในความหมายว่า "ถ้าผู้ใช้พูดถึงการซื้อขาย ให้ใช้เครื่องมือนี้" เอาไว้ - กว่าการเรียกจะเสถียร ก็หลังจากใส่ description ในรูปแบบ "Use this when... Do NOT use this for..." เพื่อระบุจังหวะการเรียกและขอบเขตที่ต่างจากเครื่องมืออื่นอย่างชัดเจน
- นั่นคือเจตนาของฟังก์ชัน ได้เคลื่อนจากซิกเนเจอร์ไปอยู่ที่คำอธิบายของฟังก์ชัน เหมือนด้ามค้อนที่บอกใบ้ว่าควรใช้อย่างไรผ่านรูปทรง คำอธิบายของฟังก์ชัน MCP จึงแทบจะเทียบได้กับ affordance ของเครื่องมือสำหรับ LLM (Donald Norman)
SRP vs affordance และทิศทางของความเชื่อใจ
- ตอนแรกตั้งใจจะแยกย่อยตามหลัก Single Responsibility Principle เป็น
get_holdings,get_prices,get_pnlแต่เมื่อผู้ใช้ถามว่า "พอร์ตของฉันเป็นยังไงบ้าง?" LLM ต้องประกอบการเรียก 4-5 ครั้ง ทำให้ตอบช้าและมีโอกาสคลาดเคลื่อนมากขึ้น - สุดท้ายจึงออกแบบ
show_portfolioให้เป็น เครื่องมือแบบหนักที่คืนผลถือครอง/ต้นทุนเฉลี่ย/ราคาปัจจุบัน/มูลค่าประเมิน/กำไรขาดทุนสะสมในครั้งเดียว ส่วนget_briefไปไกลกว่านั้นอีกโดยคืนทั้งตัวชี้วัดมหภาคและอินไซต์พร้อมกัน - SRP คือคุณธรรมของคนที่สร้างฟังก์ชัน ส่วน affordance คือคุณธรรมของคนที่ใช้เครื่องมือ ถ้าผู้เรียกเป็นมนุษย์ก็ประกอบเองได้ แต่ถ้าเป็น LLM เครื่องมือที่แตะเจตนาโดยตรงจะดีกว่า
- ในเครื่องมือฝั่งเขียน ทิศทางของความเชื่อใจแสดงออกชัดที่สุด เมื่อใส่ไว้ใน
add_txnว่า "Always confirm with the user before recording" LLM ก็ถามทุกครั้ง และผู้ใช้ก็ต้องตอบ "โอเค" ทุกครั้ง — ข้อดีของอินเทอร์เฟซภาษาธรรมชาติจึงหายไป - สุดท้ายจึงแบ่งความรับผิดชอบใหม่เป็น "ให้บันทึกทันที ถ้าคลุมเครือค่อยถาม ถ้าผิดก็ย้อนกลับได้" คำชี้นำแบบนี้ไม่ใช่คำอธิบายเชิงรูปแบบของเครื่องมือ แต่เป็น หลักการปฏิบัติการที่มอบให้ผู้เรียก
เป็นไปได้ว่าการเรียกฟังก์ชันต่างหากที่เป็นกรณีพิเศษ
- เดิมทีมานุษย์ก็ใช้เครื่องมือที่ตัวเองไม่ได้สร้างอยู่แล้ว ไม่ว่าจะเป็นชามที่ช่างปั้นทำ มีดที่ช่างตีเหล็กทำ หรือโปรแกรมที่นักพัฒนาสร้างขึ้น ก็ล้วนเป็นแบบนั้น
- การเรียกฟังก์ชันจึงอาจเป็น ความสัมพันธ์ที่ค่อนข้างพิเศษ ที่ผู้เรียกและผู้เขียนแบ่งปันบริบทร่วมกันมาก และมี type system/IDE/เอกสารคอยเสริมความใกล้ชิดนั้นอยู่ตลอด
- ถ้าผู้เรียกไม่ใช่มนุษย์ ก็มีสองทางเลือก: (1) ใส่บริบทให้ LLM มากขึ้นเพื่อทำให้เป็นผู้เรียกที่ใกล้ชิดกว่าเดิม, (2) ให้ฝั่งเครื่องมือเป็นผู้เติมช่องว่างของระยะห่างนั้น MCP ใกล้เคียงกับแบบหลังมากกว่า
- อาจเป็นช่วงเวลาที่วิธีออกแบบอินเทอร์เฟซกำลังเปลี่ยนไปอย่างเงียบ ๆ จากซิกเนเจอร์ไปสู่คำอธิบาย จากการบังคับไปสู่การโน้มน้าว จากการสมมติว่ามีความใกล้ชิดไปสู่การยอมรับว่ามีระยะห่าง
ยังไม่มีความคิดเห็น