ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

AI房产搜索助手:从对话到图片理解的垂直搜索MVP实战

2026/9/4 19:40:18 拓冰建站 浏览量
AI房产搜索助手:从对话到图片理解的垂直搜索MVP实战 这次看一个很有意思的房屋搜索产品形态。它来自 Hacker News 上的 Show HN 展示作者的表达很直接搜房不应该只是筛户型、筛价格、翻列表图而应该像聊天一样用户问“我想找通勤 30 分钟内、带书房、月成本控制在 8000 以内的小两居”系统能理解这句话能看懂房源照片里是不是真有书房还能把每月的持有成本估算出来。标题里三个能力点很值得拆开看对话式搜索、照片级多模态理解、月度开销估算。前两个是现在 AI 应用里最常见的能力组合第三个“月度成本估算”才是这套产品的差异化所在。它意味着系统不只做排序还要做推理和归因把不确定的持有成本拆成可解释的明细。这篇文章会做三件事先把这个产品形态背后的技术链路拆清楚再给出一套可以在本地跑起来的 MVP 验证流程最后把部署、接口、资源占用和合规边界一起盘一遍。如果你正在做房产信息类工具、智能体应用或者想了解多模态模型怎么落地到垂直搜索场景这篇可以直接收藏。1. 房屋搜索 AI 助手的核心能力速览从项目标题能推断出核心能力是三条链路不是单点功能能力项说明项目类型AI 房产搜索助手 / 智能 Agent 展示核心功能自然语言对话搜房、房源照片内容识别、月度持有成本估算交互方式对话式输入代替传统筛选项组合关键技术NL 转查询、语义召回、多模态图片理解、结构化成本计算输入数据房源文本字段、户型图/室内实拍图、周边设施信息等输出内容匹配房源列表、图片解析结论、月成本拆分明细部署方式视具体实现而定可做成 Web 服务或本地 API是否需要 GPU涉及多模态模型推理建议有独显纯文本降级逻辑可以 CPU 跑是否支持 API从产品形态看必须暴露后端接口否则前端对话无法工作是否支持批量任务批量图片解析和成本试算是比较合理的扩展方向适合场景房产信息平台、找房助手、经纪人提效工具、房源信息管理需要注意标题是产品展示而非完整开源仓库文档所以表格里的“推荐配置”“接口路径”不等于官方参数。实际要跑通这个产品还需要结合具体数据源和模型版本核实。2. 这个产品形态解决什么问题传统房产搜索的体验已经被固定了选城市、选户型、拉价格区间、看列表图然后用户自己判断照片里的装修、采光、房间实际用途。这套流程有两个明显问题。第一搜索表达是碎片化的。用户很难用连续的自然语言描述“我想找一套朝南、客厅能放下投影幕布、离地铁站步行不超过 800 米的房子”。传统筛选项支持价格、面积、居室数但很难支持“客厅能不能放投影幕布”这种需要看图和估算的条件。第二筛选粒度停留在字段层没有进入内容层。房源列表页通常会写“3 室 2 厅”但只有看了图片才知道第三个房间是书房、儿童房还是储物间。如果系统能理解图片内容和房间关系就能把搜索精度提高一个层次。月度成本估算的价值更直接。买房或租房的真实开销不只是挂牌价还包括按揭、物业、水电网、保险、维修分摊。标题里用“est. monthly costs”而不是简单写“价格”说明作者想提供一个更接近用户决策的计算能力。那这类工具适合谁如果是有真实房源数据的平台它可以作为“智能选房助手”的交互入口。如果是独立开发者它可以做一套小规模 MVP先验证对话、图片理解和成本估算三个子任务能不能串起来。如果是在做 Agent 应用它的技术链路也足够通用多模态输入到参数抽取、检索到调用外部计算最后把结果组织成自然语言返回。也要说清不适用的情况。如果房源数据量小且字段很规范传统筛选足够没必要引入多模态模型。如果产品要处理的是真实用户隐私和交易数据却没有明确的数据合规方案也不建议直接上线。这类 AI 房产搜索能做得很“聪明”但聪明的前提是数据来源合法、图片内容有授权、成本估算公式透明可复查。3. 标题背后其实是四个技术模块拆开看一个“会聊天、会读图、会算月成本”的房产搜索助手至少有四层模块。3.1 自然语言转查询用户聊天输入不能直接进数据库。需要把“我想找海淀区 500 万以内、通勤方便的电梯房”转成结构化的过滤条件。常用做法是让大模型做工具调用输出统一的 JSON Schema{ city: 北京, district: 海淀区, max_price: 5000000, features: [电梯房, 通勤方便], sort_by: match_score }这个 JSON 再转成后端查询。问题在于“通勤方便”“采光好”这类主观词没法直接映射必须先做语义检索或再走一轮模型判断。3.2 多模态房源图片理解图片理解的目标是把室内图、户型图变成可检索的结构化信息。比如识别出客厅、主卧、厨房的边界判断是否有阳台、是否有独立书房、整体装修风格、空间是否局促。这类任务可以用视觉语言模型VLM来实现。输入一张房源图和一个 prompt输出结构化描述{ room_type: living_room, space_feeling: open, has_balcony: true, furniture: [sofa, tv_console, bookshelf], lighting: bright, description: 客厅朝南采光好带阳台 }户型图比实拍图更难一些因为涉及墙体、门窗、面积比例关系部分模型只能做粗略判断。稳妥点的方法是先走普通 OCR 抽取面积和房间数标注再做视觉问答。3.3 月度成本估算引擎月度成本不能靠模型“拍脑袋”生成更适合写成一个计算函数由规则引擎决定。结构上通常包括输入变量、费用分母和说明输出三部分。输入变量包括房屋总价、首付比例、贷款年限、当前利率、物业费、保险、预估水电燃气、年均维修分摊。输出则要把每一个子项拆给用户看。如果直接让大模型生成成本结果容易产生数字幻觉。更推荐的做法是让模型从房源数据里提取关键字段然后把字段传给一个确定性的计算模块。成本估算的核心是透明度不是计算复杂度。3.4 对话编排与结果解释最后一层是把上面三个能力串起来。用户的每一轮提问系统要决定先检索文本还是先看图再决定是否需要调用成本计算。这种典型场景适合用 Function Calling 或 ReAct 式 Agent 来组织。比如用户说“这套房月维护大概多少”系统需要先定位当前房源再读取房源详情然后调用费用估算函数。如果用户问“这个客厅放得下双人沙发吗”系统需要先读取这张客厅图的尺寸描述再做空间关系判断。整个过程就是工具调用 多轮记忆并不需要特别复杂的架构但要把路由规则和上下文管理做好。4. 本地验证的环境准备在没有官方一键包的情况下本地搭一个验证环境并不复杂。核心思路是文本检索用轻量级向量库图片理解接开源多模态模型成本计算先写死规则函数最后用 FastAPI 把这些模块暴露出来。建议按下面的清单准备环境:依赖项说明Python3.10 或 3.11 即可太高或太低都可能遇到依赖兼容问题操作系统Windows / macOS / Linux 都可以Ubuntu 22.04 最省事模型运行时有 GPU 可以用 vLLM、Ollama 或 llama.cpp无 GPU 只能用小模型 CPU 推理多模态模型可选支持图像输入的开源模型具体按本机显存选择向量库本地小规模可直接用 Chroma 或 SQLite sqlite-vec数据源准备一个 CSV 或 JSON 格式的房源列表以及对应本地图片目录磁盘空间模型文件通常需要数 GB 到十几 GB需预留端口规划Web 服务建议先用 8000 或 7860 这类常见端口启动前排查占用先检查硬件# Linux 或 macOS 检查 GPU 工具 nvidia-smi # 检查 Python 版本 python --version如果本机没有可用 GPU方案就要调整图片理解任务换成 API 调用或者用 CPU 版的小型多模态模型速度会明显变慢只适合做功能验证不适合批量。5. 搭建一个可运行的最小原型下面给的不是原项目官方命令而是一套用于理解该产品形态的最小实现模板。假设已经有一个houses.json数据文件字段包括房源 ID、标题、价格、城市、户型字段并有一个图片文件夹photos/。5.1 安装依赖pip install fastapi uvicorn pydantic requests如果要用 Embedding 模型和向量检索再装向量库。假如选择 Chromapip install chromadb5.2 定义核心数据结构和成本计算函数from typing import List, Optional from pydantic import BaseModel class House(BaseModel): id: str city: str district: Optional[str] None title: str total_price: float area: float rooms: int living_rooms: int bathrooms: int has_elevator: bool False has_balcony: bool False class PhotoDescription(BaseModel): house_id: str rooms_detected: List[str] balcony: bool bright: bool description: str def estimate_monthly_cost(house: House, down_payment_ratio: float 0.3, loan_years: int 30, annual_rate: float 0.045, hoa_fee: float 0.0, insurance: float 0.0, utilities: float 0.0) - dict: loan_amount house.total_price * (1 - down_payment_ratio) monthly_rate annual_rate / 12 months loan_years * 12 if monthly_rate 0: mortgage loan_amount * (monthly_rate * (1 monthly_rate) ** months) / \ ((1 monthly_rate) ** months - 1) else: mortgage loan_amount / months monthly_cost { mortgage: round(mortgage, 2), hoa_fee: hoa_fee, insurance: insurance, utilities: utilities, maintenance_reserve: round(house.total_price * 0.0005, 2), total: round(mortgage hoa_fee insurance utilities house.total_price * 0.0005, 2) } return monthly_cost成本估算函数本身不需要大模型只要输入数据可靠结果就是确定性计算。这里的利率、首付比例只是示例真实场景应该从用户配置读取并且明确告知贷款利率会影响最终月供。5.3 图片理解函数图片理解这里用一个占位函数。真实项目中这个函数内部会调用多模态模型输出房间类型和特征。这里先保留调用结构方便后续接入模型或云服务def describe_house_photo(house_id: str, image_url: str) - PhotoDescription: # 这里应替换为真实多模态模型调用。 # 示例输出结构用于表示模型返回后的清洗结果。 return PhotoDescription( house_idhouse_id, rooms_detected[living_room, kitchen, bedroom], balconyTrue, brightTrue, description客厅明亮通透带朝南阳台地面铺设木地板。 )生产环境中需要在函数内部加错误处理。图片模糊、暗光、角度很偏都会影响识别结果最好在描述里带一个confidence字段低于阈值的图片不能进入搜索召回。5.4 对话解析与搜索装配对话查询先让大模型输出结构化参数。为了保持模块简单这里用一个parse_query函数代替完整的模型调用from typing import List def parse_query(user_input: str) - dict: # 真实环境使用大模型 Function Calling # 示例返回表示从“找海淀500万以内带电梯的两居”抽出的参数 return { city: 北京, district: 海淀, max_total_price: 5000000, rooms: 2, require_elevator: True } def search_houses(query: dict, houses: List[House]) - List[House]: result [] for h in houses: if query.get(city) and h.city ! query[city]: continue if query.get(district) and h.district ! query[district]: continue if query.get(max_total_price) and h.total_price query[max_total_price]: continue if query.get(rooms) and h.rooms query[rooms]: continue if query.get(require_elevator) and not h.has_elevator: continue result.append(h) return result这里用的是规则匹配更完整的方案是接入语义检索和向量召回。要理解的是架构分界自然语言转结构化是模型层检索房源是数据层成本估算是规则层最后统一由编排层响应。5.5 组装 FastAPI 服务from fastapi import FastAPI app FastAPI(titleAI Home Search API) houses_db [] app.post(/api/search) def chat_search(user_input: str): query parse_query(user_input) matched search_houses(query, houses_db) return {query: query, results: matched} app.post(/api/photo/describe) def photo_describe(house_id: str, image_url: str): desc describe_house_photo(house_id, image_url) return desc app.post(/api/estimate) def estimate(house_id: str, hoa_fee: float 0, utilities: float 0): house next((h for h in houses_db if h.id house_id), None) if house is None: return {error: house not found} cost estimate_monthly_cost(house, hoa_feehoa_fee, utilitiesutilities) return cost启动服务uvicorn main:app --host 127.0.0.1 --port 8000启动后可以先访问http://127.0.0.1:8000/docs看接口列表。这个过程可以作为本地验证的第一步先别接模型用假数据和函数把链路跑通再逐步替换成真实模型排查会容易很多。6. 功能测试与效果验证这套 MVP 最需要验证的并不是代码能不能跑而是三个核心任务的效果是否达标。建议准备一个只有 5 到 10 套房源的小数据集跑下面三类测试。6.1 对话式搜索测试测试输入可以这样写“北京海淀 500 万以内两居室要求带电梯”“不需要电梯但希望有阳台”“预算再低一点450 万以内”预期结果是系统能把连续几轮限制条件记录到上下文并生成准确的结构化查询。判断标准是看解析出来的 JSON 是否完整覆盖价格、地区、户型、特殊要求。最容易出问题的地方是“再低一点”这种需要结合上一轮上下文才能理解的描述所以要重点测多轮对话。6.2 图片理解测试选择三种典型图片室内客厅实拍图、户型图、光线很暗的手机随手拍。预期结果是客厅图能识别出是否带阳台、空间是否开阔、有没有明显家具户型图能识别出有几个卧室和客厅光线很暗的图应该提示图片质量低而不是强行返回一个不靠谱结论。判断标准是结构化输出和人工标注的差异。实际测试不需要追求识别和人工完全一致关键是看错误是否集中在某类图上。如果暗光图错误率特别高就在工程上做图片清晰度预检过滤低质量素材而不是把所有压力都交给模型。检查显存或 CPU 占用时可以观察推理过程。6.3 月度成本估算测试用同一套房源分别给三组不同首付比例和利率看输出明细是否合理。判断标准是总额等于各分项之和并且贷款月供随利率上行而上升。这里建议测试一个极端值比如全款买房此时贷款月供应该为 0成本只剩物业、水电和维修分摊。这类边界测试最能暴露公式写错的问题。成本估算引擎不能直接交给黑盒模型必须做单元测试。7. 接口 API 与批量任务设计如果前面 MVP 跑通下一步就是把接口按业务场景拆细。建议拆成四类接口接口功能调用时机/api/search对话搜索用户在聊天框输入问题后调用/api/photo/describe单图解析用户上传或系统抓取房源图后调用/api/estimate月成本估算用户点开具体房源时调用/api/batch/process批量解析图片和刷新成本定时任务或管理员批量导入时调用7.1 curl 调用示例对话搜索接口示例curl -X POST http://127.0.0.1:8000/api/search \ -H Content-Type: application/json \ -d { user_input: 北京海淀500万以内带电梯两居, session_id: user-001 }图片解析接口示例curl -X POST http://127.0.0.1:8000/api/photo/describe \ -H Content-Type: application/json \ -d { house_id: house_001, image_url: https://example.com/photos/living_room.jpg }月成本估算接口示例curl -X POST http://127.0.0.1:8000/api/estimate \ -H Content-Type: application/json \ -d { house_id: house_001, hoa_fee: 300, utilities: 450 }7.2 Python 调用示例import requests BASE_URL http://127.0.0.1:8000 payload { user_input: 北京海淀500万以内带电梯两居, session_id: user-001 } resp requests.post(f{BASE_URL}/api/search, jsonpayload, timeout30) print(resp.json())7.3 批量任务建议房源图片解析是典型批量任务场景。一个小区可能一次导入几百套房源每套房 5 到 10 张图。如果逐张调用网络和模型推理都会成为瓶颈。工程上建议加一层任务队列。任务结构可以用 JSON 表示{ job_id: batch_20250101_001, house_ids: [house_001, house_002, house_003], tasks: [ {type: photo_parse, house_id: house_001, image_urls: [url1, url2]}, {type: cost_update, house_id: house_001} ], webhook_url: https://example.com/callback }批量任务必须有日志和重试。图片下载失败、模型接口超时、返回 JSON 解析异常都要单独记录不能让整个队列停下来重跑。状态设计可以拆成 pending、processing、success、failed 四类每个任务单独标记便于断点续跑。8. 资源占用与性能观察AI 房产搜索的性能瓶颈主要集中在图片理解和自然语言解析两个模型推理环节传统数据库筛选和规则成本计算几乎不占资源。从技术上判断这个产品的核心开销可以分成三层环节开销来源主要观察指标文本解析大模型推理显存占用、单次请求延迟图片理解多模态模型推理显存占用、每张图片处理延迟文本向量化与检索Embedding 向量索引内存占用、检索延迟本地观察 GPU 资源nvidia-smi如果同时起多个模型进程比如一个文本模型负责对话、一个多模态模型负责图片显存会叠加。更稳妥的做法是按需加载模型或者用支持多模型常驻的推理服务统一管理。分辨率对推理速度的影响最直接。图片不能直接拿原始像素尺寸进模型需要先做预处理长边通常压到 1024 或 768 级别。分辨率越接近模型训练尺寸推理越快结果也越稳定。如果要支持大图识别可以做切片把一张户型图按区域切成多块再分别识别效果往往好于直接缩放整图。批量并发时要注意任务排队。图片理解接口如果设计成单模型常驻默认只能单张顺序处理。要让吞吐提升需要做推理服务层的并发控制而不是简单开多个 Python 线程因为模型显存和线程锁很快会成为瓶颈。一个可行方案是前端用 Redis 做任务队列后端消费任务并控制并发数尽量保证单卡推理服务每秒处理数量稳定。CPU 推理能不能用取决于选什么规模的模型。纯尺寸不大的 OCR 或者文本分类模型在 CPU 上可以做但完整的多模态图片理解加对话CPU 推理延迟会很高只能做小流量验证。如果本机没有 NVIDIA 显卡建议优先考虑调用合规的云模型 API而不是硬扛本地推理。9. 常见问题与排查方法下面这组排查表可以直接照搬用来处理这个 MVP 最常见的坑。实测环境不同问题不一定完全相同但排查顺序都是一样的。问题现象可能原因排查方式解决方案uvicorn启动后端口被占用8000 端口已被其他进程占用运行lsof -i :8000或netstat -ano换一个端口例如--port 8001图片解析返回空结果图片 URL 不可访问或格式不支持先用浏览器打开图片 URL检查 HTTP 状态码下载到本地再解析或转成 JPG模型显存不足模型参数量超过显卡显存运行nvidia-smi看显存状态换更小的量化模型或调低图片输入分辨率对话搜索解析不出结构化参数输入太口语化或缺少上下文打印模型返回的原始 JSON别直接吞异常增加 few-shot 示例或把用户输入的约束缺失字段在 prompt 中显式说明成本估算总额不等于分项之和浮点精度或保留位数不一致检查total是否重新计算统一用round到小数点后两位避免中间变量被覆盖批量任务跑到一半卡住单个图片下载或模型调用超时查看任务日志检查超时配置给单个任务设置超时和失败重试超过次数就标记failed接口响应速度特别慢没有并发控制所有请求排队看推理服务和接口日志的时间戳用任务队列限制并发数避免请求直接打到模型层图片返回结果质量不稳定同一种对象拍摄角度差异大对比多组图片的人工标签和模型输出加入低置信度过滤把不确定的图片交给人工复核队列实际调试时最值得记住的一条经验是把模型调用和业务逻辑解耦。模型返回的非结构化结果先转成统一 JSON再交给下游逻辑整个过程记录一次原始返回。这样即使某张图识别错了也不至于让整个房源进入错误排序。10. 产品上线前的合规与使用边界做房产搜索 AI 工具必须把边界想清楚不能只关注模型效果。房源数据是典型的强版权和高隐私数据。图片内容通常来自中介平台、业主或经纪公司没有授权的情况下不能把图片随意抓取后用于模型训练或对外展示。做 MVP 时建议使用公开可授权的数据集或者自己模拟数据。涉及用户输入的小区、预算、通勤条件等偏好信息也属于敏感信息存储时要脱敏并限制访问范围。成本估算天然带有财务建议属性。示例代码里的折算利率、物业费等参数不能作为投资建议。产品界面应展示公式和参数来源并提示用户最终费用需要结合银行、物业和税务机构的信息进行确认。一旦涉及贷款、税费等专业结论最好增加免责说明。月成本估算要做到可解释不能只给一个“约 7000 元/月”的数字要有 mortgage、物业费、水电等拆分项。还有一个容易被忽略的合规点图片识别可能会识别出人脸、门牌号、儿童房和室内私人物品。房源图通常不希望暴露原住址和隐私物品所以在做批量解析时应优先做去标识化处理并限制图片的可见范围。11. 从标题到落地真正值得验证的三件事这类“AI 垂直搜索”产品最怕的不是模型不够聪明而是用户问完一轮后发现回答解释不了或者推荐结果不知道为什么出现。第一件值得花时间验证的事是对话质量。用户会换很多种说法描述同一需求系统要能在多轮对话里稳定抽取条件。这个测试不需要大样本准备 30 到 50 条真实找房语句反复调 prompt 和解析逻辑就能看出模型在短句、长句、否定表达上的差距。第二件值得验证的是图片理解的准确率边界。搞清楚模型在客厅图、厨房图、暗光图、户型图上分别什么表现能否过滤低质量图输出的房间类型和设施标签是否可用于检索。只要这一步稳定搜索结果质量就会有明显提升。第三件是成本估算的可解释性。把公式写清楚让用户能看懂为什么是这个月成本比把数字预测得精确更重要。与其让模型生成一个看起来精准但解释不了的数字不如让规则引擎把每个分项算得明明白白。这个设计思路也适合扩展方继续做税费计算、学区距离、通勤时间等更多结构化能力。如果你想拿这个方向做产品这套 MVP 是足够快的起点FastAPI 做接口、规则函数做成本计算、多模态模型做图片解析、大模型负责自然语言路由。先把链路跑通再逐步替换模块比一开始就搭建完整 Agent 系统更容易控制风险。