菜鸟AI - 让提示词生成更简单! 全站导航 全站导航
AI工具安装 新手教程 进阶教程 辅助资源 AI提示词 热点资讯 技术资讯 产业资讯 内容生成 模型技术 AI信息库

已有账号?

首页 > AI教程 > 2024前端RAG文档检索接入聊天页十大推荐方案
进阶教程 综合资讯

2024前端RAG文档检索接入聊天页十大推荐方案

2026-06-08
阅读 0
热度 0
作者 菜鸟AI编辑部
摘要

摘要

今天咱们聊聊前端怎么接入 RAG。RAG 这词儿吧,全称Retrieval-Augmented Generation,听起来挺唬人

今天咱们聊聊前端怎么接入 RAG。RAG 这词儿吧,全称Retrieval-Augmented Generation,听起来挺唬人,但本质其实特别简单:就是在问大模型问题之前,先把相关的资料翻出来,一块儿塞进 Prompt 里。这篇不讲虚的理论,直接给出一份前端开发者能立刻跑起来的最小可行版本——从数据流到代码实现,每一步都拆开来看。

你能从这篇里摸清楚三件事:一个真正能跑的 RAG 数据流到底需要几步;哪些步骤可以放心地交给前端、哪些必须得放在服务端;以及,引用来源的 UI 到底怎么设计才能既不丑又不碍事。

一、最小数据流

先画个图,把流程理清爽。

[Indexing 阶段,离线/上传时跑一次] 文档 ── 切片 ─→ Embedding ─→ 存向量库

[Query 阶段,用户每次提问跑] 用户问题 ── Embedding ─→ 向量检索 ─→ Top-K 切片 ─→ 拼进 Prompt ── 调 LLM ── 流式吐回前端 ─→ 引用来源 UI

整个流程的核心动作只有四个:切片、嵌入、检索、引用。别被那些花里胡哨的术语绕晕了,抓住这四步就够了。

二、前端能做哪些步骤

既然聊前端,最直接的问题就是:这些活儿到底能放多少到浏览器里跑?

步骤推荐放哪原因
切片 (chunking)服务端或上传时算法稳定,不需要每次跑
文档 Embedding服务端API Key 不能暴露在浏览器
查询 Embedding可以放前端(用 transformers.js)节省服务端调用,且支持纯客户端场景
向量检索服务端(pgvector / Qdrant / Milvus)数据规模大时必须
LLM 调用服务端同上,Key 安全
引用来源 UI前端显然

总结一下:切片和文档嵌入属于一次性的准备工作,服务端干更靠谱。查询嵌入可以借助 transformers.js 在浏览器里执行,节省一次服务端调用。向量检索和 LLM 调用因为有 Key 安全和数据规模的问题,还是乖乖放服务端。最后的引用 UI 展示,那就全看前端的了。

三、最小服务端接口(伪代码)

服务端只需要一个接口,用来接收问题、做检索、拼 Prompt、最后流式返回给前端。

// POST /api/rag/query

app.post('/api/rag/query', async (req, res) => {

const { question } = req.body;

// 1. 嵌入问题

const qVec = await embed(question);

// 2. 检索 top-5

const hits = await vectorStore.search(qVec, { topK: 5 });

// 3. 拼 prompt

const context = hits.map((h, i) => `[${i + 1}] ${h.text}`).join('\n\n');

const prompt = `请基于以下资料回答问题。引用资料时用 [1][2] 标记。\n\n资料:\n${context}\n\n问题:${question}`;

// 4. 流式调 LLM,把 hits 元信息也通过 SSE 发给前端

res.setHeader('Content-Type', 'text/event-stream');

res.write(`event: sources\ndata: ${JSON.stringify(hits)}\n\n`);

for await (const chunk of llm.stream(prompt)) {

res.write(`event: token\ndata: ${JSON.stringify({ delta: chunk })}\n\n`);

}

res.write('event: done\ndata: {}\n\n');

res.end();

});

这里最关键的是第四步:把检索结果 sources 先于 LLM 的输出推到前端。这样一来,引用 UI 可以提前占好位置,等 LLM 吐出 [1] 这样的标记时,前端直接高亮对应的卡片——体验比 ChatGPT 那种机灵小角标好多了。

四、前端展示引用来源

前端这边,代码结构其实挺清晰。

<script setup lang="ts">

import { ref } from 'vue';

interface Source { id: string; title: string; url: string; text: string; }

const sources = ref([]);

const answer = ref('');

const isStreaming = ref(false);

async function ask(question: string) {

sources.value = [];

answer.value = '';

isStreaming.value = true;

const res = await fetch('/api/rag/query', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ question }) });

// 简化的 SSE parser,参考流式渲染那篇

const reader = res.body!.pipeThrough(new TextDecoderStream()).getReader();

let buffer = '';

while (true) {

const { value, done } = await reader.read();

if (done) break;

buffer += value;

const events = buffer.split('\n\n');

buffer = events.pop() ?? '';

for (const ev of events) {

const lines = ev.split('\n');

const event = lines.find((l) => l.startsWith('event:'))?.slice(7);

const data = lines.find((l) => l.startsWith('data:'))?.slice(6);

if (!data) continue;

if (event === 'sources') { sources.value = JSON.parse(data); }

else if (event === 'token') { answer.value += JSON.parse(data).delta; }

}

}

isStreaming.value = false;

}

</script>

renderWithCitations 这个工具函数其实很简单:把答案里的 [1] 替换成 ¹,点击或者悬停时弹出一个浮层,展示对应资料的标题和摘要。相比 ChatGPT 那种藏在角标里的信息,这种设计让用户一眼就能看到引文来源,体验更直接。

五、什么场景你不需要 RAG

当然,RAG 也不是万能的。有些场景下,直接塞 Prompt 反而更简单:

  • 数据量极小(几千字以内):把所有内容直接丢进 Prompt 里,省去检索步骤,效果往往更好。
  • 用户问的就是 LLM 自己知道的事:如果问题涉及通用知识,RAG 不仅帮不上忙,反而可能限制模型的回答范围。
  • 需要“创造”而不是“事实”:RAG 的本质是拉回相关文档拼进 Prompt,这会天然地把模型“拉回”到参考资料附近,让它变得更保守、更不敢发挥。

六、什么场景前端可以纯客户端跑 RAG

虽然大部分场景需要服务端支持,但有一种情况例外:你的文档全是公开内容,或者用户自己上传的文件只在本地处理。比如:

  • 用 transformers.js 在浏览器里跑 bge-small-zh 做嵌入;
  • 用 IndexedDB 存向量;
  • LLM 部分接 OpenAI 或 DeepSeek 的 API(这一步仍然需要服务端袋里 Key 来保证安全)。

这种方案特别适合做"个人知识库"、"PDF 阅读助手"、"本地代码搜索"这类隐私敏感的产品。用户的数据全程留在本地,不用上传到任何服务端,心理负担直接降到零。

七、下一步

把流程跑通只是入门。RAG 在生产环境里真正的难点是切片策略、召回质量、以及重排(rerank)。切片怎么切才能不丢失语义?检索结果怎么排序才能把最相关的放在前头?这些才是真正拉开差距的地方。这篇先把基础流程跑通,后续再单独成篇深入聊那些进阶话题。

顺便提一下,如果你想深入了解相关内容,可以看看这几篇:流式渲染里关于 SSE 和 WebSocket 在 Chat UI 的实现;transformers.js 如何在浏览器里跑模型;以及 Prompt 工程的工程化最佳实践。

来源:互联网

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

同类文章推荐

相关文章推荐

更多