CarFinanceAgent / chatbot /tools /catalog_tool.py
emreceniklioglu
Initial commit: LangGraph multi-agent car finance chatbot
49102bb
Raw
History Blame Contribute Delete
2.36 kB
"""
tools/catalog_tool.py — Araç Modeli Kataloğu
AGENTIC PATTERN: Tool Use
━━━━━━━━━━━━━━━━━━━━━━━━
Araç modeli → binek/ticari sınıflandırması bu tool ile yapılır.
LLM modeli çıkarır, katalog nihai kararı verir.
O(1) lookup: JSON yüklenip dict'e çevrilir, uygulama başında bir kez.
"""
import json
import os
from functools import lru_cache
from langchain_core.tools import tool
CATALOG_PATH = os.path.join(os.path.dirname(__file__), "..", "data", "vehicle_catalog.json")
@lru_cache(maxsize=1)
def _load_catalog() -> dict:
"""
Kataloğu bir kez yükle, in-memory cache'de tut.
lru_cache(maxsize=1) → uygulama hayatı boyunca sadece bir kez okur.
"""
with open(CATALOG_PATH, encoding="utf-8") as f:
entries = json.load(f)
# Arama kolaylığı için düzleştirilmiş dict: "bmw_3 serisi" → {type, brand, model}
catalog: dict = {}
for entry in entries:
key = f"{entry['brand'].lower()}_{entry['model'].lower()}"
catalog[key] = entry
# Variant'ları da ekle
for variant in entry.get("variants", []):
vkey = f"{entry['brand'].lower()}_{variant.lower()}"
catalog[vkey] = {**entry, "model": variant}
return catalog
@tool
def lookup_vehicle(brand: str, model: str) -> dict:
"""
Araç marka ve modelinin binek/ticari sınıfını katalogdan döndürür.
Args:
brand: Araç markası (örn. "BMW", "Ford")
model: Araç modeli (örn. "3 Serisi", "Transit")
Returns:
{"found": bool, "type": "binek"|"ticari"|None, "brand": str, "model": str}
"""
catalog = _load_catalog()
key = f"{brand.lower()}_{model.lower()}"
if key in catalog:
entry = catalog[key]
return {"found": True, "type": entry["type"], "brand": entry["brand"], "model": entry["model"]}
# Fuzzy: sadece marka eşleşmesi
brand_matches = [v for k, v in catalog.items() if k.startswith(brand.lower() + "_")]
if brand_matches:
return {
"found": False,
"type": None,
"brand": brand,
"model": model,
"suggestions": [f"{m['brand']} {m['model']}" for m in brand_matches[:5]],
}
return {"found": False, "type": None, "brand": brand, "model": model, "suggestions": []}