Declarative API จะเปลี่ยนรูปแบบองค์ประกอบ <form> ของ HTML มาตรฐานให้เป็นเครื่องมือ WebMCP ผ่านแอตทริบิวต์ เบราว์เซอร์จะสังเคราะห์สคีมา JSON จากอินพุตของแบบฟอร์มและจัดการการโต้ตอบของ Agent
Angular Signal Forms: อย่าเพิ่ม toolname/tooldescription ลงในแบบฟอร์มที่สร้างด้วย form() จาก @angular/forms/signals แต่ให้เพิ่ม provideExperimentalWebMcpForms() ไปยังผู้ให้บริการแอปและส่งตัวเลือก experimentalWebMcpTool: { name, description } ไปยัง form() แทน จากนั้น Angular จะลงทะเบียนแบบฟอร์มผ่าน Imperative API โดยสร้างสคีมาจากโมเดลสัญญาณและเชื่อมโยงกับการตรวจสอบและการส่ง การใช้ทั้ง 2 แนวทางจะลงทะเบียนแบบฟอร์มเดียวกัน 2 ครั้ง
แอตทริบิวต์ของแบบฟอร์ม
toolname: ชื่อที่ไม่ซ้ำกันสำหรับเครื่องมือtooldescription: สิ่งที่เครื่องมือทำและกรณีที่ Agent ควรใช้เครื่องมือ อย่าระบุช่อง ตัวเลือก หรือขีดจำกัดของแบบฟอร์ม เนื่องจากเบราว์เซอร์ได้รวมข้อมูลเหล่านี้ไว้ในสคีมาที่สร้างจากการควบคุมแบบฟอร์มแล้วtoolautosubmit: (ไม่บังคับ) หากมี ตัวแทนจะส่งแบบฟอร์มได้โดยไม่ต้องรอการโต้ตอบของผู้ใช้toolparamdescription: (ไม่บังคับ) ช่วยให้กำหนดคำอธิบายพร็อพเพอร์ตี้ภายในสคีมา JSON ได้ ใช้เพื่ออธิบายความหมายของค่า (เช่น ด้วยค่าตัวอย่าง) ไม่ใช่เพื่ออธิบายตัวเลือกหรือขีดจำกัดของตัวควบคุมซ้ำ- ลำดับการแก้ไข: เบราว์เซอร์จะใช้
toolparamdescriptionหากมี หากไม่มี ระบบจะใช้textContentของ<label>ที่เชื่อมโยง (ข้ามองค์ประกอบสืบทอดที่ติดป้ายกำกับได้) หากไม่มีป้ายกำกับ ระบบจะกลับไปใช้aria-description - การจัดกลุ่ม (Fieldset): หากต้องการแนบคำอธิบายกับกลุ่มองค์ประกอบที่เกี่ยวข้อง (เช่น ปุ่ม
<input type="radio">) ให้วางtoolparamdescriptionไว้ในองค์ประกอบ<fieldset>ระดับบนสุดที่ใกล้ที่สุดเพื่อให้มีผลกับกลุ่มพารามิเตอร์โดยรวม
- ลำดับการแก้ไข: เบราว์เซอร์จะใช้
ตัวอย่าง
<form toolname="search-cars"
tooldescription="Perform a car make/model search"
toolautosubmit>
<label for="make">Vehicle Make</label>
<input type="text" id="make" name="make" required>
<label for="model">Vehicle Model</label>
<input type="text" id="model" name="model" toolparamdescription="e.g., 330i, F-150" required>
<button type="submit">Search</button>
</form>
การจัดการการส่งใน JavaScript
เมื่อตัวแทนส่งแบบฟอร์ม SubmitEvent จะมี agentInvoked (บูลีน) และ respondWith(promise)
document.querySelector('form').addEventListener('submit', (event) => {
event.preventDefault();
// Validate the form
const formValidationErrors = myFormIsValid();
if (formValidationErrors.length > 0) {
if (event.agentInvoked) {
const errorString =
'Validation failed: ' +
formValidationErrors
.map((err) => `${err.field} (${err.message})`)
.join(', ');
event.respondWith(Promise.resolve(errorString));
}
return;
}
const resultPromise = performAsyncSearch(new FormData(event.target));
// Return the result directly to the agent without navigation
if (event.agentInvoked) {
event.respondWith(resultPromise);
}
});
เหตุการณ์ในวงจร
document.modelContext จะส่งเหตุการณ์เมื่อ Agent เริ่มหรือหยุดโต้ตอบกับเครื่องมือ โดย toolactivated จะเริ่มทำงานเมื่อการเรียกใช้เครื่องมือเริ่มต้น และ toolcancel จะเริ่มทำงานเมื่อมีการยกเลิก
// Starting in Chrome 156, these events are dispatched on `document.modelContext`.
// Older versions dispatch them on `window`. Feature-detect the event handler
// property to pick the right target for backward compatibility.
const targetFor = (type, listener, options) =>
(`on${type}` in (document.modelContext ?? {}) ? document.modelContext : window)
.addEventListener(type, listener, options);
targetFor('toolactivated', ({ toolName }) => {
console.log(`Tool "${toolName}" started execution.`);
});
targetFor('toolcancel', ({ toolName }) => {
console.log(`Tool "${toolName}" execution is cancelled.`);
});
การตอบสนองด้วยภาพ (CSS)
ใช้คลาสจำลองเพื่อไฮไลต์แบบฟอร์มเมื่อตัวแทนโต้ตอบกับแบบฟอร์ม
:tool-form-active: ใช้กับองค์ประกอบ<form>ที่ Agent ใช้งานอยู่:tool-submit-active: ใช้กับปุ่มส่งเมื่อเบราว์เซอร์หยุดชั่วคราวเพื่อให้ผู้ใช้ตรวจสอบ (หากละเว้นtoolautosubmit)
form:tool-form-active {
outline: 2px dashed blue;
background-color: rgba(0, 0, 255, 0.05);
}
button:tool-submit-active {
outline: 2px dashed red;
animation: pulse 2s infinite;
}
ความเหมาะสมของแบบฟอร์ม (กรณีที่ควรหลีกเลี่ยง)
Declarative API เหมาะที่สุดสำหรับแบบฟอร์มมาตรฐานที่สมบูรณ์ในตัว แต่ไม่เหมาะสำหรับสถานการณ์ต่อไปนี้
- ช่องที่ขึ้นอยู่กับข้อมูลอื่นอย่างมาก: แบบฟอร์มที่ข้อมูลที่ป้อนจะเปลี่ยนตัวเลือกหรือระดับการเข้าถึงตามข้อมูลที่ป้อนอื่นๆ สคีมาที่สังเคราะห์ขึ้นไม่สามารถแสดงความสัมพันธ์เหล่านี้ได้ดีนัก
- คอมโพเนนต์ UI ที่กำหนดเอง: แบบฟอร์มที่อาศัยอินพุตที่ไม่ได้มาตรฐาน (เช่น Canvas, เครื่องมือแก้ไข Rich Text) ซึ่งไม่ได้จัดเรียงค่าเป็นอนุกรมโดยอัตโนมัติ
- วิซาร์ดแบบหลายขั้นตอน: เวิร์กโฟลว์ที่ซับซ้อนซึ่งต้องส่งแบบฟอร์มหลายรายการ Imperative API หรือการโต้ตอบ DOM มาตรฐานเหมาะกับกรณีนี้มากกว่า
กรณีที่ควรใช้ toolautosubmit
- การดำเนินการและการค้นหาแบบอ่านอย่างเดียว: การค้นหา การกรอง การดึงข้อมูลรายละเอียด หรือการตรวจสอบสถานะ (เช่น การค้นหารุ่นรถ การค้นหาไดเรกทอรี การตรวจสอบความพร้อมจำหน่ายของสินค้าคงคลัง)
- การดำเนินการที่มีความเสี่ยงต่ำและย้อนกลับได้: การดำเนินการในแบบฟอร์มที่ผู้ใช้สามารถยกเลิกหรือปรับแต่งด้วยตนเองได้ง่ายๆ (เช่น การเพิ่มสินค้าลงในรถเข็น การใช้รหัสคูปอง การบันทึกฉบับร่าง หรือการตั้งค่าตัวเลือกเลย์เอาต์ชั่วคราว)
กรณีที่ควรละเว้น toolautosubmit
- การดำเนินการที่ทำลายหรือย้อนกลับไม่ได้: การลบบันทึก การรีเซ็ตการกำหนดค่าระบบ หรือการล้างฐานข้อมูล
- การดำเนินการทางการเงินและธุรกรรม: การส่งแบบฟอร์มการชำระเงิน การโอนเงิน การอนุมัติการชำระเงินค่าสมัครใช้บริการ หรือการสั่งซื้อขั้นสุดท้าย
- การสื่อสารกับผู้ใช้ที่มีผลกระทบสูง: การส่งใบสมัครงานขั้นสุดท้าย การส่งอีเมล/ข้อความถึงผู้ใช้จริงรายอื่นๆ หรือการเผยแพร่เนื้อหาที่แสดงต่อสาธารณะ
- การตั้งค่าบัญชีที่มีความละเอียดอ่อน: การเปลี่ยนรหัสผ่าน การแก้ไขบทบาท/สิทธิ์ของผู้ใช้ หรือการอัปเดตข้อมูลโปรไฟล์/การเรียกเก็บเงิน
กลยุทธ์สำรอง
WebMCP Declarative API ปลอดภัยต่อการใช้งานในเบราว์เซอร์ทั้งหมด เบราว์เซอร์ที่ไม่รองรับ WebMCP จะไม่สนใจแอตทริบิวต์ tool* และ <form> จะยังคงทำงานเป็นแบบฟอร์ม HTML ปกติ ไม่จำเป็นต้องมีการตรวจหาฟีเจอร์