• LangChain 也是一套面向大模型的开发框架(SDK)
  • LangChain 是 AGI 时代软件工程的一个探索和原型
  • 学习 LangChain 要关注接口变更

LangChain 的核心组件

  1. 模型 I/O 封装
    • Chat Models:对语言模型接口的封装
    • PromptTemple:提示词模板
    • OutputParser:解析输出
  2. 数据连接封装(弱于 LlamaIndex)
    • Document Loaders:各种格式文件的加载器
    • Document Transformers:对文档的常用操作,如:split, filter, translate, extract metadata, etc
    • Text Embedding Models:文本向量化表示,用于检索等操作
    • Verctorstores & Retrievers:向量数据库与向量检索
  3. 架构封装
    • Chain/LCEL:实现一个功能或者一系列顺序功能组合
    • Agent:(建议使用langgraph)根据用户输入,自动规划执行步骤,自动选择每步需要的工具,最终完成用户指定的功能
      • Tools:调用外部功能的函数,例如:调 google 搜索、文件 I/O、Linux Shell 等等
    • LangGraph:工作流开发框架
  4. LangSmith:过程监控与调试框架

文档(以 Python 版为例)

LangChain 是开源项目

项目地址:https://github.com/langchain-ai

1. 模型 I/O 封装

把不同的模型,统一封装成一个接口,方便更换模型而不用重构代码。

1.1 模型 API: ChatModel

1.1.1 OpenAI 模型封装

注意版本

# !pip install -U langchain
# !pip install -U langchain-openai

from langchain.chat_models import init_chat_model
model = init_chat_model("gpt-4o-mini", model_provider="openai")
response = model.invoke("你是谁")
print(response.content)
1.1.2 多轮对话 Session 封装,,版本问题
from langchain.schema import (
    AIMessage,  # 等价于OpenAI接口中的assistant role
    HumanMessage,  # 等价于OpenAI接口中的user role
    SystemMessage  # 等价于OpenAI接口中的system role
)

messages = [
    SystemMessage(content="你是聚客AI大模型课的课程助理。"),
    HumanMessage(content="我是聚客AI学员,我叫小聚。"),
    AIMessage(content="欢迎!"),
    HumanMessage(content="我是谁?")
]

ret = model.invoke(messages)

print(ret.content)

通过模型封装,实现不同模型的统一接口调用

1.1.3 DeepSeek 模型封装

记得设置api并充钱

pip install -U langchain-deepseek 

from langchain.chat_models import init_chat_model

model = init_chat_model(model="deepseek-chat", model_provider="deepseek")

response = model.invoke("你是谁")
print(response.content)
1.1.4 流式输出
for token in model.stream("你是谁"):
    print(token.content, end="")
1.1.5 通义千问模型封装
  1. OpenAI兼容接口
from langchain_openai import ChatOpenAI
import os

chatLLM = ChatOpenAI(
    api_key=os.getenv("DASHSCOPE_API_KEY"),
    base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
    model="qwen-plus",  # 此处以qwen-plus为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
    # other params...
)
messages = [
    {"role": "system", "content": "You are a helpful assistant."},
    {"role": "user", "content": "你是谁?"}]
response = chatLLM.invoke(messages)
print(response)
  1. DashScope 接口

# !pip install langchain-community
# !pip install dashscope

from langchain_community.chat_models.tongyi import ChatTongyi
from langchain_core.messages import HumanMessage

chatLLM = ChatTongyi(
    model="qwen-max",   # 此处以qwen-max为例,您可按需更换模型名称。模型列表:https://help.aliyun.com/zh/model-studio/getting-started/models
    streaming=True,
    # other params...
)
res = chatLLM.stream([HumanMessage(content="hi")], streaming=True)
for r in res:
    print("chat resp:", r.content)
1.1.6 Ollama模型封装

# !pip install -U langchain-ollama

from langchain_ollama import ChatOllama

llm = ChatOllama(
    model="qwen3:8b",
    temperature=0.7,
    # other params...
)

messages = [
    (
        "system",
        "你是一名专业的翻译家,可以将用户的中文翻译为英文。",
    ),
    ("human", "我喜欢编程。"),
]
ai_msg = llm.invoke(messages)
print(ai_msg.content)

1.2 模型的输入与输出

1.2.1 Prompt 模板封装
  1. PromptTemplate 可以在模板中自定义变量
from langchain.prompts import PromptTemplate

template = PromptTemplate.from_template("给我讲个关于{subject}的笑话")
print("===Template===")
print(template)
print("===Prompt===")
print(template.format(subject='小明'))
from langchain.chat_models import init_chat_model

# 定义 LLM
llm = init_chat_model("deepseek-chat", model_provider="deepseek")
# 通过 Prompt 调用 LLM
ret = llm.invoke(template.format(subject='小明'))
# 打印输出
print(ret.content)
  1. ChatPromptTemplate 用模板表示的对话上下文
  2. from langchain.prompts import (
        ChatPromptTemplate,
        HumanMessagePromptTemplate,
        SystemMessagePromptTemplate,
    )
    from langchain.chat_models import init_chat_model
    llm = init_chat_model("deepseek-chat", model_provider="deepseek", temperature=0)
    
    template = ChatPromptTemplate.from_messages(
        [
            SystemMessagePromptTemplate.from_template("你是{product}的客服助手。你的名字叫{name}"),
            HumanMessagePromptTemplate.from_template("{query}")
        ]
    )
    
    prompt = template.format_messages(
        product="有钱AI大模型课程",
        name="1w",
        query="你是谁"
    )
    
    print(prompt)
    
    ret = llm.invoke(prompt)
    
    print(ret.content)

  3. MessagesPlaceholder 把多轮对话变成模板
  4. from langchain.prompts import (
        ChatPromptTemplate,
        HumanMessagePromptTemplate,
        MessagesPlaceholder,
    )
    
    human_prompt = "Translate your answer to {language}."
    human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)
    
    chat_prompt = ChatPromptTemplate.from_messages(
        # variable_name 是 message placeholder 在模板中的变量名
        # 用于在赋值时使用
        [MessagesPlaceholder("history"), human_message_template]
    )
    
    from langchain_core.messages import AIMessage, HumanMessage
    
    human_message = HumanMessage(content="Who is Elon Musk?")
    ai_message = AIMessage(
        content="Elon Musk is a billionaire entrepreneur, inventor, and industrial designer"
    )
    
    messages = chat_prompt.format_prompt(
        # 对 "history" 和 "language" 赋值
        history=[human_message, ai_message], language="中文"
    )
    
    print(messages.to_messages())
    
    result = llm.invoke(messages)
    print(result.content)

    划重点:把Prompt模板看作带有参数的函数

完整正确代码
from langchain_core.prompts import PromptTemplate, MessagesPlaceholder, HumanMessagePromptTemplate  # 修改导入路径

template = PromptTemplate.from_template("给我讲个关于{subject}的笑话")
print("===Template===")
print(template)
print("===Prompt===")
print(template.format(subject='小明'))

from langchain.chat_models import init_chat_model

# 定义 LLM
llm = init_chat_model("deepseek-chat", model_provider="deepseek")
# 通过 Prompt 调用 LLM
ret = llm.invoke(template.format(subject='小明'))
# 打印输出
print(ret.content)

#ChatPromptTemplate 用模板表示的对话上下文
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate
from langchain.chat_models import init_chat_model

from langchain.chat_models import init_chat_model
llm = init_chat_model("deepseek-chat", model_provider="deepseek", temperature=0)

# 替换原有 SystemMessagePromptTemplate 部分
template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(content="你是{product}的客服助手。你的名字叫{name}"),
        HumanMessage(content="{query}")
    ]
)


prompt = template.format_messages(
    product="有钱AI大模型课程",
    name="1w",
    query="你是谁"
)

print(prompt)

ret = llm.invoke(prompt)

print(ret.content)

#MessagesPlaceholder 把多轮对话变成模板

human_prompt = "Translate your answer to {language}."
human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)

chat_prompt = ChatPromptTemplate.from_messages(
    # variable_name 是 message placeholder 在模板中的变量名
    # 用于在赋值时使用
    [MessagesPlaceholder("history"), human_message_template]
)
from langchain_core.messages import AIMessage, HumanMessage

human_message = HumanMessage(content="Who is Elon Musk?")
ai_message = AIMessage(
    content="Elon Musk is a billionaire entrepreneur, inventor, and industrial designer"
)

messages = chat_prompt.format_prompt(
    # 对 "history" 和 "language" 赋值
    history=[human_message, ai_message], language="中文"
)

print(messages.to_messages())
result = llm.invoke(messages)
print(result.content)
1.2.2 从文件加载 Prompt 模板
from langchain.prompts import PromptTemplate

template = PromptTemplate.from_file("example_prompt_template.txt", encoding="utf-8")
print("===Template===")
print(template)
print("===Prompt===")
print(template.format(topic='黑色幽默'))

1.3 结构化输出

1.3.1 直接输出 Pydantic 对象
from pydantic import BaseModel, Field

# 定义你的输出对象
class Date(BaseModel):
    year: int = Field(description="Year")
    month: int = Field(description="Month")
    day: int = Field(description="Day")
    era: str = Field(description="BC or AD")
from langchain.prompts import PromptTemplate, ChatPromptTemplate, HumanMessagePromptTemplate
from langchain_core.output_parsers import PydanticOutputParser

from langchain.chat_models import init_chat_model
llm = init_chat_model("gpt-4o", model_provider="openai")

# 定义结构化输出的模型
structured_llm = llm.with_structured_output(Date)

template = """提取用户输入中的日期。
用户输入:
{query}"""

prompt = PromptTemplate(
    template=template,
)

query = "2023年四月6日天气晴..."
input_prompt = prompt.format_prompt(query=query)

structured_llm.invoke(input_prompt)

1.3.2 输出指定格式的 JSON
# OpenAI 模型的JSON格式
json_schema = {
    "title": "Date",
    "description": "Formated date expression",
    "type": "object",
    "properties": {
        "year": {
            "type": "integer",
            "description": "year, YYYY",
        },
        "month": {
            "type": "integer",
            "description": "month, MM",
        },
        "day": {
            "type": "integer",
            "description": "day, DD",
        },
        "era": {
            "type": "string",
            "description": "BC or AD",
        },
    },
}
structured_llm = llm.with_structured_output(json_schema)

structured_llm.invoke(input_prompt)
1.3.3 使用 OutputParser

OutputParser 可以按指定格式解析模型的输出

from langchain_core.output_parsers import JsonOutputParser

parser = JsonOutputParser(pydantic_object=Date)

prompt = PromptTemplate(
    template="提取用户输入中的日期。\n用户输入:{query}\n{format_instructions}",
    input_variables=["query"],
    partial_variables={"format_instructions": parser.get_format_instructions()},
)

input_prompt = prompt.format_prompt(query=query)
output = llm.invoke(input_prompt)
print("原始输出:\n"+output.content)

print("\n解析后:")
parser.invoke(output)

也可以用 PydanticOutputParser

from langchain_core.output_parsers import PydanticOutputParser

parser = PydanticOutputParser(pydantic_object=Date)

input_prompt = prompt.format_prompt(query=query)
output = llm.invoke(input_prompt)
print("原始输出:\n"+output.content)

print("\n解析后:")
parser.invoke(output)

OutputFixingParser 利用大模型做格式自动纠错

from langchain.output_parsers import OutputFixingParser
from langchain.chat_models import init_chat_model

llm = init_chat_model(model="gpt-4o-mini", model_provider="openai")

# 纠错能力与大模型能力相关
new_parser = OutputFixingParser.from_llm(parser=parser, llm=llm)

bad_output = output.content.replace("4","四")
print("PydanticOutputParser:")
try:
    parser.invoke(bad_output)
except Exception as e:
    print(e)

print("OutputFixingParser:")
new_parser.invoke(bad_output)
1.4 Function Calling
from langchain_core.tools import tool

@tool
def add(a: int, b: int) -> int:
    """Add two integers.

    Args:
        a: First integer
        b: Second integer
    """
    return a + b

@tool
def multiply(a: float, b: float) -> float:
    """Multiply two integers.

    Args:
        a: First integer
        b: Second integer
    """
    return a * b

import json

llm_with_tools = llm.bind_tools([add, multiply])

query = "3.5的4倍是多少?"
messages = [HumanMessage(query)]

output = llm_with_tools.invoke(messages)

print(json.dumps(output.tool_calls, indent=4))

回传 Funtion Call 的结果

messages.append(output)

available_tools = {"add": add, "multiply": multiply}

for tool_call in output.tool_calls:
    selected_tool = available_tools[tool_call["name"].lower()]
    tool_msg = selected_tool.invoke(tool_call)
    messages.append(tool_msg)

new_output = llm_with_tools.invoke(messages)
for message in messages:
    print(json.dumps(message.model_dump(), indent=4, ensure_ascii=False))
print(new_output.content)
正确的完整代码
# 导入第一部分:PromptTemplate相关
from langchain_core.prompts import PromptTemplate, MessagesPlaceholder, HumanMessagePromptTemplate  # 修改导入路径

template = PromptTemplate.from_template("给我讲个关于{subject}的笑话")
print("===模板定义===")
print(template)
print("===填充后的提示词===")
print(template.format(subject='小明'))

print("\n" + "="*50 + "\n")  # 分割线

# 导入第二部分:ChatModel相关
from langchain.chat_models import init_chat_model

# 定义语言模型
llm = init_chat_model("deepseek-chat", model_provider="deepseek")
# 通过提示词调用语言模型
ret = llm.invoke(template.format(subject='小明'))
# 打印输出
print("===语言模型回复===")
print(ret.content)

print("\n" + "="*50 + "\n")  # 分割线

# 导入第三部分:聊天提示词模板相关
from langchain_core.messages import SystemMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate

# 重新定义语言模型
llm = init_chat_model("deepseek-chat", model_provider="deepseek", temperature=0)  # temperature=0, AI就不会自由发挥

# 创建聊天提示词模板
template = ChatPromptTemplate.from_messages(
    [
        SystemMessage(content="你是{product}的客服助手。你的名字叫{name}"),
        HumanMessage(content="{query}")
    ]
)


# 格式化提示词
prompt = template.format_messages(
    product="有钱AI大模型课程",
    name="1w",
    query="你是谁"
)

print("===聊天提示词模板生成的消息===")
print(prompt)

# 调用语言模型
ret = llm.invoke(prompt)
print("\n===语言模型回复===")
print(ret.content)

print("\n" + "="*50 + "\n")  # 分割线

# 导入第四部分:消息占位符相关
from langchain_core.messages import AIMessage, HumanMessage

# 创建人类消息模板
human_prompt = "将你的回答翻译成{language}。"
human_message_template = HumanMessagePromptTemplate.from_template(human_prompt)

# 创建聊天提示词模板(包含历史对话)
chat_prompt = ChatPromptTemplate.from_messages(
    # variable_name 是消息占位符在模板中的变量名
    # 用于在赋值时使用
    [MessagesPlaceholder("history"), human_message_template]
)

# 创建历史对话消息
human_message = HumanMessage(content="埃隆·马斯克是谁?")
ai_message = AIMessage(
    content="埃隆·马斯克是一位亿万富翁企业家、发明家和工业设计师"
)

# 格式化提示词
messages = chat_prompt.format_prompt(
    # 对 "history" 和 "language" 赋值
    history=[human_message, ai_message], language="中文"
)

print("===消息占位符生成的消息===")
print(messages.to_messages())

# 调用语言模型
result = llm.invoke(messages)
print("\n===语言模型回复===")
print(result.content)

1.5 小结

  1. LangChain 统一封装了各种模型的调用接口,包括补全型和对话型两种
  2. LangChain 提供了 PromptTemplate 类,可以自定义带变量的模板
  3. LangChain 提供了一些列输出解析器,用于将大模型的输出解析成结构化对象
  4. LangChain 提供了 Function Calling 的封装
  5. 上述模型属于 LangChain 中较为实用的部分

2. 数据连接封装

2.1 文档加载器:Document Loaders

[ ]:pip install -U langchain-community pymupdf

from langchain_community.document_loaders import PyMuPDFLoader

loader = PyMuPDFLoader("./data/deepseek-v3-1-4.pdf")
pages = loader.load_and_split()

print(pages[0].page_content)

2.2 文档处理器

2.2.1 TextSplitter
from langchain_text_splitters import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=200, 
    length_function=len,
    add_start_index=True,
)

paragraphs = text_splitter.create_documents([pages[0].page_content])
for para in paragraphs:
    print(para.page_content)
    print('-------')

2.3、向量数据库与向量检索

# !pip install dashscope
# !pip install faiss-cpu

import os
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.embeddings import DashScopeEmbeddings
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyMuPDFLoader

# 加载文档
loader = PyMuPDFLoader("./data/deepseek-v3-1-4.pdf")
pages = loader.load_and_split()

# 文档切分
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=200,
    length_function=len,
    add_start_index=True,
)

texts = text_splitter.create_documents(
    [page.page_content for page in pages[:1]]
)

# 灌库
embeddings = DashScopeEmbeddings(
    model="text-embedding-v1", dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
index = FAISS.from_documents(texts, embeddings)

# 检索 top-5 结果
retriever = index.as_retriever(search_kwargs={"k": 5})

docs = retriever.invoke("deepseek v3有多少参数")

for doc in docs:
    print(doc.page_content)
    print("----")

更多的三方检索组件链接,参考:https://python.langchain.com/docs/integrations/vectorstores/

2.4 小结

  1. 文档处理部分,建议在实际应用中详细测试后使用
  2. 与向量数据库的链接部分本质是接口封装,向量数据库需要自己选型

3. Chain 和 LangChain Expression Language (LCEL)

LangChain Expression Language(LCEL)是一种声明式语言,可轻松组合不同的调用顺序构成 Chain。LCEL 自创立之初就被设计为能够支持将原型投入生产环境,无需代码更改,从最简单的“提示+LLM”链到最复杂的链(已有用户成功在生产环境中运行包含数百个步骤的 LCEL Chain)。

LCEL 的一些亮点包括:

  1. 流支持:使用 LCEL 构建 Chain 时,你可以获得最佳的首个令牌时间(即从输出开始到首批输出生成的时间)。对于某些 Chain,这意味着可以直接从 LLM 流式传输令牌到流输出解析器,从而以与 LLM 提供商输出原始令牌相同的速率获得解析后的、增量的输出。

  2. 异步支持:任何使用 LCEL 构建的链条都可以通过同步 API(例如,在 Jupyter 笔记本中进行原型设计时)和异步 API(例如,在 LangServe 服务器中)调用。这使得相同的代码可用于原型设计和生产环境,具有出色的性能,并能够在同一服务器中处理多个并发请求。

  3. 优化的并行执行:当你的 LCEL 链条有可以并行执行的步骤时(例如,从多个检索器中获取文档),我们会自动执行,无论是在同步还是异步接口中,以实现最小的延迟。

  4. 重试和回退:为 LCEL 链的任何部分配置重试和回退。这是使链在规模上更可靠的绝佳方式。目前我们正在添加重试/回退的流媒体支持,因此你可以在不增加任何延迟成本的情况下获得增加的可靠性。

  5. 访问中间结果:对于更复杂的链条,访问在最终输出产生之前的中间步骤的结果通常非常有用。这可以用于让最终用户知道正在发生一些事情,甚至仅用于调试链条。你可以流式传输中间结果,并且在每个 LangServe 服务器上都可用。

  6. 输入和输出模式:输入和输出模式为每个 LCEL 链提供了从链的结构推断出的 Pydantic 和 JSONSchema 模式。这可以用于输入和输出的验证,是 LangServe 的一个组成部分。

  7. 无缝 LangSmith 跟踪集成:随着链条变得越来越复杂,理解每一步发生了什么变得越来越重要。通过 LCEL,所有步骤都自动记录到 LangSmith,以实现最大的可观察性和可调试性。

  8. 无缝 LangServe 部署集成:任何使用 LCEL 创建的链都可以轻松地使用 LangServe 进行部署。

原文:https://python.langchain.com/docs/expression_language/

3.1 Pipeline 式调用 PromptTemplate, LLM 和 OutputParser

from langchain.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from pydantic import BaseModel, Field
from typing import List, Dict, Optional
from enum import Enum
import json
from langchain.chat_models import init_chat_model

# 输出结构
class SortEnum(str, Enum):
    data = 'data'
    price = 'price'


class OrderingEnum(str, Enum):
    ascend = 'ascend'
    descend = 'descend'


class Semantics(BaseModel):
    name: Optional[str] = Field(description="流量包名称", default=None)
    price_lower: Optional[int] = Field(description="价格下限", default=None)
    price_upper: Optional[int] = Field(description="价格上限", default=None)
    data_lower: Optional[int] = Field(description="流量下限", default=None)
    data_upper: Optional[int] = Field(description="流量上限", default=None)
    sort_by: Optional[SortEnum] = Field(description="按价格或流量排序", default=None)
    ordering: Optional[OrderingEnum] = Field(
description="升序或降序排列", default=None)


# Prompt 模板
prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "你是一个语义解析器。你的任务是将用户的输入解析成JSON表示。不要回答用户的问题。"),
        ("human", "{text}"),
    ]
)

# 模型
llm = init_chat_model("deepseek-chat", model_provider="deepseek")

structured_llm = llm.with_structured_output(Semantics)

# LCEL 表达式
runnable = (
    {"text": RunnablePassthrough()} | prompt | structured_llm
)

# 直接运行
ret = runnable.invoke("不超过100元的流量大的套餐有哪些")
print(
    json.dumps(
        ret.model_dump(),
        indent = 4,
        ensure_ascii=False
    )
)

使用 LCEL 的价值,也就是 LangChain 的核心价值。
官方从不同角度给出了举例说明:https://python.langchain.com/docs/concepts/lcel/

3.2 用 LCEL 实现 RAG

import os
from langchain.chat_models import init_chat_model
# 删除错误的导入: from langchain_classic.chains import llm
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.embeddings.dashscope import DashScopeEmbeddings

# 首先初始化语言模型
llm = init_chat_model("deepseek-chat", model_provider="deepseek")

# 加载文档
loader = PyMuPDFLoader("./data/deepseek-v3-1-4.pdf")
pages = loader.load_and_split()

# 文档切分
text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=200,
    length_function=len,
    add_start_index=True,
)

texts = text_splitter.create_documents(
    [page.page_content for page in pages[:1]]
)

# 灌库
embeddings = DashScopeEmbeddings(
    model="text-embedding-v1", dashscope_api_key=os.getenv("DASHSCOPE_API_KEY")
)
db = FAISS.from_documents(texts, embeddings)

# 检索 top-5 结果
retriever = db.as_retriever(search_kwargs={"k": 5})

# Prompt模板
template = """Answer the question based only on the following context:
{context}

Question: {question}
"""
prompt = ChatPromptTemplate.from_template(template)

# 构建 RAG chain
rag_chain = (
    {"question": RunnablePassthrough(), "context": retriever}
    | prompt
    | llm  # 这里使用我们初始化的 llm 实例
    | StrOutputParser()
)

# 执行查询
response = rag_chain.stream("deepseek V3有多少参数")
for value in response:
    print(value, end='', flush=True)

3.3 用 LCEL 实现模型切换(工厂模式)

from langchain_core.runnables.utils import ConfigurableField
from langchain_community.chat_models import QianfanChatEndpoint
from langchain.prompts import (
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
)
from langchain.chat_models import init_chat_model
from langchain.schema import HumanMessage
import os

# 模型1
ds_model = init_chat_model("deepseek-chat", model_provider="deepseek")

# 模型2
gpt_model = init_chat_model("gpt-4o-mini", model_provider="openai")


# 通过 configurable_alternatives 按指定字段选择模型
model = gpt_model.configurable_alternatives(
    ConfigurableField(id="llm"), 
    default_key="gpt", 
    deepseek=ds_model,
    # claude=claude_model,
)

# Prompt 模板
prompt = ChatPromptTemplate.from_messages(
    [
        HumanMessagePromptTemplate.from_template("{query}"),
    ]
)

# LCEL
chain = (
    {"query": RunnablePassthrough()} 
    | prompt
    | model 
    | StrOutputParser()
)

# 运行时指定模型 "gpt" or "deepseek"
ret = chain.with_config(configurable={"llm": "gpt"}).invoke("请自我介绍")

print(ret)

alang.ai/langchain/101/lc05

扩展阅读:什么是工厂模式设计模式概览。

3.4 通过 LCEL,还可以实现

  1. 配置运行时变量:https://python.langchain.com/docs/how_to/configure/
  2. 故障回退:https://python.langchain.com/docs/how_to/fallbacks/
  3. 并行调用:https://python.langchain.com/docs/how_to/parallel/
  4. 逻辑分支:https://python.langchain.com/docs/how_to/routing/
  5. 动态创建 Chain: https://python.langchain.com/docs/how_to/dynamic_chain/

更多例子:https://python.langchain.com/docs/how_to/lcel_cheatsheet/

4. LangChain 与 LlamaIndex 的错位竞争

  • LangChain 侧重与 LLM 本身交互的封装
    • Prompt、LLM、Message、OutputParser 等工具丰富
    • 在数据处理和 RAG 方面提供的工具相对粗糙
    • 主打 LCEL 流程封装
    • 配套 Agent、LangGraph 等智能体与工作流工具
    • 另有 LangServe 部署工具和 LangSmith 监控调试工具
  • LlamaIndex 侧重与数据交互的封装
    • 数据加载、切割、索引、检索、排序等相关工具丰富
    • Prompt、LLM 等底层封装相对单薄
    • 配套实现 RAG 相关工具
    • 同样配套智能体与工作流工具
    • 提供 LlamaDeploy 部署工具,通过与三方合作提供过程监控调试工具

5. 总结

  1. LangChain 随着版本迭代可用性有明显提升
  2. 使用 LangChain 要注意维护自己的 Prompt,尽量 Prompt 与代码逻辑解依赖
  3. 它的内置基础工具,建议充分测试效果后再决定是否使用
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐