# 基本介绍
官网 (opens new window) 中文网 (opens new window)
- 核心功能:
开发(Development) # 通过开源组件和第三方集成构建 LLM 应用
生产化(Productionization) # 使用 LangSmith 监控、调试和评估应用
部署(Deployment) # 通过 LangGraph Platform 将应用部署为 API 或助手服务
- 关键工具链:
langchain-core # 核心接口(如 Runnable)、基础抽象和LangChain表达式语言
langchain-community # 第三方集成包(例如langchain-openai,langchain-anthropic等)
langgraph # 通过将步骤建模为图中的边和节点,使用 LLM 构建健壮且有状态的多角色应用程序
LangSmith # 追踪与评估
Langserve # 部署为 REST API
# 搭建 RAG
- RAG 是如何检索的
向量化 # 使用 Embedding 模型将文本转为向量
相似度计算 # 使用余弦相似度(cosine similarity)在向量数据库查找最接近的文档
返回 Top-K # 返回最相关的K的文档作为上下文
- RAG 是如何生成答案的
# 将用户问题+检索到的上下文一起拼接成prompt
# 输入给LLM进行推理
# LLM仅基于上下文作答,避免幻觉
- 技术栈选型
文本加载 # PyPDF2/Unstructured
分块工具 # RecursiveCharacterTextSplitter
Embedding # text-embedding-ada-002/Qwen-embedding
向量数据库 # Chroma/FAISS/PostgreSQL+pgvector(本地)/Pinecone(云端)/ Milvus
大模型 # Qwen-30B/Qwen-32B
部署框架 # FastAPI+Uvicorn
- 核心流程
数据摄取 # 加载 PDF/Word/ 网页等格式文件
文本分块 # 将长文本拆分为 500-1000 字的语义片段
向量索引 # 通过 Embedding 模型生成向量
向量存储 # 向量存储到数据库
检索增强 # 根据用户问题检索相关文档片段
LLM选择 # 配置大语言模型
生成优化 # 将检索结果与问题结合生成最终回答
# 数据摄取
因为数据源是多种多样的,langchain 中使用 Loader 对各种数据源进行支持。一些常用的:
pip install pypdf
from langchain_community.document_loaders import PyPDFLoader
from langchain_community.document_loaders import TextLoader
from langchain_community.document_loaders import CSVLoader
# 进行简单的文本提取,不考虑文档结构,适用于只需纯文本内容的场景
pip install docx2txt
from langchain_community.document_loaders import Docx2txtLoader
# 能识别文档结构(如标题、段落、列表),将其转换为带有元数据的文本块,便于后续处理
pip install unstructured
pip install python-docx
from langchain_community.document_loaders import UnstructuredWordDocumentLoader
from langchain_community.document_loaders import UnstructuredMarkdownLoader
from langchain_community.document_loaders import UnstructuredHTMLLoader
from langchain_community.document_loaders import JSONLoader
from langchain_community.document_loaders import WebBaseLoader
# 加载PDF文件
# 需要安装 pip install PyPDF PyPDF2
loader = PyPDFLoader("data/report.pdf")
documents = loader.load()
# 加载本地文本文件
loader = TextLoader("data/faq.txt")
loader = TextLoader("data/faq.md")
documents += loader.load()
# 加载网页内容
loader = WebBaseLoader("https://example.com")
documents += loader.load()
# 读取到的数据结构是 Document 对象
from langchain_core.documents import Document
非结构化文档加载 UnstructuredWordDocumentLoader 会使用 nltk
- 需要把【packages】 文件夹名换成 :【nltk_data】,放在【/root/nltk_data】
- 然后把【tokenizers】文件夹下的【punkt.zip】进行解压,才可能使用
# 文本分块
七种不同的字符文本分割 TextSplitter
from langchain_text_splitters import CharacterTextSplitter
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_text_splitters import TokenTextSplitter
from langchain_text_splitters import SpacyTextSplitter
from langchain_text_splitters import SentenceTransformersTokenTextSplitter
from langchain_text_splitters import NLTKTextSplitter
from langchain_text_splitters import KonlpyTextSplitter
# pip install langchain_text_splitters
# RecursiveCharacterTextSplitter 使用
# chunk_size 指定字符串和,重叠文本的长度
text_splitter = RecursiveCharacterTextSplitter(chunk_size=300, chunk_overlap=50)
# CharacterTextSplitter的 使用,用到 tiktoken_encoder
text_splitter = CharacterTextSplitter.from_tiktoken_encoder(
encoding_name="cl100k_base",
chunk_size=100, # chunk_size 指定字符串和
chunk_overlap=0 # 重叠文本的长度
)
# document
splits = text_splitter.split_documents(docs)
# text
texts = text_splitter.split_text(document)
# 向量索引
查看 langchain 支持 embeddings 模型 (opens new window)
- 使用 OpenAI 的 embeddings + InMemoryVectorStore
from langchain_openai import OpenAIEmbeddings
from langchain_core.vectorstores import InMemoryVectorStore
embeddings_model = OpenAIEmbeddings()
vector_store = InMemoryVectorStore(embedding=SomeEmbeddingModel())
# 向向量数据库添加文档
vector_store.add_documents(splits)
- 使用 ZhipuAI 的 embeddings + FAISS
from langchain_community.embeddings import ZhipuAIEmbeddings
from langchain_community.vectorstores import FAISS
import dotenv
class ZhipuEmbeddings():
api_key = dotenv.get_key(".env", "api_key")
@classmethod
def create_zhipu_embeddings(self, model_name):
embeddings = ZhipuAIEmbeddings(
model=model_name,
api_key=self.api_key
)
return embeddings
vector_store = FAISS.from_documents(splits, ZhipuEmbeddings())
- 使用 OllamaEmbeddings + Chroma
from langchain_community.embeddings import OllamaEmbeddings
from langchain_community.vectorstores import Chroma
embeddings = OllamaEmbeddings(model="llama2")
vector_store = Chroma.from_documents(splits, embeddings)
- 使用 Qwen3 Embeddig + Milvus
from langchain_community.vectorstores import Milvus
# 需要安装 pip install pymilvus
URI = "./milvus_example.db"
vector_store = Milvus(
embedding_function=embeddings,
connection_args={"uri": URI},
)
# 向向量数据库添加文档
vector_store.add_documents(splits)
# 向量存储
- 向量数据 VectorStore 的核心方法:
add_texts(texts, metadatas) # 将文本及其元数据嵌入并存储到 VectorStore
similarity_search(query, k) # 基于查询向量,返回最相似的 k 个结果
similarity_search_with_score # 使用距离运行相似性搜索
delete(ids) # 根据指定的 ID 删除向量
from_documents(documents) # 从文档列表构建向量存储
save_local(path) 和 load_local(path) # 将向量存储保存到本地或从本地加载
- 具体使用,更适合直接的向量相似度搜索需求
query = "主要业务?"
# 搜索向量
docs = vectorstore.similarity_search(query)
# 检索增强
将 VectorStore 转换为检索器,更适合构建复杂的 RAG 应用,可以方便地更换不同的检索策略
# 转成检索器,配置检索参数
retriever = vector_store.as_retriever(
search_type="similarity",
# search_type="similarity_score_threshold",
search_kwargs={"k": 5, "score_threshold": 0.7}
)
# 检索
retrieved_docs = retriever.invoke("主要业务?")
# LLM选择
- 本地模型部署
from langchain_community.llms.ollama import Ollama
llm2 = Ollama(
base_url="http://localhost:11434",
model="models/qwen-1.8-chat-int4.bin",
temperature=0.6,
)
- 云端模型调用
from langchain_openai import ChatOpenAI
load_dotenv()
llm = ChatOpenAI(
openai_api_base="https://dashscope.aliyuncs.com/compatible-mode/v1",
openai_api_key=os.getenv("DASHSCOPE_API_KEY"),
model_name="qwen-plus",
temperature=0.7
)
# 生成优化
使用 Langchian 的 chain 组合上传文档生成内容
- retriever 做来 context 的值传递给 chain 后面的内容
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_core.output_parsers import StrOutputParser
# 提示词模板
prompt_template = """
请根据以下上下文回答问题:
上下文:{context}
问题:{question}
答案:
"""
prompt = ChatPromptTemplate.from_template(prompt_template)
def format_docs(documents):
return "\n\n".join(doc.page_content for doc in documents)
# RunnablePassthrough:将原始输入原样传递给下一步
rag_chain = (
{"context": retriever | format_docs, "question": RunnablePassthrough()}
| prompt
| llm
| StrOutputParser()
)
- 使用 create_retrieval_chain api 来创建一个 rag_chain
from langchain.chains import create_retrieval_chain
document_chain = create_stuff_documents_chain(llm, prompt)
rag_chain = create_retrieval_chain(retriever, document_chain)
# 问题测试
# .invoke(input) 单次调用
# .batch(inputs) 批量调用(并发)
# .stream(input) 流式输出
# .ainvoke(input)/abatch(inputs) 异步调用
response = rag_chain.invoke("主要业务?")
print(response)
# 测试多个问题
questions = [
"主要业务?",
"产品介绍?",
"客户案例?"
]
for question in questions:
response = rag_chain.invoke(question)
print(f"问题: {question}\n答案: {response}\n")
# Langgraph
LangGraph 是一个强大的 Agent 开发框架,它让复杂的多步骤推理变得更加可控和可靠
← 基础知识