从零到一!前端搭建本地轻量化 RAG 问答系统
1. 引言大模型虽强但面对私有知识库、企业内部文档时往往存在「幻觉」和「知识过时」的问题。RAGRetrieval-Augmented Generation检索增强生成正是解决这一痛点的主流方案先检索出与问题相关的文档片段再交给大模型生成回答。传统 RAG 方案往往依赖后端服务、向量数据库和复杂的部署链路。而随着浏览器能力的增强前端完全可以在本地搭建一套轻量化的 RAG 问答系统——无需服务器、无需安装数据库数据不出浏览器隐私安全。本文将从零到一带你用纯前端技术栈Vite React Transformers.js localStorage搭建一套可运行的本地 RAG 问答系统。2. 技术选型与整体架构2.1 技术栈模块选型说明构建工具Vite极快的开发体验UI 框架React组件化开发向量化模型Transformers.js all-MiniLM-L6-v2纯浏览器端运行无需后端向量存储localStorage 自研余弦相似度检索轻量、零依赖生成模型可选本地模型 / 云端 API按需接入2.2 整体流程用户上传文档文本切分向量化 Embedding向量存入 localStorage用户提问问题向量化余弦相似度检索 Top-K拼接上下文 问题调用大模型生成回答3. 环境准备与项目初始化首先确保本机已安装 Node.js 18然后执行npmcreate vitelatest local-rag ----templatereact-tscdlocal-ragnpminstallnpminstallhuggingface/transformers安装完成后启动开发服务器npmrun dev4. 文本切分把长文档拆成小块RAG 检索的粒度很关键。整篇文档直接向量化检索精度差切得太碎又丢失上下文。这里实现一个简单的按段落 字符数控制的切分器。// src/utils/chunker.tsexportinterfaceChunk{id:string;text:string;source:string;}exportfunctionchunkText(text:string,source:string,maxLen500):Chunk[]{constparagraphstext.split(/\n\s*\n/);constchunks:Chunk[][];letbuffer;for(constparaofparagraphs){consttrimmedpara.trim();if(!trimmed)continue;if((buffer\ntrimmed).lengthmaxLenbuffer){chunks.push({id:crypto.randomUUID(),text:buffer.trim(),source,});buffertrimmed;}else{bufferbuffer?buffer\ntrimmed:trimmed;}}if(buffer.trim()){chunks.push({id:crypto.randomUUID(),text:buffer.trim(),source,});}returnchunks;}5. 向量化在浏览器中运行 Embedding 模型借助 Transformers.js我们可以在浏览器端直接加载并运行 MiniLM 模型把文本转成 384 维向量。// src/utils/embedder.tsimport{pipeline}fromhuggingface/transformers;letembedder:anynull;exportasyncfunctiongetEmbedder(){if(!embedder){embedderawaitpipeline(feature-extraction,Xenova/all-MiniLM-L6-v2);}returnembedder;}exportasyncfunctionembedTexts(texts:string[]):Promisenumber[][]{constmodelawaitgetEmbedder();constoutputsawaitmodel(texts,{pooling:mean,normalize:true});returnoutputs.tolist();}提示首次加载模型需要下载约 90MB 文件之后浏览器会缓存二次访问秒开。6. 向量存储与检索localStorage 余弦相似度6.1 存储层localStorage 无法直接存高维数组这里用 JSON 序列化存储并封装读写接口。// src/utils/store.tsimporttype{Chunk}from./chunker;interfaceStoredChunkextendsChunk{vector:number[];}constSTORAGE_KEYlocal-rag-chunks;exportfunctionsaveChunks(chunks:StoredChunk[]):void{localStorage.setItem(STORAGE_KEY,JSON.stringify(chunks));}exportfunctionloadChunks():StoredChunk[]{constrawlocalStorage.getItem(STORAGE_KEY);returnraw?JSON.parse(raw):[];}exportfunctionclearChunks():void{localStorage.removeItem(STORAGE_KEY);}6.2 余弦相似度检索// src/utils/search.tsimporttype{StoredChunk}from./store;functioncosineSimilarity(a:number[],b:number[]):number{letdot0,normA0,normB0;for(leti0;ia.length;i){dota[i]*b[i];normAa[i]*a[i];normBb[i]*b[i];}returndot/(Math.sqrt(normA)*Math.sqrt(normB)1e-8);}exportfunctionsearchChunks(queryVector:number[],chunks:StoredChunk[],topK3):StoredChunk[]{returnchunks.map((chunk)({chunk,score:cosineSimilarity(queryVector,chunk.vector),})).sort((a,b)b.score-a.score).slice(0,topK).map((item)item.chunk);}7. 组装问答把检索结果交给大模型检索到 Top-K 相关片段后把它们拼进 Prompt再调用大模型生成回答。这里以 OpenAI 兼容接口为例你也可以替换为本地 Ollama 或其他模型。// src/utils/qa.tsimport{searchChunks}from./search;import{loadChunks}from./store;exportasyncfunctionaskQuestion(question:string,queryVector:number[],apiKey:string,baseUrlhttps://api.openai.com/v1):Promisestring{constchunksloadChunks();consttopChunkssearchChunks(queryVector,chunks,3);constcontexttopChunks.map((c,i)【片段${i1}】\n${c.text}).join(\n\n);constprompt请基于以下资料回答问题。如果资料中没有相关信息请直接说明资料中未找到相关内容。 资料${context}问题${question}回答;constrespawaitfetch(${baseUrl}/chat/completions,{method:POST,headers:{Content-Type:application/json,Authorization:Bearer${apiKey},},body:JSON.stringify({model:gpt-4o-mini,messages:[{role:user,content:prompt}],temperature:0.3,}),});constdataawaitresp.json();returndata.choices[0].message.content;}8. 前端界面串联完整流程最后用 React 把以上模块串起来实现「上传文档 → 建立索引 → 提问 → 得到回答」的完整交互。// src/App.tsx import { useState } from react; import { chunkText } from ./utils/chunker; import { embedTexts } from ./utils/embedder; import { saveChunks, loadChunks, clearChunks } from ./utils/store; import { askQuestion } from ./utils/qa; export default function App() { const [docText, setDocText] useState(); const [question, setQuestion] useState(); const [answer, setAnswer] useState(); const [loading, setLoading] useState(false); const [indexed, setIndexed] useState(false); const handleIndex async () { setLoading(true); try { const chunks chunkText(docText, 本地文档); const vectors await embedTexts(chunks.map((c) c.text)); saveChunks(chunks.map((c, i) ({ ...c, vector: vectors[i] }))); setIndexed(true); alert(索引完成共 ${chunks.length} 个片段); } finally { setLoading(false); } }; const handleAsk async () { if (!question.trim()) return; setLoading(true); try { const [queryVector] await embedTexts([question]); const apiKey prompt(请输入 API Key本地运行仅存于内存) || ; const res await askQuestion(question, queryVector, apiKey); setAnswer(res); } finally { setLoading(false); } }; return ( div style{{ maxWidth: 720, margin: 0 auto, padding: 24 }} h1本地轻量化 RAG 问答/h1 section h21. 上传文档/h2 textarea value{docText} onChange{(e) setDocText(e.target.value)} rows{8} style{{ width: 100% }} placeholder粘贴你的文档内容... / button onClick{handleIndex} disabled{loading || !docText.trim()} {loading ? 处理中... : 建立索引} /button {indexed ( button onClick{() { clearChunks(); setIndexed(false); }} 清空索引 /button )} /section section h22. 提问/h2 input value{question} onChange{(e) setQuestion(e.target.value)} style{{ width: 100%, padding: 8 }} placeholder输入你的问题... / button onClick{handleAsk} disabled{loading || !indexed} 提问 /button /section {answer ( section h2回答/h2 div style{{ whiteSpace: pre-wrap, background: #f5f5f5, padding: 16, borderRadius: 8 }} {answer} /div /section )} /div ); }9. 效果演示与运行在项目根目录执行npm run dev浏览器打开http://localhost:5173粘贴一段产品文档或技术资料点击「建立索引」等待模型加载与向量化首次约 10~30 秒输入问题点击「提问」系统检索相关片段并调用大模型生成回答。10. 总结与优化方向本文实现了一套完全运行在浏览器端的轻量化 RAG 系统核心亮点零后端向量化、存储、检索全部在前端完成隐私安全文档数据不离开本地浏览器轻量依赖仅需 Transformers.js 一个核心库。后续可优化方向接入 Web Worker避免向量化阻塞 UI 线程使用 IndexedDB 替代 localStorage突破 5MB 存储上限引入重排序Rerank模型提升检索精度支持 PDF、Word 等格式解析接入本地 Ollama 模型实现完全离线运行。希望这篇文章能帮你快速上手前端 RAG 开发动手试试吧

相关新闻

事务 Outbox 与幂等键:跨过“提交后崩溃”的缝隙

事务 Outbox 与幂等键:跨过“提交后崩溃”的缝隙

复用 replay.py 的恢复结论 上一篇产出的 replay.py 会从 EventStore.load 恢复 ReplayResult,并明确让 pending_commands 永远不从重放结果派发命令。这留下一个必须回答的问题:真正待执行的命令存在哪里?本篇以 replay(...).last_seq 作为乐…

2026/8/9 10:53:40 阅读更多 →
AI充电桩管理系统:智能运维与轻量化开发指南-充电桩源码解析

AI充电桩管理系统:智能运维与轻量化开发指南-充电桩源码解析

博主介绍: 所有项目都配有从入门到精通的安装教程,可二开,提供核心代码讲解,项目指导。 项目配有对应开发文档、解析等 项目都录了发布和功能操作演示视频;项目的界面和功能都可以定制,包安装运行&#xff…

2026/8/9 8:23:50 阅读更多 →
如何用AtlasOS优化Windows系统:解决卡顿、隐私泄露的终极方案

如何用AtlasOS优化Windows系统:解决卡顿、隐私泄露的终极方案

如何用AtlasOS优化Windows系统:解决卡顿、隐私泄露的终极方案 【免费下载链接】Atlas 🚀 An open and lightweight modification to Windows, designed to optimize performance, privacy and usability. 项目地址: https://gitcode.com/GitHub_Trendi…

2026/8/7 3:12:28 阅读更多 →

最新新闻

OpenWorkflow schema validation教程:使用Zod和Yup确保数据安全

OpenWorkflow schema validation教程:使用Zod和Yup确保数据安全

OpenWorkflow schema validation教程:使用Zod和Yup确保数据安全 【免费下载链接】openworkflow Open-source TypeScript framework for building durable, resumable workflows. Supports Node.js and Bun. 项目地址: https://gitcode.com/gh_mirrors/op/openwork…

2026/8/9 23:39:54 阅读更多 →
前端实现人脸头套叠加效果:基于Face-api.js与Canvas的实时图像处理实战

前端实现人脸头套叠加效果:基于Face-api.js与Canvas的实时图像处理实战

最近在开发一个儿童安全出行应用时,遇到了一个有趣的需求:如何在应用中模拟一个“蒙面娃”的形象,既保护儿童隐私,又能让应用界面生动有趣。这让我想到了使用头像叠加或“头套”滤镜的技术方案。本文将围绕如何在前端(…

2026/8/9 23:39:54 阅读更多 →
Kretes部署指南:3种简单方法将你的Deno应用上线生产环境

Kretes部署指南:3种简单方法将你的Deno应用上线生产环境

Kretes部署指南:3种简单方法将你的Deno应用上线生产环境 【免费下载链接】kretes A Programming Environment for TypeScript & Deno 项目地址: https://gitcode.com/gh_mirrors/kr/kretes Kretes是专为TypeScript和Deno设计的编程环境,本指…

2026/8/9 23:39:54 阅读更多 →
从文本到图像:基于Stable Diffusion的AI绘画实战指南

从文本到图像:基于Stable Diffusion的AI绘画实战指南

1. 先搞清楚这个标题到底在说什么看到“香蕉姐穿个透明雨衣就出门了”这个标题,第一反应可能觉得这是个娱乐或生活类话题。但在技术博客的语境下,我们不能停留在字面意思。我们需要把它理解为一个符号化的、具有传播性的网络热词或现象,并探讨…

2026/8/9 23:39:54 阅读更多 →
Prime Agent无障碍设计:让AI编码助手对所有人可用的方法

Prime Agent无障碍设计:让AI编码助手对所有人可用的方法

Prime Agent无障碍设计:让AI编码助手对所有人可用的方法 【免费下载链接】prime-agent A self-improving RLM agent for coding workflows and long-running autonomous tasks. 项目地址: https://gitcode.com/GitHub_Trending/pr/prime-agent Prime Agent是…

2026/8/9 23:39:54 阅读更多 →
Android滚动选项卡设计利器:ScrollableLayout实战案例详解

Android滚动选项卡设计利器:ScrollableLayout实战案例详解

Android滚动选项卡设计利器:ScrollableLayout实战案例详解 【免费下载链接】Scrollable Android scrollable tabs 项目地址: https://gitcode.com/gh_mirrors/sc/Scrollable ScrollableLayout是一款专为Android开发者打造的滚动选项卡解决方案,它…

2026/8/9 23:38:54 阅读更多 →

日新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/9 0:01:47 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/9 0:01:47 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/9 0:03:48 阅读更多 →

周新闻

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁

5分钟告别提取码焦虑:baidupankey如何智能破解百度网盘资源锁 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 你是否曾经在深夜寻找一份重要资料&#x…

2026/8/9 0:01:47 阅读更多 →
如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南

如何快速生成中国车牌图片:Python开源工具完整指南 【免费下载链接】chinese_license_plate_generator 中国车牌生成器 项目地址: https://gitcode.com/gh_mirrors/ch/chinese_license_plate_generator 中国车牌生成器是一个基于Python的开源项目&#xff0c…

2026/8/9 0:01:47 阅读更多 →
收藏!小白程序员轻松入门大模型,从Harness工程开始实践

收藏!小白程序员轻松入门大模型,从Harness工程开始实践

文章强调学习大模型不应只关注模型本身,而应重视模型外的系统搭建,即Harness。提出AgentModelHarness的实用公式,详细介绍Harness的四个层次:持久化层、执行层、控制层和观察与验证层。文章还探讨了上下文工程、工具设计、AGENTS.…

2026/8/9 0:03:48 阅读更多 →

月新闻

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南

免费解锁百度网盘SVIP加速:macOS用户必备的下载提速终极指南 【免费下载链接】BaiduNetdiskPlugin-macOS For macOS.百度网盘 破解SVIP、下载速度限制~ 项目地址: https://gitcode.com/gh_mirrors/ba/BaiduNetdiskPlugin-macOS 还在为百度网盘macOS版的龟速下…

2026/8/9 17:05:02 阅读更多 →
终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换

终极ncmdump指南:3分钟实现网易云NCM音乐解密与格式转换 【免费下载链接】ncmdump 项目地址: https://gitcode.com/gh_mirrors/ncmd/ncmdump 还在为网易云音乐下载的NCM格式文件无法在其他播放器播放而烦恼吗?ncmdump解密工具帮你轻松解决这个困…

2026/8/9 0:45:04 阅读更多 →
HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

HarmonyOS 应用开发《掌上英语》第81篇: 智能体卡片:为英语学习 App 打造桌面级学习助手

AgentCard 智能体卡片:为英语学习 App 打造桌面级学习助手适用平台:HarmonyOS 7.0 (API 26 Beta)一、引言 HarmonyOS 7.0(API 26 Beta)新增了 AgentCard 智能体卡片能力,这是继 HMAF(鸿蒙智能体框架&#x…

2026/8/9 17:05:02 阅读更多 →