
Claude Managed Agents 如何记住用户偏好memory store 跨会话记忆实践【免费下载链接】claude-cookbooksA collection of notebooks/recipes showcasing some fun and effective ways of using Claude.项目地址: https://gitcode.com/GitHub_Trending/an/claude-cookbooksClaude Managed AgentsCMA里的很多 agent 每开一次会话都从零开始客户刚在购物助手里说过自己的尺码、预算和想避开的面料下次回来又要重说一遍体验显得泛而不专。Memory store 就是为了解决这一点——你可以给每个用户挂一个专属的笔记本Claude 在会话中把相关信息记下来下一次同一个用户再来时这些笔记仍然在。这篇实战文章基于仓库里的 CMA_remember_user_preferences.ipynb用一个零售品牌的购物助手串起完整的跨会话记忆流程建一个 memory store、把它挂到会话里、让 agent 学习并自动召回偏好最后从你自己的应用侧读取、修正这些记忆。前提条件开始前需要具备一个可访问 Claude Managed Agents beta 的 Anthropic API key设置为环境变量ANTHROPIC_API_KEY。Python 3.11仓库 pyproject.toml 把 Python 版本限定在3.11,3.13。Anthropic Python SDK 的较新发行版。notebook 前置条件给出的安装命令是uv add anthropic # 或pip install -U anthropicBeta 特性。Memory store 属于 Claude Managed Agents 的公开 betaAPI 在正式发布前可能变化。Python SDK 会为client.beta下的每个方法自动加上所需的anthropic-beta请求头你不需要手动处理。关于 SDK 版本有一个文档层面的差异值得留意notebook 里的单元格实际安装的是anthropic0.91.0而仓库 pyproject.toml 声明的是anthropic0.109.0。两者都要求较新的 SDK 才能用 memory store 方法本文以较新的0.109.0作为建议目标。Memory store 挂载到会话后会以一个目录的形式出现在 agent 环境里的/mnt/memory/{store-name}Claude 用它的标准文件工具读写那里的文件。你的应用则通过 REST API 对同一批文件拥有完整的读写权限可以用来预置已知事实、审计 agent 写了什么、或把内容导出到你自己的系统。初始化客户端与一个回合辅助函数先初始化客户端。模型名取自环境变量COOKBOOK_MODEL默认是claude-sonnet-4-6见 notebook 中的MODEL os.environ.get(COOKBOOK_MODEL, claude-sonnet-4-6)。wait_for_idle_status来自仓库共享工具 utilities.pyimport os from anthropic import Anthropic from utilities import wait_for_idle_status MODEL os.environ.get(COOKBOOK_MODEL, claude-sonnet-4-6) client Anthropic()Managed agent 会话是事件驱动的你发一条用户消息然后流式接收事件直到会话回到 idle。为了可读性把这段发消息—流式等 idle的循环包进一个辅助函数run_turn它打印 agent 的回复并标出它访问/mnt/memory/下的每次读写def run_turn(session_id: str, user_text: str) - str: 发送一条用户消息流式接收 agent 回复直到 idle。 返回 agent 的完整文本回复供需要程序化使用的调用方。 print(f\n[user] {user_text}) reply_parts: list[str] [] with client.beta.sessions.events.stream(session_id) as stream: client.beta.sessions.events.send( session_id, events[ { type: user.message, content: [{type: text, text: user_text}], } ], ) for event in stream: if event.type agent.message: for block in event.content: if block.type text: reply_parts.append(block.text) print(f[agent] {block.text}) elif event.type agent.tool_use: # 把对 memory 挂载点的读写显式打出来方便看到 agent 在查和写记忆 inp event.input or {} target inp.get(file_path) or inp.get(command, ) if /mnt/memory/ in str(target): print(f [memory] {event.name}: {target}) elif event.type session.status_idle: # 遇到任意 idle 原因都 break防止意外的 stop_reason 让循环挂死 break elif event.type session.status_terminated: break wait_for_idle_status(client, session_id) return .join(reply_parts)wait_for_idle_status会轮询到会话的服务器端状态字段变为idle。notebook 里特意用它来吸收一个竞态session.status_idle事件可能在sessions.retrieve报告status idle之前到达如果紧接着就archive()会返回 400。清理一节会用到它。步骤 1创建 memory storememory store 是一个存放文本文件、按 workspace 隔离的具名容器。生产里你通常给每个终端用户建一个 store并在自己的数据库里维护用户 ID → store ID的映射。你在这里设置的description会在 store 被挂载时渲染进 agent 的系统提示所以用它来告诉 Claude 这个 store 是干什么的store client.beta.memory_stores.create( nameShopper Preferences, description( Personal shopping preferences for a single customer: sizes, style, budget, favorite brands, and materials to avoid. ), ) print(store.id) # 示例输出memstore_01NKkumXZXY8mEhoRA3xhBvNstore.id形如memstore_...后面创建会话时要用到它。步骤 2定义带文件工具的 agent 与环境每个 managed agent 会话都需要一个agent模型、系统提示、工具和一个environmentagent 运行的容器。这两个可以只创建一次在多个客户和多个会话之间复用。给 agent 内置的agent_toolset——它包含了读写记忆所需的文件工具。agent_toolset_20260401这个类型字符串是 toolset 的 API 标识符不是模型别名所以后续出了新模型也不用改它environment client.beta.environments.create( nameshopping-demo, config{type: cloud, networking: {type: limited}}, ) agent client.beta.agents.create( namePersonal Shopper, modelMODEL, system( You are a personal shopping assistant for a retail brand. Help the customer find products that match their taste and budget, and remember what you learn about them for future visits. ), tools[ { type: agent_toolset_20260401, default_config: { enabled: True, permission_policy: {type: always_allow}, }, } ], ) print(agent.id) # 示例输出agent_011CaMbJoHMUyR5TjeFDtMG9步骤 3首次会话——让 agent 学习偏好现在创建一个会话通过resources数组把 memory store 挂进去。instructions字段是每次挂载级别的指引告诉 Claude 在本次会话里如何使用这个特定的 store。因为是这位客户的首次到访store 是空的。观察输出里的[memory]行agent 会先检查 store、发现还没有内容然后写下一个新文件来记录它学到的东西memory_resource { type: memory_store, memory_store_id: store.id, access: read_write, instructions: ( This customers personal preferences: sizes, style, budget, and materials to avoid. Check it at the start of every conversation and update it whenever you learn something new. ), } session_one client.beta.sessions.create( agent{type: agent, id: agent.id, version: agent.version}, environment_idenvironment.id, resources[memory_resource], ) # 响应会告诉你 store 在 agent 环境里挂载到了哪里 for resource in session_one.resources: if resource.type memory_store: print(fMounted at {resource.mount_path})创建会话的响应会告诉你 store 在 agent 环境里的挂载路径。notebook 展示的示例输出是Mounted at /mnt/memory/shopper-preferences接着让这位客户第一次开口说清自己的偏好run_turn( session_one.id, Hi! Im looking for a new jacket. A few things about me: I wear a size medium, I only buy vegan leather (no animal leather please), my budget is usually under $200, and I love earth tones. What would you suggest?, )下面是一段示例输出具体商品名、价格、品牌都是 LLM 当次生成的不要当作固定结果关键看其中[memory]行——它们表明 agent 确实在检查 store 并写入新文件[user] Hi! Im looking for a new jacket. A few things about me: ... [agent] Let me check if I have any info about you on file, and save your preferences right away! [memory] bash: cat /mnt/memory/shopper-preferences 2/dev/null || echo No file found [memory] write: /mnt/memory/shopper-preferences [memory] write: /mnt/memory/shopper-preferences/preferences.md [agent] Ive saved your preferences for future visits! Now, here are some great **vegan leather jacket picks in earth tones under $200** ...步骤 4从应用侧检查 agent 写了什么agent 写到挂载点里的每个文件都是一个普通的 memory 文档你的应用可以通过 API 读取、编辑或删除。用viewfull列表时响应里会带上文件内容page client.beta.memory_stores.memories.list( store.id, viewfull, ) for memory in page.data: if memory.type memory: print(f {memory.path} ) print(memory.content) print()这就是你构建我们对你了解到的信息页面、把记忆同步进自己的数据库、或让人工审校纠正 agent 记错的依据。示例输出文件名和内容结构都是 Claude 自己选的不一定每次相同 /preferences.md # Shopper Preferences ## Sizes - Tops/Jackets: Medium ## Style - Loves earth tones (browns, tans, olive, terracotta, camel, rust, etc.) - Interested in jackets ## Budget - Usually under $200 ## Materials - VEGAN LEATHER ONLY — absolutely no animal leather - (No other material restrictions noted yet) ## Favorite Brands - None noted yet ## Other Notes - First visit; preferences collected 2026-04-23你能看到一份按主题组织的文件通常是/preferences.md之类里面是这位客户提到的尺码、预算、面料和颜色偏好。步骤 5再次会话——同一 store自动召回这是最关键的一步。创建一个全新的会话挂上同一个 memory store。这次客户没有重复任何偏好但 agent 会从记忆里读出来并据此调整推荐。session_two client.beta.sessions.create( agent{type: agent, id: agent.id, version: agent.version}, environment_idenvironment.id, resources[memory_resource], # 同一个 store新会话 ) run_turn( session_two.id, Hey, Im back! I need a bag for work. Any recommendations?, )示例输出推荐内容同样是 LLM 当次生成不要当作固定结果。注意 agent 在作答前先读了/mnt/memory/shopper-preferences/然后给出的是纯素皮革、大地色系、$200 以内的推荐——尽管这条消息里一个都没提[user] Hey, Im back! I need a bag for work. Any recommendations? [agent] Welcome back! Let me check your preferences before making any recommendations! [memory] read: /mnt/memory/shopper-preferences [memory] bash: ls /mnt/memory/shopper-preferences/ [memory] read: /mnt/memory/shopper-preferences/preferences.md [agent] Great news — I already have your preferences on file! Heres what I kept in mind for you: - **Style:** Earth tones (browns, tans, olive, camel, etc.) - **Budget:** Under $200 - **Materials:** Vegan leather only — no animal leather ...在输出里agent 先read/ls挂载目录再作答推荐项都落在纯素皮革、大地色、$200 以内——这些偏好是从第一次会话跨过来的就是跨会话记忆生效的直接证据。进阶预置、共享 store 与审计从已有数据预置 store可选分支。如果你已经知道一些关于客户的信息来自账号资料或购买历史可以在第一次会话前把它们写进 store让 agent 一开始就有上下文。真实应用里这个预置步骤应该在任何会话创建之前运行notebook 把它放在演示之后只是为了让上面的学习→召回主流程保持聚焦seeded client.beta.memory_stores.memories.create( store.id, path/purchase-history.md, content( ## Recent purchases\n - Canvas tote, olive, $89 (Jan 2026)\n - Wool beanie, rust, $34 (Dec 2025)\n ), ) print(fSeeded {seeded.path})提示由于结尾的清理单元格会删除store这段预置代码要在清理单元格之前运行。组合按客户和共享的 store。一个会话最多可以挂 8 个 memory store每个 store 有各自的访问级别。一种常见做法是每个客户一个可读写的 store再加一个所有会话共享的、品牌级只读 store如当前促销、尺码指南、库存说明catalog client.beta.memory_stores.create( nameProduct Catalog Notes, descriptionCurrent promotions, sizing guidance, and stock notes., ) session client.beta.sessions.create( agent{type: agent, id: agent.id, version: agent.version}, environment_idenvironment.id, resources[ { type: memory_store, memory_store_id: store.id, access: read_write, instructions: This customers personal preferences., }, { type: memory_store, memory_store_id: catalog.id, access: read_only, instructions: Brand-wide product guidance. Consult before recommending items., }, ], ) # 用完记得清理 catalog store # client.beta.memory_stores.delete(catalog.id)审计与修正。对 memory store 的每次写入都会记录为一个不可变版本并带上产生它的会话。用client.beta.memory_stores.memory_versions.list(...)查看历史用client.beta.memory_stores.memories.update(...)修正 agent 记错的文件。清理资源最后删除这次跟做过程中创建的资源。注意这段代码有实际副作用archive会把两个会话归档delete会删除 memory storearchive还会归档 agent 和 environment——只影响本文示例中你刚创建的这些对象。开头提到的wait_for_idle_status就是用来在归档前吸收status 还在 running 就 archive 会 400的竞态wait_for_idle_status(client, session_one.id) wait_for_idle_status(client, session_two.id) client.beta.sessions.archive(session_one.id) client.beta.sessions.archive(session_two.id) client.beta.memory_stores.delete(store.id) client.beta.agents.archive(agent.id) client.beta.environments.archive(environment.id)适用边界Memory store 处于 Claude Managed Agents 公开 betaAPI 在正式发布前可能变化。store 内的文件名和结构如/preferences.md由 Claude 自己选择不同运行会不同本文出现的文件内容、推荐商品、价格、品牌都是 notebook 的示例输出不要当作每次必得的固定结果。agent_toolset_20260401是 toolset 的 API 标识符而非模型别名跨新模型无需更新MODEL默认claude-sonnet-4-6可由COOKBOOK_MODEL覆盖才是模型名两者不要混为一谈。完整的 API 细节可参考 CMA_remember_user_preferences.ipynb以及 utilities.py 里的流式回合与 idle 轮询辅助函数。【免费下载链接】claude-cookbooksA collection of notebooks/recipes showcasing some fun and effective ways of using Claude.项目地址: https://gitcode.com/GitHub_Trending/an/claude-cookbooks创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考