AI 实践:本地搭建 RAG + LLMs
2025-08-09
0.背景
突出一批「典型场景」,利用 AI 能力实现,加深原理的理解。
这次的主要内容,都在 local-RAG-with-LLM。
实践:先做、尽快做完,再依赖迭代做到完美。
1.RAG 系统原理
包含几个部分:
- 基础工具:向量数据库、大数据模型、向量化工具(也可以复用大模型能力)
- 基础数据:关联文档
- 具体过程:
- 1.数据准备:
- 1.1.将关联文档,进行切块
- 1.2.将文档切块,向量化
- 1.3.向量化的文档切块,存入
向量数据库
- 2.查询语句 Query,在向量化后,得到
向量化Query
,依赖向量数据库
,使用向量化Query
,查询出 最相关的几个文档切块 - 3.将 Query 语句 + 相关的文档切块,加入
prompt 模板
,输入给 LLM 模型,得到最终的答案。
- 1.数据准备:
注意:
1.两次向量化:第一部分
向量化
,只是获取了相关的文档片段
;后续,仍然是语言文本
构造 prompt,输入给 LLM 模型,在大模型内部,仍然会进行二次向量化
。2.向量数据库,边界:只认识向量,不认识语言文本;需要在外部,将语言文本,转换为向量。
示意图:
2. 实践:本地搭 RAG 系统 + Ollama
示例代码: 更多细节参考 design-manual
import faiss
import numpy as np
import requests
import textwrap
import json
# ========= 1. Ollama API 封装 =========
OLLAMA_API = "http://localhost:11434/api"
def ollama_embed(text, model="deepseek-r1:8b"):
"""调用 Ollama embedding 接口"""
resp = requests.post(f"{OLLAMA_API}/embed", json={"model": model, "input": text})
data = resp.json()
# print('ollama_embed result data:', data)
return np.array(data["embeddings"][0], dtype="float32")
def ollama_chat(prompt, model="deepseek-r1:8b"):
"""调用 Ollama Chat 接口"""
payload = {
"model": model,
"prompt": prompt,
"stream": False
}
resp = requests.post(f"{OLLAMA_API}/generate", json=payload)
data = resp.json()
# print('ollama_chat result data:', data)
return data["response"].strip()
# ========= 2. 加载文档并切分 =========
docs = [
"""我们的系统支持多种支付方式,包括支付宝、微信支付和银行卡支付。
在支付过程中如遇到问题,可以联系客服协助处理。""",
"""用户可以通过点击登录页面的“忘记密码”,
使用注册邮箱或手机号进行验证,即可重置密码。""",
"""完成订单后,您可以在“个人中心-订单管理”页面申请电子发票。
系统将自动开具并发送到您的邮箱。"""
]
def split_into_chunks(text, chunk_size=200):
text = text.replace("\n", " ")
return textwrap.wrap(text, chunk_size)
chunks = []
for doc in docs:
processed_doc = split_into_chunks(doc)
chunks.extend(processed_doc)
chunk_embeddings = []
for chunk in chunks:
emb = ollama_embed(chunk)
chunk_embeddings.append(emb)
# ========= 3. 构建向量库 =========
dim = len(ollama_embed("测试")) # 向量维度
index = faiss.IndexFlatL2(dim)
index.add(np.array(chunk_embeddings))
# ========= 4. 检索 =========
def retrieve_chunks(query, top_k=3):
query_emb = ollama_embed(query)
D, I = index.search(np.array([query_emb]), top_k)
return [chunks[i] for i in I[0]]
# ========= 5. 生成答案 =========
def answer_query(query):
retrieved = retrieve_chunks(query, top_k=3)
context = "\n".join(retrieved)
prompt = f"""
你是一个文档问答助手。
只能根据以下提供的文档内容回答用户问题,
如果找不到,请回答:“抱歉,文档中没有相关内容”。
文档内容:
{context}
用户问题: {query}
请用自然语言总结或改写回答:
"""
return ollama_chat(prompt)
# ========= 6. 测试 =========
if __name__ == "__main__":
# q = "系统支持哪些支付方式?"
q = "你是谁?"
print("用户提问:", q)
print("助手回答:", answer_query(q))
特别注意:上面的 prompt 模板,其中包含 原始 query
+ 相关文档片段 context
prompt = f"""
你是一个文档问答助手。
只能根据以下提供的文档内容回答用户问题,
如果找不到,请回答:“抱歉,文档中没有相关内容”。
文档内容:
{context}
用户问题: {query}
请用自然语言总结或改写回答:
"""
原文地址:https://ningg.top/ai-series-local-rag-with-llm-practise/