LangChain(七)让大模型拥有记忆!新手向

系列文章目录

LangChain(二)基础问答大模型,纯新手向-CSDN博客

LangChain(三)基础问答大模型,从LLMchain开始了解chain!纯新手向-CSDN博客

LangChain(四)工具调用的底层原理!给大模型按上双手吧!(新手向)-CSDN博客

LangChain(五)工具调用的底层原理进阶!依旧纯新手向~-CSDN博客

LangChain(六)LLMRouteChain的基本原理和构建方式-新手向-CSDN博客


文章目录

前言

一、大模型记忆功能原理浅谈

二、方式一:通过ChatPromptTemplate构建消息列表

1.导入相关库与设定聊天模型

2.构建消息列表(ChatPromptTemplate)

3. 最终输出

三、 MessagesPlaceholder,构建后置消息列表

1. 构建大模型

2. 构建消息列表和链

        ①首先对于第一部分,代码如下

         ②第二部分,链的定义和具体的流程说明

四、纯手工构建消息列表! 

1. 构建大模型

2. 构建prompt和链

3. 构建自己的消息队列,并灵活弃取

总结


前言

随着前面几篇内容的写作,对于大模型的chain的概念、工具调用、路由操作。我想大家都有了一定程度的了解和熟悉。本篇我们回归大模型本身,将有代码表象出发,逐步讲解至本质。给大家清晰大模型记忆功能的原理和操作方式。任然是新手向~


一、大模型记忆功能原理浅谈

        从本质上来说,LLM大模型的基础原理是自然语言处理算法,即:给出一部分文本,进行后续的扩写or整句话的补全。从这个角度来看,大模型是文本相似度矩阵计算中的概率学问题,和记忆能力根本不沾边。

        从前面的学习过程中,大家也可以得到启发:大模型只能对当前文本进行处理,除此之外,啥也干不了。

        现如今在算法本身上给大模型增加记忆能力依旧是那帮子openAI算法大拿的一线课题,那么现在应用市场上,各大厂商是怎么给大模型增加记忆能力的呢?……

        我想大家心里已经有一个隐隐约约的想法了,但是又觉得咋可能呢?真的这么弱智吗?在这里我可以很负责任的告诉大家,真的就这么弱智……

        记忆能力就是把之前所有的对话保存下来,然后在下一轮作为prompt的一部分一起给到大模型……

        太弱智了……当然这也就导致了,对话上下文长度的设定问题。若上下文过长,那么后续的大模型需要处理的文本量也就越来越多(大家可要小心自己的钱钱),处理速度也是随之下降。

二、方式一:通过ChatPromptTemplate构建消息列表

1.导入相关库与设定聊天模型

代码如下:

from langchain_community.chat_models import QianfanChatEndpoint
import os

# 设定百度千帆大模型的AK和SK-去百度千帆官网的控制台新建一个应用即可
os.environ["QIANFAN_AK"] = "your AK"
os.environ["QIANFAN_SK"] = "your SK"

#创建千帆LLM模型
qianfan_chat = QianfanChatEndpoint(
    model="ERNIE-3.5-8K",
    temperature=0.2,
    timeout=30,
)

无需赘述~,前面已经很熟练了想必。 

2.构建消息列表(ChatPromptTemplate)

代码如下:

from langchain_core.prompts import ChatPromptTemplate

chat_template = ChatPromptTemplate.from_messages(
    [
        ("system", "You are a helpful AI bot. Your name is {name}."),
        ("human", "Hello, how are you doing?"),
        ("ai", "I'm doing well, thanks!"),
        ("human", "{user_input}"),
    ]
)

该部分需要好好说一下,毕竟我们是新手向,我们对于每一个新东西都需要好好讲解一下。

消息列表会保存以往的所有消息,包括system的人设、用户的输入、AI的输出。那么就带来了一个问题,我们需要让大模型知道,哪句话是谁说的!万一AI大模型把自己给代入了用户,那岂不是完蛋(笑)。

此处的ChatPromptTemplate最大的用处就是设定每句话的 role 。注意,key可不是上面的那三个固定死的,你甚至可以把自己的名字写上去,此时就算有多个用户同时和大模型对话,大模型也不会分不清谁是谁了。

可能大家在各个地方都看到过不同的template,觉得很烦!那么多template干什么,这个还没学完,就又来一个!其实常用的template没多少,也就下面这几个:

大家眼尖的可以看到最后的这个 MessagesPlaceholder:用于容纳消息列表。这不就是我们今天要做的事儿吗/。没错!这个东西就是后面的重点之一,上面的代码仅仅是给大家浅尝一下,并没有使用MessagesPlaceholder。(其实直接用上面的方式构建消息列表也没什么问题,反正消息有了,列表也有了,怎么不是消息列表(叉腰))

3. 最终输出

代码如下

messages = chat_template.format_messages(name="Bob", user_input="What is your name?")

print(qianfan_chat.invoke(messages).content)

既然是template,那么就需要把template的内容传进去,这就是第一行做的事儿。 

输出如下 

My name is Bob. I'm an AI bot designed to help people.

可见大模型识别到了system的内容!

三、 MessagesPlaceholder,构建后置消息列表

1. 构建大模型

如上,跳过

2. 构建消息列表和链

from langchain_core.messages import AIMessage, HumanMessage
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
    [
        ("system","You are a helpful assistant. Answer all questions to the best of your ability.",),
        MessagesPlaceholder(variable_name="下次写"),
    ]
)
chain = prompt | qianfan_chat
respond = chain.invoke(
    {
        "下次写": [
            HumanMessage(content="我叫千天夜"),
            AIMessage(content="你的名字是千天夜,这是一个非常独特和美丽的名字!很高兴认识你,千天夜!"),
            HumanMessage(content="我刚才说了什么?"),
        ],
    }
)

         此处想必各位读者第一次读会很懵逼。经过之前的学习,你好像每一段代码都能看得懂,但是放一起就不知道怎么回事了。

        没关系,我们慢慢来。

        ①首先对于第一部分,代码如下

prompt = ChatPromptTemplate.from_messages(
    [
        ("system","You are a helpful assistant. Answer all questions to the best of your ability.",),
        MessagesPlaceholder(variable_name="下次写"),
    ]
)

         此部分可以回顾一下上面说到的 ChatPromptTemplate。主要是用来构建聊天消息模板,此处应当保存消息列表。然而此处明显为消息列表的只有下面这个:

 ("system","You are a helpful assistant. Answer all questions to the best of your ability.")

         MessagesPlaceholder 是个什么东西呢?上面我们简单说了一下,MessagesPlaceholder 这其实是用于容纳消息列表的。但是问题在于,为什么需要使用这个东西,我直接像上面的写法一样往上写不就完了吗?

        然而,在实际场景中,我们常常会需要对消息列表进行编辑。例如百度的文心一言,你可以从任意行开始重写输入,此时消息列表就会回退到之前的部分。如果我们不对消息列表进行解耦化处理,我们将很难处理这些需求。

        比如说,在某些场景下,我们一开始并不知道消息列表内应当保存什么东西 or 我们也无法确定消息列表的内容一定不要修改,此时我们就需要用到MessagesPlaceholder。所以MessagesPlaceholder就是一个用以容纳消息列表的东西,我们可以在后续的开发过程中动态的填入相关的记忆。

        其实把MessagesPlaceholder看成记忆容器即可,往里面放什么记忆,大模型就只如同傀儡一样,只能记得这些记忆。这么理解是不是一下子就科幻起来了,肆意操纵别人的记忆。

        当然MessagesPlaceholder(variable_name="下次写")这里显然就是告诉大模型,这里有一个消息列表,消息列表的具体内容,会放在一个字典中,对应的key值:“下次写”

         ②第二部分,链的定义和具体的流程说明

chain = prompt | qianfan_chat
respond = chain.invoke(
    {
        "下次写": [
            HumanMessage(content="我叫千天夜"),
            AIMessage(content="你的名字是千天夜,这是一个非常独特和美丽的名字!很高兴认识你,千天夜!"),
            HumanMessage(content="我刚才说了什么?"),
        ],
    }
)

此处我们直接解释,首先构建一个链chain,无需赘述!

显然,此时的输入为一个字典

 {
        "下次写": [
            HumanMessage(content="我叫千天夜"),
            AIMessage(content="你的名字是千天夜,这是一个非常独特和美丽的名字!很高兴认识你,千天夜!"),
            HumanMessage(content="我刚才说了什么?"),
        ],
    }

字典的key为“下次写”,value为一个消息列表。此时输入会被传给prompt模块,此时 MessagesPlaceholder会开始工作,将自己替换为对应的消息列表并且进行整合为一个大的消息列表。整合好的消息列表就会传给大模型。

输出如下:

你刚才说:“我叫千天夜”。如果你还有其他问题或需要帮助,请随时告诉我。

四、纯手工构建消息列表! 

经过上面的说明,我想大家肯定还是有点模模糊糊的。没关系!我们通过下面的代码狠狠巩固一下!

1. 构建大模型

如上上,直接跳过。

2. 构建prompt和链

代码如下

from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder

prompt = ChatPromptTemplate.from_messages(
    [
        ("system", "You are an assistant for question-answering tasks."),
        MessagesPlaceholder("chat_history"),
        ("human", "{input}"),
    ]
)

chain = prompt | qianfan_chat

此处我们依旧使用 ChatPromptTemplate 。在让大模型拥有记忆这方面,ChatPromptTemplate 是必不可少的。保存了三行消息队列,中间是一个MessagesPlaceholder 消息队列容器。

注意:这里有两个内容需要填充,分别是 input 和 chat_history

3. 构建自己的消息队列,并灵活弃取

代码如下:

from langchain_core.messages import HumanMessage

chat_history = []

question = "南瓜汤是哪里的小吃?"
ai_msg_1 = chain.invoke({"input": question, "chat_history": chat_history})
print(ai_msg_1.content)
chat_history.extend([HumanMessage(content=question), ("ai", ai_msg_1.content)])

second_question = "那要如何烹饪它呢?"
ai_msg_2 = chain.invoke({"input": second_question, "chat_history": chat_history})

print(ai_msg_2.content)

这里我们直接自己写一个list:chat_history

每对话一次,直接extend进来。此时就相当于保存了往期内容。

并在后续的问答中,传入chat_history数据……

那么对应的两个输出如下:

南瓜汤是一道民间小吃,主要属于**浙江菜菜系**。以下是关于南瓜汤的详细信息:

1. **主要特点**:南瓜汤香醇浓郁,味美色雅,主要以南瓜为主料,辅以洋葱等佐料,通过适当方式制作而成。
2. **适宜人群**:一般人群均可食用,尤其适宜肥胖者、糖尿病患者和中老年人食用。
3. **忌食人群**:南瓜性温,胃热炽盛者、气滞中满者、湿热气滞者少吃;同时患有脚气、黄疸、气滞湿阻病者忌食。
4. **制作方法**:南瓜汤有多种制作方法,可以单独使用南瓜作为主料,也可以和其他食物如红薯、紫菜等一起做主料。

综上所述,南瓜汤是一道具有浙江菜特色的民间小吃,以其独特的口感和营养价值受到广泛喜爱。

南瓜汤的原材料主要包括以下几种:

1. **主料**:
   - 南瓜:这是南瓜汤的主要成分,通常使用中等大小的南瓜,去皮去籽后切成块或薄片。南瓜的用量可以根据个人口味和制作量来调 整,例如在某些制作方法中,南瓜的用量可以达到350克。

2. **辅料**:
   - 洋葱:洋葱是南瓜汤中常见的辅料,用于增加汤的香气和口感。洋葱通常被切成碎片或末,与南瓜一起烹饪。
   - 其他配料:根据不同的制作方法,南瓜汤还可能包含其他配料,如黄油、肉汤、牛奶、面粉、鲜乳酪、荷兰芹、肉豆蔻、盐、胡椒 等。这些配料用于增加汤的丰富度和口感。

3. **调料**:
   - 盐、胡椒粉和其他香料:用于调味,根据个人口味添加适量的盐和胡椒粉,以及其他香料如肉桂粉等。

4. **其他可选配料**:
   - 蘑菇、地瓜、鲜奶或忌廉、杞子、牛油等:这些配料可以根据个人口味和喜好添加到南瓜汤中,增加汤的口感和营养价值。

综上所述,南瓜汤的原材料主要包括南瓜、洋葱等主料,以及黄油、肉汤、牛奶、面粉、鲜乳酪、荷兰芹、肉豆蔻、盐、胡椒等辅料和调料。根据个人口味和喜好,还可以添加其他配料如蘑菇、地瓜、鲜奶或忌廉等。

可见第二个问答内容完美的知道我们在问的是南瓜汤的原材料。 


总结

到此为止,我们对于大模型如何构建记忆能力,从代码出发,再到算法原理,一一剖析结束!

  • 21
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值