
这是AI Agent落地业务系统智能化改造系列的第八篇。前七篇讲了Agent怎么建、怎么编排、怎么做RAG。这篇讲一个容易被忽略的问题Agent怎么”记住”用户。不是”存对话历史”而是”知道你是谁、记住你的偏好、给你最合适的回答”。目录引言你的Agent有”记忆”吗一、Agent记忆的三层结构二、上下文窗口管理让Agent”记住”更多三、”千人千面”从用户角色到个性化四、踩坑清单五、还没解决的问题六、你可以试的几件事总结引言你的Agent有”记忆”吗用户第一次问”帮我查山东省的产业园数据。”Agent回答了。用户第二次问”那浙江的呢”Agent反问”什么浙江”这是大多数Agent的真实状态——每次对话都从零开始不认识用户不记得历史。还有一种更隐蔽的问题领导和基层工作人员问同一个问题”产业园情况怎么样”Agent给了完全一样的回答。领导想看宏观趋势基层想看具体项目但Agent不知道谁在问。这两个问题的本质是一样的Agent没有记忆。这篇讲三件事Agent的记忆怎么分层、上下文窗口怎么管理、怎么做到”千人千面”。业界正在把这些话题归入一个更大的概念Context Engineering上下文工程——不再是”写Prompt”而是”设计Agent看到的全部上下文”。记忆管理、上下文压缩、用户画像、RAG检索结果都是Context Engineering的一部分。一、Agent记忆的三层结构一个类比你去一家常去的咖啡店。第一次去店员不知道你要什么没有记忆。第二次去店员记得你上次点了美式短期记忆。去了十次后店员不用问就知道你要大杯美式少冰长期记忆。更重要的是店员知道你是熟客和你是第一次来的新人服务方式不一样角色感知。Agent的记忆也是这样分层的层类比存什么生命周期工作记忆你正在想的事当前对话的消息本次对话短期记忆今天发生的事会话摘要、关键决策本次会话长期记忆你认识这个人用户画像、历史偏好跨会话永久这三层不是三选一而是同时存在、互相补充。工作记忆放不下的信息压缩到短期记忆短期记忆中有价值的偏好提取到长期记忆。四个开源方案怎么处理这三层当前比较主流的四个方案它们对记忆的处理方式差异很大Mem061.4k starsYC孵化是当前最成熟的独立记忆层。它的核心设计是”多信号检索”——语义搜索、BM25关键词、实体匹配、时序推理四路并行打分融合。2026年4月的新算法只用一次LLM调用就能提取记忆ADD-only只增不改。不过要注意Mem0在LoCoMo基准上报告了92.5分但Zep团队发表了详细的反驳文章指出LoCoMo基准本身存在缺陷——对话平均仅16K-26K token在现代LLM上下文窗口内全量上下文基线73%反而优于Mem0最佳配置68%。也就是说短对话场景下直接把历史塞进上下文可能比用记忆系统更好。记忆系统的真正价值在长对话100K token和跨会话场景。from mem0importMemory mMemory()m.add(用户是后端开发主要用Go和Python,user_idalice)m.add(用户喜欢简洁的代码风格,user_idalice)resultsm.search(Alice的技术栈是什么,user_idalice)Mem0的API极简add和search两个核心操作。它负责从对话中自动提取关键信息、建立索引、处理检索。你不需要自己设计记忆结构。Letta/MemGPT40k stars走了另一条路把LLM的上下文窗口类比为操作系统的虚拟内存。上下文窗口是”寄存器/L1缓存”容量小但快外部存储是”磁盘”容量大但慢。Agent通过function call自主决定什么时候把信息从上下文移到外部存储什么时候从外部检索回来。┌──────────────────────────────────────┐ │ LLM Context Window │ ← 主记忆类似CPU寄存器 │ ┌──────────────────────────────┐ │ │ │ System Prompt(固定)│ │ │ │ Working Memory(可读写)│ │ ← Agent可自主编辑 │ │ FIFO Queue(最近消息)│ │ │ └──────────────────────────────┘ │ ├──────────────────────────────────────┤ │ External Storage │ ← 外部记忆类似磁盘 │ │ Archival Memory(无限)│ │ ← 向量检索 │ │ Recall Memory │ │ ← 完整对话历史 └──────────────────────────────────────┘Letta的设计哲学是”Agent自主管理记忆”——不是你告诉Agent记什么而是Agent自己判断什么值得记。理论上很优雅但实现复杂度高且依赖Agent的自主决策质量。LangChain/LangGraph105k stars经历了Memory模块的完整生命周期创建ConversationBufferMemory等系列类→废弃→重构为LangGraph的Checkpoint短期 Store长期方案。Checkpoint自动保存每次graph执行后的状态Store手动管理跨会话的持久信息。灵活性高但需要自己设计记忆的提取和检索逻辑。CrewAI55.9k stars的Memory设计最简洁remember/recall/forget三件套。LLM自动推断记忆的scope层级路径、categories分类、importance重要性权重。检索时用复合评分score α·语义相似度 β·时间衰减 γ·重要性。四个方案的核心差异项目Stars核心理念核心API复杂度Mem061.4k通用记忆层多信号检索add/search低Letta/MemGPT40kOS式分层Agent自主管理archival_memory_insert/search高LangGraph105kCheckpointStore灵活组合checkpointer store.put中CrewAI55.9k统一Memory自动推断重要性remember/recall/forget低选型建议场景推荐方案原因快速给Agent加记忆Mem0API最简单开箱即用已用LangGraph生态LangGraph CheckpointStore不引入额外依赖需要Agent自主管理记忆Letta/MemGPTOS式分层理论最优雅多Agent协作CrewAI Memory统一API自动推断重要性决策路径如果你是第一次给Agent加记忆从Mem0开始——pip install mem0aiadd/search两个API5分钟跑通。如果你已经在用LangGraph用CheckpointStore不引入额外依赖。如果你需要Agent自己管理记忆自主决定记什么忘什么看Letta但做好实现复杂的准备。二、上下文窗口管理让Agent”记住”更多核心问题LLM的上下文窗口是有限的。GPT-4o 128K tokenDeepSeek V4 128K tokenClaude 200K token。看起来很大但实际使用中很快就会遇到三个问题对话越长越贵每次请求都要把整个上下文发给APItoken数×单价成本对话越长越慢prefill阶段的延迟和token数成正比对话越长越”忘”Lost in the Middle问题——LLM对中间位置的信息感知力弱上下文管理不是”截断”是”在有限窗口里放最有价值的信息”。方案1LLMLingua-2 — token级压缩这是目前最成熟的上下文压缩方案来自Microsoft Research发表在ACL 2024 Findings。核心思路用一个BERT级别的encoder对每个token做二分类——保留还是删除。不需要大模型XLM-RoBERTa-large就够CPU上也能跑。from llmlinguaimportPromptCompressor compressorPromptCompressor(model_namemicrosoft/llmlingua-2-xlm-roberta-large-meetingbank,device_mapcpu)# 压缩一段长文本resultcompressor.compress_prompt(long_context,rate0.5,# 保留50%的tokenforce_tokens[\n,?,Q:],# 这些token强制保留)# result[compressed_prompt] 就是压缩后的文本效果论文报告最高20x压缩率在特定数据集上实际场景中5-10x更常见性能损失极小。比第一代LLMLingua快3-6x因为从自回归生成改成了分类任务。LongLLMLinguaACL 2024在此基础上加了”问题感知”——根据用户问题和文档段落的相关性对token重排序解决Lost in the Middle问题。NaturalQuestions上性能提升21.4%token减少4x。适用场景RAG检索结果压缩、长Prompt压缩、CoT推理压缩。方案2递归摘要 — 最简单的方案LangChain内置的ConversationSummaryBufferMemory3行代码实现from langchain.memoryimportConversationSummaryBufferMemory memoryConversationSummaryBufferMemory(llmChatOpenAI(modeldeepseek-v4-flash),max_token_limit2000,# 超过2000 token时触发摘要return_messagesTrue,)原理维护一个token计数器。当总token超过阈值把最旧的N条消息用LLM摘要为1段。摘要最近消息新上下文。优点是简单可靠几乎零额外基础设施。缺点是累积摘要可能丢失早期细节——每轮摘要都会损失一点信息对话足够长后早期的内容可能被”摘要掉”了。适用场景简单Agent、token预算固定的场景。方案3Parent-Child — RAG场景的实践这个方案在第七篇讲过这里补充一个重要的改进Anthropic在2024年提出的Contextual Retrieval。核心思想每个chunk在入库前用LLM加一段”上下文前缀”——这段话在全文中讲什么。检索时有了上下文前缀的chunk比裸chunk命中率高得多。Anthropic的实验数据加上下文前缀后检索失败率降低了49%。如果再叠加BM25向量混合检索Rerank失败率降低67%。# 给chunk加上下文前缀def add_context_prefix(chunk, full_document): promptf给以下文档片段写一段简短的上下文说明50字以内 说明这段话在全文中讲什么。 完整文档{full_document[:500]}... 片段{chunk} contextllm.invoke(prompt).contentreturnf{context}\n\n{chunk}代价是入库阶段多了一次LLM调用每个chunk一次但对于文档量不大的场景几百到几千个chunk这个代价完全可以接受。方案4滑动窗口关键信息锚定这是生产环境中最常见的组合策略上下文System Prompt固定 Pinned Facts用户画像、关键决策固定 Sliding Window最近N轮对话动态 RAG Results检索结果按需优先级System Prompt Pinned Facts Sliding Window RAG Results。当token不够时从低优先级开始丢弃。class ContextManager: def __init__(self,max_tokens8000): self.max_tokensmax_tokens self.pinned_facts[]# 关键信息不参与滑动self.window[]# 最近N轮对话self.summary# 更早对话的摘要def add_message(self, role, content): self.window.append({role:role,content:content})ifself._count_tokens()self.max_tokens: self._compress()def build_context(self, system_prompt,rag_results): contextsystem_promptifself.pinned_facts: contextf\n\n关键信息\n\n.join(self.pinned_facts)ifself.summary: contextf\n\n历史摘要{self.summary}context\n\n\n.join(f{m[role]}: {m[content]}forminself.window[-10:])ifrag_results: contextf\n\n参考资料{rag_results}returncontext def _compress(self):# 把最旧的消息摘要oldself.window[:5]self.summarysummarizer(self.summary, old)self.windowself.window[5:]取舍总结方案压缩率信息损失延迟增加实现复杂度推荐场景LLMLingua-2高(20x)低低低RAG结果压缩递归摘要中中中(1次LLM)极低简单AgentParent-Child无无无低RAG场景滑动窗口锚定低可控无低通用Agent实际项目中这些方案通常组合使用LLMLingua-2压缩RAG结果递归摘要管理对话历史滑动窗口关键信息锚定组织最终上下文。记忆注入的token成本方案选好了还有一个容易忽略的问题——记忆注入到Prompt后增加多少token记忆条目数预估token数占8K窗口比例10条偏好~200 token2.5%50条偏好~1000 token12.5%200条偏好~4000 token50%10条以内几乎无感50条开始需要压缩200条以上必须做检索过滤只注入和当前问题相关的记忆。这也是为什么Mem0的”多信号检索”比”全量注入”更实用——不是把所有记忆都塞进Prompt而是只检索最相关的几条。三、”千人千面”从用户角色到个性化3.1 两种”千人千面”很多人理解的”千人千面”是记住用户喜欢简洁回答下次就给简洁回答。这只是偏好个性化是浅层的。更深层的是角色个性化领导和基层问同一个问题Agent应该给完全不同的回答。维度偏好个性化角色个性化核心问题用户喜欢什么风格用户是什么角色信息来源从对话中自动提取从业务系统获取变化频率随对话积累缓慢变化相对固定组织架构决定影响范围回答风格、详细程度数据权限、工具权限、回答视角、信息粒度两者不是二选一而是叠加角色决定框架偏好决定细节。3.2 角色个性化不同用户看到不同的Agent以乡村产业监测系统为例。这个系统服务农业农村部用户从部领导到县级工作人员都有。同样是”产业园情况怎么样”这个问题角色关注点Agent应该怎么回答部领导全国宏观趋势、政策效果“2024年全国新增产业园23个同比增长15%。山东、浙江表现突出建议关注中西部地区的追赶态势。”省级工作人员本省产业情况、与全国对比“山东省现有产业园12个全国排名第3。较去年新增2个增速高于全国均值。与浙江相比主导产业集中度偏低。”县级工作人员本县具体项目、申报流程“兰陵县产业园2024年申报状态已提交实施方案待省级评审。下一步需准备资金使用方案截止日期8月31日。”数据分析师原始数据、统计口径“产业园表共412条记录最新数据截止2024-06-30。查询语句SELECT * FROM parks WHERE province‘山东’。统计口径国家级省级认定。”同一个Agent同一个知识库但因为用户角色不同回答的视角、粒度、格式完全不同。3.3 角色信息从哪来角色信息不是Agent自己猜的而是从业务系统获取的来源方式可靠性登录系统SSO/OAuth → user_id → 查询角色表最可靠会话开头用户主动告知”我是XX省的”依赖用户配合行为推断从查询模式推断经常问SQL→分析师不可靠作为补充组织架构对接RBAC权限体系可靠但对接成本高推荐的做法以登录系统为主行为推断为辅。用户登录后系统从数据库查到他的角色、所属组织、数据权限注入到Agent的上下文中。3.4 角色怎么影响Agent行为角色信息影响Agent的四个层面用户提问 → 系统获取user_id → 查询角色权限 │ ├── 数据层角色决定能看哪些数据行级/列级权限 ├── 工具层角色决定能调用哪些工具导出/审批/修改 ├── 回答层角色决定回答的视角和详细程度 └── 风格层角色决定称呼、语气、格式实现方式是基于角色的System Prompt模板ROLE_PROMPTS{leader:(你是乡村产业分析助手。用户是{org}的领导关注宏观趋势和政策效果。回答要简洁有力给出结论和建议不需要展示原始数据。如果用户问具体数据给汇总数字而不是明细。),staff:(你是乡村产业分析助手。用户是{org}的工作人员需要具体的数据和操作指导。回答要详细附上具体数字和操作步骤。如果涉及申报流程列出每一步和截止日期。),analyst:(你是乡村产业数据分析助手。用户是数据分析师需要原始数据和统计口径。回答要精确优先提供SQL查询和数据接口。如果用户问统计指标说明计算口径和数据来源。),}def build_system_prompt(user_id: str)-str:# 1. 从业务系统获取角色信息user_infoget_user_info(user_id)# {role: staff, org: 山东省农业农村厅, ...}# 2. 基于角色选择Prompt模板templateROLE_PROMPTS.get(user_info[role], ROLE_PROMPTS[staff])base_prompttemplate.format(orguser_info.get(org,))# 3. 叠加数据权限data_scopeget_data_scope(user_id)# {province: 山东, level: province}base_promptf\n用户数据范围{data_scope[province]}{data_scope[level]}级别数据。# 4. 叠加偏好个性化从记忆系统获取preferencesmemory.search(user_iduser_id)ifpreferences: base_promptf\n用户偏好{preferences}returnbase_prompt3.5 偏好个性化从对话中学习角色是”框架”偏好是”细节”。偏好从对话中自动提取逐步积累。三种提取方法方法1实体提取spaCy NER—— 速度快、成本低但只能提取显式提到的信息。注意spaCy对标准实体人名、地名、组织名效果好但对领域特定实体技术栈、代码风格偏好准确率有限。如果需要提取”用户喜欢简洁风格”这类非标准实体建议用LLM提取。importspacy nlpspacy.load(zh_core_web_trf)def extract_entities(conversation: str)-dict: docnlp(conversation)entities{}forentindoc.ents: entities.setdefault(ent.label_,[]).append(ent.text)returnentities# 示例输出{PERSON: [张三], ORG: [阿里]}# 但 简洁的代码风格 这类偏好不会被识别为实体方法2LLM直接提取—— 理解能力强能处理隐式偏好但延迟高、成本高。ChatGPT Memory就是这个路线。from pydanticimportBaseModel class UserPreference(BaseModel): response_style: str|NoneNone# 简洁/详细/有示例technical_level: str|NoneNone# 入门/中级/高级preferred_tools: list[str][]other_notes: str|NoneNone def extract_preferences(conversation: str, existing: UserPreference|NoneNone)-UserPreference: promptf从对话中提取用户偏好。只提取明确提到的信息。 对话{conversation}{f已有偏好{existing.model_dump_json()}ifexistingelse}提取字段response_style, technical_level, preferred_tools, other_notes 如果信息冲突以最新对话为准。 responsellm.invoke(prompt)returnUserPreference.model_validate_json(response.content)方法3事实提取三元组—— 介于两者之间提取”主体-关系-客体”的结构化事实适合构建用户知识图谱。实际建议初创阶段用实体提取简单规则生产环境用LLM直接提取。3.6 两种个性化的组合最终Agent行为角色个性化(业务系统) 偏好个性化(记忆系统)角色决定你能问什么、我怎么答框架 偏好决定你喜欢什么样的回答细节一个完整的例子用户山东省产业园情况怎么样 系统判断 - user_id: user_001 - role: staff省级工作人员 - org: 山东省农业农村厅 - 数据范围: 山东省 - 偏好: 喜欢有图表的回答、技术中级 Agent回答山东省现有国家现代农业产业园12个见下表较去年新增2个。 在全国排名第3仅次于浙江15个和江苏14个。 | 产业园 | 主导产业 | 认定年份 | |--------|---------|---------| | 兰陵县 | 蔬菜 | 2021 | | ... | ... | ... | 建议关注寿光市产业园的蔬菜产业链完整度最高可作为标杆案例。同一个问题如果是领导问的回答会变成”山东省产业园数量全国第3增速高于均值建议关注中西部追赶态势。”3.7 个性化的风险“千人千面”听起来很好但ChatGPT Memory的实践暴露了两个严重问题谄媚放大Sycophancy Amplification当Agent记住了用户的偏好后它会倾向于给出用户想听的回答而不是正确的回答。比如用户说”我觉得Python是最好的语言”Agent记住了这个偏好之后所有语言选型问题都推荐Python——即使场景更适合Go或Rust。记忆幻觉Memory HallucinationChatGPT用户报告记忆功能会编造用户从未说过的偏好。”ChatGPT’s new memory feature is just making stuff up about them”——这不是个别现象而是记忆系统的结构性风险。怎么缓解1区分”事实”和”偏好”——”用户是后端开发”是事实”用户喜欢Python”是偏好两者的置信度不同2给记忆加来源标注——这条记忆来自用户的原话还是Agent推断的3定期让用户审核记忆——ChatGPT的做法是让用户查看和编辑所有已保存的记忆。四、踩坑清单坑1记忆太忠实记住了用户的错误输入现象用户说”我喜欢咖啡”三个月后说”我不喝咖啡了”但Agent还是推荐咖啡。原因Mem0的ADD-only策略只增不改。新记忆加进去了但旧记忆还在检索时旧记忆可能排在前面。解决给每条记忆加时间戳检索时按时间加权。或者在提取阶段做冲突检测——如果新记忆和旧记忆矛盾标记旧记忆为”已过期”。效果理论上偏好冲突场景的准确率可从60%提升到85%基于冲突检测时间加权的组合策略未做大规模评测。教训记忆不是越多越好质量和一致性比数量重要。坑2上下文压缩丢失关键信息现象用户3轮前说了一个关键需求递归摘要后Agent忘了。原因递归摘要是”有损压缩”。每轮摘要都会损失一点细节多轮累积后早期的关键信息可能被”摘要掉了”。解决区分”可压缩”和”不可压缩”的信息。用户明确表达的偏好、关键决策、重要数字标记为pinned facts不参与压缩。只压缩对话的”过程性内容”。教训压缩策略要有”豁免机制”关键信息不能被压缩。坑3用户画像更新太慢Agent”记不住”现象用户已经改变了工作方向从后端转前端但Agent还在推荐后端相关的回答。原因画像提取频率太低。如果只在会话结束时提取一次用户的变化可能很久才被感知到。解决每轮对话后异步触发画像更新。不需要每轮都调LLM——先用规则判断”这轮对话是否包含可能改变画像的信息”比如用户提到了新的技术栈、新的工作内容只有命中规则时才触发LLM提取。教训画像更新要有”触发条件”不是每轮都提取但也不能提取太慢。坑4多轮对话token爆炸现象对话20轮后上下文超过128K tokenAPI响应变慢变贵。原因没有上下文管理策略所有消息都塞进上下文。解决递归摘要滑动窗口组合。最近10轮保留原文更早的消息用摘要替代。关键信息pinned在System Prompt里。教训上下文管理从第一轮对话就要做不是等token爆了再补。坑5不同用户的画像互相污染现象用户A的偏好影响了用户B的回答。原因user_id隔离没做好。可能是namespace没有正确隔离或者共享的向量数据库没有按user_id过滤。解决每条记忆必须绑定user_id检索时强制加user_id过滤条件。向量数据库的namespace按user_id隔离。教训多用户系统必须从第一天就做好隔离后补的成本很高。坑6角色错配现象基层工作人员收到了领导级别的宏观回答。原因角色信息获取失败登录态过期、接口超时系统默认用了”领导”模板。解决角色获取失败时用最保守的默认角色基层工作人员而不是最高权限的角色。宁可回答太详细不要回答太宏观。教训默认角色应该是”最低权限”不是”最高权限”。坑7记忆层的LLM调用成本被低估现象上线后发现记忆层的API费用比Agent本身的推理费用还高。原因Mem0、Zep、Letta等记忆系统都需要调用LLM做记忆提取和分类。每轮对话至少一次额外的LLM调用。Mnemosyne项目开发者的测算100K memories/月 → $1K-3K API费用仅用于记忆层。解决1用规则做初筛只有”可能包含偏好信息”的对话才触发LLM提取2考虑零LLM方案如Mnemosyne用确定性pipeline替代LLM提取3用小模型deepseek-v4-flash做记忆提取成本降一个数量级。零LLM方案值得单独说一下。Mnemosyne项目的动机就是”记忆层不应该再花LLM的钱”——用确定性的12步pipeline规则匹配模式识别结构化提取替代LLM提取。适合大规模场景100K memories/月但提取质量不如LLM。这是一个trade-off花LLM的钱提取质量高还是用规则省钱但质量低。教训记忆系统的成本不只是存储LLM提取才是大头。设计时就要算清楚每月的记忆层API费用。五、还没解决的问题记忆冲突用户偏好变化时旧记忆和新记忆矛盾。Mem0的ADD-only策略简单但不优雅覆盖旧记忆又怕丢失历史上下文。目前没有好的自动化冲突解决机制。遗忘机制人类会遗忘Agent不会。所有记忆永久存储检索时噪声越来越大。什么时候该”忘掉”一条记忆目前没有好的自动化遗忘策略。一个简单的近似方案是TTLTime To Live——给每条记忆设过期时间超过N天未被检索到的记忆自动降权或归档。但这只是工程上的妥协不是真正的”遗忘”。LoCoMo基准测试也没有覆盖遗忘场景。记忆评测RAG有RAGASAgent有评测集但”记住用户偏好”的准确率怎么量化LoCoMo是目前唯一的记忆benchmarkMem0拿了92.5分但覆盖的场景有限。自建评测集的成本很高需要构造”用户说了什么→Agent应该记住什么”的标注数据。隐私合规用户要求”忘掉我之前说的话”向量数据库里的embedding能精确删除吗大多数向量数据库支持按ID删除但embedding模型的不可逆性意味着你无法从embedding反推出原始文本。这在GDPR等合规框架下可能有问题。成本控制万级记忆条目时每次对话的记忆检索注入成本是多少Mem0的多信号检索需要同时查向量库、关键词库、实体库延迟和成本都随记忆数量增长。还没做过压测。跨系统画像用户在A系统和B系统的画像怎么打通统一身份SSO可以解决身份问题但画像数据的同步和冲突处理是另一个挑战。图谱记忆2025-2026年的一个明确趋势是用知识图谱Knowledge Graph替代纯向量存储做记忆。Zep的Temporal Knowledge Graph、Graphiti、Cognee等方案正在兴起。图谱的优势是能表达实体之间的关系”用户→使用→Python”、”Python→属于→用户的技术栈”支持多跳推理。但图谱的构建和维护成本比向量存储高很多目前还在早期阶段。六、你可以试的几件事试15分钟 — 给Agent加滑动窗口摘要最简单的上下文管理。不需要额外依赖LangChain内置。from langchain.memoryimportConversationSummaryBufferMemory memoryConversationSummaryBufferMemory(llmChatOpenAI(modeldeepseek-v4-flash),max_token_limit2000,return_messagesTrue,)预期效果多轮对话不再token爆炸。 可能踩的坑摘要丢失早期关键信息。解决方法关键信息pinned。试230分钟 — 用Mem0给Agent加长期记忆Mem0的API极简pip install mem0ai就能用。from mem0importMemory mMemory()# 对话中自动提取记忆m.add(用户是后端开发主要用Go,user_idalice)# 下次对话时检索resultsm.search(Alice的技术栈,user_idalice)# 注入到System Prompt中预期效果用户第二次来能认出回答自动适配偏好。 可能踩的坑记忆提取质量依赖LLM有时会提取到无关信息。试32小时 — 基于角色做System Prompt分发如果你的系统已经有用户登录和角色体系这一步很直接。ROLE_PROMPTS{admin:你是管理员助手...,user:你是普通用户助手...,analyst:你是数据分析助手...,}def get_prompt(user_id): roledb.get_user_role(user_id)returnROLE_PROMPTS.get(role, ROLE_PROMPTS[user])预期效果不同角色看到不同Agent。 可能踩的坑角色信息获取失败时的兜底。用最低权限角色做默认值。试4半天 — 搭建用户画像提取管线在试2的基础上搭建自动化的偏好提取。每轮对话后异步触发def on_conversation_turn(user_id, conversation):# 1. 规则判断是否需要更新画像ifnot contains_preference_signal(conversation):return# 2. LLM提取偏好new_prefsextract_preferences(conversation)# 3. 与已有画像合并处理冲突existingget_user_profile(user_id)mergedmerge_profiles(existing, new_prefs)# 4. 存储save_user_profile(user_id, merged)预期效果Agent根据用户偏好自动调整回答风格。 可能踩的坑画像更新延迟、新旧偏好冲突。试5一天 — 实现完整的三层记忆角色系统把试1-4组合起来滑动窗口管理上下文Mem0管理长期记忆角色Prompt分发画像自动提取。预期效果千人千面的个性化Agent。 可能踩的坑系统复杂度上升、多个组件之间的数据流需要仔细设计、成本控制。总结记忆不是”存历史”。Agent的记忆不是把对话记录存下来就完了。工作记忆管当前对话短期记忆管会话摘要长期记忆管用户画像。三层各司其职互相补充。千人千面不是”记住偏好”。偏好个性化记住你喜欢什么只是浅层的。角色个性化知道你是什么角色、能看什么数据、需要什么粒度的回答才是业务系统中”千人千面”的核心。两者叠加角色决定框架偏好决定细节。上下文管理不是”截断”。在有限的上下文窗口里放最有价值的信息——LLMLingua-2做token级压缩递归摘要做对话级压缩关键信息锚定保证不丢。组合使用效果最好。相关关键词Agent记忆、上下文管理、千人千面、用户画像、Mem0、LLMLingua、个性化Agent、角色个性化、长期记忆、对话摘要