小白举手05-青训营ai笔记-chain+memory| 豆包MarsCode AI 刷题

121 阅读7分钟

一、定义

(一)什么是链

“Chain” 来链接LangChain的各个组件和功能——模型之间彼此链接,或模型与其他组件链接。

使用链的原因是整体代码能够更加简洁,就类似于链是一个包,然后你输入==包===输出,只用调用这个包即可

(二)链的类型

image.png

(三)路由链

RouterChain,也叫路由链,能动态选择用于给定输入的下一个链。我们会根据用户的问题内容,首先使用路由器链确定问题更适合哪个处理模板,然后将问题发送到该处理模板进行回答。如果问题不适合任何已定义的处理模板,它会被发送到默认链。

在这里,我们会用LLMRouterChain和MultiPromptChain(也是一种路由链)组合实现路由功能,该MultiPromptChain会调用LLMRouterChain选择与给定问题最相关的提示,然后使用该提示回答问题。

具体步骤如下:

  1. 构建处理模板:为鲜花护理和鲜花装饰分别定义两个字符串模板。
  2. 提示信息:使用一个列表来组织和存储这两个处理模板的关键信息,如模板的键、描述和实际内容。
  3. 初始化语言模型:导入并实例化语言模型。
  4. 构建目标链:根据提示信息中的每个模板构建了对应的LLMChain,并存储在一个字典中。
  5. 构建LLM路由链:这是决策的核心部分。首先,它根据提示信息构建了一个路由模板,然后使用这个模板创建了一个LLMRouterChain。
  6. 构建默认链:如果输入不适合任何已定义的处理模板,这个默认链会被触发。
  7. 构建多提示链:使用MultiPromptChain将LLM路由链、目标链和默认链组合在一起,形成一个完整的决策系统。

(四)conversationchain

ConversationChain 作为默认链的原因主要在于其设计和功能特点,使其在处理未匹配输入时能够有效地提供响应。以下是具体的分析:

1. 上下文管理能力

ConversationChain 具备内存管理功能,能够保留对话的上下文信息。这意味着它可以在多轮对话中保持状态,理解用户的意图和历史交互,从而生成更为连贯和相关的回答。这种能力使得它在处理复杂的对话场景时表现优越。

2. 兜底机制

在 LangChain 中,默认链的主要作用是处理那些不符合任何已定义处理模板的输入。当用户输入无法被其他链有效处理时,ConversationChain 可以作为一个兜底选项,确保系统始终能给出回应,而不会出现无响应或错误

3. 简化开发

使用 ConversationChain 作为默认链,可以减少开发者在构建链时需要考虑的复杂性。开发者不需要为每一种可能的输入情况都定义特定的处理逻辑,而是可以依赖于 ConversationChain 来处理那些边缘情况,从而提高开发效率

4. 与其他链的兼容性

ConversationChain 是 LLMChain 的子类,这使得它能够与其他链(如目标链和路由链)无缝集成。在构建多提示链(MultiPromptChain)时,可以轻松地将 ConversationChain 作为默认选项,增强整个系统的灵活性和可扩展性

(五)记忆

image.png

二、代码操作

(一)几种链的调用方法

# 导入所需的库
from langchain import PromptTemplate, OpenAI, LLMChain
# 原始字符串模板
template = "{flower}的花语是?"
# 创建模型实例
llm = OpenAI(temperature=0)
# 创建LLMChain
llm_chain = LLMChain(
    llm=llm,
    prompt=PromptTemplate.from_template(template))
# 调用LLMChain,返回结果
result = llm_chain("玫瑰")
print(result)


# 设置OpenAI API密钥
import os

# 导入所需库
from langchain import PromptTemplate, LLMChain
from langchain_openai import ChatOpenAI

# 设置提示模板
prompt = PromptTemplate(
    input_variables=["flower", "season"], template="{flower}在{season}的花语是?"
)

# 初始化大模型
llm = ChatOpenAI(model=os.environ.get("LLM_MODELEND"), temperature=0)

# 初始化链
llm_chain = LLMChain(llm=llm, prompt=prompt)

# 调用链
response = llm_chain({"flower": "玫瑰", "season": "夏季"})
print(response)

# run方法
llm_chain.run({"flower": "玫瑰", "season": "夏季"})

# predict方法
result = llm_chain.predict(flower="玫瑰", season="夏季")
print(result)

# apply方法允许您针对输入列表运行链
input_list = [
    {"flower": "玫瑰", "season": "夏季"},
    {"flower": "百合", "season": "春季"},
    {"flower": "郁金香", "season": "秋季"},
]
result = llm_chain.apply(input_list)
print(result)

# generate方法
result = llm_chain.generate(input_list)
print(result)


# 设置OpenAI API密钥
import os

# 导入所需要的库
from langchain.chains import LLMChain, SequentialChain
from langchain.prompts import PromptTemplate
from langchain_openai import ChatOpenAI

# 第一个LLMChain:生成鲜花的介绍
llm = ChatOpenAI(
    temperature=0.7,
    model=os.environ.get("LLM_MODELEND"),
)
template = """
你是一个植物学家。给定花的名称和类型,你需要为这种花写一个200字左右的介绍。
花名: {name}
颜色: {color}
植物学家: 这是关于上述花的介绍:"""
prompt_template = PromptTemplate(input_variables=["name", "color"], template=template)
introduction_chain = LLMChain(
    llm=llm, prompt=prompt_template, output_key="introduction"
)

# 第二个LLMChain:根据鲜花的介绍写出鲜花的评论
template = """
你是一位鲜花评论家。给定一种花的介绍,你需要为这种花写一篇200字左右的评论。
鲜花介绍:
{introduction}
花评人对上述花的评论:"""
prompt_template = PromptTemplate(input_variables=["introduction"], template=template)
review_chain = LLMChain(llm=llm, prompt=prompt_template, output_key="review")

# 第三个LLMChain:根据鲜花的介绍和评论写出一篇自媒体的文案
template = """
你是一家花店的社交媒体经理。给定一种花的介绍和评论,你需要为这种花写一篇社交媒体的帖子,300字左右。
鲜花介绍:
{introduction}
花评人对上述花的评论:
{review}
社交媒体帖子:
"""
prompt_template = PromptTemplate(
    input_variables=["introduction", "review"], template=template
)
social_post_chain = LLMChain(
    llm=llm, prompt=prompt_template, output_key="social_post_text"
)

# 总的链:按顺序运行三个链
overall_chain = SequentialChain(
    chains=[introduction_chain, review_chain, social_post_chain],
    input_variables=["name", "color"],
    output_variables=["introduction", "review", "social_post_text"],
    verbose=True,
)

# 运行链并打印结果
result = overall_chain({"name": "玫瑰", "color": "黑色"})
print(result)

(二)路由链

import warnings

warnings.filterwarnings("ignore")

# 设置OpenAI API密钥

# 构建两个场景的模板
flower_care_template = """
你是一个经验丰富的园丁,擅长解答关于养花育花的问题。
下面是需要你来回答的问题:
{input}
"""

flower_deco_template = """
你是一位网红插花大师,擅长解答关于鲜花装饰的问题。
下面是需要你来回答的问题:
{input}
"""

# 构建提示信息
prompt_infos = [
    {
        "key": "flower_care",
        "description": "适合回答关于鲜花护理的问题",
        "template": flower_care_template,
    },
    {
        "key": "flower_decoration",
        "description": "适合回答关于鲜花装饰的问题",
        "template": flower_deco_template,
    },
]

# 初始化语言模型
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(
    model=os.environ.get("LLM_MODELEND"),
)

# 构建目标链
from langchain.chains.llm import LLMChain
from langchain.prompts import PromptTemplate

chain_map = {}

for info in prompt_infos:
    prompt = PromptTemplate(template=info["template"], input_variables=["input"])
    print("目标提示:\n", prompt)

    chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
    chain_map[info["key"]] = chain

# 构建路由链
from langchain.chains.router.llm_router import LLMRouterChain, RouterOutputParser
from langchain.chains.router.multi_prompt_prompt import (
    MULTI_PROMPT_ROUTER_TEMPLATE as RounterTemplate,
)

destinations = [f"{p['key']}: {p['description']}" for p in prompt_infos]
router_template = RounterTemplate.format(destinations="\n".join(destinations))
print("路由模板:\n", router_template)

router_prompt = PromptTemplate(
    template=router_template,
    input_variables=["input"],
    output_parser=RouterOutputParser(),
)
print("路由提示:\n", router_prompt)

router_chain = LLMRouterChain.from_llm(llm, router_prompt, verbose=True)

# 构建默认链
from langchain.chains import ConversationChain

default_chain = ConversationChain(llm=llm, output_key="text", verbose=True)

# 构建多提示链
from langchain.chains.router import MultiPromptChain

chain = MultiPromptChain(
    router_chain=router_chain,
    destination_chains=chain_map,
    default_chain=default_chain,
    verbose=True,
)

# 测试1
print(chain.run("如何为玫瑰浇水?"))
# 测试2
print(chain.run("如何为婚礼场地装饰花朵?"))
# 测试3
print(chain.run("如何区分阿豆和罗豆?"))

注释:

1、verbose=True 是一个常用的参数设置,通常用于控制输出的详细程度。具体来说,当 verbose 参数被设置为 True 时,程序会提供更为详尽的信息,帮助用户理解程序的执行过程。

2、 导入警告模块import warnings 语句用于导入 Python 的内置 warnings 模块,该模块提供了一种控制警告信息的机制。

过滤警告warnings.filterwarnings("ignore") 语句设置了警告过滤器,使得所有的警告都被忽略,不会被显示或记录。具体来说,"ignore" 是一个动作参数,表示对于所有匹配的警告不执行任何操作。

  • 警告的作用:在 Python 中,警告(Warnings)是用于提示用户某些潜在问题的消息,但不会导致程序终止。它们通常用于标识即将弃用的功能或其他可能影响程序运行的事项。

  • 使用场景:使用 warnings.filterwarnings("ignore") 常见于以下情况:

    • 清理输出:在运行一些第三方库时,可能会产生大量不必要的警告信息,通过忽略这些警告,可以使输出更加干净整洁。
    • 调试时:当开发者确认某些警告不影响程序功能时,可以选择忽略它们,以便专注于其他重要信息。