helloworld入门【从0到1,LangChain+RAG全链路实战AI知识库】

LangChain + RAG 全链路实战 AI 知识库

从环境搭建到 Prompt 工程,覆盖开发全流程,附可运行代码


一、为什么要自己做 RAG 知识库?

痛点 RAG 带来的收益
大模型「幻觉」严重 用检索结果约束生成,事实性↑
私有数据无法直接微调 无需重训模型,实时外挂知识
上下文长度有限 只给模型最相关的 Top-K 片段
迭代周期长 增删改文档即可,分钟级上线

二、整体架构(5 步闭环)

复制代码
┌────────────┐     ┌──────────────┐     ┌──────────┐     ┌──────────┐     ┌────────┐
│  文档加载   │ ──► │  分块 & 向量化 │ ──► │  Chroma  │ ──► │  检索器   │ ──► │  生成器  │
└────────────┘     └──────────────┘     └──────────┘     └──────────┘     └────────┘

技术选型:

  • LangChain 0.3+(链式编排)
  • Chroma 轻量级本地向量库
  • OpenAI Embedding & GPT-3.5-turbo(可换开源模型)
  • Python 3.10+

三、开发环境一键准备

bash 复制代码
# 1. 创建虚拟环境
python -m venv rag-env
source rag-env/bin/activate      # Windows 用 rag-env\Scripts\activate

# 2. 安装依赖
pip install -U langchain langchain-community langchain-openai langchain-chroma chromadb openai tiktoken pypdf

# 3. 放私密 KEY
export OPENAI_API_KEY="sk-xxxxxxxx"   # Windows 用 set

四、完整代码(单文件即可跑)

文件:rag_bot.py

python 复制代码
import os, sys, time
from pathlib import Path

from langchain.document_loaders import PyPDFLoader, TextLoader, DirectoryLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_chroma import Chroma
from langchain.chains import RetrievalQA
from langchain.prompts import ChatPromptTemplate
from langchain.schema.runnable import RunnablePassthrough
from langchain.schema.output_parser import StrOutputParser

#################### 1. 参数区 ####################
DATA_PATH = "./data"               # 放 PDF/TXT 的文件夹
PERSIST_DIR = "./chroma_db"        # 向量库落盘位置
CHUNK_SIZE = 800
CHUNK_OVERLAP = 150
TOP_K = 4
MODEL_NAME = "gpt-3.5-turbo"
##################################################

#################### 2. 文档加载 ####################
def load_docs(path: str):
    loaders = {
        ".pdf": DirectoryLoader(path, glob="**/*.pdf", loader_cls=PyPDFLoader),
        ".txt": DirectoryLoader(path, glob="**/*.txt", loader_cls=TextLoader),
    }
    docs = []
    for ext, loader in loaders.items():
        if any(f.suffix == ext for f in Path(path).rglob(f"*{ext}")):
            docs += loader.load()
    if not docs:
        print("❌ 未找到任何文档,程序结束"); sys.exit()
    print(f"📄 共加载 {len(docs)} 个文档")
    return docs

#################### 3. 分块 ####################
def split_docs(docs):
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=CHUNK_SIZE,
        chunk_overlap=CHUNK_OVERLAP,
        separators=["\n\n", "\n", "。", "!", "?", " ", ""]
    )
    chunks = splitter.split_documents(docs)
    print(f"🪓 得到 {len(chunks)} 个文本块")
    return chunks

#################### 4. 向量化+入库 ####################
def build_vectorstore(chunks):
    embedding = OpenAIEmbeddings(model="text-embedding-3-small")
    if os.path.exists(PERSIST_DIR):
        print("🔄 发现已有向量库,直接加载...")
        return Chroma(persist_directory=PERSIST_DIR, embedding_function=embedding)
    print("⏳ 首次构建向量库,需要几分钟...")
    vectordb = Chroma.from_documents(
        documents=chunks,
        embedding=embedding,
        persist_directory=PERSIST_DIR
    )
    vectordb.persist()
    return vectordb

#################### 5. Prompt 工程 ####################
SYSTEM_TMPL = """You are an assistant for question-answering tasks.
Use the following pieces of retrieved context to answer the question.
If you don't know the answer, just say that you don't know.
Use three sentences maximum and keep the answer concise.
Context: {context}
"""
prompt = ChatPromptTemplate.from_messages([
    ("system", SYSTEM_TMPL),
    ("human", "{question}")
])

#################### 6. 链式 RAG ####################
def build_chain(vectordb):
    retriever = vectordb.as_retriever(search_kwargs={"k": TOP_K})
    llm = ChatOpenAI(model_name=MODEL_NAME, temperature=0)
    chain = (
        {"context": retriever | (lambda docs: "\n\n".join(d.page_content for d in docs)), 
         "question": RunnablePassthrough()}
        | prompt
        | llm
        | StrOutputParser()
    )
    return chain

#################### 7. 交互 ####################
def chat(chain):
    print("✅ 知识库已就绪,输入问题(输入 exit 退出):")
    while True:
        q = input("\n👤 > ").strip()
        if q.lower() == "exit":
            break
        t0 = time.time()
        ans = chain.invoke(q)
        print(f"🤖 < {ans}  (cost {time.time()-t0:.2f}s)")

#################### 8. 主入口 ####################
if __name__ == "__main__":
    docs = load_docs(DATA_PATH)
    chunks = split_docs(docs)
    db = build_vectorstore(chunks)
    rag_chain = build_chain(db)
    chat(rag_chain)

五、运行演示

bash 复制代码
# 1. 把 PDF/TXT 放进 data 文件夹
mkdir data && cp xxx.pdf data/

# 2. 首次运行会构建向量库(后续秒启动)
python rag_bot.py

# 3. 交互示例
👤 > 公司年假天数规定?
🤖 < 根据员工手册,入职满 1 年享 5 天年假,满 10 年 10 天。详情见 HR-2025-001 号文件。

六、Prompt 工程调优清单

技巧 示例 效果
角色扮演 You are a legal advisor... 领域术语↑
强制引用 Answer with "Source: <doc_name>" 可追溯
拒绝幻觉 If the context lacks info, say "I don't know" 幻觉↓
格式限定 Return JSON {"answer": "...", "confidence": 0.8} 方便下游解析
多语言 Answer in the same language as the question 中文问答自动适配

七、常见坑 & 解决方案

  1. Chroma 锁库

    退出程序前先 vectordb.persist(),且只保留一个进程占用。

  2. 块太小丢上下文

    RecursiveCharacterTextSplitter 并保留 10--20 % 重叠。

  3. Top-K 过大导致超限

    gpt-3.5-turbo 4k 上下文,K=4×800≈3200 token,留 800 token 给 Prompt 与生成。

  4. Windows 终端中文乱码
    chcp 65001 并升级 Powershell 7。


八、进阶路线

  • ensemble_retriever 做混合检索(BM25 + 向量)。
  • 接入 ReRank 模型(bge-reranker)精排 Top-K。
  • 把 Chroma 换成 Milvus / Pinecone 支撑亿级向量。
  • 引入 Agent,对多知识库自动路由。
  • LlamaIndex + LangChain 双框架互补,支持图谱 & 结构化数据。

完整源码已开源在 GitHub,欢迎 Star / PR:
github.com/yourname/la...

把代码拖下来,5 分钟你就能拥有一个可交互的私有 AI 知识库!

相关推荐
UIUV9 小时前
RAG技术学习笔记(含实操解析)
javascript·langchain·llm
神秘的猪头14 小时前
🚀 拒绝“一本正经胡说八道”!手把手带你用 LangChain 实现 RAG,打造你的专属 AI 知识库
langchain·llm·openai
栀秋66615 小时前
重塑 AI 交互边界:基于 LangChain 与 MCP 协议的全栈实践
langchain·llm·mcp
大模型真好玩16 小时前
LangChain DeepAgents 速通指南(三)—— 让Agent告别混乱:Tool Selector与Todo List中间件解析
人工智能·langchain·trae
是一碗螺丝粉2 天前
LangChain 链(Chains)完全指南:从线性流程到智能路由
前端·langchain·aigc
前端付豪2 天前
LangChain记忆:通过Memory记住上次的对话细节
人工智能·python·langchain
神秘的猪头2 天前
🔌 给 AI 装上“三头六臂”!实战大模型接入第三方 MCP 全攻略
langchain·llm·mcp
前端付豪2 天前
LangChain链 写一篇完美推文?用SequencialChain链接不同的组件
人工智能·python·langchain
神秘的猪头2 天前
🔌 把 MCP 装进大脑!手把手带你构建能“热插拔”工具的 AI Agent
langchain·llm·mcp
是一碗螺丝粉4 天前
5分钟上手LangChain.js:用DeepSeek给你的App加上AI能力
前端·人工智能·langchain