DeepSeek นำ V4 Pro ออกจากการแสดงตัวอย่างเมื่อวันที่ 12 สิงหาคม 2026 และรายงานการเปิดตัวเน้นเวิร์กโฟลว์เอเจนต์ เช่น การเขียนโค้ด การใช้เครื่องมือ และงานหลายขั้นตอนที่ต้องรักษาเป้าหมายต่อเนื่อง ความสามารถ API ที่สำคัญจึงไม่ใช่แค่การสร้างข้อความแชท แต่คือการเรียกใช้ฟังก์ชัน (function calling)
บทความนี้จะพาคุณสร้าง agent loop ที่เรียกใช้เครื่องมือจริงด้วย Python และ SDK openai ตั้งแต่กำหนด JSON Schema, รับ tool_calls, ส่งผลลัพธ์กลับด้วยข้อความ tool ไปจนถึงทดสอบ request/response ใน Apidog ก่อนนำไปใช้งานจริง หากยังไม่มี API key ให้เริ่มจากคู่มือวิธีการใช้ DeepSeek V4 API
สรุป
-
deepseek-v4-pro(GA build DeepSeek-V4-Pro-0813) รองรับ function calling แบบ OpenAI: ส่งtools, รับtool_callsและส่งผลลัพธ์กลับด้วยข้อความtool - ใช้ SDK
openaiมาตรฐานได้โดยตั้งbase_urlเป็นhttps://api.deepseek.com - agent loop ที่ใช้งานได้จริงประกอบด้วย: เรียกโมเดล → รันเครื่องมือ → เพิ่มผลลัพธ์ → ทำซ้ำจนได้คำตอบสุดท้าย
- คุณภาพการเรียกใช้เครื่องมือขึ้นอยู่กับคำอธิบายและ JSON Schema ของเครื่องมือ จึงควรทดสอบกับสกีมาจริงของระบบคุณ
- การแคชคำนำหน้าช่วยลดต้นทุนอินพุตที่ถูกแคชจาก $0.435/M เหลือ $0.003625/M โทเค็น
เหตุใด function calling จึงเหมาะกับ V4 Pro
V4 Pro ถูกวางตำแหน่งสำหรับงานเอเจนต์ โดยมีสเปกที่เหมาะกับลูปหลายขั้นตอน:
| สเปก | DeepSeek V4 Pro |
|---|---|
| สถาปัตยกรรม | Sparse MoE: พารามิเตอร์รวม 1.6 ล้านล้าน, 49 พันล้านที่ทำงานต่อโทเค็น |
| หน้าต่างบริบท | 1M โทเค็น |
| เอาต์พุตสูงสุด | 384K โทเค็น |
| ราคาอินพุต | $0.435/M โทเค็น (แคชพลาด), $0.003625/M (แคชสำเร็จ) |
| ราคาเอาต์พุต | $0.87/M โทเค็น |
| Function calling |
tools แบบ OpenAI และการตอบกลับ tool_calls
|
| อินเทอร์เฟซอื่น | Anthropic Messages format, DeepSeek Responses API |
หน้าต่างบริบทขนาดใหญ่ช่วยเก็บประวัติการเรียกเครื่องมือและผลลัพธ์หลายรอบได้ ขณะที่การแคชคำนำหน้าช่วยลดต้นทุนของการส่งประวัติเดิมซ้ำในทุกเทิร์น
สำหรับการเปรียบเทียบผู้ให้บริการ โมเดลนี้ระบุใน OpenRouter เป็น deepseek-v4-pro-0813
ข้อควรระวัง: นักพัฒนาในการสนทนาบน Hacker Newsรายงานว่าผลลัพธ์การเรียกใช้เครื่องมือไวต่อโครงสร้างของ prompt, framework และ schema มาก อย่าใช้ benchmark เป็นคำตอบสุดท้าย ให้ทดสอบกับสกีมาและสถานการณ์จริงของคุณ
วิธีทำงานของ DeepSeek function calling
โมเดลไม่ได้รันฟังก์ชันแทนคุณ แต่ส่งคำขอที่มีโครงสร้างกลับมา เช่น:
{
"name": "get_order",
"arguments": "{\"order_id\": \"ORD-10442\"}"
}
จากนั้น runtime ของคุณต้องรันฟังก์ชัน ส่งผลลัพธ์กลับไป และให้โมเดลตัดสินใจขั้นตอนถัดไป
ลำดับการทำงานมีดังนี้:
- ส่ง
messagesพร้อมอาร์เรย์toolsที่อธิบายฟังก์ชันด้วย JSON Schema - โมเดลตอบกลับด้วย
tool_callsและfinish_reason: "tool_calls" - โค้ดของคุณแยก JSON arguments แล้วเรียกฟังก์ชันจริง
- เพิ่มผลลัพธ์เป็นข้อความ
role: "tool"พร้อมtool_call_id - เรียกโมเดลอีกครั้งจนกว่าจะตอบข้อความสุดท้าย
หากเคยใช้OpenAI function callingคุณสามารถใช้รูปแบบเดียวกันได้เกือบทั้งหมด โดยเปลี่ยน base URL และชื่อโมเดลเท่านั้น ดูอินเทอร์เฟซอื่นเพิ่มเติมได้จากเอกสาร DeepSeek
ขั้นตอนที่ 1: ตั้งค่าไคลเอนต์
ติดตั้ง SDK และตั้งค่า API key:
pip install openai
export DEEPSEEK_API_KEY="sk-..."
สร้างไคลเอนต์โดยชี้ไปที่ DeepSeek API:
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["DEEPSEEK_API_KEY"],
base_url="https://api.deepseek.com",
)
ตัวอย่างทั้งหมดด้านล่างใช้โมเดล deepseek-v4-pro ซึ่งแปลงเป็น GA build DeepSeek-V4-Pro-0813
ขั้นตอนที่ 2: กำหนดสกีมาเครื่องมือ
ตัวอย่างนี้สร้างเครื่องมือ get_order สำหรับค้นหาสถานะคำสั่งซื้อ
tools = [
{
"type": "function",
"function": {
"name": "get_order",
"description": (
"Look up a customer order by its ID. Returns the order status, "
"carrier, tracking number, and estimated delivery date. Use this "
"whenever the user asks where an order is or what state it's in."
),
"parameters": {
"type": "object",
"properties": {
"order_id": {
"type": "string",
"description": "The order ID, formatted like 'ORD-10442'.",
}
},
"required": ["order_id"],
},
},
}
]
คำอธิบายของเครื่องมือมีผลโดยตรงต่อการตัดสินใจของโมเดล ควรระบุให้ชัดเจนว่า:
- เครื่องมือนี้ใช้ทำอะไร
- ควรเรียกใช้ในสถานการณ์ใด
- ส่งคืนข้อมูลอะไร
- พารามิเตอร์แต่ละตัวมีรูปแบบอย่างไร
สร้าง implementation แบบจำลองก่อนเชื่อมต่อบริการจริง:
def get_order(order_id: str) -> dict:
"""Stub for your real order service."""
fake_db = {
"ORD-10442": {
"status": "shipped",
"carrier": "DHL",
"tracking_number": "4281337005",
"estimated_delivery": "2026-08-15",
},
"ORD-10587": {
"status": "processing",
"estimated_ship_date": "2026-08-14",
},
}
return fake_db.get(order_id, {"error": f"Unknown order ID: {order_id}"})
ขั้นตอนที่ 3: เรียกใช้เครื่องมือครั้งแรก
ส่งคำถามที่ต้องใช้ข้อมูลจากระบบภายนอก:
messages = [
{"role": "system", "content": "You are a support agent for an online store."},
{"role": "user", "content": "Where is my order ORD-10442?"},
]
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
tools=tools,
)
message = response.choices[0].message
print(message.tool_calls[0].function.name)
# get_order
print(message.tool_calls[0].function.arguments)
# {"order_id": "ORD-10442"}
โมเดลจะไม่ตอบสถานะคำสั่งซื้อโดยตรง แต่ร้องขอให้ runtime ของคุณรัน get_order
ตัวอย่าง response แบบดิบ:
{
"id": "chatcmpl-8f3a1c",
"object": "chat.completion",
"model": "deepseek-v4-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "",
"tool_calls": [
{
"id": "call_0_f1c29a44",
"type": "function",
"function": {
"name": "get_order",
"arguments": "{\"order_id\": \"ORD-10442\"}"
}
}
]
},
"finish_reason": "tool_calls"
}
],
"usage": {
"prompt_tokens": 312,
"completion_tokens": 24,
"total_tokens": 336,
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 312
}
}
จุดที่ต้องตรวจสอบ:
-
finish_reasonเป็น"tool_calls"หมายถึงต้องประมวลผลเครื่องมือ - ทุก
tool_callมีidเฉพาะ -
argumentsเป็น JSON string จึงต้องใช้json.loads()
ขั้นตอนที่ 4: รันฟังก์ชันและส่งผลลัพธ์กลับ
เพิ่มทั้งข้อความ assistant ที่มี tool_calls และข้อความ tool ที่มีผลลัพธ์:
import json
tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_order(**args)
messages.append(message)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
})
final = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
tools=tools,
)
print(final.choices[0].message.content)
ตัวอย่างคำตอบสุดท้าย:
Your order ORD-10442 shipped with DHL and is estimated to arrive
by August 15, 2026. Tracking number: 4281337005.
tool_call_id ต้องตรงกับ ID ที่โมเดลส่งมา ทุก tool_call ต้องมีข้อความ tool ที่จับคู่กันก่อนเรียกโมเดลในเทิร์นถัดไป
ขั้นตอนที่ 5: สร้าง agent loop แบบเต็ม
เอเจนต์จริงอาจเรียกใช้หลายเครื่องมือต่อเนื่องกัน เช่น ค้นหาคำสั่งซื้อ ตรวจสอบนโยบายคืนสินค้า แล้วร่างอีเมลตอบลูกค้า
ใช้ loop ที่เรียกโมเดลซ้ำจนกว่าจะไม่มี tool_calls:
import json
TOOLS_BY_NAME = {
"get_order": get_order,
}
def run_agent(client, messages, tools, max_rounds=10):
"""Run the model until it produces a final answer or hits the cap."""
for _ in range(max_rounds):
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
tools=tools,
)
message = response.choices[0].message
messages.append(message)
if not message.tool_calls:
return message.content
for tool_call in message.tool_calls:
fn = TOOLS_BY_NAME.get(tool_call.function.name)
try:
if fn is None:
raise ValueError(
f"Unknown tool: {tool_call.function.name}"
)
args = json.loads(tool_call.function.arguments)
result = fn(**args)
except Exception as exc:
result = {"error": str(exc)}
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result),
})
raise RuntimeError(f"Agent did not finish within {max_rounds} rounds")
ตั้ง max_rounds เสมอ เพื่อป้องกันลูปไม่สิ้นสุดเมื่อโมเดลเรียกเครื่องมือซ้ำหลังเกิดข้อผิดพลาด
การเรียกใช้เครื่องมือแบบขนาน
หากผู้ใช้ถามว่า:
เปรียบเทียบสถานะของ ORD-10442 และ ORD-10587
โมเดลอาจส่งคำขอสองรายการใน response เดียว:
"tool_calls": [
{
"id": "call_0_a7d1",
"type": "function",
"function": {
"name": "get_order",
"arguments": "{\"order_id\": \"ORD-10442\"}"
}
},
{
"id": "call_1_b3e9",
"type": "function",
"function": {
"name": "get_order",
"arguments": "{\"order_id\": \"ORD-10587\"}"
}
}
]
ลูปก่อนหน้านี้รองรับรูปแบบนี้อยู่แล้ว เพราะวนผ่าน message.tool_calls และส่งผลลัพธ์กลับตาม tool_call_id ของแต่ละรายการ
หากเครื่องมือของคุณเป็น I/O-bound เช่น HTTP request หรือ database query คุณสามารถเปลี่ยนส่วนนี้ให้ใช้ asyncio.gather() เพื่อรันคำขอพร้อมกันได้
แนวทางนี้ต่างจากการเรียกใช้เครื่องมือแบบโปรแกรมของ GPT-5.6ซึ่งโมเดลเขียนโค้ดเพื่อจัดการเครื่องมือใน sandbox ขณะที่ DeepSeek ให้ runtime ของคุณเป็นผู้ควบคุมการประมวลผลและขอบเขตความน่าเชื่อถือ
โหมดการคิดพร้อมเครื่องมือ
V4 Pro มีโหมดการคิดหลายแบบเพื่อเพิ่มความพยายามในการวางแผนสำหรับงานซับซ้อน ดูชื่อโหมดและค่าเริ่มต้นจากเอกสารทางการ
เมื่อเปิดใช้งาน API จะส่ง reasoning_content พร้อม tool_calls:
response = client.chat.completions.create(
model="deepseek-v4-pro",
messages=messages,
tools=tools,
extra_body={"thinking": {"type": "enabled"}},
)
message = response.choices[0].message
print(message.reasoning_content)
print(message.tool_calls)
ใช้ reasoning_content เพื่อดีบักการเลือกเครื่องมือและสกีมา แต่ไม่ควรเพิ่มฟิลด์นี้กลับเข้าสู่ประวัติข้อความ ควรเปิดโหมดคิดเฉพาะเทิร์นที่ต้องวางแผนมาก เพราะ reasoning มีค่าใช้จ่ายตามราคาเอาต์พุต $0.87/M โทเค็น
จัดการข้อผิดพลาดของ arguments
อย่าปล่อยให้ agent ล้มเหลวทันทีเมื่อโมเดลส่ง JSON ผิดรูปแบบหรือค่าที่ไม่ผ่านกฎธุรกิจ ให้ส่งข้อผิดพลาดกลับเป็นผลลัพธ์ของเครื่องมือเพื่อให้โมเดลแก้ไขการเรียกครั้งถัดไป
import json
from jsonschema import ValidationError, validate
schema = tools[0]["function"]["parameters"]
try:
args = json.loads(tool_call.function.arguments)
validate(instance=args, schema=schema)
result = get_order(**args)
except (json.JSONDecodeError, ValidationError) as exc:
result = {
"error": f"Invalid arguments: {exc}",
"hint": (
"Call get_order again with an order_id string "
"like 'ORD-10442'."
),
}
hint ที่ชัดเจนช่วยให้โมเดลแก้ไขคำขอได้ในรอบถัดไป
นอกจากนี้ ให้ถือว่าการเรียกเครื่องมือเป็นขอบเขตด้านความปลอดภัยด้วย หากโมเดลถูกชักจูงให้เรียกเครื่องมือทำลายข้อมูล เช่น delete_order ความเสียหายขึ้นอยู่กับสิทธิ์ของ credential ที่ runtime ใช้ ควรใช้API key ที่มีสิทธิ์น้อยที่สุดสำหรับ AI agentsและแยกสิทธิ์ read/write ออกจากกัน
ทดสอบและดีบัก tool calling ด้วย Apidog
เครื่องมือของเอเจนต์มักเป็น wrapper รอบ API ภายในหรือ API ภายนอก ดังนั้นคุณควรทดสอบทั้ง API และ payload ที่ส่งให้โมเดล
ใช้ Apidog ในขั้นตอนดังนี้:
ออกแบบ API ที่รองรับก่อน
กำหนดGET /orders/{order_id}ใน visual designer แล้วใช้สเปกเดียวกันเป็นต้นทางของ JSON Schema สำหรับเครื่องมือMock ก่อนสร้าง backend เสร็จ
สร้าง response จำลองจากสกีมา เพื่อพัฒนา agent loop ได้ก่อนบริการจริงพร้อมใช้งานตรวจสอบ payload ดิบของ DeepSeek
ส่ง request body เดียวกับที่ใช้ในโค้ด ได้แก่messagesและtoolsไปยังhttps://api.deepseek.comแล้วตรวจดูtool_callsโดยตรงสร้าง regression test สำหรับสกีมา
ตรวจสอบfinish_reason, ชื่อเครื่องมือ และรูปแบบ arguments ทุกครั้งที่เปลี่ยน schema ดูแนวทางเพิ่มเติมในบทความการเชื่อมต่อ AI agent เข้ากับ Apidog test harness
ดาวน์โหลด Apidogเพื่อเริ่มสร้าง mock server และสถานการณ์ทดสอบ
ค่าใช้จ่ายของ agent loop และการแคช
agent loop จะส่งประวัติการสนทนาเดิมซ้ำในทุกเทิร์น รอบที่ 10 จะรวม system prompt, คำจำกัดความเครื่องมือ และผลลัพธ์จากเก้ารอบก่อนหน้า
การแคชคำนำหน้าอัตโนมัติของ V4 Pro ทำให้ส่วนที่ซ้ำกันถูกคิดค่าบริการที่ $0.003625/M แทน $0.435/M โทเค็น
ตัวอย่างการอ่านประวัติ 100K โทเค็นซ้ำ:
- ไม่ถูกแคช: ประมาณ
$0.0435 - ถูกแคช: ประมาณ
$0.0004
ตรวจสอบอัตราการใช้งานจริงจากฟิลด์ต่อไปนี้:
{
"prompt_cache_hit_tokens": 0,
"prompt_cache_miss_tokens": 312
}
เพื่อรักษา cache hit rate:
- อย่าแก้ไขข้อความก่อนหน้าโดยไม่จำเป็น
- รักษาลำดับและเนื้อหาของ
toolsให้คงที่ระหว่างรอบ - เพิ่มข้อความใหม่ต่อท้ายประวัติ แทนการเขียนทับข้อความเดิม
อ่านหลักการเพิ่มเติมได้ในบทความการแคชพร้อมต์
แม้ deepseek-v4-flash ที่ราคา $0.14/$0.28 อาจเหมาะกับการส่งต่อเครื่องมือเพียงครั้งเดียว แต่ในลูปที่มี 10+ รอบ การลองใหม่และการส่งบริบทซ้ำอาจลดข้อได้เปรียบด้านต้นทุนได้ ดังนั้น DeepSeek Pro จึงเป็นค่าเริ่มต้นที่ปลอดภัยกว่าสำหรับเอเจนต์หลายขั้นตอน
คำถามที่พบบ่อย
คำจำกัดความของเครื่องมือมีค่าใช้จ่ายเป็นโทเค็นหรือไม่?
มี อาร์เรย์ tools เป็นส่วนหนึ่งของ input ทุก request อย่างไรก็ตาม หากรักษาไว้ให้คงที่ ระบบสามารถนำไปใช้กับ prefix cache หลังรอบแรกได้
ฉันสามารถรวม function calling กับเอาต์พุตที่มีโครงสร้างได้หรือไม่?
ได้ รูปแบบทั่วไปคือให้เครื่องมือดึงข้อมูลกลาง แล้วใช้สกีมาเอาต์พุตที่มีโครงสร้างจัดรูปแบบคำตอบสุดท้าย วิธีนี้ช่วยให้ระบบปลายน้ำไม่ต้องแยกวิเคราะห์ข้อความธรรมดา
สรุป
Function calling ของ DeepSeek V4 Pro ใช้รูปแบบที่คุ้นเคยสำหรับผู้ใช้ OpenAI-compatible API: กำหนด tools, รับ tool_calls, รันฟังก์ชันใน runtime ของคุณ และส่งผลลัพธ์กลับด้วยข้อความ tool
ส่วนสำคัญที่สุดไม่ใช่ loop เพียงอย่างเดียว แต่คือคุณภาพของ tool schema, การตรวจสอบ arguments, การจำกัดสิทธิ์ของเครื่องมือ และ regression test ที่ครอบคลุมสถานการณ์จริง ออกแบบ API ให้ชัดเจน สร้าง mock ล่วงหน้า และเก็บชุดทดสอบ tool-calling ไว้ใน Apidog เพื่อป้องกันการเปลี่ยนสกีมาที่ทำให้เอเจนต์ทำงานผิดพลาดโดยไม่รู้ตัว
Top comments (0)