字节跳动青训营 | LangChain实战课学习笔记--链与记忆

261 阅读4分钟

一、链的介绍

1.1 LangChain中的Chain概念

  • Chain的重要性:对于简单的应用程序,直接调用LLM(Large Language Model)足够。但对于更复杂的应用,需要通过“Chain”链接LangChain的各个组件和功能。

  • Chain的定义:Chain是将多个组件相互链接,组合成一个链,简化复杂应用程序的实现,并使之模块化,便于调试、维护和改进。

1.2 Chain的实现和使用

  • 接口设计:LangChain通过设计好的接口实现具体链的功能,如LLMChain接受用户输入,格式化后传递给LLM。

  • 链的组合:实现链的具体功能后,可以通过组合多个链或将链与其他组件组合来构建更复杂的链。

  • 预置链:LangChain提供多种类型的预置链,方便实现各种任务。

1.3 LLMChain:最简单的链

  • LLMChain功能:整合PromptTemplate、LLM和Output Parser,将Model I/O流程封装在一个链中。

  • 代码示例

  - 不使用链:

    from langchain import PromptTemplate
    template = "{flower}的花语是?"
    prompt_temp = PromptTemplate.from_template(template)
    prompt = prompt_temp.format(flower='玫瑰')
    print(prompt)
    from langchain import OpenAI
    model = OpenAI(temperature=0)
    result = model(prompt)
    print(result)

  - 使用链:

    from langchain import PromptTemplate, OpenAI, LLMChain
    template = "{flower}的花语是?"
    llm = OpenAI(temperature=0)
    llm_chain = LLMChain(llm=llm, prompt=PromptTemplate.from_template(template))
    result = llm_chain("玫瑰")
    print(result)

1.4 链的调用方式

  • 直接调用:调用链对象,实际上是调用内部实现的__call__方法。

  • run方法:等价于直接调用。

  • predict方法:类似于run,输入键被指定为关键字参数。

  • apply方法:针对输入列表运行链,一次处理多个输入。

  • generate方法:类似于apply,返回LLMResult对象。

1.5 Sequential Chain:顺序链

  • Sequential Chain功能:将多个LLMChain串起来,形成一个顺序链。

  • 示例:通过三个LLMChain生成鲜花的知识性说明、评论和社交媒体文案。

  • 代码实现

 from langchain.chains import SequentialChain
  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)

二、LangChain路由链的使用

2.1 任务设定

  • 目标:构建一个智能客服ChatBot,能够区分并处理两大类问题:

  - 鲜花养护(如何保持花的健康、浇水、施肥等)

  - 鲜花装饰(如何搭配花、装饰场地等)

2.2 整体框架

  • RouterChain:动态选择用于给定输入的下一个链。

  • 流程

  1. 使用路由器链确定问题更适合哪个处理模板。

  2. 将问题发送到该处理模板进行回答。

  3. 如果问题不适合任何已定义的处理模板,发送到默认链。   

2.3 具体步骤

  1. 构建处理模板:为鲜花护理和鲜花装饰定义两个字符串模板。

  2. 提示信息:使用列表组织这两个处理模板的关键信息。

  3. 初始化语言模型:导入并实例化语言模型。

  4. 构建目标链:根据提示信息中的每个模板构建对应的LLMChain,并存储在字典中。

  5. 构建LLM路由链:使用LLMRouterChain选择与给定问题最相关的提示。

  6. 构建默认链:如果输入不适合任何已定义的处理模板,触发默认链。

  7. 构建多提示链:使用MultiPromptChain组合LLM路由链、目标链和默认链。

2.4 具体实现步骤

(1)构建提示信息的模板

(2)初始化语言模型

(3)构建目标链

(4)构建路由链

(5)构建默认链

(6)构建多提示链

三、记忆

3.1 无状态的LLM和代理

  • 默认情况下,LLM和代理是无状态的,每次模型调用都是独立的,不记录之前的交互。

3.2 记忆机制的重要性

  • 记忆机制允许模型记录对话上下文,并将其作为提示的一部分在最新的调用中传递给模型,对于聊天机器人的构建至关重要。

3.3 ConversationChain

  • 特点:提供包含AI前缀和人类前缀的对话摘要格式,与记忆机制紧密结合。

  • 内置提示模板

  from langchain import OpenAI
  from langchain.chains import ConversationChain
  llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
  conv_chain = ConversationChain(llm=llm)
  print(conv_chain.prompt.template)

3.4 使用ConversationBufferMemory

  • 实现:最简单的记忆机制,存储会话记忆。
 from langchain import OpenAI
  from langchain.chains import ConversationChain
  from langchain.chains.conversation.memory import ConversationBufferMemory
  llm = OpenAI(temperature=0.5, model_name="gpt-3.5-turbo-instruct")
  conversation = ConversationChain(llm=llm, memory=ConversationBufferMemory())

5. 使用ConversationBufferWindowMemory

  • 实现:缓冲窗口记忆,只保存最新最近的几次人类和AI的互动。
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
  conversation = ConversationChain(llm=llm, memory=ConversationBufferWindowMemory(k=1))

6. 使用ConversationSummaryMemory

  • 实现:对话总结记忆,将对话历史进行汇总,然后传递给{history}参数。
from langchain.chains.conversation.memory import ConversationSummaryMemory
  conversation = ConversationChain(llm=llm, memory=ConversationSummaryMemory(llm=llm))

7. 使用ConversationSummaryBufferMemory

  • 实现:对话总结缓冲记忆,结合了ConversationSummaryMemory和ConversationBufferWindowMemory的特点,通过max_token_limit参数管理Token使用。
from langchain.chains.conversation.memory import ConversationSummaryBufferMemory
  conversation = ConversationChain(llm=llm, memory=ConversationSummaryBufferMemory(llm=llm, max_token_limit=300))

8. 四种记忆机制的比较

  • 表格比较:对比四种记忆机制的特点和适用场景。

  • Token消耗示意图:展示不同记忆机制随着对话轮次增加的Token消耗情况。