前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >用 LangChain 构建文档问答助手

用 LangChain 构建文档问答助手

原创
作者头像
IT蜗壳-Tango
发布于 2025-04-09 14:40:43
发布于 2025-04-09 14:40:43
20500
代码可运行
举报
文章被收录于专栏:机器学习机器学习
运行总次数:0
代码可运行

一、项目背景与目标

随着大语言模型(LLM)的广泛应用,越来越多企业和个人希望利用它来实现“基于文档的智能问答”功能。例如:

  • 企业内部员工通过上传手册、政策文档后,就可以直接用自然语言提问,系统智能返回答案。
  • 教育场景中,学生上传课件后提出问题,系统能够快速根据内容答疑。
  • 客服场景中,将产品说明书上传后,AI 即可作为问答机器人服务用户。

**传统 LLM 模型并不能直接处理本地文档知识。**这时候就需要用到一种重要技术——RAG(Retrieval-Augmented Generation,检索增强生成)

本项目就基于该原理,借助 LangChain 框架 + 向量数据库(Chroma)+ OpenAI/GPT 构建一个完整的文档问答助手。


二、项目技术栈

组件

说明

LangChain

框架核心,负责构建 Prompt、LLM、Chain 等模块

OpenAI GPT

用于生成回答的语言模型(也可替换为其他支持 Chat 接口的模型)

Chroma

本地向量数据库,用于文档内容向量化与查询

FAISS / SQLite(可选)

替代 Chroma 的向量库(本文以 Chroma 为主)

SentenceTransformers / OpenAI Embedding

将文本转换为向量的模型

Gradio / Streamlit(可选)

构建交互界面用于问答体验

Jupyter Notebook / Python 脚本

开发测试工具


三、项目核心流程

下图展示了文档问答助手的核心执行流程:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
用户输入问题
    ↓
LangChain 调用向量数据库
    ↓
根据 Embedding 查找相关内容
    ↓
构建带上下文的 Prompt
    ↓
传入 GPTLLM 获取回答
    ↓
输出最终结果

这一过程涉及 3 个核心模块:

  1. 文档预处理与入库(Embedding)
  2. 文档检索(Retriever)
  3. 问答链构建(RetrievalQA)

四、环境准备与依赖安装

先安装所需依赖:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install langchain openai chromadb tiktoken
pip install unstructured  # 用于文档加载(支持 PDF、txt、md)

若你使用 HuggingFace 本地模型:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pip install sentence-transformers

五、项目实战步骤

我们将以 example.txt 为例,构建一个本地文档问答助手。


第一步:设置 OpenAI API 密钥

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
os.environ["OPENAI_API_KEY"] = "你的API密钥"

你也可以通过 .env 或配置文件管理。


第二步:加载文档

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.document_loaders import TextLoader

loader = TextLoader("example.txt", encoding="utf-8")
documents = loader.load()
print(f"文档数量:{len(documents)}")

若是 PDF 等文档,可使用:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.document_loaders import PyPDFLoader
loader = PyPDFLoader("example.pdf")

第三步:切分文档

长文档必须分块,否则 Embedding 会失效。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.text_splitter import CharacterTextSplitter

text_splitter = CharacterTextSplitter(
    separator="\n",
    chunk_size=500,
    chunk_overlap=50
)
docs = text_splitter.split_documents(documents)

建议:

  • chunk_size 控制每块 token 数
  • chunk_overlap 保证上下文连续性

第四步:生成文本向量(Embedding)

选择一个嵌入模型:

使用 OpenAI Embedding(推荐):
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.embeddings import OpenAIEmbeddings

embedding = OpenAIEmbeddings()
使用本地模型(如 all-MiniLM):
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.embeddings import HuggingFaceEmbeddings

embedding = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")

第五步:存入向量数据库 Chroma

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.vectorstores import Chroma

db = Chroma.from_documents(docs, embedding, persist_directory="db")
db.persist()  # 持久化保存

之后可通过 Chroma(persist_directory="db", embedding=embedding) 加载已存库。


第六步:构建 RetrievalQA 问答链

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA

llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")

retriever = db.as_retriever(search_kwargs={"k": 3})

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    chain_type="stuff",
    retriever=retriever,
    return_source_documents=True
)

chain_type 可选:

  • stuff: 把所有检索结果直接拼接
  • map_reduce: 分块处理后汇总(慢)
  • refine: 逐步更新回答

第七步:开始问答!

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
query = "这个文档讲了什么?"
result = qa_chain(query)

print("答案:", result['result'])

for i, doc in enumerate(result['source_documents']):
    print(f"\n来源片段{i+1}:\n{doc.page_content}")

六、完整代码汇总(文档问答助手)

以下是完整的 Python 脚本版本:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import os
from langchain.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import Chroma
from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA

# 设置密钥
os.environ["OPENAI_API_KEY"] = "你的API密钥"

# 1. 加载文档
loader = TextLoader("example.txt", encoding="utf-8")
documents = loader.load()

# 2. 分割文档
text_splitter = CharacterTextSplitter(
    separator="\n", chunk_size=500, chunk_overlap=50
)
docs = text_splitter.split_documents(documents)

# 3. 生成向量
embedding = OpenAIEmbeddings()

# 4. 存入向量数据库
db = Chroma.from_documents(docs, embedding, persist_directory="db")
db.persist()

# 5. 构建问答链
llm = ChatOpenAI(temperature=0, model_name="gpt-3.5-turbo")
retriever = db.as_retriever(search_kwargs={"k": 3})
qa_chain = RetrievalQA.from_chain_type(
    llm=llm, chain_type="stuff", retriever=retriever, return_source_documents=True
)

# 6. 提问
query = input("请输入你的问题:")
result = qa_chain(query)
print("回答:", result["result"])

七、扩展建议

✅ 构建网页问答界面(使用 Gradio)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import gradio as gr

def chat_fn(question):
    result = qa_chain(question)
    return result["result"]

iface = gr.Interface(fn=chat_fn, inputs="text", outputs="text")
iface.launch()

✅ 支持多文档、多格式上传

  • 支持 Word、PDF、Markdown、HTML 等格式
  • 加载器如 UnstructuredLoader 可自动识别多种文档格式
  • 文件上传功能结合前端使用 Flask 或 Streamlit 构建即可

✅ 替换为本地大模型

  • 使用 llama-cpp, ollama, Transformers 作为 LLM 接入 LangChain
  • Embedding 可使用 HuggingFaceEmbeddings
  • 实现企业内网环境下的闭环问答系统

✅ 多轮对话 + Memory 模块集成

使用 ConversationBufferMemory 保持上下文问答:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory()
qa_chain.memory = memory

八、项目总结

本文带你从零搭建了一个基于 LangChain 的“文档问答助手”,核心技术包括文档加载、文本分块、嵌入向量化、向量数据库检索、结合 LLM 的生成回答。

这套架构能广泛应用在以下场景:

  • 内部知识库问答系统
  • 企业政策/合同文档解析系统
  • 教育领域讲义辅助问答
  • 客服文档机器人

九、下一步学习建议

  1. 深入理解 Prompt 构建技巧
  2. 学习 Agent 工具调用(如结合搜索、数据库查询)
  3. 尝试结合多文档、多模型构建多轮问答系统
  4. 用 Docker 部署服务或 API 化封装调用

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、项目背景与目标
  • 二、项目技术栈
  • 三、项目核心流程
  • 四、环境准备与依赖安装
  • 五、项目实战步骤
    • 第一步:设置 OpenAI API 密钥
    • 第二步:加载文档
    • 第三步:切分文档
    • 第四步:生成文本向量(Embedding)
      • 使用 OpenAI Embedding(推荐):
      • 使用本地模型(如 all-MiniLM):
    • 第五步:存入向量数据库 Chroma
    • 第六步:构建 RetrievalQA 问答链
    • 第七步:开始问答!
  • 六、完整代码汇总(文档问答助手)
  • 七、扩展建议
    • ✅ 构建网页问答界面(使用 Gradio)
    • ✅ 支持多文档、多格式上传
    • ✅ 替换为本地大模型
    • ✅ 多轮对话 + Memory 模块集成
  • 八、项目总结
  • 九、下一步学习建议
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档