跳转至

02. LangChain 入门与 RAG 实战

一句话说明:LangChain 是一个 Python 框架,帮你把大语言模型(LLM)和你自己的数据连起来——最核心的用法就是 RAG(先搜后答),让 AI 回答问题时能查你的文档,而不是瞎编。


目录

  1. 为什么要学
  2. 核心概念详解
  3. 环境安装与配置
  4. 实操教程
  5. 用 RAG 搭建个人知识库问答
  6. 常见报错与解决方案
  7. LangChain vs LlamaIndex vs 直接调 API 对比
  8. 速查表
  9. 延伸学习资源

1. 为什么要学

RAG 解决了什么问题

大语言模型有两个致命缺陷:

缺陷 白话 举例
知识截止 模型训练完就不更新了,不知道最新的事 问它2026年最新的 MetaPhlAn 版本,它可能答错
幻觉 不知道的东西它会瞎编,而且编得很像真的 问它你论文里的数据,它会编一个看起来像真的结果

RAG(Retrieval-Augmented Generation,检索增强生成) 的思路很简单:先从你的文档里搜到相关内容,再把搜到的内容喂给 AI,让 AI 基于真实资料回答。

白话比方:你问一个学生问题,与其让他凭记忆瞎答,不如先让他翻书找到相关段落,再基于书上的内容回答——这就是 RAG。

LangChain 在 AI 生态中的地位

  • GitHub 135,000+ stars(截至2026年5月),Python AI 框架中 star 数最多
  • 官方定位:The Agent Engineering Platform(代理工程平台)
  • 生态完善:对接了几百种 LLM、向量数据库、文档加载器
  • 面试加分:许多生信+AI 岗会问"你有没有用 LangChain 搭过 RAG"

2. 核心概念详解

2.1 LangChain 是什么(白话比方)

白话:LangChain 就像一个"AI 应用搭建的乐高积木盒"。它不是一个 AI 模型,而是一套工具,帮你把各种组件(模型、数据库、文档、搜索引擎)像搭积木一样拼成一个完整的 AI 应用。

不用 LangChain 的话:你需要自己写代码调 API、自己处理文档切分、自己管理向量数据库……全部手动拼接。

用了 LangChain:每个步骤都有现成的模块,几行代码就能搭起来。

2.2 Chain(链)是什么

白话:Chain 就是"流水线"——把多个步骤串起来,前一步的输出自动传给下一步。

用户提问 → 组装 Prompt → 调用 LLM → 解析输出 → 返回结果

就像工厂的流水线:原料进去 → 加工 → 包装 → 出货,每一站做一件事,最后得到成品。

2.3 Agent(代理)是什么

白话:Agent 是一个"会自己决定下一步该做什么的 AI"。

Chain 是固定流水线(步骤提前定好),Agent 是灵活的——它会根据情况自己判断: - 需要搜索吗?→ 调用搜索工具 - 需要算数吗?→ 调用计算器 - 需要查数据库吗?→ 调用 SQL 工具

类似于:Chain 是按食谱做菜(步骤固定),Agent 是大厨随机应变(根据食材临场发挥)。

2.4 RAG 完整流程详解(重点)

RAG 一共 6 步,像一条加工流水线:

┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐    ┌─────────┐
│ ① 加载   │ →  │ ② 切分   │ →  │ ③ 向量化  │ →  │ ④ 存储   │ →  │ ⑤ 检索   │ →  │ ⑥ 生成   │
│ 文档     │    │ 文本     │    │ Embedding│    │ 向量库   │    │ 相似搜索  │    │ LLM回答  │
└─────────┘    └─────────┘    └─────────┘    └─────────┘    └─────────┘    └─────────┘
   离线准备阶段(只做一次)                                      在线问答阶段(每次提问都走)

每一步白话解释:

步骤 做了什么 白话比方
① 文档加载 读取你的文件(PDF/Markdown/TXT/网页) 把书从书架上拿下来
② 文本切分 把长文档切成小段(chunk),一般 500-1000 字一段 把整本书拆成一张张知识卡片
③ 向量化 用 Embedding 模型把每段文字变成一组数字(向量) 给每张卡片编一个"含义坐标"
④ 存储 把所有向量存到向量数据库里 把编好号的卡片整齐放进索引柜
⑤ 检索 用户提问时,也把问题变成向量,去向量库里找最相似的几段 用户问问题,从柜子里找出最相关的几张卡片
⑥ 生成 把找到的段落 + 用户问题一起喂给 LLM,让它基于内容回答 把卡片交给 AI,说"根据这些资料回答"

2.5 Embedding 是什么

白话:把文字变成数字坐标,让计算机能算"两段文字有多像"。

举例: - "糖尿病肠道菌群" → [0.23, -0.15, 0.87, ...](一组几百维的数字) - "T2D gut microbiome" → [0.21, -0.13, 0.85, ...](坐标很接近!) - "今天天气不错" → [0.91, 0.44, -0.32, ...](坐标差很远)

意思越接近的文字,生成的坐标就越接近。这样计算机就能用数学方法(余弦相似度)算出哪些文字跟你的问题最相关。

2.6 向量数据库是什么

白话:一个按"含义相似度"搜索的仓库。

普通数据库搜索是精确匹配(搜"苹果"只能找到包含"苹果"两个字的记录),向量数据库是语义搜索(搜"苹果"也能找到"iPhone""水果"相关的内容)。

常用的向量数据库:

名称 特点 适合场景
ChromaDB 轻量、纯 Python、开箱即用 学习、个人项目(我们用这个)
FAISS Meta 出品、速度极快 大规模向量搜索
Milvus 分布式、生产级 企业级部署
Pinecone 云托管、免运维 不想自己维护数据库的情况

2.7 Prompt Template 是什么

白话:一个"填空题模板",把固定格式的指令和动态内容拼在一起。

# 不用模板(硬拼接,容易出错)
prompt = "请根据以下内容回答:" + context + "\n问题:" + question

# 用模板(清晰、可复用)
template = """请根据以下内容回答用户的问题。
如果内容中没有答案,请说"我不确定"。

参考内容:{context}
用户问题:{question}
"""

好处:统一管理提示词,改一处就行,不用到处改字符串。


3. 环境安装与配置

# 建议在独立的 conda 环境中安装
conda create -n langchain python=3.11 -y
conda activate langchain

# 安装核心包
pip install langchain langchain-community langchain-openai chromadb

每个包是干什么的:

包名 作用
langchain 核心框架,提供 Chain、Prompt Template 等基础组件
langchain-community 社区贡献的集成(文档加载器、向量数据库连接器等)
langchain-openai OpenAI/兼容 API 的封装(也支持连 Ollama 等本地模型)
chromadb 轻量级向量数据库,存储和检索向量

可选安装:

# 如果要用本地 Ollama 模型(免费方案)
pip install langchain-ollama

# 如果要加载 PDF 文件
pip install pypdf

# 如果要用 HuggingFace 的 Embedding 模型(免费)
pip install langchain-huggingface sentence-transformers

4. 实操教程

4.1 入门:第一个 LangChain 程序

用 LangChain 调用 LLM 回答一个问题:

# === 第一个 LangChain 程序 ===
# 功能:调用 LLM 回答一个简单问题

# 导入 ChatOpenAI 类(支持 OpenAI 及兼容 API)
from langchain_openai import ChatOpenAI

# 初始化模型
# 如果你用 OpenAI 官方 API:
# llm = ChatOpenAI(model="gpt-4o-mini", api_key="你的key")

# 如果你用本地 Ollama(免费,推荐):
llm = ChatOpenAI(
    model="qwen2.5:7b",               # Ollama 里下载的模型名
    base_url="http://localhost:11434/v1",  # Ollama 的 API 地址
    api_key="ollama",                  # Ollama 不需要真实 key,随便填
    temperature=0                      # 0 = 回答更稳定,不随机
)

# 调用模型回答问题
response = llm.invoke("什么是宏基因组学?用一句话解释。")

# 打印结果
print(response.content)
# 输出示例:宏基因组学是直接从环境样本中提取所有微生物的DNA进行测序分析的学科。

4.2 搭建一个完整的 RAG 系统(重点)

这是本教程的核心。我们从零搭建一个完整的 RAG 系统:加载文档 → 切分 → 向量化 → 存储到 ChromaDB → 检索问答。

# === 完整 RAG 系统 ===
# 功能:加载 Markdown 文件 → 切分 → 向量化 → 存储 → 检索问答

# ============ 第1步:导入所有需要的模块 ============
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate

# ============ 第2步:加载文档 ============
# 从指定目录加载所有 .md 文件
loader = DirectoryLoader(
    path="./knowledge_base",       # 你的知识库目录
    glob="**/*.md",                # 匹配所有 .md 文件(** 表示递归子目录)
    loader_cls=TextLoader,         # 用纯文本加载器
    loader_kwargs={"encoding": "utf-8"}  # 指定编码,避免中文乱码
)
# 执行加载,返回 Document 对象列表
documents = loader.load()
print(f"✓ 加载了 {len(documents)} 个文档")

# ============ 第3步:文本切分 ============
# 把长文档切成小段(chunk)
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=500,       # 每段最多 500 个字符
    chunk_overlap=50,     # 相邻段之间重叠 50 个字符(避免切断句子丢失上下文)
    separators=["\n## ", "\n### ", "\n\n", "\n", "。", ";", " "]
    # 切分优先级:优先在标题处切 → 空行处切 → 句号处切
    # 这样能保证每段内容是完整的意思
)
# 执行切分
chunks = text_splitter.split_documents(documents)
print(f"✓ 切分成 {len(chunks)} 个文本块")

# ============ 第4步:向量化 + 存储到 ChromaDB ============
# 初始化 Embedding 模型(把文字变成数字向量)
# 方案A:用 OpenAI 的 Embedding(付费但效果好)
# embeddings = OpenAIEmbeddings(api_key="你的key")

# 方案B:用 Ollama 本地 Embedding(免费,推荐)
from langchain_ollama import OllamaEmbeddings
embeddings = OllamaEmbeddings(
    model="nomic-embed-text",  # Ollama 里的 Embedding 模型
    base_url="http://localhost:11434"
)

# 把所有文本块向量化并存入 ChromaDB
vectorstore = Chroma.from_documents(
    documents=chunks,                # 要存储的文本块
    embedding=embeddings,            # 用什么模型做向量化
    persist_directory="./chroma_db"  # 数据存在磁盘的位置(下次不用重新建)
)
print(f"✓ 向量数据库构建完成,共 {vectorstore._collection.count()} 条记录")

# ============ 第5步:构建检索问答链 ============
# 初始化 LLM(用 Ollama 本地模型)
llm = ChatOpenAI(
    model="qwen2.5:7b",
    base_url="http://localhost:11434/v1",
    api_key="ollama",
    temperature=0
)

# 自定义 Prompt Template(告诉 AI 怎么回答)
prompt_template = PromptTemplate(
    input_variables=["context", "question"],
    template="""你是一个生物信息学知识助手。请根据以下参考内容回答问题。
要求:
1. 只根据参考内容回答,不要编造
2. 如果参考内容中没有答案,请说"根据已有资料无法回答"
3. 用中文回答,术语附英文原文

参考内容:
{context}

问题:{question}

回答:"""
)

# 创建检索问答链(把检索器 + LLM + Prompt 组装起来)
qa_chain = RetrievalQA.from_chain_type(
    llm=llm,                                         # 用哪个语言模型
    chain_type="stuff",                               # stuff = 把所有检索到的内容塞进一个 prompt
    retriever=vectorstore.as_retriever(
        search_kwargs={"k": 3}                        # 每次检索返回最相关的 3 段
    ),
    chain_type_kwargs={"prompt": prompt_template},    # 使用自定义 Prompt
    return_source_documents=True                      # 同时返回来源文档(方便溯源)
)

# ============ 第6步:提问! ============
question = "宏基因组分析的主要流程有哪些步骤?"
result = qa_chain.invoke({"query": question})

# 打印回答
print("=" * 50)
print(f"问题:{question}")
print(f"回答:{result['result']}")
print("=" * 50)

# 打印来源(可以看到 AI 参考了哪些文档片段)
print("\n参考来源:")
for i, doc in enumerate(result["source_documents"]):
    print(f"  [{i+1}] {doc.metadata.get('source', '未知')} ")
    print(f"      内容片段:{doc.page_content[:80]}...")

4.3 使用本地 Ollama 模型搭建免费 RAG

上面的代码已经用 Ollama 作为默认方案了。这里补充完整的 Ollama 配置流程:

# ====== 第1步:安装 Ollama ======
# Linux:
curl -fsSL https://ollama.com/install.sh | sh

# ====== 第2步:下载模型 ======
# 下载对话模型(选一个,推荐 qwen2.5:7b,中文好)
ollama pull qwen2.5:7b       # 4.7GB,中文效果好
# 或者
ollama pull llama3.1:8b      # 4.7GB,英文强

# 下载 Embedding 模型(必须下,用于向量化)
ollama pull nomic-embed-text  # 274MB,小巧够用

# ====== 第3步:验证模型可用 ======
ollama list   # 查看已下载的模型
ollama run qwen2.5:7b "你好"  # 测试对话
# ====== 免费 RAG 完整配置(不花一分钱) ======

from langchain_openai import ChatOpenAI
from langchain_ollama import OllamaEmbeddings

# LLM:用 Ollama 本地模型(免费)
llm = ChatOpenAI(
    model="qwen2.5:7b",
    base_url="http://localhost:11434/v1",
    api_key="ollama"
)

# Embedding:用 Ollama 本地 Embedding 模型(免费)
embeddings = OllamaEmbeddings(
    model="nomic-embed-text",
    base_url="http://localhost:11434"
)

# 向量数据库:ChromaDB(免费,本地存储)
# 加上上面4.2节的代码就是一个完整的免费 RAG 系统
# 总花费:0元

4.4 自定义 Prompt Template

# === 不同场景的 Prompt Template ===

from langchain.prompts import PromptTemplate

# 场景1:严格问答(不让 AI 编造)
strict_qa_prompt = PromptTemplate(
    input_variables=["context", "question"],
    template="""请严格根据以下参考内容回答问题。
如果参考内容中找不到答案,请回答"无法确定"。

参考内容:{context}
问题:{question}
回答:"""
)

# 场景2:生信面试模拟
interview_prompt = PromptTemplate(
    input_variables=["context", "question"],
    template="""你是一位生信面试教练。
根据参考资料,用面试回答的格式回答问题:
1. 先用一句话总结核心要点
2. 再分点展开(2-3个要点)
3. 最后举一个实际应用的例子

参考资料:{context}
面试问题:{question}
回答:"""
)

# 场景3:多语言术语对照
bilingual_prompt = PromptTemplate(
    input_variables=["context", "question"],
    template="""根据以下内容回答问题。
要求:所有专业术语同时给出中文和英文,格式为"中文(English)"。

内容:{context}
问题:{question}
回答:"""
)

4.5 Chain 的串联用法

# === 用 LCEL(LangChain Expression Language)串联 Chain ===
# LCEL 是 LangChain 推荐的新写法,用 | 符号串联步骤

from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

# 初始化模型
llm = ChatOpenAI(
    model="qwen2.5:7b",
    base_url="http://localhost:11434/v1",
    api_key="ollama"
)

# 定义一个翻译 + 总结的串联 Chain
# 第一步:翻译
translate_prompt = ChatPromptTemplate.from_template(
    "把以下英文生信术语翻译成中文并解释:{term}"
)

# 第二步:简化
simplify_prompt = ChatPromptTemplate.from_template(
    "把以下解释用更通俗的白话重新说一遍,让完全没基础的人也能听懂:\n{text}"
)

# 用 | 串联:输入 → 翻译prompt → LLM → 解析文本 → 简化prompt → LLM → 输出
chain = translate_prompt | llm | StrOutputParser() | simplify_prompt | llm | StrOutputParser()

# 运行
result = chain.invoke({"term": "Metagenomic binning"})
print(result)

5. 用 RAG 搭建个人知识库问答

把你 knowledge_base 目录里的文档变成一个可以问答的系统:

# === 个人知识库问答系统(完整版) ===
# 把你面试准备的知识库目录变成 AI 可问答的系统

import os
from langchain_community.document_loaders import DirectoryLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import Chroma
from langchain_openai import ChatOpenAI
from langchain_ollama import OllamaEmbeddings
from langchain.chains import RetrievalQA
from langchain.prompts import PromptTemplate

# ======== 配置区(根据你的实际情况修改) ========
KNOWLEDGE_DIR = "/home/pweaz/面试/knowledge_base  知识库"  # 你的知识库路径
CHROMA_DIR = "/home/pweaz/面试/my_vectordb"                # 向量库存储位置
OLLAMA_URL = "http://localhost:11434"                      # Ollama 地址

def build_knowledge_base():
    """构建向量知识库(只需运行一次)"""

    # 1. 加载所有 Markdown 文件
    loader = DirectoryLoader(
        path=KNOWLEDGE_DIR,
        glob="**/*.md",
        loader_cls=TextLoader,
        loader_kwargs={"encoding": "utf-8"},
        show_progress=True    # 显示加载进度条
    )
    docs = loader.load()
    print(f"加载了 {len(docs)} 个文档")

    # 2. 切分
    splitter = RecursiveCharacterTextSplitter(
        chunk_size=500,
        chunk_overlap=50,
        separators=["\n## ", "\n### ", "\n\n", "\n", "。", " "]
    )
    chunks = splitter.split_documents(docs)
    print(f"切分成 {len(chunks)} 个文本块")

    # 3. 向量化 + 存储
    embeddings = OllamaEmbeddings(
        model="nomic-embed-text",
        base_url=OLLAMA_URL
    )
    vectorstore = Chroma.from_documents(
        documents=chunks,
        embedding=embeddings,
        persist_directory=CHROMA_DIR
    )
    print(f"知识库构建完成!共 {vectorstore._collection.count()} 条记录")
    return vectorstore

def ask(question, vectorstore=None):
    """向知识库提问"""

    # 如果没传入 vectorstore,就从磁盘加载已有的
    if vectorstore is None:
        embeddings = OllamaEmbeddings(
            model="nomic-embed-text",
            base_url=OLLAMA_URL
        )
        vectorstore = Chroma(
            persist_directory=CHROMA_DIR,
            embedding_function=embeddings
        )

    # 初始化 LLM
    llm = ChatOpenAI(
        model="qwen2.5:7b",
        base_url=f"{OLLAMA_URL}/v1",
        api_key="ollama",
        temperature=0
    )

    # 自定义 Prompt
    prompt = PromptTemplate(
        input_variables=["context", "question"],
        template="""你是彭文强的面试备考助手。请根据知识库中的内容回答问题。
要求:
1. 只基于提供的内容回答,不要编造
2. 如果涉及面试,给出面试回答模板
3. 术语给出英文原文

参考内容:
{context}

问题:{question}

回答:"""
    )

    # 构建 QA Chain
    qa = RetrievalQA.from_chain_type(
        llm=llm,
        retriever=vectorstore.as_retriever(search_kwargs={"k": 4}),
        chain_type_kwargs={"prompt": prompt},
        return_source_documents=True
    )

    result = qa.invoke({"query": question})
    print(f"\n问:{question}")
    print(f"答:{result['result']}")
    print(f"\n来源:")
    for doc in result["source_documents"]:
        src = os.path.basename(doc.metadata.get("source", ""))
        print(f"  - {src}")
    return result

# ======== 使用方式 ========
if __name__ == "__main__":
    # 第一次运行:构建知识库(约需几分钟)
    # vs = build_knowledge_base()

    # 之后每次运行:直接提问(秒级响应)
    ask("宏基因组分析流程有哪些步骤?")
    ask("Shannon 指数和 Simpson 指数有什么区别?")
    ask("如果面试官问我随机森林的原理,我该怎么回答?")

6. 常见报错与解决方案

报错信息 原因 解决方法
Connection refused localhost:11434 Ollama 没有启动 终端运行 ollama serve,或检查 Ollama 是否安装
model 'xxx' not found 模型没下载 运行 ollama pull qwen2.5:7b 下载对应模型
UnicodeDecodeError: 'utf-8' codec can't decode 文件编码不是 UTF-8 loader_kwargs={"encoding": "utf-8"} 或转换文件编码
chromadb.errors.InvalidCollectionException ChromaDB 版本不兼容或数据损坏 删除 ./chroma_db 目录重新构建
openai.AuthenticationError: invalid api_key 用 OpenAI API 但 key 无效/过期 检查 OPENAI_API_KEY 环境变量;或改用 Ollama 免费方案
ImportError: cannot import name 'xxx' LangChain 版本更新,API 变了 pip install --upgrade langchain langchain-community;查看迁移文档
RuntimeError: CUDA out of memory 本地 GPU 显存不够跑模型 换小模型如 qwen2.5:1.5b,或用 CPU 模式(慢但能跑)
RecursionError: maximum recursion depth Chain 套了死循环 检查 Chain 定义,确保没有循环引用

7. LangChain vs LlamaIndex vs 直接调 API 对比

维度 LangChain LlamaIndex 直接调 API
定位 通用 AI 应用框架 专注数据索引和 RAG 最底层调用
上手难度 中等,概念多 较低,RAG 开箱即用 最低,但什么都要自己写
RAG 搭建 灵活但需要手动组装各步骤 几行代码就能搭好 RAG 需要自己实现切分、向量化、检索
Agent 支持 强(核心功能之一) 弱(不是主要方向) 需要自己实现
生态集成 极广(几百种工具/模型) 主要围绕数据索引 取决于你自己写多少代码
灵活性 高,可自定义每个环节 中等,封装较重 最高,完全自由
适合场景 复杂 AI 应用、Agent 纯 RAG / 知识库问答 简单调用、追求极致控制
推荐 想系统学 AI 应用开发 只想快速搭 RAG 只需要简单调用 LLM

对于你(生信面试)的建议:先学 LangChain(覆盖面广,面试加分),等熟悉后再看 LlamaIndex 作为补充。


8. 速查表

常用文档加载器

from langchain_community.document_loaders import (
    TextLoader,           # 纯文本文件(.txt, .md)
    PyPDFLoader,          # PDF 文件(需要 pip install pypdf)
    CSVLoader,            # CSV 表格
    DirectoryLoader,      # 批量加载整个目录
    WebBaseLoader,        # 从网页加载(需要 pip install beautifulsoup4)
    UnstructuredFileLoader # 通用加载器(自动识别格式)
)

常用文本切分器

from langchain.text_splitter import (
    RecursiveCharacterTextSplitter,  # 最常用,递归按分隔符切
    CharacterTextSplitter,           # 简单按字符数切
    MarkdownTextSplitter,            # 按 Markdown 标题切
    TokenTextSplitter                # 按 Token 数切
)

常用向量数据库

from langchain_community.vectorstores import (
    Chroma,    # ChromaDB(轻量,推荐入门用)
    FAISS,     # Facebook AI 相似度搜索
)

常用 Chain 类型

Chain 类型 用途
RetrievalQA 检索 + 问答(RAG 核心)
ConversationalRetrievalChain 带对话历史的 RAG
LLMChain 最基础的 Prompt → LLM 调用
SequentialChain 串联多个 Chain

LCEL 常用写法

# 基础调用
chain = prompt | llm | StrOutputParser()
result = chain.invoke({"question": "..."})

# 带检索的 RAG
from langchain_core.runnables import RunnablePassthrough
chain = (
    {"context": retriever, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)

9. 延伸学习资源

资源 说明
LangChain 官方文档 最权威的参考,API 变动时以此为准
LangChain GitHub 135k+ stars,源码和示例
LangSmith LangChain 官方的调试和监控平台
Ollama 官网 本地模型下载和管理
ChromaDB 文档 向量数据库使用指南
本知识库:21_大语言模型入门.md LLM 基础概念(先读这个再来看本文)
本知识库:22_Prompt工程技巧.md Prompt 写法技巧,搭配 RAG 的 Prompt Template 使用

学习路线建议: 1. 先确保 Ollama 本地模型跑通(参考知识库2的 01_Ollama本地大模型部署与使用.md) 2. 跑通 4.1 节的第一个程序 3. 跑通 4.2 节的完整 RAG 4. 用第 5 节的代码把自己的知识库接上去 5. 面试前能讲清楚 RAG 的 6 步流程,加分