摘要: 如何让大模型精准回答您公司的内部问题?答案是构建一个强大的AI知识库。本文将深入探讨当前最主流的模式——检索增强生成(RAG),并系统性地拆解其两大核心流水线:数据索引与检索生成。我们将通过一个完整的Python实战案例,手把手教您使用LangChain和ChromaDB向量数据库,将非结构化文档转化为一个可查询、可交互的智能知识库。
标签: RAG
, 检索增强生成
, 向量数据库
, LangChain
, ChromaDB
, 生成式AI
, 知识库
引言:从“通用大脑”到“企业专家”
在“启智未来”,我们的通用聊天机器人很受欢迎。但当员工问及“我们最新的‘凤凰计划’项目进展如何?”或者“A轮融资的法务文件在哪?”时,它就哑口无言了。因为它的大脑里,装的是整个互联网的通用知识,而不是我们公司内部的、私有的、最新的信息。
我们意识到,要让AI真正成为企业的生产力工具,就必须让它从一个“通用大脑”进化成一个“企业专家”。实现这一目标最流行、最高效的技术范式,就是检索增强生成 (Retrieval-Augmented Generation, RAG)。
这篇文章,就是我们团队从零开始,使用RAG和向量数据库,为“启智未来”构建企业级智能知识库的完整复盘。
Part 1: RAG,为大模型装上“外挂知识库”
大语言模型(LLM)本身像一个博学的、但不读报纸的老教授——知识渊博,但内容截止到他“毕业”的那天(即训练数据的截止日期),而且他不了解任何新生事物或内部秘密。
RAG的核心思想非常直观:当LLM遇到一个问题时,不让它直接凭记忆回答,而是先给它提供一本书(或几页相关的资料),让它“开卷考试”。
这个过程完美地解决了两大痛点:
- 知识时效性: 只要我们能更新我们的“书”(知识库),AI就能回答最新的问题。
- 减少幻觉: AI的回答不再是天马行空的“创作”,而是基于我们提供的、可验证的真实材料。
Mermaid 图解:RAG 的核心工作原理
graph TD
A[用户提问] --> B{RAG 系统};
B -- 1. 检索相关资料 --> C[企业知识库];
C -- 2. 返回相关文本块 --> B;
B -- 3. 将问题和资料打包 --> D{大语言模型 (LLM)};
D -- 4. 基于资料生成答案 --> B;
B -- 5. 返回精准答案 --> A;
Part 2: RAG 的双引擎:两大核心流水线
一个完整的RAG系统,由两条并行不悖的流水线构成。
流水线一:数据索引 (Indexing Pipeline) - 把大象装进冰箱
这条流水线的目标是将我们海量的、非结构化的文档(如PDF, Word, TXT),处理成AI能够快速理解和检索的格式。这通常是一个离线的、预处理的过程。
步骤 1: 加载与分块 (Load & Chunk)
我们不能把整篇几万字的文档直接丢给模型。我们需要将其切分成更小的、有意义的文本块(Chunks)。
- 为何分块?: 一来符合模型处理的上下文长度限制,二来可以更精确地定位到与问题最相关的具体段落。
- 策略: 可以按段落、按句子,或者使用更智能的、能理解语义边界的递归分块器。
步骤 2: 嵌入 (Embedding)
计算机不理解文字,只理解数字。Embedding(嵌入)就是调用一个专门的模型(如 text-embedding-ada-002
),将每个文本块都转换成一个由几百上千个数字组成的向量(Vector)。这个向量,就是该文本块在多维语义空间中的“数学坐标”。
步骤 3: 存储 (Store)
我们有了成千上万个文本块和它们对应的向量“坐标”,该如何高效存储呢?如果用传统数据库,进行一次相似度查询可能需要遍历所有数据,效率极低。
这时,向量数据库 (Vector Database) 就登场了。它使用特殊的索引算法(如HNSW),可以极速地在亿万级的向量中找到与给定向量“距离”最近的邻居。
主流向量数据库:
- 云服务: Azure AI Search, Pinecone
- 开源/本地部署: ChromaDB, Weaviate, Qdrant
流水线二:检索与生成 (Retrieval & Generation Pipeline) - 实时响应的智慧
这条流水线是实时的,在用户提出问题的瞬间被触发。
步骤 1: 用户问题向量化
当用户输入问题时,我们使用与索引时相同的Embedding模型,将问题也转换成一个向量。
步骤 2: 向量检索
我们拿着这个“问题向量”,去向量数据库中进行查询,要求它返回N个语义上最相似的文本块向量,以及它们对应的原始文本块。
步骤 3: 上下文增强与生成
我们将检索到的文本块(我们称之为上下文, Context),连同用户的原始问题,一起打包成一个新的、更丰富的提示(Prompt),发送给LLM。
原始问题: "我们的项目交付标准是什么?"
增强后的Prompt:
"""
根据以下背景信息:
---
[检索到的文本块1]: "所有项目交付物必须通过三轮内部审查..."
[检索到的文本块2]: "项目交付标准文档v2.3规定,代码覆盖率不得低于85%..."
[检索到的文本块3]: "交付给客户前,需由法务部门确认合规性..."
---
请回答问题: 我们的项目交付标准是什么?
"""
LLM在看到这些具体、相关的材料后,就能生成一个全面、准确、有理有据的回答。
Part 3: Python 实战 - 从0到1构建RAG问答机器人
现在,让我们用当前最流行的AI应用开发框架 LangChain 和开源向量数据库 ChromaDB,来把理论变为现实。
1. 环境准备
# 安装必要的库
pip install langchain langchain-openai chromadb beautifulsoup4
同时,请确保你的OpenAI API密钥已经设置在环境变量 OPENAI_API_KEY
中。
2. 完整代码示例
这个脚本将完成一个完整的RAG流程:加载一个网页作为知识源 -> 分块 -> 嵌入并存入ChromaDB -> 构建检索器 -> 实现问答。
import os
from langchain_community.document_loaders import WebBaseLoader
from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain.chains import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# 确保OpenAI API密钥已设置
# os.environ["OPENAI_API_KEY"] = "sk-..."
# --- 1. 数据索引流水线 (Indexing Pipeline) ---
# 步骤 1: 加载文档
# 我们使用LangChain的WebBaseLoader来加载一个关于大模型的网页作为我们的知识库
print("正在加载知识库...")
loader = WebBaseLoader("https://lilianweng.github.io/posts/2023-06-23-agent/")
docs = loader.load()
# 步骤 2: 文本分块
print(f"知识库加载完毕,共 {len(docs)} 个文档。正在进行分块...")
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)
print(f"分块完成,共得到 {len(splits)} 个文本块。")
# 步骤 3: 嵌入并存入向量数据库
# 我们使用OpenAI的Embedding模型和ChromaDB
print("正在将文本块嵌入并存入ChromaDB向量数据库...")
# ChromaDB会在本地创建一个持久化的数据库目录 `./chroma_db`
vectorstore = Chroma.from_documents(documents=splits,
embedding=OpenAIEmbeddings(),
persist_directory="./chroma_db")
print("向量数据库构建完成!")
# --- 2. 检索与生成流水线 (Retrieval & Generation Pipeline) ---
# 初始化我们使用的LLM
llm = ChatOpenAI(model="gpt-3.5-turbo-0125")
# 将向量数据库转换为一个“检索器”组件
# a. k=4 表示每次检索返回4个最相关的文本块
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
# b. 定义我们的“增强提示”模板
system_prompt = (
"你是一个智能问答助手。请使用下面提供的背景信息来回答用户的问题。"
"如果你在背景信息中找不到答案,就说你不知道,不要试图编造答案。"
"请让你的回答尽可能简洁。"
"\\n\\n"
"{context}"
)
prompt = ChatPromptTemplate.from_messages(
[
("system", system_prompt),
("human", "{input}"),
]
)
# c. 创建一个文档处理链,它负责将检索到的文档塞进提示中
question_answer_chain = create_stuff_documents_chain(llm, prompt)
# d. 将检索器和文档处理链组合成一个完整的RAG链
rag_chain = create_retrieval_chain(retriever, question_answer_chain)
# --- 3. 开始问答! ---
print("\\n--- RAG 问答机器人已就绪 ---")
question1 = "What are the main challenges of LLM-powered agents?"
print(f"问题1: {question1}")
response1 = rag_chain.invoke({"input": question1})
print(f"回答1: {response1['answer']}")
print("\\n-------------------------------------\\n")
question2 = "What is task decomposition?"
print(f"问题2: {question2}")
response2 = rag_chain.invoke({"input": question2})
print(f"回答2: {response2['answer']}")
# 清理(可选)
# vectorstore.delete_collection()
3. 运行与解读
当你运行这个脚本,你会看到清晰的日志输出了每个步骤的执行情况。最终,对于你提出的问题,AI会基于它从网页中检索到的具体信息,给出准确而精炼的回答,而不会胡言乱语。你已经成功构建了一个微型的、但功能完备的RAG应用!
结论:RAG 是通往企业级 AI 的高速公路
掌握 RAG,就像是掌握了将通用大模型“驯化”为特定领域专家的核心技术。它以一种相对低成本、高效率的方式,优雅地解决了AI应用的知识更新和可信度问题。
在“启智未来”,我们已经将RAG架构应用到了公司的方方面面:
- 对内: 智能HR机器人、法务合同审查助手、研发知识库搜索引擎。
- 对外: 能够回答最新产品问题的智能客服、个性化的课程推荐系统。
RAG范式正在开启一个全新的AI应用时代。现在,轮到你来构建属于你自己的“专家”了。