langchain与rag简单快速入门

LangChain & RAG 简单快速入门

可能会有问题,欢迎评论区留言


目录

  1. 核心概念速览
  2. LangChain 基础组件
  3. RAG 原理详解
  4. 实战:构建完整的 RAG 应用
  5. 高级技巧与最佳实践
  6. 常见问题与解决方案

1. 核心概念速览

什么是 LangChain?

LangChain 是一个用于开发大语言模型(LLM)应用的框架。它的核心思想是:把 LLM 和其他数据源连接起来,构建复杂的应用。

1
2
3
4
5
6
┌─────────────────────────────────────────────────────────┐
│ LangChain 应用 │
├─────────────┬─────────────┬─────────────┬───────────────┤
│ LLM │ Chains │ Agents │ Memory │
│ (大脑) │ (工作流) │ (决策者) │ (记忆) │
└─────────────┴─────────────┴─────────────┴───────────────┘

什么是 RAG?

RAG (Retrieval-Augmented Generation) = 检索 + 生成

1
2
3
4
5
6
7
用户提问 → 检索相关知识 → 把知识和问题一起给 LLM → LLM 生成答案

┌──────────┐ ┌──────────┐ ┌──────────┐
│ 提问 │ → │ 检索 │ → │ 生成 │
│ "公司法 │ │ 找到相关 │ │ LLM 结合 │
│ 人代表?"│ │ 法律条文 │ │ 上下文回答│
└──────────┘ └──────────┘ └──────────┘

为什么需要 RAG?

  • LLM 的知识是有限的(训练数据截止时间)
  • LLM 会"胡编乱造"(幻觉问题)
  • 你有私有数据需要利用(公司文档、数据库等)

2. LangChain 基础组件

2.1 模型(Models)

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic

# 初始化模型
llm = ChatOpenAI(
model="gpt-4o-mini",
temperature=0, # 0 = 确定性回答,1 = 创造性回答
api_key="your-api-key"
)

# 调用模型
response = llm.invoke("你好,请介绍一下自己")
print(response.content)

2.2 提示词(Prompts)

Prompt Template 让你可以复用提示词结构:

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_core.prompts import ChatPromptTemplate

# 创建一个模板
prompt = ChatPromptTemplate.from_messages([
("system", "你是一个专业的{role}助手"),
("human", "{question}")
])

# 使用模板
formatted = prompt.format(role="法律", question="什么是合同?")
# 输出:
# System: 你是一个专业的法律助手
# Human: 什么是合同?

2.3 链(Chains)

Chain = 多个组件的组合,形成完整的工作流。

1
2
3
4
5
6
7
8
9
10
11
12
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough

# 最简单的 Chain:Prompt + LLM + Output Parser
chain = (
prompt # 输入处理
| llm # 模型处理
| StrOutputParser() # 输出解析
)

# 使用 chain
result = chain.invoke({"role": "法律", "question": "什么是合同?"})

链式调用的本质:数据像流水线一样经过每个组件

1
2
3
输入 → Prompt → LLM → Parser → 输出
↓ ↓ ↓
格式化 生成 解析

2.4 工具(Tools)

Tools 让 LLM 能够执行具体操作(搜索、计算、调用 API 等)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from langchain.tools import tool
from langchain_community.tools import DuckDuckGoSearchRun

# 使用现成的工具
search = DuckDuckGoSearchRun()
result = search.invoke("今天北京的天气")

# 自定义工具
@tool
def calculate_bmi(weight: float, height: float) -> float:
"""计算 BMI 指数。

Args:
weight: 体重 (kg)
height: 身高 (m)

Returns:
BMI 指数
"""
return weight / (height ** 2)

# 工具需要告诉 LLM 它能做什么
print(calculate_bmi.name) # "calculate_bmi"
print(calculate_bmi.description) # "计算 BMI 指数..."

2.5 代理(Agents)

Agent = LLM + Tools,让 LLM 自主决定使用哪个工具。

1
2
3
4
5
6
7
8
9
10
11
12
from langchain.agents import create_agent

# 创建 agent
agent = create_agent(
model="gpt-4o-mini",
tools=[search, calculate_bmi],
prompt="你是一个有帮助的助手"
)

# agent 会自己决定:
# - 用户问"今天天气" → 使用 search 工具
# - 用户问"70kg, 1.75m 的 BMI" → 使用 calculate_bmi 工具

Agent 工作流程:

1
2
3
用户输入 → LLM 思考 → 决定使用工具 → 执行工具 → 得到结果 → 生成回答
↓
"我需要搜索天气信息"

2.6 记忆(Memory)

Memory 让对话有连续性,记住之前的对话内容。

1
2
3
4
5
6
7
8
9
10
11
12
from langchain.memory import ConversationBufferMemory

# 创建记忆
memory = ConversationBufferMemory(return_messages=True)

# 保存对话
memory.save_context({"input": "你好"}, {"output": "你好!有什么可以帮助你的?"})
memory.save_context({"input": "我叫小明"}, {"output": "你好小明!"})

# 获取历史对话
history = memory.load_memory_variables({})
# 输出:[Human: 你好, AI: 你好!..., Human: 我叫小明, AI: 你好小明!]

3. RAG 原理详解

3.1 RAG 的核心流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
┌─────────────────────────────────────────────────────────────────┐
│ RAG 完整流程 │
└─────────────────────────────────────────────────────────────────┘

【索引阶段 - 离线】
文档 → 分块 → 向量化 → 存储到向量数据库

┌────────┐ ┌────────┐ ┌────────┐ ┌────────────┐
│ PDF/ │ → │ 切成小 │ → │ 转换成 │ → │ 向量数据库 │
│ Word/ │ │ 段落 │ │ 向量 │ │ (FAISS等) │
│ 网页 │ │ │ │ │ │ │
└────────┘ └────────┘ └────────┘ └────────────┘

【检索阶段 - 在线】
用户问题 → 向量化 → 相似度搜索 → 返回相关文档

┌────────┐ ┌────────┐ ┌────────┐ ┌────────┐
│ 用户 │ → │ 转换 │ → │ 在向量 │ → │ 找到最 │
│ 提问 │ │ 为向量 │ │ 库搜索 │ │ 相似的 │
└────────┘ └────────┘ └────────┘ └────────┘
↓
┌────────┐
│ 相关 │
│ 文档块 │
└────────┘

【生成阶段 - 在线】
问题 + 文档 → LLM → 生成答案

┌────────┐ ┌────────┐ ┌────────┐
│ 问题 │ + │ 检索到 │ → │ LLM │ → 答案
│ │ │ 的文档 │ │ 生成 │
└────────┘ └────────┘ └────────┘

3.2 核心概念解释

什么是向量(Vector)?

向量是一串数字,用来表示文本的"语义"。

1
2
3
4
5
6
7
8
文本:"我喜欢吃苹果"
向量:[0.1, -0.5, 0.8, ..., 0.3] (可能是 1536 维的数字)

文本:"苹果很好吃"
向量:[0.09, -0.48, 0.82, ..., 0.31] (非常接近!)

文本:"今天天气不错"
向量:[-0.7, 0.2, -0.1, ..., -0.5] (完全不同)

相似的内容,向量也相似 → 可以用数学方法找到"语义相似"的文本

什么是 Embedding(嵌入)?

Embedding 模型负责把文本转换成向量。

1
2
3
4
5
6
7
from langchain_openai import OpenAIEmbeddings

embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# 把文本转换成向量
vector = embeddings.embed_query("我喜欢吃苹果")
print(len(vector)) # 1536 维的向量

常见 Embedding 模型:

模型 维度 特点
text-embedding-3-small 1536 快速、便宜
text-embedding-3-large 3072 更准确
jina-embeddings-v2 768 开源、免费

什么是向量数据库?

专门用来存储和搜索向量的数据库。

1
2
3
4
5
6
7
普通数据库:WHERE name = "张三"  (精确匹配)
向量数据库:找和这个向量"最相似"的向量 (语义匹配)

相似度计算(余弦相似度):
similarity = cos(向量 A, 向量 B) = (A·B) / (|A|×|B|)

结果范围:0 (完全不同) ~ 1 (完全相同)

常见向量数据库:

  • InMemoryVectorStore - 内存存储,适合学习/测试
  • FAISS - Facebook 开源,快速
  • Chroma - 轻量级,易上手
  • Milvus - 专业向量数据库,适合生产
  • Elasticsearch - 支持混合搜索

3.3 文档分块(Chunking)

为什么要分块?

  1. LLM 有上下文长度限制
  2. 检索时需要精确匹配相关内容
  3. 太大块包含噪声,太小块丢失上下文
1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500, # 每块最多 500 个字符
chunk_overlap=100, # 块之间重叠 100 个字符(保持上下文连续)
length_function=len, # 计算长度的函数
)

# 示例
text = "这是一段很长的文本..." * 100
chunks = text_splitter.split_text(text)

# 输出:[块 1, 块 2, 块 3, ...]

分块策略选择:

场景 chunk_size chunk_overlap
简短问答 200-400 50-100
技术文档 500-1000 100-200
法律合同 1000-2000 200-300
书籍章节 500-800 100-150

4. 实战:构建完整的 RAG 应用

4.1 最简 RAG 示例(10 行代码)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
from langchain_core.vectorstores import InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from langchain_core.documents import Document
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate

# 1. 准备文档
docs = [
Document(page_content="苹果公司 2024 年营收达到 5000 亿美元"),
Document(page_content="苹果的总部在美国加州库比蒂诺"),
Document(page_content="苹果的代表产品有 iPhone, iPad, Mac"),
]

# 2. 创建向量存储
vectorstore = InMemoryVectorStore.from_documents(docs, OpenAIEmbeddings())
retriever = vectorstore.as_retriever(k=2) # 每次检索 2 个最相关的

# 3. 创建提示词
prompt = ChatPromptTemplate.from_template(
"""根据以下上下文回答问题。如果不知道,就说不知道。

上下文:
{context}

问题:{question}
答案:"""
)

# 4. 创建 RAG 链
chain = (
{"context": retriever, "question": RunnablePassthrough()}
| prompt
| ChatOpenAI(model="gpt-4o-mini")
| StrOutputParser()
)

# 5. 使用
answer = chain.invoke("苹果的总部在哪里?")
print(answer) # "苹果的总部在美国加州库比蒂诺"

4.2 完整的 RAG 应用(从文档加载到问答)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# ========== 第一步:加载文档 ==========
from langchain_community.document_loaders import (
PyPDFLoader, # PDF
Docx2txtLoader, # Word
TextLoader, # 文本
WebBaseLoader, # 网页
)

# 加载 PDF
loader = PyPDFLoader("company_handbook.pdf")
documents = loader.load()

# 加载多个文件
loaders = [
PyPDFLoader("handbook.pdf"),
Docx2txtLoader("policy.docx"),
WebBaseLoader("https://example.com/faq"),
]
documents = []
for loader in loaders:
documents.extend(loader.load())

# ========== 第二步:分割文档 ==========
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
chunk_size=1000,
chunk_overlap=200,
)
splits = text_splitter.split_documents(documents)

print(f"原始文档数:{len(documents)}")
print(f"分块后文档数:{len(splits)}")

# ========== 第三步:创建向量存储 ==========
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS

# 创建嵌入模型
embeddings = OpenAIEmbeddings(model="text-embedding-3-small")

# 创建向量存储
vectorstore = FAISS.from_documents(splits, embeddings)

# 保存到本地(可选)
vectorstore.save_local("faiss_index")

# 从本地加载(可选)
# vectorstore = FAISS.load_local("faiss_index", embeddings)

# ========== 第四步:创建检索器 ==========
retriever = vectorstore.as_retriever(
search_type="similarity", # similarity | mmr | similarity_score_threshold
search_kwargs={"k": 4} # 返回 4 个最相关的文档
)

# ========== 第五步:创建 RAG 链 ==========
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
from langchain_openai import ChatOpenAI

# 定义提示词
rag_prompt = ChatPromptTemplate.from_template("""你是一个专业的问答助手。
请根据下面的【上下文】来回答【问题】。

【要求】
1. 只根据上下文回答,不要编造信息
2. 如果上下文中没有答案,直接说"根据提供的文档,无法回答这个问题"
3. 回答要简洁、准确
4. 引用原文时请说明

【上下文】
{context}

【问题】
{question}

【答案】
""")

# 定义文档格式化函数
def format_docs(docs):
"""把检索到的文档合并成字符串"""
return "\n\n---\n\n".join(
f"[来源:{doc.metadata.get('source', '未知')}, 页码:{doc.metadata.get('page', 'N/A')}]\n{doc.page_content}"
for doc in docs
)

# 创建 RAG 链
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| rag_prompt
| ChatOpenAI(model="gpt-4o-mini", temperature=0)
| StrOutputParser()
)

# ========== 第六步:使用 ==========
questions = [
"公司的年假政策是什么?",
"如何申请报销?",
"工作时间是几点到几点?",
]

for q in questions:
print(f"\n问题:{q}")
answer = rag_chain.invoke(q)
print(f"答案:{answer}")

4.3 带对话历史的 RAG(多轮问答)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
from langchain.memory import ConversationBufferMemory
from langchain_core.prompts import MessagesPlaceholder

# 创建记忆
memory = ConversationBufferMemory(
return_messages=True,
output_key="answer",
input_key="question"
)

# 带历史对话的提示词
rag_prompt = ChatPromptTemplate.from_messages([
("system", """你是一个专业的问答助手。
根据【上下文】回答用户的【问题】。
如果有多轮对话历史,请参考历史来理解当前问题。"""),
MessagesPlaceholder(variable_name="history"), # 插入对话历史
("human", """【上下文】
{context}

【当前问题】
{question}

【答案】""")
])

# 创建链
from langchain_core.runnables import RunnableLambda

def load_memory(x):
return {"history": memory.load_memory_variables({})["history"]}

rag_with_memory = (
RunnableLambda(load_memory)
| {"context": retriever | format_docs, "question": lambda x: x["question"], "history": lambda x: x["history"]}
| rag_prompt
| ChatOpenAI(model="gpt-4o-mini")
| StrOutputParser()
)

# 多轮对话示例
questions = [
"公司的年假政策是什么?",
"那病假呢?", # 需要理解"那"指的是年假政策
"这两个有什么区别?", # 需要记住前面两个政策
]

for q in questions:
answer = rag_with_memory.invoke({"question": q})
memory.save_context({"input": q}, {"output": answer})
print(f"Q: {q}")
print(f"A: {answer}\n")

4.4 高级 RAG:混合搜索 + 重排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 混合搜索 = 语义搜索 + 关键词搜索
from langchain.retrievers import EnsembleRetriever
from langchain_community.retrievers import BM25Retriever

# 语义检索器(向量搜索)
vector_retriever = vectorstore.as_retriever(search_kwargs={"k": 5})

# 关键词检索器(BM25)
keyword_retriever = BM25Retriever.from_documents(splits)
keyword_retriever.k = 5

# 组合两个检索器
ensemble_retriever = EnsembleRetriever(
retrievers=[vector_retriever, keyword_retriever],
weights=[0.5, 0.5] # 各占 50%
)

# 使用新的检索器
rag_chain = (
{"context": ensemble_retriever | format_docs, "question": RunnablePassthrough()}
| rag_prompt
| ChatOpenAI(model="gpt-4o-mini")
| StrOutputParser()
)

5. 高级技巧与最佳实践

5.1 提高检索质量

技巧 1:Metadata 过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
# 给文档添加元数据
for doc in splits:
doc.metadata["category"] = "policy" # 类别
doc.metadata["year"] = 2024 # 年份
doc.metadata["department"] = "HR" # 部门

# 检索时过滤
retriever = vectorstore.as_retriever(
search_kwargs={
"k": 4,
"filter": {"category": "policy", "year": 2024}
}
)

技巧 2:多查询检索

1
2
3
4
5
6
7
8
9
10
11
12
13
from langchain.retrievers.multi_query import MultiQueryRetriever

# 让 LLM 从不同角度重新表述问题
retriever = MultiQueryRetriever.from_llm(
retriever=vectorstore.as_retriever(),
llm=ChatOpenAI(model="gpt-4o-mini"),
)

# 原问题:"公司休假政策"
# 会生成多个变体:
# - "年假有多少天?"
# - "病假怎么申请?"
# - "法定节假日放假吗?"

技巧 3:Parent Document Retriever

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
from langchain.retrievers.parent_document_retriever import ParentDocumentRetriever
from langchain.storage import InMemoryStore
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 大块存储,小块检索
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=2000)
child_splitter = RecursiveCharacterTextSplitter(chunk_size=400)

store = InMemoryStore() # 存储大块文档

retriever = ParentDocumentRetriever(
vectorstore=vectorstore,
docstore=store,
child_splitter=child_splitter,
parent_splitter=parent_splitter,
)

5.2 优化 RAG 响应质量

添加引用来源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
from langchain_core.runnables import RunnableParallel

def format_docs_with_citation(docs):
"""格式化文档并添加引用编号"""
formatted = []
for i, doc in enumerate(docs):
source = doc.metadata.get("source", "未知来源")
page = doc.metadata.get("page", "")
formatted.append(
f"[{i+1}] {source}{' 第'+str(page)+'页' if page else ''}\n{doc.page_content}"
)
return "\n\n".join(formatted)

prompt_with_citation = ChatPromptTemplate.from_template("""根据上下文回答问题,并在回答中标注引用来源(如 [1], [2])。

上下文:
{context}

问题:{question}

答案(带引用):""")

# 同时返回答案和来源文档
rag_with_sources = RunnableParallel(
answer=(
{"context": retriever | format_docs_with_citation, "question": RunnablePassthrough()}
| prompt_with_citation
| ChatOpenAI(model="gpt-4o-mini")
| StrOutputParser()
),
sources=retriever
)

result = rag_with_sources.invoke("问题...")
print(result["answer"])
print("\n来源文档:")
for doc in result["sources"]:
print(f"- {doc.metadata.get('source')}")

添加思考过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 在提示词中引导模型逐步思考
cot_prompt = ChatPromptTemplate.from_template("""请逐步思考并回答问题。

上下文:
{context}

问题:{question}

请按以下步骤回答:
1. 分析问题:这个问题在问什么?
2. 查找信息:从上下文中找到相关信息
3. 组织答案:整合信息形成完整回答
4. 检查验证:确认答案准确且基于上下文

你的回答:""")

5.3 性能优化

批量处理文档

1
2
3
4
5
6
7
8
9
# 批量添加向量,而不是一个一个添加
from langchain_community.vectorstores import FAISS

# 慢的方式
for doc in splits:
vectorstore.add_documents([doc])

# 快的方式(批量)
vectorstore.add_documents(splits, batch_size=100)

异步处理

1
2
3
4
5
6
# 异步调用
answer = await rag_chain.ainvoke("问题...")

# 批量异步
questions = ["问题 1", "问题 2", "问题 3"]
answers = await rag_chain.abatch(questions)

5.4 评估 RAG 质量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate

# 创建评估链
eval_prompt = ChatPromptTemplate.from_template("""评估 RAG 系统的答案质量。

问题:{question}
上下文:{context}
答案:{answer}

请从以下维度评分(1-5 分):
1. 相关性:答案是否回答了问题?
2. 准确性:答案是否基于上下文且正确?
3. 完整性:答案是否完整全面?
4. 引用:是否正确引用了来源?

评分和理由:""")

eval_chain = (
eval_prompt
| ChatOpenAI(model="gpt-4o-mini", temperature=0)
| StrOutputParser()
)

# 评估
evaluation = eval_chain.invoke({
"question": "问题...",
"context": "检索到的上下文...",
"answer": "生成的答案..."
})
print(evaluation)

6. 常见问题与解决方案

Q1: 检索到的文档不相关怎么办?

原因分析:

  • 文档分块太大或太小
  • Embedding 模型不适合你的领域
  • 检索参数设置不当

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1. 调整分块大小
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=300, # 减小块大小
chunk_overlap=50,
)

# 2. 使用更好的 Embedding
embeddings = OpenAIEmbeddings(model="text-embedding-3-large")

# 3. 增加检索数量
retriever = vectorstore.as_retriever(search_kwargs={"k": 10})

# 4. 使用混合搜索
from langchain.retrievers import EnsembleRetriever

Q2: LLM 编造信息(幻觉)怎么办?

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 1. 在提示词中明确要求
prompt = ChatPromptTemplate.from_template("""严格根据以下上下文回答问题。
如果上下文中没有答案,请直接说"根据提供的文档,无法回答这个问题",不要编造。

上下文:
{context}

问题:{question}
答案:""")

# 2. 降低 temperature
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)

# 3. 添加验证步骤
verify_prompt = ChatPromptTemplate.from_template("""检查以下答案是否完全基于上下文。
如果答案包含上下文中没有的信息,请指出。

上下文:{context}
答案:{answer}
验证结果:""")

Q3: 如何处理大量文档?

解决方案:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 1. 使用专业向量数据库(不是内存存储)
from langchain_community.vectorstores import FAISS # 支持磁盘存储
# 或
from langchain_milvus import Milvus # 专业向量数据库

# 2. 增量添加文档
vectorstore = FAISS.load_local("index_path", embeddings)
vectorstore.add_documents(new_documents)
vectorstore.save_local("index_path")

# 3. 分批次处理
batch_size = 1000
for i in range(0, len(documents), batch_size):
batch = documents[i:i+batch_size]
vectorstore.add_documents(batch)

Q4: 如何实现多语言支持?

1
2
3
4
5
6
7
8
9
10
11
12
# 1. 使用多语言 Embedding
from langchain_community.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
model_name="sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2"
)

# 2. 在提示词中指定语言
prompt = ChatPromptTemplate.from_template("""用中文回答以下问题。

上下文:{context}
问题:{question}
答案:""")

附录:快速参考手册

常用 Import

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 模型
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain_anthropic import ChatAnthropic

# 文档处理
from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter

# 向量存储
from langchain_community.vectorstores import FAISS, Chroma
from langchain_core.vectorstores import InMemoryVectorStore

# 检索
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser

# 提示词
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

# 记忆
from langchain.memory import ConversationBufferMemory

# 工具与代理
from langchain.tools import tool
from langchain.agents import create_agent

核心流程图

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
完整 RAG 应用架构

┌─────────────────────────────────────────────────────────────┐
│ 用户界面 │
│ (Streamlit / Web / CLI) │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ LangChain 应用层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ RAG Chain │ │ Agent │ │ Memory Management │ │
│ │ (问答核心) │ │ (工具调用) │ │ (对话历史) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 检索层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ Retriever │ │ Vector Store│ │ Embedding Model │ │
│ │ (检索策略) │ │ (FAISS等) │ │ (向量生成) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────┐
│ 数据层 │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────────┐ │
│ │ PDF/Word │ │ 数据库 │ │ API/网页 │ │
│ │ (文档加载) │ │ (结构化数据)│ │ (实时数据) │ │
│ └─────────────┘ └─────────────┘ └─────────────────────┘ │
└─────────────────────────────────────────────────────────────┘

学习路线建议

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
第 1 天:LangChain 基础
- 安装和环境配置
- 模型调用(ChatOpenAI)
- 提示词模板(ChatPromptTemplate)

第 2 天:链和输出解析
- 创建简单的 Chain
- 输出解析器(StrOutputParser)
- Runnable 接口

第 3 天:RAG 入门
- Embedding 和向量
- 文档加载和分块
- 向量存储和检索

第 4 天:完整 RAG 应用
- 构建端到端 RAG
- 添加对话历史
- 优化检索质量

第 5 天:高级主题
- Agent 和 Tools
- 混合搜索
- 评估和优化

第 6-7 天:实战项目
- 选择实际场景
- 完整实现
- 调优和部署

环境搭建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 基础安装
pip install langchain langchain-core langchain-community

# OpenAI 支持
pip install langchain-openai

# 文档加载器
pip install pypdf docx2txt beautifulsoup4

# 向量数据库
pip install faiss-cpu chromadb

# 可选:Web 界面
pip install streamlit

# 验证安装
python -c "from langchain_openai import ChatOpenAI; print('安装成功!')"

总结

LangChain 核心要点:

  1. Models - LLM 是大脑
  2. Prompts - 好的提示词 = 好的输出
  3. Chains - 组合组件形成工作流
  4. Agents - 让 LLM 自主使用工具
  5. Memory - 保持对话连续性

RAG 核心要点:

  1. 文档分块 - 大小要合适
  2. 向量检索 - 找到相关内容
  3. 提示词设计 - 引导 LLM 正确回答
  4. 评估优化 - 持续改进质量

学习建议:

  • 先跑通最简单的示例
  • 理解每个组件的作用
  • 逐步添加功能
  • 在实际项目中练习

langchain与rag简单快速入门
https://www.furinaluna.top/posts/297d2532.html
作者
Furina
发布于
2026年4月5日
更新于
2026年9月11日
许可协议
BY FURINA