EYDefterEmre Yakut
← tüm yazılar
AI & Claude · Sistem · derin

“DN20 kelepçeli ultrasonik su sayacı” — katalogu cümleyle aramak

Satışçı ürünü tarif ediyor, kod numarasını bilmiyor. Katalogda 4.000 kalem var. Aradaki boşluğu AI ile doldurdum — ama AI’ın ürün uydurmasına izin vermeden.

"yirmilik, ultrasonik, uzaktan" niyet ayrıştırıcı kalıp eşleme SERT (eleme) YUMUŞAK (sıralama)diameter = DN20product_type = waterpressure_class ≥ …technology = ultrasoniccommunication ∈ {wmbus…} veritabanı GERÇEK ürünler model veri ÜRETMEZ — filtre üretir. ürün listesi her zaman veritabanından gelir.ontolojide tanımlı olmayan bir anahtar üretilirse istek REDDEDİLİR, tahmin edilmezhalüsinasyon için bir kapı bırakılmaz

Satış ekibindeki biri müşteriyle telefonda konuşuyor. Müşteri diyor ki: “yirmilik hatta takılacak, ultrasonik olsun, uzaktan okunsun.”

Satışçının bulması gereken şey katalogdaki bir kalem. Katalogda dört binden fazla ürün var ve arama kutusu yalnız ürün adında ve kodunda arıyor. “Ultrasonik” yazınca 180 sonuç geliyor.

Bu boşluğu kapatmak için CRM’e bir semantik arama katmanı yazdım.

Önce yanlış yolu söyleyeyim

Kolay çözüm şu: cümleyi bir dil modeline ver, “bana uygun ürünleri listele” de.

Bu, çalışıyormuş gibi görünen ve satılamayacak bir sonuç üretiyor. Model kataloğu ezbere bilmediği için mantıklı görünen ürün kodları uyduruyor. Satışçı o kodu teklifle gönderiyor. Öyle bir ürün yok.

Bir kere bile olsa bu, sistemin tamamına olan güveni bitirir.

Kural: model veri üretmez, filtre üretir

Mimarinin tek cümlelik özeti bu.

serbest metin
   ↓  (niyet ayrıştırıcı)
{ sert filtreler, yumuşak filtreler }
   ↓  (veritabanı sorgusu)
gerçek ürünler

Model — ya da regex tabanlı ayrıştırıcı — yalnız ortadaki adımı yapıyor. Ürün listesi her zaman veritabanından geliyor. Katalogda yoksa sonuçta da yok.

Ontoloji: neyin ne olduğunu tanımlamak

Bunun işe yaraması için sistemin ürün özelliklerini anlaması gerekiyor. Onu da elle tanımladım: her özellik anahtarı, tipi, ve ağırlığı.

alantürneden
diameter (çap)sertDN20 hattına DN25 takılmaz. Fiziksel.
product_typesertSu sayacı isteyene ısı sayacı gösterilmez.
pipe_connectionsertDişli/flanşlı — takılmıyorsa takılmıyor.
pressure_classsertBasınç sınıfı yetmiyorsa ürün geçersiz.
technologyyumuşakUltrasonik tercih; mekanik de iş görebilir.
communicationyumuşakwM-Bus tercih; M-Bus da uzaktan okunur.
certificationyumuşakVarsa artı, yoksa eksi — ama eleme değil.

Sert filtre sağlanmıyorsa ürün listeden çıkar. Yumuşak filtre yalnız sıralamayı etkiler. Bu ayrım, sonucun hem doğru hem kullanışlı olmasını sağlıyor: eleme fiziksel gerçeklerle, sıralama tercihlerle yapılıyor.

Niyet ayrıştırıcı

Serbest metni filtrelere çeviren parça. Şaşırtıcı biçimde büyük kısmı model değil, kalıp eşleme:

"yirmilik"  → diameter = DN20
"DN 20"     → diameter = DN20
"20'lik"    → diameter = DN20
"ultrasonik"→ technology = ultrasonic
"uzaktan"   → communication ∈ {wmbus, mbus, lora}

Buradaki incelik, çakışmaları çözmek. “wmbus” eşleştiğinde “mbus” listeden çıkarılıyor — yoksa iki ayrı haberleşme tipi aynı anda isteniyor gibi görünüyor ve sonuç bulanıklaşıyor.

Ve en önemli kural: ayrıştırıcı ontolojide tanımlı olmayan bir anahtar üretemiyor. Tanımsız bir alan gelirse istek reddediliyor. Halüsinasyon için bir kapı bırakılmıyor.

Sonra MCP: Claude’un doğrudan bağlanması

Bu katman hazır olunca bir adım daha attım: CRM’e bir MCP sunucusu yazdım. Böylece bir AI istemcisi doğrudan bağlanıp katalogda arama yapabiliyor.

Sunucu araçlarını listeliyor, istemci onları çağırıyor. Veri hiçbir zaman modele toplu olarak verilmiyor — model yalnız sorduğu sorunun cevabını görüyor.

bir dayanıklılık detayı

Eski veritabanı katmanı, bir hata durumunda die() ile süreci sonlandırıyordu. MCP bir JSON-RPC protokolü olduğu için bu, istemciye yarım kalmış bozuk bir yanıt gönderiyor ve bağlantıyı düşürüyordu.

Çözüm çıktıyı tamponlayıp bir kapanış kancası koymak oldu: süreç beklenmedik şekilde biterse tampon temizleniyor ve yerine geçerli bir JSON-RPC hata yanıtı yazılıyor. İstemci “bir şeyler ters gitti” diyor; “protokol bozuldu” demiyor.

Eski bir kod tabanını yeni bir protokole bağlarken en çok zaman alan şey özellikler değil, bu tür çıkış yolları oluyor.

Ne öğrendim

Bir sisteme AI eklerken doğru soru “model ne kadar akıllı?” değil. “Model yanılırsa ne olur?”

Burada cevabı şu: yanılırsa yanlış filtre üretir. Sonuçta ya alakasız ürünler çıkar ya da hiç çıkmaz. İkisi de fark edilir ve düzeltilebilir.

Modelin ürün uydurmasına izin verseydim, yanlış cevap doğru cevapla aynı görünecekti. Aradaki tüm fark bu.

AI & ClaudeSistem