从 0 到 1 搭建企业级多模态 RAG 知识库:一个装修公司的 AI 落地实战

从 0 到 1 搭建企业级多模态 RAG 知识库:一个装修公司的 AI 落地实战

300 人销售团队、15 天岗前培训、知识散落在各个角落------这是一家江西知名装修公司面临的真实困境。本文完整拆解我主导设计的企业级知识库项目,从产品原型到数据库表设计,从多模态文档解析到 GraphRAG 推理链路,把每个技术决策背后的"为什么"讲透。


一、为什么企业知识库是 AI 时代绕不开的"基建"

先看一个具体的场景。

这家装修公司全省有 300 多人的销售团队,学历参差不齐。每个人上岗前都要经历为期 15 天的岗前培训,内容涵盖装修案例、项目手册、客户权益、售后流程等。培训结束后,员工日常工作中还会不断积累新的业务资料、操作经验、问题解决方案和规范流程。

问题出在哪?

  • 知识资产零散:文档散落在个人电脑、微信群、邮件附件里,没有统一归档
  • 电子化只解决了一半:信息化、云端化让文件"存得下",但没让知识"找得到"
  • 传统检索效率极低:手动翻文档,或者关键词检索------搜"客户退单怎么处理",文档里写的是"订单取消流程",关键词对不上,就是搜不到
  • 反复问人、反复试错:老员工被问烦,新员工成长慢,15 天培训的成本反复支出

所以这个项目的定位非常清晰:搭建统一的企业知识库,支持语义检索、AI 一键问答,看懂需求就能匹配资料、直接给出解决方案。

它不是锦上添花的功能,而是企业 AI 落地的基础设施。

这里有个关键的产品思维:需求不太清晰时,先用产品原型图把想法"可视化"。


二、产品原型图:把想法变成可沟通的模型

产品原型图是产品的简易可视化模型,用线条、模块展示页面布局、功能与交互逻辑。它的价值在于:提前验证想法、方便团队沟通、及早发现设计缺陷、减少后期返工成本。

常用工具有 Figma、蓝湖、墨刀。值得一提的是,Figma 现在可以结合 MCP(Model Context Protocol),把产品原型图直接转成前端页面,大大缩短从设计到开发的链路。

这个知识库后台管理系统,产品经理画了六张核心图:

图一:整体框架与登录

  1. 企业共享的知识库后台管理系统
  2. 登录页
  3. 顶部 7 个导航,直达文档、问答、知识图谱

图二:首页大盘

这是首页大盘,用可视化一眼看懂全局:

  • 折线图盯访问趋势
  • 环形图看文档分类占比
  • 五大指标配上涨跌箭头
  • 底部操作记录,最终谁干了啥一目了然

管理员不用翻数据,开会张口就有数据。核心功能是文档、AI 问答、知识图谱这三块。

这里有个重要的设计原则:文档会做权限管理,只有有权限的文档才可以被检索出来用于生成回答。 这一点后面会展开讲技术实现。

图三:文档管理核心模块

  • 左侧:按"我的、公共、部门、归档"分类
  • 右侧:列表可搜索、批量上传、新建文件夹
  • 每行标注:类型、上传人、解析状态、权限范围
  • 两种显示:列表式和卡片式

图四:智能搜索页

输入关键词,非常快的速度检索出搜索结果:

  • 关键词高亮
  • 按相关度排序
  • 每条标出来源、更新时间和可见权限
  • 只让搜到有权限的文档,又快又安全

图五:AI 智能问答页

  • 左侧:存着历史会话,随时回顾
  • 右侧:直接提问,AI 从库里找出答案,流式输出并附带文档引用
  • 提供"你可能想要问"主动引导
  • 答得快、有出处、还能追问

图六:知识图谱


三、攻克的核心难点:从"单条文档匹配"到 GraphRAG

传统的 RAG 方案是这样的:

javascript 复制代码
query -> 单条 document 匹配

用 ES/Milvus 做语义/关键词检索,找最相似的文档片段喂给 LLM。但这种方式有些不足:

  • 复杂业务问题往往需要跨文档、多跳推理
  • 比如"客户在质保期内要求退单,流程怎么走、责任怎么划分"------这需要串联"质保政策""退单流程""责任认定"多个文档
  • 单条匹配只能找到"看起来像"的片段,无法构建完整的推理链路

所以项目引入了 GraphRAG :用图数据库(Neo4j)构建知识图谱,通过 LLM 抽取文档实体、关系自动存入图数据库。用户问题会用 LLM 抽取实体、执行多跳检索,把推理链路和 RAG 的结果融合送入 Prompt 上下文,提升复杂业务问题问答的完整性与逻辑性。


四、功能模块拆解

知识库核心功能 = 文档管理 + 问答助手 + 知识图谱。

4.1 文档管理:多模态统一解析

这是整个项目最"重"的部分,也是最能体现工程能力的地方。

文本类文件

支持格式:PDF、DOCX、DOC、XLSX、XLS、PPTX、PPT、TXT、MD、CSV、JSON。

用 langchain/community/document_loaders 就能支持以上格式。同时支持输入网页 URL,系统自动抓取页面正文并导入知识库归档检索。

图片文件(JPG、PNG 等)

上传后做两件事:

  1. 通过视觉嵌入模型提取图片特征
  2. 调用大模型 OCR / 图片理解生成图片描述文本

这样就能实现"文字搜图片"和"以图搜图"。

音频文件(MP3、WAV、M4A)

上传自动执行 ASR(Automatic Speech Recognition)语音转文字,将完整转录文本归档,依托文本内容参与检索。

视频文件

用视频理解模型做全维度内容解析:

  • 同步提取音频文字
  • 提取画面视觉信息
  • 整合生成完整文本内容用于检索
  • 输出视频多模态向量,实现图文视频跨模态检索
统一解析策略

项目里有一个很聪明的设计:所有格式统一解析为 Markdown 文档。

  • 自动提取文档中的图片上传到 MinIO
  • 并替换文档中的图片为 .url
  • 图片基于 OCR 解析、音频基于 ASR、视频基于分片 + 视频理解模型解析成文档

这样做的好处是:下游的检索、问答、图谱抽取都只需要面对一种格式,极大简化了系统复杂度。

4.2 权限管理:检索前筛选

权限管理分两层:

  1. 功能权限:页面、菜单、按钮三级细粒度权限拦截
  2. 数据权限:在检索前筛选,用 PSQL 实现

核心逻辑是:依据当前用户角色过滤文档池,不同人员仅查询自身权限范围内的知识资料,实现功能权限与数据权限双重隔离,满足多部门资料分级保密要求。

4.3 问答助手

  • 混合检索:Elasticsearch 全文检索 + Milvus 向量语义检索 + 知识图谱
  • 流式输出以及源文件引用
  • 主动引导用户追问
  • 语音输入 TTS

五、技术栈与简历级项目亮点

技术栈

复制代码
LangChain、LangGraph、DeepAgents、Vercel AI SDK、Nest、Redis、
PostgreSQL、ElasticSearch、Neo4j、MinIO、Docker Compose、
Mem0、LangSmith、LangFuse、WebSocket

项目亮点(8 条)

1. 混合检索 + Reranker 重排

向量 + 关键词(PGVector + ElasticSearch)实现混合检索,用 Reranker 模型重排,实现多路召回,提高检索准确率。

底层理解:向量检索擅长"语义相似",关键词检索擅长"精确匹配"。两路召回后用 RRF(Reciprocal Rank Fusion)融合,再用 Reranker 精排,是当前工业界最稳的 RAG 检索方案。

2. Neo4j 知识图谱 + 多跳推理

利用 Neo4j 构建知识图谱,通过 LLM 抽取文档实体、关系自动存入图数据库。用户问题会用 LLM 抽取实体、执行多跳检索,把推理链路和 RAG 的结果融合送入 Prompt 上下文。

3. 多模态统一解析

支持 PDF、Word、TXT 等图文格式,支持图片、音视频等多媒体文件,统一解析为 Markdown 文档。自动提取图片上传到 MinIO,并替换文档中的图片为 .url。图片基于 OCR 解析、音频基于 ASR、视频基于分片 + 视频理解模型解析成文档。

4. 分层记忆存储

Redis 实现短期记忆存储,Mem0 实现长期记忆分层存储,包括用户级、会话级记忆。

5. 分层权限管控体系

落地页面、菜单、按钮三级细粒度权限拦截;同时联动检索逻辑做数据权限隔离,依据当前用户角色过滤文档池,不同人员仅查询自身权限范围内的知识资料,实现功能权限与数据权限双重隔离。

6. Agentic RAG 架构

基于 LangGraph 实现 Agentic RAG 架构,Agent 自主判别问题复杂度,动态决策调用混合检索、图谱推理等工具,灵活适配多维度复杂业务提问,规避固定检索流程带来的回答局限性。

7. 语音交互

基于 ASR + 流式 TTS 实现语音交互,SSE 实现文字流式输出,WebSocket + 流式 TTS 实现语音的同步流式播放。

8. 全链路观测与评估

本地开发用 LangSmith 调试,线上用 LangFuse 搜集数据,实现全链路观测,记录检索耗时、LLM 调用成本、回答召回来源、模型报错日志等。搭建 RAG 和 Agent 效果量化评估机制,自动跑实验来评估检索效果。


六、数据库设计:PSQL + PGVector 的底层细节

项目涉及多种存储:

  • PSQL(带 PGVector 扩展):存储结构化业务数据 + 文档分片向量
  • 中间件:ES、Redis、Neo4j 图数据库

所有知识库相关表用 kh_ 前缀(knowledge base)。

6.1 User 表

sql 复制代码
CREATE TABLE IF NOT EXISTS kh_user {
  id BIGINT PRIMARY KEY,  -- 用户ID(雪花)
  username VARCHAR(50) NOT NULL, -- 登录用户名
  password VARCHAR(255) NOT NULL, -- 密码 (bcrypt 哈希)
  email VARCHAR(100), -- 邮箱(可选)
  email_verified SMALLINT NOT NULL DEFAULT 1, -- 0 未验证 1 已验证
  real_name VARCHAR(50), -- 真实姓名(可选)
  avatar VARCHAR(500), -- 头像URL(可选)
  status SMALLINT NOT NULL DEFAULT 1, -- 0 禁用 1 启用
  last_login_at TIMESTAMP, -- 最后登录时间
  created_at TIMESTAMP NOT NULL DEFAULT NOW(), -- 创建时间
  updated_at TIMESTAMP NOT NULL DEFAULT NOW(), -- 更新时间
  deleted BOOLEAN NOT NULL DEFAULT false -- 是否删除 软删除标记
}

CREATE UNIQUE INDEX IF NOT EXISTS uk_kh_user_username ON kh_user(
  username) WHERE deleted=false;
代码解析:为什么这么设计?

① ID 用 BIGINT + 雪花算法

  • INT 是 4 字节,最大值约 21 亿
  • BIGINT 是 8 字节,最大值约 922 亿

用户量大的系统,INT 很快就用完了。雪花算法生成的是分布式唯一 ID,天然适合分库分表。

② password 用 VARCHAR(255) 存 bcrypt 哈希

bcrypt 哈希固定 60 字符,但留 255 是防御性设计------未来换算法(如 Argon2)不用改表结构。永远不要明文存密码。

③ email_verified 用 SMALLINT 而不是 BOOLEAN

用 SMALLINT 存 0/1,比 BOOLEAN 更灵活,未来可以扩展成 2、3 表示更多状态(比如"验证中""验证失败")。

④ deleted 软删除标记 + 唯一索引的 WHERE 条件

sql 复制代码
CREATE UNIQUE INDEX ... ON kh_user(username) WHERE deleted=false;

这是部分唯一索引 。意思是:只有 deleted=false 的行才参与唯一性约束。这样用户被软删除后,同一个 username 可以被重新注册,不会因为历史数据冲突。

⑤ created_at / updated_at 默认 NOW()

时间戳由数据库生成,避免应用层时钟不一致的问题。

6.2 角色表:RBAC 模型

RBAC(Role-Based Access Control)基于角色的访问控制,核心是用户 → 角色 → 权限的三层关系。

sql 复制代码
CREATE TABLE IF NOT EXISTS kh_role (
  id BIGINT PRIMARY KEY,
  role_name VARCHAR(50) NOT NULL,
  role_code VARCHAR(50) NOT NULL UNIQUE,
  description VARCHAR(200),
  status SMALLINT NOT NULL DEFAULT 1 -- 0 禁用 1 启用
)

CREATE TABLE IF NOT EXISTS kh_user_role (
  id BIGINT PRIMARY KEY,
  user_id BIGINT NOT NULL REFERENCES kh_user(id),
  role_id BIGINT NOT NULL REFERENCES kh_role(id),
  created_at TIMESTAMP NOT NULL DEFAULT NOW(),
  UNIQUE (user_id, role_id)
)

CREATE INDEX IF NOT EXISTS idx_kh_user_role_user_id ON kh_user_role(user_id)
代码解析

① 为什么角色表要同时有 role_name 和 role_code?

  • role_name:给人看的,比如"销售主管"
  • role_code:给程序看的,比如 SALES_MANAGER

代码里判断权限用 role_code,不会因为改名而失效。role_code 加 UNIQUE 约束,保证不重复。

② kh_user_role 是典型的中间表

用户和角色是多对多 关系:一个用户可以有多个角色,一个角色可以分配给多个用户。中间表用 UNIQUE (user_id, role_id) 防止重复分配。

③ 外键 REFERENCES + 索引

sql 复制代码
user_id BIGINT NOT NULL REFERENCES kh_user(id)

外键保证引用完整性------不能给不存在的用户分配角色。

sql 复制代码
CREATE INDEX ... ON kh_user_role(user_id)

查询"某用户有哪些角色"是最高频的操作,给 user_id 建索引是必须的。注意这里没有给 role_id 单独建索引,因为"某角色下有哪些用户"的查询频率相对低,可以按需再加。

④ 注意笔记里有个笔误

sql 复制代码
role_id BIGINT NOT NULL REFERENCES hk_role(id),

这里写成了 hk_role,应该是 kh_role。实际建表时要小心这种拼写错误------外键引用错表会在建表时报错。


七、总结:这个项目为什么"能打"

回头看,这个企业级知识库项目的价值在于它同时解决了三个层面的问题:

  1. 业务层面:把 15 天岗前培训的成本、反复问人的沟通成本,转化为一次性的知识库建设
  2. 技术层面:多模态统一解析 + 混合检索 + GraphRAG + Agentic RAG,覆盖了当前 RAG 领域最前沿的工程实践
  3. 工程层面:分层权限、全链路观测、量化评估,让它不是一个 Demo,而是能上生产的系统

如果你正在准备 AI 应用方向的面试,或者要在公司内部落地知识库,这个项目的架构和取舍思路都值得参考。

核心心法只有一句:RAG 的成败不在模型,而在检索;检索的成败不在算法,而在数据治理和权限设计。

相关推荐
Purple Coder1 小时前
M-H图像分析
人工智能
沛东的认知和实践1 小时前
能增、能删,但不幂等:拆开 WeKnora 的LLMWiki知识编译——彻底搞懂LLM Wiki第二篇
人工智能
两万五千个小时1 小时前
DeepSeek Harness 从 0 开始:20 goal模式
人工智能·程序员·架构
QuZhengRong1 小时前
【周报】2026-10-02~10-08 AI 科技周报
人工智能·科技·新闻
云沛科技1 小时前
在实验室复刻暴风雪:低温雨雪冰雾耦合试验室解锁极端环境 “实景仿真”
人工智能·功能测试·科技
程序员大狐狸1 小时前
Ultra X7 358H 笔记本电脑,本地部署当红炸子鸡 Qwen3.8-27B-Q4,实测生成速度 5.6 tok/s
人工智能
styshoo1 小时前
NVIDIA Dynamo Snapshot 介绍
人工智能
用户8314550980311 小时前
如一 Agent 架构解读(一):数字分身的执行模型——Run、Turn 与四个时间尺度
人工智能
Kyops1 小时前
GPT-6 把地图和交互组件带进 ChatGPT,答案终于可以直接操作了
人工智能