อัปเดต
การสร้างแอปภาษาจีน: พรอมต์ การควบคุมสคริปต์ และ UTF-8
การส่งฟีเจอร์ภาษาจีนส่วนใหญ่เป็นปัญหาการแปลและปรับแต่ง ไม่ใช่ปัญหาโมเดล คุณตัดสินใจว่าจะให้ผู้ใช้เห็นสคริปต์ใด รักษาการเข้ารหัสให้สะอาดตั้งแต่ไฟล์จนถึงการส่งข้อมูล และวางแผนโทเคนสำหรับข้อความที่ไม่มีการแบ่งคำด้วยช่องว่าง คู่มือนี้ครอบคลุมชั้นทั้งสามด้วยโค้ดที่คุณสามารถรันกับเอนด์พอยต์ chat completions ได้วันนี้
สิ่งที่คุณกำลังเชื่อมต่อ
บริการเปิดเผย POST /v1/chat/completions และ GET /v1/models ภายใต้ https://api.chinesellmapi.com/v1 การตรวจสอบสิทธิ์คือคีย์แบบ bearer และ id ของโมเดลมีเพียง uncensored เท่านั้น เป็น API ข้อความล้วนที่มีโมเดลเดียว จึงไม่มีอะไรให้เลือก: การทำงานด้านการแปลและปรับแต่งของคุณเกิดขึ้นทั้งหมดในพรอมต์และในโค้ดของคุณที่ล้อมรอบมัน
ข้อจำกัดที่ควรรู้ก่อนออกแบบ: หน้าต่างบริบท 100,000 โทเคนที่ใช้ร่วมกันระหว่างพรอมต์และการสร้างผลลัพธ์, max_tokens ค่าเริ่มต้นที่ 2,048 โดยมีเพดานที่ 32,000, ร่างคำขอขนาดสูงสุด 8 MB และ 300 คำขอต่อนาทีต่อคีย์ การสตรีม (stream: true) ทำงานผ่าน server-sent events และเครื่องมือในรูปแบบการเรียกใช้ฟังก์ชันของ OpenAI ได้รับการยอมรับ
บัญชีใหม่ได้รับเครดิตทดลองใช้ $0.50 ใช้ได้ 7 วัน ไม่ต้องใส่รายละเอียดการชำระเงิน ลงทะเบียนด้วยอีเมลและรหัสผ่าน คีย์จะปรากฏทันที ดู FAQ การทดลองใช้ เพื่อรายละเอียดกฎ
เขียนพรอมต์เป็นภาษาจีน และระบุว่าเป็นภาษาจีนแบบไหน
พรอมต์ภาษาผสมเป็นแหล่งที่มาของการเบี่ยงเบนที่พบบ่อยที่สุดในฟีเจอร์ที่แปล หากคำแนะนำเป็นภาษาอังกฤษแต่เนื้อหาเป็นภาษาจีน คำตอบบางครั้งอาจกลับมาเป็นภาษาอังกฤษหรือผสมกัน รูปแบบที่เชื่อถือได้คือพรอมต์ระบบที่เขียนในภาษาเป้าหมาย โดยระบุสามสิ่ง: บทบาท สคริปต์ และคำศัพท์ภูมิภาค เก็บข้อความที่ผู้ใช้ให้ไว้ในข้อความแยกต่างหากเพื่อให้ไม่ถูกเข้าใจผิดว่าเป็นคำแนะนำ
นี่คือการตั้งค่าภาษาจีนตัวย่อ หมายเหตุว่าพรอมต์ระบบบอกโมเดลให้ตอบเฉพาะในอักขระจีนตัวย่อและหลีกเลี่ยงภาษาอังกฤษที่หลุดมา โดยยกเว้นชื่อเฉพาะ:
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.chinesellmapi.com/v1",
api_key=os.environ["API_KEY"],
)
SYSTEM_SC = (
"你是一名产品文案助手。始终使用简体中文回答,使用中国大陆常见的用词和标点,"
"不要夹杂繁体字或英文句子,专有名词除外。"
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": SYSTEM_SC},
{"role": "user", "content": "为一款记账应用写三条应用商店的一句话简介。"},
],
max_tokens=300,
temperature=0.7,
)
print(resp.choices[0].message.content)
print(resp.usage)
สองนิสัยที่ให้ผลตอบแทนอย่างรวดเร็ว ประการแรก รักษาพรอมต์ให้สั้นและเฉพาะเจาะจง: บทบาท รูปแบบเอาต์พุต ข้อจำกัดหนึ่งหรือสองประการ ประการที่สอง ใส่ข้อกำหนดภาษาในข้อความระบบแทนที่จะทำซ้ำในทุกการโต้ตอบของผู้ใช้ เพื่อให้ประวัติการสนทนาไม่ทำให้เจือจาง
การควบคุมผลลัพธ์ระหว่างจีนตัวย่อและจีนตัวเต็ม
การเลือกสคริปต์เป็นตัวเลือกผลิตภัณฑ์ที่เชื่อมโยงกับภูมิภาคผู้ใช้ ไม่ใช่การตั้งค่าโมเดล ผลิตภัณฑ์ที่มุ่งเน้นแผ่นดินใหญ่ต้องการตัวอักษร Simplified; ผู้ชมในไต้หวันและฮ่องกงต้องการตัวอักษร Traditional พร้อมคำศัพท์ที่แตกต่างกัน (ตัวอย่างทั่วไปคือคำศัพท์ด้านซอฟต์แวร์ เครือข่าย และฐานข้อมูล) วิธีปฏิบัติคือแมปแท็กภูมิภาคของคุณเข้ากับระบบพรอมต์และทำให้การเลือกนั้นชัดเจนในโค้ด
- zh-CN, zh-SG: จีนตัวย่อ, คำศัพท์แผ่นดินใหญ่, ตัวเลขกึ่งความกว้าง, เครื่องหมายวรรคตอนภาษาจีนความกว้างเต็ม
- zh-TW: จีนตัวเต็ม, คำศัพท์ไต้หวัน, วงเล็บเหลี่ยมสำหรับการอ้างอิงเป็นสิ่งที่พบได้ทั่วไป
- zh-HK: ตัวเต็มพร้อมคำศัพท์ฮ่องกง จัดเตรียมกLOSSARY สั้นๆ หากผลิตภัณฑ์ของคุณมีคำศัพท์คงที่
รูปแบบตัวเต็มของการเรียกเดียวกันดูเหมือนนี้; มีเพียงพรอมต์ระบบที่เปลี่ยนแปลง:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.chinesellmapi.com/v1", api_key=os.environ["API_KEY"])
SYSTEM_TC = (
"你是一名產品文案助手。請一律使用繁體中文回答,採用臺灣常用的詞彙與全形標點,"
"例如「軟體」「網路」「資料庫」,不要混入簡體字。"
)
resp = client.chat.completions.create(
model="uncensored",
messages=[
{"role": "system", "content": SYSTEM_TC},
{"role": "user", "content": "請用兩句話說明什麼是雙重驗證。"},
],
max_tokens=200,
)
print(resp.choices[0].message.content)
โมเดลอาจรั่วไหลอักขระไม่กี่ตัวจากสคริปต์อื่นเป็นครั้งคราว โดยเฉพาะเมื่อข้อความของผู้ใช้เองอยู่ในสคริปต์อื่น เพิ่มการตรวจสอบหลังการส่งที่ราคาถูกและลองใหม่หนึ่งครั้งด้วยคำแนะนำที่เข้มงวดกว่าหากมันผิดพลาด สำหรับสิ่งใดๆ ที่เกินกว่าการตรวจสอบตัวอย่าง ให้รันเอาต์พุตผ่านไลบรารีตัวแปลงเฉพาะเช่น OpenCC:
# A cheap guard: flag replies that contain characters that exist only in Simplified.
# The set below is a small sample, not a full list; use a converter such as OpenCC
# for production-grade checks.
SIMPLIFIED_ONLY = set("这个们说话时间书买卖东车门开关见觉")
def looks_simplified(text: str) -> bool:
return any(ch in SIMPLIFIED_ONLY for ch in text)
reply = "請用繁體中文回覆的範例文字"
print(looks_simplified(reply)) # False
UTF-8 จากดิสก์ไปยังสายส่งและกลับ
ข้อบกพร่องส่วนใหญ่ที่ทำให้ข้อความภาษาจีนเพี้ยนไม่ใช่ปัญหาของโมเดล มันมาจากค่าการเข้ารหัสเริ่มต้นในบางจุดของระบบ: คอนโซล Windows ที่ใช้หน้ารหัสแบบเก่า, ไฟล์ CSV ที่เปิดโดยไม่ระบุการเข้ารหัส, หรือพร็อกซีที่เขียนใหม่ content type ให้ชัดเจนในทุกจุดเชื่อมต่อ
ใน Python ส่ง encoding="utf-8" ไปยัง open และหากคุณสร้าง JSON ด้วยตนเอง ให้ใช้ ensure_ascii=False ตามด้วย .encode("utf-8") ตัวอย่างด้านล่างทำสิ่งนั้นด้วย requests ซึ่งยังแสดงรูปร่าง HTTP ดิบของการเรียก:
import json
import os
import requests
# 1) Always open files as UTF-8, never rely on the platform default encoding.
with open("notes_zh.txt", "r", encoding="utf-8") as f:
note = f.read()
payload = {
"model": "uncensored",
"messages": [{"role": "user", "content": "请把下面的笔记整理成三个要点:\n" + note}],
"max_tokens": 400,
}
# 2) requests encodes json= as UTF-8 for you. If you build the body by hand,
# keep Chinese readable and make the encoding explicit.
body = json.dumps(payload, ensure_ascii=False).encode("utf-8")
r = requests.post(
"https://api.chinesellmapi.com/v1/chat/completions",
headers={
"Authorization": "Bearer " + os.environ["API_KEY"],
"Content-Type": "application/json; charset=utf-8",
},
data=body,
timeout=60,
)
r.raise_for_status()
r.encoding = "utf-8"
print(r.json()["choices"][0]["message"]["content"])
ใน Node, readFile จะคืนค่า Buffer เว้นแต่คุณจะระบุการเข้ารหัส และเทมเพลตสตริงที่มีภาษาจีนก็ใช้ได้ตราบใดที่ไฟล์ต้นฉบับบันทึกเป็น UTF-8 SDK ทางการจะแปลงร่างข้อมูลเป็น JSON string ให้คุณ:
import { readFile } from "node:fs/promises";
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.chinesellmapi.com/v1",
apiKey: process.env.API_KEY,
});
// Pass "utf8" explicitly; without it readFile returns a Buffer, not a string.
const note = await readFile("notes_zh.txt", "utf8");
const res = await client.chat.completions.create({
model: "uncensored",
messages: [{ role: "user", content: `请把下面的笔记整理成三个要点:\n${note}` }],
max_tokens: 400,
});
console.log(res.choices[0].message.content);
console.log(res.usage);
กับดักอีกสองประการ การตัดสตริงด้วยความยาวไบต์สามารถตัดตัวอักษรได้ครึ่งหนึ่ง ดังนั้นให้ตัดตามตัวอักษรเสมอ และเมื่อคุณสตรีม ให้ถอดรหัสสตรีมเป็น UTF-8 แบบเพิ่มทีละส่วน เนื่องจากอักขระหลายไบต์อาจถูกแบ่งข้ามชิ้นส่วนเครือข่าย SDK จัดการสิ่งนี้ แต่ตัวประมวลผลที่เขียนขึ้นเองมักจะไม่ทำ
การจัดสรรโทเคนสำหรับข้อความภาษาจีน
ภาษาจีนไม่มีช่องว่าง ดังนั้นการนับคำจึงไร้ประโยชน์สำหรับการวางแผนโทเคน ในฐานะสมมติฐานการวางแผน ไม่ใช่ค่าคงที่ที่วัดได้ ให้พิจารณาตัวอักษรจีนหนึ่งตัวเป็นประมาณ 1 ถึง 2 โทเคน และใช้ 1.5 เมื่อคุณต้องการตัวเลขเดียว คำและตัวเลขภาษาละตินที่ฝังอยู่ในข้อความใกล้เคียงกับ 1.3 โทเคนต่อคำ อัตราส่วนนี้แตกต่างกันไปตามคำศัพท์ ดังนั้นตัวเลขที่มีอำนาจสูงสุดคือวัตถุ usage ที่ส่งกลับมาพร้อมกับการตอบกลับทุกครั้ง
ตัวช่วยเล็กๆ ทำให้ง่ายต่อการประมาณการพรอมต์ก่อนที่คุณจะส่งมัน และปรับอัตราส่วนให้ตรงกับการใช้งานจริงเมื่อเวลาผ่านไป:
import re
CJK = re.compile(r"[㐀-鿿- -〿]")
def rough_tokens(text: str, per_cjk: float = 1.5, per_other_word: float = 1.3) -> int:
"""Planning estimate only. The 1.5 and 1.3 ratios are assumptions, not
measured values; compare against resp.usage and adjust them."""
cjk = len(CJK.findall(text))
others = len(re.findall(r"[A-Za-z0-9_]+", CJK.sub(" ", text)))
return round(cjk * per_cjk + others * per_other_word)
sample = "订单 A-1042 已发货,预计周三送达。"
print(rough_tokens(sample))
ตัวอย่างที่ทำงานได้ พร้อมสมมติฐานที่ระบุ: บทความ 2,000 ตัวอักษรที่ 1.5 โทเคนต่อตัวอักษรคือประมาณ 3,000 โทเคนอินพุต สรุปความยาว 400 ตัวอักษรคือประมาณ 600 โทเคนเอาต์พุต ที่ $0.25 ต่อล้านโทเคนอินพุตและ $1.00 ต่อล้านโทเคนเอาต์พุต การเรียกหนึ่งครั้งมีค่าใช้จ่ายประมาณ $0.00075 สำหรับอินพุตบวก $0.0006 สำหรับเอาต์พุต รวมประมาณ $0.00135 เนื่องจากบริบทถูกจำกัดที่ 100,000 โทเคน สมมติฐานเดียวกันหมายถึงพรอมต์ขนาดประมาณ 40,000 ตัวอักษรเหลือพื้นที่สำหรับการตอบกลับ
เมื่อคุณต้องป้อนเอกสารยาว ให้แบ่งตามย่อหน้าหรือหัวข้อ อย่าแบ่งกลางประโยค และรักษา max_tokens ให้ชัดเจน ราคาและข้อจำกัดแสดงอยู่ในหน้า pricing
การรักษาแชทภาษาจีนหลายรอบภายในหน้าต่าง
ฟีเจอร์แชทจะส่งประวัติทั้งหมดอีกครั้งในทุกคำขอ ดังนั้นต้นทุนและบริบทจึงเพิ่มขึ้นในแต่ละรอบ เนื่องจากหน้าต่างมี 100,000 โทเคนที่ใช้ร่วมกันระหว่างพรอมต์และการสร้างผลลัพธ์ การสนทนาที่ยาวนานจะกระตุ้นข้อผิดพลาด 400 หากคุณไม่ทำอะไรเลย ตัดสินใจนโยบายการตัดทอนแต่เนิ่นๆ แทนที่จะตอบสนองต่อข้อผิดพลาด
นโยบายอย่างง่ายคือการรักษาพรอมต์ระบบ ลบการโต้ตอบที่เก่าที่สุดจนกว่าพรอมต์ที่ประมาณการจะพอดีกับงบประมาณ และสงวนส่วนที่เหลือสำหรับการตอบกลับ สเก็ตช์ด้านล่างนำตัวประมาณการจากส่วนก่อนหน้ามาใช้ใหม่:
MAX_PROMPT_TOKENS = 48_000 # leave headroom under the 100,000 window for the reply
def trim_history(messages, estimate):
# messages[0] is the system prompt and is always kept
system, rest = messages[0], messages[1:]
while rest and sum(estimate(m["content"]) for m in [system] + rest) > MAX_PROMPT_TOKENS:
rest.pop(0) # drop the oldest turn first
return [system] + rest
สำหรับผลิตภัณฑ์ที่บริบทช่วงต้นสำคัญ เช่น บอทสอนหนังสือหรือผู้ช่วยสนับสนุน ให้แทนที่การสนทนาที่หายไปด้วยข้อความสรุปสั้นๆ แทนที่จะทิ้งไปเลย สั่งให้โมเดลบีบอัดการสนทนาเก่าให้เหลือไม่กี่ประโยคในสคริปต์เดียวกัน แล้วแทรกข้อความสรุปหลังพรอมต์ระบบทันที วิธีนี้ต้องเรียกโมเดลเพิ่มเป็นครั้งคราวแต่ช่วยรักษาบุคลิกและข้อเท็จจริงให้คงที่
อย่าลืมจำกัด max_tokens อย่างมีเหตุผลสำหรับการแชท คำตอบใน UI การส่งข้อความมักไม่ต้องการโทเคนมากกว่าไม่กี่ร้อย และการจำกัดที่แน่นขึ้นทำให้ทั้งความล่าช้าและต้นทุนคาดเดาได้มากขึ้น การสตรีมการตอบกลับโทเคนต่อโทเคนช่วยความเร็วที่รับรู้ได้ โดยเฉพาะสำหรับข้อความภาษาจีนที่ผู้ใช้อ่านเป็นช่วงสั้นๆ
รายการตรวจสอบก่อนเปิดตัวและขั้นตอนถัดไป
- แมปลโลเกิลแต่ละรายการกับพรอมต์ระบบและทดสอบหน่วยการแมป
- ตั้งค่าการเข้ารหัสอย่างชัดเจนในการอ่านไฟล์ ร่างคำขอและล็อก
- บันทึก
usageต่อฟีเจอร์และเปรียบเทียบกับตัวประมาณการของคุณเป็นรายสัปดาห์ - จัดการ 402 (
no_credit), 429 และ 503 (upstream_busy) ต่างกัน: เติมเงิน, ลดความเร็ว, ลองใหม่หลังจากนั้นไม่กี่วินาที - พิจารณา 403 (
content_blocked) เป็นคำตอบสุดท้ายสำหรับการเรียกนั้น ไม่ใช่กรณีการลองใหม่
หากแอปของคุณเกี่ยวข้องกับกระบวนการแปล ให้ดำเนินการต่อด้วย คู่มือการแปลและการปรับโลคัลไลเซชัน; สำหรับนิยายต่อเนื่องและการแชทตัวละคร ดู คู่มือเว็บนิยาย เอกสารอ้างอิงพารามิเตอร์เต็มรูปแบบอยู่ใน เอกสาร
ถาม-ตอบ
ฉันจะทำให้การตอบกลับเป็นภาษาจีนตัวย่อเท่านั้นได้อย่างไร
ระบุในพรอมต์ระบบภาษาจีน เช่น "ตอบเป็นภาษาจีนตัวย่อเสมอโดยใช้คำศัพท์จากแผ่นดินใหญ่" รักษาคำสั่งนี้ไว้ในข้อความระบบและเพิ่มการตรวจสอบหลังการประมวลผลหากต้องการความเข้มงวด
สามารถขอภาษาจีนตัวเต็มสำหรับผู้ใช้ไต้หวันได้หรือไม่
ใช่ ใช้พรอมต์ระบบที่เขียนด้วยอักขระจีนตัวเต็มซึ่งระบุคำศัพท์ภูมิภาคที่คุณต้องการ และแมปมันจากโลเคิล zh-TW ในโค้ดของคุณ
ทำไมฉันถึงเห็นตัวอักษรจีนที่อ่านไม่ออกในการแสดงผลของฉัน
เกือบทุกครั้งเป็นปัญหาการเข้ารหัสฝั่งไคลเอนต์ อ่านไฟล์เป็น UTF-8 ตั้งค่า charset ของประเภทเนื้อหา และตรวจสอบให้แน่ใจว่าเทอร์มินัลหรือโปรแกรมดูล็อกของคุณใช้ UTF-8 เช่นกัน
ข้อความภาษาจีนใช้โทเคนจำนวนเท่าใด
วางแผนโดยประมาณที่ 1.5 โทเคนต่อตัวอักษร จากนั้นตรวจสอบฟิลด์ usage ในการตอบกลับแต่ละครั้งและปรับประมาณการของคุณ
คีย์ของคุณอยู่ห่างแค่แบบฟอร์มเดียว
สร้างบัญชี คัดลอกคีย์ เปลี่ยน base URL นั่นคือการตั้งค่าทั้งหมด