资讯 文档
技术能力
语音技术
文字识别
人脸与人体
图像技术
语言与知识
视频技术

ERNIE用户记忆机制实践教程

大模型用户记忆能力介绍

当我们使用大模型能力去重构或赋能已有的产品时,或者使用大模型能力进行产品创新时,期望大模型具备支撑个性化产品形态、满足终端用户个性化需求的能力,而记忆机制就是在使用大模型满足"个性化"需求的完整的一套解决方案。记忆机制可以解决包括但不限于以下几类痛点问题:

  • 用户在一个对话中让模型记住有关自己的重要信息,模型当即表示自己记住了,新建对话后模型就不记得、不知道了…
  • 用户希望得到更个性化的回复时,模型好像总是“套模版”,车轱辘话来回说,无法提供体贴、个性化的帮助…
  • 用户与模型的对话超过最长上下文场景后,模型就不记得用户之前说过的话了…
  • 客户为了让模型基础超过上下文限度的信息,总结上文并拼接到query中,占用过多token数…

针对上述痛点问题,我们开放了大模型的用户记忆能力用户记忆存储了User的人设,即Bot对User重要信息的记忆:

用户记忆(User memory) Bot对User信息的长期记忆 User维度相对稳定的,比较重要的信息会作为Bot的长期记忆作为管理,在实际使用时会按需进行提取或使用,例如:当User希望讨论职业规划问题时候,Bot会调取长期记忆中的用户职业、用户学历等信息,生成更个性化的回复。

用户记忆的应用场景

  1. 个性化问候:在用户与模型开始第一次对话,或重启对话时,Assistant可以根据用户记忆生成不同的问候语;
  2. 生产力任务:在用户需要Assistant完成写作、解题指导等任务时,Assistant根据用户记忆有侧重性地回答用户问题;
  3. 与用户个人情况紧密相关的任务:Assistant根据用户记忆,生成个性化的职业规划、内在洞察,帮助解决人际关系困扰;
  4. 个性化推荐:Assistant用户偏好进行推荐,例如推荐鞋服、美食等。

记忆内容管理

API接口列表:

操作 appid维度 userMemoryId维度 memories 维度
创建 / 创建用户记忆id 写入用户记忆内容
修改 / / 修改用户记忆内容
查询 查询应用内所有用户记忆id 查询用户记忆内容 查询用户记忆内容
删除 / 删除用户记忆id和记忆内容 删除用户记忆id和记忆内容

最佳实践

以下,我们以"文小言"Ai助手为例,展开关于用户记忆能力的应用实践:

文小言是百度旗下新搜索智能助手,基于文心一言大模型开发。提供多模态搜索、问题解答、文章创作、图片创作与识别、语聊数字人、自由订阅、专业智能体等丰富的AI能力。通过用户记忆能力,文小言能够更好地理解用户的喜好,为用户提供更有针对性的问候、问题解答、商品推荐等帮助。

获得鉴权认证

以下在完成系统记忆机制的实践中,我们使用Postman环境进行,具体鉴权步骤如下:

对API请求进行签名计算

当您将HTTP请求发送到百度智能云时,您需要对您的请求进行签名计算,以便百度智能云可以识别您的身份。您将使用百度智能云的访问密钥来进行签名计算,该访问密钥包含访问密钥ID(Access Key Id, 后文简称AK)和秘密访问密钥(Secret Access Key, 后文简称SK).

注意:

仅当您手动创建HTTP请求(RESTful API调用)时,您才需要了解如何对请求进行签名计算。当您使用智能云提供的SDK时,在SDK中已经封装了完整的签名算法,使用者无需自己实现。

了解如何创建、查看和下载Access Key Id(AK)和Secret Access Key(SK), 请参考管理您的AKSK.

使用IAM工具生成认证字符串(Authorization)

认证字符串(Authorization)是向HTTP服务发送与记忆相关请求时需要输入的必要参数,因此您需要首先使用IAM工具生成认证字符串后,才能使用记忆功能。

  1. IAM签名工具中设置以下参数:
HTTP请求信息 信息设置
http方法 POST
路径 /v2/memory
参数 创建用户记忆id:Action=CreateUserMemory
写入用户记忆内容:Action=ModifyUserMemory
修改用户记忆内容:Action=ModifyUserMemoryContent
查询应用内所有用户记忆id:Action=DescribeUserMemories
查询用户记忆id和记忆内容:Action=DescribeUserMemory
删除用户记忆id和记忆内容:Action=DeleteUserMemory
AccessKeyld(ak): 依靠千帆获得
SecretAccessKey(sk): 依靠千帆获得
Host qianfan.baidubce.com
时间戳 务必确保右侧时间戳和左侧x-bce-date保持一致
签名有效期(秒): 为了避免重复生成鉴权带来的麻烦,可以设置更长时间的有效期(默认为1800s)

1.png

2.png

  1. 点击一键计算,可在红框处复制认证字符串(Authorization),复制后粘贴到postman的Headers参数下的Authorization处。

3.png

在postman中设置发送记忆相关请求的参数

  1. 设置请求方法:POST
  2. 在请求地址栏中输入:https://qianfan.baidubce.com/v2/memory
  3. 添加并设置Params:可一次添加所有Key-Value对,使用时保证Action与你的请求动作(增删改查)保持一致。
Key-Value对介绍 Key Value
创建用户记忆id Action CreateUserMemory
写入用户记忆内容 Action ModifyUserMemory
修改用户记忆内容 Action ModifyUserMemoryContent
查询应用内所有用户记忆id Action DescribeUserMemories
查询用户记忆id和记忆内容 Action DescribeUserMemory
删除用户记忆id和记忆内容 Action DeleteUserMemory

4.png

  1. 设置Headers参数:在Headers下需要设置3个参数,参数解释见下
Key Value
Content-Type application/json
x-bce-date 必须与生成鉴权时的x-bce-date保持一致
Authorization 通过IAM平台计算获得

5.png

创建用户记忆id

接口文档:创建用户记忆id:用于创建用户记忆id。

创建用户记忆id的实践案例

以下以“文小言”Ai助手为例,展示创建用户记忆的过程:

  • 其中appId是您的千帆应用ID,后续在调用推理服务时需要使用与此相同appId的应用,以确保记忆生效。
  • 其中description是为了方便您辨认用户特征信息的参数,不能为空,但并不会传入模型进行推理。
{
    "appId": "48886xxx",
    "description": "小A,一名女性用户"
}

得到的响应字段的Body内容如下,表明该用户记忆创建成功:

{
    "requestId":"1bef3f87-c5b2-4419-936b-50f9884fxxx",
    "result": {
        "userMemoryId" : "um-9a8cfb8eexx"
      }
}

至此,您获得了唯一标识用户身份的userMemoryId,不同userMemoryId对应不同用户的记忆,接下来我们逐步使用这个userMemoryId去增加(更新)、删除、全量更改或插入(更新)单个用户的记忆。

写入用户记忆内容

接口文档:写入用户记忆内容:用于全量写入/更新用户记忆内容。

全量写入/更新记忆的实践案例

全量写入/更新记忆时,新存入的用户记忆信息会覆盖用户过往所有的历史记忆信息。

我们继续以“文小言”Ai助手为例,之前我们在创建用户记忆步骤中若创建成功,会返回用户小A所对应的唯一用户人设标识userMemoryId

我们使用这个userMemoryId和用户小A归属的appId写入多条记忆内容。

由于是全量写入/更新,所以此时 operator参数设置为“cover”,并在 memories 字段中写入新的记忆信息。

由于我们刚刚才创建了小A的人设,因此我们此处输入的记忆内容,会被全部写入(全量写入);如果您在实践过程中,某个userMemoryId已存储记忆信息,此时原有记忆内容会被全部更新(全量更新)。

以下是请求示例:

{
    "appId":"48886xxx", 
    "userMemoryId": "um-j4gnrcrchehvv4ii",
    "operator":"cover",
    "memories":[
        [
            {   "role": "user",
                "content": "你好,我叫小A,请你记住我的口味偏好:我的口味偏清淡,喜欢喝绿茶,很注重饮食健康。"
            },
            {
                "role": "system",
                "content": "好的小A,我记住你的口味清淡,喜欢健康饮食,而且喜欢喝绿茶"
            }
         ],
         [
            {
                "role": "user",
                "content": "记住我的点单偏好:不另外加糖、少冰、不加小料。"
            },
            {
                "role": "system",
                "content": "好的小A,我已经记住了你的偏好。"
            }
         ]
    ]
}

得到的响应字段的Body内容如下,表明以上用户记忆写入成功。

{
    "requestId":"1bef3f87-c5b2-4419-936b-50f9884f10d4",
    "result": true
}

写入用户记忆内容的实践案例

另外,我们还可以直接为用户写入单条或多条记忆对内容。

由于是直接写入,所以此时operator参数设置为“insert”,并在 memories 字段中写入新的记忆信息,此时用户原有的记忆信息不会被覆盖。

以下是写入用户记忆内容的请求示例:

{
    "appId":"48886xxx", 
    "userMemoryId": "um-j4gnrcrchehvv4ii", 
    "operator": "insert",
    "memories":[
        [
            {
                "role": "user",
                "content": "我很喜欢吃粤菜。"
            },
            {
                "role": "system",
                "content": "已记住您的菜系偏好。"
            }
    ]
    ]
}

出现以下示例代表单条插入操作成功完成。

{
    "requestId": "74e3a9fb-d962-49e5-9c4f-fe73f751233c",
    "result": true
}

在插入后检查该用户记忆是否插入成功,查询的具体操作请参看文档:查询用户记忆内容

查询用户记忆内容

接口文档:查询用户记忆内容,具体功能为:

  • 查询单个用户所有的记忆内容,即查询一个 userMemoryId 和对应的 discriptionmemories
  • 查询单个用户的单条记忆内容,即查询一个 userMemoryId 下的单条memoryContentId内容

查询单个用户所有的记忆内容的实践案例

之前,我们在创建用户记忆步骤中,若创建成功,会返回用户小A所对应的唯一用户人设识userMemoryId

我们使用用户小A的userMemoryId和其归属的 appId 查询,目前用户小A所有的记忆内容。

以下是请求示例:

{
    "appId": "48886017""userMemoryId":"um-j4gnrcrchehvv4ii" # 替换需查询记忆的用户的唯一userMemoryId
}

得到的响应字段的Body内容如下,表明查询该用户所有的记忆内容成功,我们可以看到之前为小A写入的所有记忆信息。

其中,我们可以从memories数组中的memoryContentId参数中,获得一个记忆问答对的独特id,我们可以使用memoryContentId参数单个用户的单条记忆内容进行查询、修改与删除。

{
    "requestId": "616142e9-fdac-4c49-8d91-b1da7c187370",
    "result": {
        "appId": "48886xxx",
        "userMemoryId": "um-j4gnrcrchehvv4ii",
        "description": "小A,一名女性用户",
        "memories": [
            [
                {
                    "memoryContentId": "jNyxRZQB38Wmv6Rt4QHZ",
                    "role": "user",
                    "content": "你好,我叫小A,我的口味偏清淡,喜欢喝绿茶,很注重饮食健康。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "jNyxRZQB38Wmv6Rt4QHZ",
                    "role": "system",
                    "content": "好的小A,我记住你的口味清淡,喜欢健康饮食,而且喜欢喝绿茶。",
                    "type": "profile"
                }
            ],
            [
                {
                    "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
                    "role": "user",
                    "content": "记住我的点单偏好:不另外加糖、少冰、不加小料。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
                    "role": "system",
                    "content": "好的小A,我已经记住了你的偏好。",
                    "type": "profile"
                }
            ], 
            [
                {
                    "memoryContentId": "N4a4RZQBl86Vmrtv8b-1",
                    "role": "user",
                    "content": "我很喜欢吃粤菜。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "N4a4RZQBl86Vmrtv8b-1",
                    "role": "system",
                    "content": "已记住您的菜系偏好。",
                    "type": "profile"
                }
            ]
        ]
    }
}

单个用户的单条记忆内容的实践案例

刚才我们查询了用户小A的所有记忆内容,并且从memories数组中的memoryContentId参数。

现在我们以memoryContentId为''N4a4RZQBl86Vmrtv8b-1"的记忆问答对为例,展示如何用查询单个用户的单条记忆内容。

以下是请求示例:

{
    "appId":"48886xxx", 
    "userMemoryId": "um-j4gnrcrchehvv4ii", #替换需查询记忆的用户的唯一userMemoryId
    "memoryContentId": ["N4a4RZQBl86Vmrtv8b-1"] # 对应的用户单条记忆内容id,目前单次请求仅支持查询一个内容id
 }

得到的响应字段的Body内容如下,表明小A这个用户的单条记忆内容查询成功:

{
    "requestId": "6d0fd2c9-22d3-4cb0-a134-c5ad273bc346",
    "result": {
        "appId": "48886xxx",
        "userMemoryId": "um-nbb533nb0pmrxs43",
        "description": "小A,一名女性用户",
        "memories": [
            [
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "user",
                    "content": "我很喜欢吃粤菜。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "system",
                    "content": "已记住您的菜系偏好。",
                    "type": "profile"
                }
            ]
        ]
    }
}

修改用户记忆内容

接口文档:修改用户记忆内容:修改用户记忆中的单条记忆内容:

修改用户记忆内容的实践案例

刚才我们在查询用户小A的所有记忆内容时,从memories数组中获取了memoryContentId参数。

假设,随着小A生活地点发生的变化,小A从广州搬家到了成都工作,她逐渐爱上川菜,川菜取代粤菜成为她最喜欢的菜系,此时我们需要修改与小A口味偏好相关的单条记忆内容,这条记忆内容示例如下:

{
    "requestId": "6d0fd2c9-22d3-4cb0-a134-c5ad273bc346",
    "result": {
        "appId": "48886xxx",
        "userMemoryId": "um-nbb533nb0pmrxs43",
        "description": "小A,一名女性用户",
        "memories": [
            [
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "user",
                    "content": "我很喜欢吃粤菜。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "system",
                    "content": "已记住您的菜系偏好。",
                    "type": "profile"
                }
            ]
        ]
    }
}

以下是修改这条用户记忆的请求示例,在示例中,我们将小A的菜系偏好由粤菜改为川菜

{
    "requestId": "6d0fd2c9-22d3-4cb0-a134-c5ad273bc346",
    "result": {
        "appId": "48886xxx",
        "userMemoryId": "um-nbb533nb0pmrxs43",
        "description": "小A,一名女性用户",
        "memories": [
            [
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "user",
                    "content": "我之前喜欢吃粤菜,现在我最喜欢的菜系是川菜。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "WCtm35QBKRPsy3wO9_px",
                    "role": "system",
                    "content": "已将您的菜系偏好更新为川菜,以后我会给你推荐更多好吃的川菜馆噢。",
                    "type": "profile"
                }
            ]
        ]
    }
}

得到的响应字段的Body内容如下,表明修改这条用户记忆的请求成功:

{
    "requestId":"1bef3f87-c5b2-4419-936b-50f9884f10d4",
    "result": true
}

删除用户记忆id和记忆内容

接口文档:删除用户记忆id和记忆内容,具体功能:

  • 删除单条用户记忆内容,即删除一个 userMemoryId 下的单条memoryContentId内容
  • 删除用户记忆id及该id对应的所有用户记忆内容,即删除一个userMemoryId 和对应的 discriptionmemories

删除单条用户记忆内容的实践案例

当误将某些不重要的信息写入用户记忆内容时,我们可以删除该条记忆。

删除前小A的所有用户信息如下:

{
    "requestId": "616142e9-fdac-4c49-8d91-b1da7c187370",
    "result": {
        "appId": "48886xxx",
        "userMemoryId": "um-j4gnrcrchehvv4ii",
        "description": "小A,一名女性用户",
        "memories": [
            [
                {
                    "memoryContentId": "jNyxRZQB38Wmv6Rt4QHZ",
                    "role": "user",
                    "content": "你好,我叫小A,我的口味偏清淡,喜欢喝绿茶,很注重饮食健康。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "jNyxRZQB38Wmv6Rt4QHZ",
                    "role": "system",
                    "content": "好的小A,我记住你的口味清淡,喜欢健康饮食,而且喜欢喝绿茶。",
                    "type": "profile"
                }
            ],
            [
                {
                    "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
                    "role": "user",
                    "content": "记住我的点单偏好:不另外加糖、少冰、不加小料。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
                    "role": "system",
                    "content": "好的小A,我已经记住了你的偏好。",
                    "type": "profile"
                }
            ], 
            [
                {
                    "memoryContentId": "N4a4RZQBl86Vmrtv8b-1",
                    "role": "user",
                    "content": "我之前喜欢吃粤菜,现在我最喜欢的菜系是川菜。",
                    "type": "profile"
                },
                {
                    "memoryContentId": "N4a4RZQBl86Vmrtv8b-1",
                    "role": "system",
                    "content": "已将您的菜系偏好更新为川菜,以后我会给你推荐更多好吃的川菜馆噢。",
                    "type": "profile"
                }
            ]
        ]
    }
}

我们想要删除的记忆信息为:

[
    {
        "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
        "role": "user",
        "content": "记住我的点单偏好:不另外加糖、少冰、不加小料。",
        "type": "profile"
    },
    {
        "memoryContentId": "i9yxRZQB38Wmv6Rt4QHZ",
        "role": "system",
        "content": "好的小A,我已经记住了你的偏好。",
        "type": "profile"
    }
]

我们在请求主体中输入该用户唯一的记忆IDuserMemoeyId及需要删除的单条记忆内容IDmemoryContentId (请注意,目前仅支持单条记忆删除,即一次请求仅支持传入一个memoryContentId),以下是请求示例:

{
    "appId":"48886xxx",
    "userMemoryId":"um-cc60b5dp8y5snc5t",
    "memoryContentId": ["i9yxRZQB38Wmv6Rt4QHZ"]
}

得到的响应字段的Body内容如下,表明该条用户记忆删除成功:

{
    "requestId": "9f23711b-3aa3-48f2-b2e1-3cb81e69a498",
    "result": true
}

删除用户记忆id的实践案例

当需要删除小A的用户id和该id对应的所有用户记忆内容时,可以发送如下请求:

{
    "appId":"48886xxx",
    "userMemoryId":"um-j4gnrcrchehvv4ii"
}

得到的响应字段的Body内容如下,表明该用户记忆id删除成功:

{
    "requestId": "b800a9ef-4538-4998-99dd-f9d92a79fdda",
    "result": true
}

查询应用内所有用户记忆id

接口文档:查询应用内所有用户记忆id:查询应用内所有用户记忆id,即查询一个 appId 下所有的 userMemoryId 和对应的 discription

查询应用内所有用户记忆id的实践案例

在上文的实践案例中,我们已展示了对一个用户的记忆进行增删改查的全过程。

而当我们需要对应用appId中的所有记忆id进行全局总览时,请求Body中需要提供千帆应用的唯一标识符appld,可以发送以下请求示例:

{
    "appId": "48886xxx"
}

得到的响应字段的Body内容如下,表明该用户记忆id删除成功:

{
    "requestId": "1bef3f87-c5b2-4419-936b-50f9884f10d4",
    "result": {
        "items": [
            {
                "appId": "48886xxx",
                "userMemoryId": "um-j4gnrcrchehvv4i2",
                "description": "用户B,男性。"
            },
            {
                "appId": "48886xxx",
                "userMemoryId": "um-j4gnrcrchehvv4i1",
                "description": "用户C,女性,天津人。"
            }
        ],
        "pageInfo": {
            "marker": "um-9a8cfb8ee59",
            "isTruncated": false,
            "nextMarker": "um-9a8cfb8ee55",
            "maxKeys": 3
        }
    }
}
上一篇
ERNIE系统记忆机制实践教程
下一篇
Prompt使用