为了账号安全,请及时绑定邮箱和手机立即绑定

不同类型的链在LangChain中的应用讲解

LangChain 提供了多种链类型,,构建和定制自然语言处理任务的工作流。这些链类型有助于将语言模型和其他工具整合到应用程序中,。基本上,链类型就是将一系列任务串联起来,我们将不同的任务链接起来,并将第一个任务的输出传递给下一个任务。管道操作符用于像链条一样连接每个后续任务,将输出从前一个任务传递到下一个任务。

以下是一些LangChain中的重要链路类型:

这段代码展示了如何使用LangChain,一个开源框架,来创建一个简单的流程,用于使用来自OpenAI的语言模型生成笑话的过程。下面是代码中涉及的步骤概述:

  1. 导入库函数
    从 dotenv 导入 load_dotenv  
    从 langchain.prompts 导入 ChatPromptTemplate  
    从 langchain.schema.output_parser 导入 StrOutputParser  
    从 langchain_openai 导入 ChatOpenAI 作为 ChatOpenAI

2. 加载环境变量:

# 从.env文件加载环境变量  
load_dotenv()

3. 初始化语言模型:

    # 创建一个ChatOpenAI实例
    model = ChatOpenAI(model="gpt-4o-mini")  # 设置模型为 "gpt-4o-mini"

4. 定义提示模板如下:

    # 定义提示模板如下(无需单独的Runnable链)  
    prompt_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位喜剧演员,讲关于{topic}的笑话。"),  
            ("human", "讲{joke_count}个关于{topic}的笑话给我听。"),  
        ]  
    )
  1. 将链和输出解析器结合起来:
    # 使用LangChain表达式语言(LCEL)构建的链,包括提示模板、模型和输出解析器。
    chain = prompt_template | model | StrOutputParser()  
    # 仅使用提示模板和模型也可以创建链,但这里增加了输出解析器以确保输出为字符串形式。

6. 执行链条 :

    # 运行这条链
    result = chain.invoke({"topic": "话题", "joke_count": "笑话数量"})

7. 打印结果:

这是生成结果所需的完整代码。

    从 dotenv 导入 load_dotenv()  
    从 langchain.prompts 导入 ChatPromptTemplate  
    从 langchain.schema.output_parser 导入 StrOutputParser  
    从 langchain.chat 导入 ChatOpenAI  

    # 从 .env 加载环境变量  
    load_dotenv()  

    # 创建一个 ChatOpenAI 实例  
    model = ChatOpenAI(model="gpt-4o-mini")  

    # 定义提示模板(无需单独的运行链)  
    prompt_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位喜剧演员,会讲关于 {topic} 的笑话。"),  
            ("human", "给我讲 {joke_count} 个笑话。"),  
        ]  
    )  

    # 使用 LangChain 表达式语言 (LCEL) 创建复合链  
    chain = prompt_template | model | StrOutputParser()  

    # 运行链  
    result = chain.invoke({"topic": "律师", "joke_count": 3})  

    # 输出结果  
    # 输出结果  
    print(result)

链在底层是如何运作的?

可运行的Lambda表达式创建方法:

    # 定义链中的各个可运行步骤
    format_prompt = RunnableLambda(lambda x: prompt_template.format_prompt(**x))
    invoke_model = RunnableLambda(lambda x: model.invoke(x.to_messages()))
    parse_output = RunnableLambda(lambda x: x.content)

    # 创建可运行序列(相当于LCEL链,即链式执行流程)
    chain = RunnableSequence(first=format_prompt, middle=[invoke_model], last=parse_output)

它定义了三个 RunnableLambda 实例对象,每个实例对象包含着处理管道中的一个环节。

  • **format_prompt**:使用提示模板来格式化输入。

  • **invoke_model**:用格式化的提示来调用语言模型。

  • **parse_output**:从模型的响应中解析输出。

创建可执行序列:

RunnableSequence 中的三个参数分别为:第一个参数是单个 Runnable,中间的参数是一个 Runnable 列表,最后一个参数是单个 Runnable。这些参数组合成一个 RunnableSequence,表示要按顺序执行的操作序列。

包含上述 RunnableLambda 的完整代码已在这里实现。

    从 dotenv 导入 load_dotenv  
    从 langchain.prompts 导入 ChatPromptTemplate  
    从 langchain.schema.runnable 导入 RunnableLambda, RunnableSequence  
    从 langchain_openai 导入 ChatOpenAI  

    # 从 .env 加载环境变量  
    load_dotenv()  

    # 创建 ChatOpenAI 模型  
    model = ChatOpenAI(model="gpt-4o-mini")  

    # 定义提示模板 # defining prompt template  
    prompt_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位喜剧演员,讲述有关 {topic} 的笑话。"),  
            ("human", "告诉我 {joke_count} 个笑话。"),  
        ]  
    )  

    # 创建单独的可运行步骤  
    format_prompt = RunnableLambda(lambda x: prompt_template.format_prompt(**x))  
    invoke_model = RunnableLambda(lambda x: model.invoke(x.to_messages()))  
    parse_output = RunnableLambda(lambda x: x.content)  

    # 创建 RunnableSequence (相当于 LCEL 链)  
    chain = RunnableSequence(first=format_prompt, middle=[invoke_model], last=parse_output)  

    # 运行链  
    response = chain.invoke({"topic": "律师", "joke_count": 3})  

    # 输出  
    print(response)  

输出结果与之前生成的代码(不含可执行部分)完全相同。

让我们仔细看看每种链类型的输出有何不同。

一、链式 — 扩展版:

额外的步骤:

### 定义更多的处理步骤使用 RunnableLambda  
uppercase_output = RunnableLambda(lambda x: x.upper())  
count_words = RunnableLambda(lambda x: f"单词数:{len(x.split())}:\n{x}")

使用 RunnableLambda 来定义额外的处理步骤或流程:

  • **uppercase_output**:将输出文本转换为全大写。
  • **count_words**:计算词数并在文本开头加上。

创建组合链:

    # 使用LangChain表达式语言(LCEL)来创建这个组合链。
    # 创建一个组合链,包括提示模板、模型、字符串输出解析器、大写输出和计词数
    chain = prompt_template | model | StrOutputParser() | uppercase_output | count_words

将提示模板、模型调用、输出解析和其他处理步骤结合成单一链,使用LangChain表达语言(LCEL)进行操作。这条链按顺序对输入数据进行一系列转换处理。

启动连锁反应:

# 运行这条链
result = chain.invoke({"主题": "律师", "笑话数量": 3})

下面是一个完整的代码示例:链式类型扩展。

    from dotenv import load_dotenv  
    from langchain.prompts import ChatPromptTemplate  
    from langchain.schema.output_parser import StrOutputParser  
    from langchain.schema.runnable import RunnableLambda  
    from langchain_openai import ChatOpenAI  

    # 从 .env 文件加载环境变量  
    load_dotenv()  

    # 创建一个 ChatOpenAI 实例  
    model = ChatOpenAI(model="gpt-4o-mini")  

    # 定义提示模板  
    prompt_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个喜剧演员,讲关于 {topic} 的笑话。"),  
            ("human", "给我讲 {joke_count} 个笑话。"),  
        ]  
    )  

    # 定义额外的处理步骤,使用 RunnableLambda  
    uppercase_output = RunnableLambda(lambda x: x.upper())  
    count_words = RunnableLambda(lambda x: f"字数:{len(x.split())}\n{x}")  

    # 使用 LangChain 表达式语言 (LCEL) 创建组合链  
    chain = prompt_template | model | StrOutputParser() | uppercase_output | count_words  

    # 运行组合链  
    result = chain.invoke({"topic": "律师", "joke_count": 3})  

    # 打印结果  
    print(result)

II. 链式 — 并行:

提示模板

    # 定义提示模板  
    prompt_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位专业的评论员。"),  
            ("human", "列出 {product_name} 的主要特点。"),  
        ]  
    )

定义了一个 ChatPromptTemplate,用来提示模型描述指定产品的关键特征。

优点和缺点分析:

    # 定义优点分析步骤
    def analyze_pros(features):
        pros_template = ChatPromptTemplate.from_messages(
            [
                ("system", "请从专业评审员的角度..."),
                (
                    "human",
                    "根据这些功能:{features},列举一下这些功能的优点吧。",
                ),
            ]
        )
        return pros_template.format_prompt(features=features)

    # 定义缺点分析步骤
    def analyze_cons(features):
        cons_template = ChatPromptTemplate.from_messages(
            [
                ("system", "请从专业评审员的角度..."),
                (
                    "human",
                    "根据这些功能:{features},说说这些功能的缺点吧。",
                ),
            ]
        )
        return cons_template.format_prompt(features=features)
  • 定义了两个函数 analyze_prosanalyze_cons,分别用于生成产品功能的优点和缺点的提示信息。

综合优缺点:

    # 将优缺点合并成最终评论
    def combine_pros_cons(pros, cons):  
        return f"好的地方:\n{pros}\n\n不好的地方:\n{cons}"

用LCEL来定义这些分支:

    从langchain.schema.runnable导入RunnableLambda,RunnableParallel  
    从langchain.schema.output_parser导入StrOutputParser  

    # 使用LCEL来简化分支  
    pros_branch_chain = (  
        RunnableLambda(lambda x: analyze_pros(x)) | model | StrOutputParser()  
    )  

    cons_branch_chain = (  
        RunnableLambda(lambda x: analyze_cons(x)) | model | StrOutputParser()  
    )
  • 使用LangChain表达式语言(LCEL)创建两个分支,每个分支分别使用RunnableLambda来应用分析函数和生成响应,并用StrOutputParser解析模型输出,来处理各自的优势和劣势。

把所有东西连成一条链:

    # 使用 LangChain 表达式语言 (LCEL) 生成组合链
    chain = (  
        prompt_template  
        | model  
        | StrOutputParser()  
        | RunnableParallel(branches={"优点": pros_branch_chain, "缺点": 缺点_branch_chain})  
        | RunnableLambda(lambda x: 合并优点和缺点(x["branches"]["优点"], x["branches"]["缺点"]))  # 将优点和缺点结合的 lambda 表达式
    )
  • 将初始提示、模型调用和并行处理分支整合成一个流程。使用 RunnableParallel 来并行执行正反两个分支,最后将这些结果整合成最终输出。

启动链条:

    # 运行这条链
    result = chain.调用({"product_name": "MacBook Pro"})

输出结果:

from dotenv import load_dotenv  
from langchain.prompts import ChatPromptTemplate  
from langchain.schema.output_parser import StrOutputParser  
from langchain.schema.runnable import RunnableParallel, RunnableLambda  
from langchain_openai import ChatOpenAI  

# 从 .env 文件中加载环境变量  
load_dotenv()  

# 创建一个 ChatOpenAI 模型  
model = ChatOpenAI(model='gpt-4o-mini')  

# 定义提示模板  
prompt_template = ChatPromptTemplate.from_messages(  
    [  
        ("system", "你是一位专家级的产品评论者。"),  
        ("human", "列出产品 {product_name} 的主要功能。"),  
    ]  
)  

# 定义优点分析步骤  
def analyze_pros(features):  
    pros_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位专家级的产品评论者。"),  
            (  
                "human",  
                "根据这些功能:{features},列出这些功能的优点。",  
            ),  
        ]  
    )  
    return pros_template.format_prompt(**{'features': features})  

# 定义缺点分析步骤  
def analyze_cons(features):  
    cons_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一位专家级的产品评论者。"),  
            (  
                "human",  
                "根据这些功能:{features},列出这些功能的缺点。",  
            ),  
        ]  
    )  
    return cons_template.format_prompt(**{'features': features})  

# 将优点和缺点合并成最终的评论  
def combine_pros_cons(pros, cons):  
    return f"优点:\n{pros}\n\n缺点:\n{cons}"  

# 使用 LCEL 简化分支  
pros_branch_chain = (RunnableLambda(lambda x: analyze_pros(x)) | model | StrOutputParser())  

cons_branch_chain = (RunnableLambda(lambda x: analyze_cons(x)) | model | StrOutputParser())  

# 使用 LangChain 表达式语言 (LCEL) 创建组合链  
chain = (  
    prompt_template  
    | model  
    | StrOutputParser()  
    | RunnableParallel(branches={"pros": pros_branch_chain, "cons": cons_branch_chain})  
    | RunnableLambda(lambda x: combine_pros_cons(x['branches']['pros'], x['branches']['cons']))  
)  

# 运行链  
result = chain.invoke({'product_name': 'MacBook Pro'})  

# 输出结果  
print(result)  # 输出最终的评论结果
II. 链式及分支型

不同反馈类型的提示模板示例:

    # 定义不同反馈类型的提示模板  
    positive_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是乐于助人的"),  
            ("human",  
             "感谢一下这条积极的反馈:{feedback}。"),  
        ]  
    )  

    negative_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是乐于助人的"),  
            ("human",  
             "回复一下这条负面的反馈:{feedback}。"),  
        ]  
    )  

    neutral_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是乐于助人的"),  
            (  
                "human",  
                "请求更多细节这条中性的反馈:{feedback}。",  
            ),  
        ]  
    )  

    escalate_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是乐于助人的"),  
            (  
                "human",  
                "将这条反馈转交给人工客服处理:{feedback}。",  
            ),  
        ]  
    )
  • 定义基于不同反馈类型的模板:积极、消极、中立,还有需要上报的反馈。

反馈分类的模板:

    # 定义反馈分类模板  
    classification_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的好助手。"),  
            ("human",  
             "请将以下反馈的情感归类为正面、负面、中立或需要上报:{feedback}。"),  
        ]  
    )

可执行的反馈处理方式如下:

    # 定义用于处理反馈的可运行分支
    branches = RunnableBranch(
        (
            lambda x: "positive" in x,
            positive_feedback_template | model | StrOutputParser()  # 积极的反馈链
        ),
        (
            lambda x: "negative" in x,
            negative_feedback_template | model | StrOutputParser()  # 消极的反馈链
        ),
        (
            lambda x: "neutral" in x,
            neutral_feedback_template | model | StrOutputParser()  # 中性的反馈链
        ),
        escalate_feedback_template | 模型 | StrOutputParser(),  # 增加逗号以保持语句一致性
    )
  • 定义一个名为 RunnableBranch 的,根据分类结果来选择合适的响应生成分支条件。

让我们来看一下带有这个链路——分叉的完整代码。

    从dotenv模块导入load_dotenv  
    从langchain.prompts导入ChatPromptTemplate  
    从langchain.schema.output_parser导入StrOutputParser  
    从langchain.schema.runnable导入RunnableBranch  
    从langchain_openai导入ChatOpenAI  

    # 从.env文件加载环境变量  
    load_dotenv()  

    # 创建一个ChatOpenAI模型  
    model = ChatOpenAI(model="gpt-4o-mini")  

    # 定义不同反馈类型的提示模板  
    positive_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的助手。"),  
            ("human",  
             "为这条正面反馈生成一封感谢信:{feedback}。"),  
        ]  
    )  

    negative_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的助手。"),  
            ("human",  
             "为这条负面反馈生成一个回应:{feedback}。"),  
        ]  
    )  

    neutral_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的助手。"),  
            ("human",  
             "为这条中立反馈请求更多细节:{feedback}。"),  
        ]  
    )  

    escalate_feedback_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的助手。"),  
            ("human",  
             "为这条反馈生成一个需要转交给客服的信息:{feedback}。"),  
        ]  
    )  

    # 定义反馈分类提示模板  
    classification_template = ChatPromptTemplate.from_messages(  
        [  
            ("system", "你是一个乐于助人的助手。"),  
            ("human",  
             "将这条反馈的情感分类为正面、负面、中立或需要转交:{feedback}。"),  
        ]  
    )  

    # 定义处理反馈的可运行分支  
    branches = RunnableBranch(  
        (  
            lambda x: "positive" in x,  
            positive_feedback_template | model | StrOutputParser()  # 正面反馈链  
        ),  
        (  
            lambda x: "negative" in x,  
            negative_feedback_template | model | StrOutputParser()  # 负面反馈链  
        ),  
        (  
            lambda x: "neutral" in x,  
            neutral_feedback_template | model | StrOutputParser()  # 中立反馈链  
        ),  
        escalate_feedback_template | model | StrOutputParser()  
    )  

    # 创建分类链  
    classification_chain = classification_template | model | StrOutputParser()  

    # 将分类和响应生成合并为一个链  
    chain = classification_chain | branches  

    # 使用示例评论运行链  
    # 好的评论 - "产品很棒。我非常喜欢使用它,觉得它非常有用。"  
    # 坏的评论 - "产品很糟糕。才用了几次就坏了,质量非常差。"  
    # 中立的评论 - "产品还可以。按预期工作,但没有什么特别之处。"  
    # 默认 - "我对这个产品还不是很确定。你能告诉我更多关于它的功能和好处吗?"  

    review = "产品很糟糕。才用了几次就坏了,质量非常差。"  
    result = chain.invoke({"feedback": review})  

    # 输出结果如下  
    print(result)

上述代码的输出是:

这个例子说明了如何使用LangChain来自动化情绪分析,并根据上下文生成合适的用户反馈回复,这对客户服务和反馈管理应用非常有用。

使用LangChain链类型的优势
  • 模块化: 链支持模块化设计,使得更换组件和集成新功能变得简单。
  • 可重用性: 链可以在不同的应用程序中重复使用,减少开发时间和精力。
  • 可扩展性: 基于链的设计支持可扩展的解决方案,通过将小而易管理的组件组合成更大的流程来实现。
  • 定制化: 开发人员可以创建定制链,以满足特定需求,从而实现高度专业化应用。

来点掌声哦 👏,觉得有帮助的话,留言评论一下吧 ❤️🙏

参考文献:
  1. <https://python.langchain.com/v0.2/docs/concepts/#prompt 模板https://python.langchain.com/v0.2/docs/concepts/#prompt 模板>

  2. https://python.langchain.com/v0.2/docs/integrations/chat/

  3. https://brandonhancock.io/langchain-master-class

  4. https://python.langchain.com/v0.1/docs/modules/chains/
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消