Toplu ve Geçmişe Dönük Sinyal İşleme: occurred_at ile Backfill
Bir müşteriyle ilgili elinizde iki yıllık görüşme geçmişi var ve bunu
HuMetric'e tek seferde yüklemek istiyorsunuz. Bu bir backfill senaryosu:
sinyaller sisteme bugün geliyor ama her biri farklı bir geçmiş tarihte
yaşandı. Bu yazı, bunu doğru yapmak için bilmeniz gereken tek alanı
(occurred_at) ve o alanın okuma tarafındaki iki uç noktayı nasıl tutarlı
tuttuğunu, gerçek curl örnekleriyle anlatıyor.
1. occurred_at: sinyalin kendi tarihi
POST /v1/signals gövdesi şu alanları kabul eder:
{
"entity_id": "musteri-demo-118",
"entity_type": "musteri",
"text": "...üst yönetime bağlanmazsam sosyal medyada şikayet ederim...",
"occurred_at": "2024-09-15T14:32:00Z"
}
occurred_at boş bırakılırsa (canlı/gerçek zamanlı sinyaller için normal
kullanım budur) sistem isteğin geldiği anı kullanır. Ama doldurulduğunda,
bu tarih sinyalin gerçek yaşandığı an olarak kaydedilir — API'ye ulaştığı
an değil. Backfill'de her zaman doldurun:
curl -X POST https://api.gethumetric.com/v1/signals \
-H "Authorization: Bearer $HUMETRIC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"entity_id": "musteri-demo-118",
"entity_type": "musteri",
"text": "...üst yönetime bağlanmazsam sosyal medyada şikayet ederim...",
"occurred_at": "2024-09-15T14:32:00Z"
}'
Yanıt hemen döner, işleme arka planda devam eder:
{ "signal_id": "sig_8fa2c1", "status": "queued" }
İşlenip işlenmediğini GET /v1/signals/{signal_id} ile sorgulayabilirsiniz;
status alanı queued → completed (ya da failed) olur. Bir backfill'i
sıraya çok sayıda sinyalle doldururken sinyalleri hangi sırada
gönderdiğiniz önemli değildir — her biri kendi occurred_at'i ile
damgalanır, sıralama motorun içinde önemsizleşir.
2. Aşınma neye göre hesaplanır
Her metrik iki sayı taşır: kaydedilen ham confidence ve okuma anında
hesaplanan effective_confidence. İkincisi zamanla düşer:
effective_confidence = confidence * exp(-λ * yaş_gün)
λ = ln(2) / 365 # güvenin yarı ömrü 1 yıl
yaş_gün, bugün ile occurred_at arasındaki farktir — sinyalin sisteme
yüklendiği tarih değil. Yukarıdaki örnekte occurred_at 2024-09-15, bugün
2026-08-25 ise yaş ~710 gün eder ve eskalasyon_riski metriği için ham
confidence 0.40 iken effective_confidence ≈ 0.2605 çıkar. Bu formül
her okumada yeniden hesaplanır; kayıtlı ham değer hiç değişmez, bu yüzden
denetlenebilir kalır.
3. İki uç nokta, aynı sayı
Bir metriği iki yerden okuyabilirsiniz:
curl https://api.gethumetric.com/v1/entities/musteri-demo-118/metrics \
-H "Authorization: Bearer $HUMETRIC_API_KEY"
{
"entity_id": "musteri-demo-118",
"metrics": [
{
"metric_key": "eskalasyon_riski",
"value": 0.72,
"confidence": 0.40,
"effective_confidence": 0.2605,
"source_count": 1,
"last_updated": "2024-09-15T14:32:00Z"
}
],
"metric_count": 1
}
curl https://api.gethumetric.com/v1/entities/musteri-demo-118/metrics/eskalasyon_riski/history \
-H "Authorization: Bearer $HUMETRIC_API_KEY"
{
"entity_id": "musteri-demo-118",
"metric_key": "eskalasyon_riski",
"points": [
{
"recorded_at": "2024-09-15T14:32:00Z",
"value": 0.72,
"confidence": 0.40,
"effective_confidence": 0.2605,
"source_count": 1
}
],
"total": 1
}
Dikkat edin: last_updated (güncel metrik ucunda) ile recorded_at (geçmiş
ucunda) aynı tarih, ve iki uçtaki effective_confidence aynı sayı.
Bu tutarlılık kazara değil — last_updated, o metriğe katkıda bulunan en
yeni gerçek gözlemin occurred_at'ini izler, sinyalin sisteme yazıldığı anı
değil. Karışık sırayla gelen bir backfill'de bile bu değer geriye gitmez:
metriğe daha eski bir occurred_at'li bir sinyal sonradan işlense bile,
last_updated en yeni gerçek gözlemde kalır.
4. Uçtan uca bir backfill döngüsü
Elinizde kronolojik olmayan sırada bir transkript arşivi varsa, tipik bir backfill scripti şuna benzer:
import httpx
BASE = "https://api.gethumetric.com/v1"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
for call in call_history: # herhangi bir sırada olabilir
httpx.post(f"{BASE}/signals", headers=HEADERS, json={
"entity_id": call["customer_id"],
"entity_type": "musteri",
"text": call["transcript"],
"occurred_at": call["happened_at"].isoformat(),
})
Her istek 202 ile hemen döner; sinyaller arka planda sırayla işlenir. Son
adım, tüm arşiv işlendikten sonra GET /v1/entities/{id}/metrics ile güncel
durumu okumak — artık GET .../history'nin en son noktasıyla birebir aynı
effective_confidence'ı görürsünüz.
Referans: kullanılan pack
Yukarıdaki örneklerde eskalasyon_riski dahil yedi metriği tanımlayan
çağrı merkezi paketi kullanıldı. Kendi ortamınızda denemek isterseniz:
entity_type: musteri
label: "Çağrı Merkezi Müşterisi"
version: 3
required_fields:
- key: kanal
type: str
label: "Kanal"
metrics:
- key: memnuniyet
label: "Memnuniyet"
type: float
default_confidence: 0.5
prompt: "Müşterinin görüşme sırasındaki genel memnuniyeti: ton, şikâyet
yoğunluğu, teşekkür/övgü ifadeleri. YÜKSEK değer = memnun
müşteri."
- key: cozum_basarisi
label: "İlk Temasta Çözüm"
type: float
default_confidence: 0.5
prompt: "Talebin bu görüşme/mesajlaşma içinde fiilen çözülüp
çözülmediği: yönlendirme, tekrar arama sözü, açık kalan konu.
YÜKSEK değer = sorun bu temasta kapandı."
- key: eskalasyon_riski
label: "Eskalasyon Riski"
type: float
default_confidence: 0.4
prompt: "Müşterinin üst birime çıkma, iptal/iade talep etme, hukuki veya
sosyal medya tehdidi savurma eğilimi. YÜKSEK değer = risk
yüksek (kötü durum, diğer metriklerle ters yönlü)."
- key: niyet_netligi
label: "Niyet Netliği"
type: float
default_confidence: 0.5
prompt: "Müşterinin talebini ne kadar net ifade ettiği: tek bir açık
istek mi, yoksa dağınık/çelişkili birden fazla konu mu.
YÜKSEK değer = niyet net."
- key: tekrar_temas_egilimi
label: "Tekrar Temas Eğilimi"
type: float
default_confidence: 0.4
prompt: "Aynı konuda kısa süre içinde tekrar arama/yazma ihtimali:
yarım kalan işlem, 'yine ararım' ifadesi, verilen sözün
belirsizliği. YÜKSEK değer = tekrar temas olası (nötr-kötü
sinyal, düşük operasyonel verimlilik)."
- key: yanit_hizi_algisi
label: "Yanıt Hızı Algısı"
type: float
default_confidence: 0.4
prompt: "Müşterinin bekleme/yanıtlanma hızından duyduğu memnuniyet
algısı: 'hemen açtınız', 'çok beklettiniz', bekleme
süresinden şikâyet gibi ifadeler. Ölçülmüş bir süre değil,
müşterinin ALGISIdır. YÜKSEK değer = hızlı yanıtlandığını
hissetti."
- key: saglik_aciliyeti
label: "Sağlık Aciliyeti"
type: float
sensitive: true
requires_consent_scope: saglik_verisi
default_confidence: 0.4
prompt: "Müşterinin anlattığı sağlık durumunun ne kadar acil
önceliklendirme gerektirdiği. YÜKSEK değer = acil. Bu metrik
KVKK m.6 anlamında özel nitelikli kişisel veriye dayanır;
rıza yoksa üretilse bile kaydedilmez."
kvkk:
sensitive_metrics:
- saglik_aciliyeti