แบบฟอร์ม Agentic

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 ปกติ ไม่จำเป็นต้องมีการตรวจหาฟีเจอร์