Python+AI 实战:搭建属于你的智能问答机器人

· Python全栈教程

如今人工智能技术不断普及,智能问答系统也成了知识整理、人机互动领域的重要应用,针对零基础开发者想要快速搭建专属问答机器人的需求,这篇文章借助Python工具库与开源AI模型,推出一套轻便、本地就能用的搭建方案,不用精通深度学习知识,也不用配备高端电脑,就能做出可以本地运行、支持自定义知识内容、不用花钱买API接口的问答机器人,这套方案既能当成个人知识整理助手、简单线上客服工具,也能作为AI实战入门的练习项目,上手难度低、实际用处也很大。

这篇文章会一步步讲解实操步骤,所有代码都能直接复制使用,全程拆解搭建步骤、细化每一处技术细节,帮助开发者弄懂系统底层的运行逻辑,真正把理论知识转化为实际操作,让新手快速学会AI问答机器人的基础搭建方法。

一、智能问答机器人核心原理

在动手写代码、搭建项目之前,我们先要弄懂系统底层的运行逻辑,不要只照搬代码却不懂背后原理,这篇文章搭建的问答机器人,核心用到RAG检索增强生成技术框架,和普通的大模型直接对话相比,这种框架有着回答准确度高、不会胡乱编造内容、知识内容能自由修改扩充三大优点,还能解决大模型乱答、知识内容过时等常见问题。

核心运行流程

  1. 离线索引构建阶段:把本地的PDF、Markdown、TXT各类文档拆分成小段文字,再通过语义转换模型把文字变成向量数据,存入专用的向量数据库,完成知识内容的语义分类整理。
  2. 在线问答推理阶段:接收用户提出的问题,把问题转换成对应向量,在向量数据库里找到匹配度最高的文字片段,再把找到的参考内容和问题一起传给大模型,让大模型根据已有知识给出准确回答。

技术栈选型(轻量化、开源免费、适配新手)

本次搭建用到的全部都是开源工具,不用申请云端API接口,也不用支付任何使用费用,所有数据和模型都存在本地电脑里,能充分保护数据隐私,也能自主掌控部署流程。

二、环境部署与依赖安装

先新建项目总文件夹,在文件夹里创建requirements.txt依赖文件,把下方需要安装的工具库写进文件里,统一安装能有效避免版本不兼容、依赖缺失等各类问题。

transformers>=4.35.0
sentence-transformers>=2.2.2
faiss-cpu>=1.7.4
langchain>=0.1.0
langchain-community>=0.0.10
torch>=2.0.0
accelerate>=0.25.0
pypdf>=3.17.0
python-dotenv>=1.0.0

打开电脑终端,切换到项目文件夹路径,运行下方批量安装命令,使用国内镜像源能大幅加快下载速度。

pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

小贴士:如果电脑配有NVIDIA独立显卡,可以把faiss-cpu换成faiss-gpu版本,借助显卡算力进一步提升向量查找的速度。

三、核心模块开发与代码实现

这个项目采用分模块开发的方式,整体分成知识整理、向量查找、答案生成三大核心部分,各个部分功能独立、逻辑清楚,方便后续添加新功能、修改原有代码。

模块一:本地知识库构建模块

新建knowledge_base.py文件,这个部分主要实现本地多种格式文档的读取、文字智能拆分功能,支持TXT、Markdown、PDF格式文件的解析,具体代码如下所示。

import os
from typing import List, Dict

class KnowledgeBase:
    """本地知识库管理类,实现文档加载与文本分块功能"""
    def __init__(self, chunk_size=500, chunk_overlap=50):
        # 定义文本切块长度、块间重叠长度
        self.chunk_size = chunk_size
        self.chunk_overlap = chunk_overlap
        self.documents = []

    # Markdown格式文档加载
    def load_markdown(self, file_path):
        with open(file_path, 'r', encoding='utf-8') as f:
            return f.read()

    # 文本切块处理,保障文本语义完整性
    def split_text(self, text: str, source="") -> List[Dict]:
        chunks = []
        start = 0
        text_len = len(text)
        while start < text_len:
            end = start + self.chunk_size
            # 优化切分节点,优先在语句结束位置切割
            if end < text_len:
                for sep in ['。', '!', '?', '\n']:
                    pos = text.rfind(sep, start, end)
                    if pos != -1:
                        end = pos + 1
                        break
            chunk = {
                "content": text[start:end].strip(),
                "metadata": {"source": source}
            }
            chunks.append(chunk)
            start = end - self.chunk_overlap
        return chunks

    # 批量加载指定目录下的知识库文件
    def load_dir(self, dir_path="./knowledge"):
        os.makedirs(dir_path, exist_ok=True)
        for file in os.listdir(dir_path):
            file_path = os.path.join(dir_path, file)
            if file.endswith((".md", ".txt")):
                text = self.load_markdown(file_path)
                chunks = self.split_text(text, source=file)
                self.documents.extend(chunks)
        return self.documents

模块二:向量存储与检索模块

新建vector_store.py文件,这个部分负责把文字转换成向量、搭建FAISS查找索引、相似度查找等工作,实现用户问题和知识库内容的精准配对,代码如下所示。

import faiss
import numpy as np
from sentence_transformers import SentenceTransformer

class VectorStore:
    """向量数据库操作类,实现语义检索与索引管理"""
    def __init__(self):
        # 加载轻量化语义嵌入模型
        self.embed_model = SentenceTransformer('all-MiniLM-L6-v2')
        self.index = None
        self.documents = []

    # 构建向量检索索引
    def build_index(self, documents):
        self.documents = documents
        # 将文本片段转化为向量数据
        texts = [doc["content"] for doc in documents]
        embeddings = self.embed_model.encode(texts)
        # 初始化FAISS索引并添加向量数据
        self.index = faiss.IndexFlatL2(embeddings.shape[1])
        self.index.add(np.array(embeddings).astype('float32'))

    # 相似度检索,返回匹配度靠前的文本结果
    def search(self, query, top_k=3):
        query_emb = self.embed_model.encode([query])
        distances, indices = self.index.search(np.array(query_emb).astype('float32'), top_k)
        results = []
        for i, idx in enumerate(indices[0]):
            if idx < len(self.documents):
                doc = self.documents[idx].copy()
                doc["score"] = float(1 - distances[0][i])
                results.append(doc)
        return results

模块三:大模型答案生成模块

新建llm_model.py文件,这个部分实现开源大模型加载、指令模板搭建、答案推导生成的功能,根据查找到的知识库内容生成合规回答,避免模型胡乱编造内容,具体实现代码如下。

import torch
from transformers import AutoTokenizer, AutoModelForCausalLM

class LLMGenerator:
    """轻量级大模型推理生成类"""
    def __init__(self):
        self.model_name = "microsoft/Phi-3-mini-4k-instruct"
        self.device = "cuda" if torch.cuda.is_available() else "cpu"
        # 加载模型与分词器
        self.tokenizer = AutoTokenizer.from_pretrained(self.model_name, trust_remote_code=True)
        self.model = AutoModelForCausalLM.from_pretrained(
            self.model_name,
            torch_dtype=torch.float16 if self.device == "cuda" else torch.float32,
            device_map="auto",
            trust_remote_code=True
        )

    # 结合检索内容生成最终答案
    def generate_answer(self, query, context_docs):
        # 拼接检索得到的参考文本
        context = "\n".join([doc["content"] for doc in context_docs])
        # 构建约束性提示词,限定模型依托知识库作答
        prompt = f"""你是专属智能问答助手,请严格依据下方参考信息回答用户问题,不要编造答案。
参考信息:
{context}

用户问题:{query}
请给出清晰、准确、简洁的回答:"""

        # 模型推理生成答案
        inputs = self.tokenizer(prompt, return_tensors="pt", truncation=True, max_length=2048).to(self.device)
        with torch.no_grad():
            outputs = self.model.generate(
                **inputs,
                max_new_tokens=300,
                temperature=0.7,
                do_sample=True,
                repetition_penalty=1.1
            )
        answer = self.tokenizer.decode(outputs[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
        return answer

模块四:系统主入口模块

新建main.py文件,作为整个系统的运行入口,整合三大核心模块,让各个组件相互配合实现交互式问答,代码如下所示。

from knowledge_base import KnowledgeBase
from vector_store import VectorStore
from llm_model import LLMGenerator

class QARobot:
    """智能问答机器人主控类"""
    def __init__(self):
        print("正在初始化知识库...")
        self.kb = KnowledgeBase()
        self.documents = self.kb.load_dir()

        print("正在构建向量索引...")
        self.vector_store = VectorStore()
        self.vector_store.build_index(self.documents)

        print("正在加载AI模型...")
        self.llm = LLMGenerator()
        print("✅ 机器人初始化完成,开始提问吧!")

    # 核心问答处理方法
    def ask_question(self, question):
        # 检索知识库相关内容
        related_docs = self.vector_store.search(question)
        if not related_docs:
            return "抱歉,知识库中暂无相关信息,无法回答~"
        # 调用大模型生成应答内容
        answer = self.llm.generate_answer(question, related_docs)
        return answer

if __name__ == "__main__":
    # 初始化问答机器人
    robot = QARobot()
    # 启动交互式问答
    while True:
        user_input = input("\n请输入你的问题(输入exit退出):")
        if user_input.lower() in ["exit", "退出"]:
            print("再见!")
            break
        if not user_input:
            continue
        # 获取并输出机器人应答结果
        res = robot.ask_question(user_input)
        print(f"\n🤖 机器人回答:{res}")

四、系统运行与效果测试

4.1 知识库准备

在项目总文件夹里创建knowledge文件夹,把个人笔记、操作指南、专业资料等TXT、Markdown格式的文件放进这个文件夹,机器人就会根据文件夹里的文档内容完成问答操作。

4.2 系统启动

在终端中运行下方指令,即可启动智能问答机器人。

python main.py

首次运行系统会自动下载对应的AI模型,需要耐心等待下载完成,后续启动会直接调用本地已下载好的模型,启动速度会快很多。

4.3 测试效果展示

请输入你的问题(输入exit退出):员工忘记密码怎么重置?
🤖 机器人回答:员工忘记密码可前往登录页点击忘记密码,输入邮箱接收重置链接,按要求设置包含大小写、数字、特殊字符的新密码即可,遇到问题可联系IT热线。

经过实际测试,这套系统能够精准提取知识库中的有用信息,生成的回答符合实际内容,不会编造信息、也不会出现逻辑错误,完全可以满足日常知识问答、信息查找的使用需求。

五、系统进阶优化方案

  1. 指令模板优化:修改llm_model.py里的指令模板,调整回答的语气和内容详略,让回答更专业、更容易读懂。
  2. 大模型更换:可以换成通义千问、Llama2等其他开源大模型,根据使用场景选择不同大小的模型,进一步提升回答质量。
  3. 搭建可视化页面:接入Streamlit、Flask等网页框架,做出网页版操作界面,让系统使用起来更简单方便。
  4. 扩充文档格式:添加Word、Excel等格式文档的读取功能,进一步扩大知识库支持的文件类型。
  5. 加快运行速度:开启模型量化功能,减少电脑资源占用,让配置低的电脑也能快速运行。

六、总结与展望

这篇文章借助Python和开源AI技术,完整做出了一款能本地运行、数据自主管控的智能问答机器人,全程用开源工具完成开发,有着不花钱、易搭建、可扩充的核心优点,整套方案步骤清楚、代码完整,既适合AI新手学习RAG框架的基础原理,也能直接修改成各类简易问答系统使用。

和调用云端API接口的方式相比,本地部署不仅能省下使用成本,还能更好地保护数据隐私,同时也能让开发者深入掌握AI项目的搭建流程,为后续开发更复杂的AI项目打下扎实的基础。

后续可以根据实际使用需求,不断优化系统运行速度、扩充更多功能,让智能问答机器人更好地应用在知识整理、客户服务、内部培训等场景中,这篇文章的方案给简易AI实战提供了可行的方法,后续也会继续研究Python+AI技术的更多应用场景,分享更多实用的技术内容。