【第四章:大模型(LLM)】11.LLM + RAG:构建私有领域专家-(4)Rag实战:使用通义千问api实现调用一个本地模型的Rag
第四章:大模型(LLM)
第十一部分:LLM + RAG 构建私有领域专家
第四节:Rag实战:使用通义千问api实现调用一个本地模型的Rag
一、任务背景与目标
在实际应用中,我们往往既想要 云端高质量的向量检索能力,又希望 生成部分能完全在本地运行,避免数据外泄、满足合规与私有化需求。
解决方案:
-
通义千问 API 提供优质的 Embedding 向量化能力,用于检索阶段。
-
本地部署的大模型(如 Llama3、Mistral、Vicuna 等)完成生成阶段。
这就是典型的 Hybrid RAG 架构:云端负责“理解文档与检索”,本地负责“生成答案”。
二、整体架构
工作流程如下:
-
文档切片:将长文档分割成小块(chunk),避免超长输入。
-
调用通义千问嵌入 API:将文本块编码为向量。
-
构建向量数据库(FAISS/Milvus):存储和检索向量。
-
用户提问 → 转换为向量 → 检索相关文档片段。
-
拼装 Prompt:将检索到的上下文与用户问题结合。
-
调用本地大模型:由本地大模型基于检索到的上下文生成答案。
图示流程:
用户问题 → 通义嵌入 → 向量检索 → 上下文拼装
↓
本地 Llama3 生成答案
三、关键步骤与实现
1. 文档切片与预处理
def chunk_text(text, size=500, overlap=100):
chunks = []
start = 0
while start < len(text):
end = min(len(text), start + size)
chunks.append(text[start:end])
start += size - overlap
return chunks
-
推荐 500-1000 字符/句子 为一个 chunk。
-
overlap 保证上下文连续性。
2. 调用通义千问 API 生成 Embedding
import requests, os
API_KEY = os.getenv("DASHSCOPE_API_KEY")
BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
def embed_texts(texts):
url = f"{BASE_URL}/embeddings"
headers = {"Authorization": f"Bearer {API_KEY}"}
data = {"model": "text-embedding-v4", "input": texts}
resp = requests.post(url, headers=headers, json=data)
return [item["embedding"] for item in resp.json()["data"]]
3. 构建 FAISS 向量数据库
import faiss, numpy as np
def build_faiss(chunks):
vectors = np.array(embed_texts(chunks)).astype("float32")
faiss.normalize_L2(vectors)
index = faiss.IndexFlatIP(vectors.shape[1])
index.add(vectors)
return index, chunks
4. 检索与 Prompt 拼装
def retrieve(query, index, chunks, top_k=3):
q_vec = np.array(embed_texts([query])).astype("float32")
faiss.normalize_L2(q_vec)
scores, idxs = index.search(q_vec, top_k)
return [chunks[i] for i in idxs[0]]
def build_prompt(query, retrieved):
context = "\n".join(retrieved)
return f"""
你是专业助手,请基于以下资料回答问题。
资料:
{context}
问题:{query}
答案:
"""
5. 使用本地大模型生成
from transformers import AutoTokenizer, AutoModelForCausalLM
LOCAL_MODEL = "/path/to/llama3"
tokenizer = AutoTokenizer.from_pretrained(LOCAL_MODEL)
model = AutoModelForCausalLM.from_pretrained(LOCAL_MODEL, device_map="auto")
def generate(prompt):
inputs = tokenizer(prompt, return_tensors="pt").to(model.device)
outputs = model.generate(**inputs, max_new_tokens=300)
return tokenizer.decode(outputs[0], skip_special_tokens=True)
6. 完整查询流程
def rag_query(query, index, chunks):
retrieved = retrieve(query, index, chunks)
prompt = build_prompt(query, retrieved)
return generate(prompt)
# 示例:
# docs = open("法律法规.txt").read()
# chunks = chunk_text(docs)
# index, chunks = build_faiss(chunks)
# print(rag_query("合同法的主要内容是什么?", index, chunks))
四、优化策略
-
向量库优化:百万级文档可用 Milvus/HNSW,提升检索速度。
-
Reranker 精排:先召回 top-50,再用 cross-encoder 精排。
-
Prompt 控制:只取 top-3-5,避免本地模型输入超长。
-
量化模型:使用 Llama3 8bit/4bit QLoRA 降低显存占用。
-
缓存与并发:对常见问题缓存结果,支持多用户并发。
五、典型应用场景
-
法律问答系统:私有化部署,保护敏感合约文档。
-
企业知识库:本地大模型结合内部资料,实现“AI 知识专家”。
-
医疗辅助:结合医学文档,提供诊断参考(必须合规+人工复核)。
六、小结
本节我们实现了一个 通义嵌入 API + 本地生成模型 的 RAG 系统:
-
通义 API 提供高质量 embedding;
-
FAISS 负责高效检索;
-
本地大模型 完成最终生成,保证私有化和合规性。
这是一种 混合 RAG 架构,兼顾了 准确性、私有化和灵活性,非常适合企业内部文档问答、法律合规、医疗知识库等场景。
更多推荐



所有评论(0)