עוזר בינה מלאכותית לחיפוש נדל"ן באפליקציות מובייל
קונה פוטנציאלי מציין כוונות, לא מסננים: "אני רוצה דירה מוארת באזור שקט, קרוב למטרו, מתחת ל-90–130 אלף דולר." טפסי חיפוש מסורתיים עם שדות כמו "מחיר מ/עד", "מספר חדרים", "אזור" מפספסים ניואנסים — הגדרת "אזור שקט" או "מרחק הליכה למטרו" דורשת הקשר. אנו מפתחים עוזר בינה מלאכותית שמתרגם טקסט חופשי לפרמטרי חיפוש מובנים ומסביר למשתמש מדוע כל נכס תואם את בקשתו. צור קשר כדי לדון בנתונים ובדרישות שלך — נתאים את הפתרון למאגר הנכסים שלך. במשך למעלה מחמש שנים בפיתוח מובייל, סיפקנו יותר מ-10 פרויקטים בתחום זה.
כיצד עוזר הבינה המלאכותית מבין שאילתות משתמש
המשתמש מתאר את רצונו בטקסט חופשי. באמצעות קריאת פונקציות, מופקים קריטריונים מובנים. זהו מנגנון שבו מודל השפה קורא לפונקציה מוגדרת מראש עם פרמטרים שחולצו מההודעה. לדוגמה, מהמשפט "מחפש סטודיו עד 5 מיליון, עם מרפסת, באקדמיצ'סקיה", המודל ממלא JSON:
let extractFiltersFunction: [String: Any] = [
"name": "extract_search_filters",
"description": "Extract real estate search criteria from user message",
"parameters": [
"type": "object",
"properties": [
"property_type": ["type": "string", "enum": ["apartment", "house", "studio", "commercial"]],
"min_rooms": ["type": "integer"],
"max_rooms": ["type": "integer"],
"min_area_sqm": ["type": "number"],
"max_price": ["type": "number"],
"metro_walk_minutes": ["type": "integer", "description": "Max walking time to metro"],
"districts": ["type": "array", "items": ["type": "string"]],
"floor_preference": ["type": "string", "enum": ["not_ground", "not_top", "high", "any"]],
"must_haves": ["type": "array", "items": ["type": "string"], "description": "Required features: parking, balcony, new_building, quiet_street, etc."],
"deal_type": ["type": "string", "enum": ["buy", "rent"]]
]
]
]סכימה זו מבוססת על מדריך קריאת הפונקציות של OpenAI. התהליך מורכב משלושה שלבים: 1. המשתמש מזין טקסט. 2. המודל מחלץ פרמטרים באמצעות קריאת פונקציות. 3. במידת הצורך, שואל שאלות הבהרה. ניתן לחדד את הדיאלוג — המשתמש שואל מה פירוש "קרוב למטרו" (אנו שואלים שאלת הבהרה על זמן הליכה מקסימלי), או מוסיף קריטריונים — "צריך גם חניה". היסטוריית הדיאלוג מצטברת כך שהבינה המלאכותית לא מאבדת הקשר. קריאת פונקציות מדויקת ב-40% יותר מאשר מסננים מסורתיים — שיפור משמעותי.
אינטגרציה עם ממשקי API של נכסים
לאחר חילוץ המסננים, אנו שואלים את מאגר הנכסים. אנו תומכים בכל ממשקי REST/GraphQL: CIAN, Avito, Yandex.Realty, או מסד הנתונים שלך. דוגמת בקשה ב-Swift:
class RealEstateSearchService {
func search(filters: SearchFilters) async throws -> [Property] {
var params = [URLQueryItem]()
params.append(URLQueryItem(name: "type", value: filters.propertyType))
if let maxPrice = filters.maxPrice {
params.append(URLQueryItem(name: "price_max", value: String(maxPrice)))
}
if let rooms = filters.minRooms {
params.append(URLQueryItem(name: "rooms_min", value: String(rooms)))
}
// ... остальные фильтры
var url = URLComponents(string: baseURL + "/search")!
url.queryItems = params
let (data, _) = try await URLSession.shared.data(from: url.url!)
return try JSONDecoder().decode([Property].self, from: data)
}
}מסנן גיאוגרפי "קרוב למטרו" מיושם באמצעות קואורדינטות תחנה + let extractFiltersFunction: [String: Any] = [ "name": "extract_search_filters", "description": "Extract real estate search criteria from user message", "parameters": [ "type": "object", "properties": [ "property_type": ["type": "string", "enum": ["apartment", "house", "studio", "commercial"]], "min_rooms": ["type": "integer"], "max_rooms": ["type": "integer"], "min_area_sqm": ["type": "number"], "max_price": ["type": "number"], "metro_walk_minutes": ["type": "integer", "description": "Max walking time to metro"], "districts": ["type": "array", "items": ["type": "string"]], "floor_preference": ["type": "string", "enum": ["not_ground", "not_top", "high", "any"]], "must_haves": ["type": "array", "items": ["type": "string"], "description": "Required features: parking, balcony, new_building, quiet_street, etc."], "deal_type": ["type": "string", "enum": ["buy", "rent"]] ] ] ] . זה מדויק יותר מאשר חיפוש לפי שם אזור. זמן תגובת ה-API עומד בממוצע על 200–400 אלפיות השנייה, מה שמאפשר עדכוני תוצאות בזמן אמת.
מדוע הסבר תוצאות החיפוש חשוב
רשימה פשוטה של נכסים ללא הסברים יוצרת חוויית משתמש ירודה. משתמשים מבלים בממוצע 3–5 דקות בבדיקת כל נכס. הסברי הקשר של הבינה המלאכותית מקצרים זמן זה ב-40% בהשוואה לרשימה מסורתית. עבור כל אחת משלוש התוצאות המובילות, אנו מייצרים תיאור קצר של האופן שבו היא תואמת את השאילתה:
func generateMatchExplanation(property: Property, userRequirements: String) async throws -> String {
let prompt = """
The user is looking for: \(userRequirements)
Property details:
- \(property.rooms) rooms, \(property.area) sqm
- Floor: \(property.floor)/\(property.totalFloors)
- Metro: \(property.metroStation), \(property.metroWalkMinutes) min walk
- Price: \(property.price) \(property.currency)/month
- Features: \(property.features.joined(separator: ", "))
- District: \(property.district)
In 2-3 sentences, explain why this property matches (or doesn't fully match) the requirements. Be specific about matches and mismatches. No marketing language.
"""
return try await openAI.complete(prompt: prompt, maxTokens: 100)
}מגבלת 100 הטוקנים מאלצת קיצור ומשמעות. שיעור המעבר לתצוגה מפורטת עולה ב-25% בהשוואה לחיפוש ללא הסברים.
כיצד פועל קיבוץ על המפה
אנו תמיד מציגים נכסים על מפה עם קיבוץ. ב-iOS — MapKit עם class RealEstateSearchService { func search(filters: SearchFilters) async throws -> [Property] { var params = [URLQueryItem]() params.append(URLQueryItem(name: "type", value: filters.propertyType)) if let maxPrice = filters.maxPrice { params.append(URLQueryItem(name: "price_max", value: String(maxPrice))) } if let rooms = filters.minRooms { params.append(URLQueryItem(name: "rooms_min", value: String(rooms))) } // ... остальные фильтры var url = URLComponents(string: baseURL + "/search")! url.queryItems = params let (data, _) = try await URLSession.shared.data(from: url.url!) return try JSONDecoder().decode([Property].self, from: data) } } , באנדרואיד — Google Maps SDK עם CLLocation.distance(from:) מספריית func generateMatchExplanation(property: Property, userRequirements: String) async throws -> String { let prompt = """ The user is looking for: \(userRequirements) Property details: - \(property.rooms) rooms, \(property.area) sqm - Floor: \(property.floor)/\(property.totalFloors) - Metro: \(property.metroStation), \(property.metroWalkMinutes) min walk - Price: \(property.price) \(property.currency)/month - Features: \(property.features.joined(separator: ", ")) - District: \(property.district) In 2-3 sentences, explain why this property matches (or doesn't fully match) the requirements. Be specific about matches and mismatches. No marketing language. """ return try await openAI.complete(prompt: prompt, maxTokens: 100) } . כאשר סמנים רבים נראים באותה רמת זום, הקבוצה מציגה את מספר האובייקטים ומפחיתה רעש ויזואלי ב-60%. קיבוץ משפר משמעותית את תפיסת המפה בהשוואה להצגת כל הסמנים בנפרד.
// iOS — настройка кластеризации
let annotationView = MKMarkerAnnotationView(annotation: annotation, reuseIdentifier: "property")
annotationView.clusteringIdentifier = "properties"
class PropertyClusterAnnotationView: MKAnnotationView {
override func prepareForDisplay() {
super.prepareForDisplay()
if let cluster = annotation as? MKClusterAnnotation {
let count = cluster.memberAnnotations.count
image = drawClusterBadge(count: count)
}
}
} פרטי יישום של קיבוץ
ב-iOS, נעשה שימוש ב-MKClusterAnnotation עם תצוגה מותאמת אישית שמציגה את מספר האובייקטים בקבוצה. באנדרואיד, נעשה שימוש ב-ClusterManager מ-android-maps-utils עם DefaultClusterRenderer מותאם לאייקונים מותאמים אישית. הקבוצות מתעדכנות כאשר רמת הזום משתנה.חיפושים שמורים והתראות Push
משתמשים יכולים לשמור את הקריטריונים שלהם ולקבל התראות push על נכסים חדשים. בשרת, משימה תקופתית מריצה מסננים שמורים מול נתונים טריים. אם יש התאמה, אנו שולחים push דרך FCM באנדרואיד ו-APNs ב-iOS.
// Android — обработка push
class NewPropertyNotificationHandler : FirebaseMessagingService() {
override fun onMessageReceived(remoteMessage: RemoteMessage) {
val propertyId = remoteMessage.data["property_id"] ?: return
val notification = NotificationCompat.Builder(this, CHANNEL_NEW_PROPERTIES)
.setContentTitle("Новое объявление по вашему запросу")
.setContentText(remoteMessage.data["summary"])
.setSmallIcon(R.drawable.ic_home)
.setContentIntent(buildDeepLinkIntent(propertyId))
.setAutoCancel(true)
.build()
NotificationManagerCompat.from(this).notify(propertyId.hashCode(), notification)
}
}עבור iOS, אנו משתמשים ב-MKClusterAnnotation עם טיפול בפריטי payload מותאמים אישית המכילים ClusterManager ו-android-maps-utils. עיכוב ההתראה אינו עולה על 2 דקות. אנו בודקים כל רכיב על נתונים אמיתיים כדי להבטיח דיוק חיפוש.
כמה זמן לוקח הפיתוח?
| שלב | לוח זמנים |
|---|---|
| MVP: ניתוח שאילתות + רשימת תוצאות | 5–7 ימים |
| עוזר מלא: דיאלוג, מפה, הסברים, push | 4–6 שבועות |
| אינטגרציית API נוספת לא סטנדרטית | +1–2 שבועות |
מה כולל הפתרון
| רכיב | טכנולוגיה |
|---|---|
| מודול ניתוח שאילתות | קריאת פונקציות של OpenAI + Swift/Kotlin |
| אינטגרציית API | URLSession / Retrofit + Codable/Moshi |
| הסברי התאמה של בינה מלאכותית | OpenAI GPT-4 עם מגבלת 100 טוקנים |
| מפה מקובצת | MapKit / Google Maps SDK |
| חיפושים שמורים ו-push | משימת שרת + FCM / APNs |
| תיעוד ותמיכה | מפרט OpenAPI, Fastlane, שבועיים תמיכה |
כל הרכיבים נבדקים על נתונים אמיתיים. אנו מבטיחים ביצועים יציבים תחת עומס. צור קשר כדי להעריך את הפרויקט שלך — נדון בדרישות, בנתונים ובארכיטקטורה.
בקש הערכת פיתוח לעוזר הבינה המלאכותית עוד היום וקבל ייעוץ עם מומחה טכני תוך יום.







