İçeriğe geç

Kılavuzlar

Eğitim: bir HTTP uç noktasının arkasındaki bir uygulama

HTTP üzerinden ulaştığınız bir hizmeti, kodunu içe aktarmadan değerlendirin: Oloproof'u URL'ye yöneltin, paketi çalıştırın, neyi kaçırdığını bulun, bir değişikliği dağıtın ve karşılaştırın. Sizinkinin yerine küçük bir yerel hizmet geçer, bu yüzden her şey çevrimdışı çalışır.

Ne oluşturacaksınız

Bir müşteri mesajını okuyup iki alan çıkaran bir sipariş alma hizmeti: bir intent (where_is_order, cancel, return ya da other) ve bir order_id (dört rakam ya da null). Her yanıtın biçimini denetleyeceksiniz, bu bir referans gerektirmez; ve her alanın doğru olup olmadığını ölçeceksiniz, bu ise gerektirir. Vaka, çalıştırma, metrik ve kapı gibi terimler Kavramlar sayfasında tanımlanmıştır.

Ön koşullar

  • Python 3.11 veya üstü ve bir sanal ortamda Oloproof:
python3 -m venv .venv
. .venv/bin/activate
pip install oloproof
  • Paketle birlikte gelen örnek proje. Onu yeni bir dizine kopyalayın ve orada çalışın (client.py dosyasının içe aktardığı httpx, Oloproof ile birlikte kurulur):
oloproof init --example http order-intake
cd order-intake
  • Bu makinede boş bir 8765 portu. Doluysa başka birini seçin ve hem sunucu komutunda hem de oloproof.yaml içinde değiştirin.

Buradaki hiçbir şey bir sağlayıcı, bir API anahtarı ya da internet kullanmaz: hizmet 127.0.0.1 üzerinde dinler.

Dosyalar

order-intake/
  server.py             the stand-in service (Python standard library only)
  client.py             a callable that calls the service with a token (used near the end)
  oloproof.yaml         the suite: dataset, HTTP system, evaluators
  release.yaml          rules for a run
  compare.yaml          a rule for a comparison
  data/messages.jsonl   20 cases

Komutları order-intake/ içinden çalıştırın. Hizmeti ikinci bir terminalde başlatın ve çalışır halde bırakın:

python server.py --port 8765
intake service (v1) on http://127.0.0.1:8765/extract

HTTP sözleşmesi

Oloproof her vaka için bir istek gönderir: vakanın input değeri JSON gövdesi olarak, bildirdiğiniz yöntemle (varsayılan olarak POST). Yanıtı JSON olarak okur. 400 ya da üzeri bir durum kodu, bir zaman aşımı ya da reddedilen bir bağlantı, o vaka için bir yürütme hatası olarak kaydedilir, asla yanlış bir yanıt olarak değil.

Bir vaka için istek ve yanıt:

POST /extract
{"message": "Where is order 1042? It has not arrived."}

200 OK
{"result": {"intent": "where_is_order", "order_id": "1042"}, "service": {"rules": "v1"}}

output_path: result, Oloproof'a vakanın çıktısı olarak yalnızca result değerini tutmasını söyler; o olmadan gövdenin tamamı çıktıdır. data.answer gibi noktalı bir yol daha derine ulaşır.

version: 1
project: order-intake
dataset: data/messages.jsonl
system:
  name: order-intake
  http:
    url: http://127.0.0.1:8765/extract
    method: POST
    version: rules-v1
    output_path: result
    timeout_s: 30
evaluators:
  - type: json_schema
    criterion: format_valid
    field: null
    schema:
      type: object
      required: [intent, order_id]
      properties:
        intent: {enum: [where_is_order, cancel, return, other]}
        order_id: {type: [string, "null"], pattern: '^\d{4}$'}
      additionalProperties: false
  - type: exact_match
    criterion: intent_correct
    field: intent
  - type: exact_match
    criterion: order_id_correct
    field: order_id

Bir HTTP sistemi bir version bildirmelidir. Oloproof bir dağıtımı göremez: her vakanın çıktısını URL, yöntem, çıktı yolu ve o sürüm altında önbelleğe alır; bu yüzden sürüm, hizmetin değiştiğini ona söyleme yolunuzdur. Değiştirmeyi unutursanız yeni bir dağıtım asla çağrılmaz.

Başlıklar ve kimlik doğrulama henüz system.http üzerinde yapılandırılamaz. Aşağıdaki token bölümü geçici çözümü gösterir.

Veri kümesi

{"id":"m04","input":{"message":"Has order #5120 shipped yet?"},"expected":{"intent":"where_is_order","order_id":"5120"}}
{"id":"m07","input":{"message":"Do you ship to Canada?"},"expected":{"intent":"other","order_id":null}}
{"id":"m16","input":{"message":"Please refund and take back the lamp from order #1560."},"expected":{"intent":"return","order_id":"1560"}}

input tam olarak istek gövdesidir. expected her alan için referansı tutar; null gerçek bir referans değeridir ve "bu mesajda sipariş kimliği yok" anlamına gelir.

Değerlendiricileri seçme

KriterDeğerlendiriciexpected gerekir miÖlçtüğü
format_validçıktı üzerinde json_schemahayırbiçim: bilinen bir niyet ve iyi biçimlendirilmiş bir kimlik
intent_correctintent üzerinde exact_matchevetilk alan için görev başarısı
order_id_correctorder_id üzerinde exact_matchevetikinci alan için görev başarısı

Şema her mesaj için {"intent": "other", "order_id": null} değerini geçirirdi: iyi biçimlendirilmiş ve işe yaramaz. Yalnızca referans denetimleri hizmetin işini yapıp yapmadığını söyler. Alanları ayrı puanlamak hangisinin başarısız olduğunu gösterir; birleşik tek bir denetim bunu gizlerdi.

release.yaml hiçbir biçim başarısızlığına izin vermez ve %95 aralığa göre değerlendirilerek her alanın zamanın en az %70'inde doğru olmasını ister:

version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
rules:
  - id: valid-format
    metric: format_valid
    kind: observed_count
    max_failures: 0
  - id: intent-floor
    metric: intent_correct
    min: 0.70
  - id: order-id-floor
    metric: order_id_correct
    min: 0.70

Çalıştırın

oloproof run
Run run_01M4... [DECIDED/COMPLETE]
Gate: BLOCK (exit 3)
│ valid-format   │ format_valid     │ PASS                  │ observed_failures_within_limit │
│ intent-floor   │ intent_correct   │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ order-id-floor │ order_id_correct │ INSUFFICIENT_EVIDENCE │ interval_overlaps_threshold    │
│ format_valid     │ 100.0%   │ [83.1%, 100.0%] │ 20 / 20 observed · 0 missing · 0 excluded │
│ intent_correct   │ 75.0%    │ [50.8%, 91.4%]  │ 15 / 20 observed · 0 missing · 0 excluded │
│ order_id_correct │ 75.0%    │ [50.8%, 91.4%]  │ 15 / 20 observed · 0 missing · 0 excluded │
Cache: execution 0 hit/20 miss; judgment 0 hit/60 miss

Her yanıt iyi biçimlendirilmiş. Her alan 20'de 15 kez doğru, ama 20 vaka %50,8'e kadar inen bir aralık bırakır, bu yüzden %70'lik tabanların hiçbiri gösterilemez: INSUFFICIENT_EVIDENCE ve kapı 3 ile engeller.

Başarısızlıkları inceleyin

oloproof inspect RUN_ID --failures
8 of 20 cases failed, errored or did not finish

m04
  output: {"intent": "where_is_order", "order_id": null}
  order_id_correct: failed

m06
  output: {"intent": "other", "order_id": "7011"}
  intent_correct: failed
...
m18
  output: {"intent": "other", "order_id": null}
  intent_correct: failed
  order_id_correct: failed

Girdileri yanlarında okuyun (oloproof inspect RUN_ID --case m04) ve iki hata ortaya çıkar: kimlik örüntüsü yalnızca "order 1234" ile eşleşir, "order #5120", "order no. 8123" ya da yalın "#1673" ile değil; ve "send back", "stop order" ve "where's my parcel" gibi ifadeler hiçbir niyete eşlenmez. Sonraki eylem budur: iki kuralı da genişletin.

Bir değişikliği dağıtın

Hizmeti durdurun ve bu düzeltmeleri taşıyan adayı başlatın:

python server.py --port 8765 --rules v2

oloproof.yaml içinde version: rules-v1 değerini version: rules-v2 yapın, çünkü URL değişmedi ve Oloproof aksi halde eski çıktıları yeniden kullanırdı. Sonra:

oloproof run
Gate: ALLOW (exit 0)
│ intent_correct   │ 100.0%   │ [83.1%, 100.0%] │ 20 / 20 observed · 0 missing · 0 excluded │
│ order_id_correct │ 100.0%   │ [83.1%, 100.0%] │ 20 / 20 observed · 0 missing · 0 excluded │

İki taban da geçer ve komut 0 ile çıkar.

İki dağıtımı karşılaştırın

compare.yaml, adayın niyetlerinin temelinkilerden daha iyi olup olmadığını sorar:

version: 1
confidence_level: 0.95
block_on: [FAIL, INSUFFICIENT_EVIDENCE, MANUAL_REVIEW]
rules:
  - id: intent-better
    kind: superiority
    metric: intent_correct
oloproof compare CANDIDATE_RUN_ID BASELINE_RUN_ID --policy compare.yaml
format_valid: +0.0 points [-23.6, +23.6] · 20 paired · 0 missing · 0 excluded
intent_correct: +25.0 points [-8.5, +58.3] · 20 paired · 0 missing · 0 excluded
order_id_correct: +25.0 points [-8.5, +58.3] · 20 paired · 0 missing · 0 excluded
Decisions
  intent-better  intent_correct  superiority  INSUFFICIENT_EVIDENCE  interval_overlaps_zero
Gate: BLOCK (exit 3)

Aday kendi tabanlarını geçer, ama karşılaştırma onun daha iyi olduğunu gösteremez: beş vaka değişti ve 20 eşleştirilmiş vaka üzerinde kazancın aralığı hâlâ sıfırı içerir. İki ifade de aynı anda doğrudur. "Gereksinimi karşılar" ve "temeli geçer" ayrı sorulardır ve bu kadar küçük bir paket ikincisini yalnızca büyük etkiler için yanıtlar. Çare daha fazla gerçek mesajdır.

Token gerektiren bir hizmet

Hizmeti bir bearer token isteyecek şekilde başlatın:

INTAKE_TOKEN=s3cret python server.py --port 8765 --rules v2 --require-token

system.http özel başlık göndermez, bu yüzden yeni bir version ile (örneğin rules-v2-auth) her çağrı reddedilir:

Gate: BLOCK (exit 3)
│ valid-format   │ format_valid     │ INSUFFICIENT_EVIDENCE │ no_observations │
│ intent_correct   │          │ [0.0%, 100.0%] │ 0 / 0 observed · 20 missing · 0 excluded │

ve oloproof inspect RUN_ID --failures her vakada execution ERROR: TransientError: system returned HTTP 401 gösterir. Yürütme hataları başarısızlık değil, eksik kanıttır: hiçbir şey gözlenmedi, bu yüzden her kural INSUFFICIENT_EVIDENCE olur.

Geçici çözüm, isteği kendisi yapan bir Python callable'ıdır. client.py başlığı bir ortam değişkeninden ekler, böylece token asla oloproof.yaml dosyasına ya da saklanan herhangi bir kayda girmez:

URL = os.environ.get("INTAKE_URL", "http://127.0.0.1:8765/extract")


def extract(case: dict[str, Any]) -> dict[str, Any]:
    headers = {"Authorization": f"Bearer {os.environ['INTAKE_TOKEN']}"}
    response = httpx.post(URL, json=case, headers=headers, timeout=30)
    response.raise_for_status()
    return response.json()["result"]

oloproof.yaml içindeki http: bloğunu şununla değiştirin:

system:
  name: order-intake
  version: rules-v2
  callable: client:extract

ve token ortamdayken çalıştırın:

INTAKE_TOKEN=s3cret oloproof run

20 vakanın hepsi yeniden gözlenir ve kapı izin verir. Callable'ın önbelleği arkasındaki hizmeti değil kendi kaynağını ve version değerini izler, bu yüzden aynı kural geçerlidir: dağıttığınızda version değerini değiştirin.

Sorun giderme

BelirtiNeden ve çözüm
Her vakada system connection failed (ConnectError)Hizmet çalışmıyor ya da başka bir portta dinliyor.
system connection failed (RemoteProtocolError)O portta başka bir şey yanıt veriyor. Boş bir port seçin.
KeyError: "missing output path 'results'"output_path, yanıtta olmayan bir alanı adlandırıyor.
system returned HTTP 401 ya da 403Uç nokta kimlik bilgisi istiyor: callable geçici çözümünü kullanın.
Bir değişikliği dağıttınız ve önbellek satırı hep isabet gösteriyorversion değişmedi, bu yüzden saklanan çıktılar yeniden kullanıldı.
an HTTP system needs a declared versionsystem ya da system.http altına version ekleyin.

Sınırlamalar

  • system.http üzerinde özel başlık, kimlik doğrulama, sorgu parametresi ya da istek şablonu yoktur: vakanın input değeri olduğu gibi JSON gövdesidir. Başka her şey için bir callable kullanın.
  • Yanıtlar JSON olmalıdır. Akış yanıtları akış olarak okunmaz.
  • Oloproof bir dağıtımı algılayamaz; bildirilen version, yanıt verenin kimliğinin tamamıdır.
  • Hizmetiniz kendi durumunun sahibidir: Oloproof istek gönderir ve yanıtları kaydeder; bir isteğin değiştirdiği hiçbir şeyi sıfırlamaz, yalıtmaz ya da geri almaz.