用RAG打造家居装修AI咨询助手:从知识库到问答系统实战 装修咨询这件事做过的人都懂。手机里存了一堆避坑指南预算表验收清单真到要问点什么的时候——比如卫生间防水到底刷几遍半包和全包的费用为什么差出一辆小车——你翻遍收藏夹也找不到一个能直接给出准确答案的入口。这就是我做家居装修 AI 智能咨询助手的起因把散落在各个装修论坛、知识平台、经验贴里的信息重新组织起来做成一个能用大白话直接提问、几秒就能给出有依据答案的问答系统让装修咨询从大海捞针变成一问即答。这个项目并不算多高深本质上是用当下成熟的 RAG检索增强生成技术针对家居装修这个垂直领域做了一次务实的落地。它要解决的是三个很具体的问题第一装修知识碎片化严重用户不知道该信谁第二通用大模型虽然懂很多常识但遇到需要精确到工艺标准、材料参数、验收细节的问题时容易含糊甚至编造第三现有的装修平台咨询入口大多对接的是人工客服或销售问专业问题容易被绕到推销上。这篇文章我会从需求拆解、方案选型、核心实现到排错经验把整个搭建过程完整讲清楚。想给自己的场景做垂直问答应用的开发者或者单纯想搞明白这种 AI 助手靠不靠谱的普通用户都能从中拿到点实在的东西。1. 先看清问题装修咨询场景里的真实需求1.1 用户到底想问什么做这个项目之前我先花了一段时间整理装修咨询的真实问题。有条件的话可以直接扒某装修平台公开展示的问答记录或者用问卷调查的方式收集身边正在装修的朋友的疑问。整理下来发现装修咨询的问题远没有想象中那么发散集中在六类流程类装修第一步该做什么先装门还是先铺地板材料类实木地板和复合地板怎么选乳胶漆和墙纸哪个环保工艺类防水刷几遍瓷砖铺完多久能踩水电改造要不要全屋换线预算类100平米半包大概多少钱全屋定制和木工打柜子哪个划算验收类交房验房要看哪些项目卫生间闭水试验做多久风格类小户型适合什么风格原木风和北欧风有什么区别这些问题有一个共性是答案不是一句话能说清的它跟户型情况、所在城市、材料档次、施工队伍的水平都有关系。比如同样是刷几遍防水卫生间墙面和地面的要求不一样厨房和阳台的要求又不一样规范上还有具体的数值。这就决定了任何一个懂行的老装修师傅在回答问题的时候都要先补充很多背景条件而传统搜索把这些细节全都摊在几十个网页里让用户自己去找体验自然很差。这些问题的另一个特点是标准答案其实就藏在一些相对权威的资料里比如施工规范、品牌官方施工说明、资深从业者写的经验总结。我的目标不是让 AI 凭空回答问题而是把这类材料收集起来做成一个可检索的知识底座让 AI 在回答时先翻资料再说话。1.2 为什么通用大模型解决不了这个问题很多人第一反应是现在的大模型不是什么都懂吗直接拿通用模型做咨询不就行了我实测过几款主流通用模型对装修话题确实能聊但离可用差得远。举几个实际测试暴露的问题回答过于笼统问卫生间防水做几遍通用模型会答一般刷两到三遍但不会说清楚墙面和地面是否一致丙纶布和涂料施工有什么本质区别闭水试验要在什么节点做。这种回答没有错但也没有用。数据陈旧装修材料和工艺更新很快比如近几年流行的薄贴法瓷砖工艺大模型训练数据里可能覆盖不足回答容易还停留在传统厚贴法的思路上。没有地区差异意识同一个全包报价一线城市和三四线城市能差出每平米几百块通用模型的回答往往是全行业平均水平的含糊数据。容易编造细节当用户追问得更细比如墙固和地固到底是不是必需品水管走顶好还是走地好模型偶尔会自信地给出一个听起来很专业、实际经不起推敲的说法。这些问题的根源不在于模型能力不行而在于模型是基于通用语料训练的对垂直领域的精确信息掌握不足也无法针对用户的具体情况做检索和引用。所以必须用 RAG 的思路把外部可信知识库作为回答的底座让模型先查后答。2. 方案设计决定好不好用的几个关键选择2.1 整体架构RAG是当下最务实的选择做垂直问答应用摆在面前的有两条路微调大模型或者 RAG。我的选型结论是 RAG理由很现实微调的成本和收益不成正比。微调需要准备大量高质量的问答对数据装修领域的公开数据很多但整理成结构化问答对的成本很高而且一旦知识需要更新比如某品牌推出了新工艺微调模型要重新训练一遍迭代太慢。RAG天然带证据链。RAG 可以把回答对应的原文片段拎出来展示给用户这是装修咨询场景里特别重要的信任基础。用户问防水做几遍AI 回答完了再补一句依据来自施工规范详见知识库第X节用户的接受度会高很多。RAG可以做增量更新。知识库里加几篇文档、重新跑一遍向量化新知识就生效了。实测从加文档到生效半小时以内就能搞定。架构上我采用了最经典的一条链路用户问题 → 向量检索 → 候选内容聚合 → 提示词组装 → 大模型生成 → 答案附带引用来源。装修领域的问题相对封闭不需要复杂的工作流和多轮工具调用简单链路维护成本低、出问题容易排查这很重要。2.2 知识库建设质量优先于数量知识库是整个系统的地基这一步偷懒后面会成倍还债。我在构造知识库时定了几条原则来源可信度分级。第一优先级是国家和行业施工规范、标准图集第二优先级是主流品牌的官方施工指南和产品说明书第三优先级是资深从业者的系统经验总结第四优先级才是论坛帖子和个人分享。低优先级内容必须经过人工审核才能进入知识库宁可少放也不要滥放。去广告化处理。网上大量装修文章是整装公司、建材品牌的软文表面讲知识结尾一定绕到找某某公司买某某品牌。这类内容不管写得多么详实我都直接排除。统一格式与术语。装修行业里同一个东西叫法很多比如地板压条有人叫扣条阴阳角有人叫阳角条。知识库里如果术语不统一检索阶段很容易出问题。我在录入资料时会把常见同义词整理成表在文本里手动标注规范叫法同时构建一个小的同义词典供检索层使用。按场景组织文档。我按空间 工序 材料 风格四个维度给文档打标签比如厨房/防水/涂料/验收这一步是为了给分块和索引提供依据。整个知识库我大概维护了二十多篇长文加一百多篇短问答覆盖了开头整理的六类高频问题。说实话量不大但每个问题都能在库里找到对应的、经过验证的答案。2.3 Embedding选型与向量存储知识库里的文本要让机器能找得到就需要转成向量做相似度检索。这里有一个容易犯的错误——不要一上来就追求高精度的商用 Embedding 接口先看看开源的通用中文模型够不够用。我用了一套开源的通用中文 Embedding 模型作为主力实测在装修垂直语料上的召回效果已经能满足需求后续如果发现检索精度不够再考虑商用服务做替换也不迟。向量存储我选了开源方案。原因很简单项目体量不大单机部署完全够用开源方案不需要额外支付服务费用数据也能保留在本机更可控。索引构建时选用余弦相似度作为距离度量比默认的 L2 距离在文本语义匹配上的表现更稳。2.4 检索不是把问题扔进去就完了RAG 项目的实际效果一半取决于检索质量另一半才取决于生成。很多人跑通 demo 之后觉得效果一般问题往往不在大模型而在检索到的资料不对。我针对装修领域做了几项针对性优化混合检索只依赖向量的语义检索会出现一个问题——用户问防水做几遍向量相似度可能把涂料刷几遍油漆涂刷次数这类文章也捞出来因为语义上太接近了。我加了 BM25 关键词检索把两种方式的召回结果做融合取并集后再统一排名。这样防水这个关键词就能稳住在结果里。查询改写用户提问很口语化比如墙皮要不要铲掉知识库里写的是原墙面基层处理。直接检索很难命中。我的做法是在检索前先用大模型做一次轻量的改写和同义扩展把口语问题映射到知识库里更规范的表述。重排混合检索召回的数量可以放宽到 10~15 条然后用一个轻量级的重排模型或简单规则把与问题真正对口的片段排到前面。这一步对最终效果提升非常明显。3. 核心实现把知识喂给 AI 的完整流程3.1 数据准备与清洗过程我从确定选题到落地花费时间最长的不是写代码而是准备数据。原始资料要么是网页格式要么是 PDF 文档转换出来全是混乱的换行符和广告区块。清洗流程大致有三步第一步转纯文本把所有内容统一转成 Markdown 格式。对网页内容用通用抽取工具把正文提取出来丢掉导航、侧栏、评论区第二步人工逐篇审阅标记可信度级别、删除广告软文、修正错别字和明显过时的内容第三步统一格式每篇文档都用多级标题组织重要工艺参数用加粗和表格突出方便后续分块时保持语义完整。这一步我有一个要特别提醒的坑不要高估自动化清洗的效果。装修行业的网页内容质量参差不齐正则抽出来的正文经常夹着无关的行业新闻和推荐位。我最后是由人工按一篇一篇的粒度审核的虽然累了点但建模之后再返工的代价高得多。清洗完成后的数据结构大致是source: 某施工规范/某经验总结 category: 卫生间防水 title: 卫生间防水施工要点 content: | ### 基层处理 ### 防水涂料施工 ### 闭水试验3.2 分块策略切分可不是按字数截断直接把一篇长文章塞给模型不现实上下文长度有限而且检索时整篇文章作为一坨向量粒度太粗定位不到具体答案句。分块是 RAG 效果的关键变量我的做法是优先按结构切分。Markdown 的一级、二级标题就是天然的切分边界先把文档按标题拆成多个小节避免一个片段跨两个主题。控制块大小。每个分块控制在 300~500 字之间。太短则信息不全模型可能拿不到完整上下文太长则引入噪声且占用大模型的输入窗口。这个数字不是拍脑袋定的我对比过 200 字、400 字、800 字三档400 字左右在命中率和回答完整度上最平衡。设置重叠。相邻分块之间保留 50~100 字的重叠。原因很朴素很多句子跨段落才说完整比如某节末尾说一般推荐两遍下一节开头才说第一遍和第二遍的间隔时间硬切会把语义截断。关键表格转成文字。装修文档里常有参数表比如防水层厚度要求不同房间的用水要求直接保留 Markdown 表格会让检索和模型理解都变困难。我在预处理时把表格逐行转成指标数值的自然语言放到对应分块里。3.3 Embedding 与向量库写入分块完成后就是向量化写入。原本我想把全部代码放在这里展示但实际核心逻辑很短主要是两个动作用 Embedding 接口把每个分块变成向量再把向量和原文元数据写进向量库。核心流程大概长这样from vector_store import VectorStore # 封装好的向量库操作 def load_knowledge_base(file_paths): store VectorStore(collection_namedecoration_kb) for path in file_paths: chunks chunk_markdown(path) for idx, chunk in enumerate(chunks): store.add( textchunk[content], metadata{ source: chunk[source], category: chunk[category], title: chunk[title], chunk_id: idx } ) return store写入的时候metadata来源、分类、标题、分块编号一定要完整保存这一步决定了后面能不能做引用溯源。很多人觉得 metadata 无所谓省掉以后再想补就得重新做一遍向量化很麻烦。3.4 检索与答案生成的完整链路检索时核心就两步先把问题向量化查向量库取 topK 候选再把候选列表和问题一起交给大模型。但为了让代码干净、易维护我把流程拆成三个函数def retrieve(query, top_k8): # 1. 查询改写可选交给大模型做同义扩展 rewritten rewrite_query(query) # 2. 向量检索 vector_results vector_store.query(rewritten, top_ktop_k) # 3. 关键词检索 BM25 keyword_results bm25_search(rewritten, top_ktop_k) # 4. 融合去重按分数重排 return merge_rank(vector_results, keyword_results) def generate_answer(question, contexts): system_prompt build_system_prompt() user_prompt f问题{question}\n\n资料\n{contexts} # 调用大模型接口返回答案和引用标记 return llm_call(system_prompt, user_prompt) def chat(question): docs retrieve(question) answer_text, citations generate_answer(question, docs) return format_response(answer_text, citations)三个函数各管一件事哪一层出了问题都能单独排查。我在开发过程中发现检索层的问题最多因为向量召回是有一定随机性的同一问题改写一版和原版召回结果会有差异所以我在查询改写时特意要求大模型不能改变原意只能做同义替换和关键实体补充这样改写出来的 query 更稳。4. 实操过程从零搭建一套最小可用系统4.1 环境准备与依赖安装环境这块不用多说Python 3.10 以上版本虚拟环境隔离依赖避免和系统环境冲突。需要安装的库也不复杂向量库客户端、Sentence Transformers 系列 Embedding 模型、大模型 SDK、HTML/文本解析工具。装完依赖后我先用一个最小的冒烟测试验证链路通不通——造两三条假知识跑一遍检索和生成确认每个环节都能正常出结果。这一步做扎实后面扩展知识库就只是数据活。4.2 构建知识库一次可重复的流程我把知识库构建写成一个脚本确保任何时候新增文档都能一键重建。流程是读入 Markdown 文档 → 按结构分块 → 文本清洗 → 向量化 → 写入向量库 → 记录一份索引文件。索引文件记录的是每篇文档的标题、来源、分块数、向量库中的 ID 区间。为什么要记录这个因为后面查这个答案引用的是哪篇文章只需要反查这个索引不用翻向量库的原始记录。另外知识库更新时如果某篇文章被替换了得能知道哪些旧的向量分块要被清掉否则会出现新旧知识打架的问题。4.3 提示词工程让模型知道边界比发挥聪明更重要大模型生成答案时提示词直接决定了回答质量。我在多次调试后把系统提示词固定为四个部分第一角色设定。明确告诉模型你是一名装修顾问你的回答必须基于提供的资料不要随意发挥。第二边界约束。如果资料里找不到答案必须说根据现有资料无法回答不能编造。第三引用要求。回答中涉及关键结论时要标注对应的资料编号。第四格式要求。如果问题包含多个要点用分点回答方便用户阅读。一个适合装修咨询场景的提示词模板大致是你是装修咨询助手。你的任务是基于用户问题从给定的资料片段中寻找答案。 规则 1. 如果资料中没有相关信息请直接回答根据现有资料暂时无法回答这个问题。 2. 不要编造工艺参数、材料性能或价格数据。 3. 回答中的每个关键结论请在末尾用[参考片段n]标注来源。 4. 当问题涉及规范性要求如防水高度、闭水试验时长请优先引用权威规范类资料。 5. 回答要口语化、有条理但不要偏离资料内容。实测这套提示词能大幅减少幻觉。有一次我故意把一个很偏的问题阳台可以改成卫生间吗丢给系统知识库里完全没有相关内容模型正确回答根据现有资料暂时无法回答这个问题还补了一句建议咨询当地物业和相关专业设计师这个补充没有编造实质内容是我可以接受的边界输出。4.4 完整问答演示一个真实可跑的案例写完代码后我用高频问题做了一遍验收。拿卫生间防水做几遍举例。第一步查询改写。原问题被发给大模型做改写返回的改写结果是卫生间防水 施工 刷几遍 涂刷遍数 要求比原问题多了几个规范化的关键词。第二步向量检索加 BM25 检索。向量召回的结果里包括卫生间防水的施工文章和几篇关于涂料涂刷工艺的泛化文章BM25 因为他包含卫生间防水几遍这几个明确关键词命中了知识库里专门的防水施工章节。第三步重排融合。经过重排后排在首位的是卫生间防水施工要点这篇文章里的防水涂刷遍数与厚度小节内容包含墙面防水涂料涂刷两遍高度不低于 1.8 米地面防水涂刷两遍以上厚度达到 1.5 毫米等具体参数。这个结果正是用户需要的。第四步生成。模型基于这些片段生成了一段有引用标注的回答关键信息完整还特别说明不同品牌涂料可能存在差异具体以产品说明和施工规范为准。整个链路从提出问题到拿到回答大概三秒。演示时我比较注意的点是回答内容要稳定——同一个问题连续问三遍答案应该基本一致。如果模型偶尔抽风给出不同版本的回答就需要排查是不是检索结果不稳定或者是温度参数设置过高。4.5 加一层简单的对话界面虽然项目核心是后端逻辑但为了演示和测试方便我加了一个极简的 Web 界面。技术选型上直接用轻量级框架后端起一个问答接口前端写一个静态 HTML 页面包含对话输入框和历史消息列表。这个界面没有做复杂的功能但保留了引用来源的展示区回答中的[参考片段n]会转成可点击的链接点开能看到原始知识片段。这一步的价值在演示时体现得很明显。给用户测试时如果他们看到回答底部跟着一段来自某施工规范的原文摘要的引用信任感会提升很多也更愿意继续问下去。5. 常见问题与排查技巧实录5.1 检索结果为空或者答非所问这是 RAG 项目最常见的问题。排查思路按顺序来查知识库有没有相关内容。如果库本身没有检索结果为空是正常的先补数据。查同义词扩展。用户问墙皮要不要铲掉库里的标题是原墙面基层处理向量可能召回BM25 召不回。这种情况必须靠查询改写把两者兜住。查 Embedding 模型在垂直领域的表现。通用中文模型在装修领域的效果基本够用但如果你发现某些行业术语的向量表示明显有问题考虑换垂直微调过的 Embedding 模型。我实测发现很多答非所问其实是查询改写太激进导致的。比如用户问半包和全包的区别改写成了装修包工包料方式对比反而把半包全包这两个最关键的用户词丢掉了召回结果自然乱了。所以改写规则里有一条硬约束保留原问题中的核心名词和数字只能增加同义表达不能删除原词。5.2 模型幻觉编造参数和价格装修咨询里最怕的就是 AI 编造工艺参数。比如用户问闭水试验要多久如果模型回答48小时而规范要求是不少于24小时这个错误会直接误导施工。我的解决办法有三层。第一层是提示词约束明确要求没有资料不得回答第二层是引用机制关键结论必须标注来源片段用户和开发者都能溯源检查第三层是幻觉自检后处理大模型生成完回答后让一个独立质检环节可以是另一个模型调用也可以是自己写规则检查回答中的数字、参数是否能在已检索到的资料片段里找到对应描述不一致就标记并重新要求模型修正。三层叠加之后致幻率明显下降。当然这个质检逻辑会增加一次大模型调用成本要多算一点但在装修咨询这种对正确性要求高的场景下这笔开销值得。5.3 多轮对话用户会说那价格呢单轮问答能跑通之后马上会遇到多轮对话问题。用户问完卫生间防水怎么做下一句很可能就是那大概要花多少钱这里的那指的是卫生间的防水施工而不是泛指装修报价。我的做法比较简单但有效前端维护一个历史消息上下文传递给后端时先让大模型做一次指代消解把当前问题和历史问题合并成一个完整独立的问题再用合并后的问题去检索。比如那大概要花多少钱加上历史卫生间防水怎么做会被改写为卫生间防水施工大概要花多少钱。这样检索才能命中预算相关的知识片段。要注意的是多轮会话历史不可能无限增长超过十轮就截断最老的消息防止上下文太长影响改写效果。同时在改写时明确告诉模型如果当前问题与历史问题无关不要强行关联。5.4 知识库更新新旧知识打架怎么办装修知识是有时效性的尤其是材料品牌、流行风格和施工工艺。比如前几年流行实木踢脚线现在很多项目开始用铝合金极简踢脚线旧知识和新知识并存时AI 可能同时引用两者给出矛盾的建议。我整理了一套简单的更新策略每条知识在进入库时打上入库时间标签检索阶段如果候选片段之间存在明显冲突比如在同一个问题上参数不一致优先选择入库时间更新、来源可信度更高的一方生成阶段也会要求模型遇到冲突时优先采用更新更权威的来源。这套策略避免了大部分矛盾情况但前提是知识库本身必须经过人工审核不能无脑堆数据。5.5 成本控制别让每个问题都烧钱RAG 的成本大头是大模型生成的 token 消耗以及查询改写、质检等环节增加的额外调用。实测下来一个普通问题平均要消耗约两千 token 的输入上下文加上改写和质检成本大概是直接问通用模型的两到三倍。控制成本的办法有几个一是知识库分块质量做高检索命中准确就不需要把十几篇文档全部塞给模型控制上下文字数二是缓存高频问题装修咨询里的高频问题其实就那几十个完全可以把第一次回答存进缓存后续命中直接返回三是优化改写逻辑简单问题比如你好“在吗”不走改写直接进普通对话流程。我从一开始就把成本控制纳入设计而不是等项目跑大了再优化建议做类似项目的也这么做否则每个测试问题都在烧钱测试意愿会大打折扣。6. 测试与验收怎么衡量这个系统能用6.1 建立评测集不要凭感觉判断没有评测集就谈不上优化。我从真实咨询记录里挑了一百个高频问题涵盖开头整理的六类场景构成了一个最小评测集。每次改动知识库、提示词或检索逻辑就跑一遍评测集统计回答是否可接受。可接受的标准我自己定了一套回答正确关键参数准确、有出处能从知识库追溯、不编造库中没有的不乱说、可操作用户听完知道怎么做。这套标准偏主观但用于横向对比版本迭代已经够了。如果要做更严谨的评测可以引入人工打分的机制代价高一些但结果更可靠。6.2 边界案例测试除了常规问题我还会测一批边界案例。比如问装修公司跑路了怎么办知识库里没有合同纠纷相关的权威资料模型应该拒绝回答而不是瞎建议问请帮我设计一套三室两厅的方案这种开放式的创作问题RAG 的系统约束效果也很明显——模型会基于知识库中关于空间规划的文档给出框架性建议但不会越界去渲染具体户型图。这些边界案例的通过标准是不犯错而不是回答得好。把不犯错这条底线守住系统才真正可对外演示。我知道很多人做这类项目会把精力全放在模型和提示词上实际上数据质量、检索逻辑、评测闭环才是让它像个真正的产品的关键。这个项目做下来我最深的体会是垂直领域的 AI 应用难点不在 AI 本身而在于把领域知识整理成模型能用的形式——分块、检索、引用每一步都是在跟信息的组织方式打交道。装修咨询只是我挑的一个方向这套思路完全能迁移到其他垂直行业比如家电维护、园艺种植、宠物喂养逻辑是一样的找一批信得过的资料搭一个能查能引的链路再配一套严格的评测标准剩下的就是不断迭代数据了。