news 2026/10/6 14:59:48

Agent分层记忆体系:突破上下文限制的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Agent分层记忆体系:突破上下文限制的工程实践

做Agent开发久了,你会发现一个很分裂的现象:Demo阶段一切顺风顺水,一进入真实使用就开始露馅。用户上午刚告诉Agent"我不吃香菜",下午Agent就推荐了香菜馅饺子;上周已经敲定的调研框架,这周重新打开会话它像失忆一样重问一遍。这些问题十有八九都指向同一个根子——Agent记忆,更具体地说,是记忆没有被分层管理。

这段时间我在反复调优自己的ai agent项目,最有收获的一块就是把记忆改成"分层记忆"体系。这篇文章我会尽量讲透三层东西:为什么Agent需要一套分层记忆而不是简单"塞上下文";工作记忆、情景记忆、语义记忆、程序性记忆每一层到底存什么、怎么落地;以及检索、写入、排错、验证这些工程环节里容易被做坏的细节。适合两类人看:正在从零搭Agent框架的新手,以及觉得自家Agent"总差点意思"但说不清差在哪的开发老手。

1. 为什么记忆是Agent从Demo走向可用的那道坎

1.1 没有记忆的Agent:三个真实翻车现场

先看第一个现场。用户在一段长对话里明确说了"我不喜欢吃香菜",因为对话太长,这句话早就被截断清出了上下文窗口。过了几轮,用户让Agent推荐外卖,Agent认认真真推荐了一家以香菜为灵魂的云南米线店。用户当场无语,但这真的不是模型笨,而是它根本"看不到"那句偏好了。

第二个现场更典型。一个跨两天的调研任务,第一天Agent已经跟用户确认了三份数据源、一套结论框架,晚上用户关掉了页面。第二天回来继续做,Agent像第一次见面一样重新问"您想从哪个角度开始分析"。用户开始怀疑自己是不是雇了一个每天失忆的实习生。

第三个现场出现在多会话场景。同一个用户同时开着三个窗口,一个问"我常用的代码风格是什么",一个让Agent写Python脚本,一个在讨论画像字段设计。三个会话各聊各的,Agent在A窗口说我偏好函数式写法,在B窗口完全没理会这件事。用户觉得这个Agent像人格分裂。

这三个翻车现场分别对应不同的记忆缺口:第一个是工作记忆管理不当,第二个是没有长期的事件记忆,第三个是没有跨会话共享的用户事实。也就是说,记忆不是一份,而是需要分层的。

1.2 分层记忆的由来:不是发明,是借鉴

很多开发者一听到"给Agent加记忆",第一反应是"把所有历史塞进向量库"。这个方向没错,但太粗糙了。真正好用的设计思路,是把认知科学里那套人类记忆模型做一层工程映射。我这边的划分是这样的:

  • 工作记忆:上下文窗口,相当于桌面上正在处理的那堆文件。特点是容量有限、变动频繁,用完就要清理。
  • 情景记忆:按时间线记录发生过的事件,相当于日记本。记的是"某时某刻做过什么事、结果怎么样"。
  • 语义记忆:从事件里提炼出来的稳定事实与偏好,相当于知识卡片。记的是"用户是谁、用户喜欢什么、业务背景是什么"。
  • 程序性记忆:沉淀下来的可复用操作方法,相当于肌肉记忆。它让Agent不用每次从零思考同一类任务怎么做。

分层的好处在于,每一层都可以有自己的存储介质、写入时机、召回方式和淘汰策略。工作记忆追求低延迟,只保留当次任务的上下文;情景记忆追求完整可回溯,但内容要做压缩;语义记忆追求准确和一致,不能轻易被噪声污染;程序性记忆追求稳定复用,需要版本管理。四层各管一摊,互不干扰,出了问题也容易定位。

1.3 先分清:记忆不是日志,也不是缓存

在agent开发群里,我经常看到有人把记忆、日志、缓存混为一谈。日志是全量事实记录,系统每一步发生了什么都往里面写,日志越多越好;但记忆是经过筛选的、面向复用和推理的可用信息,写多了反而会污染Agent的判断。举个例子,日志里可以留着"用户在某天搜过法语课程",但记忆里没必要存这条,除非它真的影响后续服务。

缓存解决的是性能问题,记忆解决的是能力问题。缓存命不中顶多多花几十毫秒,记忆不准确直接让Agent做出离谱决策。还有状态管理,它通常是会话级的临时状态,比如"当前表单填到第几步了",而记忆需要跨会话、跨天、跨任务存活,生命周期完全不同。

还有一个值得分清的概念,正好回应"harness和agent区别"这类搜索。在常见的agent架构里,Harness(编排层)负责执行循环、工具调度和上下文包装;记忆模块是挂在Harness下面的一个组件,它决定"把哪些历史信息投喂给模型",而不是替模型做推理。把记忆和编排层的关系理清之后,你就能理解为什么不是所有Agent框架都内置记忆——它们把记忆当作可插拔能力,而不是执行循环的一部分。

2. 四层记忆的职责切分:先搞清楚每一层到底存什么

2.1 工作记忆:桌面只有那么大的地方

工作记忆就是"现在正在处理的事",对应模型上下文窗口里的全部内容:系统提示词、用户消息、工具返回结果、Agent自己的推理步骤。它的核心矛盾是容量有限,而任务信息会持续增长。你不可能让一个只有几万token的窗口装下用户过去三个月的所有对话。

我的做法是把工作记忆当作一个结构化Buffer来管理,而不是一个裸的消息数组。它分成四个区:指令区放系统提示词,常驻不动;任务区放当前任务的必要信息,比如目标、约束、关键参数,动态刷新;对话区放最近N轮消息,滚动淘汰;临时区放工具返回结果,用完就丢。这样设计的原因是,不同分区的生命周期不同,统一用FIFO淘汰必然误伤。

淘汰策略也不能一刀切。早期我踩过坑,超出窗口就丢掉最早的消息,结果把最开头那条"用户要求全程用中文回复"的指令给丢了。后来改成:超窗时先对最早一段消息做摘要提炼,把核心目标放进任务区,再淘汰原始消息。模型始终能看到"历史概要加近期细节",连续性好很多。

2.2 情景记忆:记录发生过什么

情景记忆存的是事件,不是结论。它回答的问题是"What happened"。一条典型的情景记忆长这样:某天某用户让Agent生成一份竞品分析报告,采用了哪几个数据源,最终输出了什么结构,用户当时是否认可。它不是一句"用户做过竞品分析"就完了,而是保留完整的事件脉络。

工程实现上,我建议把每条情景记忆存成结构化记录:id、用户标识、事件类型、时间戳、重要性评分、压缩后的内容摘要、内容向量。摘要用LLM压缩过,向量用于召回时的相似度计算,元数据单独留字段是为了支持按时间、类型、用户做过滤。这比直接把整段对话扔进向量库要可控得多。

情景记忆最典型的召回场景是"回顾类"请求。用户说"帮我把上次那份周报改一下",如果Agent有情景记忆,就能先想起上周那份周报的框架是什么;没有的话,只能傻傻地反问一句"哪份周报?"。就这一句话的差别,用户的体感是一个天上一个地下。

2.3 语义记忆:沉淀下来的事实与偏好

语义记忆是从情景记忆里抽象出来的稳定事实,回答的是"What does it mean"。它存的不是"某天用户说了一句话",而是"用户偏好简洁回复""用户的工作日是周一到周五""项目A的技术栈是Rust"。这些东西是跨会话复用的基础。

很多项目只做情景记忆不做语义记忆,结果就是模型能"想起"上周的事,但总结不出用户偏好。因为每次对话都要面对一堆事件记录重新归纳,既费token又容易不稳定。语义记忆应该像一张不断更新的用户事实表,有专门的结构化字段,而不是靠每次临时去向量库里猜。

语义记忆要处理冲突。新事实和旧事实矛盾时,我默认不直接覆盖,而是把旧事实标记为"过期"并保留历史版本。因为用户偏好是会变的,保留历史能在回溯时解释"Agent为什么会从A方案切到B方案",排查问题时很有用。

2.4 程序性记忆:把做过的事变成会做的事

程序性记忆在开源社区里有个更流行的名字:Skill。最近"agent skill""agent skills教程""agent开发"这些搜索热度很高,本质上大家就是在找怎么教Agent掌握固定流程。

举个例子,你写过一次"把网页保存成Markdown"的脚本,之后这个能力就该固化成技能,而不是每次让模型重新设计一遍。程序性记忆的载体可以是一个注册表:技能名称、功能描述、触发条件、参数定义、执行入口。模型在相关任务出现时,先查注册表、匹配技能、填参数、执行,全程不用重新试验。

这一层我通常放最后做。原因是,只有前几层记忆积累到一定程度,你才能发现自己重复调用的流程到底有哪些。太早固化技能,基本上是在拍脑袋设计——你以为的"高频任务"可能根本不是真实需求。

2.5 四层记忆对比:一张表看清全貌

记忆层存什么生命周期典型存储召回方式典型用例
工作记忆当前任务上下文会话级消息Buffer、摘要块窗口内直接读取当次对话连续性
情景记忆历史事件与结果数周至数月SQLite/Postgres加向量字段时间过滤加相似度回顾上次任务
语义记忆用户事实与偏好长期事实表/图谱实体匹配加向量检索回答个性化问题
程序性记忆可复用技能与流程长期更新Skill注册表/函数库意图路由加参数解析固定流程自动化

我建议把这张表贴在工位前。很多记忆系统设计不合理,根源就是把某几层混在一起了,最典型的是把语义记忆塞进情景记忆表,用向量检索去查"用户偏好是什么",结果召回一堆不相关的事件。

3. 落地一套最小分层记忆系统:从Buffer到向量库再到压缩

3.1 选型:不要一上来就上重型框架

聊落地,很多新手第一反应是上一套完整的agent框架,再配一个专门的向量数据库。我劝你先冷静。一个最小可用的分层记忆系统,只需要三样东西:一个关系型数据库存结构化记忆,一个能算embedding的接口,一个能做时间衰减重排的脚本。

我选SQLite起步,而不是直接上大型向量库,原因是分层记忆的第一步是先把数据模型设计对。数据模型错了,换任何存储都是白搭。等单机验证通过,再迁移到Postgres加pgvector,或者专门的向量库也不迟,迁移成本远低于一开始就陷入复杂基础设施的维护。下面这套示例代码用Python写,逻辑完全可以迁移到其他语言。

3.2 工作记忆的结构化Buffer:超出窗口不丢关键信息

先看工作记忆的代码。下面是一个我在小项目里用过的简化版本:

class WorkingMemory: def __init__(self, max_turns=20, max_task_tokens=1200): self.system_prompt = "" # 指令区 self.task_context = [] # 任务区:核心目标与约束 self.dialogue_turns = [] # 对话区 self.temp_tool_results = [] # 临时区 self.max_turns = max_turns self.max_task_tokens = max_task_tokens def add_user_message(self, msg): self.dialogue_turns.append({"role": "user", "content": msg}) def add_assistant_message(self, msg): self.dialogue_turns.append({"role": "assistant", "content": msg}) def add_task_context(self, key, content): for i, (k, _) in enumerate(self.task_context): if k == key: self.task_context[i] = (k, content) return self.task_context.append((key, content)) def compact(self, summary_fn): # 超过窗口后,把最旧的一半做摘要,放进任务区 if len(self.dialogue_turns) <= self.max_turns: return overflow = self.dialogue_turns[: len(self.dialogue_turns) // 2] summary = summary_fn(overflow) self.add_task_context("history_summary", summary) self.dialogue_turns = self.dialogue_turns[len(self.dialogue_turns) // 2:] def to_messages(self): messages = [{"role": "system", "content": self.system_prompt}] for key, content in self.task_context: messages.append({"role": "system", "content": f"[{key}] {content}"}) messages.extend(self.dialogue_turns) return messages

核心逻辑是:当对话轮次超过上限时,不直接丢弃最老消息,而是调一次summary_fn把前半段压缩成摘要,放进任务区。这样模型始终能看到"历史概要加近期消息"。摘要的generation成本不高,但对连续性的提升非常明显。

3.3 情景记忆的写入与检索:一个事件一张卡

情景记忆的存储结构,我用的是下面这张表:

CREATE TABLE episodic_memory ( id INTEGER PRIMARY KEY AUTOINCREMENT, agent_id TEXT NOT NULL, user_id TEXT NOT NULL, event_type TEXT NOT NULL, -- task_completed / preference / correction ... content TEXT NOT NULL, -- 压缩后的描述 content_embedding BLOB, -- embedding 向量 importance REAL DEFAULT 0.5, -- 重要性 0~1 source_session TEXT, -- 来源会话ID created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_episodic_user_time ON episodic_memory(user_id, created_at); CREATE INDEX idx_episodic_event_type ON episodic_memory(event_type);

写入时机比表结构更容易踩坑。我建议在三种时机写入:用户明确表达好恶、一个复杂任务完成并且用户确认结果、用户纠正了Agent的错误。一般寒暄和无关紧要的请求,不要写。写入示例:

def write_episodic_memory(conn, agent_id, user_id, event_type, content, embedding, importance): conn.execute( "INSERT INTO episodic_memory(agent_id, user_id, event_type, content, content_embedding, importance, source_session) VALUES (?, ?, ?, ?, ?, ?, ?)", (agent_id, user_id, event_type, content, serialize(embedding), importance, current_session_id()), ) conn.commit()

检索时我更推荐"先过滤再相似度"的顺序。先按user_id过滤,再按event_type可选过滤,最后才在候选集合里算embedding相似度。原因是embedding计算有成本,而且候选集里如果混了别的用户事件,召回质量会明显下降。

3.4 语义记忆的抽取:用LLM把事件变成事实

语义记忆不能靠手工维护,一定要从事件里自动抽取。我的做法是每个会话结束时,把当次对话交给LLM,按固定模板抽取"候选用户事实":

EXTRACT_PROMPT = """ 你是用户画像分析师。根据下面的对话,抽取关于该用户的稳定事实。 要求: 1. 只抽取对话中明确表达或可合理推断的事实,不要脑补。 2. 每条事实必须附上对话原文证据。 3. 输出JSON数组:[{"fact": "...", "type": "preference|attribute|constraint", "evidence": "原文"}] 对话内容: {transcript} """

抽取出来的事实,先写入"待确认事实"表,而不是直接进语义记忆表。如果连续两次会话抽到同一事实,再正式入库。这个"两次确认"策略非常有效,能把一次性噪声过滤掉一大半。至于为什么用LLM抽取而不是正则,是因为用户表达偏好的方式千奇百怪,"别给我发太长的邮件"和"工作日别老打扰我"都需要语义理解,正则扛不住。

3.5 程序性记忆的注册:Skill注册表长什么样

程序性记忆的落地形态就是技能注册表。一个技能需要几个字段:技能名称、给模型看的描述、触发条件、参数Schema、执行入口。注册表长这样:

class SkillRegistry: def __init__(self): self.skills = {} def register(self, skill): self.skills[skill.name] = skill def match(self, task_intent): candidates = [] for skill in self.skills.values(): score = cosine_similarity(embed(task_intent), embed(skill.description)) candidates.append((score, skill)) candidates.sort(key=lambda x: x[0], reverse=True) return candidates[:3] def execute(self, skill_name, params): return self.skills[skill_name].run(params)

匹配不一定要用embedding相似度,也可以用LLM路由,但轻量场景下embedding够用了。等匹配精度成为瓶颈,再上LLM也不迟。这里的要点是"先匹配再执行",让技能通过描述被模型发现,而不是硬编码一堆if-else触发条件。

4. 检索与写入策略:分层记忆里最容易被做坏的环节

4.1 为什么"向量相似度一把梭"不行

只要真正做过一次记忆召回,你就会发现纯向量检索的问题:它检索的是语义相似,不是"对当前任务有用"。举个实际例子,用户说"帮我写周报",向量库里和"周报"语义最接近的三条记忆,可能是上周周报的内容、用户说"周报格式太啰嗦"的偏好、一条和ERP系统相关的上下文碎片。如果只按相似度取前三返回给模型,模型会被一堆碎片搞迷糊。

所以我的结论是:向量相似度只是基础筛选,真正决定召回质量的是后续的重排策略。这一步做不好,记忆系统越是"内容丰富",Agent越容易把不相关的记忆掺进回答里。

4.2 混合重排:时间、重要性、相关度三因素叠加

我私下整理过一个混合评分公式,实测比纯相似度好用很多:

score = w1 * similarity + w2 * recency + w3 * importance recency = exp(-(now - created_at) / half_life)

三个权重根据业务调。回顾类任务把recency权重拉高,偏好类任务把importance权重拉高。简化实现:

def rerank(candidates, now, w=(0.6, 0.25, 0.15), half_life_days=7.0): scored = [] for cand in candidates: sim = cand["similarity"] recency = math.exp(-max(0, (now - cand["created_at"]).days) / half_life_days) importance = cand["importance"] total = w[0] * sim + w[1] * recency + w[2] * importance scored.append((total, cand)) scored.sort(key=lambda x: x[0], reverse=True) return [c for _, c in scored]

时间衰减参数是重灾区。我踩过一版把半衰期设成2天的,结果用户三个月前明确的编程语言偏好被严重降权,模型又开始追问"您喜欢用什么语言"。除非业务确实只关心近期行为,否则半衰期不建议短于7天。

4.3 记忆路由:让任务去对口的记忆层找人

比重排更前置的问题是:你打算访问哪一层记忆?用户问"我上个月的总结报告在哪",应该查情景记忆;用户问"我的写作风格偏好",应该查语义记忆;用户说"接着刚才聊",应该读工作记忆。我建议做一个轻量路由函数:

def route_query(query): if 包含时间回溯词("上次", "上周", "之前", "上个月"): return "episodic" if 包含偏好词("喜欢", "偏好", "不喜欢", "觉得"): return "semantic" if 查询的是当前对话上下文: return "working" if 包含操作意图("帮我把", "这个流程能"): return "procedural" return "episodic"

这个函数看起来简单,价值却很大。它避免了你每次提问都对四层记忆各检索一遍,省token、省延迟。等规则路由不够用了,再换成LLM路由也不难,只要保证路由结果仍然是"去哪一层"。

4.4 写入策略:不是所有对话都值得记住

记忆污染的最大来源是写入策略太宽松。一条对话值不值得写入记忆,我建议至少过三个问题:这个信息以后还会被用吗?它跟已有记忆是重复还是矛盾?写入代价能接受吗?重要性评分可以用规则:用户明确说"记住"给0.9,纠正行为给0.8,完成任务给0.6,一般请求给0.3。规则不完美,但胜在稳定、可解释。

写入方式上优先选异步批量。不要在用户请求的同步链路上做embedding和写库,否则响应延迟会直接变大。我见过把写入放在主线程里的项目,Agent每次回答后多出800毫秒,体验直接崩掉。正确做法是:回答返回的同时,把需要写入的消息丢进队列,后台任务慢慢写。

5. 上线必踩的坑:记忆污染、幻觉写入与并发竞态

5.1 记忆污染:模型把一次性噪声当成了长期事实

第一个坑我踩得最惨。当时规则是"对话结束后把整段对话存进记忆表",结果用户随口说了一句"我最近在学法语",被当成长期偏好存进了语义记忆。之后Agent在完全无关的场景里频繁推荐法语学习资源,用户被烦到差点弃用。

完整排查链路是这样的:先在语义记忆表里查最新记录,发现一条"用户正在学法语"的事实;再去查这条记录的产生时间,确认它来自某次闲聊;回看那次对话的原始日志,发现用户只是在给朋友介绍业余爱好,根本没有要求Agent长期服务这个需求;最后定位根因——写入策略没有区分"闲聊"和"明确表达偏好"。

修复方案是把写入时机改成"抽取式"。不是整段对话入库,而是先让模型抽取候选事实,再判断候选事实是否属于长期偏好,同时加上"两次确认"机制。从那以后,语义记忆表的噪声记录肉眼可见地减少了。

5.2 幻觉式写入:LLM总结事件时会脑补

第二个坑是LLM总结事件时的幻觉式脑补。用户说"这版回复很好,但下次不要用太多列表",LLM抽取时总结成"用户不喜欢列表",再过一轮可能升级成"用户要求所有输出都用段落"。这种逐级放大会让记忆系统变得非常不可信。

我的对策有三条。第一,抽取prompt里强制要求evidence字段,事实必须引用对话原文,没有原文证据就不准输出。第二,给每条事实加一个confidence字段,证据不充分的置信度就低,检索排序时权重自动降低。第三,对置信度低但影响大的语义记忆,提供人工确认入口,也就是所谓的"记忆审核后台"。

第三个对策看起来最重,但很有必要。记忆系统一旦上线,模型的决策就会依赖记忆,如果记忆本身是幻觉,后面所有推理都建立在沙地上。这个坑难的不是技术,而是承认"LLM总结不可信"这个前提。

5.3 并发写入竞态:两个会话同时写同一条记忆

"ai agent怎么扛并发"这个搜索词其实也出现在我的实战范围里。用户经常同时开多个会话,两个会话里的Agent可能同时抽取到同一条事实,比如"用户偏好简洁回答",然后同时写入,结果语义记忆表里出现两条几乎一样的记录。更坏的是,两个会话抽到的内容互相矛盾,后写的直接覆盖先写的,用户觉得Agent"变了一个人"。

排查链路基本是这样的:先在语义记忆表里按事实内容做group by,发现大量重复记录;再看写入时间和会话ID,确认是并发会话同时写入;最后确认数据库的upsert条件只用了自增id,没有对"事实内容+用户"建唯一约束。

修复分三步。第一,给语义记忆表加唯一索引,比如(user_id, fact_normalized)。第二,写入使用insert ... on conflict do update。第三,冲突时先比较两条候选记录的置信度和证据条数,保留置信度高的,而不是简单后写覆盖。程序性记忆的并发注册也要做类似处理,比如技能签名唯一约束,避免同一个技能被注册多份。

5.4 成本与延迟:记忆不能成为主链路的负担

还有一个每天都在发生的隐性坑:成本。如果每次Agent请求都把四层记忆全部检索一遍,embedding调用和token消耗会占掉账单的大头。我的经验是三层控制:

第一,用路由函数减少无效召回,比如普通闲聊根本不用查语义记忆;第二,给记忆检索加缓存,常见问题对应的召回结果缓存10分钟,重复问题直接命中缓存;第三,把压缩和抽取放到异步任务里,主链路只做最轻量的top-k召回。

另外记忆表要定期优化索引。实测中,情景记忆表到几十万条之后,没有user_id加created_at复合索引的查询会明显变慢。数据量上来以后,这类结构性问题比模型调参更影响体验。

6. 怎么证明分层记忆真的有用:离线评测与线上指标

6.1 离线评测:构建一份"记忆问答集"

记忆系统最容易陷入"自嗨"。代码写完了,效果好不好全靠感觉。我的建议是构建一份离线评测集:从真实会话历史里挑出一批跨会话提问,比如"上次用户提到不喜欢什么""用户项目A用的什么框架""上个月那份报告里写了哪几个部分"。每个问题配标准答案和对应的记忆类型。

然后跑评测脚本:对每个问题执行分层记忆的写入与检索全流程,看Agent的回答是否命中正确答案,统计三个指标:

指标含义作用
召回率标准答案对应的记忆是否被检索到检验检索层
准确率检索到的记忆里有多少与问题相关检验重排与路由
事实一致性Agent基于记忆的回答是否与标准事实一致检验记忆写入质量

我建议把评测脚本写进CI。每次改写入策略或检索权重,都跑一遍,防止"修好一个坑、打崩一片回忆"。

6.2 线上指标:别只看"像不像有记忆"

线上指标主要盯四个。一是跨会话任务完成率:用户第二次提到同一件事时,Agent能不能直接续做而不是重新询问。二是重复提问率:用户问过的问题是否还会再问,这个指标降下来说明记忆在起作用。三是用户纠错率:Agent犯错后用户纠正的频率,如果引入记忆后不降反升,多半是记忆污染已经出现了。四是平均会话轮次:有记忆的Agent应该能更快收敛。

注意第四个指标是双刃剑,轮次减少也可能是因为Agent直接翻出历史答案应付,所以要结合用户满意度一起看。好的记忆系统不只是让对话变短,而是让对话变准。

6.3 A/B测试的要点:对照组要真"无记忆"

很多人做A/B测试,对照组其实也带了上下文窗口的记忆,结果差异不明显,就得出"记忆没用"的结论。这是不对的。真正的无记忆对照组,应该每次都清空工作记忆之外的记忆层,只保留系统提示词和当前对话。测试用例也一定要选跨会话场景,否则根本测不出长期记忆的差异。

我实测过一组数据:在同样的跨会话任务上,使用分层记忆后,任务完成率提升了大约15到20个百分点,平均会话轮次下降了约30%。最明显的改善不是模型变聪明了,而是它不再重复问已经回答过的问题。这件事听起来基础,但对用户体感来说提升非常大。

6.4 一个常见的评估误区:把"记住刚才"当成了"有记忆系统"

最后提醒一句:单轮对话里模型能记住之前说的内容,那是上下文窗口的功劳,不是记忆系统的功劳。真正的分层记忆评价,一定要落在"跨会话、跨天、跨任务"上。如果一个评测集里所有问题都在同一个上下文窗口内,那测出来的数字只能说明Prompt Engineering做得好,不能说明记忆系统有效。

这就是我把工作记忆单独列入记忆系统的原因。它是记忆体系的入口,但绝不是全部。很多人以为"Agent能记住我刚才说的话"就够了,等到真正做长线任务、个性化服务、多会话共享的时候,才知道分层记忆的价值。

做Agent开发这一年多,我最大的体会是:分层记忆的核心难点不在技术选型,而在取舍。哪些信息该进工作记忆、哪些该沉淀成情景记忆、哪些要抽成用户事实、哪些干脆就该遗忘,这些决策比模型本身更能决定Agent的上限。别急着堆功能,先把最小闭环跑通:结构化Buffer管工作记忆、一张表管情景记忆、LLM抽事实管语义记忆,等数据量上来了再谈技能固化和大规模检索。最后分享一个排查问题的小技巧:给每条记忆记录source_session和confidence两个字段,将来遇到"Agent为什么说出这么离谱的话"时,能顺着这两个字段在半天内找到根因,省下的时间绝对值得。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/6 14:59:45

AI代码审查工程化:构建可验证的确定性流水线

1. 项目概述&#xff1a;当代码审查不再依赖“人盯人”&#xff0c;而是一条可验证、可回溯、可审计的确定性流水线最近在几个核心开源项目的 PR 评论区里&#xff0c;我连续看到三类高度相似的自动化评论&#xff1a;一条指出某段 Go 代码存在潜在的 nil pointer dereference …

作者头像 李华
网站建设 2026/10/6 14:58:10

从编程助手到AI Agent:工作流接管与Token成本控制实战

1. 从写代码到管事情&#xff1a;AI 角色迁移的底层逻辑过去两年&#xff0c;我身边不少做开发的朋友都在经历同一种微妙的变化&#xff1a;以前打开编辑器是写函数、调接口、修 bug&#xff0c;现在打开对话框是描述需求、审阅方案、验收结果。这个转变不是简单的工具替换&…

作者头像 李华
网站建设 2026/10/6 14:57:43

电子商务网站课程设计模板:数据库设计与MVC避坑指南

简介&#xff1a;一份电子商务网站系统设计文档&#xff0c;对应《管理信息系统》课程设计中的“个人商务网站管理系统设计与实现”&#xff0c;适合计算机相关专业学生、课程设计团队以及初学Web开发的读者参考。文档围绕网上购物、在线支付、商品展示等商务活动&#xff0c;系…

作者头像 李华
网站建设 2026/10/6 14:57:42

AI辅助黑苹果调试:聪明但不在现场?——Sonoma升级事故复盘

一直想把这系列第四篇写出来&#xff0c;结果拖了一个多月。上个月给手头这台拯救者R9000P&#xff08;AMD Ryzen 7 5800H Radeon RX 6600M&#xff09;从Ventura升到Sonoma&#xff0c;进度条走到80%就自动重启&#xff0c;循环了整整一晚上。我开着在线AI问答窗口&#xff0…

作者头像 李华
网站建设 2026/10/6 14:57:10

阿里云百炼自定义语言模型实战:3小时完成业务微调闭环

简介&#xff1a;本资源是一份面向企业技术负责人、AI应用开发者及大模型初学者的实战指南&#xff0c;聚焦如何在阿里云百炼平台零基础构建业务适配的自定义大语言模型。文档系统拆解了模型调优、部署与评测三大核心环节&#xff0c;并详解训练数据准备&#xff08;含Prompt-C…

作者头像 李华
网站建设 2026/10/6 14:56:17

工业级无人机管道巡检:西气东输3900km落地实操指南

简介&#xff1a;本资源是一份面向能源行业管道运维工程师、无人机巡检技术实施人员及安全管理人员的专业解决方案文档&#xff0c;聚焦西气东输等长输油气管道的智能化巡检升级需求&#xff0c;系统解决人工巡线在复杂地形、远距离、高危区域中存在的效率低、响应慢、覆盖盲区…

作者头像 李华