目标: 学习 LangChain 的数据处理、记忆和工具集成能力,为构建更复杂的应用奠定基础。
- 数据连接(Data Connection):
- 文档加载器(Document Loaders): 从不同来源(PDF, TXT, CSV, 网页等)加载数据。
- 文本分割器(Text Splitters): 将长文本分割成适合 LLM 处理的块(如
RecursiveCharacterTextSplitter)。 - 嵌入(Embeddings): 理解将文本转换为向量的原理及其重要性。
- 向量存储(Vector Stores): 存储和查询文本嵌入(如
FAISS,ChromaDB,Pinecone)。 - 检索器(Retrievers): 根据查询从向量存储中检索相关文档。
- 检索增强生成(Retrieval Augmented Generation, RAG): 结合检索与 LLM 生成,实现基于私有数据的问答。
- 记忆(Memory):
- 记忆的重要性: 实现多轮对话的上下文连贯性。
- 分类:数据库持久化记忆、键值记忆、摘要记忆、滑动窗口记忆、完整对话历史记忆、无记忆模式
- LangGraph:SqliteSaver,MemorySaver,InMemorySaver
- 工具(Tools):
- 为什么 Agent 需要工具
- 内部工具、自定义工具
一、数据连接
常见加载器类型
| 来源 | 加载器类名 |
|---|---|
| 本地 PDF | PyPDFLoader |
| 本地 TXT | TextLoader |
| 本地 CSV | CSVLoader |
| 网页 | WebBaseLoader |
| YouTube | YoutubeLoader |
文本分割
当处理长文本(如 100 页的 PDF)时,直接输入 LLM 会遇到两个问题:
- 上下文窗口超限:LLM 有最大 token 限制,长文本会被截断;
- 检索精度低:若将整本书作为一个 “块” 存储,当查询具体细节(如 “第三章第二点”)时,很难精准匹配。
因此,文本分割器的作用是:将长文本拆分为语义连贯的 “小文本块”,既避免超过 LLM 上下文限制,又能提高后续检索的相关性。LangChain 中最常用的是RecursiveCharacterTextSplitter,它的设计原则是 “按语义边界分割”,尽可能保留文本的语义连贯性,工作原理如下:
按 “优先级从高到低” 的分隔符递归分割:
- 先尝试用最强语义分隔符(如
\n\n,表示段落间隔)分割; - 若分割后块仍过大,再用次强分隔符(如
\n,表示换行); - 若仍过大,继续用更弱分隔符(如空格、标点),直到块大小符合要求。
关键参数
chunk_size:每个文本块的最大长度(单位:通常按 token 数,1token≈0.75 英文单词 / 0.25 中文汉字);chunk_overlap:相邻块的重叠长度(作用:保留上下文关联,避免分割后语义断裂,通常设为chunk_size的 10%-20%)。
补充其他分割器
CharacterTextSplitter:简单按固定字符(如\n)分割,不考虑语义(适合纯代码、日志等无复杂语义的文本);TokenTextSplitter:按 LLM 的 token 规则分割(直接控制 token 数,避免超限,但可能破坏语义);MarkdownTextSplitter:按 Markdown 格式(标题、列表等)分割(适合 MD 文档)。
嵌入
人类通过文字的 “语义” 理解含义,但计算机无法直接理解文字,需要将文本转换为可计算的数值形式。Embeddings(嵌入)就是实现这一转换的技术:
- 定义:Embeddings 模型将文本(词、句、段落)映射到高维向量空间(如 384 维、768 维),每个文本对应一个向量;
- 核心特性:向量的 “距离”(如余弦距离)反映语义相似度 —— 两个文本的向量距离越近,语义越相似(例:“猫” 和 “狗” 的向量距离,比 “猫” 和 “汽车” 更近)。
Embeddings 是后续 “向量存储” 和 “检索” 的基础:
- 没有向量,计算机无法判断 “用户查询” 与 “文档内容” 的相关性;
- 只有将文本转为向量后,才能通过 “向量相似度搜索” 快速找到与查询相关的文档。
向量存储
向量存储是专门用于存储文本嵌入向量的数据库,核心能力是:当输入一个 “查询向量”(用户问题的嵌入)时,能快速找到与它最相似的向量对应的文本块(基于余弦相似度、欧氏距离等算法)
| 向量存储 | 类型 | 特点与适用场景 |
|---|---|---|
| FAISS | 本地开源 | Facebook 推出的轻量级库,纯本地运行(无需服务器),适合开发测试、小数据量场景。 |
| ChromaDB | 本地 / 云端 | 开源且易用,支持内存 / 磁盘存储,自带嵌入能力(可简化代码),适合快速原型开发。 |
| Pinecone | 云端服务 | 托管式服务(无需维护基础设施),支持大规模数据(亿级向量),适合生产环境。 |
| Milvus | 分布式开源 | 支持超大规模数据(十亿级),适合企业级私有部署,需一定运维能力。 |
RAG
RAG 的优势
- 突破LLM知识截止限制
- 支持私有领域知识问答
- 提供答案来源追溯(检索文档)
import os
from dotenv import load_dotenv
from langchain.chains.retrieval_qa.base import RetrievalQA
from langchain.chat_models import init_chat_model
from langchain_community.document_loaders import PyPDFLoader, WebBaseLoader, TextLoader
os.environ["TOKENIZERS_PARALLELISM"] = "false"
text_loader = TextLoader("sample.txt")
text_docs = text_loader.load() # List[Document]
print("txt 页数:", len(text_docs))
print("第一页前 200 字:", text_docs[0].page_content[:200])
web_loader = WebBaseLoader("https://python.langchain.com/docs/get_started/introduction")
web_docs = web_loader.load()
print("网页字符数:", len(web_docs[0].page_content))
loader = PyPDFLoader("企业手册.pdf") # 初始化加载器,传入文件路径
pdf_documents = loader.load() # 执行加载,返回Document对象列表
from langchain_text_splitters import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=500,
chunk_overlap=50,
add_start_index=True# 额外记录每块在原文中的起始位置
)
split_docs = text_splitter.split_documents(text_docs + web_docs +pdf_documents)
print("切分后块数:", len(split_docs))
from langchain_huggingface import HuggingFaceEmbeddings # 新导入路径
embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2") # 使用新包)
# 对文本生成向量(以分割后的文本块为例)
sample_text = split_docs[0].page_content # 取分割后的第一个块
vector = embeddings.embed_query(sample_text) # 生成向量
print(f"文本:{sample_text[:50]}...")
print(f"向量维度:{len(vector)}(all-MiniLM-L6-v2输出384维)")
print(f"向量前5个值:{vector[:5]}") # 输出:[-0.02, 0.05, ...](高维浮点数)
from langchain_community.vectorstores import FAISS
# 将分割后的文本块(split_docs)转为向量并存储到FAISS
db = FAISS.from_documents(
documents=split_docs, # 分割后的文本块列表
embedding=embeddings # 嵌入模型
)
# 保存到本地(后续可直接加载,无需重新处理)
db.save_local("企业手册向量库")
load_dotenv()
# 1. 初始化 DeepSeek 模型
llm = init_chat_model(
model="deepseek-chat",
temperature=0.7
)
db = FAISS.load_local("企业手册向量库", HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2"), allow_dangerous_deserialization=True)
retriever = db.as_retriever(search_kwargs={"k": 5})
# 3. 构建RAG链
qa_chain = RetrievalQA.from_chain_type(
llm=llm,
chain_type="stuff",
retriever=retriever,
return_source_documents=True
)
# 4. 提问并获取回答
query = "该企业申请了多少专利"
result = qa_chain.invoke({"query": query})
# 输出结果
print("回答:", result["result"])
print("\n引用的文档:")
for doc in result["source_documents"]:
print(f"- 来源页码:{doc.metadata.get('page')},内容:{doc.page_content}")
二、记忆
分类
| 记忆模式 | 描述 | 适用场景 | 实现方式 | 优点 | 缺点 |
|---|---|---|---|---|---|
| 无记忆模式 | 不保留任何对话历史,每次交互独立。 | 单次查询、无上下文任务。 | 不使用检查点,直接调用 llm.invoke。 | 简单、资源占用低。 | 无法处理多轮对话,缺乏上下文。 |
| 完整对话历史记忆 | 存储所有消息,传递完整上下文。 | 需要完整上下文的对话(如客服)。 | 使用 MemorySaver 或 SqliteSaver,存储 messages。 | 提供完整上下文,适合复杂对话。 | 上下文过长可能导致性能问题。 |
| 滑动窗口记忆 | 保留最近 N 条消息,丢弃早期历史。 | 长对话、主题变化频繁。 | 截取 state ["messages"][-N:]。 | 控制上下文长度,提高效率。 | 可能丢失早期重要信息。 |
| 摘要记忆 | 定期生成对话摘要,替换完整历史。 | 长对话、需要保留关键信息。 | 使用 LLM 生成摘要,存储在状态中。 | 减少上下文长度,保留关键信息。 | 摘要可能丢失细节,增加计算成本。 |
| 键值记忆 | 提取关键信息为键值对存储。 | 需要记住特定事实(如用户名)。 | 使用 ConversationEntityMemory 或自定义键值存储 | 高效存储结构化数据。 | 需要定义提取逻辑,不适合复杂上下文。 |
| 数据库持久化记忆 | 将状态存储在数据库中,支持长期持久化。 | 多用户系统、跨会话一致性。 | 使用 SqliteSaver 或 PostgresSaver。 | 支持多用户、长期存储。 | 数据库维护和配置复杂。 |
import sqlite3
from typing import TypedDict, Annotated, Sequence
import operator
from dotenv import load_dotenv
from langchain.chat_models import init_chat_model
from langchain_core.messages import BaseMessage, HumanMessage
from langgraph.checkpoint.serde.encrypted import EncryptedSerializer
from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.graph import StateGraph, END
from langgraph.checkpoint.memory import MemorySaver, InMemorySaver
# 加载环境变量并初始化语言模型
load_dotenv()
llm = init_chat_model(
model="deepseek-chat",
temperature=0.7
)
# --- 1. 定义图的状态 (State) ---
classAgentState(TypedDict):
messages: Annotated[Sequence[BaseMessage], operator.add]
# --- 2. 定义图的节点 (Nodes) ---
defcall_llm(state: AgentState):
"""
调用LLM的节点,接收状态并返回更新后的消息。
"""
messages = state['messages']
response = llm.invoke(messages)
return {"messages": [response]}
# --- 3. 组装图 (Graph) ---
graph_builder = StateGraph(AgentState)
graph_builder.add_node("chatbot", call_llm)
graph_builder.set_entry_point("chatbot")
graph_builder.add_edge("chatbot", END)
# 使用内存检查点来持久化状态
checkpointer1 = MemorySaver()
checkpointer2=InMemorySaver()
conn = sqlite3.connect(
"checkpoint.db",
check_same_thread=False# 解决线程不匹配问题
)
# 配置加密序列化器和SQLite检查点
serde = EncryptedSerializer.from_pycryptodome_aes()
checkpointer3 = SqliteSaver(
conn, # 使用配置好的连接
serde=serde
)
# 编译图,启用检查点
chain = graph_builder.compile(checkpointer=checkpointer3)
# --- 4. 对话循环 ---
defrun_conversation():
# 使用线程ID来跟踪对话(模拟会话ID)
thread_id = "conversation_1"
print("你好!我是 DeepSeek 聊天助手。输入 'exit' 或 'quit' 退出。")
whileTrue:
try:
user_input = input("你: ")
if user_input.lower() in ["exit", "quit"]:
print("再见!")
break
# 直接将用户输入作为新消息传入
result = chain.invoke(
{"messages": [HumanMessage(content=user_input)]},
config={"configurable": {"thread_id": thread_id}}
)
# 获取最新的 AI 回复
ai_response = result["messages"][-1].content
print(f"AI: {ai_response}")
except (KeyboardInterrupt, EOFError):
print("\n再见!")
break
if __name__ == "__main__":
run_conversation()
代码说明
- 状态持久化:通过 SQLite + AES 加密实现安全的对话状态存储
- 模块化设计:状态定义 → 节点逻辑 → 图构建 → 持久化 → 执行 清晰分离
- 多存储支持:同时演示了三种不同的检查点存储方案
- 线程安全:SQLite 连接设置
check_same_thread=False解决多线程问题
三、工具
为什么需要工具
大型语言模型 (LLM) 本身非常强大,拥有海量的知识。但它们存在一些固有的局限性:
- 知识截止日期 (Knowledge Cutoff): LLM 的知识是基于其训练数据的,这些数据在某个时间点之后就不再更新。它们不知道“今天”发生了什么。
- 不擅长精确计算 (Poor at Precise Math): LLM 可以理解数学概念,但对于复杂的或需要高精度的计算,它们很容易出错。
- 无法与外部系统交互 (Inability to Interact with External Systems): LLM 无法主动浏览网页、查询数据库、读取你的本地文件或发送电子邮件。它只是一个文本生成模型。
LangChain 提供了许多开箱即用的工具,方便我们快速构建强大的 Agent
from langchain.chat_models import init_chat_model
from langchain_community.tools import WikipediaQueryRun
from langchain_community.utilities import WikipediaAPIWrapper
from langchain_core.tools import tool
from langchain_core.messages import HumanMessage
from langgraph.prebuilt import create_react_agent
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
llm = init_chat_model(model="deepseek-chat", temperature=0)
# 自定义数学工具
@tool
defcalculator(expression: str) -> str:
"""Evaluates a mathematical expression and returns the result."""
try:
return str(eval(expression)) # Use sympy in production for safety
except Exception as e:
returnf"Error: Invalid expression ({str(e)})"
# 初始化 Wikipedia 工具
wiki = WikipediaQueryRun(api_wrapper=WikipediaAPIWrapper())
tools = [calculator, wiki]
agent_executor = create_react_agent(llm, tools)
print("=== 示例 1:数学计算 (551368 ÷ 82) ===")
math_query = "What is 551368 divided by 82?"
math_response = agent_executor.invoke({"messages": [HumanMessage(content=math_query)]})
print(f"数学计算结果: {math_response['messages'][-1].content}")
print("\n=== 示例 2:数学计算 ((10 + 5) * 2) ===")
math_query = "What is (10 + 5) * 2?"
math_response = agent_executor.invoke({"messages": [HumanMessage(content=math_query)]})
print(f"数学计算结果: {math_response['messages'][-1].content}")
print("\n=== 示例 3:维基百科查询 ===")
wiki_query = "Tell me about the Python programming language."
wiki_response = agent_executor.invoke({"messages": [HumanMessage(content=wiki_query)]})
print(f"维基百科查询结果: {wiki_response['messages'][-1].content}")

知识总结
| 知识点类别 | 具体内容 | 说明 |
|---|---|---|
| 环境配置 | load_dotenv() | 加载环境变量(通常用于存储 API 密钥等敏感信息),需安装python-dotenv库 |
| 大模型初始化 | init_chat_model() | LangChain 的聊天模型初始化函数,支持多种模型(此处使用 deepseek-chat) |
| 工具定义 | @tool 装饰器 | 用于定义自定义工具函数,使智能体能够识别和调用 |
| 第三方工具集成 | WikipediaQueryRun | 维基百科查询工具,基于WikipediaAPIWrapper实现 |
| 智能体创建 | create_react_agent() | LangGraph 提供的创建 ReAct 模式智能体的函数 |
| 智能体调用 | agent_executor.invoke() | 调用智能体执行任务,参数为包含消息的字典 |
敏感信息),需安装python-dotenv库 | ||
| 大模型初始化 | init_chat_model() | LangChain 的聊天模型初始化函数,支持多种模型(此处使用 deepseek-chat) |
| 工具定义 | @tool 装饰器 | 用于定义自定义工具函数,使智能体能够识别和调用 |
| 第三方工具集成 | WikipediaQueryRun | 维基百科查询工具,基于WikipediaAPIWrapper实现 |
| 智能体创建 | create_react_agent() | LangGraph 提供的创建 ReAct 模式智能体的函数 |
| 智能体调用 | agent_executor.invoke() | 调用智能体执行任务,参数为包含消息的字典 |
| 消息类型 | HumanMessage | LangChain 中的消息类型,表示人类输入的消息 |
如何系统学习掌握AI大模型?
AI大模型作为人工智能领域的重要技术突破,正成为推动各行各业创新和转型的关键力量。抓住AI大模型的风口,掌握AI大模型的知识和技能将变得越来越重要。
学习AI大模型是一个系统的过程,需要从基础开始,逐步深入到更高级的技术。
这里给大家精心整理了一份
全面的AI大模型学习资源,包括:AI大模型全套学习路线图(从入门到实战)、精品AI大模型学习书籍手册、视频教程、实战学习、面试题等,资料免费分享!

1. 成长路线图&学习规划
要学习一门新的技术,作为新手一定要先学习成长路线图,方向不对,努力白费。
这里,我们为新手和想要进一步提升的专业人士准备了一份详细的学习成长路线图和规划。可以说是最科学最系统的学习成长路线。

2. 大模型经典PDF书籍
书籍和学习文档资料是学习大模型过程中必不可少的,我们精选了一系列深入探讨大模型技术的书籍和学习文档,它们由领域内的顶尖专家撰写,内容全面、深入、详尽,为你学习大模型提供坚实的理论基础。(书籍含电子版PDF)

3. 大模型视频教程
对于很多自学或者没有基础的同学来说,书籍这些纯文字类的学习教材会觉得比较晦涩难以理解,因此,我们提供了丰富的大模型视频教程,以动态、形象的方式展示技术概念,帮助你更快、更轻松地掌握核心知识。

4. 大模型行业报告
行业分析主要包括对不同行业的现状、趋势、问题、机会等进行系统地调研和评估,以了解哪些行业更适合引入大模型的技术和应用,以及在哪些方面可以发挥大模型的优势。

5. 大模型项目实战
学以致用 ,当你的理论知识积累到一定程度,就需要通过项目实战,在实际操作中检验和巩固你所学到的知识,同时为你找工作和职业发展打下坚实的基础。

6. 大模型面试题
面试不仅是技术的较量,更需要充分的准备。
在你已经掌握了大模型技术之后,就需要开始准备面试,我们将提供精心整理的大模型面试题库,涵盖当前面试中可能遇到的各种技术问题,让你在面试中游刃有余。

全套的AI大模型学习资源已经整理打包,有需要的小伙伴可以
微信扫描下方优快云官方认证二维码,免费领取【保证100%免费】

3097

被折叠的 条评论
为什么被折叠?



