รายละเอียดพารามิเตอร์ API โมเดลใหญ่: จากฟิลด์คำขอถึงฟิลด์คำตอบ
เอกสาร API chat completion มักดูน่ากลัวด้วยพารามิเตอร์เยอะ ลองนึกภาพการสั่งอาหาร: messages คือการคุยกับพนักงาน, temperature คือระดับอิสระของเชฟ, max_tokens คือปริมาณสูงสุด, tools คือการให้เชฟโทรถามวัตถุดิบ บทความนี้อธิบายทีละตารางอย่างละเอียดตามแนวคิดนี้
อัปเดตเมื่อ
ข้อสำคัญ
- messages ประกอบด้วย role system, user, assistant, tool โมเดลไม่มีหน่วยความจำ คุณต้องนำประวัติมาเอง
- temperature ควบคุมความสุ่ม และ top_p ควบคุมขอบเขตตัวเลือก โดยทั่วไปปรับเพียงค่าใดค่าหนึ่ง
- finish_reason บอกวิธีจัดการผลลัพธ์: stop คือจบปกติ, length คือถูกตัด, tool_calls คือต้องเรียกใช้ฟังก์ชัน
- ฟิลด์ usage เป็นหลักฐานเดียวที่เชื่อถือได้สำหรับการคิดเงินและงบประมาณ ควรอ่านทุกครั้ง
ลักษณะคำขอ
ที่อยู่ API คือ POST https://api.apidamoxing.com/v1/chat/completions, หัวข้อการตรวจสอบสิทธิ์คือ Authorization: Bearer <key>, ร่างคำขอคือ JSON และเข้ากันได้กับ chat completion ของ OpenAI ดูคำขอเต็มรูปแบบที่ใช้ฟิลด์ทั่วไป:
curl https://api.apidamoxing.com/v1/chat/completions \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "uncensored",
"messages": [
{"role": "system", "content": "你是一位耐心的天文科普作者。"},
{"role": "user", "content": "为什么月亮总是同一面朝向地球?"}
],
"temperature": 0.7,
"top_p": 0.9,
"max_tokens": 400,
"stop": ["###"]
}'หมายเหตุ model ต้องใส่ uncensored เท่านั้น เพราะมีเพียงโมเดลเดียว ใช้ GET /v1/models เพื่อยืนยัน อธิบายฟิลด์ทีละตัวดังนี้
เมื่ออ่านจบคุณจะเห็นว่าพารามิเตอร์แบ่งเป็น 3 กลุ่ม: "จะพูดอะไร" (messages, tools), "จะพูดอย่างไร" (temperature, top_p) และ "พูดมากแค่ไหน หยุดเมื่อไหร่" (max_tokens, stop, stream)
messages: สมุดบันทึกการสนทนา
messages เป็นอาร์เรย์ที่มี role และ content เปรียบเสมือนบันทึกการประชุมที่โมเดลอ่านใหม่ทุกครั้ง ไม่จำประวัติ ดังนั้นคุณต้องส่งประวัติมาครบ
| role | ผู้เขียน | วัตถุประสงค์ |
|---|---|---|
| system | คุณ (นักพัฒนา) | กำหนดตัวตน กฎ และรูปแบบเอาต์พุต มักอยู่ด้านหน้าสุด |
| user | ผู้ใช้ปลายทาง | คำถามหรือคำสั่ง |
| assistant | โมเดล (หรือประวัติที่คุณเติม) | คำตอบก่อนหน้า สำหรับบริบทหลายรอบ |
| tool | โปรแกรมของคุณ | ผลการเรียกใช้ฟังก์ชัน ต้องมี tool_call_id |
เทคนิคหนึ่งคือใส่ข้อความ assistant ลงในประวัติเพื่อให้โมเดลเขียนต่อในโทนนั้น จำไว้ว่า prompt และ output รวมกันต้องไม่เกิน 100,000 token; ประวัติยาวยิ่งใช้พื้นที่มาก
ตัวอย่าง: สร้างผู้ช่วยบริการลูกค้า โดย system บอก "ตอบเฉพาะคำถามเกี่ยวกับคำสั่งซื้อ ไม่เกิน 3 ประโยค" เมื่อผู้ใช้ถามเรื่องการจัดส่งแล้วถามต่อว่า "แล้วการคืนสินค้าล่ะ" ในคำขอที่สอง, messages ต้องเรียง: system, user รอบแรก, assistant รอบแรก, user รอบสอง หากขาดไป โมเดลจะไม่เข้าใจว่า "แล้ว" หมายถึงอะไร
พารามิเตอร์การสุ่ม: ปรับ "พื้นที่อิสระ"
โมเดลจะคำนวณความน่าจะเป็นของคำที่เป็นไปได้ทั้งหมดก่อน แล้วจึงสุ่มเลือก พารามิเตอร์สองตัวนี้คือปุ่มปรับกฎการสุ่ม:
| พารามิเตอร์ | การเปรียบเทียบ | วิธีเข้าใจ | ค่าทั่วไป |
|---|---|---|---|
| temperature | ระดับความคิดสร้างสรรค์ของโมเดล | ค่าต่ำลงทำให้ผลลัพธ์มีความเสถียรมากขึ้น; ค่าสูงขึ้นทำให้ผลลัพธ์มีความหลากหลายมากขึ้น | ช่วง 0 ถึง 1.2; ใช้ค่าต่ำสำหรับงานตอบคำถาม และค่าสูงสำหรับงานสร้างสรรค์ |
| top_p | สุ่มเลือกเฉพาะจากตัวเลือกอันดับต้นๆ | สุ่มเลือกเฉพาะจากตัวเลือกที่ความน่าจะเป็นสะสมถึงค่า p | ช่วง 0.8 ถึง 1; ค่าเริ่มต้นมักเพียงพอ |
ทั้งสองตัวควบคุมระดับความสุ่ม แต่คนละมุม การปรับทั้งคู่พร้อมกันทำให้ยากที่จะรู้ผลที่มาจากตัวไหน จึงแนะนำให้ปรับทีละตัว ฟิลด์การสุ่มมาตรฐานเหล่านี้จะถูกส่งต่อไปยัง API โดยไม่มีการแก้ไข
ตัวอย่างตัวเลข: หากคำที่เป็นไปได้คือ A (60%), B (30%), C (10%) การลด temperature จะทำให้ A โดดเด่นขึ้นเหมือนการเลือกอันดับหนึ่งเสมอ; การเพิ่ม temperature จะทำให้ความน่าจะเป็นใกล้เคียงกัน ทำให้ C มีโอกาสถูกสุ่มมากขึ้น หากใช้ top_p 0.9 จะเก็บเพียง A และ B รวมกันถึง 90% ส่วน C จะถูกตัดออก ตัวเลขนี้เป็นเพียงสมมติฐานเพื่ออธิบายหลักการ ไม่ใช่ความน่าจะเป็นจริง
ควบคุมความยาวและการหยุด: max_tokens, stop, stream
| พารามิเตอร์ | หน้าที่ | ข้อควรระวัง |
|---|---|---|
| max_tokens | จำกัดจำนวน token สูงสุดที่สามารถสร้างได้ในครั้งนั้น | ค่าเริ่มต้นคือ 2048 ค่าสูงสุดต่อครั้งคือ 32,000; ผลรวมกับจำนวนโทเคนในพรอมต์ต้องไม่เกิน 100,000 |
| stop | หยุดการสร้างเมื่อพบสตริงที่กำหนด | สามารถส่งเป็นอาร์เรย์ของสตริง เหมาะสำหรับงานแบ่งส่วนหรือตัดรูปแบบที่กำหนดตายตัว |
| stream | เป็นการส่งผลลัพธ์แบบสตรีมมิงหรือไม่ | เมื่อตั้งค่าเป็น true จะส่งข้อมูลแบบทีละบล็อกผ่าน SSE และจะเพิ่มบล็อกข้อมูลที่มีข้อมูล usage เป็นบล็อกสุดท้ายโดยอัตโนมัติ |
max_tokens เปรียบเสมือนขนาดจานที่เสิร์ฟอาหาร หากจานเล็กเกินไป อาหารอาจยังไม่หมดจานก็ถูกเก็บไป ซึ่ง finish_reason จะเป็น length stop เปรียบเสมือนรหัสลับที่เชฟจะหยุดทำงานเมื่อได้ยินรหัสนี้ stream ไม่เปลี่ยนเนื้อหา แต่เปลี่ยนวิธีการส่งข้อมูล: จาก "ทำเสร็จทั้งหมดแล้วค่อยเสิร์ฟ" เป็น "ทำเสร็จคำละคำ" ทำให้ผู้ใช้รู้สึกว่าตอบสนองเร็วขึ้น
stop มีประโยชน์มาก: หากคุณกำหนดให้โมเดลตอบในรูปแบบ "คำถาม: ... คำตอบ: ... ###" และตั้งค่า ### เป็น stop การสร้างจะหยุดอัตโนมัติเมื่อพบตัวคั่น ช่วยประหยัดโทเคนและป้องกันไม่ให้โมเดลพูดเกินความจำเป็น หมายเหตุ: เมื่อหยุดเนื่องจาก stop finish_reason จะเป็น stop เช่นกัน หากคุณต้องการแยกแยะ ต้องตรวจสอบเนื้อหาด้วยตนเอง
tools และ tool_choice: ให้โมเดล "โทร" หาคุณ
โมเดลไม่สามารถดึงข้อมูลแบบเรียลไทม์ได้เอง วิธีการ function calling คือ: คุณแจ้งโมเดลก่อนว่ามีฟังก์ชันใดบ้าง เมื่อโมเดลตัดสินใจว่าจำเป็นต้องใช้ จะไม่ตอบโดยตรง แต่จะส่งกลับว่า "โปรดเรียกใช้ฟังก์ชัน某 พร้อมพารามิเตอร์...
| พารามิเตอร์ | ค่า | คำอธิบาย |
|---|---|---|
| tools | อาร์เรย์คำอธิบายฟังก์ชัน | แต่ละรายการประกอบด้วย name, description และ parameters ในรูปแบบ JSON Schema |
| tool_choice | "auto" / "none" / ฟังก์ชันที่กำหนด | auto ให้โมเดลตัดสินใจ, none ห้ามเรียกใช้, การระบุฟังก์ชันจะบังคับให้เรียกใช้ฟังก์ชันนั้น |
import json
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.apidamoxing.com/v1", api_key=os.environ["API_KEY"])
tools = [{
"type": "function",
"function": {
"name": "get_tide_time",
"description": "查询某港口今天的高潮时刻",
"parameters": {
"type": "object",
"properties": {"port": {"type": "string", "description": "港口名称"}},
"required": ["port"],
},
},
}]
messages = [{"role": "user", "content": "青岛今天几点涨潮?"}]
first = client.chat.completions.create(
model="uncensored", messages=messages, tools=tools, tool_choice="auto"
)
msg = first.choices[0].message
if msg.tool_calls:
call = msg.tool_calls[0]
args = json.loads(call.function.arguments)
result = {"port": args["port"], "high_tide": "14:20"} # 这里换成你自己的查询
messages.append(msg)
messages.append({"role": "tool", "tool_call_id": call.id, "content": json.dumps(result, ensure_ascii=False)})
final = client.chat.completions.create(model="uncensored", messages=messages, tools=tools)
print(final.choices[0].message.content)
else:
print(msg.content)กระบวนการทำงานมีสองขั้นตอน: ขั้นแรกได้รับ tool_calls ขั้นที่สองนำผลลัพธ์ที่มี role เป็น tool ไปเพิ่มแล้วส่งคำขอใหม่ การเขียน description ให้ชัดเจนจะช่วยให้โมเดลรู้เวลาที่เหมาะสมในการเรียกใช้ พารามิเตอร์เป็นสตริง JSON ควรใช้ json.loads เพื่อแยกวิเคราะห์และตรวจสอบความถูกต้อง อย่าไว้วางใจโดยตรง
ฟิลด์ตอบกลับ: อ่าน "ใบเสร็จ" ของการตอบกลับ
การตอบกลับที่สำเร็จมีโครงสร้างโดยประมาณดังนี้ โดยฟิลด์ต่างๆ มีค่าคงที่:
{
"id": "chatcmpl-xxxx",
"object": "chat.completion",
"model": "uncensored",
"choices": [
{
"index": 0,
"message": {"role": "assistant", "content": "因为潮汐锁定……"},
"finish_reason": "stop"
}
],
"usage": {"prompt_tokens": 38, "completion_tokens": 212, "total_tokens": 250}
}| ฟิลด์ | ความหมาย |
|---|---|
| choices | อาร์เรย์ผลลัพธ์ โดยปกติจะมีเพียงรายการเดียว เนื้อหาอยู่ใน choices[0].message.content |
| finish_reason | สาเหตุการสิ้นสุด: stop คือการสิ้นสุดปกติ; length คือการถูกตัดเมื่อถึง max_tokens; tool_calls คือโมเดลขอเรียกใช้ฟังก์ชัน |
| usage.prompt_tokens | โทเคนที่ใช้สำหรับข้อมูลนำเข้า |
| usage.completion_tokens | โทเคนที่ใช้สำหรับข้อมูลผลลัพธ์ |
| usage.total_tokens | ผลรวมของทั้งสอง |
ในโค้ดควรตรวจสอบ finish_reason ก่อน: หากเป็น length ให้แจ้งผู้ใช้ว่าเนื้อหาถูกตัดหรือเขียนต่ออัตโนมัติ; หากเป็น tool_calls ให้เข้าสู่ขั้นตอนการเรียกใช้ฟังก์ชัน บทบาทของ usage มีวิธีการคำนวณงบประมาณโดยละเอียดในtoken กับการ计费
ข้อผิดพลาดทั่วไปเกี่ยวกับพารามิเตอร์
- เข้าใจผิดว่า max_tokens คือ "ขีดจำกัดข้อมูลนำเข้า" มันควบคุมเฉพาะข้อมูลส่งออก ข้อมูลนำเข้าควบคุมโดยคุณ
- เข้าใจผิดว่าโมเดลจำคำขอครั้งก่อนได้ ทุกคำขอเป็นอิสระต่อกัน ประวัติต้องส่งมาเอง
- เข้าใจผิดว่าตั้งค่า temperature เป็น 0 แล้วผลลัพธ์จะเหมือนกันทุกครั้ง จะมีความเสถียรกว่า แต่ไม่ควรสมมติว่าผลลัพธ์จะตรงกันทุกตัวอักษร
- อ่าน choices[0].message โดยตรงในโหมดสตรีมมิง บล็อกข้อมูลสตรีมมิงมีฟิลด์เป็น delta ต้องนำข้อมูลมาต่อกันเอง
- ลืมเพิ่มข้อความ assistant ที่มี tool_calls หลังจากเรียกใช้ tool ทำให้เกิดข้อผิดพลาดในรอบที่สอง
ความหมายของรหัสข้อผิดพลาดและกลยุทธ์การเรียกซ้ำสามารถดูได้ในเอกสาร หากต้องการดูตัวอย่างที่เชื่อมโยงพารามิเตอร์เหล่านี้ทั้งหมด โปรดอ้างอิงบทความการสร้างแชทบอท
คำถามที่พบบ่อย
สามารถตั้งค่า temperature และ top_p พร้อมกันได้หรือไม่?
ทำได้ แต่ยากต่อการแยกแยะผลลัพธ์ที่ได้ ในสถานการณ์ส่วนใหญ่การปรับเพียง temperature ก็เพียงพอแล้ว ควรปรับ top_p เมื่อต้องการควบคุมขอบเขตของตัวเลือกอย่างละเอียด
ควรทำอย่างไรหาก finish_reason เป็น length?
แสดงว่าข้อมูลส่งออกถูกตัดเนื่องจากถึง max_tokens สามารถเพิ่มค่า max_tokens ได้สูงสุดถึง 32,000 หรือให้โมเดลสร้างข้อมูลแบบแบ่งส่วน
รูปแบบของ tools เหมือนกับ OpenAI หรือไม่?
ใช่ ใช้รูปแบบ tools และ tool_choice ของ OpenAI และโครงสร้าง tool_calls ในการตอบกลับก็เหมือนกัน
จะดึงข้อมูลการใช้งานในสตรีมมิงได้อย่างไร?
เมื่อเปิด stream ระบบจะเพิ่มบล็อกข้อมูลที่มี usage เป็นบล็อกสุดท้ายโดยอัตโนมัติ เพียงอ่านบล็อกนั้นก็ไม่จำเป็นต้องใช้พารามิเตอร์เพิ่มเติม
กรอกแบบฟอร์มเพื่อรับคีย์ API
สร้างบัญชี คัดลอกคีย์ และแก้ไข Base URL การตั้งค่าก็ง่ายเพียงเท่านี้