เมื่ออ่านคู่มือนี้จบ คุณจะสามารถกำหนดเครื่องมือ ส่งไปยัง OpenAI อ่านการเรียกใช้เครื่องมือที่โมเดลส่งกลับมา และเรียกใช้ฟังก์ชันของคุณเองด้วยอาร์กิวเมนต์ที่มีโครงสร้างที่ได้รับกลับมา คุณยังจะเปิดใช้งานโหมดเข้มงวด (strict mode) และการเรียกใช้แบบขนาน (parallel calls) จากนั้นยืนยันและจำลองฝั่งเครื่องมือด้วย Apidog เพื่อให้คุณมั่นใจในผลลัพธ์ก่อนที่จะนำไปใช้งานจริง เปิด เอกสารประกอบการเรียกใช้ฟังก์ชัน (function calling) ของ OpenAI ไว้ในแท็บอื่นเพื่อใช้อ้างอิง และดูข้อมูลเบื้องต้นเกี่ยวกับการ สร้างเอเจนต์ด้วย OpenAI Agents SDK ของเราสำหรับภาพรวมที่กว้างขึ้น
สิ่งที่คุณต้องมีก่อนเริ่มต้น
การเรียกใช้ฟังก์ชัน (Function calling) (มักเรียกว่า การเรียกใช้เครื่องมือ - tool calling) คือวิธีที่โมเดลเชื่อมต่อกับโค้ดและระบบภายนอกของคุณ คุณอธิบายฟังก์ชันที่แอปของคุณมีให้ โมเดลจะอ่านคำขอของผู้ใช้ และเมื่อฟังก์ชันนั้นเหมาะสม ก็จะส่งคืนชื่อฟังก์ชันพร้อมกับออบเจกต์ JSON ของอาร์กิวเมนต์ โมเดลไม่เคยรันสิ่งใดด้วยตัวเอง มันจะส่งคำขอที่มีโครงสร้างให้คุณ และโค้ดของคุณจะเป็นผู้ดำเนินการ
การแบ่งแยกหน้าที่นี้คือสิ่งสำคัญที่ต้องจำไว้ขณะที่คุณสร้าง โมเดลจะเลือกเจตนาและเติมพารามิเตอร์ คุณยังคงควบคุมการดำเนินการ ข้อความ “สภาพอากาศในปารีสเป็นอย่างไรตอนนี้” จะกลายเป็นการเรียกใช้ get_weather({"location": "Paris, France"}) ที่ชัดเจน แทนที่จะเป็นข้อความยาวๆ ที่คุณต้องแยกวิเคราะห์ด้วยตนเอง
ในการทำตาม คุณต้องมีคีย์ OpenAI API และฟังก์ชันในโค้ดของคุณเองที่คุณต้องการให้โมเดลสามารถเรียกใช้งานได้ สิ่งหนึ่งที่ต้องตัดสินใจล่วงหน้าคือ คุณจะใช้ปลายทาง (endpoint) ใด คุณสมบัติเดียวกันนี้ใช้งานได้สองที่ Chat Completions API แบบเก่ารองรับ และ Responses API แบบใหม่ก็รองรับเช่นกัน ซึ่งรวมเอาสิ่งที่เคยแยกกันระหว่าง Chat Completions และ Assistants API เข้าไว้ด้วยกัน รูปแบบอาจแตกต่างกันเล็กน้อย และขั้นตอนด้านล่างจะครอบคลุมทั้งสองแบบ
ขั้นตอนที่ 1: กำหนดเครื่องมือของคุณ
เครื่องมือคือการนิยามฟังก์ชันที่โมเดลสามารถอ่านได้ คุณกำหนดชื่อ คำอธิบาย และ JSON Schema สำหรับอาร์กิวเมนต์ คำอธิบายมีบทบาทสำคัญในที่นี้ มันจะบอกโมเดลว่าเมื่อใดควรใช้ฟังก์ชันนี้ ดังนั้น ให้เขียนเหมือนเป็นคำแนะนำ ไม่ใช่แค่ป้ายกำกับ
นี่คือคำนิยามเครื่องมือในรูปแบบ Chat Completions โดยที่ฟังก์ชันจะอยู่ภายใต้ wrapper function:
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city. Use when the user asks about temperature or conditions.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City and country, e.g. Bogotá, Colombia"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"]
}
},
"required": ["location"],
"additionalProperties": false
}
}
}
Responses API ทำให้สิ่งนี้แบนราบลง ฟิลด์ name, description, parameters และ strict จะอยู่ที่ระดับสูงสุดของออบเจกต์เครื่องมือ โดยไม่มีคีย์ function ซ้อนอยู่ ข้อมูลเดียวกัน แต่มีชั้นน้อยลง
หากคุณดูแลรักษา OpenAPI spec สำหรับบริการพื้นฐานอยู่แล้ว รูปแบบพารามิเตอร์จะสามารถนำมาใช้ได้เกือบโดยตรง คู่มือของเราเกี่ยวกับการ สร้างชุดการทดสอบจาก OpenAPI specs แสดงให้เห็นว่าการทำงานเกี่ยวกับ Schema นั้นให้ผลตอบแทนสองเท่าได้อย่างไร
ขั้นตอนที่ 2: สร้างคำขอแรกของคุณ
ส่งเครื่องมือของคุณไปยังโมเดลพร้อมกับข้อความของผู้ใช้ คำขอ Chat Completions ฉบับเต็มที่ทำเช่นนี้มีลักษณะดังนี้:
curl https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-4.1",
"messages": [
{"role": "user", "content": "What is the weather in Paris right now?"}
],
"tools": [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
"required": ["location"],
"additionalProperties": false
}
}
}
]
}'
อาร์เรย์ tools จะบรรจุทุกฟังก์ชันที่คุณต้องการเปิดเผยสำหรับการตอบโต้ครั้งนี้ โมเดลจะอ่านข้อความของผู้ใช้ ตัดสินใจว่ามีเครื่องมือใดเหมาะสมหรือไม่ แล้วตอบกลับ เมื่อโมเดลเลือกเครื่องมือใดเครื่องมือหนึ่ง คุณจะได้รับ tool call กลับมาแทนที่จะเป็นข้อความทั่วไป ซึ่งเป็นสิ่งที่คุณจะอ่านในขั้นตอนถัดไป
ขั้นตอนที่ 3: อ่านการเรียกใช้เครื่องมือที่โมเดลส่งกลับมา
เมื่อโมเดลตัดสินใจเรียกใช้ฟังก์ชัน มันจะไม่ส่งข้อความกลับมา แต่จะส่ง tool call ที่คุณอ่านได้จากผลตอบกลับ
ใน Chat Completions ข้อความของผู้ช่วยจะมีอาร์เรย์ tool_calls แต่ละรายการจะมี id, type เป็น function และออบเจกต์ function ที่มี name และสตริง arguments:
{
"id": "call_12345xyz",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"location\":\"Paris, France\"}"
}
}
ใน Responses API การเรียกใช้จะปรากฏในอาร์เรย์ output ด้วยรูปแบบที่แบนราบกว่า: มี type เป็น function_call, call_id, name และ arguments:
{
"type": "function_call",
"call_id": "call_12345xyz",
"name": "get_weather",
"arguments": "{\"location\":\"Paris, France\"}"
}
รายละเอียดหนึ่งที่มักทำให้คนสับสนคือ: arguments เป็นสตริงที่เข้ารหัสแบบ JSON ไม่ใช่ออบเจกต์ที่แยกวิเคราะห์แล้ว คุณต้องแยกวิเคราะห์ด้วยตนเอง เรียกใช้ฟังก์ชันของคุณ จากนั้นส่งผลลัพธ์กลับไปเพื่อให้โมเดลสามารถตอบกลับให้เสร็จสมบูรณ์ได้
ขั้นตอนที่ 4: ส่งผลลัพธ์กลับไปยังโมเดล
หลังจากที่คุณรันฟังก์ชันของคุณแล้ว ให้ส่งผลลัพธ์กลับไปเพื่อให้โมเดลสามารถสร้างคำตอบสุดท้ายได้ ใน Chat Completions คุณจะเพิ่มข้อความที่มีบทบาท tool ที่เชื่อมโยงกับ id ของการเรียกใช้ ใน Responses API คุณจะส่งรายการ function_call_output ที่เชื่อมโยงกับ call_id ไม่ว่าจะด้วยวิธีใด วงจรก็เหมือนกัน: โมเดลถาม, คุณรัน, คุณส่งผลลัพธ์กลับ, โมเดลตอบกลับ
ขั้นตอนที่ 5: เพิ่มการเรียกใช้แบบขนานและโหมดเข้มงวด
การตั้งค่าสองอย่างที่เปลี่ยนความน่าเชื่อถือและความเร็วของสิ่งนี้ และคุณจะเพิ่มเมื่อวงจรพื้นฐานทำงานแล้ว
การเรียกใช้เครื่องมือแบบขนาน. โดยค่าเริ่มต้น โมเดลสามารถส่งคืน tool call ได้มากกว่าหนึ่งรายการในการโต้ตอบครั้งเดียว หากผู้ใช้ถามสภาพอากาศในสามเมือง คุณอาจได้รับการเรียกใช้สามครั้งพร้อมกันและสามารถรันพร้อมกันได้ หากคุณต้องการบังคับให้มีการเรียกใช้ไม่เกินหนึ่งครั้งต่อการโต้ตอบ ให้ตั้งค่า parallel_tool_calls เป็น false
โหมดเข้มงวด. ตั้งค่า strict: true ในคำนิยามฟังก์ชัน และอาร์กิวเมนต์ของโมเดลจะได้รับการรับรองว่าตรงกับ JSON Schema ของคุณ แทนที่จะเป็นเพียงความพยายามที่ดีที่สุด OpenAI แนะนำให้เปิดใช้งานเสมอ โหมดเข้มงวดมีกฎ: ทุกออบเจกต์ต้องมี additionalProperties: false และทุกฟิลด์ใน properties ต้องปรากฏใน required หากต้องการทำให้ฟิลด์เป็นทางเลือก คุณไม่ต้องลบออกจาก required; คุณเพียงเพิ่ม null เข้าไปในรายการประเภทที่อนุญาต
| การตั้งค่า | สิ่งที่ควบคุม | ค่าเริ่มต้น | เมื่อใดควรเปลี่ยน |
|---|---|---|---|
parallel_tool_calls |
มีการเรียกใช้เครื่องมือหลายรายการกลับมาได้ในการโต้ตอบครั้งเดียวหรือไม่ | true |
ตั้งค่าเป็น false เมื่อการเรียกใช้ขึ้นอยู่ซึ่งกันและกันหรือต้องรันตามลำดับ |
strict |
อาร์กิวเมนต์ถูกบังคับให้ตรงกับ Schema หรือไม่ | พยายามดีที่สุดเว้นแต่จะตั้งค่า; แนะนำให้เปิด | เปิดใช้งานสำหรับการเรียกใช้ใดๆ ที่คุณแยกวิเคราะห์โดยไม่มีโค้ดป้องกัน |
tool_choice |
โมเดลสามารถเรียกใช้ฟังก์ชันใดได้บ้างและหรือไม่ | auto |
required เพื่อบังคับการเรียกใช้, none เพื่อปิดใช้งาน, หรือระบุชื่อเพื่อตรึงไว้ |
กฎเกี่ยวกับฟิลด์ที่เป็นทางเลือกมักทำให้คนประหลาดใจ สมมติว่า unit เป็นทางเลือกใน get_weather ภายใต้โหมดเข้มงวด คุณยังคงระบุไว้ใน required จากนั้นทำเครื่องหมายว่าเป็น nullable ใน Schema เช่น "unit": {"type": ["string", "null"], "enum": ["celsius", "fahrenheit"]} ตอนนี้โมเดลสามารถส่งหน่วยจริงหรือ null ชัดเจนได้ แต่จะไม่สามารถละเว้นคีย์ได้ ความคาดเดาได้นั้นคือจุดประสงค์ทั้งหมด: โค้ดการแยกวิเคราะห์ของคุณจะรู้ว่าควรรอคีย์ใดบ้างทุกครั้ง
โหมดเข้มงวดช่วยลด JSON ที่มีรูปแบบไม่ถูกต้อง แต่ไม่ได้ตรวจสอบว่าค่าต่างๆ มีความหมายทางธุรกิจหรือไม่ สถานที่อาจถูกต้องตาม Schema แต่ยังคงเป็นเมืองที่คุณไม่ได้ให้บริการ นั่นคือจุดที่การทดสอบเข้ามามีบทบาท
วิธีทดสอบใน Apidog
โมเดลจะส่ง tool call ให้คุณ ก่อนที่คุณจะเชื่อมต่อกับการทำงานจริง คุณต้องการการรับรองสองประการ: อาร์กิวเมนต์ตรงกับรูปแบบที่คุณคาดไว้ และ API ปลายทางที่ฟังก์ชันของคุณจะเรียกใช้นั้นทำงานตามที่คุณคาดการณ์ Apidog ครอบคลุมทั้งสองด้าน และควรจะระบุให้ชัดเจนว่าด้านใด

Apidog ตรวจสอบและจำลองฝั่ง API มันไม่ได้รันฟังก์ชันของแอปพลิเคชันของคุณ สิ่งที่ทำได้ดีคือข้อตกลงรอบๆ ฟังก์ชันเหล่านั้น
ยืนยันโครงสร้างของอาร์กิวเมนต์. นำสตริง arguments จากการเรียกใช้เครื่องมือจริง ถือว่าเป็นเนื้อหาคำขอ และรันการยืนยันใน Apidog ตรวจสอบว่า location มีอยู่และเป็นสตริง, ฟิลด์ enum มีเฉพาะค่าที่อนุญาต, และฟิลด์ที่จำเป็นมีอยู่ การดึงฟิลด์เฉพาะออกจาก Payload ทำได้ง่ายด้วย นิพจน์ JSONPath และสำหรับการตรวจสอบโครงสร้างที่ลึกซึ้งยิ่งขึ้นมีการ ตรวจสอบกับ JSON Schema ซึ่งสะท้อนถึง Schema เดียวกันกับที่คุณส่งให้ OpenAI ในโหมดเข้มงวด หากผลลัพธ์ของโมเดลผ่าน Schema เดียวกันกับที่ฟังก์ชันของคุณคาดหวัง คุณก็ปิดวงจรได้แล้ว
จำลอง API ปลายทางที่ฟังก์ชันจะเรียกใช้. ฟังก์ชัน get_weather ของคุณน่าจะเรียกใช้ผู้ให้บริการสภาพอากาศ ในระหว่างการพัฒนา ผู้ให้บริการนั้นอาจมีการจำกัดอัตรา (rate-limited) ต้องชำระเงิน หรือยังไม่ถูกสร้างขึ้น สร้าง mock API ใน Apidog ที่ส่งกลับข้อมูลสภาพอากาศที่สมจริง ชี้ฟังก์ชันของคุณไปยัง mock และทดสอบเส้นทางการเรียกใช้ทั้งหมดโดยไม่ต้องใช้คำขอกับบริการจริง คุณสามารถควบคุมการตอบกลับ รวมถึงกรณีข้อผิดพลาดที่ live API ไม่ค่อยสร้างขึ้นตามต้องการ เพื่อให้คุณสามารถยืนยันได้ว่าโค้ดของคุณจัดการกับการหมดเวลา (timeout) หรือข้อผิดพลาด 429 ได้ก่อนที่ผู้ใช้จะพบ
โดยรวมแล้ว ขั้นตอนการทำงานคือ: ดักจับ tool call จาก OpenAI, ยืนยันอาร์กิวเมนต์กับ Schema ของคุณใน Apidog, จากนั้นรันฟังก์ชันของคุณกับ Apidog mock ของ API จริง คุณตรวจสอบข้อตกลงทั้งสองฝั่งโดยไม่ต้องสิ้นเปลืองการเรียกใช้จริงหรือคาดเดากรณีขอบ
คำถามที่พบบ่อย
การเรียกใช้ฟังก์ชัน (function calling) ใช้งานได้ทั้งใน Chat Completions และ Responses API หรือไม่? ได้ ปลายทางทั้งสองรองรับ Responses API ได้รวมความสามารถที่เคยแยกกันระหว่าง Chat Completions และ Assistants API เข้าไว้ด้วยกัน ความแตกต่างหลักคือรูปแบบ: Chat Completions จะซ้อนฟังก์ชันไว้ใต้คีย์ function และส่งคืน tool_calls ในขณะที่ Responses API ใช้คำนิยามเครื่องมือแบบแบนราบและส่งคืนรายการ function_call ในอาร์เรย์ output
ทำไมโมเดลถึงส่งคืนอาร์กิวเมนต์เป็นสตริงแทนที่จะเป็นออบเจกต์? ฟิลด์ arguments เป็นข้อความที่เข้ารหัสแบบ JSON คุณต้องแยกวิเคราะห์ในโค้ดของคุณก่อนนำไปใช้ นี่เป็นไปตามข้อกำหนดใน API ทั้งสอง ดังนั้นควรรันผ่าน JSON parser ของคุณเสมอและตรวจสอบผลลัพธ์แทนที่จะเชื่อถือโดยไม่ตรวจสอบ การรันอาร์กิวเมนต์เหล่านั้นผ่าน การตรวจสอบ JSON Schema จะช่วยดักจับ Payload ที่มีรูปแบบไม่ถูกต้องก่อนที่จะไปถึงฟังก์ชันของคุณ
โหมดเข้มงวดรับประกันว่าฟังก์ชันจะทำงานสำเร็จหรือไม่? ไม่ โหมดเข้มงวดรับประกันว่าอาร์กิวเมนต์ตรงกับ JSON Schema ของคุณ ทำให้โครงสร้างน่าเชื่อถือ มันไม่ได้ตรวจสอบว่าค่าถูกต้องสำหรับตรรกะทางธุรกิจของคุณหรือไม่ และไม่ได้รันฟังก์ชันของคุณ คุณยังคงต้องตรวจสอบค่าและจัดการกับความล้มเหลวของการเรียกใช้ปลายทางด้วยตนเอง
Apidog สามารถรันฟังก์ชันจริงของฉันได้หรือไม่? ไม่ และมันไม่ได้พยายามจะทำเช่นนั้น Apidog ตรวจสอบอาร์กิวเมนต์ที่โมเดลสร้างขึ้น และจำลอง API ที่ฟังก์ชันของคุณต้องพึ่งพา แอปพลิเคชันของคุณยังคงรันฟังก์ชันของตัวเอง Apidog ครอบคลุมข้อตกลงทั้งสองฝั่ง เพื่อให้คุณมั่นใจในข้อมูลนำเข้าและส่วนประกอบต่างๆ ก่อนที่จะนำไปใช้งานจริง
สรุป
ตอนนี้คุณเข้าใจวงจรทั้งหมดแล้ว: กำหนดเครื่องมือของคุณให้ชัดเจน, ส่งไปพร้อมกับคำขอ, อ่านผลลัพธ์ tool_calls หรือ function_call, ส่งผลลัพธ์กลับ, จากนั้นเปิดโหมดเข้มงวดและตัดสินใจว่าการเรียกใช้แบบขนานมีประโยชน์หรือเป็นผลเสีย ปิดท้ายด้วยการทดสอบโดยยืนยันว่าอาร์กิวเมนต์ตรงกับ Schema ของคุณและจำลอง API ปลายทาง เพื่อให้คุณมั่นใจก่อนนำไปใช้งานจริง
ต้องการลองใช้งานด้านการทดสอบหรือไม่? ดาวน์โหลด Apidog เพื่อยืนยันอาร์กิวเมนต์ของ tool call กับ Schema ของคุณ และจำลอง API ที่ฟังก์ชันของคุณต้องพึ่งพา ทั้งหมดในที่เดียว
