Langchain+Ollama实现Qwen模型+客服问答私有数据FAQ-实现RAG

目标:

部署一个结合大模型和RAG的,客服问题API,如果提问的问题在常见FAQ里,使用FAQ里数据,否则使用大模型回答问题。

本文使用Ollama 直接运行本地 Qwen 模型,需要先安装好ollama。


现在我们将使用 LangChain + Ollama 搭建 RAG(检索增强生成)系统,让它可以:

  1. 从 Excel 读取 FAQ
  2. 将 FAQ 问题转换为向量(使用 Ollama 的 Embedding 模型)
  3. 存入 FAISS 向量数据库
  4. 提供问答接口
    • 优先检索 FAQ(如果 FAQ 匹配度高,直接返回)
    • 匹配度低则让 Ollama 生成答案
  5. 启动 API 服务器,供前端调用

1. 安装必要的库

如果你还没有安装这些库,请运行:

pip install langchain langchain-community faiss-cpu ollama pandas openpyxl fastapi uvicorn

2. 代码:构建 RAG 方案

下面的代码会:

  • 从 Excel 读取 FAQ
  • 计算向量并存入 FAISS
  • 使用 Ollama 进行回答
  • 启动 API 服务器

我们将代码分成 两个部分

  1. build_vector_db.py 负责 一次性构建向量数据库(只在 FAQ 变化时运行)
  2. faq_rag_api.py 负责 实时查询 FAQ & 生成答案(只做检索 & 生成)
构建向量数据库 (build_vector_db.py)
from langchain_community.document_loaders import DataFrameLoader
from langchain_ollama import OllamaEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_core.documents import Document  # 确保 FAQ “答案”存入 metadata
import pandas as pd

file_path = "客服问答素材.xlsx"
df = pd.read_excel(file_path)

# 重新组织数据,确保 "答案" 存入 metadata
df = df.rename(columns={"问题": "question", "答案": "answer"}).dropna()
documents = [Document(page_content=row["question"], metadata={"answer": row["answer"]}) for _, row in df.iterrows()]

# 计算 FAQ 问题的向量(Embedding)
MODEL_NAME = "qwen2.5:0.5b"
embedding_model = OllamaEmbeddings(model=MODEL_NAME)
vector_store = FAISS.from_documents(documents, embedding_model)

# 存储向量数据库
vector_store.save_local("faq_index")
print("✅ FAQ 向量数据库构建完成!")

Excel数据如下

问题 答案
小红书分享活动什么时候开始?可以参与几次? 2025年3月11日-3月17日10:00:00,本活动每人、每个平台的账号仅能参加1次,如使用多个京东账号上传同一篇笔记,系统将自动判定参加无效。
笔记内容方向有范围吗? 方向①已在京东享受国补的朋友,发笔记分享3C数码、家电家居等购物体验和攻略,内容体现不同平台对比后,京东价格更优、服务更好的笔记更佳。方向②把京东国补的好消息分享给亲朋好友,号召大家一起参与领补贴。
小红书分享活动内容有要求带的话题吗?粉丝量有要求吗? 带上双话题#京东国补 #领国补就上京东。本次活动要求用户本人的小红书账号粉丝量必须≥50,否则视为参加无效。
小红书分享活动笔记可以提交几次?可以修改吗? 本次活动每位用户仅能参加1次,(上传后不可修改内容,请确认信息准确后再提交噢),每篇笔记限领1次。请您提交前认真核对信息,避免影响京豆奖励发放,感谢您的理解和支持。
奖励什么时候发?/什么时候发放京豆?/在哪里查看? 京豆奖励非实时发放。经系统审核后,奖励预计在2025年3月25日当天24点前由系统自动发放,具体时间以到账为准;您可在京东APP-我的-京豆-京豆收支明细中查看(京豆有效期为180天),京豆数量有限,送完即止。

 实时查询 FAQ & 生成答案(faq_rag_api.py) 
from fastapi import FastAPI
from langchain_community.vectorstores import FAISS
from langchain.chains import RetrievalQA
from langchain_community.llms import Ollama
from langchain_ollama import OllamaEmbeddings
from langchain_core.prompts import PromptTemplate

app = FastAPI()

# 1. 加载 FAQ 向量数据库
MODEL_NAME = "qwen2.5:0.5b"
embedding_model = OllamaEmbeddings(model=MODEL_NAME)
vector_store = FAISS.load_local("faq_index", embedding_model, allow_dangerous_deserialization=True)

# 2. 修改检索器,返回 metadata["answer"],并筛选匹配度
# retriever = vector_store.as_retriever(search_kwargs={"k": 3})  # 取最相关的 3 个 FAQ

def custom_retriever(query):
    """ 遍历所有匹配的 FAQ,找到最佳答案 """
    #docs = retriever.get_relevant_documents(query)
    docs_with_scores = vector_store.similarity_search_with_relevance_scores(query, k=1)  # 获取 FAQ 及相似度分数
    if docs_with_scores:
        best_doc, best_score = docs_with_scores[0]  # LangChain 自动返回匹配度最高的 FAQ
        # 设定匹配度阈值,防止错误 FAQ
        if best_score >= 0.7:
            return best_doc.metadata["answer"]

    return None  # 没有合适的 FAQ,交给大模型生成


# 3. 修改问答逻辑
@app.post("/chat")
def chat(request: dict):
    """ 处理用户提问,返回 FAQ 或 Ollama 生成的答案 """
    faq_answer = custom_retriever(request["query"])
    
    if faq_answer:
        return {"answer": faq_answer}  # 直接返回 FAQ 的“答案”

    # 如果 FAQ 里没有匹配的,就让 Ollama 生成
    llm = Ollama(model=MODEL_NAME)
    response = llm.invoke(request["query"])
    return {"answer": response}

# 运行 API 服务器:
# uvicorn faq_rag_api:app --host 0.0.0.0 --port 8000

3. 启动 API 服务器

uvicorn faq_rag:app --host 0.0.0.0 --port 8000

然后,你可以用 前端Postman 进行测试:

curl -X POST "http://localhost:8000/chat" -H "Content-Type: application/json" -d '{"query": "如何修改密码?"}'

它会:

  • 如果 FAQ 里有这个问题,返回 FAQ 里的标准答案
  • 如果 FAQ 里没有匹配项,让 Ollama 生成答案

4. 让前端连接 API

如果你有 网页客服前端,可以用 JavaScript 调用:

async function askQuestion() {
    let query = document.getElementById("question").value;
    let response = await fetch("http://localhost:8000/chat", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ query })
    });
    let data = await response.json();
    document.getElementById("answer").innerText = data.answer;
}

5. 可选:Docker 部署

你可以用 Docker 容器化 这个 API:

创建 Dockerfile
FROM python:3.9
WORKDIR /app
COPY . /app
RUN pip install -r requirements.txt
CMD ["uvicorn", "faq_rag:app", "--host", "0.0.0.0", "--port", "8000"]

然后:

docker build -t faq-chatbot .
docker run -p 8000:8000 faq-chatbot

✅ 总结

功能 实现方式
读取 FAQ 数据 直接从 Excel (xlsx) 读取
存储 FAQ 问题的向量 FAISS 进行检索
大模型问答 Ollama (Qwen-7B)
API 提供服务 FastAPI
可接入 Web 客服系统 JavaScript 调用 API
支持 Docker 部署

这样,你的 AI 客服 RAG 系统就搭建好了!

  • 优先检索 FAQ,减少 LLM 生成成本
  • 超出 FAQ 问题才让 Ollama 生成
  • 支持本地运行,无需云 API 费用
  • 前端可调用 API,无缝集成 Web 客服

你可能感兴趣的:(python,开发语言)