发布时间:2026/8/31 13:08:33
Agent记忆架构实战:用Context、Memory、Session、State构建持久对话系统 在实际 Agent 项目里最难解释但又最影响体验的往往不是模型能力而是“记忆”这一层。同样是客服助手有的 Agent 聊完一轮就忘干净用户必须重新报订单号有的 Agent 能记住用户上次的售后进度、常用地址甚至能从历史对话里找到用户真正想要的信息。差异不在模型本身而在 Context、Memory、Session、State 这四个词能否被组织成一套可落地的记忆架构。这篇文章会围绕电商客服助手场景把短期状态、长期存储、上下文窗口超限处理分别拆开讲清楚并给出可以运行的代码。你会看到 Session 和 State 负责短期会话Memory 负责跨会话沉淀Context 负责把记忆组装成模型能理解的内容。读完以后你可以把这套结构直接套用到自己的 Agent 项目里。1. 先理清四个词Context、Memory、Session、State 到底管什么1.1 四个概念在 Agent 中的分工很多开发者把 Context、Memory、Session、State 混为一谈结果代码写完后要么状态全部堆在内存里要么把长期记忆一股脑塞进提示词很快就把模型的上下文窗口撑爆。先把四个词的定义区分清楚Context模型在单次推理中能看到的全部内容包括系统提示词、历史对话、检索到的记忆、工具返回结果和用户最新输入。它受 token 上限约束是“每次请求临时拼出来的”。Session一次业务交互的边界从用户开始咨询到这次咨询结束用 session_id 标识。它负责隔离不同用户的对话也决定短期数据存活多久。State一条工作流从开始到当前时刻的中间状态集合。比如用户填到一半的表单地址填了、手机号还没填这些中间值就存在 State 里。Memory跨 Session 保留的长期信息比如用户常用的收货地址、历史订单编号、售后进度。Memory 是“越用越聪明”的核心来源。维度ContextSessionStateMemory一句话定位模型这次能看到什么一次服务交互的边界当前流程走到哪一步跨会话记住什么生命周期单次请求结束即释放一次会话通常较短工作流执行期间长期保留按策略清理典型载体Token 序列会话 ID 存储内存 / 数据库字段数据库 / 向量库丢失后果模型无法回答当前问题用户身份和上下文混淆流程中断或重复填写用户必须重新描述历史信息这四个词不是并列关系而是层层配合Session 划出边界State 记录当前流程Memory 沉淀长期事实Context 把所有需要的内容在请求发出前组装好。1.2 记忆在 Agent 中的一条完整流动路径在设计记忆系统前先理解一条完整链路用户发送消息网关解析出 session_id。Session 模块恢复该会话对应的 AgentState。Memory 模块根据用户问题召回相关长期记忆。Context 构建模块把系统提示词、召回记忆、历史对话、用户问题组装成上下文。模型完成推理可能调用订单查询等工具。Agent 根据模型输出更新 State。异步沉淀新的 Memory 条目。把最终回复返回给用户。这个顺序很重要。先恢复 State再召回 Memory因为组装 Context 时既需要当前流程状态也需要历史长期信息。先更新 State再写 Memory避免只记住了一半的对话过程。2. 电商客服助手的记忆需求拆解2.1 场景一个需要“记住你”的客服假设真实场景是这样一个售后咨询周三用户问“订单 OD20240415008 怎么退货”Agent 返回退货地址并把订单号和地址写进长期记忆。周五用户说“我那个退货已经寄走了地址没问题吧”。如果 Agent 完全不记得用户要重新报一次订单号体验很糟糕。要做到“记住”需要拆成两部分短期当前会话内用户说的每一句话、Agent 上一轮回答的地址、用户是否还有未填完的表单。长期用户是谁、常用地址、历史订单、售后进度、之前承诺的退款金额。2.2 记忆分层方案电商客服场景建议分成四层层级内容存储位置生命周期典型示例L0 上下文窗口单次请求拼装的内容请求内存中的 Token 序列请求结束即释放系统提示词 最近 10 轮对话L1 会话状态当前会话的中间变量Redis / 数据库Session TTL比如 30 分钟用户填到一半的地址表单L2 长期记忆跨会话保留的业务事实MySQL / PostgreSQL / 键值库长期按重要度清理订单号、退货地址、用户偏好L3 业务数据订单、商品、物流、售后单业务系统数据库由业务系统管理订单当前物流状态L0 和 L1 是“短期状态”L2 是“长期记忆”。很多项目最容易犯的错误是把 L0 当 L2 用把所有历史对话都存下来每次请求全部塞进 Context。这样短期能跑对话一长必然超限。2.3 记忆条目到底存什么长期记忆不是记录流水账而是提取“值得记住”的结构化事实。电商客服场景可以分成这些抽屉用户画像称呼、常用收货地址、回复偏好简洁或详细。会话事实咨询过的订单号、退货原因、客服承诺的退款金额。业务实体订单、物流单、售后单之间的关联状态。对话摘要历史对话压缩后的结论比如“用户要求工单优先处理原因是收货地址填错”。每条记忆都建议带上分类和重要度方便召回时排序。否则长期记忆越多召回时越容易把不相关的信息塞进上下文。3. 环境准备与项目结构3.1 依赖清单先准备一套轻量可运行的环境。下面依赖版本只是示例落地前先确认与你使用的模型 SDK 兼容。requirements.txtfastapi0.111.0 uvicorn[standard]0.30.1 redis5.0.4 sqlalchemy2.0.30 pydantic2.7.1 openai1.30.1 langgraph0.0.67 python-dotenv1.0.1说明FastAPI 用来暴露 HTTP 接口承接用户消息。Redis 用来存 Session 短期状态天然支持 TTL 过期。SQLAlchemy 用来存长期记忆方便后续切换 PostgreSQL。openai 是模型调用 SDK实际项目按自己使用的模型服务替换。LangGraph 可选如果工作流简单可以不用直接手写状态机。3.2 目录结构项目结构建议拆成独立模块避免把所有逻辑堆在 main.pyagent-memory-demo/ ├── app/ │ ├── __init__.py │ ├── main.py # FastAPI 入口 │ ├── models.py # 数据库模型和数据结构 │ ├── session.py # Session 和 AgentState 管理 │ ├── memory.py # 长期记忆写入与召回 │ ├── context.py # 上下文组装与超限处理 │ ├── agent.py # Agent 主流程 │ └── utils.py # Token 估算、JSON 解析等工具 ├── .env.example └── requirements.txt这个结构的好处是每个模块只负责一件事session.py 不关心模型调用memory.py 不关心 HTTP 层context.py 只负责组装和压缩。3.3 基础配置项.env.exampleREDIS_URLredis://localhost:6379/0 DATABASE_URLsqlite:///agent_memory.db LLM_API_BASEhttps://api.example.com/v1 LLM_API_KEYsk-xxxx LLM_MODELyour-model-name SESSION_TTL_SECONDS1800 MAX_CONTEXT_TOKENS8000 MAX_HISTORY_TURNS20 MEMORY_TOP_K5几个关键参数参数默认值作用调大影响调小影响SESSION_TTL_SECONDS1800会话状态保留时间会话能跨更长空闲时间恢复用户稍久没操作就丢失状态MAX_CONTEXT_TOKENS8000单次请求上下文上限模型能看到更多内容但成本更高降低超限概率但可能丢失细节MAX_HISTORY_TURNS20会话历史保留轮次保留更完整上下文减少 token但可能忘记前文MEMORY_TOP_K5召回长期记忆条数找到更多相关信息避免记忆污染但可能漏关键信息这些参数要在开发环境先跑通再根据真实流量调整。4. 用 Session 和 State 管理短期状态4.1 Session 的创建、读取和过期Session 的核心是隔离和过期。每个用户进入客服时前端或网关生成一个 session_id后续请求都带这个 ID。Redis 是最常用的载体因为可以设置 TTL避免僵尸会话堆积。session.pyimport json import time import redis from dataclasses import dataclass, field redis_client redis.Redis.from_url(redis://localhost:6379/0) SESSION_TTL_SECONDS 1800 dataclass class Message: role: str content: str timestamp: float field(default_factorytime.time) dataclass class AgentState: session_id: str user_id: str messages: list[Message] field(default_factorylist) current_intent: str | None None form_data: dict field(default_factorydict) order_result: dict | None None def create_session(user_id: str) - str: session_id fsession_{int(time.time() * 1000)} state AgentState(session_idsession_id, user_iduser_id) save_state(state) return session_id def get_state(session_id: str) - AgentState | None: raw redis_client.get(fsession:{session_id}) if not raw: return None data json.loads(raw) state AgentState(**data) state.messages [Message(**m) for m in data.get(messages, [])] return state def save_state(state: AgentState) - None: payload { session_id: state.session_id, user_id: state.user_id, current_intent: state.current_intent, form_data: state.form_data, order_result: state.order_result, messages: [ {role: m.role, content: m.content, timestamp: m.timestamp} for m in state.messages[-20:] ], } redis_client.setex( fsession:{state.session_id}, SESSION_TTL_SECONDS, json.dumps(payload, ensure_asciiFalse), )这里的 TTL 自动做了两件事活跃用户每次 save_state 都会续期不活跃用户的 Session 到期后自动清理不需要手动写定时任务。需要提一句Web 场景常说的 Cookie 和 Token 解决的是“用户身份识别”Agent 场景的 Session 解决的是“多轮对话上下文归属”两者不是同一层概念。Cookie 可以带来 session_id但 Agent 的 Session 存储的是对话状态不是登录票据。4.2 AgentState 的数据结构设计AgentState 是工作流中的“中央状态”它要承载messages最近 N 轮对话。current_intent当前意图比如“查订单”“填退货地址”。form_data表单中间值比如地址、手机号、订单号。order_result工具调用结果比如订单服务返回的物流信息。不要把工具返回的完整 JSON 全量塞进 messages。订单详情、日志等大块文本要么截断要么只保留结论否则 State 会被撑大Redis 也会成为瓶颈。正确做法是保留结构化字段state.form_data {order_id: OD20240415008, address: 浙江省杭州市西湖区...} state.order_result {status: delivered, summary: 订单已签收}这样模型需要时可以由 context.py 决定是否把 order_result 拼进 Context不需要时它只安静地躺在 State 里。4.3 在 LangGraph 节点函数里正确更新 State如果你用 LangGraph节点函数里最容易犯的错是“改了 dict 但没生效”。LangGraph 的 State 合并机制是增量更新每个节点返回一个 dict框架会把它合并到全局 State 中。直接原地修改传入的 state 对象在部分运行时里不会触发持久化。错误写法def fill_address_node(state): state[form_data][address] 浙江省杭州市西湖区... return None正确写法def fill_address_node(state): form_data dict(state.get(form_data, {})) form_data[address] 浙江省杭州市西湖区... return {form_data: form_data}关键点是新建字段后再返回不要依赖外部副作用。这样设计的好处是每个节点的输入输出可追踪方便日志排查和状态回滚。5. 用 MemoryStore 沉淀长期记忆5.1 记忆表设计长期记忆建议用独立表存储避免和会话状态混在一起。MySQL / PostgreSQL 通用建表 SQLCREATE TABLE user_profile ( user_id VARCHAR(64) PRIMARY KEY, nickname VARCHAR(128), default_address TEXT, preferred_style VARCHAR(32), created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); CREATE TABLE memory ( memory_id BIGINT PRIMARY KEY AUTO_INCREMENT, user_id VARCHAR(64) NOT NULL, category VARCHAR(32) NOT NULL, content TEXT NOT NULL, importance TINYINT DEFAULT 1, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_user_category (user_id, category), INDEX idx_user_updated (user_id, updated_at) );字段说明category记忆分类比如 profile、order、after_sale、summary。content记忆的具体内容建议用一句话或短 JSON。importance重要度1 到 5召回时优先取重要度高的。updated_at用于“最近更新的记忆优先”策略。user_profile 表存用户画像memory 表存可增量追加的事实。两者分开避免一张表读出来一堆不同类型的数据。5.2 记忆写入从对话里抽取值得记住的事实不是每句话都要写入记忆。建议用模型做一次“记忆抽取”只提取稳定事实。示例 promptdef extract_memories(messages): prompt 你是客服系统的记忆抽取器。从以下客服对话中抽取值得长期保存的事实。 只输出 JSON 数组不要输出其他文字。每个元素格式 {category: profile|order|after_sale|summary, content: 一句话描述, importance: 1-5} 规则 1. 用户说出的收货地址、订单号、电话号码要保存importance 不低于 4。 2. 客服承诺的退款金额、处理时限要保存importance 不低于 4。 3. 一般寒暄、临时语气词不要保存。 4. 如果对话太长优先保存结论不要保存中间推理过程。 对话内容 result llm_client.chat( prompt json.dumps(messages, ensure_asciiFalse) ) return parse_json_array(result.content)写入时机建议放到异步任务里不阻塞用户响应。用户已经等到了客服回复记忆抽取晚 2 秒完成完全没影响。5.3 记忆召回怎么把“相关记忆”找出来召回环节最容易出现两个问题召回太少导致模型失忆召回太多导致上下文污染。最开始不用上向量库先做关键词粗筛加重要度排序。def recall_memories(user_id: str, query: str, top_k: int 5): keywords extract_keywords(query) result [] for memory in load_user_memories(user_id): if any(k in memory.content for k in keywords): result.append(memory) result.sort(keylambda m: (m.importance, m.updated_at), reverseTrue) return result[:top_k]如果项目里已经有 embedding 服务可以升级成向量召回先把 query 转成向量再在向量库里做相似度检索召回后再按重要度过滤。向量召回更适合“语义相关但字面不匹配”的场景比如用户说“上次那个快递”需要匹配到“订单 OD20240415008”。5.4 记忆更新与合并同一个订单的售后进度会多次更新。不能每次都插入新记录否则用户查一次订单就多一条重复记忆召回时全是垃圾。正确做法是按业务主键 upsert。例如售后进度def upsert_order_memory(user_id: str, order_id: str, content: str, importance: int 4): existing find_memory(user_id, forder:{order_id}) if existing: existing.content content existing.importance importance existing.updated_at now() commit() else: insert_memory(user_id, forder:{order_id}, content, importance)这样同一个订单只有一条记忆最新进度替换旧进度召回时不会被历史状态干扰。6. 上下文窗口超限处理6.1 超限报错长什么样模型服务返回的上下文超限错误通常长这样api error: 400 this models maximum context length is 1048576 tokens. however, the total tokens in your request including system, history, memory and user input exceed the limit. context length exceeded (169,692 tokens). cannot compress further.这类错误不是代码 bug而是请求的 Context 已经超过了模型窗口。要把它当成运行时异常来处理而不是启动配置。6.2 为什么上下文会越长越多Context 膨胀通常来自四个来源对话轮次无限累积每次请求都把全部历史塞进 Context。记忆召回过多每次召回 20 条长期记忆每条 200 token就是 4000 token。工具结果直接拼入订单查询返回完整 JSON几千甚至上万 token。系统提示词写得太长把完整业务规则、历史说明全写进 system prompt。超限不是一次性发生的而是随着对话推进逐渐逼近上限。所以要在组装阶段就有预算意识。6.3 分级降级处理方案当 Context 接近窗口上限时按顺序降级优先级策略触发条件效果代价1减少记忆召回条数总 Token 超限立刻减少几千 Token可能遗漏低相关记忆2裁剪历史对话轮次记忆减少后仍超限保留最近对话丢失较早上下文3对历史对话做摘要裁剪后仍超限用几百 Token 概括全量历史细节可能丢失4截断工具结果摘要后仍超限保留工具结论模型看不到细节5拒绝本次请求并提示新会话上面都无效保证响应质量用户需要开新会话降级顺序的原则是优先丢弃“可重新检索”的内容其次丢弃“低价值历史”最后才影响用户当前正在处理的问题。6.4 动态组装上下文的代码实现MAX_CONTEXT_TOKENS 8000 MAX_HISTORY_TURNS 20 MEMORY_TOP_K 5 SYSTEM_PROMPT 你是一个电商客服助手可以查询订单、处理退货。回答要简洁准确。 def build_context(state, memories, user_input): parts [] token_budget MAX_CONTEXT_TOKENS system_token estimate_tokens(SYSTEM_PROMPT) token_budget - system_token # 第一优先级长期记忆可被裁剪 selected_memories memories[:MEMORY_TOP_K] memory_text 长期记忆\n \n.join( f- {m.content} for m in selected_memories ) while estimate_tokens(memory_text) token_budget * 0.3 and selected_memories: selected_memories selected_memories[:-1] memory_text 长期记忆\n \n.join( f- {m.content} for m in selected_memories ) parts.append(SYSTEM_PROMPT) if selected_memories: parts.append(memory_text) token_budget - estimate_tokens(memory_text) # 第二优先级最近对话历史可裁剪 recent_messages state.messages[-MAX_HISTORY_TURNS:] history_text \n.join( f{m.role}: {m.content} for m in recent_messages ) while estimate_tokens(history_text) token_budget * 0.5 and len(recent_messages) 2: recent_messages recent_messages[2:] history_text \n.join( f{m.role}: {m.content} for m in recent_messages ) parts.append(history_text if recent_messages else ) token_budget - estimate_tokens(history_text) # 用户当前输入不可裁剪 parts.append(fuser: {user_input}) return \n\n.join(parts)这个实现体现了两个原则长期记忆可以降级因为它是可重新检索的。用户当前输入不可裁剪因为模型必须回答它。如果裁剪后仍然超限再进入摘要压缩def compress_history(state): recent state.messages[-6:] old state.messages[:-6] if not old: return state summary_text \n.join(f{m.role}: {m.content} for m in old) summary_prompt 把以下客服对话压缩成 200 字以内的摘要保留订单号、地址、承诺金额\n summary_text summary llm_client.chat(summary_prompt).content state.messages [Message(rolesystem, contentf历史摘要{summary})] recent return state摘要层是兜底方案。实际项目里如果每 10 轮就触发摘要说明 MAX_HISTORY_TURNS 设置得太保守应该调小窗口而不是频繁调用摘要模型。7. 把记忆模块接入电商客服完整流程7.1 整体工作链路现在把 Session、Memory、Context 模块串起来。完整链路如下从请求参数获取 session_id没有则创建新 Session。加载 AgentState。根据用户输入召回长期记忆。组装 Context。调用模型得到回复。如果需要查订单执行工具调用拿到订单状态。把订单状态追加到 AgentState。异步抽取长期记忆并写入 MemoryStore。保存 State返回响应。7.2 查询订单的完整代码agent.pydef handle_chat(session_id: str, user_input: str): state get_state(session_id) if state is None: return {error: session expired}, None state.messages.append(Message(roleuser, contentuser_input)) memories recall_memories(state.user_id, user_input, top_kMEMORY_TOP_K) context build_context(state, memories, user_input) response_text llm_client.chat(context).content if 查订单 in user_input or 物流 in user_input: order_id extract_order_id(state, memories, user_input) if order_id: order_result query_order_service(order_id) state.order_result order_result response_text format_order_reply(order_result, response_text) state.messages.append(Message(roleassistant, contentresponse_text)) # 异步写入长期记忆 async_extract_memories(state.user_id, state.messages[-4:]) save_state(state) return response_text, statemain.pyfrom fastapi import FastAPI from pydantic import BaseModel app FastAPI() class ChatRequest(BaseModel): session_id: str | None None user_id: str message: str class ChatResponse(BaseModel): session_id: str reply: str app.post(/chat, response_modelChatResponse) def chat(req: ChatRequest): session_id req.session_id or create_session(req.user_id) reply, _ handle_chat(session_id, req.message) return ChatResponse(session_idsession_id, replyreply)关键点handle_chat 不直接感知 HTTP 层不管是 FastAPI、WebSocket 还是消息队列都能复用同一套逻辑。7.3 运行验证与预期输出启动服务uvicorn app.main:app --host 0.0.0.0 --port 8000第一次对话curl -X POST http://localhost:8000/chat \ -H Content-Type: application/json \ -d {user_id: user_001, message: 我叫李四订单 OD20240415008 想退货退货地址是什么}预期输出{ session_id: session_1715000000000, reply: 李四您好订单 OD20240415008 的退货地址是浙江省杭州市西湖区...请将商品原包装寄回。 }隔一天后不带订单号再问curl -X POST http://localhost:8000/chat \ -H Content-Type: application/json \ -d {user_id: user_001, session_id: session_1715000000000, message: 我把那个退货寄走了地址没问题吧}如果长期记忆生效Agent 应该能通过 user_id 找到订单号不需要用户重新提供。这个验证非常关键它证明的不是模型能力而是记忆系统真的在工作。8. 常见问题与排查清单8.1 高频报错与处理问题现象常见原因检查方式处理建议maximum context length 报错Context 中历史对话和记忆累积过多打印组装后的 context token 数按 6.3 的降级策略裁剪节点函数改了 state 但没生效LangGraph 节点没有返回增量 dict检查节点 return 值返回 {field: new_value}用户 A 的数据出现在用户 B 的回复里Redis key 或查询条件漏了 user_id检查 Session key 和 SQL 条件所有 key 都带上 user_idSession 过期后聊一半状态丢失TTL 太短或前端没传 session_id看 redis ttl 日志调大 TTL同时做状态落库召回记忆太多上下文被污染MEMORY_TOP_K 过大或关键词太宽打印召回的记忆内容调小 top_k增加重要度过滤同一订单多条重复记忆没有做 upsert查询 memory 表按业务主键 upsert8.2 四步排查链路遇到 Agent 记忆不生效按顺序排查输入侧确认请求是否带了正确的 session_id 和 user_id。很多“记忆丢失”其实是 session_id 每次都在变。会话侧确认 Redis 里 Session 状态是否还在。redis-cli get session:session_1715000000000 redis-cli ttl session:session_1715000000000记忆侧确认长期记忆是否真的写入了。sqlite3 agent_memory.db select * from memory where user_iduser_001 order by created_at desc limit 5;上下文侧确认组装后的 Context 是否包含召回记忆。可以在 context.py 里加一个 debug 开关打印 memory_text 和 history_text而不是只打印最终回复。排查顺序一定是从输入到存储再到组装不要一开始就怀疑模型。模型不记得大概率是没喂进去不是模型智商问题。8.3 可复用检查清单[ ] session_id 是否由服务端生成并稳定返回。[ ] AgentState 中的 messages 是否有长度上限。[ ] 长期记忆是否按 user_id 隔离。[ ] 记忆写入是否走异步链路避免拖慢主流程。[ ] 上下文组装时是否有 token 预算。[ ] 超限时是否有明确的降级顺序。[ ] 订单号、地址等关键字段是否做了归一化避免同义重复。[ ] Session 是否设置了 TTL且 TTL 是否匹配业务空闲容忍度。[ ] 是否记录了上下文使用率指标用于提前发现膨胀趋势。9. 生产环境最佳实践与扩展方向9.1 上线前要做的五件事开发环境跑通只是第一步生产环境还差得很远。上线前重点处理第一记忆写入异步化。模型响应后先返回给用户再进入记忆抽取和写入队列避免用户等待额外 1 到 2 秒。异步写入要保证幂等同一个订单的更新要么用 upsert要么在消息队列里做去重。第二敏感信息脱敏。客服助手会接触到手机号、地址、支付信息。入库前对手机号做掩码例如138****1234完整信息只保存在业务系统不进入 Agent 长期记忆。这样即使记忆库泄露损失也被限制住。第三监控上下文使用率。记录每次请求的 total_tokens、context_token、memory_tokens、history_tokens。如果 context_token 长期超过限制的 80%说明需要调小历史窗口或增加摘要触发频率。第四设计遗忘机制。长期记忆不能只增不减。对 importance 较低的记忆设置过期时间比如普通会话摘要保留 30 天重要业务事实保留 180 天。超出时限的自动归档或删除。第五准备手动清理工具。客服运营人员需要能查看某个用户记住了什么也能手动删除错误记忆。否则错误的记忆一旦写入会在后续对话中反复污染回答。9.2 扩展方向向量检索、记忆反思、多级记忆当前例子用的是关键词召回适合起步。后面可以逐步升级。向量检索当记忆条数超过几千条后关键词召回会漏掉很多语义相关的记忆。可以引入 embedding 模型把记忆内容转成向量再用向量相似度召回。记忆表和向量库通过 memory_id 关联长期记忆以数据库为主向量只作为索引。记忆反思定期对用户的原始记忆做一次归纳把“订单 OD20240415008 退货”“订单 OD20241111002 换货”合并成“该用户近期有两次售后偏好选择退货处理”。这种归纳后的记忆比原始碎片更有业务价值。多级记忆可以进一步拆分出工作记忆、情景记忆和语义记忆。工作记忆就是当前 Session 的 State情景记忆是具体事件语义记忆是用户画像和偏好。每一级的存储策略、召回权重、过期时间都不同适合用户量较大的生产项目。如果刚开始做 Agent 开发可以按“提示词工程 - 工具调用 - 记忆管理 - 多 Agent 协作”的路线推进。记忆管理放在工具调用之后因为只有先掌握工具调用才知道有哪些业务数据可以沉淀。Agent 是否“越用越聪明”不取决于模型参数规模取决于记忆架构能否把短期状态、长期存储和上下文窗口组织成闭环。先给 Session 加上 TTL给 Memory 加上分类给 Context 加上 token 预算跑通最小闭环后再逐步加入向量检索和记忆反思。这套能力会让你的客服助手从“每次都重新认识用户”进化成“越聊越懂用户”。

相关新闻

2026/8/31 13:08:33

holaOS深度解析:AI智能体平台的部署与验证指南

最近在关注本地部署和 AI 智能体方向的读者,可能已经在 GitHub 趋势或者技术社区里刷到过holaboss-ai / holaOS这个名字。从项目命名看,它明显不是普通的模型仓库,而是一个偏“操作系统 / 智能体平台”方向的工程化项目,目标更像是…

2026/8/31 13:08:33

自研缝纫机器人软硬协同设计:四层架构与事件驱动实战

在自研电脑缝纫机和缝纫机器人的项目里,最难的往往不是单个电机能不能转,而是机械结构、硬件控制板、嵌入式固件和工艺设计系统之间如何咬合在一起。一个完整缝制工艺通常包含起针、送布、转角、剪线、抬压脚、断线检测等动作,任何一个环节出…

2026/8/31 13:08:33

1.8万 Star 的 GPT-Image-2 实战案例库:从提示词到落地工作流

一个整理了 532 个 GPT-Image-2 实战案例的 GitHub 项目,目前已经有 18645 个 Star。这类项目在图像生成工具越来越普及的时候特别有用,因为它整理的不是抽象功能介绍,而是别人拿这个模型真实做过什么、怎么做的、做出来长什么样。如果你正在…

2026/8/31 13:18:34

CNN卷积神经网络零基础入门:PyTorch实现MNIST图像分类

CNN 卷积神经网络是深度学习入门绕不开的第一座山。很多零基础读者第一次接触 CNN 时,被卷积、池化、全连接、特征图、感受野这些名词劝退,但实际上它的设计逻辑非常朴素:让网络像人眼看图一样,先从局部细节开始识别,再…

2026/8/31 13:18:33

JMeter接口测试与性能测试实战:从核心原理到项目落地

很多人在初学接口测试和性能测试时,最先遇到的问题往往不是工具本身,而是不知道从哪儿下手。网上关于 JMeter 的资料并不少,但大多是零散的片段:今天看到一个教程讲如何加 HTTP 请求,明天又看到一个帖子讲参数化&#…

2026/8/31 13:18:33

Zabbix与Prometheus监控体系实战:从部署到告警全解析

做运维这几年一个很深的体会:监控不是“装个工具”就结束了,而是要把数据采集、集中存储、可视化展示、告警通知这一整条链路真正跑通。很多公司一开始只是给服务器加了个 CPU、内存监控,等线上真的出故障时才发现:数据粒度太粗、…

2026/8/31 13:18:33

JeecgBoot RAG知识库快速上手:3步建库、关联应用,附5个避坑点

JeecgBoot RAG知识库快速上手:3步建库、关联应用,附5个避坑点 【免费下载链接】jeecg-boot 【低代码v2.0,一句话即可生成整个系统】企业级AI低代码平台,一键生成前后端代码甚至整个系统。 AI Skills 一句话画流程、设计表单、生成…

2026/8/31 13:13:33

餐厅点餐系统Java课程设计:面向对象建模与全流程实现指南

简介:本资源是面向计算机类专业本科生的软件工程课程期末大作业参考方案,聚焦餐厅自助点餐系统开发全过程,以面向对象方法为核心,覆盖需求分析、系统设计、可行性论证、测试验证及基础界面实现五大关键环节,有效解决课…

2026/8/31 1:05:20

vSound小提琴数字处理器实操指南:从接线到演出的完整配置

电小提琴或者原声小提琴插电演出,第一个绕不开的坎就是声音难听。原声琴的共鸣和空气感一旦进了拾音器,出来的往往是一坨干瘪、发尖、带着奇怪塑料味的信号。我当初第一次把琴接上乐队调音台,直接被主唱吐槽"你这声音像在锯钢丝"。…

2026/8/31 2:14:20

传感器接口IC如何攻克生物化学传感的微弱信号难题?

1. 从电极到比特流:为什么生物化学传感必须依赖专用接口IC 做生物化学传感的人都有过类似的经历:明明传感器本身性能很好,信号输出却一塌糊涂——噪声大、漂移明显、重复性差,怎么调都达不到预期。很多时候问题并不在传感器&#…

2026/8/31 1:41:28

STM32F411CEU6多通道ADC采集:扫描模式+DMA实现详解

1. 多通道 ADC 的用武之地把“Multichannel ADC”和“STM32F411CEU6”这两个关键字放在一起,其实就是嵌入式开发里最常遇到的一类需求:用一块不算贵的 MCU,同时采集多路模拟信号。STM32F411CEU6 是 48 引脚的 Cortex-M4F 主控,主频…

2026/8/31 0:07:32

STM32C5设备支持包(IAR DFP)安装指南与常见坑

上一阵子在IAR里折腾一块基于STM32C5系列的新板子,工程从STM32CubeMX导出来之后怎么都编译不过。报错信息很干脆:找不到设备描述文件。跟着错误路径去查,发现指向的是一个让我愣了一下的名字:STMicroelectronics.stm32c5xx.2.1.0.…

2026/8/31 0:07:32

STM32N657 SWO引脚矛盾:CubeMX显示PB3,数据手册为PB5

拿到STM32N657这颗料的第一天,我就撞上了一个让人原地懵圈的引脚矛盾:CubeMX里清清楚楚显示SWO在PB3,翻开数据手册的引脚说明表,却赫然写着PB5。对于一个靠SWO输出调试日志吃饭的人而言,这种"工具和手册打架"…

2026/8/31 12:44:45

实测才敢推 AI论文网站 2026最新测评与推荐

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。一、综…

2026/8/31 9:19:59

2026必备!AI论文网站测评:最新推荐与深度对比

2026年真正好用的AI论文网站,核心看生成的论文质量、低AI味、格式正确、学术适配四大指标。综合实测,千笔AI、ThouPen、豆包、DeepSeek、Grammarly 是当前最值得推荐的梯队,覆盖从免费到付费、从中文到英文、从文科到理工的全场景需求。 一、…

2026/8/31 6:53:02

摆脱论文困扰!盘点2026年全网爆红的的AI论文写作工具

一天写完毕业论文在2026年已不再是天方夜谭。2026年最炸裂、实测能大幅提速的AI论文写作工具,覆盖选题构思、文献整理、内容生成、格式排版等核心场景,真正帮你高效搞定论文难题。 一、全流程王者:一站式搞定论文全链路(一天定稿首…