2-qism · Matn generatsiyasi·05-bob
Structured Outputs: qat'iy JSON formatda javob
Modelni erkin matn emas, aniq belgilangan JSON sxemasida javob berishga majburlash — dastur uchun ishonchli ma'lumot olish, sxema qoidalari va real xatolar.
Model javobini foydalanuvchiga o'qish uchun emas, dasturingizga
uzatish uchun ishlatsangiz (masalan, bazaga yozish, boshqa funksiyaga
argument sifatida berish), erkin matn muammo tug'diradi: bugun
{"ism": "Aziz"} qaytarsa, ertaga Ism: Aziz deb yozishi mumkin. Dastur
uchun bu — doimiy sinish xavfi.
1. Muammo: "iltimos JSON qaytar" yetarli emas#
Ko'p boshlovchi shunday yozadi:
response = client.responses.create(
model="gpt-4o-mini",
input="Aziz, 28 yoshda, Toshkentda yashaydi. Buni JSON qilib ber.",
)Bu ko'pincha ishlaydi, lekin kafolat yo'q. Model qo'shimcha izoh
qo'shib javob berishi (masalan, "Mana JSON: ..." deb boshlab), maydon
nomini o'zgartirishi yoki noto'g'ri turdagi qiymat qaytarishi mumkin
("yosh": "yigirma sakkiz" matn sifatida, raqam emas). Production
kodida json.loads() tasodifiy portlab turadi.
2. Yechim: qat'iy sxema berish#
text.format parametri orqali JSON Schema beriladi — model shu
sxemaga mos javob qaytarishga majburlanadi, erkin matn emas:
response = client.responses.create(
model="gpt-4o-mini",
input="Aziz, 28 yoshda, Toshkentda yashaydi.",
text={
"format": {
"type": "json_schema",
"name": "shaxs_malumoti",
"schema": {
"type": "object",
"properties": {
"ism": {"type": "string"},
"yosh": {"type": "integer"},
"shahar": {"type": "string"},
},
"required": ["ism", "yosh", "shahar"],
"additionalProperties": False,
},
"strict": True,
},
},
)
import json
data = json.loads(response.output_text)
print(data["ism"], data["yosh"], data["shahar"])strict: True — kalit so'z. Bu yoqilganda model sxemadan chetga
chiqa olmaydi: qo'shimcha maydon qo'sha olmaydi, talab qilingan
maydonni tashlab keta olmaydi, noto'g'ri tur qaytara olmaydi. Sxema —
kafolat, taxmin emas.
3. Pydantic bilan — Python'da qulayroq yo'l#
Sxemani qo'lda JSON sifatida yozish zerikarli va xatoga moyil. Python'da
pydantic klassidan avtomatik sxema chiqarish mumkin:
from pydantic import BaseModel
class ShaxsMalumoti(BaseModel):
ism: str
yosh: int
shahar: str
response = client.responses.parse(
model="gpt-4o-mini",
input="Aziz, 28 yoshda, Toshkentda yashaydi.",
text_format=ShaxsMalumoti,
)
shaxs = response.output_parsed
print(shaxs.ism, shaxs.yosh, shaxs.shahar) # to'g'ridan-to'g'ri Python obyekti.parse() metodi sxemani avtomatik quradi VA javobni qayta Pydantic
obyektiga aylantiradi — json.loads() ham, qo'lda tekshirish ham shart
emas. IDE'ingiz shaxs.ism deb yozganingizda avtokompleteni ko'rsatadi,
chunki bu — oddiy tiplangan Python obyekti.
4. Enum — cheklangan variantlar to'plami#
Ba'zan maydon cheksiz matn emas, balki oldindan belgilangan variantlardan biri bo'lishi kerak — masalan, "holat" faqat uchta qiymatdan biri bo'lsin:
from enum import Enum
from pydantic import BaseModel
class Holat(str, Enum):
OCHIQ = "ochiq"
JARAYONDA = "jarayonda"
YOPILGAN = "yopilgan"
class Murojaat(BaseModel):
mavzu: str
holat: Holat
response = client.responses.parse(
model="gpt-4o-mini",
input="Mijoz internet ulanishi ishlamayapti deb yozdi, hali hal bo'lmagan.",
text_format=Murojaat,
)
murojaat = response.output_parsed
print(murojaat.holat) # Holat.OCHIQ — model boshqa hech narsa qaytara olmaydiBu klassifikatsiya vazifalarida ayniqsa foydali — model "balki ochiq, balki yopilgan" kabi noaniq javob berish imkoniga umuman ega emas.
5. Murakkabroq sxema: ro'yxatlar va ichma-ich obyektlar#
from pydantic import BaseModel
class Mahsulot(BaseModel):
nomi: str
narxi: float
mavjud: bool
class Buyurtma(BaseModel):
mijoz_ismi: str
mahsulotlar: list[Mahsulot]
jami_narx: float
response = client.responses.parse(
model="gpt-4o-mini",
input="""
Mijoz Dilnoza. U ikkita narsa buyurtma qildi: noutbuk kompyuter — narxi
8500000 so'm, mavjud. Va simsiz sichqoncha — narxi 120000 so'm, hozircha
tugagan. Jami: 8620000 so'm.
""",
text_format=Buyurtma,
)
buyurtma = response.output_parsed
for mahsulot in buyurtma.mahsulotlar:
print(f"{mahsulot.nomi}: {mahsulot.narxi:,.0f} so'm — {'bor' if mahsulot.mavjud else 'yo\\'q'}")Model matndagi tabiiy tilni avtomatik ravishda to'g'ri turlangan
ma'lumotga aylantiradi — raqamlarni floatga, ha/yo'qni boolga. Bu —
noaniq matndan (email, foydalanuvchi xabari, hujjat) tuzilgan ma'lumot
ajratib olishning eng ishonchli yo'li.
6. refusal — model rad etganda nima bo'ladi#
Ba'zan model xavfsizlik siyosati asosida javob berishdan bosh tortadi (masalan, zararli so'rov bo'lsa). Structured Outputs bilan ishlaganda bu holat ham strukturalangan tarzda keladi, shuning uchun uni maxsus tekshirish kerak — aks holda kodingiz bo'sh yoki noto'g'ri ma'lumotni haqiqiy natija deb qabul qilib qo'yishi mumkin:
response = client.responses.parse(model="gpt-4o-mini", input="...", text_format=ShaxsMalumoti)
if response.output[0].content[0].type == "refusal":
print("Model javob berishdan bosh tortdi:", response.output[0].content[0].refusal)
else:
shaxs = response.output_parsed7. Qachon kerak, qachon ortiqcha#
- 01Javob to'g'ridan-to'g'ri dasturga (bazaga, funksiyaga, API'ga) ketayotgan bo'lsa — Structured Outputs ishlating.
- 02Javob shunchaki foydalanuvchiga o'qish uchun matn bo'lsa (masalan, chat javobi) — sxema shart emas, ortiqcha murakkablik qo'shadi.
- 03"Model bu formatda javob berishi kerak" degan har qanday talab — bu sxema kerakligining belgisi.
- 04strict: True har doim yoqing, agar SDK'ingiz qo'llab-quvvatlasa — u xato ehtimolini deyarli nolga tushiradi.
- 05Cheklangan variantlar (holat, kategoriya) uchun erkin string emas, enum ishlating.
8. Nima noto'g'ri ketishi mumkin#
| Belgi | Sabab | Yechim |
|---|---|---|
additionalProperties xatosi | strict: True bilan bu maydon unutilgan | Sxemaga "additionalProperties": false qo'shing |
| Ixtiyoriy maydon xato beradi | strict rejimida hamma maydon required'da bo'lishi kerak | Ixtiyoriy maydonni ["string", "null"] turi bilan belgilang |
output_parsed bo'sh yoki None | Model rad etgan (refusal) | Har doim refusal holatini alohida tekshiring |
| Sxema juda murakkab deb rad etiladi | Ichma-ich darajalar yoki maydonlar soni chegaradan oshgan | Sxemani soddalashtiring yoki bir necha kichikroq so'rovga bo'ling |
Chek ma'lumotini sxemaga soling
Erkin matn ko'rinishidagi (masalan, "Bugun, 14-sentabr, do'kondan non — 8000 so'm va sut — 15000 so'm oldim") xabarni qat'iy sxemaga ega tuzilgan ma'lumotga aylantiruvchi Pydantic klass va so'rov yozing. Natijada jami summani ham avtomatik hisoblatib ko'ring (modeldan so'rang yoki o'zingiz Python'da yig'indini oling — ikkala yondashuvni solishtiring).
Maslahatni ko'rsatish
Pydantic klassida DokonNomi, Sana, JamiSumma va Mahsulotlar (ro'yxat, har biri Nomi+Narxi) maydonlarini aniqlang. Namunaviy matnni qo'lda yozib, .parse() orqali sinab ko'ring.