07 β Vision va hujjatlar¶
β¬ οΈ Oldingi: 06 β Strukturali chiqish Β· π Kitob boshi Β· Keyingi: 08 β Xatolar va ishonchlilik β‘οΈ
Bu bobda: modelga nafaqat matn, balki rasm va PDF hujjat ham yuborishni o'rganamiz. Rasmni base64 yoki URL orqali jo'natamiz, formatlar va cheklovlarni ko'ramiz. Keyin ikkita amaliy ish quramiz: chek/kvitansiyadan summa-sana-do'konni ajratish (OCR + strukturali chiqish) va mahsulot rasmini tavsiflash. Oxirida PDF hujjatdan savol-javob qilamiz va hammasini birlashtirib "chek tahlilchisi" dasturini yozamiz.
Multimodal nima?¶
Hozirgacha biz modelga faqat matn yuborardik: savol yozasiz, model matn bilan javob beradi. Lekin zamonaviy modellar bundan ko'proqni qila oladi β ular rasmni ham "ko'ra oladi".
Hayotiy o'xshatish. Tasavvur qiling, sizning yordamchingiz bor. Avval u faqat siz yozgan xatlarni o'qiy olardi. Endi esa unga rasm ko'rsatsangiz ("mana bu chekka qara, qancha pul ketdi?"), u rasmga qarab javob beradi. Ya'ni yordamchi endi ko'zli β quloq (matn) ustiga ko'z (rasm) qo'shildi.
Bir necha turdagi ma'lumotni (matn + rasm + hujjat) bir vaqtda tushuna oladigan model multimodal deyiladi (multi = ko'p, modal = ma'lumot turi). Bizning Claude modellarimiz multimodal: bitta so'rovga matn ham, rasm ham, PDF ham qo'sha olasiz.
Buni qayerda ishlatamiz? Mana eng keng tarqalgan vazifalar:
- Rasm tavsifi β rasmda nima borligini so'z bilan aytib berish (mahsulot, manzara, vaziyat).
- OCR (rasmdan matn) β surat ichidagi yozuvni matnga o'girish (chek, varaqa, yo'lyo'riq, vizitka).
- Chek/hujjat tahlili β kvitansiyadan summa, sana, do'kon nomini ajratish; shartnomadan muhim shartlarni topish.
- Diagramma/grafik tushunish β sxema yoki grafikni o'qib, undagi ma'noni izohlash.
- Klassifikatsiya β rasmni kategoriyaga ajratish (bu kiyim? oziq-ovqat? texnika?).
Eslatma
Multimodal β bu tushunchaning o'zi provayderga bog'liq emas. OpenAI (GPT), Gemini va boshqa yetuk modellar ham rasmni "ko'radi". Biz kodni Claude PHP SDK'da yozamiz, lekin g'oya (rasm bloki + matn bloki yuborish) hamma joyda bir xil.
Rasm yuborish β base64 orqali¶
Eng asosiy savol: rasmni so'rovga qanday qo'shamiz? Eslang, 4-bobda har xabarning content maydoni oddiy matn satri edi:
Rasm yuborganda content endi satr emas, balki bloklar massivi bo'ladi. Har blok β bu bitta "bo'lak": biri rasm, biri matn. Modelga "mana rasm, mana mening savolim" deb beramiz.
Eng ko'p ishlatiladigan usul β rasmni base64 ga aylantirish. Base64 β bu faylning baytlarini oddiy matn (harf-raqamlar) ko'rinishiga o'tkazadigan kodlash. Nega kerak? Chunki API'ga so'rovni matn (JSON) sifatida yuboramiz, rasm esa "ikkilik" fayl β uni avval matnga aylantirmasak, JSON ichiga sig'maydi.
Hayotiy o'xshatish. Base64 β bu rasmni pochta orqali yuborish uchun konvertga solish. Rasmning o'zini "telefon orqali" ayta olmaysiz; lekin uni harflar zanjiriga (konvert) o'rab, matn sifatida jo'natasiz, narigi tomon esa konvertni ochib rasmni qayta yig'adi.
PHP'da bu ikki funksiya bilan bajariladi: file_get_contents() faylni o'qiydi, base64_encode() uni base64 matnga aylantiradi.
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
// 1) Faylni o'qib, base64 matnga aylantiramiz
$baytlar = file_get_contents('mushuk.png'); // rasm fayli baytlari
$base64 = base64_encode($baytlar); // base64 matn
// 2) content β bloklar massivi: rasm bloki + matn bloki
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => [
'type' => 'base64',
'media_type' => 'image/png', // rasm turi (pastda jadval)
'data' => $base64, // base64 matn
],
],
[
'type' => 'text',
'text' => 'Bu rasmda nima bor? O\'zbek tilida tasvirlab ber.',
],
],
]],
);
// 3) Javobni o'qiymiz (matn bloki)
echo $message->content[0]->text;
Diqqat qiling: content ichida ikki blok bor β birinchisi 'type' => 'image' (rasm), ikkinchisi 'type' => 'text' (savol). Model ikkalasini birga ko'radi: rasmga qarab, savolingizga javob beradi.
'source' ichidagi maydonlar:
'type' => 'base64'β rasmni base64 sifatida yuborayotganimizni bildiradi.'media_type'β rasm formati (image/png,image/jpeg, ...). Buni xato bermaslik kerak β fayl PNG bo'lsaimage/pngyozing.'data'β base64 matnning o'zi.
Ehtiyot bo'ling
media_type rasm formatiga mos bo'lsin. JPEG faylga image/png yozsangiz xato chiqishi mumkin. Fayl kengaytmasidan formatni aniqlang yoki PHP'ning mime_content_type('rasm.png') funksiyasidan foydalaning.
Rasm yuborish β URL orqali¶
Agar rasm allaqachon internetda joylashgan bo'lsa (masalan, saytingizdagi mahsulot surati), uni base64 ga aylantirish shart emas β to'g'ridan-to'g'ri havola (URL) bera olasiz. Bunda source turi 'url' bo'ladi:
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
[
'type' => 'image',
'source' => [
'type' => 'url',
'url' => 'https://example.com/mahsulot.jpg',
],
],
['type' => 'text', 'text' => 'Bu mahsulotni qisqa tasvirlab ber.'],
],
]],
);
echo $message->content[0]->text;
URL holatida biz faylni o'qimaymiz va kodlamaymiz β model rasmni o'zi havoladan yuklab oladi. Kod ham qisqaroq.
Qachon qaysi usul?
| Holat | Tavsiya |
|---|---|
| Rasm sizning serveringizda fayl (yuklangan) | base64 β faylni o'qib yuborasiz |
| Rasm foydalanuvchi yuborgan (forma orqali yuklangan) | base64 β vaqtinchalik faylni kodlaysiz |
| Rasm allaqachon ochiq internetda (URL bor) | URL β havolani berasiz, qulayroq |
| Rasm maxfiy/ichki tarmoqda (internetdan ko'rinmaydi) | base64 β model URL'ga yeta olmaydi |
Maslahat
URL usulida rasm ommaviy (login talab qilmaydigan) havolada bo'lishi kerak β aks holda model uni yuklab ololmaydi. Ishonchingiz komil bo'lmasa, base64 doim ishonchli ishlaydi.
Formatlar va cheklovlar¶
Model har qanday faylni emas, balki bir nechta keng tarqalgan rasm formatlarini qo'llab-quvvatlaydi. media_type ga shulardan birini yozasiz:
| Format | media_type |
|---|---|
| PNG | image/png |
| JPEG | image/jpeg |
| GIF | image/gif |
| WebP | image/webp |
Bilib qo'yishingiz kerak bo'lgan amaliy cheklovlar:
- Hajm chegarasi bor. Juda katta rasmni (masalan, o'nlab megabaytli foto) avval kichraytirgan ma'qul. Amalda 5 MB atrofidagi rasm xavfsiz; kattasini siqib (resize) yuboring.
- Bir nechta rasmni bitta so'rovga qo'shsa bo'ladi.
contentmassiviga bir nechtaimageblok joylashtiring β model hammasini ko'radi va taqqoslay oladi. - Har rasm tokenlarni "yeydi". Rasm qancha katta/aniq bo'lsa, shuncha ko'p token sarflaydi (ya'ni qimmatroq). Kerakmas darajada katta rasm yubormang.
Bir nechta rasm yuborishga misol β ikki mahsulotni taqqoslash:
// Ikki rasmni base64 ga aylantiramiz
$rasm1 = base64_encode(file_get_contents('mahsulot1.jpg'));
$rasm2 = base64_encode(file_get_contents('mahsulot2.jpg'));
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
['type' => 'text', 'text' => 'Birinchi rasm:'],
['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => $rasm1]],
['type' => 'text', 'text' => 'Ikkinchi rasm:'],
['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => $rasm2]],
['type' => 'text', 'text' => 'Bu ikki mahsulotning farqini ayt.'],
],
]],
);
echo $message->content[0]->text;
Bu yerda matn bloklarini rasmlardan oldin qo'yib, modelga "qaysi rasm qaysi" ekanini tushuntirdik. Bu β yaxshi odat: bir nechta rasmda har biriga nom/izoh bering.
Maslahat
Rasmni kichraytirish kerak bo'lsa, PHP'ning GD yoki Imagick kengaytmasidan foydalaning (imagescale(), imagejpeg() sifatni pasaytirib saqlaydi). Bu xarajatni ham, hajmni ham kamaytiradi.
Amaliy 1 β chekdan ma'lumot ajratish (OCR + extraction)¶
Endi haqiqiy misol. Tasavvur qiling, foydalanuvchilar do'kondan chek (kvitansiya) suratini yuklaydi, biz esa do'kon nomi, sana va umumiy summani avtomatik ajratib olib, bazaga yozmoqchimiz. Qo'lda terish o'rniga β model o'qib bersin.
Bu yerda ikki narsani birlashtiramiz: vision (rasmni o'qish) + strukturali chiqish (6-bobda o'rgangan outputConfig bilan JSON obyekt olish). Natijada model bizga aralash matn emas, balki tayyor PHP obyektini qaytaradi.
Avval natija shaklini klass bilan ta'riflaymiz (6-bobdagidek, StructuredOutputModel):
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
use Anthropic\Lib\Contracts\StructuredOutputModel;
use Anthropic\Lib\Concerns\StructuredOutputModelTrait;
// Chekdan ajratiladigan ma'lumot shakli
class Chek implements StructuredOutputModel
{
use StructuredOutputModelTrait;
public string $dokon; // do'kon nomi
public string $sana; // YYYY-MM-DD ko'rinishida
public float $summa; // umumiy summa (raqam)
}
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
// Chek rasmini base64 ga aylantiramiz
$chekRasm = base64_encode(file_get_contents('chek.jpg'));
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => $chekRasm]],
['type' => 'text', 'text' => 'Bu chek. Do\'kon nomi, sana va umumiy summani ajratib ber. Summani faqat raqam qil.'],
],
]],
outputConfig: ['format' => Chek::class], // strukturali chiqish
);
// Natija β validatsiyalangan Chek obyekti
$chek = $message->content[0]->parsed;
echo "Do'kon: {$chek->dokon}\n";
echo "Sana: {$chek->sana}\n";
echo "Summa: {$chek->summa}\n";
E'tibor bering: bu xuddi 6-bobdagi strukturali chiqish, faqat content ga rasm bloki qo'shildi. Model rasmni o'qiydi (OCR), kerakli ma'lumotni topadi va Chek shakliga soladi. Endi $chek->summa to'g'ridan-to'g'ri bazaga yoziladigan raqam β qo'lda tahlil shart emas.
Misol β bazaga yozish
Mana shu β "buxgalter yordamchisi" prototipi: foydalanuvchi chek suratini yuklaydi, dastur summani o'zi bazaga kiritadi.Ehtiyot bo'ling
Model β sehrgar emas. Surat xira, qiyshiq yoki yarmi ko'rinmasa, summani noto'g'ri o'qishi mumkin. Pul bilan ishlaganda doim natijani tekshirib ko'rsating (foydalanuvchiga "summa 16 000 to'g'rimi?" deb tasdiqlatish) β buni mashinaga to'liq ishonib qo'ymang.
Amaliy 2 β rasm klassifikatsiya va tavsif¶
Ikkinchi keng tarqalgan vazifa β mahsulot rasmini tavsiflash va kategoriyaga ajratish. Masalan, onlayn do'konga sotuvchi rasm yuklaydi, biz unga avtomatik sarlavha, tavsif va kategoriya yaratib beramiz.
Bu ham vision + strukturali chiqishning birlashmasi. Natija shaklini ta'riflaymiz:
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
use Anthropic\Lib\Contracts\StructuredOutputModel;
use Anthropic\Lib\Concerns\StructuredOutputModelTrait;
class MahsulotTavsifi implements StructuredOutputModel
{
use StructuredOutputModelTrait;
public string $sarlavha; // qisqa nom
public string $kategoriya; // masalan: "kiyim", "texnika", "oziq-ovqat"
public string $tavsif; // 1-2 jumlali tavsif
/** @var string[] */
public array $teglar; // qidiruv uchun kalit so'zlar
}
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
$rasm = base64_encode(file_get_contents('mahsulot.jpg'));
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
system: 'Sen onlayn do\'kon uchun mahsulot kartochkalari tayyorlaysan. Qisqa va sotuvchi tilda yoz.',
messages: [[
'role' => 'user',
'content' => [
['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => 'image/jpeg', 'data' => $rasm]],
['type' => 'text', 'text' => 'Bu mahsulot uchun sarlavha, kategoriya, tavsif va teglar yarat.'],
],
]],
outputConfig: ['format' => MahsulotTavsifi::class],
);
$m = $message->content[0]->parsed;
echo "Sarlavha: {$m->sarlavha}\n";
echo "Kategoriya: {$m->kategoriya}\n";
echo "Tavsif: {$m->tavsif}\n";
echo "Teglar: " . implode(', ', $m->teglar) . "\n";
Bir rasmdan butun mahsulot kartochkasi tayyor bo'ldi β sarlavha, kategoriya, tavsif va qidiruv teglari. Bu β kontent yaratishni avtomatlashtirishning kuchli misoli.
Maslahat
Kategoriyalarni cheklab berish ko'pincha foydaliroq. text ga "Kategoriya faqat shulardan biri bo'lsin: kiyim, texnika, oziq-ovqat, uy-ro'zg'or" deb yozing β shunda model bazangizga mos kategoriya qaytaradi, kutilmagan qiymat chiqmaydi.
Hujjatlar (PDF) yuborish¶
Rasmdan tashqari model PDF hujjatlarni ham o'qiy oladi. Buning uchun blok turi 'image' emas, balki 'document' bo'ladi va media_type 'application/pdf' bo'ladi. Qolgan hammasi rasmnikiga o'xshash.
Hayotiy o'xshatish. Bu β yordamchiga 10 betlik shartnoma berib, "menga muhim shartlarini bir necha gapda ayt" deyish bilan bir xil. Siz hujjatni o'qib o'tirmaysiz β yordamchi o'qiydi va xulosa qiladi.
PDF'ni ham base64 ga aylantirib yuboramiz:
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
// PDF faylni base64 ga aylantiramiz
$pdf = base64_encode(file_get_contents('shartnoma.pdf'));
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
[
'type' => 'document',
'source' => [
'type' => 'base64',
'media_type' => 'application/pdf',
'data' => $pdf,
],
],
['type' => 'text', 'text' => 'Bu shartnomaning asosiy shartlarini 5 ta band qilib qisqacha ayt.'],
],
]],
);
echo $message->content[0]->text;
Endi hujjatdan savol-javob qilishingiz mumkin: "to'lov muddati qachon?", "jami necha modda bor?", "qaysi tomon bekor qila oladi?" β model PDF matnidan javobni topadi.
Files API β bir marta yuklab, qayta-qayta ishlatish¶
Agar bitta katta PDF'ni bir necha bor ishlatadigan bo'lsangiz (har savolda qaytadan yuborish o'rniga), uni serverga bir marta yuklab, keyin faqat uning file_id'sini berish qulayroq. Buning uchun Files API bor β u $client->beta->files orqali ishlaydi.
use Anthropic\Core\FileParam;
// 1) Faylni bir marta yuklaymiz -> file_id olamiz.
// upload() string yoki FileParam qabul qiladi (to'g'ridan fopen resursi EMAS) β
// shuning uchun resursni FileParam::fromResource() bilan o'raymiz.
$yuklangan = $client->beta->files->upload(
file: FileParam::fromResource(fopen('katta-hujjat.pdf', 'r')),
);
$fileId = $yuklangan->id; // masalan: "file_abc123..."
// 2) Endi document blokida base64 emas, file_id beramiz
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
[
'type' => 'document',
'source' => ['type' => 'file', 'file_id' => $fileId],
],
['type' => 'text', 'text' => 'Bu hujjatdan asosiy xulosani ayt.'],
],
]],
);
echo $message->content[0]->text;
Files API'ning boshqa foydali metodlari:
$client->beta->files->list()β yuklangan fayllar ro'yxati.$client->beta->files->retrieveMetadata($fileId)β fayl haqida ma'lumot (nomi, hajmi).$client->beta->files->delete($fileId)β faylni o'chirish.$client->beta->files->download($fileId)β faylni qaytarib yuklash.
Boshqa provayderda
PDF/hujjat va fayl yuklash imkoniyatlari provayderlarda har xil. Ba'zilarida hujjatni o'zingiz matnga aylantirib (matn ajratuvchi kutubxona bilan) so'ngra yuborishingiz kerak. Claude'da PDF'ni to'g'ridan-to'g'ri berish qulay β bu kitobda shu usuldan foydalanamiz.
Multimodal + strukturali = hujjatdan JSON¶
Eng kuchli naqsh β rasmni/hujjatni strukturalangan ma'lumotga aylantirish. Yuqorida chekda ko'rdik; bu PDF hujjatga ham aynan ishlaydi. Masalan, hisob-faktura (invoice) PDF'idan asosiy maydonlarni JSON qilib olamiz:
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
use Anthropic\Lib\Contracts\StructuredOutputModel;
use Anthropic\Lib\Concerns\StructuredOutputModelTrait;
class Hisobfaktura implements StructuredOutputModel
{
use StructuredOutputModelTrait;
public string $raqam; // hisob-faktura raqami
public string $sana; // YYYY-MM-DD
public string $mijoz; // mijoz nomi
public float $jamiSumma; // jami to'lov
public string $valyuta; // masalan: "UZS", "USD"
}
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
$pdf = base64_encode(file_get_contents('invoice.pdf'));
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
messages: [[
'role' => 'user',
'content' => [
['type' => 'document', 'source' => ['type' => 'base64', 'media_type' => 'application/pdf', 'data' => $pdf]],
['type' => 'text', 'text' => 'Bu hisob-fakturadan raqam, sana, mijoz, jami summa va valyutani ajratib ber.'],
],
]],
outputConfig: ['format' => Hisobfaktura::class],
);
$hf = $message->content[0]->parsed;
echo "β{$hf->raqam} Β· {$hf->mijoz} Β· {$hf->jamiSumma} {$hf->valyuta}\n";
Bu naqsh β hujjatlarni avtomatik qayta ishlash (document processing) deb ataladi va biznesda juda qadrlanadi: skanerlangan hujjatlar, kvitansiyalar, anketalar β hammasini odam o'qimasdan bazaga tushadi.
Cheklovlar va maslahatlar¶
Vision kuchli, lekin uni to'g'ri ishlatish kerak. Mana amaliy qoidalar:
- Aniqlik 100% emas. Model rasmni "o'qiydi", lekin xato ham qilishi mumkin β ayniqsa xira, qiyshiq yoki past sifatli suratda. Muhim ma'lumotni (pul, hujjat) doim tekshirib ko'rsating yoki foydalanuvchiga tasdiqlatish bering.
- Rasm tokenlari pulga teng. Rasm qancha katta/aniq bo'lsa, shuncha ko'p token sarflaydi. Kerakmas darajada katta surat yubormang β avval kichraytiring (16-bobda xarajat optimizatsiyasini chuqurroq ko'ramiz).
- Sifatsiz/juda kichik rasm β yomon natija. Yozuvni o'qish kerak bo'lsa (OCR), surat aniq va to'g'ri tushgan bo'lsin. "Axlat kirsa, axlat chiqadi" qoidasi bu yerda ham amal qiladi.
- Maxfiy hujjatlarga ehtiyot bo'ling. Pasport, shaxsiy ma'lumot, tibbiy hujjat kabi maxfiy rasm/PDF'ni yuborishdan oldin xavfsizlik va maxfiylik talablarini o'ylab ko'ring. Bu mavzuni 20-bobda (Xavfsizlik) batafsil ko'ramiz β ayniqsa shaxsiy ma'lumot (PII) bilan ishlashda.
Xavfsizlik
Foydalanuvchi yuklagan faylga ishonmang: hajmini cheklang, formatini tekshiring (mime_content_type), faylni xavfsiz papkaga saqlang va uni darhol kerakli ishni qilib bo'lgach o'chiring. Maxfiy hujjatni keraksiz joyga (loglar, ochiq saqlash) tushib qolishidan saqlaning.
To'liq misol β "Chek tahlilchisi"¶
Endi hammasini birlashtiramiz. Foydalanuvchi chek faylining yo'lini beradi, dastur uni o'qiydi, tekshiradi, modelga yuboradi va strukturalangan natijani chiqaradi. Bu β bu bobning kichik kapstoni.
<?php
require __DIR__ . '/vendor/autoload.php';
use Anthropic\Client;
use Anthropic\Lib\Contracts\StructuredOutputModel;
use Anthropic\Lib\Concerns\StructuredOutputModelTrait;
// 1) Natija shakli
class ChekNatija implements StructuredOutputModel
{
use StructuredOutputModelTrait;
public string $dokon; // do'kon nomi
public string $sana; // YYYY-MM-DD
public float $summa; // umumiy summa
public string $valyuta; // masalan: "UZS"
/** @var string[] */
public array $mahsulotlar; // chekdagi mahsulot nomlari
}
/**
* Chek faylidan ma'lumot ajratuvchi funksiya.
* Fayl yo'lini oladi, ChekNatija obyektini qaytaradi.
*/
function chekTahlil(Client $client, string $faylYoli): ChekNatija
{
// Fayl bormi?
if (!is_file($faylYoli)) {
throw new RuntimeException("Fayl topilmadi: {$faylYoli}");
}
// Formatni aniqlaymiz (image/jpeg, image/png ...)
$mime = mime_content_type($faylYoli);
$ruxsat = ['image/jpeg', 'image/png', 'image/webp', 'image/gif'];
if (!in_array($mime, $ruxsat, true)) {
throw new RuntimeException("Qo'llab-quvvatlanmaydigan format: {$mime}");
}
// base64 ga aylantiramiz
$base64 = base64_encode(file_get_contents($faylYoli));
// Modelga yuboramiz (vision + strukturali)
$message = $client->messages->create(
model: 'claude-opus-4-8',
maxTokens: 1024,
system: 'Sen chek/kvitansiya tahlilchisisan. Faqat chekda ko\'ringan ma\'lumotni ber. '
. 'Summani raqam qil, sanani YYYY-MM-DD shaklida ber.',
messages: [[
'role' => 'user',
'content' => [
['type' => 'image', 'source' => ['type' => 'base64', 'media_type' => $mime, 'data' => $base64]],
['type' => 'text', 'text' => 'Ushbu chekdan ma\'lumotni ajratib ber.'],
],
]],
outputConfig: ['format' => ChekNatija::class],
);
return $message->content[0]->parsed;
}
// 2) Ishlatish
$client = new Client(apiKey: getenv('ANTHROPIC_API_KEY'));
try {
$chek = chekTahlil($client, 'cheklar/chek-001.jpg');
echo "π§Ύ Chek tahlili\n";
echo "Do'kon: {$chek->dokon}\n";
echo "Sana: {$chek->sana}\n";
echo "Summa: {$chek->summa} {$chek->valyuta}\n";
echo "Mahsulotlar (" . count($chek->mahsulotlar) . " ta):\n";
foreach ($chek->mahsulotlar as $m) {
echo " - {$m}\n";
}
} catch (\Throwable $e) {
echo "Xato: " . $e->getMessage() . "\n";
}
Bu dastur:
- Faylni tekshiradi (bor-yo'qligi va formati).
- Rasmni base64 ga aylantiradi.
systemprompt bilan modelni "chek tahlilchisi" rolida ishlatadi.- Strukturalangan
ChekNatijaobyektini qaytaradi. - Xato bo'lsa (
try/catch) chiroyli xabar beradi.
Bu yerda xatolarni faqat ushladik. Keyingi bobda esa API xatolari, rate limit va qayta urinish (retry) ni jiddiyroq, ishonchli usulda boshqarishni o'rganamiz β productionga chiqadigan har bir dastur uchun bu shart.
Tekshirib ko'ring
Yuqoridagi dasturni o'zingizning chek suratingiz bilan ishlatib ko'ring. Model summani to'g'ri o'qidimi? Endi xira yoki qiyshiq suratda sinab ko'ring β natija qanchalik o'zgaradi? Bu sizga "modelning aniqligi rasm sifatiga bog'liq" degan saboqni amalda ko'rsatadi.
Xulosa¶
- Multimodal model nafaqat matnni, balki rasm va PDF'ni ham tushunadi β bu "ko'zli yordamchi" kabi.
- Rasm yuborganda
contentsatr emas, bloklar massivi bo'ladi:imagebloki +textbloki. - Rasmni ikki yo'l bilan beramiz: base64 (
file_get_contents+base64_encode) yoki URL (rasm ochiq internetda bo'lsa). - Qo'llab-quvvatlanadigan formatlar: PNG, JPEG, GIF, WebP. Hajm chegarasi bor; bir so'rovga bir nechta rasm qo'sha olasiz; har rasm token (pul) sarflaydi.
- PDF hujjat uchun
'type' => 'document',media_type => 'application/pdf'. Katta/qayta ishlatiladigan fayllar uchun Files API ($client->beta->files->upload) bilan bir marta yuklabfile_idishlatish qulay. - Eng kuchli naqsh β vision + strukturali chiqish: rasm/hujjat β validatsiyalangan PHP obyekt (chek β summa-sana-do'kon, hujjat β JSON).
- Aniqlik 100% emas: muhim ma'lumotni (pul, hujjat) tekshirib ko'rsating; sifatli rasm yuboring; maxfiy hujjatlarda xavfsizlikka e'tibor bering (20-bob).
Amaliy mashqlar¶
-
Rasm tavsifi. Telefoningiz bilan biror narsaning suratini oling va modelga base64 orqali yuborib, "Bu rasmda nima bor? O'zbek tilida tasvirlab ber" deb so'rang. Keyin xuddi shu rasmni URL orqali (biror joyga yuklab) yuborib, natijani solishtiring.
-
Chekdan extraction. Do'kon chekining suratini oling va
ChekNatijaklassidan foydalanib do'kon, sana, summa va mahsulotlar ro'yxatini ajratib oling. Natijani PDO bilan SQLite/MySQL bazasiga yozadigan kod qo'shing. -
PDF xulosa. Bironta PDF hujjat (masalan, dars konspekti yoki maqola) oling va modelga
documentbloki bilan yuborib, "asosiy 5 fikrini ayt" deb so'rang. So'ng undan aniq savol bering ("3-bo'limda nima yozilgan?") va javobni tekshiring. -
Multimodal + strukturali. Mahsulot suratidan
MahsulotTavsifiobyektini olib, kategoriyalarni faqat sizning do'koningizdagi ro'yxatdan (masalan: kiyim, texnika, oziq-ovqat) tanlashga majburlovchi prompt yozing. Model har doim ruxsat etilgan kategoriya qaytarishini tekshiring. -
Bir nechta rasm taqqoslash. Ikki o'xshash mahsulot suratini bitta so'rovda yuborib, ularning farqini topadigan dastur yozing. Har rasmga matn bloki bilan nom bering ("Birinchi rasm:", "Ikkinchi rasm:").
β¬ οΈ Oldingi: 06 β Strukturali chiqish Β· π Kitob boshi Β· Keyingi: 08 β Xatolar va ishonchlilik β‘οΈ