【RAG实战】基于 LangChain+Transformers+Qwen3 的RAG 智能产品助手实现

1、背景介绍

就在2025年4月29日凌晨,阿里巴巴正式推出新一代大语言模型通义千问Qwen3,并宣布全面开源。这一消息瞬间引爆AI圈,被誉为“开源大模型王座再易主”的里程碑事件。作为国内首个支持“混合推理”的模型,Qwen3不仅在技术上实现颠覆性创新,更以开源生态加速行业变革。

Qwen3大模型的主要创新点有:

1、支持两种思考模式:

  • 思考模式:在这种模式下,模型会逐步推理,经过深思熟虑后给出最终答案,适合需要深入思考的复杂问题。
  • 非思考模式:在此模式中,模型提供快速、近乎即时响应,适用于对速度要求高于深度的简单问题。

2、多语言支持

Qwen3 模型支持 119 种语言和方言,其中包括印欧语系、汉藏语系、亚非语系、南岛语系、德拉威语、突厥语系 、壮侗语系、乌拉尔语系、南亚语系等等。这一广泛的多语言能力为国际应用开辟了新的可能性,让全球用户都能受益于这些模型的强大功能。

3、增强的 Agent 能力

优化了 Qwen3 模型的 Agent 和 代码能力,同时也加强了对 MCP 的支持。

请添加图片描述

本文基于 FastAPI+LangChain+Transformers+Qwen3+RAG 来实现一个智能产品助手,通过具体的项目实战来帮助大家学习如何 基于Qwen3大模型来构建自己的AI应用。当下人工智能行业不缺AI算法专家和算法工程师,缺的是能基于大模型定制开发企业专用智能体或者应用的工程化人才,希望本文能帮你踏入大模型应用开发的大门,开启大模型应用开发工程师的精彩人生。

2、项目介绍

2.1 项目架构

img

2.2 项目实现原理:

img

实现步骤:

  1. 加载文件
  2. 读取文件
  3. 文本分割
  4. 文本向量化
  5. 问句向量化
  6. 在文本向量中匹配出与问句向量相似的top_k个
  7. 匹配出的文本作为上下文和问题一起添加到prompt中
  8. 提交给LLM生成答案

主要功能包括:

  • 基于本地知识库的问答:系统可以根据用户的提问,在本地的知识库中进行搜索,并返回相关的答案。
  • 多模型支持:项目支持使用不同的语言模型,可以根据需求选择合适的模型进行使用。
  • 离线私有化:可以将该问答系统部署在本地环境中,确保数据的安全性和隐私性。
3、项目的执行流程

img

4、代码实现

4.1 安装依赖
pip install langchain 
pip install fastapi
pip install transfomers

这里只列举了部分,项目详细依赖可以看 requirements.txt 文件

4.2 模型下载

本项目采用离线方式运行,所以需要把qwen3和Embedding 模型下载到本地。

import os
from transformers import AutoModel, AutoTokenizer

os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"  # 国内镜像

# 下载千问3大模型
model_name = "Qwen/Qwen3-1.7B"  # 替换为你想下载的模型名称
tokenizer = AutoTokenizer.from_pretrained(model_name)
model = AutoModel.from_pretrained(model_name)

# 保存到本地
save_path = "../models/qwen3"
model.save_pretrained(save_path)
tokenizer.save_pretrained(save_path)

# 下载embedding模型
model_name = "moka-ai/m3e-base"  # 替换为你想下载的模型名称
tokenizer = AutoTokenizer.from_pretrained(model_name, trust_remote_code=True)
model = AutoModel.from_pretrained(model_name, trust_remote_code=True, force_download=True)
# 保存到本地
save_path = "../models/embedding"
model.save_pretrained(save_path)
tokenizer.save_pretrained(save_path)
4.3 主程序入口
import logging
from contextlib import asynccontextmanager
import uvicorn
from fastapi import FastAPI
from app.routers import chat
from app.services.rag_service import RAGService

# 日志配置
logging.basicConfig(  
  level=logging.DEBUG,    
  format='%(asctime)s - %(levelname)s - %(message)s',    
  handlers=[   
       logging.FileHandler("../app.log", encoding="utf-8"),  # 文件输出        
       logging.StreamHandler()  # 控制台输出  
         ]
)

# 应用启动执行
@asynccontextmanager
async def lifespan(app: FastAPI): 
   from app import rag  # 延迟导入,避免循环引用    
   rag.rag_service = RAGService()    
   logging.info("RAGService 初始化完成")    
   yield    
   logging.info("应用关闭,释放资源")

app = FastAPI(lifespan=lifespan)
app.include_router(chat.api_router)

if __name__ == "__main__":  
  uvicorn.run(app, host="0.0.0.0", port=8000)   
   pass
4.4 FastAPI服务
from fastapi import APIRouter, Depends
from app.schemas.user_input import UserInput
from app.services.qwen_chatbot import QwenChatbot
from app.rag import get_rag_service
from app.services.rag_service import RAGService

api_router = APIRouter(tags=["Qwen3"])

@api_router.post("/chat")
async def chat(query: UserInput, rag: RAGService = Depends(get_rag_service)):
   chatbot = QwenChatbot("../models/qwen3")    
   response = chatbot.generate_response(user_input=query.query, rag=rag)

return response
4.5 自定义QwenChatbot类
from langchain_core.prompts import PromptTemplate
from transformers import AutoModelForCausalLM, AutoTokenizer
from app.services.rag_service import RAGService

class QwenChatbot:   
 def __init__(self, model_name="Qwen/Qwen3-1.7B"):  
       self.tokenizer = AutoTokenizer.from_pretrained(model_name)        
       self.model = AutoModelForCausalLM.from_pretrained(    
               model_name,   
     )       
      self.history = []  

  def generate_response(self, user_input, rag: RAGService):  
        # 搜索相近内容       
         related_content = rag.retrieve_docs(user_input)        
         # 提示词模板        
         PROMPT_TEMPLATE = f"""             
                    基于以下已知信息,简洁和专业的来回答用户的问题。不允许在答案中添加编造成分。                        
                    已知内容:                       
                     {related_content}                       
                      问题:                       
                       {user_input}                    
"""      

  messages = self.history + [{"role": "user", "content": PROMPT_TEMPLATE}]        

text = self.tokenizer.apply_chat_template(    
        messages,            
        tokenize=False,            
        add_generation_prompt=True       
 )       

 inputs = self.tokenizer(text, return_tensors="pt")        
 response_ids = self.model.generate(**inputs, max_new_tokens=32768)[0][len(inputs.input_ids[0]):].tolist()       
  response = self.tokenizer.decode(response_ids, skip_special_tokens=True)        

# Update history       
 self.history.append({"role": "user", "content": user_input})        
 self.history.append({"role": "assistant", "content": response})       

 return response
4.6 RAG构建索引和知识库检索
import os
from pathlib import Path
import pandas as pd
from langchain.chains import RetrievalQA
from langchain.schema import Document
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_chroma import Chroma
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain_huggingface import HuggingFaceEmbeddings

class RAGService:  
  def __init__(self):       
   # 1. 找到项目根目录(rag_service.py 的上上一级)        
   BASE_DIR = Path(__file__).resolve().parent.parent.parent        
   self.docs_path = f"{BASE_DIR}/product_docs/"        
   self.persist_dir = f"{BASE_DIR}/chroma_dbs/"        
   self.chunk_size = 1000        
   self.chunk_overlap = 100        
   self.embedding_model = f"{BASE_DIR}/models/embedding"        
   self.k = 3        
   self._vectordb = None       
    self._initialize()    
 
   def _initialize(self):        
    # 如果已存在持久化目录,直接加载,否则重新构建      
      if os.path.exists(self.persist_dir) and os.listdir(self.persist_dir):            
      self._load_vectorstore()      
        else:        
            self._build_vectorstore()    

def _load_vectorstore(self):    
    """       
     从持久化目录加载 Chroma 向量数据库        
     """       
      embeddings = HuggingFaceEmbeddings(model_name=self.embedding_model)        
      self._vectordb = Chroma(    
              persist_directory=self.persist_dir,            
              embedding_function=embeddings      
  )    

def _build_vectorstore(self):  
      """        
      加载文档、分割并生成向量数据库,并持久化        
      """        
      # 分别加载 txt 和 xlsx 文件,避开单一 loader_cls dict        
      txt_loader = DirectoryLoader(     
             str(self.docs_path),          
               glob="**/*.txt",          
                 loader_cls=TextLoader,        
                     loader_kwargs={'encoding': 'utf-8'}  # 关键参数   
     )       
     xlsx_docs = []   
          for xlsx_file in Path(self.docs_path).glob("**/*.xlsx"):           
           # 读 Excel(默认就支持 .xlsx、.xls)          
             df = pd.read_excel(xlsx_file, sheet_name=None)  # sheet_name=None 会返回 dict,把所有 sheet 一并读入         
                # 如果你只关心第一个 sheet,可以写:df = pd.read_excel(xlsx_file)            
                # 如果读的是 dict(多个 sheet)         
                   if isinstance(df, dict):           
                        for sheet_name, sheet_df in df.items():                  
                          for _, row in sheet_df.iterrows():           
             # 把每行拼成一大段文本                    
                 content = "\n".join(f"{col}: {row[col]}" for col in sheet_df.columns)                        
                 xlsx_docs.append(Document(page_content=content))      
                       else:         
                              # 单个 DataFrame         
                                     for _, row in df.iterrows():               
                                          content = "\n".join(f"{col}: {row[col]}" for col in df.columns)                    
                                          xlsx_docs.append(Document(page_content=content))        

txt_docs = txt_loader.load()       
 documents = txt_docs + xlsx_docs       
  print(f"加载文档数:{len(documents)}")        

splitter = RecursiveCharacterTextSplitter(  
          chunk_size=self.chunk_size,           
           chunk_overlap=self.chunk_overlap,    
    )       
     split_docs = splitter.split_documents(documents)        
     print(f"分割后文档片段数:{len(split_docs)}")       
      embeddings = HuggingFaceEmbeddings(model_name=self.embedding_model)        self._vectordb = Chroma.from_documents(            
      split_docs,            
      embeddings,           
       persist_directory=self.persist_dir, 
       )   
 def retrieve_docs(self, user_input: str) -> str:    
     """        
只做语义检索,返回相关文档内容拼接(不调用 LLM)       
 """        
 docs = []        
# 优先检索城市信息       
 city_docs = self._vectordb.similarity_search(f"city:{user_input}", k=self.k)        docs.extend(city_docs)       
  # 然后检索县区信息        
  county_docs = self._vectordb.similarity_search(f"county:{user_input}", k=self.k)        
  docs.extend(county_docs)        
  # 处理多重结果并去重      
    docs = list({doc.page_content: doc for doc in docs}.values())       
     return "\n".join([doc.page_content for doc in docs])  
       def reload(self):    
           """       
            重新构建向量数据库,例如当文档更新后调用       
             """       
              self._build_vectorstore()
4.7 完整项目的下载地址:

https://github.com/leyu2017126/qwen3_rag_project.git

4.8 结果展示

img

如何学习大模型 AI ?

由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。

但是具体到个人,只能说是:

“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。

这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。

我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。

我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

https://img-blog.csdnimg.cn/img_convert/05840567e2912bcdcdda7b15cba33d93.jpeg

在这里插入图片描述

第一阶段(10天):初阶应用

该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。

  • 大模型 AI 能干什么?
  • 大模型是怎样获得「智能」的?
  • 用好 AI 的核心心法
  • 大模型应用业务架构
  • 大模型应用技术架构
  • 代码示例:向 GPT-3.5 灌入新知识
  • 提示工程的意义和核心思想
  • Prompt 典型构成
  • 指令调优方法论
  • 思维链和思维树
  • Prompt 攻击和防范

第二阶段(30天):高阶应用

该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。

  • 为什么要做 RAG
  • 搭建一个简单的 ChatPDF
  • 检索的基础概念
  • 什么是向量表示(Embeddings)
  • 向量数据库与向量检索
  • 基于向量检索的 RAG
  • 搭建 RAG 系统的扩展知识
  • 混合检索与 RAG-Fusion 简介
  • 向量模型本地部署

第三阶段(30天):模型训练

恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。

到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?

  • 为什么要做 RAG
  • 什么是模型
  • 什么是模型训练
  • 求解器 & 损失函数简介
  • 小实验2:手写一个简单的神经网络并训练它
  • 什么是训练/预训练/微调/轻量化微调
  • Transformer结构简介
  • 轻量化微调
  • 实验数据集的构建

第四阶段(20天):商业闭环

对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。

  • 硬件选型
  • 带你了解全球大模型
  • 使用国产大模型服务
  • 搭建 OpenAI 代理
  • 热身:基于阿里云 PAI 部署 Stable Diffusion
  • 在本地计算机运行大模型
  • 大模型的私有化部署
  • 基于 vLLM 部署大模型
  • 案例:如何优雅地在阿里云私有部署开源大模型
  • 部署一套开源 LLM 项目
  • 内容安全
  • 互联网信息服务算法备案

学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。

如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。

这份完整版的大模型 AI 学习资料已经上传CSDN,朋友们如果需要可以微信扫描下方CSDN官方认证二维码免费领取【保证100%免费

https://img-blog.csdnimg.cn/img_convert/05840567e2912bcdcdda7b15cba33d93.jpeg

<think>好的,用户的问题是关于Qwen模型如何实现RAG(检索增强生成)的。首先,我需要明确RAG的基本原理,它结合了检索和生成两个步骤,通过从外部知识库检索相关信息来增强生成的准确性和相关性。接下来,我需要结合用户提供的引用内容,特别是引用[1]和引用[2],分析Qwen模型如何与RAG结合。 用户提供的引用[1]提到了使用Qwen系列开源模型与LangChain构建RAG应用,并给出了加载模型的代码示例。这说明Qwen可以作为生成模型,而LangChain可能负责检索部分。引用[2]则提到Qwen2.5-7B与bge-reranker-base和stella-base-zh-v2组合成RAG系统,这表明在检索阶段可能使用了这些模型进行重排序和向量检索。 接下来,我需要组织回答的结构,先解释RAG的基本流程,然后分步骤说明Qwen在其中的角色,比如生成模型部分。同时,需要结合代码示例展示如何加载Qwen模型,并提到如何与其他组件(如检索模块)结合。此外,用户可能想知道具体的实现步骤或代码结构,因此需要给出一个整合后的示例代码框架,并解释每个部分的作用。 还要注意用户提到的优化方法,比如模型选择、检索优化和结果增强,这些都需要在回答中详细说明。比如,可以建议用户根据计算资源选择不同大小的Qwen模型,或者调整检索器的参数。此外,引用中的bge-reranker和向量模型stella-base-zh-v2的作用也需要解释清楚,说明它们在检索阶段的重要性。 最后,生成相关问题时要围绕RAG实现、优化和Qwen的调整,确保问题有针对性,帮助用户进一步探索。例如,如何选择适合的Qwen模型,如何优化检索步骤,或者如何处理中文场景下的RAG应用。</think># RAGQwen实现方式 RAG(检索增强生成)通过将检索系统与生成模型结合,有效提升问答系统的准确性和知识覆盖范围。Qwen作为开源大语言模型,可以通过以下方式与RAG系统集成: ## 实现架构 1. **检索模块** - 使用向量数据库(如Faiss)存储知识文档 - 采用`stella-base-zh-v2`等中文向量模型进行语义编码 - 通过`bge-reranker-base`实现检索结果重排序[^2] 2. **生成模块** - 加载Qwen作为生成核心: ```python from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen-7B", trust_remote_code=True) model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen-7B", device_map="auto", trust_remote_code=True) ``` 3. **工作流程** ``` 用户输入 → 检索相关文档 → 重排序 → 拼接提示词 → Qwen生成答案 ``` ## 关键实现步骤 1. **知识库构建**: - 使用`stella-base-zh-v2`将文档转换为向量 - 建立分片索引提升检索效率 2. **提示工程**: - 构造包含检索结果的增强提示: ``` [检索结果] {doc1_content} {doc2_content} [问题] {user_question} ``` 3. **结果生成**: ```python def generate_answer(context, question): prompt = f"{context}\n问题:{question}\n答案:" inputs = tokenizer(prompt, return_tensors="pt").to(model.device) outputs = model.generate(**inputs, max_new_tokens=500) return tokenizer.decode(outputs[0], skip_special_tokens=True) ``` ## 优化方法 1. **模型选择**:根据硬件条件选择Qwen-1.8B到Qwen-72B不同规模模型[^1] 2. **检索优化**:调整top_k检索数量(建议5-10),重排序阈值设置 3. **结果增强**:添加温度系数控制生成多样性 ```python outputs = model.generate(..., temperature=0.7, do_sample=True) ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值