Skip to content

物流行业信息咨询问答系统

目录

  1. 背景介绍
  2. 项目基本原理
  3. 项目流程
  4. 环境配置
  5. 代码实现

背景介绍

2023 年以来,随着 ChatGPT 的火爆,使得 LLM 成为研究和应用的热点,但是市面上大部分 LLM 都存在一个共同的问题:模型都是基于过去的经验数据进行训练完成,无法获取最新的知识,以及各企业私有的知识。因此很多企业为了处理私有的知识,主要借助一下两种手段来实现:

  • 01 利用企业私有知识,基于开源大模型进行微调

  • 02 基于 LangChain 集成向量数据库以及 LLM 搭建本地知识库的问答(RAG)

本次项目以"某物流行业"为例,基于物流信息构建本地知识库,测试问答效果。

注意:除物流场景外,使用者可以自由切换其他行业类型知识,实现本地知识库问答的效果。

项目原理

原理图

原理描述:

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

主要功能

  1. 基于本地知识库的问答

    系统可以根据用户的提问,在本地的知识库中进行搜索,并返回相关的答案

  2. 多模型支持

    项目支持使用不同的语言模型,可以根据需求选择合适的模型进行使用

  3. 离线私有化

    可以将该问答系统部署在本地环境中,确保数据的安全性和隐私性

项目流程

环境配置

  1. 查看 python 的版本

    确保你的机器安装了

    Python3.8 - Python3.12(推荐)

  2. 安装依赖

    shell
    pip install langchain
    pip install langchain_ollama
    pip install faiss-cpu
  3. 模型下载

    如需在本地或离线环境下运行本项目,需要首先将项目所需的模型下载至本地。

    本项目中默认使用 ollama 平台,LLM 模型为 qwen3:1.7b ,Embedding 模型 nomic-embed-text

代码实现

构建 Faiss 索引

目的:构建向量库

1、导入必备的工具包

python
from langchain_community.document_loaders import UnstructuredFileLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS

2、定义 main() 方法

python
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.embeddings import HuggingFaceEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_ollama.embeddings import OllamaEmbeddings

from langchain_unstructured import UnstructuredLoader


def main():
    # 第一步:加载文档:
    loader = UnstructuredLoader('物流信息.txt')
    data = loader.load()
    # print(f'data-->{data}')

    # 第二步:切分文档
    text_split = RecursiveCharacterTextSplitter(chunk_size=128, chunk_overlap=4)
    split_data = text_split.split_documents(data)
    # print(f'split_data-->{split_data}')

    # 第三步:初始化 embedding 模型
    embeddings = OllamaEmbeddings(model="nomic-embed-text")

    # 第四步:将切分后的文档进行向量化,并且存储下来
    db = FAISS.from_documents(split_data, embeddings)
    db.save_local('./faiss/camp')

    return split_data


if __name__ == '__main__':
    main()

实现 QA 本地知识库问答

python
from langchain.prompts import PromptTemplate
from get_vector import *
from langchain_ollama.embeddings import OllamaEmbeddings
from langchain_deepseek import ChatDeepSeek
from langchain_community.llms import Ollama

from langchain_ollama import OllamaLLM

embeddings = OllamaEmbeddings(model="nomic-embed-text")

# 加载 FAISS 向量库
db = FAISS.load_local(r'faiss/camp', embeddings, allow_dangerous_deserialization=True)


def get_related_content(related_docs):
    related_content = []
    for doc in related_docs:
        related_content.append(doc.page_content.replace('\n\n', '\n'))
    return '\n'.join(related_content)


def define_prompt():
    question = '我买的商品 ABC123456 来自于哪个仓库,从哪出发的,预计什么到达'
    docs = db.similarity_search(question, k=1)
    # print(f'docs-->{docs}')
    related_docs = get_related_content(docs)

    # 构建模板
    PROMPT_TEMPLATE = """
           基于以下已知信息,简洁和专业的来回答用户的问题。不允许在答案中添加编造成分。
           已知内容:
           {context}
           问题:
           {question}"""
    prompt = PromptTemplate(input_variables=["context", "question"],
                            template=PROMPT_TEMPLATE)

    return prompt.format(context=related_docs,
                         question=question)


if __name__ == '__main__':
    # llm = ChatDeepSeek(model="deepseek-chat")
    llm = OllamaLLM(model="qwen3:1.7b")
    my_prompt = define_prompt()
    result = llm.invoke(my_prompt)
    print(f'result-->{result}')

3、结果展示

货物ABC123456的当前位置为上海分拨中心,预计将于2024年6月20日到达。运输方式由快运通负责,具体出发地及所属仓库信息未在现有资料中明确提及。