做 AI Agent 开发的同学,大概率都遇到过这样的尴尬场景:一个电商客服 Agent,用户刚说完“我上周买的订单还没发货”,Agent 回答了查询方式,用户紧接着说“那我要退掉”。结果 Agent 像失忆一样反问:“请问您的订单号是多少?”用户瞬间火大:“你不是刚问过吗?”
这种“边做边忘”的现象,本质不是模型太笨,而是 Agent 的记忆体系没有设计好。
真正让 Agent“越用越聪明”的,不是换一个更大的模型,而是把 Context、Memory、Session、State 这四层概念分清楚,并且用工程手段把它们组合起来。很多人把这四个词混为一谈,导致代码越写越乱,回答越来越“飘”。本文会把四者的区别、分工、落地方式和超限处理讲透,最后带大家手把手实现一个最小可用的电商客服助手。
读完之后,你能在这些方面有明确收获:第一,彻底分清 Context、Memory、Session、State 的区别;第二,知道短期状态和长期记忆分别该存什么、怎么存;第三,掌握上下文超限的四种处理策略;第四,跑通一个带记忆能力的电商客服示例项目。
1. 先看一个场景:Agent 为什么总是“边做边忘”
设想你正在开发一个电商客服 Agent。用户第一次进来说:“你好,我上周买的那双鞋怎么还没到?”Agent 根据订单号查到了物流信息,答复“您的订单正在运输中,预计明天送达”。用户又说:“那我明天不在家,想申请退款,来得及吗?”此时如果 Agent 没有保存状态,这一轮它可能完全不知道“那双鞋”是哪双鞋,也不知道用户刚才已经查过物流。
这不是个别现象。很多 Agent 项目在演示时表现很好,一到真实长对话就崩,原因通常出在三个层面:
1.1 会话内的短期记忆缺失
用户在当前会话里说过的话,Agent 没有完整传给模型。一些开发者在拼接 prompt 时只放了系统指令和最近一条用户消息,模型自然无法理解上下文。这个问题看似低级,却非常普遍。
1.2 跨会话的长期记忆缺失
用户今天咨询完,明天再来,Agent 已经完全不认识他。用户画像、历史订单、商品偏好、上次未解决的问题,全部丢失。用户被迫重复描述,体验直线下降。
1.3 上下文窗口的物理限制
即使你愿意把所有历史消息都传给模型,大模型的 Context Window 也不是无限的。你可能会在线上看到这类报错:
api error: 400 this model's maximum context length is 1048576 tokens context length exceeded (169,692 tokens). cannot compress further.当对话过长、文档过多、工具返回结果过大时,记忆再多也塞不进一次请求。
所以,Agent 要“越用越聪明”,必须建立一套分层记忆机制:哪些信息只活在当前会话,哪些信息要存到长期,哪些信息需要压缩,哪些信息要主动丢弃。这恰恰是 Context、Memory、Session、State 四者要解决的问题。
2. 一次讲清四个核心概念:Context、Memory、Session、State
很多开发者把这四个词当成同义词,实际它们描述的是不同层级的东西。可以先记住一句话:Session 是一条时间线,State 是这条时间线上的快照,Context 是每次请求递给模型的“工作材料”,Memory 是跨时间线存在的“长期档案”。
2.1 Context:一次请求里的全部输入
Context 是模型在单次调用中看到的所有内容,包括系统提示词、用户输入、历史对话、检索到的知识、工具返回结果。它本质上是“这一次请求的工作台”。
Context 的特点是:
- 有长度上限,即模型的 Context Window。
- 每次请求都需要重新组装。
- 组装成本直接影响响应延迟和费用。
很多人误以为“只要把 Context 塞得越多越好”,但实际是塞得越多,模型越容易受到无关信息干扰,响应也越慢。上下文越长,成本往往也越高。
2.2 Session:一次连续交互的会话载体
Session 是用户与 Agent 之间一段连续交互的载体。它解决的问题是:如何把多轮消息归拢到同一个逻辑单元中。
Session 与 Web 开发里的 Session 概念很接近,但它更偏 Agent 业务语义。一个用户打开对话框,创建 Session;连续对话,Session 延续;用户离开一段时间,Session 过期;重新回来,可以创建新 Session。
Session 的生命周期一般由服务端控制。你可以在 Redis 中维护session:{id}的键值对,并设置过期时间。Session 本身不负责“记忆”,它只是一个容器。
2.3 State:某一时刻的数据快照
State 是 Agent 在某一时刻的数据状态。它回答的不是“你们刚才聊了什么”,而是“现在事情进行到哪一步了”。
在电商客服场景里,State 可以包含:
- 当前用户是否已登录。
- 当前正在处理哪个订单。
- 用户是否处于售后流程。
- 对话是否已经完成。
State 与 Session 的关系是:Session 是会话线,State 是会话线上的节点快照。Session 可以贯穿始终,State 则随着业务流转不断更新。
2.4 Memory:跨请求、跨会话的长期信息
Memory 是真正让 Agent “记得你”的部分。它不受单个会话限制,可以跨用户、跨会话存在。
Memory 可以包括:
- 用户档案。
- 历史订单。
- 偏好信息。
- 历史问题解决记录。
- 过去的对话摘要。
Memory 的存储方式多种多样,常见的是业务数据库加向量库的组合。重要信息落业务表,模糊信息做向量化后做语义检索。
四者的对比可以看这个表:
| 维度 | Context | Session | State | Memory |
|---|---|---|---|---|
| 生命周期 | 单次请求 | 一次会话 | 随业务变化 | 跨会话长期 |
| 存储位置 | 请求体 | Redis/内存/数据库 | Redis/数据库 | 数据库/向量库 |
| 是否持久化 | 否 | 短暂,可过期 | 短暂,可恢复 | 是 |
| 核心作用 | 提供决策材料 | 归拢消息 | 记录进度 | 积累经验 |
| 典型问题 | 超长、超限 | 会话丢失 | 状态字段混乱 | 召回不准确 |
看到这里,你应该能理解为什么不能把这四者混为一谈:如果你把 Memory 当成 Context 无限塞,会遇到超限;如果你把 State 当成 Session,用户状态会混乱;如果你把 Context 当成 Memory,每次请求都会重复浪费 token,而且跨会话毫无积累。
3. Agent 记忆分层:短期状态与长期记忆的职责划分
既然四个概念分工不同,Agent 的记忆就应该分层设计。比较稳妥的分层思路是三层,恰好对应三类存储介质:
3.1 工作记忆层:Context Window
承载单次请求中模型需要的全部信息。这一层的特点是“快、小、贵”,所以要控制内容量级,只放与当前问题最相关的材料。
作者建议:工作记忆层一定要做预算控制,比如设定单次请求 token 上限。系统指令占多少、用户历史占多少、检索结果占多少,都应该在组装层固定下来,而不是自然增长。
3.2 短期状态层:Session 与 State
承载一次会话内的上下文和业务进度。这一层的特点是“临时、可恢复、有生命周期”。
典型实现是:Session 存消息列表和元信息,State 存业务状态。两者可以放在 Redis、内存或关系型数据库里,过期时间根据业务调整。
3.3 长期记忆层:持久化存储
承载跨会话的用户信息、历史摘要和业务数据。这一层的特点是“慢、大、持久”,需要检索手段配合。
典型实现是 MySQL/PostgreSQL 存业务数据,向量库存对话摘要和知识片段。查询时先做关联检索,再放入 Context。
三层之间的关系,可以理解为:长期记忆是“图书馆”,短期状态是“桌面便签”,工作记忆是“当前正在批阅的文件”。每次请求,Agent 先从图书馆里查资料,放到桌面便签上,再挑最相关的放上桌面参与批注。
这个分层的价值在于:每一层各司其职,可以独立优化。比如长期记忆召回不准,不会影响 Session 状态;Context 超限,不会破坏长期记忆的持久性。
写代码前,我们先把记忆的“写入”和“召回”两个方向想清楚:
- 写入:对话过程中产生的用户关键信息,要异步落库,而不是每次请求都全量写。
- 召回:发起新请求时,根据当前会话 state 和用户问题,去长期记忆里检索,再组装到 Context。
很多 Agent 项目失败,是因为只在“召回”上下了功夫,却忽略了“写入”。模型每轮输出的信息如果不被结构化保存,下一轮就无从召回。
4. 短期状态落地:Session 与 State 的工程实现
下面进入代码部分。我们先解决短期状态的问题。
4.1 Session 生命周期设计
Session 的生命周期至少包含四个动作:创建、读取、续期、过期清理。
创建时分配唯一 session_id;读取时从 Redis 取数据;每次接收到新消息时续期;当 Redis TTL 到期,自动删除。
用 Redis 存 Session 的典型流程如下:
import json import redis redis_client = redis.Redis(host="localhost", port=6379, db=0) def create_session(session_id: str, ttl: int = 1800): key = f"session:{session_id}" redis_client.set(key, json.dumps({"history": [], "updated_at": None}), ex=ttl) def get_session(session_id: str): key = f"session:{session_id}" raw = redis_client.get(key) if not raw: return None return json.loads(raw) def update_session(session_id: str, data: dict, ttl: int = 1800): key = f"session:{session_id}" redis_client.set(key, json.dumps(data), ex=ttl)这段代码的关键点是ex=ttl。每次更新都重置过期时间,用户持续对话时 Session 不会消失,用户离开半小时后自动清理。
4.2 State 的数据结构设计
State 建议用独立的数据结构管理,不要和 Session 的原始 message 混在一起。下面是一个电商客服场景的 State 定义:
from dataclasses import dataclass, field from typing import Optional @dataclass class CustomerState: session_id: str user_id: Optional[str] = None status: str = "initial" # initial / consulting / after_sale / finished order_id: Optional[str] = None pending_intent: Optional[str] = None history: list = field(default_factory=list) def intents(self): return self.pending_intent字段解释:
status:业务状态,决定 Agent 下一步走什么流程。order_id:当前正在处理的订单,避免用户反复报单号。pending_intent:尚未完成的意图,比如“申请退款”在等待用户确认。history:当前会话的短消息列表,用于 Context 组装。
4.3 状态流转
在电商客服中,State 的流转大致如下:
initial -> consulting -> after_sale -> finished用户第一次进入是initial,发来咨询后变为consulting,当识别到退换货意图时进入after_sale,问题解决后进入finished。
在代码里,状态流转应该显式进行,而不是在任意函数里随意改字段。推荐用一个状态机或至少一个集中的update_state函数:
class SessionManager: def __init__(self, redis_client): self.redis = redis_client def get_state(self, session_id: str) -> CustomerState: data = get_session(session_id) if data and data.get("state"): return CustomerState(**data["state"]) return CustomerState(session_id=session_id) def save_state(self, state: CustomerState): session_data = get_session(state.session_id) or {"history": []} session_data["state"] = state.__dict__ update_session(state.session_id, session_data)注意这里有一个容易被忽略的细节:业务状态和会话历史分开存储,但放在同一个 Session key 下。这样读取时一次性拿到,Redis 请求次数少。
如果你在使用 LangGraph 之类的 Agent 编排框架,需要特别注意:State 的更新原则是“不可变更新”。不要在节点函数内部直接修改已有的 state dict 内容,而是返回一个包含更新字段的新字典。比如return {"status": "after_sale"}。如果你原地修改state["status"]后不返回,框架很可能不会感知到变化,节点执行完后状态依旧没变。这是 LangGraph 中经常出现的问题。
5. 长期记忆落地:让 Agent 记住用户与业务上下文
短期状态解决了“这一轮不忘”,长期记忆解决的是“下一轮还记得”。常见的长期记忆有三种落地形态:业务数据库、向量库、对话摘要。
5.1 业务数据库:结构化用户信息
适合存储用户 ID、姓名、地址、历史订单、售后记录等结构化数据。这类数据适合用 MySQL 或 PostgreSQL 管理,查询条件明确。
示例表结构:
CREATE TABLE user_memory ( id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id VARCHAR(64) NOT NULL, memory_key VARCHAR(64) NOT NULL, memory_value TEXT, updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uk_user_key (user_id, memory_key) );写入时机:当 Agent 从对话中识别到关键信息,比如“我住在杭州”“我的订单号是 12345”,就应该通过结构化抽取写入这张表。
5.2 向量库:非结构化对话记忆
用户历史消息、历史对话摘要、商品知识文档,这类内容不适合放在关系表里精确匹配,更适合用向量检索。
下面是一个最小长期记忆模块示例,使用向量库保存用户对话摘要:
# memory_store.py class LongTermMemory: def __init__(self, collection_name="user_memory"): # 这里以任意支持持久化的向量库为例 self.collection_name = collection_name def remember(self, user_id: str, memory_text: str, metadata: dict): # 将 memory_text 编码成向量并写入向量库 # 不同向量库 API 不同,核心是: # 1. 对文本做 embedding # 2. 将向量与 metadata 一起写入 pass def recall(self, query: str, top_k: int = 3): # 将 query 编码成向量 # 在向量库中检索最相似的 top_k 条记忆 # 返回记忆文本列表 return []这个示例故意没有绑定具体向量库,因为不同项目的选型差异很大。比较常见的组合是 Embedding 模型加开源的向量数据库,或者使用云厂商的向量检索服务。你需要根据项目实际环境,把remember和recall内部实现替换成对应 SDK 的调用。
召回时需要注意几点:
top_k不要设太大,3 到 5 条通常足够。- 需要对召回结果做相关性阈值过滤,避免引入无关内容。
- 召回结果要拼接在 Context 的“记忆区域”,而不是混在系统指令里。
5.3 对话摘要:压缩旧消息
当单次会话消息过长,可以把较早的消息用模型做一次摘要,然后保留摘要,丢弃原文。这样长期记忆里有摘要,短期 Context 也放得下。
摘要的典型实现:
def summarize_messages(messages: list) -> str: # 实际项目里调用一次 LLM: # prompt = f"请总结以下对话,保留订单号、用户诉求、商品信息:\n{messages}" # return llm_response return ""摘要不能只简单地截断前 N 个字符,而是要有目的的提取。电商场景至少要保留:订单号、用户诉求、售后进度、商品名称、价格信息。否则摘要不完整,后面的业务流程就可能断掉。
6. 上下文超限处理:Context Window 不够用的四个策略
模型接触到的外网报错里,最经典的就是:
Context length exceeded (169,692 tokens). Cannot compress further.出现这种问题的根源是:Context 里塞了太多东西,或者消息长度增长速度超过了预期。解法不是只靠“压缩”,而是要在请求组装阶段就做好预算。
6.1 策略一:长度截断
最简单粗暴的办法。超过上限时,优先丢弃最老的用户消息,保留系统指令和最近消息。适合短期会话。
需要明确的一点:永远不要把系统指令和最关键的当前用户问题去掉,否则模型会失去行为约束和回答目标。
6.2 策略二:关键消息摘要
会话很长时,把前面的消息做摘要,替换成一句话。例如用户问过 20 个问题,摘要成“用户咨询了物流延迟、退款流程、优惠券使用条件,最终选择退款订单 12345”。模型仍能抓住重点,token 占用大幅下降。
6.3 策略三:向量检索召回
把历史对话全部向量化存起来,每次请求只召回最相关的几个片段进入 Context。这样理论上无论历史多长,Context 都不会无限膨胀。适合大量知识库场景。
6.4 策略四:分治与重开会话
上下文已经无法压缩,或者 Agent 进入另一个业务域时,主动结束当前 Session,开启新 Session,把关键信息通过长期记忆传递下去。这听上去很“不优雅”,却是很多生产系统的实际兜底方案。
下面是一个组装 Context 的简化实现,把“截断 + 摘要”结合在一起:
# context_builder.py def build_context(system_prompt, history, long_term_memories, max_tokens=4096): memory_block = "\n".join(long_term_memories) history_block = "\n".join(history) # 预估 token 数量,这里用简单字符数近似 def estimate_tokens(text): return len(text) // 3 while estimate_tokens(system_prompt + memory_block + history_block) > max_tokens: if len(history) > 2: # 丢弃最旧的一条用户消息 history.pop(0) history_block = "\n".join(history) else: # 历史已经很少,说明是单条内容过长,需要摘要 history_block = summarize_messages(history) break return { "system_prompt": system_prompt, "memory_block": memory_block, "history_block": history_block, }这段代码不是生产级实现,但它演示了一个重要的原则:先在组装层限制,而不是等到请求发出去后让模型处理超限。如果你等到模型报context length exceeded再来想办法,已经浪费了一次请求时间和费用。
在实际项目中,用 tiktoken 或其他分词器精确统计 token,而不是用字符数估算,会更稳妥。
7. 完整实战:电商客服助手从零搭建
现在我们把所有概念串起来,实现一个最小电商客服助手。这个例子不依赖某个特定大模型 SDK,你可以根据自己的项目替换模型调用部分。
7.1 环境准备
建议环境:
- Python 3.9 及以上版本。
- Redis 服务,用于 Session 存储。
- 一个可调用的大模型 API,或本地部署的模型服务。
- 一个嵌入模型 + 向量库,用于长期记忆检索。
如果项目还没有向量库,可以先省略长期记忆部分,用 Redis 存用户画像和对话摘要,先跑通流程,再逐步替换。
依赖安装以实际项目为准,至少需要 redis 客户端和 HTTP 客户端。
7.2 项目结构
ecommerce_agent/ ├── app.py # 主入口 ├── state.py # 状态定义 ├── session_manager.py # Session 与 State 管理 ├── memory_store.py # 长期记忆接口 ├── context_builder.py # Context 组装与超限处理 └── agent.py # Agent 主逻辑7.3 核心代码
第一步:定义状态模块。
# state.py from dataclasses import dataclass, field @dataclass class CustomerState: session_id: str user_id: str = "" status: str = "initial" order_id: str = "" pending_intent: str = "" history: list = field(default_factory=list)第二步:实现会话管理。
# session_manager.py import json import redis redis_client = redis.Redis(host="localhost", port=6379, db=0) SESSION_TTL = 1800 # 30 分钟 def create_session(session_id): redis_client.set(f"session:{session_id}", "{}", ex=SESSION_TTL) def get_session(session_id): raw = redis_client.get(f"session:{session_id}") if raw: return json.loads(raw) return {} def update_session(session_id, data): redis_client.set(f"session:{session_id}", json.dumps(data), ex=SESSION_TTL) def save_state(session_id, state: CustomerState): data = get_session(session_id) data["state"] = state.__dict__ update_session(session_id, data)第三步:实现长期记忆接口。
# memory_store.py class LongTermMemory: def __init__(self, collection_name="ecommerce_memory"): self.collection_name = collection_name def remember(self, user_id, memory_text): # 写入向量库或数据库 pass def recall(self, query, top_k=3): # 从长期记忆检索与 query 相关的片段 return []第四步:实现 Context 组装。
# context_builder.py def build_context(system_prompt, history, memory_snippets, max_tokens=4096): memory_block = "\n".join(memory_snippets) history_block = "\n".join(history) def estimate_tokens(text): return len(text) // 3 while estimate_tokens(system_prompt + memory_block + history_block) > max_tokens: if len(history) > 2: history.pop(0) history_block = "\n".join(history) else: history_block = summarize_messages(history) break return f"{system_prompt}\n\n【长期记忆】\n{memory_block}\n\n【对话历史】\n{history_block}"第五步:实现 Agent 主逻辑。
# agent.py from session_manager import get_session, save_state from context_builder import build_context from state import CustomerState from memory_store import LongTermMemory def call_llm(messages): # 这里替换成你自己的模型调用 # 例如: # response = your_model_client.chat.completions.create( # model="your-model", # messages=messages, # ) # return response.choices[0].message.content return "已收到您的请求,正在为您处理。" class EcommerceAgent: def __init__(self): self.memory = LongTermMemory() def handle_message(self, session_id, user_message): session_data = get_session(session_id) or {} state = CustomerState(**session_data.get("state", {"session_id": session_id})) state.history.append(f"用户: {user_message}") # 1. 从长期记忆召回用户信息 memory_snippets = self.memory.recall(user_message) # 2. 组装 Context system_prompt = "你是一个电商客服助手。如果用户询问物流、退款、商品信息,请根据记忆和上下文作答。" context = build_context(system_prompt, state.history, memory_snippets) # 3. 调用模型 reply = call_llm(context) state.history.append(f"助手: {reply}") save_state(session_id, state) return reply这个示例代码中,call_llm是一个待替换函数,你可以根据自己的项目选择接入方式。只要把最终组装好的context传入模型接口,并取回模型回复即可。
7.4 运行与验证
在app.py里写一个简单的命令行入口:
# app.py from agent import EcommerceAgent if __name__ == "__main__": agent = EcommerceAgent() session_id = "test-session-001" while True: user_input = input("用户: ") if user_input == "exit": break reply = agent.handle_message(session_id, user_input) print(f"助手: {reply}")运行:
python app.py验证重点:
- 第一轮输入“订单 12345 还没发货”,检查 state 中是否记录 order_id。
- 第二轮输入“我要退款”,检查 Agent 是否能知道用户说的是订单 12345。
- 检查 Redis 中
session:test-session-001是否存在,State 是否更新。 - 如果已经接入长期记忆,重启进程后再输入相同内容,观察 Agent 是否还能召回历史信息。
如果第二轮 Agent 依然问“您的订单号是多少”,说明 State 没有正确写入或 Context 没有把 order_id 带上,优先检查save_state和build_context两个函数。
8. 常见问题与排查思路
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 同一 Session 内 Agent 忘记刚才的对话 | 消息历史没有传给模型 | 打印最终 context,检查是否包含历史 | 将历史消息拼入 Context,不要只传最新一条 |
| 提示 context length exceeded 或 cannot compress further | 历史消息或检索内容过长 | 统计每次请求的 token 数量 | 增加截断、摘要、检索召回逻辑,提前控制长度 |
| LangGraph 节点内改了 state 却没生效 | 原地修改 state 后未返回新值 | 检查节点返回值与状态不可变性 | 返回包含更新字段的新字典,例如return {"status": "after_sale"} |
| Redis 中 Session 丢失 | TTL 设置过短或 Redis 重启 | 检查 Redis 内存策略与 key 过期时间 | 按业务调整 TTL,必要时将 Session 持久化 |
| 长期记忆检索不到有用信息 | 写入时机不对或向量召回阈值过低 | 检查 recall 返回结果 | 确保关键信息在对话完成时异步写入,增加阈值过滤 |
| Agent 被无关长期记忆干扰 | 检索 top_k 过大 | 查看召回片段是否与 query 相关 | 调小 top_k,增加相关性和时间过滤 |
| auto-compaction 后上下文仍难以恢复 | 上下文已经接近不可用状态 | 观察压缩前后的 token 和语义 | 在压缩失败时主动提示用户开启新会话,丢弃中间历史 |
9. 最佳实践与工程建议
9.1 保持三层记忆职责单一
不要试图用一个 Redis key 解决所有记忆问题。Session 管消息,State 管业务进度,Memory 管跨会话积累。每一层独立存储,独立优化,出了问题也能快速定位。
9.2 控制每次请求的 token 预算
推荐给每次请求设一个 token 预算,并在组装层强制约束。系统指令占固定比例,历史消息和记忆片段按比例分配。宁可少带一些历史,也不要让请求超限后反复重试。
9.3 关键信息及时落库
当 Agent 从对话中识别到订单号、用户 ID、地址等结构化信息时,应立即写入业务数据库或长期记忆。不要等到会话结束才批量落库,因为一旦进程崩溃,这批关键信息就会丢失。
9.4 敏感信息脱敏与最小权限
电商场景涉及用户隐私,长期记忆里不要保存明文敏感信息。用户手机号、身份证号、地址等字段要做脱敏处理,访问时遵循最小权限原则。涉及用户数据的删除、导出操作,需要先确认权限和合规要求。
9.5 生产环境变更先在测试环境验证
Agent 的提示词、记忆写入逻辑、上下文组装策略,任何一项改动都可能影响线上回答质量。建议在测试环境用固定测试用例回归,观察状态流转和记忆召回是否符合预期,再发布到生产。
9.6 为记忆设置上限和时间衰减
长期记忆不是越多越好。超过一定条数的旧记忆,可以按时间衰减或合并成摘要。这样可以避免记忆库无限膨胀,也降低检索噪声。
9.7 建立可观测性
每一轮请求至少要记录三样东西:使用了哪些记忆片段、组装后的 token 数、模型回复内容。有了这三样日志,线上出了问题才能追溯是什么记忆影响了回答。
10. 结语
很多 Agent 项目最初都死在“模型能力不足”上,但实际排查下来,多半是记忆链路不完整。Context、Session、State、Memory 四者不是一个概念的不同说法,而是四个层级、四种生命周期、四种存储策略。
建议你先不要急着上向量库和复杂编排框架,把手上的“会话上下文 + 业务状态 + 简单长期记忆”最小闭环跑通,再逐步加入摘要压缩、向量召回、记忆编辑这些增强能力。这样既容易排查问题,也能更快看到 Agent 从“记不住事”到“越用越聪明”的变化。
如果你正在做电商、客服、个人助理类的 Agent 项目,建议收藏这篇文章,下一次遇到上下文超限或状态丢失时,按这个思路排查,大概率能少走很多弯路。