RAG生產級完全指南:2026年檢索增強生成從原理到實戰,建構企業知識庫AI
技术架构
2026年,RAG已成為AI應用的標配
沒有RAG的大模型就像沒有圖書館的學者——知識停留在訓練資料截止日。RAG讓AI擁有即時、可更新的知識庫,是2026年企業AI應用的核心基礎設施。
一個資料:2026年企業AI應用中,87%使用了RAG,比2024年的31%增長了近3倍。
RAG解決了什麼問題
| 問題 | 沒有RAG | 有RAG |
|---|---|---|
| 知識過時 | 模型訓練資料截止 | 即時檢索最新文件 |
| 幻覺(Hallucination) | 捏造不存在的事實 | 基於檢索結果回答 |
| 領域知識缺失 | 通用知識,不懂專業 | 注入企業私有知識 |
| 資料隱私 | 資料上傳到模型廠商 | 知識庫本地/私有雲 |
| 可追溯性 | 不知道答案來源 | 每個答案附帶引用來源 |
RAG核心架構
基礎架構:索引 + 檢索 + 生成
┌──────────────────────────────────────────────────────┐
│ 使用者提問 │
│ "公司2025年Q4的營收是多少?" │
├──────────────────────────────────────────────────────┤
│ 查詢處理層 │
│ 查詢改寫 │ 查詢擴展 │ 意圖識別 │ HyDE │
├──────────────────────────────────────────────────────┤
│ 檢索層(雙路召回) │
│ 向量檢索(語意相似) │ 關鍵詞檢索(精確匹配) │
│ ↕ 融合排序(RRF/Cross-Encoder重排) │
├──────────────────────────────────────────────────────┤
│ 生成層 │
│ 上下文注入 → LLM推理 → 答案 + 引用來源 │
└──────────────────────────────────────────────────────┘
第一步:文件處理與分塊
分塊策略對比
| 策略 | 原理 | 優點 | 缺點 | 適用場景 |
|---|---|---|---|---|
| 固定長度 | 按token數切割 | 簡單 | 切斷語意 | 日誌、表格 |
| 遞迴字元 | 按分隔符遞迴切 | 保留段落結構 | 長度不均 | 通用文件 |
| 語意分塊 | Embedding相似度斷點 | 語意完整 | 計算量大 | 技術文件 |
| 文件結構 | 按標題/章節切 | 結構完整 | 需解析器 | Markdown/HTML |
生產級分塊實作
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";
import { MarkdownTextSplitter } from "langchain/text_splitter";
// 通用文件分塊
const splitter = new RecursiveCharacterTextSplitter({
chunkSize: 512,
chunkOverlap: 64,
separators: ["\n\n", "\n", "。", ".", " ", ""],
});
// Markdown結構化分塊
const mdSplitter = new MarkdownTextSplitter({
chunkSize: 1024,
chunkOverlap: 128,
});
// 帶元資料的分塊
interface ChunkMetadata {
source: string;
page?: number;
section?: string;
chunkIndex: number;
totalChunks: number;
}
async function chunkDocument(doc: Document): Promise<Chunk[]> {
const chunks = await splitter.splitText(doc.content);
return chunks.map((text, index) => ({
content: text,
metadata: {
source: doc.source,
section: extractSection(text),
chunkIndex: index,
totalChunks: chunks.length,
},
}));
}
語意分塊(2026年最佳實踐)
import OpenAI from "openai";
const openai = new OpenAI();
async function semanticChunk(text: string, threshold = 0.85): Promise<string[]> {
const sentences = text.match(/[^。.!!??]+[。.!!??]/g) || [];
const embeddings = await openai.embeddings.create({
model: "text-embedding-3-small",
input: sentences,
});
const chunks: string[] = [];
let currentChunk = sentences[0];
for (let i = 1; i < sentences.length; i++) {
const similarity = cosineSimilarity(
embeddings.data[i - 1].embedding,
embeddings.data[i].embedding
);
if (similarity > threshold) {
currentChunk += sentences[i];
} else {
chunks.push(currentChunk);
currentChunk = sentences[i];
}
}
chunks.push(currentChunk);
return chunks;
}
第二步:Embedding與向量資料庫
Embedding模型選型(2026年6月)
| 模型 | 維度 | 效能(MTEB) | 價格/1M tokens | 中文支援 |
|---|---|---|---|---|
| text-embedding-3-large | 3072 | 68.4 | $0.13 | ✅ |
| text-embedding-3-small | 1536 | 62.3 | $0.02 | ✅ |
| bge-m3(開源) | 1024 | 65.8 | 免費 | ✅✅ |
| gte-Qwen2-1.5B(開源) | 1536 | 67.2 | 免費 | ✅✅ |
| Cohere embed-v4 | 1024 | 66.1 | $0.10 | ✅ |
向量資料庫選型
| 資料庫 | 類型 | 延遲(1M向量) | 特點 | 適用場景 |
|---|---|---|---|---|
| Pinecone | 託管 | 15ms | 零維運 | 快速上線 |
| Weaviate | 開源/託管 | 20ms | 混合檢索 | 通用 |
| Qdrant | 開源/託管 | 12ms | Rust高效能 | 高併發 |
| Milvus | 開源/託管 | 18ms | 十億級規模 | 大規模 |
| pgvector | PostgreSQL擴充 | 25ms | 複用PG | 已有PG |
| Chroma | 開源 | 30ms | 輕量級 | 原型開發 |
Qdrant生產級設定
import { QdrantClient } from "@qdrant/js-client-rest";
const client = new QdrantClient({ url: "http://localhost:6333" });
// 建立集合
await client.createCollection("knowledge_base", {
vectors: {
size: 1536,
distance: "Cosine",
},
optimizers_config: {
indexing_threshold: 20000,
},
hnsw_config: {
m: 16,
ef_construct: 100,
},
});
// 索引文件
async function indexDocuments(chunks: Chunk[]) {
const embeddings = await openai.embeddings.create({
model: "text-embedding-3-small",
input: chunks.map((c) => c.content),
});
const points = chunks.map((chunk, i) => ({
id: crypto.randomUUID(),
vector: embeddings.data[i].embedding,
payload: {
content: chunk.content,
...chunk.metadata,
},
}));
await client.upsert("knowledge_base", { points, wait: true });
}
// 向量檢索
async function vectorSearch(query: string, topK = 5) {
const queryEmbedding = await openai.embeddings.create({
model: "text-embedding-3-small",
input: query,
});
const results = await client.search("knowledge_base", {
vector: queryEmbedding.data[0].embedding,
limit: topK,
with_payload: true,
});
return results.map((r) => ({
content: r.payload?.content as string,
score: r.score,
metadata: r.payload,
}));
}
第三步:混合檢索(2026年標配)
向量檢索 + 關鍵詞檢索 + 重排序
import { BM25Retriever } from "langchain/retrievers/bm25";
async function hybridSearch(query: string, topK = 10) {
// 1. 向量檢索(語意相似)
const vectorResults = await vectorSearch(query, topK * 2);
// 2. 關鍵詞檢索(精確匹配)
const bm25Results = await bm25Search(query, topK * 2);
// 3. 倒數排名融合(Reciprocal Rank Fusion)
const fused = reciprocalRankFusion(
[vectorResults, bm25Results],
[0.7, 0.3] // 權重:向量70%,關鍵詞30%
);
// 4. Cross-Encoder重排序
const reranked = await crossEncoderRerank(query, fused, topK);
return reranked;
}
function reciprocalRankFusion(
resultSets: SearchResult[][],
weights: number[]
): SearchResult[] {
const scores = new Map<string, number>();
resultSets.forEach((results, setIndex) => {
results.forEach((result, rank) => {
const key = result.content;
const score = weights[setIndex] / (rank + 1 + 60); // k=60
scores.set(key, (scores.get(key) || 0) + score);
});
});
return Array.from(scores.entries())
.sort((a, b) => b[1] - a[1])
.map(([content, score]) => ({ content, score }));
}
async function crossEncoderRerank(
query: string,
candidates: SearchResult[],
topK: number
): Promise<SearchResult[]> {
const pairs = candidates.map((c) => [query, c.content]);
const results = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: pairs.map(([q, c]) => ({
role: "user",
content: `判斷以下文件與查詢的相關性(0-10分):\n查詢:${q}\n文件:${c}\n評分:`,
})),
});
return candidates
.map((c, i) => ({
...c,
rerankScore: parseFloat(results.choices[i]?.message?.content || "0"),
}))
.sort((a, b) => b.rerankScore - a.rerankScore)
.slice(0, topK);
}
第四步:生成與引用
帶引用的RAG生成
async function ragGenerate(query: string) {
// 1. 檢索相關文件
const documents = await hybridSearch(query, 5);
// 2. 建構上下文
const context = documents
.map((doc, i) => `[${i + 1}] 來源:${doc.metadata.source}\n${doc.content}`)
.join("\n\n");
// 3. 生成答案
const response = await openai.chat.completions.create({
model: "gpt-4o",
messages: [
{
role: "system",
content: `你是知識庫問答助手。基於以下檢索到的文件回答使用者問題。
規則:
1. 只基於檢索到的文件回答,不捏造資訊
2. 每個陳述必須標註引用來源 [1][2]...
3. 如果檢索結果不足以回答,明確說明
4. 優先使用最新、最相關的資訊
檢索文件:
${context}`,
},
{ role: "user", content: query },
],
temperature: 0.1,
});
return {
answer: response.choices[0].message.content,
sources: documents.map((d) => ({
source: d.metadata.source,
score: d.score,
snippet: d.content.slice(0, 100),
})),
};
}
進階最佳化:查詢改寫與HyDE
// 查詢改寫:將模糊查詢轉為精確查詢
async function queryRewrite(query: string): Promise<string[]> {
const response = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{
role: "system",
content: "將使用者查詢改寫為3個不同角度的搜尋查詢,提高檢索召回率。輸出JSON陣列。",
},
{ role: "user", content: query },
],
response_format: { type: "json_object" },
});
return JSON.parse(response.choices[0].message.content).queries;
}
// HyDE:假設性文件嵌入
async function hydeEmbedding(query: string): Promise<number[]> {
const hypotheticalAnswer = await openai.chat.completions.create({
model: "gpt-4o-mini",
messages: [
{ role: "system", content: "給出這個問題的詳細答案(即使你不確定)。" },
{ role: "user", content: query },
],
});
const embedding = await openai.embeddings.create({
model: "text-embedding-3-small",
input: hypotheticalAnswer.choices[0].message.content,
});
return embedding.data[0].embedding;
}
生產級部署架構
┌──────────────────────────────────────────────────────┐
│ API Gateway │
│ 認證 │ 限流 │ 快取 │ 日誌 │
├──────────────────────────────────────────────────────┤
│ RAG Pipeline │
│ 查詢改寫 → 混合檢索 → 重排序 → 生成 → 引用 │
├───────────────┬──────────────────────────────────────┤
│ Embedding │ 向量資料庫 │ 關鍵詞索引 │
│ API/本地模型 │ Qdrant/Pinecone │ Elasticsearch │
├───────────────┴──────────────────────────────────────┤
│ 文件擷取Pipeline │
│ 解析 → 分塊 → Embedding → 索引 → 元資料儲存 │
├──────────────────────────────────────────────────────┤
│ 監控與評估 │
│ 檢索命中率 │ 答案準確率 │ 延遲 │ 成本 │
└──────────────────────────────────────────────────────┘
RAG評估指標
| 指標 | 說明 | 目標值 |
|---|---|---|
| 檢索命中率 | 查詢相關文件被召回的比例 | > 90% |
| MRR | 首個相關文件的平均排名倒數 | > 0.8 |
| 答案準確率 | 答案與ground truth一致的比例 | > 85% |
| 引用準確率 | 引用來源與答案內容匹配的比例 | > 95% |
| 端到端延遲 | 從查詢到答案的總時間 | < 2s |
| 拒答率 | 正確拒絕無法回答的問題的比例 | > 80% |
2026下半年趨勢
| 趨勢 | 說明 |
|---|---|
| GraphRAG | 知識圖譜+向量檢索,處理多跳推理 |
| ColBERT晚期互動 | 更精細的token級匹配,檢索精度提升20% |
| 多模態RAG | 圖表、圖片、影片也能檢索和引用 |
| 自適應分塊 | 根據查詢動態調整分塊策略 |
| RAG快取 | 相似查詢複用檢索結果,降低延遲和成本 |
總結
- 分塊是RAG的地基 — 語意分塊 > 結構分塊 > 固定分塊
- 混合檢索是2026年標配 — 向量70% + 關鍵詞30% + 重排序
- 引用是RAG的靈魂 — 每個答案必須可追溯到原始文件
- 評估是持續最佳化的前提 — 檢索命中率、答案準確率、引用準確率
RAG不是「檢索+生成」這麼簡單,而是一個需要精心設計每個環節的系統工程。分塊策略、檢索方法、重排序、查詢改寫——每個環節都決定了最終答案的品質。
本站提供瀏覽器本地工具,免註冊即可試用 →
#RAG#检索增强生成#向量数据库#Embedding#大模型#知识库#LangChain#LlamaIndex