骁龙X2 Elite平台AI实战(3):部署本地RAG知识库问答系统
前言
这篇实战直接带你在骁龙X2 Elite笔记本上把本地RAG(检索增强生成)问答环境跑起来。
这套方案的目标很明确:文档不出本机、问答响应可控、开发流程可复现。
我们先从环境搭建和基础验证开始,接着把FAISS检索链路和Prompt策略补齐,形成完整可用的本地知识问答系统。
一. 环境搭建与基础验证
1.1 本文硬件与系统信息
我这边使用的是固定配置:
- 设备:骁龙X2 Elite开发笔记本
- 系统:Windows 11
- 内存:32GB
- Python:3.10.x
- Ollama:Windows 版本
- 模型:qwen2.5:7b

1.2 整体执行流程
先把整件事的执行路径放出来,后面每一步都照这个走。
- 环境准备:
确认X2 Elite系统为Windows 11;
确保获取系统管理员权限,关闭安全软件拦截; - 部署Python
下载并安装Python 3.10;
安装时务必勾选“Add Python to PATH”选项; - 虚拟环境配置
安装Miniconda包管理工具;
执行命令创建rag_env独立环境; - 部署服务端
下载并安装Ollama工具;
首次启动Ollama服务,初始化本地模型服务环境;
打开命令行工具,执行ollama pull qwen2.5:7b,自动下载并部署阿里通义千问2.5 7B模型,完成后即可在本地调用LLM能力。
二. 环境安装步骤
2.1 安装 Python 3.10
直接去Python官网下3.10安装包,安装时一定勾选Addpython.exe toPATH。这一项不勾,后面命令行会一直报找不到python。
安装完成后,执行:
python --version
看到3.10. x就是正常。
2.2 安装 Miniconda 并创建环境
我这边统一用 conda 管理依赖,避免系统 Python 被污染。
conda create - n rag_env python=3.10 - y
conda activate rag_env
然后升级 pip:
python - m pip install --upgrade pip
2.3 安装 Ollama 并拉取模型
安装完 Ollama for Windows 后,先确认服务可用:
ollama --version
接着拉模型:
ollama pull qwen2.5:7b
这个步骤通常会花几分钟到十几分钟,取决于网络。
2.4 安装 RAG 所需 Python 依赖
在 rag_env 环境里执行:
pip install langchain langchain- community faiss- cpu sentence- transformers ollama
为了做基础接口调用测试,再补一个 requests:
pip install requests
三. 基础能力验证
3.1 验证本地模型是否可推理
执行:
ollama run qwen2.5:7b "请用一句话介绍骁龙X2 Elite在端侧AI场景的优势"
只要能稳定返回中文回答,说明模型推理链路没问题。
3.2 验证 RAG 链路的数据流
这里先不追求复杂业务,先把最小可用链路打通:
- 准备一份FAQ Markdown文档;
- 切分文本;
- 生成向量;
- 落到 FAISS;
- 用户提问后检索 Top- K;
- 交给 qwen2.5:7b 生成答案。
流程如下:

3.3 最小验证脚本
新建 quick_rag_check.py,内容如下:
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
docs = [
"X2 Elite支持低功耗端侧推理。",
"本项目使用Ollama运行qwen2.5:7b模型。",
"RAG流程包括切分、向量化、检索、生成四个核心步骤。"
]
splitter = RecursiveCharacterTextSplitter(chunk_size=80, chunk_overlap=10)
chunks = splitter.create_documents(docs)
emb = HuggingFaceEmbeddings(model_name="sentence- transformers/all- MiniLM- L6- v2")
db = FAISS.from_documents(chunks, emb)
query = "这个项目的核心流程是什么?"
hits = db.similarity_search(query, k=2)
for i, h in enumerate(hits, 1):
print(f"Top{i}: {h.page_content}")
运行:
python quick_rag_check.py
只要能输出Top1、Top2命中文本,就说明检索部分已经打通。
到这里,达成了:
- X2 Elite 本地大模型环境已经可用;
- RAG 的最小检索链路已经跑通;
- 关键依赖和排错路径都已经验证。
下面我们直接进入实战:把 Markdown 文档目录批量入库,做可复用的检索+生成脚本,并给出可直接迁移到业务项目的目录结构。
五.文档批量入库
5.1 整体数据流
先看这篇的核心数据流,从文档目录到最终问答输出:
5.2 准备知识库目录
在项目根目录下新建 knowledge_base/ 文件夹,把需要入库的 Markdown 文件放进去。我这边放了 5 个文件,内容覆盖产品 FAQ、操作手册、常见故障排查。
# 目录结构:
knowledge_base/
├── faq.md
├── install_guide.md
├── troubleshooting.md
├── ...
5.3 编写入库脚本
新建 build_index.py :
import os
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain.schema import Document
KNOWLEDGE_DIR = "./knowledge_base"
INDEX_DIR = "./faiss_index"
def load_markdown_files(directory):
docs = []
for filename in os.listdir(directory):
if filename.endswith(".md"):
filepath = os.path.join(directory, filename)
with open(filepath, "r", encoding="utf-8") as f:
content = f.read()
docs.append(Document(page_content=content, metadata={"source": filename}))
return docs
def build_index():
raw_docs = load_markdown_files(KNOWLEDGE_DIR)
print(f"加载了 {len(raw_docs)} 个文档")
splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
separators=["\n## ", "\n### ", "\n\n", "\n", ""]
)
chunks = splitter.split_documents(raw_docs)
print(f"切分为 {len(chunks)} 个片段")
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
db = FAISS.from_documents(chunks, embeddings)
db.save_local(INDEX_DIR)
print(f"FAISS索引已保存到 {INDEX_DIR}")
if __name__ == "__main__":
build_index()
运行:
python build_index.py
正常输出类似:
加载了 5 个文档
切分为 47 个片段
FAISS索引已保存到 ./faiss_index
5.4 切分参数说明
这里 chunk_size=500 是经过测试的值。太大会导致检索命中不够精准,太小会丢失上下文。chunk_overlap=50 保证相邻片段之间有一定重叠,避免关键信息被切断。
separators 的优先级从高到低:先按二级标题切,再按三级标题,最后按段落和行。这样能保持文档结构的完整性。
六. 检索生成脚本
6.1 编写问答脚本
新建 rag_query.py :
from langchain_community.vectorstores import FAISS
from langchain_community.embeddings import HuggingFaceEmbeddings
import ollama
INDEX_DIR = "./faiss_index"
def load_index():
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/all-MiniLM-L6-v2"
)
db = FAISS.load_local(INDEX_DIR, embeddings, allow_dangerous_deserialization=True)
return db
def retrieve_and_generate(db, question, top_k=3):
hits = db.similarity_search(question, k=top_k)
context_parts = []
for i, hit in enumerate(hits, 1):
source = hit.metadata.get("source", "unknown")
context_parts.append(f"[片段{i}] 来源:{source}] \n{hit.page_content}")
context = "\n\n".join(context_parts)
prompt = f"""你是一个技术支持助手。根据以下参考资料回答用户的问题。
如果参考资料中没有相关内容,直接说"抱歉,当前知识库中没有找到相关信息"。
参考资料:
{context}
用户问题:{question}
请用简洁准确的中文回答:
"""
response = ollama.chat(
model="qwen2.5:7b",
messages=[{"role": "user", "content": prompt}]
)
return response["message"]["content"], hits
if __name__ == "__main__":
db = load_index()
print("知识库已加载,输入问题开始问答(输入q退出)")
while True:
question = input("\n你的问题:")
if question.strip().lower() == "q":
break
answer, sources = retrieve_and_generate(db, question)
print(f"\n回答:{answer}")
print(f"\n参考来源:{', '.join(set(s.metadata.get('source','') for s in sources))}")
6.2 运行效果
启动问答:
python rag_query.py
实际测试记录:
你的问题:安装失败怎么办?
回答:安装失败时,先检查系统盘剩余空间是否大于10GB,然后确认
Python版本为3.10. x。如果仍然失败,删除已有的conda环境后重新
创建:conda remove - n rag_env - - all,再执行 conda create - n
rag_env python = 3.10 - y。
参考来源:troubleshooting.md,install_guide.md
从提问到返回答案,在X2 Elite上的端到端延迟大约在3-5秒,其中检索部分不到100ms,主要耗时在qwen2.5:7b的生成阶段。
七. Prompt策略优化
7.1 限定回答范围
上面的Prompt里有一句关键话:“如果参考资料中没有相关内容,直接说抱歉”。这一句不能省,否则模型会自由发挥,编造不存在的操作步骤。
7.2 控制输出长度
如果回答太长,在 Prompt 末尾加一句:
请控制回答在200字以内。
实测这对 qwen2.5:7b 的约束效果很好。
7.3 多轮对话扩展
当前脚本是单轮问答。如果要支持多轮,把历史消息列表传给 ollama.chat 的 messages 参数即可:
messages = [
{ "role": "user", "content": "第一轮问题..."},
{ "role": "assistant", "content": "第一轮回答..."},
{ "role": "user", "content": prompt}
]
八. 性能数据
在骁龙 X2 Elite(32GB 内存)上的实测数据:
| 指标 | 数值 |
|---|---|
| 文档加载(5个MD文件) | 0.3秒 |
| 向量化(47个片段) | 4.2秒 |
| FAISS索引构建 | 0.1秒 |
| 单次检索(Top-3) | 80ms |
| qwen2.5:7b生成(约150字) | 3.1秒 |
| 端到端问答延迟 | 3.2秒 |
| 内存占用峰值 | 6.8GB |
骁龙X2 Elite上RAG各阶段性能指标:
数据总结:RAG系统在“检索侧”已达到毫秒级响应标准,性能瓶颈主要集中在“计算侧”的向量化与模型推理阶段,后续优化应聚焦于模型量化与并行计算加速。
- 极速检索响应
单次检索(Top-3)仅需80ms,索引构建与文档加载均在毫秒级完成,系统在检索环节展现出极高的吞吐效率。 - 核心耗时瓶颈
向量化处理耗时最长达4.2秒,模型生成紧随其后约3.1秒,这是当前影响整体性能的主要计算密集型环节。 - 端到端体验可控
完整问答链路延迟控制在3.2秒,在保证检索精准度的前提下,实现了高效的生成与响应平衡。
九. 常见问题
9.1 ollama pull 很慢
这是最常见问题。直接结论:
- 高峰时段确实慢,换网络最有效;
- 不要反复中断,断点续传有时候比重拉更快;
- 先把7B模型跑通,后面再考虑更大参数版本。
9.2 Windows 下 FAISS 安装报错
优先用 faiss- cpu,不要先上GPU版。另外,Python版本固定在3.10,兼容性会明显好很多。
9.3 中文检索命中率一般
这个问题在第一版里很正常,先别急着怀疑模型。先检查三件事:
- chunk切分是不是太粗;
- 文档里是不是有大量噪声文本;
- 查询语句和知识库语料是否同领域。
9.4 FAISS索引加载报安全警告
allow_dangerous_deserialization=True这个参数必须加,否则 LangChain 新版会拒绝加载本地索引。这是因为 FAISS 索引使用了 pickle 序列化,LangChain 默认阻止反序列化以防注入攻击。本地使用场景下加上即可。
9.5 检索结果不相关
先排查这几点:
- 检查 chunk_size 是否合理,500 是个不错的起点;
- 确认文档内容和查询语句是同一个领域;
- 尝试把 top_k 从 3 调到 5,看看是不是相关片段排在了后面。
9.6 生成速度太慢
qwen2.5:7b 在 X2 Elite 上的生成速度大约 8-12 tokens/s。如果觉得慢,换成 qwen2.5:3b 会快很多,但回答质量会下降。根据实际业务需求选择模型大小。
小结
至此,我们在骁龙 X2 Elite 上完成了一个完整的本地 RAG 知识问答系统:既搞定了环境安装和基础链路验证;又实现了文档批量入库、检索生成脚本、Prompt 优化策略;
整套系统完全离线运行,端到端延迟 3 秒左右,实用性没问题。
更多推荐


所有评论(0)