Çağrı Sonrası Analiz
Arama kapanır kapanmaz elle özet yazmana, “bu görüşme nasıl geçti” diye kontak kartını doldurmana ya da pipeline’ı sürüklemene gerek kalmaz: Purvisor AI, konuşmayı saniyeler içinde analiz eder — özet çıkarır, duyguyu ölçer, satış sonucunu sınıflar, BANT’ı (Bütçe-Yetki-İhtiyaç-Zaman) çıkarır ve kontağı otomatik günceller. Bu, Purvisor’ın en çok zaman kazandıran özelliğidir; çünkü onlarca aramayı elle raporlamak yerine, pipeline kendi kendine ilerler ve sıcak bir lead belirdiğinde sistem gerekirse bir takip kuralını, kadansı veya kampanyayı kendisi devreye sokar.
Nasıl çalışır?
Arama biter (LiveKit oturumu kapanır)
↓
Agent, konuşma geçmişini analiz LLM'ine yollar (gpt-4o-mini, Chain of Thought)
↓
Yapılandırılmış JSON analiz üretilir (özet · duygu · sonuç · BANT ipuçları · ...)
↓ POST /api/agent/call-analysis
Kontak güncellenir: pipeline aşaması · lead skoru · ısı · BANT · itiraz geçmişi
↓
Kadans/kampanya yaşam döngüsü + Takip Kuralları + webhook'lar (call.completed, lead.hot) tetiklenirAnaliz görüşme bittikten sonra arka planda çalışır — canlı aramanın gecikmesini etkilemez. Backend’e ulaşamazsa analiz kaybolmaz; ölü mektup kuyruğuna (DLQ) yazılır ve backend ayağa kalkınca yeniden denenir.
Analiz motoru: Chain of Thought
Agent, görüşme transkriptini gpt-4o-mini modeline 10 adımlık bir “Chain of Thought” talimatıyla gönderir (düşük temperature=0.3, garantili JSON çıktısı için response_format: json_object):
| Adım | Ne üretir? |
|---|---|
| 1. Özet | Görüşmenin 2-3 cümlelik özeti (summary) |
| 2. Duygu analizi | positive | neutral | negative (sentiment) |
| 3. Satış sonucu | interested | callback_scheduled | appointment_scheduled | rejected | no_answer | information_provided (outcome) |
| 4. Kritik noktalar | İtirazlar, talepler, rakip bilgisi (keyPoints, objections) |
| 5. Bir sonraki adım | Geri arama tarihi varsa nextCallAt; “beni aramayın/silin” dediyse dncRequested: true |
| 6. Dönüşüm olasılığı | 0-1 arası (conversionProbability) |
| 7. Önerilen yaklaşım | Bir sonraki aramada nasıl yaklaşılmalı (recommendedApproach) |
| 8. Agent kalite skoru | Doğallık, empati, tekrar, doğruluk, satış becerisi, kapanış (1-10) |
| 9. Uyum kontrolü | Liste/emoji kullanımı, bilgi uydurma, uzun cümle ihlalleri |
| 10. Kümülatif özet | Önceki görüşmelerin özetiyle birleşen 2-4 cümlelik profil (cumulativeSummary) |
Adım 10 için agent, kontağın önceki en fazla 3 görüşme özetini ve genel profil özetini prompt’a önceki bağlam olarak ekler — böylece cumulativeSummary tek bir aramayı değil, müşteriyle olan tüm ilişkiyi yansıtır.
LLM bazen tarihi yanlış üretir (örneğin geçmiş bir yıl). Backend, nextCallAt değerini reddeder — eğer yıl bugünden küçükse veya tarih geçmişteyse alan null bırakılır, hayali bir geri arama planlanmaz. Aynı şekilde contactStatus alanı yalnızca pending, scheduled, interested, rejected, unreachable, converted değerlerinden birini kabul eder; LLM geçersiz bir değer (örn. outcome alanını buraya yazması) üretirse mevcut durum korunur — analiz asla veritabanı hatasına yol açmaz.
Analiz çıktısı (JSON şeması)
Agent’ın ürettiği ve /api/agent/call-analysis uç noktasına gönderdiği yapı, gerçek bir örnekle:
{
"summary": "Mehmet Bey teklifimizi ilgiyle karşıladı, aylık paket fiyatını sordu, ürünü kendi ekibinde nasıl kullanacağı hakkında bilgi aldı ve yarın saat 14:00'e randevu onayladı.",
"sentiment": "positive",
"outcome": "appointment_scheduled",
"keyPoints": [
"Fiyat konusunda bilgi istedi, aylık paket tutarını sordu",
"Şirketin karar vericisi kendisi olduğunu belirtti",
"Yarın saat 14:00 randevu onayladı"
],
"objections": [],
"contactStatus": "scheduled",
"dncRequested": false,
"cumulativeSummary": "Mehmet Kaya, ilk temasta teklife olumlu yaklaştı; fiyatı sorguladı, karar verici kendisi ve yarın randevu onayladı.",
"nextCallAt": null,
"conversionProbability": 0.85,
"recommendedApproach": "Randevu öncesi teyit SMS'i gönder, demo sırasında paket fiyatlandırmasını netleştir.",
"agentQualityScore": { "overall": 9, "naturalness": 9, "empathy": 8, "noRepetition": 9, "accuracy": 9, "salesSkill": 8, "closing": 9 },
"compliance": { "usedLists": false, "usedEmoji": false, "fabricatedInfo": false, "longSentences": false, "violations": [] }
}
agentQualityScorevecompliancedoğrudan kontak kartına yazılmaz — bunlar asistanın kendi performansını ölçer. Tekrarlayan düşük “empati” veya “kapanış” skorları, prompt’unu gözden geçirmen gerektiğinin işaretidir. Bkz. Prompt Yazma Rehberi.
Sonuç haritası: outcome → durum → pipeline aşaması
outcome, hem kontağın panel “Durum”unu hem de kümülatif “Pipeline Aşaması”nı belirler — ikisi farklı alanlardır:
outcome | contactStatus (Durum) | Türetilen universalStage |
|---|---|---|
appointment_scheduled | scheduled | committed |
interested | interested | evaluating |
callback_scheduled | interested | contacted |
information_provided | interested | contacted |
rejected | rejected | lost |
no_answer | unreachable | (değişmez) |
Pipeline aşaması yalnızca ileri gider (tek istisna: lost, her aşamadan tetiklenebilir). Aşama geçişinin tam kuralı ve lead skoru formülü için: Satış Pipeline.
Somut örnek: bir arama nasıl kontak güncellemesine dönüşür
Yukarıdaki JSON’u üreten arama, arka planda şu adımları tetikler:
Kontak bulunur
Backend, çağrının contactId’sini (varsa) ya da telefon numarasını kullanarak Mehmet Kaya’nın kontak kaydını bulur. Bu, aynı telefonu paylaşan mükerrer kayıtlarda analizin yanlış kişiye yazılmasını önler.
Kontak alanları güncellenir
Mehmet daha önce hiç aranmamıştı (new, leadScore: 5, ısı: soğuk). Analiz geldikten sonra:
| Alan | Önce | Sonra |
|---|---|---|
universalStage | new | committed (appointment_scheduled eşlemesi) |
bantData | 0/4 dolu | 4/4 dolu — fiyat soruldu (bütçe), karar verici kendisi (yetki), kullanım/bilgi soruldu (ihtiyaç), yarın randevu (zaman) |
leadScore | 5 | 90 — BANT 40 + Pipeline (committed) 35 + Duygu (ilk arama, stable) 5 + Başarı oranı (1/1) 10 |
heat | soğuk | sıcak (skor 70 üzerinde) |
lastCallSummary / customerSummary | — | summary / cumulativeSummary alanlarıyla dolar |
contactStatus | pending | scheduled |
callAttempts / successfulCalls | 0 / 0 | 1 / 1 |
lastContactedAt, firstContactAt | boş | şimdiki zaman (SLA ölçümü için ilk temas anı kaydedilir) |
Isı “sıcak”a geçtiği için lead.hot tetiklenir
Mehmet’in ısısı bu aramada ilk kez hot olduğu için (önceden hot değildi), Purvisor bir lead.hot olayı yayınlar — Zapier/Make’e bağlıysan otomasyonların anında haberdar olur.
Takip kuralı devreye girer
Hesabında “Sıcak Lead Tespit Edildiğinde” (lead_hot) tetikleyicili ve aksiyonu Kampanyaya Ekle olan bir takip kuralı varsa, Mehmet o an “Öncelikli Takip” kampanyasına pending olarak eklenir — sen panele girmeden, elle hiçbir şey yapmadan.
📸 [Ekran görüntüsü: Kontak detayı → Analiz sekmesi — güncellenen pipeline şeridi, lead skoru kartı (90, Sıcak) ve BANT kutuları]
Kadans ve kampanya yaşam döngüsü
Analiz, tek bir kontak alanını değil, kampanya ve kadans akışını da otomatik yönetir:
- Kampanya → Kadans devri — Arama bir kampanyaya aitse ve o kampanyanın bağlı bir kadansı varsa (
cadenceEnabled+cadenceId), kontak ilk arama sonrası — daha önce kaydolmadıysa — otomatik olarak o kadansın ilk adımına kaydedilir. - Aşamaya göre kadans yaşam döngüsü — Kontağın aktif bir kadans kaydı varsa: pipeline
committedveyacloseda ulaştığında kayıt otomatik tamamlanmış (completed,stopReason: stage_committed/stage_closed) sayılır;losta düşerse kayıt otomatik durdurulur (stopped,stopReason: lost). - Geri arama isteği kampanyayı geciktirir — Kampanya aramasında müşteri “sonra ara”, “toplantıdayım”, “beş dakika sonra” gibi bir ifade kullandıysa (veya analiz
nextCallAtüretirse), kampanya kaydıcompletedyerinefailed+callback_requestedolarak işaretlenir ve hesaplanannextRetryAt’e göre otomatik arayıcı tekrar dener — Türkçe ifadelerden dakika bile çıkarılır (“beş dakika sonra” → 5 dk).
Kadansların adım türleri ve otomatik kayıt mantığı için: Cadence Nedir?.
Takip kuralları ve dış sistemler
- Takip Kuralları —
call_completed,call_no_answer,call_interested,call_not_interested,lead_hot,sentiment_positive/negativegibi temel tetikleyiciler doğrudan bu analizden beslenir;objection_detected,pipeline_stage_changed,bant_criteria_met,heat_changed,lead_score_thresholdgibi “akıllı” tetikleyiciler ise her kontak güncellemesinde çalışır. Tüm tetikleyici/aksiyon mekaniği için: Takip Kuralları. - Zapier/Make webhook’ları — Her analiz sonrası
call.completedolayı (callId, telefon, yön, süre, outcome, sentiment, özet, contactId alanlarıyla) yayınlanır; ısı sıcağa geçtiyse ayrıcalead.hotyayınlanır. Ayrıntı: Webhooklar. - Kommo geri-yazma — Kontak Kommo’dan senkronize geldiyse, arama sonucu (outcome, sentiment, özet, süre) otomatik olarak ilgili Kommo lead kartına not olarak düşer.
- Post-call aksiyonlar — Asistana bağlı bilgi çıkarıcı, SMS/e-posta/WhatsApp veya webhook aksiyonları varsa, bunlar da analizle aynı anda ama bağımsız olarak (engellemeden) çalışır. Bkz. Aksiyonlar — Genel Bakış.
Maliyet ve gecikme ölçümü (ayrı bir sinyal)
Analizden bağımsız olarak agent, her arama için ayrıca bir maliyet ve gecikme sinyali gönderir (/api/agent/call-metrics): LLM/STT/TTS kullanım miktarları, sağlayıcı bazlı gecikme ortalamaları ve toplam maliyet. Bu veri kontak kartına yazılmaz; Redis’te günlük toplamlar olarak tutulur ve panel/rapor tarafında maliyet-gecikme panosunu besler. Detay: Maliyet ve Gecikme.
Geçmişi yeniden senkronize etme
Bir kontak silinip yeniden oluşturulursa, o telefon numarasına ait eski aramaların aiAnalysis verisi backend’de durur ama yeni kontağa bağlı değildir. POST /api/contacts/{id}/sync-analysis bu numaraya ait tüm geçmiş aramaları tarayıp özet, duygu geçmişi, itirazlar, BANT, pipeline aşaması ve lead skorunu sıfırdan yeniden inşa eder — tek bir aramadan değil, o numaraya ait bulabildiği bütün analizlerden.
İyi uygulamalar
- BANT’ı sadece güven — doğrulama olarak kullan — anahtar kelime tabanlı bir sezgiseldir, mükemmel değildir; kontak detayından elle düzeltebilirsin.
- Sıcak lead’leri bekletme —
lead_hottetikleyicili bir takip kuralı kur, skor 70’i geçen kişi otomatik önceliklensin. agentQualityScoredüşükse prompt’u gözden geçir — düşük “empati” veya “kapanış” tekrarlanıyorsa, tek tek görüşmeleri değil, asistanın talimatını düzelt.- KVKK — özet, duygu ve BANT alanları kişisel veridir; bu verilerin işlenme amacını açık rıza metninde belirt, “beni arama/verimi sil” talebi (
dncRequested) otomatik DNC işaretlemesine rağmen ilgili kişiye teyit ver. Ayrıntı: KVKK ve Veri Yönetimi.
Sorun giderme
| Belirti | Olası neden / çözüm |
|---|---|
| Analiz hiç üretilmedi | LLM çağrısı başarısız oldu → agent bir analysisFailed: true düşme analizi kaydeder (nötr duygu, information_provided sonucu); backend’e ulaşamadıysa DLQ’da bekliyordur. |
| Pipeline aşaması değişmedi | outcome hep no_answer dönüyor olabilir (aşama değişmez); veya türetilen aşama mevcut aşamadan geride kaldı (pipeline yalnızca ileri gider). |
| BANT kutuları boş kaldı | Görüşme metninde anahtar kelimeler (fiyat/bütçe, karar/yönetici, ihtiyaç/istedi, randevu/yarın) geçmemiş olabilir — elle düzelt. |
lead.hot webhook’u gelmedi | Isı zaten hottı (yeniden geçiş yok, olay yalnızca soğuk/ılıktan sıcağa geçişte tetiklenir); Zapier/Make bağlantısı yok. |
| Kadans otomatik tamamlanmadı/durmadı | Kontakta aktif bir kadans kaydı yoktu; aşama committed/closed/losta ulaşmadı. |
| Kampanya geri arama planlamadı | Görüşme bir kampanyaya bağlı değildi; callback ifadesi/nextCallAt tespit edilmedi. |