欢迎光临
我们一直在努力

[LangChain] 学习笔记(02):LCEL 链式调用与动态模型配置实战

📌 核心结论(TL;DR)

  • LCEL 灵魂:LangChain 表达式语言(LCEL)通过重载管道符 |,将实现了 Runnable 协议的组件(模型、解析器等)像积木一样串联,实现优雅的链式编程。

  • 动态切换:利用 init_chat_model 结合 configurable_fields,可以在不修改底层代码的情况下,在运行时动态切换大模型厂商(如 OpenAI 切 DeepSeek)并调整参数。

  • 组件解耦:通过 LCEL 组装,Prompt、Model、Parser 各司其职,极大地提高了代码的复用性和可维护性。

  • 🔍 一、 原理图解与核心概念

    1. 什么是 Runnable 协议?

    在 LangChain 中,能使用 | 符号连接的前提是,该组件必须实现 Runnable 协议。它规定了组件必须具备的核心能力:

    • invoke:单次同步调用。

    • batch:批量并行调用。

    • stream:流式输出(打字机效果)。
      大语言模型(ChatOpenAI)、输出解析器(StrOutputParser)、甚至提示词模板(PromptTemplate)全部实现了此协议。

    2. LCEL 的链式魔法

    # 将模型输出直接传给字符串解析器
    chain = model | parser

    底层相当于调用了 RunnableSequence(first=model, last=parser)。数据像流水线一样,从上游流向下游。

    💻 二、 精选核心代码片段

    1. 基础链式调用(以 DeepSeek 为例)

    from langchain_openai import ChatOpenAI
    from langchain_core.messages import SystemMessage, HumanMessage
    from langchain_core.output_parsers import StrOutputParser

    model = ChatOpenAI(
    model="deepseek-chat",
    api_key="your_api_key",
    base_url="https://api.deepseek.com", # 注意:目前官方推荐使用根路径,无需 /v1
    )

    messages = [
    SystemMessage(content="请补全一段故事,100个字以内:"),
    HumanMessage(content="一只猫正在__?")
    ]

    # 使用 LCEL 构建链
    chain = model | StrOutputParser()
    print(chain.invoke(messages))

    2. 进阶:运行时动态切换模型(DeepSeek 与 Ollama 无缝切换)

    通过 configurable_alternatives,实现极高的灵活性,且无需安装额外的模型集成包。

    from langchain_openai import ChatOpenAI
    from langchain_ollama import ChatOllama
    from langchain_core.messages import HumanMessage
    from langchain_core.runnables import ConfigurableField

    # 1. 定义默认的基础模型(云端 DeepSeek)
    base_model = ChatOpenAI(
    model="deepseek-chat",
    api_key="your_deepseek_api_key",
    base_url="https://api.deepseek.com",
    temperature=0.3
    )

    # 2. 挂载备选模型(本地 Ollama)
    model = base_model.configurable_alternatives(
    ConfigurableField(id="llm_provider"),
    default_key="deepseek",
    ollama=ChatOllama(
    model="deepseek-r1:1.5b", # 确保你本地已拉取该模型
    base_url="http://127.0.0.1:11434",
    temperature=0.3
    )
    )

    messages = [HumanMessage(content="请用一句话介绍你自己。")]

    # ==========================================
    # 场景一:使用云端 DeepSeek(默认走 default_key)
    # ==========================================
    print("=== 使用云端 DeepSeek ===")
    result_cloud = model.invoke(messages)
    print(result_cloud.content)

    # ==========================================
    # 场景二:动态切换到本地 Ollama
    # ==========================================
    print("\\n=== 动态切换到本地 Ollama ===")
    result_local = model.invoke(
    messages,
    config={
    "configurable": {
    "llm_provider": "ollama" # 这里指定走备选模型
    }
    }
    )
    print(result_local.content)

    (完整的包含多轮对话与异常处理的代码已上传至 Gitee 仓库)

    ⚠️ 三、 踩坑排查排雷

  • 报错 UnicodeEncodeError: 'ascii' codec can't encode characters:httpx 默认用 ASCII 编码 HTTP 请求头。如果 API Key 里混入了中文空格、全角字符或不可见字符,就会崩溃。排查:重新复制纯 ASCII 的 Key,或在代码中使用 key.encode("ascii", errors="ignore").decode("ascii") 清洗。

  • 报错 Unsupported model_provider='deepseek':init_chat_model 需要安装 langchain-deepseek 集成包才能识别。排查:若因 Python 版本限制无法安装,直接用 ChatOpenAI 并指定 base_url 即可完美兼容。

  • Connection Error 或 Timeout:如果你在国内直连 OpenAI 会报错;或者本地 Ollama 服务没有启动。排查:检查代理设置,或确保终端执行过 ollama run <model_name> 启动本地服务。

  • 链最后输出了 AIMessage 对象而非字符串:忘了在链的最后加 StrOutputParser()。大模型原生返回的是包含元数据的 AIMessage,解析器负责提取纯文本。

  • 赞(0)
    未经允许不得转载:171主机测评 » [LangChain] 学习笔记(02):LCEL 链式调用与动态模型配置实战
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址