文章目录
Prompt实战之构建语义搜索引擎 6)问答系统构建与响应生成(QA Chain)
在前面几章中,我们完成了文档加载、分割、向量化、索引与检索。在这一章,我们将构建一个端到端的问答系统(Question-Answering Chain),它能够基于用户问题,从语料中找出相关信息,并生成流畅自然的回答。
6.1 问答系统的结构
一个典型的问答系统(Retrieval QA)的流程如下:
用户问题 → Retriever(文档检索) → LLM(答案生成)→ 回复用户
LangChain 中,我们可以使用 RetrievalQA
模块实现这一完整流程。
6.2 构建 QA Chain
基本示例
from langchain.chains import RetrievalQA
from langchain.chat_models import ChatOpenAI
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(temperature=0),
retriever=vectorstore.as_retriever(),
return_source_documents=True
)
提问并获得答案
query = "介绍一下图灵测试的基本原理。"
result = qa_chain(query)
print("答案:", result["result"])
6.3 可选参数说明
参数名 | 作用 |
---|---|
return_source_documents=True | 是否返回原始参考文档(调试/溯源) |
chain_type="stuff" | 如何组合文档(可选:stuff, map_reduce, refine 等) |
6.4 Chain 类型比较
类型 | 特点 | 适合场景 |
---|---|---|
stuff | 简单拼接全部文档给 LLM | 文档少、回答简洁场景 |
map_reduce | 每个文档单独回答,最后合并 | 大量文档、需要稳定答案 |
refine | 基于初始答案逐步优化 | 结构化问答、摘要类任务 |
✅ 建议从
stuff
开始,如果输出不理想再切换为高级类型。
6.5 自定义 Prompt 提升效果
你可以自定义提示模板来引导回答风格、输出格式等。
示例:限制回答字数
from langchain.prompts import PromptTemplate
prompt_template = PromptTemplate.from_template("""
你是一个专业中文学术助手。请基于以下内容简洁回答用户问题,控制在100字内。
上下文:
{context}
问题:
{question}
""")
qa_chain = RetrievalQA.from_chain_type(
llm=ChatOpenAI(temperature=0),
retriever=vectorstore.as_retriever(),
chain_type_kwargs={"prompt": prompt_template}
)
6.6 回答结果结构说明
一个典型的返回结果如下:
{
"result": "图灵测试是一种用于判断机器是否具有智能的方法...",
"source_documents": [Document(page_content="...", metadata={...}), ...]
}
你可以将 source_documents 渲染为参考文献、悬浮提示等,增强用户信任感。
6.7 问题优化(Query Refinement)
LangChain 还支持对用户输入的问题进行改写(Rephrasing),提升检索效果:
from langchain.chains import ConversationalRetrievalChain
qa = ConversationalRetrievalChain.from_llm(
llm=ChatOpenAI(),
retriever=vectorstore.as_retriever()
)
chat_history = []
query = "它是怎么工作的?"
result = qa({"question": query, "chat_history": chat_history})
chat_history.append((query, result["answer"]))
print(result["answer"])
6.8 本章小结
你已经完成了语义问答系统的最后一环:
- 利用检索器和 LLM 构建问答链(RetrievalQA);
- 理解不同的 Chain 类型与适用场景;
- 可以通过 Prompt 与 Chain 参数提升系统输出;
- 掌握上下文式问答(多轮 QA)基本技巧。
小贴士 💡
-
如果回答质量不稳定,可尝试:
- 减少检索的文档数量
- 使用 map_reduce 代替 stuff
- 使用更强大的 Embedding 模型
-
可在 UI 中展示参考片段,提升用户信任与可追溯性。
练习区 🛠️
- 构建一个 RetrievalQA Chain,回答“中国近代史的发展阶段”。
- 将 chain_type 切换为
"map_reduce"
,观察回答质量变化。 - 自定义 Prompt:要求答案以“首先、其次、最后”结构回答问题。
- 使用 ConversationalRetrievalChain 进行连续对话,记录 chat_history。