
在信息爆炸的时代,企业内部的文档、规范、技术手册和项目经验往往散落在不同系统,形成“数据孤岛”。如何让AI理解并利用这些非结构化知识,提供准确、可溯源的问答服务,已成为技术团队提效的关键突破口。本文将带领你零基础掌握新一代AI工具链——以 LangChain 为编排框架,Chroma/FAISS 为向量检索底座,GPT-4 为生成核心,搭建一套生产可用的知识库问答系统。我们不仅会深入检索增强生成(RAG)的技术细节,还会探讨性能调优、评估方法和工程落地要点,让你从“会用”到“精通”。
面对企业私有数据,常见两条路:微调(Fine-tuning) 和 检索增强生成(RAG)。
本文聚焦 RAG 架构,采用 LangChain 作为胶水层,Chroma 作为轻量向量库,OpenAI GPT-4 作为生成模型(亦可替换为开源模型,如 Llama 3)。
┌─────────────────┐
│ 用户提问 │
└────────┬────────┘
▼
┌─────────────────────────────────────┐
│ LangChain 检索链 (RetrievalQA) │
│ ┌────────────────────────────┐ │
│ │ 1. 文本嵌入 (Embedding) │ │
│ │ 2. 向量相似性检索 (ANN) │ │
│ │ 3. 上下文压缩 / 重排序 │ │
│ └────────────────────────────┘ │
└────────┬────────────────────────────┘
▼
┌─────────────────────────────────────┐
│ 向量数据库 (Chroma / FAISS) │
│ 索引:文档片段 + 向量 │
└────────┬────────────────────────────┘
▼
┌─────────────────────────────────────┐
│ LLM 生成 (GPT-4) │
│ 输入:Prompt + 检索到的文档片段 │
│ 输出:答案 + 引用 │
└─────────────────────────────────────┘核心流程:
推荐 Python 3.10+,创建虚拟环境:
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate安装核心依赖(新一代AI工具的标准组合):
pip install langchain langchain-community chromadb openai tiktoken pypdf python-docx如果需要本地 embedding 模型(如 HuggingFace),可加装 sentence-transformers,但本文以 OpenAI text-embedding-ada-002 为例(便宜且效果稳定)。
LangChain 提供丰富的 DocumentLoader:
from langchain_community.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader
# 加载 PDF
pdf_loader = PyPDFLoader("docs/technical_manual.pdf")
pdf_docs = pdf_loader.load()
# 加载 Word
docx_loader = Docx2txtLoader("docs/design_spec.docx")
docx_docs = docx_loader.load()
# 合并
documents = pdf_docs + docx_docs分割粒度直接影响检索精度。过短则上下文不足,过长则噪声多。常用 RecursiveCharacterTextSplitter,按段落、句子、字符层级递归切分:
from langchain.text_splitter import RecursiveCharacterTextSplitter
splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块最大字符数
chunk_overlap=50, # 重叠长度,保持语义连贯
separators=["\n\n", "\n", "。", "!", "?", " ", ""]
)
chunks = splitter.split_documents(documents)
print(f"共生成 {len(chunks)} 个片段")调优建议:
chunk_size(如 800),保留更多上下文。from langchain_openai import OpenAIEmbeddings
embeddings = OpenAIEmbeddings(
model="text-embedding-ada-002",
openai_api_key="your-api-key"
)from langchain_community.vectorstores import Chroma
vectorstore = Chroma.from_documents(
documents=chunks,
embedding=embeddings,
persist_directory="./chroma_db" # 持久化路径
)
# 持久化保存
vectorstore.persist()后续加载已有库:
vectorstore = Chroma(
persist_directory="./chroma_db",
embedding_function=embeddings
)基础检索采用余弦相似度,返回 Top-K:
retriever = vectorstore.as_retriever(
search_type="similarity",
search_kwargs={"k": 4}
)进阶检索技巧:
MultiQueryRetriever)。from langchain_openai import ChatOpenAI
from langchain.chains import RetrievalQA
llm = ChatOpenAI(
model="gpt-4-turbo",
temperature=0.2,
openai_api_key="your-api-key"
)
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff", # 将全部检索片段一次性放入上下文
retriever=retriever,
return_source_documents=True # 返回引用
)
query = "如何配置服务的超时参数?"
result = qa_chain.invoke({"query": query})
print("答案:", result["result"])
print("来源:", result["source_documents"])chain_type 可选:
stuff:适合片段少且短的情况(简单)。map_reduce:对每个片段单独生成答案再汇总(可处理长文档)。refine:迭代优化答案。map_rerank:先让模型对片段打分,再选最佳。对于企业场景,建议 stuff + 合理 Top-K 兼顾速度与质量。
实际业务需要多轮对话,需维护对话历史。使用 ConversationalRetrievalChain:
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
memory = ConversationBufferMemory(
memory_key="chat_history",
return_messages=True,
output_key="answer"
)
conv_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
return_source_documents=True
)
# 第一轮
response = conv_chain.invoke({"question": "什么是RAG?"})
print(response["answer"])
# 第二轮(带上下文)
response2 = conv_chain.invoke({"question": "它和微调比有什么优势?"})
print(response2["answer"])注意:ConversationBufferMemory 会保留所有历史,可改用 ConversationSummaryMemory 压缩历史,防止 token 超限。
默认 Prompt 可能过于通用,定制模板可引导模型格式、语气和引用格式:
from langchain.prompts import PromptTemplate
template = """
你是一个专业的技术顾问。请根据以下“上下文”片段回答用户的问题。
如果无法从上下文中找到答案,请明确说“根据现有资料无法回答”。
请在回答末尾列出所引用的文档来源(文件名和页码)。
上下文:
{context}
问题:{question}
回答:
"""
prompt = PromptTemplate(template=template, input_variables=["context", "question"])然后在构建链时传入:
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True,
chain_type_kwargs={"prompt": prompt}
)检索到的片段可能包含冗余或不相关内容。可使用 ContextualCompressionRetriever 对片段进行重排或过滤:
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainFilter
compressor = LLMChainFilter.from_llm(llm) # 让LLM判断哪些片段相关
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=retriever
)
# 替换原有检索器
qa_chain.retriever = compression_retriever更高效的做法是使用 重排序模型(如 Cohere Rerank),在向量检索后进行二次排序,显著提升精度。
示例:使用 FAISS 本地存储
from langchain_community.vectorstores import FAISS
vectorstore = FAISS.from_documents(documents, embeddings)
vectorstore.save_local("faiss_index")
# 加载
vectorstore = FAISS.load_local("faiss_index", embeddings, allow_dangerous_deserialization=True)对于高频问题,可引入 Redis 缓存答案,减少 LLM 调用成本。
import hashlib
import redis
cache = redis.Redis(host='localhost', port=6379, db=0)
def cached_query(question):
key = hashlib.md5(question.encode()).hexdigest()
cached = cache.get(key)
if cached:
return cached.decode()
answer = qa_chain.invoke({"query": question})["result"]
cache.setex(key, 3600, answer) # 缓存1小时
return answerRecall@K、MRR 评估检索器效果(可人工标注测试集)。RAGAS 框架(开源)自动化评估 Faithfulness、Answer Relevance、Context Relevance。安装 RAGAS:
pip install ragas简单评估示例:
from ragas.metrics import faithfulness, answer_relevancy
from ragas import evaluate
# 准备测试数据(包含 question, answer, contexts)
# 参考 ragas 官方文档使用 FastAPI 提供 RESTful API:
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
app = FastAPI()
class Query(BaseModel):
question: str
session_id: str = None
@app.post("/ask")
async def ask(query: Query):
# 根据 session_id 管理不同 memory(可使用字典或 Redis)
result = qa_chain.invoke({"question": query.question})
return {"answer": result["result"], "sources": [doc.metadata for doc in result["source_documents"]]}编写 Dockerfile,使用 gunicorn + uvicorn 启动多 worker。结合 K8s 可实现水平扩展。注意:embedding 和 LLM 调用是 I/O 密集型,可适当提高 worker 数。
记录每次请求的耗时、token 消耗、检索片段,便于优化和成本核算。使用 Prometheus + Grafana 收集指标。
本文完整展示了基于 LangChain 和 GPT-4 构建企业知识库问答系统的技术路径,从文档预处理、向量检索到 Prompt 优化、服务部署,各环节均给出代码实例和调优建议。RAG 架构凭借其灵活性、低成本更新和可解释性,正成为企业 AI 落地的首选范式,而 LangChain + GPT-4 + 向量数据库 正是当下最具代表性的新一代AI工具组合。
未来演进方向:
掌握这些技能,你不仅能快速搭建 MVP,更能深入调优使其达到生产级标准。希望本文能为你的技术实践提供切实帮助,欢迎在思否社区交流讨论!
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。