步骤1:配置APIkey

LangChain 提供了简单直观的 API 来快速构建 LLM 应用程序。

申请 API key 并配置环境变量 在系统环境变量中设置对应大模型API_KEY OPENAI_API_KEY=your-api-key

步骤2:定义大模型

from langchain_openai import ChatOpenAI
llm = ChatOpenAI(model="gpt-3.5-turbo")

步骤3:定义消息列表

from langchain_core.messages import HumanMessage, SystemMessage
messages = [
    SystemMessage(content="你是一个 helpful assistant."),
    HumanMessage(content="请介绍你自己")
]

步骤4:调用大模型

response = llm.invoke(messages)

步骤5:输出解析

print(response.content)

步骤6:链式执行

from langchain_core.output_parsers import StrOutputParser
chain = llm | StrOutputParser()
result = chain.invoke(messages)

2. 聊天模型核心能力

定义聊天模型

# 方式1:ChatOpenAI
from langchain_openai import ChatOpenAI
chat = ChatOpenAI(model="gpt-3.5-turbo")
​
# 方式2:init_chat_model
from langchain_community.chat_models import init_chat_model
chat = init_chat_model("openai", model="gpt-3.5-turbo")

聊天模型--调用工具

创建工具

# 使用 @tool 装饰器创建工具
from langchain_core.tools import tool
@tool
def add(a: int, b: int) -> int:
    """Add two numbers"""
    return a + b
​
# 使用 StructuredTool 类提供的函数创建工具
from langchain_core.tools import StructuredTool
def multiply(a: int, b: int) -> int:
    """Multiply two numbers"""
    return a * b
multiply_tool = StructuredTool.from_function(multiply)

绑定工具

tools = [add, multiply_tool]
chat_with_tools = chat.bind_tools(tools)

工具调用

response = chat_with_tools.invoke("计算 3 + 5")

强制模型调用工具

response = chat_with_tools.invoke("计算 3 + 5", tool_choice="add")

工具属性

@tool
def complex_operation(a: int, b: int, c: str) -> str:
    """Complex operation with description and parameters"""
    return f"Result: {a + b}, {c}"

将工具输出传递给聊天模型

tool_call = response.tool_calls[0]
tool_output = add.invoke(tool_call["args"])
final_response = chat_with_tools.invoke([
    HumanMessage(content="计算 3 + 5"),
    response,
    ToolMessage(tool_output=tool_output, tool_call_id=tool_call["id"])
])

聊天模型--结构化输出

with_structured_output()

from pydantic import BaseModel, Field
class Joke(BaseModel):
    setup: str = Field(description="question to set up a joke")
    punchline: str = Field(description="answer to resolve the joke")
structured_llm = chat.with_structured_output(Joke)
joke = structured_llm.invoke("tell me a joke")

返回 Pydantic 对象

class Person(BaseModel):
    name: str
    age: int
structured_output = chat.with_structured_output(Person)
person = structured_output.invoke("John is 30 years old")

返回 TypedDict

from typing import TypedDict
class Person(TypedDict):
    name: str
    age: int
structured_output = chat.with_structured_output(Person)
person = structured_output.invoke("John is 30 years old")

返回 JSON

structured_output = chat.with_structured_output(schema={"properties": {"name": {"type": "string"}, "age": {"type": "integer"}}})
person = structured_output.invoke("John is 30 years old")

选择输出格式

# 返回 Pydantic
structured_output = chat.with_structured_output(Joke)
​
# 返回 JSON Schema
structured_output = chat.with_structured_output(Joke.model_json_schema())
​
# 返回 TypedDict
structured_output = chat.with_structured_output(Person)

聊天模型--流式传输

stream() 同步传输

for chunk in chat.stream("写一个关于AI的故事"):
    print(chunk.content, end="", flush=True)

astream() 异步传输

async for chunk in chat.astream("写一个关于AI的故事"):
    print(chunk.content, end="", flush=True)

使用 StrOutputParser 解析模型的输出

from langchain_core.output_parsers import StrOutputParser
chain = chat | StrOutputParser()
async for chunk in chain.astream("写一个关于AI的故事"):
    print(chunk, end="", flush=True)

自定义流式输出解析器

from langchain_core.output_parsers import BaseOutputParser
class CustomParser(BaseOutputParser):
    def parse(self, text):
        return text.upper()
chain = chat | CustomParser()
async for chunk in chain.astream("写一个关于AI的故事"):
    print(chunk, end="", flush=True)

SSE 协议介绍 SSE (Server-Sent Events) 是一种允许服务器向客户端推送实时更新的技术,常用于流式传输。

LangChain 流式传输流程分析

  1. 客户端发起请求

  2. 服务器保持连接打开

  3. 服务器分块发送数据

  4. 客户端接收并处理每个数据块

使用 LangSmith 跟踪 LLM 应用

from langchain.callbacks import LangChainTracer
tracer = LangChainTracer(project_name="my-project")
with tracer:
    response = chat.invoke("你好")

3. 核心组件(Components)

LangChain 的核心组件包括:

  • LLMs (大语言模型)

  • Prompts (提示词)

  • Chains (链)

  • Indexes (索引)

  • Agents (代理)

  • Memory (记忆)

  • Output Parsers (输出解析器)

4. 消息(Messages)

LLM 消息结构 LangChain 支持多种消息类型,包括 HumanMessage、AIMessage、SystemMessage 等。

LangChain 消息

from langchain_core.messages import (
    HumanMessage,
    SystemMessage,
    AIMessage,
    ToolMessage,
    FunctionMessage
)

BaseMessage 抽象消息类 所有消息类型的基类,提供统一的消息接口。

对话模式 支持多种对话模式,包括单轮对话、多轮对话等。

缓存历史消息

from langchain_core.chat_history import InMemoryChatMessageHistory
history = InMemoryChatMessageHistory()
history.add_user_message("你好")
history.add_ai_message("你好!有什么可以帮助你的吗?")

多轮对话

messages = [
    SystemMessage(content="你是一个 helpful assistant."),
    HumanMessage(content="你好"),
    AIMessage(content="你好!有什么可以帮助你的吗?"),
    HumanMessage(content="请介绍你自己")
]

内存缓存

from langchain_community.chat_message_histories import ChatMessageHistory
from langchain_core.chat_history import BaseChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
​
store = {}
def get_session_history(session_id: str) -> BaseChatMessageHistory:
    if session_id not in store:
        store[session_id] = ChatMessageHistory()
    return store[session_id]
​
with_message_history = RunnableWithMessageHistory(chat, get_session_history)
response = with_message_history.invoke(
    [HumanMessage(content="你好")],
    config={"configurable": {"session_id": "abc123"}}
)

管理历史消息

  • 添加消息

  • 获取消息

  • 清除消息

前置概念

  • 上下文窗口

  • Token

消息裁剪 当消息超过上下文窗口时,需要裁剪消息。

基于输入 Token 数的修剪

from langchain_core.messages import trim_messages
trimmed_messages = trim_messages(
    messages,
    max_tokens=100,
    strategy="last",
    token_counter=llm
)

基于消息数的修剪

trimmed_messages = trim_messages(
    messages,
    max_messages=5,
    strategy="last"
)

消息过滤

trimmed_messages = trim_messages(
    messages,
    include_types=["human", "ai"],
    exclude_types=["system"]
)

消息合并

trimmed_messages = trim_messages(
    messages,
    strategy="merge",
    token_counter=llm
)

5. 提示词模板(Prompt Template)

概念 提示词模板是可重用的提示词结构,允许动态插入变量。

用法

from langchain_core.prompts import PromptTemplate
template = "你是一个 {role},请 {action}"
prompt = PromptTemplate.from_template(template)
formatted_prompt = prompt.format(role="翻译专家", action="将以下中文翻译成英文:{text}")

字符串模板

template = "翻译以下文本:\n\n{text}\n\n到 {language}"
prompt = PromptTemplate(template=template, input_variables=["text", "language"])

聊天消息模板

from langchain_core.prompts import ChatPromptTemplate
template = ChatPromptTemplate.from_messages([
    ("system", "你是一个 {role}"),
    ("human", "{text}")
])

消息占位符

from langchain_core.prompts import MessagesPlaceholder
prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个 helpful assistant."),
    MessagesPlaceholder(variable_name="history"),
    ("human", "{input}")
])

使用 LangChain Hub 的提示词模板

from langchain import hub
prompt = hub.pull("jamesliang/openai-functions-agent")

6. 少样本提示(few-shotting)

概念 少样本提示通过提供少量示例来指导模型生成更准确的输出。

实现

from langchain_core.prompts import FewShotPromptTemplate, PromptTemplate
examples = [
    {"input": "happy", "output": "joyful"},
    {"input": "sad", "output": "melancholy"}
]
example_prompt = PromptTemplate.from_template("Input: {input}\nOutput: {output}")
few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="将以下情感词转换为同义词:",
    suffix="Input: {input}\nOutput:",
    input_variables=["input"]
)

使用案例

案例一:推理引导 通过提供推理步骤的示例来引导模型进行复杂推理。

案例二:使用示例数据增强 LangChain 信息提取能力

examples = [
    {"text": "苹果公司成立于1976年", "entity": "苹果公司", "date": "1976年"},
    {"text": "微软总部位于华盛顿", "entity": "微软", "location": "华盛顿"}
]
few_shot_prompt = FewShotPromptTemplate(
    examples=examples,
    example_prompt=example_prompt,
    prefix="从文本中提取实体信息:",
    suffix="Text: {text}\nExtracted:",
    input_variables=["text"]
)

7. 示例选择器(Example selectors)

概念 示例选择器根据输入动态选择最相关的示例。

按长度选择示例(Length)

from langchain_core.example_selectors import LengthBasedExampleSelector
example_selector = LengthBasedExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    max_length=50
)

按语义相似性选择示例(Similarity)

from langchain_community.example_selectors import SemanticSimilarityExampleSelector
from langchain_openai import OpenAIEmbeddings
example_selector = SemanticSimilarityExampleSelector.from_examples(
    examples,
    OpenAIEmbeddings(),
    FAISS,
    k=1
)

按最大边际相关性选择示例(MMR)

from langchain.retrievers import MultiQueryRetriever
retriever = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(),
    llm=llm
)

通过 ngram 重叠选择示例(Ngram)

from langchain_community.example_selectors import NGramOverlapExampleSelector
example_selector = NGramOverlapExampleSelector(
    examples=examples,
    example_prompt=example_prompt,
    ngram_size=2
)

8. 输出解析器(Output parsers)

概念 输出解析器将 LLM 的输出转换为结构化格式。

解析文本输出

from langchain_core.output_parsers import StrOutputParser
parser = StrOutputParser()
parsed_output = parser.parse(response.content)

解析结构化对象输出

from langchain.output_parsers import PydanticOutputParser
from pydantic import BaseModel, Field
class Person(BaseModel):
    name: str = Field(description="person's name")
    age: int = Field(description="person's age")
parser = PydanticOutputParser(pydantic_object=Person)

解析 JSON 输出

from langchain.output_parsers import JsonOutputParser
parser = JsonOutputParser()
parsed_output = parser.parse(response.content)

9. 文档加载器(Document loaders)

RAG 介绍 RAG (Retrieval-Augmented Generation) 结合检索和生成,提高回答的准确性和相关性。

RAG 概念 通过检索相关文档来增强 LLM 的知识。

RAG 流程

  1. 检索相关文档

  2. 将文档与问题结合

  3. 生成回答

RAG 示例

from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import CharacterTextSplitter
from langchain.embeddings import OpenAIEmbeddings
from langchain.vectorstores import FAISS
​
loader = TextLoader("data.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)

Document 类

from langchain_core.documents import Document
document = Document(page_content="文本内容", metadata={"source": "文档来源"})

加载 PDF 文档

from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader("document.pdf")
pages = loader.load_and_split()

加载 Markdown 文件

from langchain_community.document_loaders import UnstructuredMarkdownLoader
loader = UnstructuredMarkdownLoader("document.md")
documents = loader.load()

10. 文本分割器(Text splitters)

概念 文本分割器将长文档分割成更小的块,以便处理。

根据文档长度与文档语义拆分 平衡块大小和语义完整性。

基于字符长度拆分

from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
    separator="\n\n",
    chunk_size=1000,
    chunk_overlap=200,
    length_function=len
)
texts = text_splitter.split_text(state_of_the_union)

基于 Token 长度拆分

from langchain.text_splitter import TokenTextSplitter
text_splitter = TokenTextSplitter(chunk_size=100, chunk_overlap=0)
texts = text_splitter.split_text(state_of_the_union)

硬性约束长度拆分

from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=100,
    chunk_overlap=20,
    length_function=len,
    add_start_index=True
)
texts = text_splitter.create_documents([state_of_the_union])

特殊文档结构拆分

from langchain.text_splitter import MarkdownHeaderTextSplitter
markdown_splitter = MarkdownHeaderTextSplitter(
    headers_to_split_on=[
        ("#", "Header 1"),
        ("##", "Header 2"),
    ]
)
texts = markdown_splitter.split_text(markdown_text)

11. 文本向量

嵌入与嵌入模型(Embedding and Embedding Models) 将文本转换为向量表示,便于相似性搜索。

Embeddings 嵌入模型类

from langchain.embeddings import OpenAIEmbeddings
embeddings = OpenAIEmbeddings()

定义嵌入模型

from langchain.embeddings import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2")

嵌入文档列表

texts = ["Hello world", "Hi there"]
embeddings_list = embeddings.embed_documents(texts)

嵌入单个查询

query = "Hello world"
query_embedding = embeddings.embed_query(query)

向量存储(Vector Stores)

向量数据库介绍 存储和检索向量数据的数据库。

内存存储

from langchain.vectorstores import FAISS
db = FAISS.from_texts(texts, embeddings)

基本操作

  • 添加文档

  • 删除文档

  • 更新文档

向量搜索

docs = db.similarity_search("query")

Redis 向量存储

基本概念 Redis 作为向量数据库,提供高性能的向量搜索。

环境设置

pip install redis

基本操作

from langchain.vectorstores import Redis
redis_url = "redis://localhost:6379"
index_name = "langchain-demo"
vector_store = Redis.from_texts(
    texts,
    embeddings,
    redis_url=redis_url,
    index_name=index_name
)

向量搜索

results = vector_store.similarity_search("query")

相似性搜索

results = vector_store.similarity_search_with_score("query")

元数据过滤

results = vector_store.similarity_search(
    "query",
    filter={"source": "my-source"}
)

最大边际相关性搜索

results = vector_store.max_marginal_relevance_search("query")

Pinecone 向量存储

介绍 Pinecone 是一个托管的向量数据库服务。

环境设置

pip install pinecone-client

基本操作

from langchain.vectorstores import Pinecone
pinecone.init(api_key="your-api-key", environment="your-env")
index_name = "langchain-demo"
vector_store = Pinecone.from_texts(texts, embeddings, index_name=index_name)

向量搜索

results = vector_store.similarity_search("query")

12. 检索器(Retrievers)

相关概念 检索器是从向量存储中检索相关文档的组件。

检索系统 结合检索和生成的系统。

检索器

retriever = vector_store.as_retriever()

使用向量数据库作为检索器

retriever = db.as_retriever(search_kwargs={"k": 4})
docs = retriever.get_relevant_documents("query")
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐