当前位置: 首页 > news >正文

《AI大模型应知应会100篇》第65篇:基于大模型的文档问答系统实现

第65篇:基于大模型的文档问答系统实现

📚 摘要:本文详解如何构建一个基于大语言模型(LLM)的文档问答系统,支持用户上传 PDF 或 Word 文档,并根据其内容进行智能问答。从文档解析、向量化、存储到检索与生成回答,手把手带你搭建完整流程。文末提供实战代码与部署指南,适合 AI 初中级开发者学习和参考。


在这里插入图片描述

一、系统架构设计概览

构建一个完整的文档问答系统,通常包括以下几个核心模块:

用户上传文档 → 文档解析 → 文本预处理 → 向量化 → 存储到向量数据库
→ 用户提问 → 检索相关段落 → 结合 LLM 生成答案 → 返回结果

我们将其拆解为五个主要步骤:

  1. 文档解析:将 PDF/Word 转换为纯文本;
  2. 文本分割与向量化:使用 LangChain 分割文本并用嵌入模型编码;
  3. 向量存储与检索:使用 Pinecone 存储向量并执行相似度搜索;
  4. 问答生成引擎:结合检索结果,调用大模型生成自然语言答案;
  5. 前后端整合:使用 FastAPI 构建后端接口 + Streamlit 实现前端交互。

二、文档预处理与向量化【实战部分】

1. 安装依赖

pip install PyPDF2 python-docx langchain openai sentence-transformers pinecone-client fastapi uvicorn streamlit

2. 解析 PDF 和 Word 文件

import PyPDF2
from docx import Documentdef read_pdf(file_path):with open(file_path, 'rb') as f:reader = PyPDF2.PdfReader(f)text = ''for page in reader.pages:text += page.extract_text()return textdef read_docx(file_path):doc = Document(file_path)full_text = [p.text for p in doc.paragraphs]return '\n'.join(full_text)

3. 使用 LangChain 进行文本分割

from langchain.text_splitter import RecursiveCharacterTextSplittertext_splitter = RecursiveCharacterTextSplitter(chunk_size=1000,chunk_overlap=100
)chunks = text_splitter.split_text(document_text)  # document_text 是上一步读取的文本

4. 使用 OpenAI 或 Sentence Transformers 生成嵌入

✅ OpenAI 嵌入方式(需 API Key)
from langchain.embeddings.openai import OpenAIEmbeddingsembeddings = OpenAIEmbeddings(openai_api_key="YOUR_OPENAI_API_KEY")
vectorized_chunks = embeddings.embed_documents(chunks)
✅ 本地 Sentence Transformer 嵌入方式(无需网络)
from sentence_transformers import SentenceTransformermodel = SentenceTransformer('all-MiniLM-L6-v2')
vectorized_chunks = model.encode(chunks)

三、向量存储与检索【实战部分】

我们以 Pinecone 为例来展示向量存储和检索过程。

1. 初始化 Pinecone

pip install pinecone-client
import pineconepinecone.init(api_key="YOUR_PINECONE_API_KEY", environment="us-west1-gcp")
index_name = "document-qa-index"if index_name not in pinecone.list_indexes():pinecone.create_index(name=index_name, dimension=1536)  # OpenAI 默认维度index = pinecone.Index(index_name)

2. 将向量写入 Pinecone

from uuid import uuid4vectors = [(str(uuid4()), vector, {"text": chunk}) for chunk, vector in zip(chunks, vectorized_chunks)]
index.upsert(vectors=vectors)

3. 执行语义检索(Top-K)

query = "什么是量子计算?"
query_vector = embeddings.embed_query(query)  # 如果是 OpenAI 嵌入
# query_vector = model.encode([query])[0]  # 如果是 Sentence Transformerresult = index.query(queries=[query_vector], top_k=3, include_metadata=True)
print(result)

输出示例:

{"matches": [{"id": "abc123","score": 0.89,"metadata": {"text": "量子计算是一种利用量子比特进行信息处理的技术..."}},...]
}

四、问答生成引擎【实战部分】

1. 使用 LangChain + OpenAI 生成答案

from langchain.chat_models import ChatOpenAI
from langchain.prompts import PromptTemplatellm = ChatOpenAI(model_name='gpt-3.5-turbo', openai_api_key="YOUR_OPENAI_API_KEY")prompt_template = """
你是一个基于以下上下文回答问题的助手。
请根据提供的上下文信息,给出简洁准确的回答。Context: {context}Question: {question}Answer:
"""prompt = PromptTemplate.from_template(prompt_template)# 整理检索结果中的 context
context = "\n".join([match['metadata']['text'] for match in result['matches']])
final_prompt = prompt.format(context=context, question=query)answer = llm.predict(final_prompt)
print(answer)

2. 多轮对话记忆机制(可选)

from langchain.memory import ConversationBufferMemorymemory = ConversationBufferMemory(memory_key="chat_history", input_key="question")
conversation = ConversationalRetrievalChain.from_llm(llm, retriever=vectorstore.as_retriever(), memory=memory)response = conversation({"question": "量子比特是什么?"})
print(response["answer"])

五、前后端整合与部署

1. 使用 FastAPI 构建后端服务

# app.py
from fastapi import FastAPI, UploadFile, File
from pydantic import BaseModel
import osapp = FastAPI()@app.post("/upload")
async def upload_file(file: UploadFile = File(...)):file_location = f"uploads/{file.filename}"with open(file_location, "wb+") as file_object:file_object.write(file.file.read())# 解析文档 + 向量化 + 存入 Pinecone 的逻辑return {"filename": file.filename, "status": "processed"}class QuestionRequest(BaseModel):question: str@app.post("/ask")
async def answer_question(req: QuestionRequest):# 调用检索 + 生成答案逻辑return {"answer": generated_answer}

启动服务:

uvicorn app:app --reload

访问 http://localhost:8000/docs 查看 API 接口文档。

2. 使用 Streamlit 构建前端界面

# frontend.py
import streamlit as st
import requestsst.title("文档问答系统")uploaded_file = st.file_uploader("上传 PDF 或 Word 文件", type=["pdf", "docx"])
if uploaded_file:files = {"file": uploaded_file.getvalue()}res = requests.post("http://localhost:8000/upload", files=files)st.success(res.json()["filename"] + " 已上传并处理完成!")question = st.text_input("请输入你的问题:")
if question:payload = {"question": question}res = requests.post("http://localhost:8000/ask", json=payload)st.write("回答:", res.json()["answer"])

运行前端:

streamlit run frontend.py

六、实战案例研究

案例一:企业内部知识库问答系统

  • 场景:员工上传公司制度、产品手册等文档,快速查找政策或技术细节;
  • 技术点:多文档上传、交叉检索、权限控制;
  • 扩展:集成 Slack / 钉钉机器人自动推送答案。

案例二:教育领域课程资料问答平台

  • 场景:学生上传讲义、笔记,提出课程相关问题,系统自动生成解答;
  • 技术点:OCR 支持扫描版 PDF、多语言识别、错题记录;
  • 扩展:支持视频字幕提取 + 知识图谱构建。

七、总结与扩展建议

当前系统优势:

  • 支持多种文档格式上传;
  • 基于语义检索 + 大模型生成,答案更准确;
  • 易于部署,前后端分离,便于扩展。

可扩展方向:

  1. 多文档交叉检索:允许多个文档同时参与检索,提升准确性;
  2. 多语言支持:使用 multilingual transformers 增加中文/日文/韩文等支持;
  3. OCR 集成:对扫描 PDF 使用 Tesseract OCR 提取文字;
  4. 知识图谱构建:将文档结构化为实体关系图,增强推理能力;
  5. 私有化部署:使用本地大模型(如 Qwen、ChatGLM)替代 OpenAI;
  6. 性能优化:使用 FAISS 替代 Pinecone 实现本地向量检索。

📌 附录:推荐工具与资源

功能推荐工具
文档解析PyPDF2, python-docx
文本分割LangChain
向量化OpenAI Embeddings, Sentence Transformers
向量数据库Pinecone, Milvus, FAISS
大模型问答OpenAI GPT, HuggingFace Transformers
后端框架FastAPI
前端界面Streamlit, React

📌 结语:本文从零开始讲解了如何构建一个完整的文档问答系统,涵盖数据处理、向量化、检索与生成等多个环节,并提供了实战代码与部署方案。希望你能通过本篇文章掌握这一关键技术,打造属于自己的智能问答助手!

如果你喜欢这篇文章,欢迎点赞、收藏、转发,也欢迎关注我的专栏《AI大模型应知应会100篇》持续更新中 👇


如有疑问或需要定制开发,请留言或私信我,我们将持续为你提供高质量的人工智能内容。

http://www.dtcms.com/a/194025.html

相关文章:

  • 一种应用非常广泛的开源RTOS(实时操作系统):nuttx
  • 【HTML 全栈进阶】从语义化到现代 Web 开发实战
  • DDD领域驱动介绍
  • C++ asio网络编程(7)增加发送队列实现全双工通信
  • 【研0学习计划表】
  • 图像分类实战:基于ResNet实现猫狗识别
  • MySQL的存储过程
  • 数学复习笔记 12
  • 深入浅出 MinIO:身份管理与权限配置实战 !
  • C#学习第23天:面向对象设计模式
  • SD2351核心板:开启AI视觉普惠化新时代
  • 涂色不踩雷:如何优雅解决 LeetCode 栅栏涂色问题
  • Room数据库
  • 筑牢信息安全防线:涉密计算机与互联网隔离的理论实践与风险防控
  • 【pbootcms】打开访问首页显示未检测到您服务器环境的sqlite3数据库拓展,请检查php.ini中是否已经开启该拓展
  • 现代计算机图形学Games101入门笔记(十二)
  • React中使用openLayer画地图
  • 拟合(最小二乘拟合)
  • React Flow 节点类型详解与实战:内置节点使用与自定义组件开发
  • 58. 区间和
  • 【GaussDB迁移攻略】DRS支持CDC,解决大规模数据迁移挑战
  • 【软件工程】符号执行与约束求解缺陷检测方法
  • 前端精度问题全解析:用“挖掘机”快速“填平精度坑”的完美解决方案
  • 深入探索:Core Web Vitals 进阶优化与新兴指标
  • AWS云入门宝典
  • 哈希表实现(1):
  • Spring Cloud:Gateway(统一服务入口)
  • R语言学习--Day03--数据清洗技巧
  • 【学习笔记】计算机操作系统(四)—— 存储器管理
  • 懒汉式单例模式的线程安全实现