Open in
สร้างการผสานรวมเครื่องมือ (API)
ให้เอเจนต์ของคุณเรียกใช้ API ของคุณระหว่างการสนทนา — ค้นหาฐานข้อมูล สร้างทิกเก็ต ค้นหาคำสั่งซื้อ
การผสานรวมเครื่องมือ คือ HTTP endpoint ที่นำกลับมาใช้ซ้ำได้ซึ่งเอเจนต์สามารถ เรียกใช้ระหว่างการโทร คุณให้ ThunderPhone คำอธิบาย JSON schema ของเครื่องมือพร้อม URL ของ endpoint จากนั้นเอเจนต์จะตัดสินใจว่าจะเรียกใช้เมื่อใด ตามการสนทนา และ ThunderPhone จะส่งคำขอ HTTP ขาออกจากเซิร์ฟเวอร์ของตน และส่งคืนการตอบกลับให้เอเจนต์
คู่มือนี้จะอธิบายการสร้างเครื่องมือค้นหาสภาพอากาศแบบครบทุกขั้นตอน
โครงสร้างของเครื่องมือ
มีสองส่วน:
- สคีมา — นิยามฟังก์ชันรูปแบบ OpenAI
(
{type: "function", function: {name, description, parameters}}) ที่บอก LLM ว่าเครื่องมือนี้ทำอะไรและรับอาร์กิวเมนต์ใดบ้าง - endpoint — URL ที่เซิร์ฟเวอร์ของ ThunderPhone เรียกใช้เมื่อ LLM ตัดสินใจใช้เครื่องมือ คำขอเป็น JSON POST โดยมี อาร์กิวเมนต์ที่ LLM เลือกเป็นเนื้อหาคำขอ
1. เลือกตัวแก้ไข
เปิด การเชื่อมต่อ → API สร้างหรือแก้ไขการเชื่อมต่อ API เปลี่ยนตัวแก้ไขพารามิเตอร์เป็น JSON แล้วเพิ่มรูปแบบที่นั่น
สร้างสเปกด้วย POST /v1/integrations หรืออัปเดตด้วย
PATCH /v1/integrations/{id}
ทั้งสองวิธีจะสร้างการผสานรวมที่บันทึกไว้ แนบการผสานรวมนั้นเข้ากับ
เอเจนต์หลังจากบันทึกแล้ว Agents API ไม่มีฟิลด์ tools แบบอินไลน์ที่เขียนได้
คู่มือนี้ใช้เส้นทาง API การผสานรวม
2. สร้างการผสานรวม
curl -X POST https://api.thunderphone.com/v1/integrations \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"display_name": "Weather API",
"spec": {
"type": "function",
"function": {
"name": "get_weather",
"description": "Return the current weather for a zip code.",
"parameters": {
"type": "object",
"properties": {
"zip": { "type": "string", "description": "5-digit US ZIP code" }
},
"required": ["zip"]
}
}
},
"endpoint_url": "https://api.example.com/weather",
"endpoint_method": "GET",
"headers": [
{ "key": "X-Api-Key", "value": "your-provider-key" }
]
}'บันทึก id ที่ส่งกลับมา (UUID)
ประกาศ format: "email" สำหรับพารามิเตอร์ที่อยู่
พารามิเตอร์ที่รับที่อยู่อีเมลควรระบุไว้ในสคีมาดังนี้:
"email": { "type": "string", "format": "email", "description": "The caller's email address" }format เป็นมากกว่าคำใบ้ สำหรับสคีมาอีเมลที่ผ่านการแก้ไขแล้ว ก่อนเรียก endpoint ของคุณ ThunderPhone จะตัดช่องว่างรอบค่า เปลี่ยนโดเมนเป็นตัวพิมพ์เล็ก แปลงคำภาษาอังกฤษแบบเดี่ยว at, dot, underscore, dash และ hyphen เป็นอักขระที่เกี่ยวข้อง และลบช่องว่างที่อยู่ติดกับ @, ., _ และ - โดยตรง คำเหล่านี้มีความหมายเดียวกันไม่ว่าบันทึกการสนทนาจะมี @ แบบตัวอักษรอยู่แล้วหรือไม่:
"john dot smith at gmail dot com" จะกลายเป็น
john.smith@gmail.com
ช่องว่างภายในอื่น ๆ จะถูกปฏิเสธแทนที่จะถูกรวมเข้าด้วยกันโดยอัตโนมัติ คำตัวคั่นที่พูดรองรับเฉพาะภาษาอังกฤษ รูปแบบที่เว้นวรรคซึ่งไม่ใช่ภาษาอังกฤษหรือไม่รู้จักจะไม่ผ่านการตรวจสอบ โดเมนสากลที่ถูกต้องและส่วน local ของ SMTPUTF8 ได้รับการยอมรับ อินพุต Punycode จะยังคงเป็น Punycode และอินพุตโดเมน Unicode จะยังคงเป็น Unicode หลังการทำให้ตัวแยกวิเคราะห์เป็นมาตรฐาน ดังนั้น API ของคุณจะได้รับรูปแบบตามธรรมเนียมที่ผู้โทรระบุ หากค่าสุดท้ายไม่ถูกต้อง เครื่องมือจะไม่ถูกเรียก เอเจนต์จะได้รับ
invalid_email_argument เพื่อแจ้งให้ยืนยันการสะกดกับผู้โทรและส่งที่อยู่แบบตัวอักษรอีกครั้ง
อีเมลแบบไม่บังคับที่ไม่ได้ระบุจะไม่ถูกแก้ไข null, สตริงว่าง หรือสตริงที่มีแต่ช่องว่างก็จะไม่ถูกแก้ไขเช่นกันเมื่อพร็อพเพอร์ตีเป็นแบบไม่บังคับหรืออนุญาต nullable ค่าเดียวกันนี้จะถูกปฏิเสธสำหรับอีเมลที่จำเป็นและไม่อนุญาต null
ระบบจะตรวจสอบการอ้างอิงสคีมาในเครื่อง เช่น #/$defs/email และ
#/definitions/email รวมถึง anyOf, oneOf และ allOf โดยมีขีดจำกัดรอบและความลึก $ref ที่ไม่ใช่ในเครื่องหรือแก้ไขไม่ได้เป็นข้อจำกัดการบังคับใช้ที่ทราบ และจะถูกส่งผ่านโดยไม่เปลี่ยนแปลง เช่นเดียวกับการเรียกที่สแนปช็อตเครื่องมือไม่มีสคีมาที่ใช้งานได้ เก็บสคีมาอีเมลไว้ในเครื่องเมื่อคุณต้องการให้มีการใช้เกตนี้
พารามิเตอร์ที่ไม่มีรูปแบบอีเมลซึ่งถูกบังคับใช้จะถูกส่งผ่านตามที่โมเดลสร้างขึ้นทุกประการ
รูปแบบที่รองรับคือ date-time, time, date, duration,
email, hostname, ipv4, ipv6 และ uuid โดยปัจจุบันมีเพียง email เท่านั้นที่ถูกทำให้เป็นมาตรฐานและบังคับใช้
3. ทดสอบ endpoint ในแซนด์บ็อกซ์
ก่อนเชื่อมโยงการผสานรวมกับเอเจนต์ ให้ส่งคำขอที่ลงนามจากเซิร์ฟเวอร์ของ ThunderPhone เพื่อยืนยันการเชื่อมต่อ:
curl -X POST https://api.thunderphone.com/v1/integrations/test-request \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/weather?zip=94110",
"method": "GET",
"headers": { "X-Api-Key": "your-provider-key" }
}'{
"ok": true,
"status": 200,
"elapsed_ms": 187,
"response_headers": { "content-type": "application/json" },
"response_preview": "{\"temperature_f\": 64, ...}"
}การทดสอบนี้ยังเสริมความแข็งแกร่งให้กับตัวป้องกัน SSRF ของ ThunderPhone ด้วย โดยคำขอไปยัง localhost หรือช่วง IP ส่วนตัวจะส่งกลับ 400 code=url_not_allowed
4. เชื่อมการผสานรวมกับเอเจนต์
แนบผ่าน integration_ids เมื่อสร้างหรืออัปเดตเอเจนต์:
curl -X PATCH https://api.thunderphone.com/v1/agents/12 \
-H "Authorization: Bearer sk_live_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"integration_ids": ["f9b5a1a4-..."]
}'คุณสามารถเชื่อมการผสานรวมหลายรายการกับเอเจนต์หนึ่งตัวได้ พรอมต์ของเอเจนต์สามารถ
อ้างอิงการผสานรวมตามชื่อได้ — "ใช้ get_weather เมื่อผู้โทรถาม
เกี่ยวกับสภาพอากาศ" — หรือให้เอเจนต์ค้นพบโดยอัตโนมัติจาก
คำอธิบายสคีมาก็ได้
5. ติดตั้งใช้งานเอนด์พอยต์
เมื่อเอเจนต์เรียกใช้เครื่องมือ ThunderPhone จะส่ง POST ที่มีลายเซ็นไปยัง
endpoint_url ของคุณ:
POST /weather HTTP/1.1
Host: api.example.com
X-Api-Key: your-provider-key
X-ThunderPhone-Signature: <HMAC-SHA256 hex>
X-ThunderPhone-Call-ID: 987654321
Content-Type: application/json
{"zip": "94110"}
เซิร์ฟเวอร์ของคุณตอบกลับด้วย JSON ซึ่งจะส่งกลับไปยัง LLM:
{"temperature_f": 64, "condition": "Partly cloudy", "wind_mph": 8}LLM จะรับข้อมูลจากการตอบกลับนั้นและพูดสรุปที่เข้าใจง่ายให้ผู้โทรฟัง
6. ทดสอบลูป
เรียกใช้ เซสชันไมโครโฟน กับเอเจนต์ และถามคำถามที่เครื่องมือของคุณรองรับ ("อากาศที่ 94110 เป็นอย่างไร?") ทรานสคริปต์ของการโทรจะแสดงการทำงานครบวงจร:
{
"call_id": 987654321,
"transcripts": [
{ "role": "user",
"content": "What's the weather in 94110?" },
{ "role": "tool_call",
"content": "{\"tool_call\": \"get_weather\", \"arguments\": {\"zip\": \"94110\"}}" },
{ "role": "tool_response",
"content": "{\"tool_name\": \"get_weather\", \"response\": {\"temperature_f\": 64, \"condition\": \"Partly cloudy\"}}" },
{ "role": "agent",
"content": "It's 64 degrees and partly cloudy." }
]
}คุณสามารถดึงข้อมูลนี้ผ่าน
GET /v1/calls/{call_id}/transcript;
สตรีมเหตุการณ์แบบดิบ (พร้อมเวลาของแต่ละรายการและตำแหน่งออฟเซ็ตเสียง) อยู่ที่
GET /v1/calls/{call_id}/history
ข้อควรระวังที่พบบ่อย
เอเจนต์ไม่เรียกใช้เครื่องมือ
LLM ตัดสินใจจากคำอธิบายของเครื่องมือ หากคำถามของผู้โทร
ไม่ตรงกับคำอธิบาย โมเดลจะไม่เรียกใช้
เครื่องมือ ปรับคำอธิบายให้เฉพาะเจาะจงขึ้น (เพิ่มคำพ้องความหมายและ
รูปแบบถ้อยคำที่พบบ่อย) หรือระบุอย่างชัดเจนในพรอมต์ของเอเจนต์ ("เมื่อ
ผู้โทรถามเกี่ยวกับสภาพอากาศ ให้ใช้ get_weather")
เครื่องมือส่งคืนข้อมูลมากเกินไป
การตอบกลับที่มีขนาดเกิน 6 kB จะถูกตัดทอนในตัวอย่างทรานสคริปต์ ส่งคืน เฉพาะฟิลด์ที่ LLM ต้องการ — ไม่ใช่ทั้งแถวข้อมูลของคุณ
หมดเวลา
เอนด์พอยต์เครื่องมือมีระยะหมดเวลาเริ่มต้น 10 วินาที หากต้องการเวลานานกว่า
ให้จัดการแบบอะซิงโครนัส: ส่งคืน {"status": "pending", "request_id": "..."}
และแสดงผลลัพธ์ผ่านการเรียกใช้เครื่องมือแยกต่างหาก
การกำหนดเวอร์ชัน
ทุกการ PATCH การผสานรวมจะสร้างรีวิชันใหม่ ตรวจสอบ
GET /v1/integrations/{id}/versions
เพื่อดูว่าใครเปลี่ยนแปลงอะไร หากคุณทำให้สคีมาของเครื่องมือใช้งานไม่ได้ คุณสามารถ
ย้อนกลับด้วยตนเองได้โดย PATCH สแนปช็อตเก่ากลับเข้าไป