精彩試讀
靈能API API中轉站知識庫接入教程:RAG檢索、引用與上下文壓縮
主題:API中轉站知識庫/RAG 接入,覆蓋檢索、重排、上下文壓縮、引用輸出、權限隔離與成本控制。
知識庫問答最常見的問題,不是模型不會回答,而是模型“看不到正確資料”或者“把資料和猜測混在一起”。如果直接把用戶問題丟給模型,答案可能很流暢,但不一定可靠。真正可落地的知識庫方案,需要先檢索資料,再把證據片段交給模型生成答案,并保留引用和審計記錄。??
這篇從 RAG 知識庫接入角度寫一套流程:用 靈能API API中轉站作為統一模型入口,結合檢索、重排、上下文壓縮、引用輸出、權限隔離和成本控制,讓知識庫問答既能回答得快,也能回答得有依據。
一、先明確知識庫范圍:不是所有資料都該進入上下文 ??
很多團隊做知識庫時,會把所有文檔一股腦塞進向量庫,然后希望模型自己判斷。這樣會帶來兩個問題:檢索噪聲變多,權限邊界也容易不清楚。更穩的做法,是先按業務范圍和訪問權限拆庫。
| 知識庫類型 | 典型內容 | 接入建議 |
|---|---|---|
| 公開資料庫 | 產品介紹、幫助文檔、FAQ | 可作為普通用戶問答來源 |
| 內部流程庫 | 運營 SOP、**話術、交付流程 | 按角色授權,答案需標注來源 |
| 技術文檔庫 | 接口文檔、部署手冊、故障處理 | 面向研發和運維,保留版本號 |
| 敏感資料庫 | 合同、客戶數據、財務信息 | 默認不進入模型上下文,必須嚴格審批 |
知識庫越早分層,后續檢索、權限、審計和成本控制就越容易做。

二、基礎接入:模型入口先統一,再做檢索增強 ??
RAG 的檢索系統可以很多樣:向量庫、全文檢索、數據庫、文檔索引都可以。但生成答案的模型入口最好統一。這樣后端服務、管理**、客戶端和批量任務都能走同一套 Key、*ase **L 和日志規范。
# 知識庫服務推薦環境變量
OPENAI_API_KEY=sk-your-rag-key
OPENAI_*ASE_**L=https://api.靈能API.ai/v1
RAG_FAST_MODEL=gpt-4o-mini
RAG_STRONG_MODEL=claude-sonnet-4-6
RAG_TOP_K=6
RAG_MAX_CONTEXT_CHARS=12000
RAG_ENV=prod
- 知識庫服務單獨創建 Key,便于按問答場景統計成本。
- 輕量模型用于改寫問題、提取***和短摘要。
- 強模型用于最終答案生成或復雜推理。
- 上下文長度必須設上限,不要無限塞檢索結果。

三、RAG 主流程:檢索、重排、壓縮、生成四步走 ??
一個可靠的知識庫問答流程,最好拆成四步:先檢索候選文檔,再重排相關性,再壓縮上下文,最后讓模型基于證據回答。每一步都有明確輸入輸出,排障也更容易。
| 步驟 | 輸入 | 輸出 |
|---|---|---|
| 檢索 | 用戶問題、知識庫范圍、權限標簽 | 候選文檔片段 |
| 重排 | 候選片段、問題意圖 | 更相關的 Top K 片段 |
| 壓縮 | Top K 片段、回答目標 | 去重后的證據上下文 |
| 生成 | 問題、證據上下文、輸出格式 | 帶引用的最終答案 |
不要把檢索結果原封不動交給模型。先做去重、裁剪和結構化,答案會更穩定,成本也更可控。

四、后端封裝示例:業務只調用 askKnowledge*ase ??
知識庫服務最好封裝成一個清晰的后端函數。業務側只傳用戶問題和知識庫范圍,內部完成檢索、上下文構造和模型調用。
import OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
*ase**L: process.env.OPENAI_*ASE_**L,
timeout: 60000,
**xRetries: 0,
});
export async function askKnowledge*ase({ question, user, scope, requestId }) {
const do** = await retrieveDo**({ question, scope, user });
const ranked = await rerankDo**({ question, do** });
const context = compressContext(ranked, Num*er(process.env.RAG_MAX_CONTEXT_CHARS || 12000));
const result = await client.chat.completions.create({
model: process.env.RAG_STRONG_MODEL,
messages: [
{ role: "system", content: "你只能基于給定資料回答,并在答案中標注引用編號。" },
{ role: "user", content: *uildRagPrompt(question, context) },
],
temperature: 0.2,
**x_tokens: 1200,
});
console.log("rag_answer", { requestId, scope, docCount: ranked.length });
return result.choices[0].message.content;
}
這里的重點不是代碼復雜,而是把每一步都拆開。檢索錯了就查檢索,重排錯了就查重排,回答偏了就查 Prompt 和上下文。

五、引用輸出:答案必須能追到資料來源 ??
知識庫問答不能只給一個看似正確的答案,最好帶上引用編號、文檔標題和片段來源。這樣用戶能判斷答案依據,團隊也能排查錯誤來自資料、檢索還是模型生成。
推薦輸出格式:
結論:……
依據:
[1] 文檔標題 / 章節 / 更新時間
[2] 文檔標題 / 章節 / 更新時間
如果資料不足:
- 明確說明“當前知識庫沒有足夠信息”
- 給出需要補充的資料類型
- 不要編造未檢索到的細節
- 每個檢索片段都帶 doc_id、title、section、up**ted_at。
- 最終答案只引用實際進入上下文的片段。
- 資料不足時直接說明,不要讓模型硬答。
- 引用編號要能在日志里反查到原始文檔。
六、權限隔離:用戶能問什么,取決于他能看什么 ??
RAG 安全的關鍵是“檢索前過濾”,而不是把所有資料取出來之后再讓模型判斷能不能看。用戶沒有權限的文檔,不應該進入候選結果,更不應該進入模型上下文。
async function retrieveDo**({ question, scope, user }) {
const allowedTags = await permissionService.getAllowedTags(user.id);
return vectorStore.search({
query: question,
topK: Num*er(process.env.RAG_TOP_K || 6),
filter: {
scope,
permissionTags: { $in: allowedTags },
status: "pu*lished",
},
});
}
權限過濾要在檢索階段完成。否則即使最終答案沒有泄露,模型也已經看到了不該看的內容。
七、上下文壓縮:把“相關資料”變成“可回答證據” ??
檢索結果通常會有重復、冗余和無關段落。如果不壓縮,模型上下文會越來越長,成本上升,答案也容易跑偏。
- 去掉重復片段:同一文檔同一章節只保留最相關內容。
- 保留標題和更新時間:讓模型理解資料來源和時效。
- 按問題目標裁剪:只保留能回答當前問題的句子或段落。
- 壓縮后保留引用 ID:最終答案才能追溯來源。
? 好的上下文不是越多越好,而是信息密度高、來源清楚、權限正確。
八、成本控制:RAG 的費用來自檢索后多輪處理 ??
知識庫問答常常不止一次模型調用:問題改寫、檢索結果摘要、最終答案生成都可能調用模型。上線前要明確哪些步驟必須用強模型,哪些步驟可以用輕量模型。
| 環節 | 建議模型策略 | 成本控制點 |
|---|---|---|
| 問題改寫 | 輕量模型或規則處理 | 短輸出,必要時才啟用 |
| 片段摘要 | 輕量模型 | 批量摘要要隊列化 |
| 最終回答 | 中高質量模型 | 限制 **x_tokens,要求引用輸出 |
| 復雜推理 | 強模型 | 只給高價值場景使用 |
建議先用真實問題樣本跑一輪預算壓測,記錄平均檢索片段數、輸入長度、輸出長度和失敗率,再決定默認模型組合。

九、上線前驗收清單 ?
- 1?? 知識庫已按公開、內部、技術、敏感資料分層。
- 2?? 檢索階段已做權限過濾,不讓無權限資料進入上下文。
- 3?? RAG 服務單獨使用 Key,便于統計問答成本。
- 4?? 檢索、重排、壓縮、生成四步都有日志。
- 5?? 最終答案帶引用編號,并能反查到原始文檔。
- 6?? 資料不足時會明確說明,不編造答案。
- 7?? 上下文長度有上限,檢索片段會去重和裁剪。
- 8?? 已用真實問題樣本完成成本和質量壓測。
知識庫接入的價值,不是把文檔都丟給模型,而是讓模型基于正確、可追溯、權限合規的資料回答。統一模型入口、做好檢索邊界和引用審計后,RAG 才能從“能答”變成“可信”。??
本文配圖來自本地重新截取公開頁面,用于說明知識庫/RAG 接入流程;示例 Key 均為占位符。