วิธีใช้ OpenAI Function Calling

คำอธิบายการเรียกใช้ฟังก์ชันของ OpenAI: กำหนดเครื่องมือ, อ่าน tool_calls, ใช้การเรียกแบบขนานและโหมดเคร่งครัด, จากนั้นยืนยันอาร์กิวเมนต์และจำลอง API ใน Apidog

Ashley Innocent

Ashley Innocent

26 June 2026

วิธีใช้ OpenAI Function Calling

Apidog สำหรับองค์กร

การติดตั้งแบบ On-Premises

SSO & RBAC

รองรับมาตรฐาน SOC 2

สำรวจ Apidog Enterprise

เมื่ออ่านคู่มือนี้จบ คุณจะสามารถกำหนดเครื่องมือ ส่งไปยัง 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 ที่ฟังก์ชันของคุณต้องพึ่งพา ทั้งหมดในที่เดียว

ปุ่ม

ฝึกการออกแบบ API แบบ Design-first ใน Apidog

ค้นพบวิธีที่ง่ายขึ้นในการสร้างและใช้ API