AgentDepthAgent 工程学习指南
输入概念或问题,检索正文和待编写目录。
第一次学习?从 L0 总览开始 →

工作、情景、语义与程序性记忆

我的学习 →

正在读取学习记录…

Agent记忆是把以后还会用到的信息保存下来,并在需要时取回。当前正在处理哪个订单、上次处理过什么、用户有什么偏好、处理退款应该按什么步骤做,用途各不相同。

工作记忆保存当前任务中的临时状态;情景记忆保存一次经历,包括发生时间与结果;语义记忆保存相对稳定的事实或偏好;程序性记忆保存执行某类任务的方法。像办公桌上的便签、工作日志、联系人档案和操作手册,分别回答“现在做什么”“以前发生什么”“已知什么”“怎样做”。

四类内容怎样随会话变化

客户u1的会话s1正在查询订单101,刚完成一次退款咨询,偏好中文回复,客服还掌握退款流程。新开s2时,当前订单便签应重新建立,用户偏好可以继续取回;另一位客户u2则不能读到u1的退款经历。

作用域表示记录对谁、在哪个会话可见。保留时间表示记录何时失效,两者是独立条件。本程序的记录用用户标识与可选会话标识限定读取,并用明确时间检查存期。

不同记忆进入不同会话:u1 / s1:工作 + 情景 + 语义 + 程序,工作绑定当前订单;u1 / s2:情景 + 语义 + 程序,工作记录留在s1;u2 / 任意会话:无u1记录,用户隔离独立检查;时刻100:情景到期,偏好与步骤仍在
图1:不同记忆进入不同会话。

跟着固定样本运行

先在 PowerShell 创建并进入学习目录:

Bash
mkdir "F:\学习\l5-memory-types" -Force
cd "F:\学习\l5-memory-types"

保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。

新建 F:\学习\l5-memory-types,将下面完整代码保存为 memory_types_demo.py。

先在 PowerShell 创建并进入学习目录:

Bash
mkdir "F:\学习\l5-memory-types" -Force
cd "F:\学习\l5-memory-types"

保存下面的文件后,在这个终端运行 dir 核对文件名,再执行本节给出的运行命令。

Python
"""四类记忆共享存储,按用户、会话和存期分别读取。"""
from dataclasses import dataclass


@dataclass(frozen=True)
class Memory:
    kind: str
    user: str
    session: str | None
    value: str
    expires_at: int | None


def recall(records, user, session, now):
    result = []
    for record in records:
        # 用户隔离先行;会话字段为空时允许同用户跨会话读取。
        if record.user != user:
            continue
        if record.session is not None and record.session != session:
            continue
        # 失效时刻也属于已过期,避免边界多保留一轮。
        if record.expires_at is not None and now >= record.expires_at:
            continue
        result.append(record)
    return result


def sample():
    return [
        Memory("工作", "u1", "s1", "正在查询订单101", 20),
        Memory("情景", "u1", None, "第1天退款咨询已解决", 100),
        Memory("语义", "u1", None, "偏好中文回复", None),
        Memory("程序", "u1", None, "先查订单,再核对退款条件", None),
    ]


if __name__ == "__main__":
    for label, user, session, now in (
        ("当前会话", "u1", "s1", 10),
        ("新会话", "u1", "s2", 10),
        ("另一用户", "u2", "s1", 10),
        ("情景过期后", "u1", "s2", 100),
    ):
        rows = recall(sample(), user, session, now)
        print(label + ":" + ("、".join(row.kind for row in rows) or "无"))

在 PowerShell 中进入保存目录并运行:

Bash
cd "F:\学习\l5-memory-types"
ls
python -X utf8 memory_types_demo.py

输出为:

TXT
当前会话:工作、情景、语义、程序
新会话:情景、语义、程序
另一用户:无
情景过期后:语义、程序

s1可以取回四类记录;s2没有s1的当前订单便签,仍能看到u1的经历、偏好和步骤。u2读到“无”,因为每条记录都属于u1。时间到100时,退款咨询经历过期,剩下偏好和操作步骤。

类别描述内容的用途,user、session、expires_at分别表达用户、会话与失效时刻。程序没有按类别名自动猜权限或存期,每条记录都明确设置这些字段。

用途与保存策略怎样配合

工作记忆常放在当前请求或会话状态中。订单号、未完成步骤和工具结果需要随着任务推进更新,完成后可以清理。情景记忆更像事件记录,要保留时间、参与对象和结果,避免把“一次退款成功”推广成“所有退款都会成功”。

语义记忆记录相对稳定的事实,如用户明确说出的语言偏好。它也可能变化,需要来源、更新时间与纠错入口。程序性记忆记录可执行的方法;步骤更新时应验证新的流程,来源不明的内容不能直接覆盖工具权限或业务规则。

类别示例内容读取时的问题
工作正在查询订单101是否属于当前会话
情景退款咨询已解决发生于何时,对本次是否有用
语义偏好中文回复用户是否确认,是否已变化
程序查订单后核对条件步骤是否是当前有效版本

示例将程序记录也绑定u1,便于观察统一隔离规则。共享客服流程通常另放团队或产品作用域,并在读取前确认访问权限。工作记忆也可以在会话持续期间保存到数据库;“工作”不等于一定只在内存,“长期”也不等于永久保存。

召回后怎样放入上下文

召回是从已保存的信息中选择本次要用的记录。用户语言偏好有助于确定回复语言;过去的退款事件需要与当前问题相关才应取回。把四类记录全部无差别塞进请求,会占用上下文,也容易让旧经历影响新判断。

调整一个存期

把样本中情景记录的100改成200,运行 python -X utf8 memory_types_demo.py。最后一行变成“情景、语义、程序”,说明第100时刻它仍未过期。当前会话与另一用户的输出不变,因为调整存期没有改变用户或会话条件。恢复100后重跑,对照过期后的两类记忆。

现象检查位置
新会话继续操作旧订单工作记录的会话绑定
另一客户看到历史经历用户过滤条件
偏好多年不变但已不准确确认时间与更新入口
旧事件被当成通用规则情景与语义的区分、来源

检查实现中的六种情况

在同一目录将下面测试保存为 test_memory_types_demo.py。测试覆盖正文中的正常路径与边界条件。

测试代码:test_memory_types_demo.py
Python
"""检查类别内容与用户、会话、失效边界。"""
import unittest
from memory_types_demo import sample, recall


class MemoryTypesTests(unittest.TestCase):
    def test_current_session(self):
        self.assertEqual(len(recall(sample(), "u1", "s1", 10)), 4)

    def test_new_session(self):
        self.assertEqual([row.kind for row in recall(sample(), "u1", "s2", 10)],
                         ["情景", "语义", "程序"])

    def test_other_user(self):
        self.assertEqual(recall(sample(), "u2", "s1", 10), [])

    def test_expiry_boundary(self):
        self.assertNotIn("工作", [row.kind for row in recall(sample(), "u1", "s1", 20)])

    def test_episode_expires(self):
        self.assertEqual([row.kind for row in recall(sample(), "u1", "s2", 100)],
                         ["语义", "程序"])

    def test_content_retained(self):
        rows = recall(sample(), "u1", "s2", 10)
        self.assertEqual(rows[0].value, "第1天退款咨询已解决")


if __name__ == "__main__":
    unittest.main()
Bash
cd "F:\学习\l5-memory-types"
python -X utf8 -m unittest -v test_memory_types_demo

应显示6项通过。将主程序恢复到上面的固定输入后,可以再次对照完整输出。

课后练习展开习题收起习题

4 道练习 · 客观题规则评分 · 其余题目待批改

正在读取本地记录…

不调用模型,不执行代码。简答、代码和场景题仅保存答案并展示自查标准,不生成评分、徽章或认证。输入内容不会自动保存,请点击提交;不要填写个人信息或密钥。

练习 1 / 4 · v1.0.1

选择题 · 先判断边界

关于“工作、情景、语义与程序性记忆”,哪种做法更稳妥?

对应知识点:L5-memory-types

选择一个答案
练习 2 / 4 · v1.0.0

简答题 · 解释失败

写出一个失败输入并说明记录字段。

对应知识点:L5-memory-types

练习 3 / 4 · v1.0.0

代码题 · 边界测试

补充正常、边界、失败三组输入和预期结果。

对应知识点:L5-memory-types

练习 4 / 4 · v1.0.0

场景题 · 结果未知

证据不足时如何设计状态和人工接管?

对应知识点:L5-memory-types

图片查看器
100%

文章配图 · 按 Esc 关闭