首页 > 其他分享 >全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南

全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南

时间:2025-01-17 16:32:29浏览次数:3  
标签:chain 任务分配 LangChain ChatPromptTemplate 任务 template input 链条 Router

系列文章目录

01-玩转LangChain:从模型调用到Prompt模板与输出解析的完整指南
02-玩转 LangChain Memory 模块:四种记忆类型详解及应用场景全覆盖
03-全面掌握 LangChain:从核心链条构建到动态任务分配的实战指南


文章目录


前言

在自然语言处理(NLP)的世界里,任务需求的多样性和复杂性不断给开发者提出挑战。一个高效的 NLP 系统需要同时胜任多个任务,例如动态生成广告语、个性化推荐,甚至能回答跨学科的问题。然而,传统开发方法通常需要独立为每个任务设计逻辑模块,不仅耗时耗力,还极易导致代码的复杂性失控。

LangChain 以其模块化的设计为这一问题提供了解决方案。它不仅简化了开发流程,还通过强大的链条组合能力,使开发者能够快速搭建从单一任务到多任务分配的完整逻辑流。本篇文章将围绕 LangChain 的核心功能模块展开,从理论到实战,全面展示如何通过它实现自然语言处理任务的高效管理。

在本文中,您将学到以下内容:

  1. LangChain 的核心链简介:从基础模块(如 ChatPromptTemplatePipe Operator)入手,学习如何构建单任务处理链条,逐步扩展到多步骤的复杂任务链。特别是通过 RunnableSequence,我们将探讨如何在多步骤任务中实现数据流转和结果汇总。
  2. Router Chain:任务分配与动态路由:通过动态路由机制,将输入内容分配到最适合的处理链条,实现智能化的跨领域任务处理,如物理、数学、历史和计算机科学问题的解答。

不仅如此,文章还提供了详细的代码示例,涵盖从单一任务到复杂任务链条的完整实现过程,助力您快速上手并将其应用于实际项目。

为什么你需要关注这篇文章?

  • 如果您是一名自然语言处理的新手:本文将带您快速入门,从基础到进阶,掌握 LangChain 的核心功能。
  • 如果您是一名经验丰富的开发者:动态路由和复杂链条的设计方法,将大幅提升您的系统灵活性与开发效率。

本文不是一个纯理论的解读,而是一个贯穿实践的指南。无论是生成广告语、推荐餐厅,还是动态解决跨学科问题,LangChain 都能为您提供强大的技术支持。而本文正是您解锁这些潜能的第一步。


一、LangChain 的核心链简介

LangChain 提供了丰富的模块,帮助开发者高效构建自然语言处理任务的逻辑流。本章将介绍如何通过新的方法直接结合 ChatPromptTemplateChatOpenAI 来实现核心功能,并利用 Pipe OperatorRunnableSequence 实现从简单到复杂的任务链。


1.1 单任务的 Prompt 模型结合

通过 ChatPromptTemplateChatOpenAI 的结合,可以快速实现单一任务,例如生成广告语、回答问题或其他简单任务。

1.1.1 使用 Prompt 模型生成广告语

以下示例展示了如何结合提示模板与语言模型,生成一条针对产品的中文广告语:

import os
from dotenv import load_dotenv  # 加载环境变量
from langchain_openai import ChatOpenAI  # OpenAI 的语言模型支持
from langchain.prompts import ChatPromptTemplate

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

# 从环境变量中获取 API Key 和 Base URL
api_key = os.getenv("ALIYUN_API_KEY")
base_url = os.getenv("ALIYUN_API_URL")

# 初始化语言模型
llm = ChatOpenAI(
    openai_api_key=api_key,
    model_name="qwen-plus",  # 使用 Qwen-Plus 模型
    base_url=base_url,
)

# 定义提示模板
prompt = ChatPromptTemplate.from_template(
    "请为以下产品设计一句吸引人的广告语:\n\n产品:{product}"
)

# 创建链条
chain = prompt | llm

# 输入产品信息并运行链条
product = "健康无糖茶饮"
result = chain.invoke({"product": product})
print(f"生成的广告语:{result.content}")
(1)功能说明
  • 模板动态化{product} 是占位符,运行时会被实际的输入内容替换。
  • 输出示例"一口茶香,一份健康,享受无糖新生活!"
(2)适用场景
  • 生成产品广告语。
  • 处理单一任务,例如生成问候语或生成 FAQ。
(3)注意事项
  • 提示模板需尽量明确,以提高输出结果的精准度。
  • 调整 temperature 参数可控制生成结果的多样性。

1.2 管道组合:顺序执行的简单链条

管道组合(Pipe Operator,即 |)是一种高效的方式,可以将多个任务串联起来,每个任务的输出作为下一个任务的输入。这种方法适用于线性的多步骤任务。

1.2.1 使用管道组合生成品牌名称和简介

以下示例展示如何通过两步链条,生成一个中文品牌名称并为其撰写品牌简介:

# 定义第一个任务:生成品牌名称
first_prompt = ChatPromptTemplate.from_template(
    "为一家主营{product}的公司起一个中文品牌名称。"
)
chain_one = first_prompt | llm

# 定义第二个任务:生成品牌简介
second_prompt = ChatPromptTemplate.from_template(
    "为以下品牌撰写一段简介:\n\n品牌名称:{brand_name}"
)
chain_two = second_prompt | llm

# 通过管道组合两个任务
simple_chain = chain_one | chain_two

# 输入数据并运行链条
product = {"product": "智能家居设备"}
result = simple_chain.invoke(product)

# 输出最终结果
print(f"生成结果:{result.content}")
(1)输出示例
  • 品牌名称"智家优选"
  • 品牌简介"智家优选致力于提供智能化的家居解决方案,为家庭带来便捷与高科技体验。"
(2)适用场景
  • 品牌命名与文案撰写。
  • 需要简单线性逻辑的任务,例如分两步生成标题和内容。
(3)注意事项
  • 管道链条适用于简单的线性任务,不适合复杂的逻辑。
  • 输入格式需与提示模板一致,确保正确传递数据。

1.3 RunnableSequence:多步骤复杂任务链

RunnableSequence 是 LangChain 的高级功能模块,支持复杂任务链,例如需要多输入、多输出以及多步骤的数据流转。

1.3.1 使用 RunnableSequence 实现多步骤餐厅推荐

以下示例展示如何通过多步骤链条,处理用户餐厅推荐任务,包括分析用户偏好、推荐餐厅并总结结果:

from langchain_core.runnables import RunnableSequence

# 步骤 1:分析用户输入的餐厅偏好
gather_preferences_prompt = ChatPromptTemplate.from_template(
    "用户输入了一些餐厅偏好:{preferences}\n"
    "请将用户的偏好总结为清晰的需求:"
)

# 步骤 2:根据需求推荐餐厅
recommend_restaurants_prompt = ChatPromptTemplate.from_template(
    "基于用户需求:{summarized_preferences}\n"
    "请推荐 3 家适合的餐厅,并说明推荐理由:"
)

# 步骤 3:总结推荐内容供用户快速参考
summarize_recommendations_prompt = ChatPromptTemplate.from_template(
    "以下是餐厅推荐和推荐理由:\n{recommendations}\n"
    "请总结成 2-3 句话,供用户快速参考:"
)

# 将每个任务组合成链条
gather_preferences_chain = gather_preferences_prompt | llm
recommend_restaurants_chain = recommend_restaurants_prompt | llm
summarize_recommendations_chain = summarize_recommendations_prompt | llm

# 创建 RunnableSequence
restaurant_chain = RunnableSequence(
    gather_preferences_chain,
    recommend_restaurants_chain,
    summarize_recommendations_chain
)

# 示例输入数据
input_data = {"preferences": "我喜欢安静的环境,最好有素食选项,并且价格适中。"}

# 执行链条
result = restaurant_chain.invoke(input_data)

# 输出最终结果
print(result.content)
(1)输出示例
  • 总结偏好"用户偏好安静的餐厅,提供素食选项,价格适中。"
  • 推荐餐厅
    • 素心小馆:环境安静,素食菜单丰富,价格合理。
    • 自然味道:素食自助餐厅,空间宽敞,经济实惠。
    • 绿叶咖啡馆:多样化菜单,氛围安静。
  • 总结推荐"推荐素心小馆、自然味道和绿叶咖啡馆,均符合您的素食和安静需求。"
(2)适用场景
  • 个性化推荐:餐厅、旅游路线、酒店等。
  • 多步骤任务链:如从输入中提取信息、分析并生成总结。
(3)注意事项
  • 每一步的输入和输出变量需保持一致。
  • 数据格式需严格按照每步任务的需求定义。

二、Router Chain:任务分配与动态路由

在复杂的自然语言处理场景中,不同输入内容可能需要不同的处理逻辑。例如,物理问题、数学问题和历史问题的解决方式可能完全不同。Router Chain 提供了动态路由解决方案,可以根据输入内容自动选择适合的处理链条。以下内容将结合您修改后的代码,详细讲解如何实现动态路由及其应用场景。


2.1 Router Chain 的概念

Router Chain 是 LangChain 提供的一种动态任务分配机制。它通过路由逻辑分析输入内容,将其动态分配到最合适的任务链。如果输入无法归类,则会调用默认处理链。Router Chain 的核心优势是灵活适配多领域任务处理需求。


2.2 实现步骤

以下是基于您的代码实现的完整动态路由逻辑及任务链的步骤。

2.2.1 定义任务模板

首先为不同领域(物理、数学、历史、计算机科学)的问题定义任务模板。这些模板会根据输入内容动态生成回答。

from langchain.prompts import ChatPromptTemplate

# 定义物理任务模板
physics_template = ChatPromptTemplate.from_template(
    "你是一位物理学教授,擅长用简洁易懂的方式回答物理问题。以下是问题内容:{input}"
)

# 定义数学任务模板
math_template = ChatPromptTemplate.from_template(
    "你是一位数学家,擅长分步骤解决数学问题,并提供详细的解决过程。以下是问题内容:{input}"
)

# 定义历史任务模板
history_template = ChatPromptTemplate.from_template(
    "你是一位历史学家,对历史事件和背景有深入研究。以下是问题内容:{input}"
)

# 定义计算机科学任务模板
computerscience_template = ChatPromptTemplate.from_template(
    "你是一位计算机科学专家,擅长算法、数据结构和编程问题。以下是问题内容:{input}"
)

2.2.2 创建任务链

将上述模板与语言模型(ChatOpenAI)结合,形成任务链条。

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI

load_dotenv()

# 从环境变量中获取 API Key 和 Base URL
api_key = os.getenv("ALIYUN_API_KEY")
base_url = os.getenv("ALIYUN_API_URL")

# 初始化语言模型
llm = ChatOpenAI(
    openai_api_key=api_key,
    model_name="qwen-plus",  # 使用 Qwen-Plus 模型
    base_url=base_url
)

# 将模板与语言模型结合,形成各领域的任务链
physics_chain = physics_template | llm
math_chain = math_template | llm
history_chain = history_template | llm
computerscience_chain = computerscience_template | llm

2.2.3 定义动态路由逻辑

通过自定义的 RunnableLambda 定义路由逻辑,根据输入内容分配到不同任务链。

from langchain_core.runnables import RunnableLambda

# 定义动态路由逻辑
def route(input):
    if "物理" in input["input"]:
        return {"key": "physics", "input": input["input"]}
    elif "数学" in input["input"]:
        return {"key": "math", "input": input["input"]}
    elif "历史" in input["input"]:
        return {"key": "history", "input": input["input"]}
    elif "计算机" in input["input"]:
        return {"key": "computer_science", "input": input["input"]}
    else:
        return {"key": "default", "input": input["input"]}

# 创建路由逻辑的 Runnable
route_runnable = RunnableLambda(route)

2.2.4 定义默认处理链

当输入内容无法匹配任何任务链时,使用默认处理链处理问题。

# 定义默认处理链
default_chain = ChatPromptTemplate.from_template(
    "输入内容无法归类,请直接回答:{input}"
) | llm

2.2.5 创建 RouterRunnable

将所有任务链和默认链条整合到 RouterRunnable 中,用于动态分配任务。

from langchain_core.runnables import RouterRunnable

# 创建 RouterRunnable
router = RouterRunnable(
    runnables={
        "physics": physics_chain,
        "math": math_chain,
        "history": history_chain,
        "computer_science": computerscience_chain,
        "default": default_chain
    }
)

2.2.6 创建完整的 Router Chain

通过 RunnableSequence 将路由逻辑与任务链整合为一个完整的 Router Chain

from langchain_core.runnables import RunnableSequence

# 创建完整的 Router Chain
router_chain = RunnableSequence(route_runnable, router)

2.2.7 测试 Router Chain

为 Router Chain 提供示例输入,验证动态分配逻辑是否正确。

# 定义示例输入
inputs = [
    {"input": "什么是黑体辐射?"},  # 物理问题
    {"input": "计算 2 + 2 的结果。"},  # 数学问题
    {"input": "介绍一次世界大战的背景。"},  # 历史问题
    {"input": "如何实现快速排序算法?"}  # 计算机科学问题
]

# 执行 Router Chain 并输出结果
for inp in inputs:
    result = router_chain.invoke(inp)
    print(f"问题:{inp['input']}\n回答:{result.content}\n")

2.3 完整代码

import os
from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from langchain.prompts import ChatPromptTemplate
from langchain_core.runnables import RouterRunnable, RunnableLambda, RunnableSequence

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

# 从环境变量中获取 API Key 和 Base URL
api_key = os.getenv("ALIYUN_API_KEY")
base_url = os.getenv("ALIYUN_API_URL")

# 初始化语言模型
llm = ChatOpenAI(
    openai_api_key=api_key,
    model_name="qwen-plus",  # 使用 Qwen-Plus 模型
    base_url=base_url
)

# Step 1: 定义各领域的任务模板
# 定义物理任务模板
physics_template = ChatPromptTemplate.from_template(
    "你是一位物理学教授,擅长用简洁易懂的方式回答物理问题。以下是问题内容:{input}"
)

# 定义数学任务模板
math_template = ChatPromptTemplate.from_template(
    "你是一位数学家,擅长分步骤解决数学问题,并提供详细的解决过程。以下是问题内容:{input}"
)

# 定义历史任务模板
history_template = ChatPromptTemplate.from_template(
    "你是一位历史学家,对历史事件和背景有深入研究。以下是问题内容:{input}"
)

# 定义计算机科学任务模板
computerscience_template = ChatPromptTemplate.from_template(
    "你是一位计算机科学专家,擅长算法、数据结构和编程问题。以下是问题内容:{input}"
)

# Step 2: 将模板与语言模型结合,形成任务链
physics_chain = physics_template | llm
math_chain = math_template | llm
history_chain = history_template | llm
computerscience_chain = computerscience_template | llm

# Step 3: 定义动态路由逻辑
def route(input):
    if "物理" in input["input"]:
        return {"key": "physics", "input": input["input"]}
    elif "数学" in input["input"]:
        return {"key": "math", "input": input["input"]}
    elif "历史" in input["input"]:
        return {"key": "history", "input": input["input"]}
    elif "计算机" in input["input"]:
        return {"key": "computer_science", "input": input["input"]}
    else:
        return {"key": "default", "input": input["input"]}

# 创建路由逻辑的 Runnable
route_runnable = RunnableLambda(route)

# 定义默认处理链
default_chain = ChatPromptTemplate.from_template(
    "输入内容无法归类,请直接回答:{input}"
) | llm

# Step 4: 创建 RouterRunnable
router = RouterRunnable(
    runnables={
        "physics": physics_chain,
        "math": math_chain,
        "history": history_chain,
        "computer_science": computerscience_chain,
        "default": default_chain
    }
)

# Step 5: 创建完整的 Router Chain
router_chain = RunnableSequence(route_runnable, router)

# Step 6: 测试 Router Chain
# 定义示例输入
inputs = [
    {"input": "什么是黑体辐射?"},  # 物理问题
    {"input": "计算 2 + 2 的结果。"},  # 数学问题
    {"input": "介绍一次世界大战的背景。"},  # 历史问题
    {"input": "如何实现快速排序算法?"}  # 计算机科学问题
]

# 执行 Router Chain 并输出结果
for inp in inputs:
    result = router_chain.invoke(inp)
    print(f"问题:{inp['input']}\n回答:{result.content}\n")


2.4 输出示例

根据输入内容,Router Chain 将问题分配到合适的任务链,并生成对应的答案。例如:

  1. 输入"什么是黑体辐射?"
    输出"黑体辐射是一个理想黑体发出的电磁辐射,其能量分布与温度相关。"

  2. 输入"计算 2 + 2 的结果。"
    输出"2 + 2 的结果是 4。"

  3. 输入"介绍一次世界大战的背景。"
    输出"一次世界大战的爆发是由于帝国主义竞争、民族主义以及萨拉热窝事件的直接影响。"

  4. 输入"如何实现快速排序算法?"
    输出"快速排序是一种分治算法,核心步骤包括选择基准值、分区操作和递归调用子序列排序。"


2.5 注意事项

  1. 路由逻辑的扩展性

    • 如果需要支持更多领域,可以在 route 函数中添加相应的逻辑,并新增任务链条。
  2. 默认处理链的重要性

    • 确保所有输入都有处理结果,未分类问题可以通过默认链解决。
  3. 任务描述的清晰性

    • 确保每个模板内容精准描述其领域,避免交叉或冲突。

三、总结

本文全面解析了 LangChain 的两大核心功能模块:基础链条构建与动态任务分配,并通过具体示例演示了它们的强大应用。以下是本文的核心要点总结:

3.1 LangChain 的核心链简介

  • 单任务 Prompt 模型结合

    • 使用 ChatPromptTemplateChatOpenAI 快速构建单任务处理链条,例如生成广告语和回答简单问题。
    • 示例代码展示了如何通过简单的输入实现动态化输出,体现了模块的灵活性。
  • 管道组合实现多步骤任务

    • 通过 Pipe Operator|)将多个任务串联,构建线性任务链,实现如品牌命名与简介生成等复杂逻辑。
    • 每个任务模块独立、清晰,可轻松扩展或修改。
  • RunnableSequence 构建复杂链条

    • 借助 RunnableSequence 模块,将多步骤任务串联为更高级的复杂链条。
    • 示例展示了如何根据用户输入偏好,动态生成餐厅推荐,并总结推荐内容,解决实际应用中的多步骤问题。

3.2 Router Chain:任务分配与动态路由

  • 动态任务分配的核心机制

    • 基于 RouterRunnableRunnableLambda,实现输入内容的智能分类和任务分配。
    • 自定义路由逻辑,根据输入内容将其路由到物理、数学、历史、计算机科学等不同领域的任务链。
  • 完整代码实现

    • 提供从任务模板定义到动态路由测试的完整代码,涵盖了任务链构建、自定义路由逻辑、默认处理链等所有步骤。
    • 默认处理链的设计确保了所有输入都能得到合理的响应。
  • 实际应用场景

    • 动态问答系统:支持多领域问题的高效解答。
    • 个性化推荐系统:根据用户需求动态生成个性化内容。
    • 跨学科任务处理:灵活适配复杂的自然语言处理场景。

标签:chain,任务分配,LangChain,ChatPromptTemplate,任务,template,input,链条,Router
From: https://blog.csdn.net/Kiradzy/article/details/145143465

相关文章

  • 二次开发,在使用LangChain中的Tongyi模型进行流式输出streaming报错问题,官网框架的BUG
    在使用LangChain中的Tongyi模型进行流式输出时,按照官方的代码直接运行会报一个类型错误:TypeError:Additionalkwargskeyoutput_tokensalreadyexistsinleftdictandvaluehasunsupportedtype<class'int'>.​其指向的错误文件路径如下C:\Users\Chenhao\AppData\Lo......
  • 任务分配与信息共享:跨职能团队协作的利器
    一、跨职能团队协作的挑战沟通障碍与信息不对称跨职能团队通常由来自不同部门的成员组成,各个部门之间存在语言、目标和工作方式上的差异。例如,研发团队更加注重技术细节和功能实现,而市场和销售团队则关注产品的市场定位、推广策略和客户需求。这种背景差异往往会导致沟通中的误......
  • 构建本地知识库:基于 LangChain 和 Ollama 的 RAG 实现教程
    构建本地知识库:基于LangChain和Ollama的RAG实现教程简介在这个教程中,我们将学习如何构建一个本地运行的知识库系统,它能够让用户上传PDF或TXT文档,并通过自然语言与文档内容进行交互。这个系统使用了RAG(检索增强生成)技术,结合了LangChain、Ollama和Streamlit......
  • 从零开始的LangChain开发教程:快速上手指南
    快速上手LangChain:轻松构建LLM应用在构建基于语言模型(LLM)的应用时,LangChain提供了一套功能强大的工具集,帮助开发者快速实现从文本处理、对话生成到复杂的问答系统等各类任务。本文将从基础入门到复杂场景应用,带你快速掌握LangChain的核心能力。1.技术背景介绍LangChain......
  • 利用 LangChain 与 Eden AI 模型进行交互的完整指南
    利用LangChain与EdenAI模型进行交互的完整指南EdenAI是一个颠覆性的AI平台,通过统一多个提供商的优秀AI模型,简化了开发者的工作流。凭借单一API,开发者可以快速将强大的AI功能整合到生产环境中,轻松实现多样化的AI能力。本文将介绍如何使用LangChain与Eden......
  • 如何贡献开源项目LangChain:完整指南
    LangChain是一个快速发展的开源项目,旨在构建强大的AI应用程序框架。作为一名开发者或技术爱好者,你或许希望为这个项目贡献力量,无论是开发新功能、修复bug、改进文档,还是参与讨论和设计。这篇文章将详细介绍如何高效地加入LangChain的开发与贡献,帮助你事半功倍。1.......
  • 基于SpringBoot+Vue在线项目管理与任务分配中的应用的设计与实现
    博主主页:一季春秋博主简介:专注Java技术领域和毕业设计项目实战、Java微信小程序、安卓等技术开发,远程调试部署、代码讲解、文档指导、ppt制作等技术指导。技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数据、物联......
  • 在LangChain中使用Hazy Research生态系统
    在AI技术不断发展的今天,HazyResearch提供了一套强大的工具生态系统,能够帮助开发者在语言模型和数据处理中获得更高的效率。今天,我们将探讨如何在LangChain中集成和使用HazyResearch的生态系统,实现安装和配置,并了解如何利用具体的HazyResearch封装器来提升应用的功能。技......
  • 使用Fireworks AI与LangChain集成实现高级AI对话功能
    技术背景介绍在AI时代,能够灵活使用各种预训练模型来处理不同的文本生成任务越来越重要。FireworksAI提供了一个强大的AI推理平台,专注于运行和自定义AI模型。与LangChain集成后,开发者可以更便捷地利用多种模型进行对话生成和自定义任务。核心原理解析FireworksAI通过其......
  • 如何通过LangChain使用KoboldAI的API进行AI辅助写作
    KoboldAI是一个浏览器端的前端工具,允许通过本地和远程的多种AI模型实现AI辅助写作。它提供了一个公共和本地API,可以与LangChain集成使用。本文将深入介绍如何通过LangChain使用KoboldAIAPI进行AI辅助写作。技术背景介绍KoboldAI提供了一个强大的界面,支持多种AI模型的集......