İçeriğe atla
openplate

Çıkarım çalışma zamanı

API

Uç noktalar, istek ve yanıt yapısı, durum kodları, CORS

Bu sayfa, İngilizce belgeden makine çevirisiyle çevrildi.

Önem taşıyan tek uç nokta vardır ve bu OpenAI biçimindedir:

POST /v1/chat/completions      Authorization: Bearer <key>, optional Accept-Language
GET  /v1/models                Authorization: Bearer <key>
GET  /readyz                   no auth, can it serve a scan right now?
GET  /healthz                  no auth, is the process alive?

Tam olarak OpenAI'ye yapacağın gibi bir metin parçası ve bir image_url veri URI'si gönder. Model kimliği openplate-plate-1 değerindedir. choices[0].message.content temiz, çitsiz bir JSON'dır:

json
{
  "foods": [
    { "name": "scrambled eggs", "estimatedGrams": 80, "confidence": "high",
      "portionHint": "a small scoop",
      "macrosPer100g": { "carbs": 1.2, "protein": 10, "fat": 10, "kcal": 140 },
      "translations": { "en": "scrambled eggs", "de": "Rührei" } }
  ],
  "notes": "…"
}

Besin veritabanı makro değerlerini sağladığında, bu servis bir besin kaydındaki provenance alanını "corpus" olarak ayarlar. Kaynak gerektirdiğinde bir attribution dizesi ekler, bkz. Yemek verileri. Öğeyi hiçbir şey çözümleyemediğinde iki alan da atlanır ve macrosPer100g null olur. Bu servis hiçbir zaman "model" değerini üretmez, çünkü paylaşılan sözleşme bu değeri bir bulut sağlayıcısına ayırır. Zaman aşımı, ret veya ağ hatası gibi bir kaynak arızası, eşleşme bulunamamasıyla aynı görünür: macrosPer100g null olur, yanıt yine 200 döner ve yanıttaki hiçbir şey hangisinin gerçekleştiğini belirtmez.

Bu servis, yemek adını tanıdığında bir yiyecekte flags (alerjenler ve hamilelik kategorileri) değerini belirler ve yanına flagsCoverage değerini "partial" olarak ekler. Bayraklar modelden değil, koddaki sabit bir kelime listesinden gelir. Bir ad, bir yiyeceğin ne içerdiğini gösterebilir ama ne içermediğini gösteremez. Bu yüzden listeleri kesin bir denetim olarak değil, bir başlangıç olarak ele al: listede bulunmayan bir alerjen yine de yiyeceğin içinde olabilir. Servis adı tanımadığında iki alanı da atlar. flags alanının bulunmaması, yiyeceğin güvenli olduğunu değil, değerlendirilmediğini gösterir.

Bu servis, her istek için tek bir dil olmak üzere, yemek adlarını Accept-Language istek başlığında belirtilen dile çevirir. Dili uygulama dillerinden (en, de, fr, it, es, tr) biri olan ve en yüksek ağırlığa sahip etiketi okur, bölgeyi ise yok sayar; yani de-DE Almanca anlamına gelir. Bu dil İngilizce olmadığında, her yiyecek iki anahtar içeren bir translations nesnesi alır: İngilizce ad ve o dildeki ad. Yukarıdaki örnek Accept-Language: de ile gönderilmiş bir istektir. Yiyecek veritabanı aramalarını onunla yaptığı için name her zaman İngilizce kalır. Çeviri, aynı modele yapılan yalnızca metin içerikli ikinci bir çağrıdır. Başarısız olursa veya 20 saniyeden uzun sürerse servis adlara dokunmaz: yanıttaki hiçbir yiyecekte translations bulunmaz ve yanıt yine de 200 olur. Başlık olmadığında veya İngilizce, * ya da bu listenin dışındaki bir dil kullanıldığında servis ikinci bir çağrı yapmaz ve translations göndermez.

Servis bir görsel kabul eder ve bir soruyu yanıtlar. İstemin yalnızca görsel için okunur, aksi halde göz ardı edilir.

Yetenekler

GET /v1/models tek modeli listeler. Girişi, bir istemciye bu servisin neleri yapıp neleri yapamayacağını bildiren bir capabilities nesnesi taşır. İstek göndermeden önce bunu oku. Girişin diğer anahtarları (id, object, created, owned_by) OpenAI yapısındadır ve değişmez. Bir OpenAI istemcisi fazladan anahtarı yok sayar.

json
{
  "object": "list",
  "data": [
    {
      "id": "openplate-plate-1",
      "object": "model",
      "created": 0,
      "owned_by": "openplate",
      "capabilities": {
        "tasks": {
          "plateImage": true,
          "describe": false,
          "pantryImage": false,
          "pantryText": false,
          "recipes": false
        },
        "flags": "partial",
        "translations": "request-language",
        "labels": false
      }
    }
  ]
}
anahtardeğerleranlam
tasks.plateImagetrue, falseTek bir fotoğraftan tabaktaki yiyecekleri tespit et. Bugün true.
tasks.describetrue, falseBir öğünün yazılmış açıklamasını yiyeceklere dönüştür.
tasks.pantryImagetrue, falseFotoğraftan bir kiler öğesini oku.
tasks.pantryTexttrue, falseYazılmış metinden bir kiler öğesini oku.
tasks.recipestrue, falseTarifler öner.
flagsnone, partial, completeServisin her yiyecekte kaç uyarı bayrağını doldurduğu. none durumunda, boş bir bayrak listesi yiyeceğin güvenli olduğu anlamına gelmez. Bu servis partial türündedir: yiyecek adından tanıyabildiklerini listeler ve bir yiyecekte flags bulunmaması, değerlendirilmediği anlamına gelir.
translationsnone, request-language, allServisin yemek adlarını hangi dillerde döndürdüğü. none tek dildir, request-language isteğin talep ettiği dildir, all desteklenen tüm dillerdir. Bu servis request-language türündedir: Accept-Language başlığını okur ve translations içermeyen bir yiyeceğin yalnızca İngilizce name değeri vardır.
labelstrue, falseServisin bir paketteki basılı besin değerleri tablosunu okuyup sayılarını macroSource: "label" olarak döndürüp döndürmediği.

Anahtar kümesi genişleyebilir. Bir istemci, eksik bir anahtarı false veya none olarak ele almalıdır.

Durum kodları

kodanlam
200Tarama tamamlandı.
400Hatalı biçimlendirilmiş istek gövdesi: mesaj alanın adını belirtir.
401Eksik veya yanlış taşıyıcı anahtarı.
413Kabul edilen sınırı aşan görsel yükü.
429Kuyruk dolu (MAX_QUEUE_DEPTH) veya RATE_LIMIT_RPM sınırının üzerinde. Bir Retry-After başlığı ayarlanır.
502Model çalışma zamanına ulaşılamıyor, başarısız oldu veya JSON şemasını zorlamıyor.
503İstek LATENCY_CEILING_MS içinde tamamlanamadığı için kabul reddedildi (yalnızca bu üst sınır etkinken).

CORS

CORS tasarımdan ötürü tamamen açıktır (*): tarayıcı bu uç noktayı doğrudan çağırır, bu nedenle bir kaynak izin listesi her sunucu barındırıcısının sunucu yapılandırmasını düzenlemesi anlamına gelirdi. Bunu güvenli kılan ortam kimlik bilgilerinin bulunmamasıdır: bu servis çerez oluşturmaz ve okumaz, bu sayede zararlı bir sayfa çapraz kaynaklı istekte bulunup bir 401 alabilir, çünkü tarayıcının otomatik olarak ekleyeceği hiçbir şey yoktur.

Hazır olma durumu

/readyz, yalnızca bir tarama gerçekten çalışabileceği zaman 200 döner: ağırlıklar mevcut, model yüklenmiş, çıkarım çalışma zamanı yanıt veriyor. /healthz yalnızca sürecin hayatta olduğu anlamına gelir. Harici modda /readyz bilmeye değer sınırlara sahiptir; Hazır olma durumu sayfasına bak.

Neden bir yönetici API'si ve CLI yok

İki kardeş servis Ağustos 2026'da birer tane edindi: openplate-gateway, üye ve davet uç noktaları üzerinde gw-api sunar; openplate-core ise hesap metaverisi yüzeyi üzerinde sync-api sunar. Bu servis kasıtlı olarak ikisini de edinmedi ve bunun yokluğunun bir ihmal değil bir karar olarak anlaşılması için gerekçesini yazmaya değer.

Bu servis başkasının şartnamesini uygular. Yüzeyi OpenAI chat-completions biçimindedir; bu da openplate dahil OpenAI uyumlu her istemcinin hiçbir bağdaştırıcı olmadan doğrudan burayı hedeflemesini sağlar. Burada bir API mümkün olan en güçlü anlamıyla "önceliklidir": API'den başka bir şey yoktur ve biçimi bizim genişletebileceğimiz bir şey değildir.

Yönetecek hiçbir yönetimsel durum yok. Bir ağ geçidinin üyeleri, davetleri ve kotaları vardır; bunların tümü bir istekten daha uzun yaşar ve listelenmesi, iptal edilmesi ve denetlenmesi gerekir. Bir eşitleme sunucusunun hesapları vardır. Bu servisin bir modeli, bir kuyruğu ve bir hız sınırlayıcısı vardır; bunların her biri ya başlangıçta okunan yapılandırmadır ya da süreçle birlikte yok olan durumdur. /readyz, herkesin sorduğu tek işletimsel soruyu (şu anda bir tarama sunabilir mi) zaten yanıtlar ve bunu bir kimlik bilgisi olmadan yapar; bu da bir izleme yoklamasının ihtiyaç duyduğu şeydir.

Burada bir yönetici yüzeyi uydurmak, bunu haklı çıkaracak durumu da uydurmak anlamına gelir. scripts/ içindeki betikler derleme, ağırlık getirme ve duman testi araçlarıdır: bunlar konteyner etrafındaki işletmen ergonomisidir, API'den gizlenen özellikler değildir.

Bu servis günün birinde çağırıcı başına kalıcı bir durum (anahtar başına kotalar, bir kullanım defteri, listelenmesi veya iptal edilmesi gereken herhangi bir şey) edinirse, bu karar yeniden değerlendirilmelidir ve takip edilecek tetikleyici budur.

Bu sayfayı GitHub üzerinde düzenle