langchain主要模块(三):Chain

langchain2之Chain

  • langchain
    • 1.概念
    • 2.主要模块
        • 模型输入/输出 (Model I/O)
        • 数据连接 (Data connection)
        • 链式组装 (Chains)
        • 代理 (Agents)
        • 内存 (Memory)
        • 回调 (Callbacks)
    • 3.链
      • • LLMChain:
      • • SimpleSequentialChain
      • • Sequential Chains:
      • • RouterChain:

langchain_2">langchain

1.概念

什么是LangChain?

源起:LangChain产生源于Harrison与领域内的一些人交谈,这些人正在构建复杂的LLM应用,他在开发方式

上看到了一些可以抽象的部分。一个应用可能需要多次提示LLM并解析其输出,因此需要编写大量的复制粘贴。

LangChain使这个开发过程更加简单。一经推出后,在社区被广泛采纳,不仅有众多用户,还有许多贡献者参

与开源工作。

还有大模型本身的问题,无法感知实时数据,无法和当前世界进行交互。

LangChain是一个用于开发大语言模型的框架。

主要特性:

\1. 数据感知:能够将语⾔模型与其他数据源进⾏连接。

\2. 代理性:允许语⾔模型与其环境进⾏交互。可以通过写⼯具的⽅式做各种事情,数据的写⼊更新。

主要价值:

1、组件化了需要开发LLM所需要的功能,提供了很多工具,方便使用。

2、有一些现成的可以完整特定功能的链,也可以理解为提高了工具方便使用。

2.主要模块

在这里插入图片描述

LangChain 为以下模块提供了标准、可扩展的接口和外部集成,按照复杂程度从低到高列出:

模型输入/输出 (Model I/O)

与语言模型进行接口交互

数据连接 (Data connection)

与特定于应用程序的数据进行接口交互

链式组装 (Chains)

构造调用序列

代理 (Agents)

根据高级指令让链式组装选择要使用的工具

内存 (Memory)

在链式组装的多次运行之间持久化应用程序状态

回调 (Callbacks)

记录和流式传输任何链式组装的中间步骤

3.链

链允许我们将多个组件组合在一起,创建一个单一而连贯的应用程序。例如,我们可以创建一个链,接受用户输入,使用 PromptTemplate 进行格式化,然后将格式化的响应传递给 LLM。我们可以通过将多个链组合在一起或将链与其他组件组合来构建更复杂的链。

目前内置的几种常用Chain:

• LLMChain:

这是一个简单的链,由PromptTemplate和LLM组成,它使用提供的输入键值格式化提示模板,将格式化的字符串传递给LLM,并返回LLM的输出。

1.模型配置

from langchain.chat_models import ChatOpenAI
from langchain import LLMChain
from langchain.prompts.chat import (
    ChatPromptTemplate,
    HumanMessagePromptTemplate,
)

api_base_url = "http://192.168.175.6:8000/v1"  
api_key= "EMPTY"
LLM_MODEL = "Baichuan-13b-Chat"
model = ChatOpenAI(
    streaming=False,
    verbose=True,
    # callbacks=[callback],
    openai_api_key=api_key,
    openai_api_base=api_base_url,
    model_name=LLM_MODEL
)

2.设置模板

from langchain import PromptTemplate

template = """\
你是一个新公司的命名咨询顾问.
为制作 {product} 的公司起好的名字? 使用中文回答问题,不少于5个名字
"""

chat_prompt = PromptTemplate.from_template(template)
chain = LLMChain(prompt=chat_prompt, llm=model)
print(chain.run("五颜六色的袜子"))
  1. 彩虹袜坊 2. 缤纷袜艺 3. 七彩袜语 4. 多彩袜尚 5. 绚丽袜裳

• SimpleSequentialChain

每个步骤都有一个单一的输入/输出,一个步骤的输出是下一个步骤的输入。

from langchain.prompts import ChatPromptTemplate
from langchain.chains import SimpleSequentialChain

# 第一个Prompt和Chain
first_prompt = ChatPromptTemplate.from_template(
    "你是一个新公司的命名咨询顾问.为制作 {product} 的公司起2个好的名字? 使用中文回答问题"
)
chain_one = LLMChain(llm=model, prompt=first_prompt)

# 第二个Prompt和Chain
second_prompt = ChatPromptTemplate.from_template(
    "为下面的公司写一个20字的简短描述:{company_name}"
)
chain_two = LLMChain(llm=model, prompt=second_prompt)
# 把第一个Chain和第二个Chain合在一起
overall_simple_chain = SimpleSequentialChain(chains=[chain_one, chain_two],
                                             verbose=True
                                            )
overall_simple_chain.run("智能手机")

在这里插入图片描述

• Sequential Chains:

不是所有的链都是有固定的输入和输出,有时候中间的链需要多个输入,最终也有多个输出,这个时候考虑用SequentialChain

# 这是一个LLMChain,给定一个剧本的标题和它所处的时代,它的任务是写一个概要。
template = """你是一位剧作家。给定剧本的标题和它所处的时代,你的任务是为该标题写一个概要。

标题: {title}
时代: {era}
剧作家: 这是上述剧本的概要:"""
prompt_template = PromptTemplate(input_variables=["title", "era"], template=template)
synopsis_chain = LLMChain(llm=model, prompt=prompt_template, output_key="synopsis")

# 这是一个LLMChain,给定一个剧本的概要,它的任务是写一个剧本的评论。
template = """你是一位专业的剧本评论家。给定剧本的概要,你的任务是为该剧本写一篇评论。

剧本概要:
{synopsis}
你对上述剧本的评论:"""
prompt_template = PromptTemplate(input_variables=["synopsis"], template=template)
review_chain = LLMChain(llm=model, prompt=prompt_template, output_key="review")


# 这是整体链,我们按顺序运行这两个链。
from langchain.chains import SequentialChain
overall_chain = SequentialChain(
    chains=[synopsis_chain, review_chain],
    input_variables=["era", "title"],
    # 这里我们返回多个变量
    output_variables=["synopsis", "review"],
    verbose=True)

overall_chain({"title":"海滩上的日落悲剧", "era": "维多利亚时代的英格兰"})

在这里插入图片描述

• RouterChain:

有时候单个串行的Chain不能满足我们的诉求,这个时候考虑使用RouterChain

它在一系列的链(Chain)中动态地选择下一个要执行的链。这种模式通常用于处理复杂的逻辑流程,其中下一个执行的步骤取决于当前的输入或状态。

#例如,如果你正在构建一个问题回答系统,你可能有多个链,每个链专门处理一种类型的问题
# (例如,一个处理物理问题,一个处理数学问题等)。
# 然后,你可以使用一个"RouterChain"来检查每个问题的特性,并将问题路由到最适合处理该问题的链。
from langchain.chains.router import MultiPromptChain
from langchain.chains import ConversationChain
from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate

physics_template = """你是一位非常聪明的物理教授。 \
你擅长以简洁易懂的方式回答物理问题。 \
当你不知道问题的答案时,你会承认你不知道。

这是一个问题:
{input}"""

math_template = """你是一位非常好的数学家。你擅长回答数学问题。 \
你之所以这么好,是因为你能够将难题分解成各个组成部分, \
回答组成部分,然后将它们组合起来回答更广泛的问题。

这是一个问题:
{input}"""

prompt_infos = [
    {  "name": "物理", "description": "适合回答物理问题","prompt_template": physics_template,},
    {  "name": "数学", "description": "适合回答数学问题","prompt_template": math_template,},
]


destination_chains = {}
for p_info in prompt_infos:
    name = p_info["name"]
    prompt_template = p_info["prompt_template"]
    prompt = PromptTemplate(template=prompt_template, input_variables=["input"])
    chain = LLMChain(llm=model, prompt=prompt)
    destination_chains[name] = chain

# 默认的Chain
default_chain = ConversationChain(llm=model, output_key="text")

destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
print(destination_chains.keys())
print(destinations)

dict_keys([‘物理’, ‘数学’]) [‘物理: 适合回答物理问题’, ‘数学: 适合回答数学问题’]

from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
# 物理: 适合回答物理问题', '数学: 适合回答数学问题
destinations = [f"{p['name']}: {p['description']}" for p in prompt_infos]
destinations_str = "\n".join(destinations)

router_prompt_template = """\
给定一个原始的文本输入到语言模型中,选择最适合输入的模型提示。
你将得到可用提示的名称和提示最适合的描述。如果你认为修改原始输入最终会得到更好的语言模型响应,你也可以修改原始输入。

<< 格式化 >>
返回一个markdown代码片段,其中包含一个格式化为如下样式的JSON对象:
​```json
{{{{
    "destination": string \\ 使用的提示名称或"DEFAULT"
    "next_inputs": string \\ 可能修改过的原始输入
}}}}
​```

记住:"destination" 必须是下面指定的候选提示名称之一,或者如果输入不适合任何候选提示,它可以是"DEFAULT"。
记住:"next_inputs" 可以是原始输入,如果你认为不需要任何修改。

<< 候选提示 >>
{destinations}

<< 输入 >>
{{input}}

<< 输出 >>
"""
router_template = router_prompt_template.format(destinations=destinations_str)
router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)
router_chain = LLMRouterChain.from_llm(model, router_prompt)

# 构建RouterChains
chain = MultiPromptChain(
    router_chain=router_chain,
    destination_chains=destination_chains,
    default_chain=default_chain,
    verbose=True,
)
print(chain.run("什么是黑体辐射?"))

在这里插入图片描述

print(chain.run("计算下7乘以24,然后再乘以60等于多少?"))

在这里插入图片描述

print(chain.run("什么是彩虹?"))

在这里插入图片描述


http://www.niftyadmin.cn/n/5023546.html

相关文章

C++ - 二叉树OJ题

二叉树的两种层序遍历 在写之前&#xff0c;我们先来看两种二叉树的层序遍历&#xff1a; 1.给你二叉树的根节点 root &#xff0c;返回其节点值的 层序遍历 。 &#xff08;即逐层地&#xff0c;从左到右访问所有节点&#xff09;。 输入&#xff1a;root [3,9,20,null,null…

Swagger(1):Swagger简介

1前言 接口文档对于前后端开发人员都十分重要。尤其近几年流行前后端分离后接口文档又变成重中之重。接口文档固然重要&#xff0c;但是由于项目周期等原因后端人员经常出现无法及时更新&#xff0c;导致前端人员抱怨接口文档和实际情况不一致。 很多人员会抱怨别人写的接口文…

聚类-kmeans

聚类算法是无监督学习算法&#xff0c;指定将数据分成k个簇。然后通过每个点到各个簇的中心的欧氏距离来分类。 kmeans本身会陷入局部最小值的状况&#xff0c;二分kmeans可以解决这一点。 二分kmeans是遍历所有的簇&#xff0c;将其分成2个&#xff0c;比较哪一个分裂结果更…

Golang 结构化日志包 log/slog 详解(三):属性字段和日志级别

上一篇文章讲解了 log/slog 包中的 Handler 的使用方法&#xff0c;通过不同的 Handler 可以输出不同格式的日志。接下来看一下如何自定义日志的属性字段和日志级别。 属性字段&#xff08;attribute&#xff09; 许多日志都有一些通用的的字段&#xff0c;例如日志级别 lev…

运用贪心算法实现卡牌游戏-2023年全国青少年信息素养大赛Python复赛真题精选

[导读]&#xff1a;超平老师计划推出《全国青少年信息素养大赛Python编程真题解析》50讲&#xff0c;这是超平老师解读Python编程挑战赛真题系列的第18讲。 全国青少年信息素养大赛&#xff08;原全国青少年电子信息智能创新大赛&#xff09;是“世界机器人大会青少年机器人设…

代码随想录day50|123. 买卖股票的最佳时机 III188. 买卖股票的最佳时机 IV

123. 买卖股票的最佳时机 III class Solution:def maxProfit(self, prices: List[int]) -> int:dp[[0]*5 for _ in range(len(prices))]dp[0][0]0dp[0][1]-prices[0]dp[0][2]0dp[0][3]-prices[0]dp[0][4]0for i in range(1,len(prices)):dp[i][0] dp[i-1][0]dp[i][1] max…

【算法专题突破】滑动窗口- 将 x 减到 0 的最小操作数(12)

目录 1. 题目解析 2. 算法原理 3. 代码编写 写在最后&#xff1a; 1. 题目解析 题目链接&#xff1a;1658. 将 x 减到 0 的最小操作数 - 力扣&#xff08;Leetcode&#xff09; 这道题并不难理解&#xff0c;其实就是在数组里找值&#xff0c;直到把x减成0&#xff0c; 这…

ShardingSphere分库分表(一):高性能架构模式

互联网业务兴起之后&#xff0c;海量用户加上海量数据的特点&#xff0c;单个数据库服务器已经难以满足业务需要&#xff0c;必须考虑数据库集群的方式来提升性能。高性能数据库集群的第一种方式是“读写分离”&#xff0c;第二种方式是“数据库分片”。 文章目录 1、读写分离架…