跳至内容

Supermemory 教程:为 AI 代理添加持久化记忆

使用 Python 构建一款训练助手,记录训练、借助 Supermemory 记住用户历史,并在多次独立运行的 AI 代理中给出个性化训练建议。
更新 2026年5月11日  · 15分钟

大多数LLM 代理每次运行都会从零开始。它们会忘记用户的名字、上次对话,以及正在处理的文件。任何与用户相关的内容都需要一轮一轮地重新建立。

本教程为代理添加持久化记忆,让下一次运行从上一次结束的地方继续。记忆层使用Supermemory,这是一个托管的API,用一次调用就能存储并返回用户级别的事实。您将用 Python 构建一位私人训练助手。该代理记录训练、给出下一次训练建议,并在脚本的多次独立运行中记住偏好与近期举重记录。

技术栈很精简。Supermemory 负责记忆;OpenAI Agents SDK 负责代理循环。训练助手由两个 Python 文件和一个pyproject.toml 文件组成。

您需要 Python 3.10 或更高版本、一个 OpenAI 账户、一个 Supermemory 账户,以及对命令行的基本熟悉。

什么是 Supermemory?

最贴切的描述是:Supermemory 是面向代理的 AI 记忆 API。您将关于用户的字符串交给 Supermemory,之后它会返回该用户的简洁画像:他们是谁、最近在做什么。嵌入、索引与检索都在 Supermemory 内部完成,因此您的代理代码保持精简。

LongMemEval 基准测试记忆系统在长对话历史上回答问题的能力。Supermemory 能回忆出 81.6% 的正确信息。下一名 Zep 得分为 71.2%,10 个百分点的差距意味着每 10 个用户问题多答对约 1 个。其开源仓库拥有 22k+ GitHub stars,也是其真实使用度的一个信号。

记忆 vs RAG

大多数在寻找代理记忆工具的读者之前都用过RAG。我们可以将 Supermemory 与它并列来看。RAG 与记忆解决的是不同的问题,而且它们常常共存于同一个代理中。

RAG 系统指向开发者预先准备的一套文档语料:产品手册、支持文章、内部文档。语料在部署时加载、运行时查询,且很少变动。代理用它来回答产品本身就知道答案的问题。

记忆系统指向用户。Supermemory 会在代理与用户对话时写入用户特定的事实,并随着每次对话而增长。代理用它来回答只有用户才能回答的问题,比如偏好、历史与近期活动。

Title: Memory vs. RAG: where the data comes from - Description: Memory vs. RAG: where the data comes from

在真实产品中,两者并行。基于公司知识库的 RAG 回答“我们的退款政策是什么?”。基于 Supermemory 的用户记忆回答“我上周的卧推是多少?”。同一个代理,两个数据源,各司其职。

用户画像:静态事实与动态事实

Supermemory 的核心概念是用户画像。每条日志都会被分入两类:很少变化的静态事实,以及关于当前活动的动态事实。反复出现的模式会被提升为静态;近期活动则留在动态中。

当代理读取画像时,一次调用会返回这两类内容以及匹配的记忆片段。

这种拆分很重要,因为静态和动态事实可以回答关于同一用户的不同问题:

静态事实

动态事实

在家训练,器械为哑铃和引体向上杆

当前重点:上肢力量

左膝受伤,避免深蹲

上次卧推:185 磅,4 组,每组 5 次

希望年底前卧推增加 20 磅

本周在做“润滑沟槽式”引体向上练习

只在晚上训练,从不在早晨

昨天 5 公里跑用时 28 分钟

看第一行。静态侧描述用户如何训练:在家、用自己的器械。这个信息周与周之间不会变。动态侧描述他们当下在做什么:本周期专注上肢。

一个训练建议器需要两者兼备。静态侧排除只能在健身房完成的动作,动态侧决定今天的训练安排。

在画像背后,Supermemory 还替您完成四项本该由您构建的工作:存储原始记忆、为每个片段做嵌入、读取时执行相似度搜索、并从日志内容中抽取画像事实。这四项都不会出现在您的代码里。

Title: What Supermemory handles for you - Description: What Supermemory handles for you

每条记忆都会打上开发者自定义的字符串标签。每次读取都会回传同一个字符串,以限制输出范围。本教程的训练助手硬编码了一个标签,因为一个用户足以展示画像的作用。真实应用会根据已认证的用户来计算标签,比如他们的 JWT。

设置您的 Supermemory 环境

训练助手需要两个 API 密钥(Supermemory 和 OpenAI)以及一个包含三个依赖的 Python 项目。在编写任何代理代码前,先用一个往返脚本验证两个密钥可用。

获取 API 密钥

Supermemory 的 API 密钥在 console.supermemory.ai,不app.supermemory.aiapp 子域是面向消费者的记忆产品(用于保存笔记、浏览您的空间)。它没有 API 密钥页面。请跳过它,直接进入控制台。

console.supermemory.ai 上:

  1. 登录。

  2. 点击侧边栏中的 API Keys

  3. 点击 Create API Key

  4. 为其命名(本教程的训练助手使用 datacamp-tutorial)。

  5. 复制生成的密钥。它以 sm_ 开头。

Title: Supermemory developer console showing the API Keys page - Description: Supermemory developer console showing the API Keys page

您还需要一个 OpenAI 密钥以供代理进行 LLM 调用。如果还没有,请前往 platform.openai.com/api-keys 获取。

在项目根目录创建一个 .env 文件并写入两个密钥。不要将其提交到仓库。

SUPERMEMORY_API_KEY=sm_your_key_here
OPENAI_API_KEY=sk-your_key_here

Supermemory 的免费层可覆盖本教程,无需填写支付信息。具体配额请参见定价页面

安装依赖

本教程使用 uv 来进行项目初始化与运行。如果您尚未安装 uv,请按照 astral.sh/uv 的一行命令安装。

初始化项目:

uv init supermemory-trainer
cd supermemory-trainer

删除 uv init 自动生成的 README.md。自动生成的 hello.py 将在下一步被覆盖,暂时保留即可。

添加三个依赖:

  • supermemory==3.37.0 是记忆客户端,版本固定为本教程验证过的版本。

  • openai-agents 是 OpenAI Agents SDK。包名使用连字符,导入路径为 agents

  • python-dotenv 用于读取您刚创建的 .env 文件。

uv add supermemory==3.37.0 openai-agents python-dotenv

最终的 pyproject.toml

[project]
name = "supermemory-trainer"
version = "0.1.0"
description = "Personal exercise trainer agent built with Supermemory and the OpenAI Agents SDK."
requires-python = ">=3.10"
dependencies = [
	"openai-agents>=0.10.2",
	"python-dotenv>=1.2.1",
	"supermemory==3.37.0",
]

验证环境配置

在编写任何代理代码之前,先让 Supermemory 在单句文本上跑通一遍。下面的脚本向 Supermemory 发送一个事实,等待流水线处理后,再把画像读出来。如果能够顺利运行,说明密钥有效且 SDK 可达。输出也能让您先了解 Supermemory 如何处理原始文本。

在项目根目录打开 hello.py,用以下导入与写入调用替换自动生成的主体:

import time
 
from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
 
client = Supermemory()
USER_ID = "demo_warmup"
 
response = client.add(
	content="The user is learning Supermemory by building a personal trainer agent.",
	container_tag=USER_ID,
)
print(f"client.add() -> id={response.id} status={response.status}")

load_dotenv() 会在构造 Supermemory() 之前,将 API 密钥从 .env 读取到环境变量中。客户端会自动读取 SUPERMEMORY_API_KEYcontainer_tag="demo_warmup" 用于将这一条事实限定到一个一次性用户。

现在在同一文件底部添加等待与读取:

print("Waiting 20 seconds for processing...")
time.sleep(20)
 
prof = client.profile(container_tag=USER_ID, q="learning")
print(f"profile.static  ({len(prof.profile.static)}): {prof.profile.static}")
print(f"profile.dynamic ({len(prof.profile.dynamic)}): {prof.profile.dynamic}")
print(f"search_results.results ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:3]:
	print(f"  - {r['memory']} (similarity={r['similarity']:.3f})")

睡眠 20 秒是为了让 Supermemory 的嵌入与抽取流水线处理新记忆。否则读取会返回空结果,脚本看起来像是坏了,其实不是。

运行该文件:

uv run python hello.py

预期输出:

client.add() -> id=zNLsJBrY1PZupAeZ3Qn6EL status=queued
Waiting 20 seconds for processing...
profile.static  (0): []
profile.dynamic (1): ['Building a personal trainer agent to learn Supermemory.']
search_results.results (1):
  - Building a personal trainer agent to learn Supermemory. (similarity=0.650)

此输出中有三点值得注意。client.add() 会立即返回 status="queued",因为 Supermemory 会异步处理文档。20 秒等待覆盖了嵌入与抽取流水线。到读取执行时,这句原始语句已经成为一个可搜索的记忆片段。

更有意思的是 profile.dynamic。输入是句子“The user is learning Supermemory by building a personal trainer agent.”,输出是动态事实 'Building a personal trainer agent to learn Supermemory.'。Supermemory 将第三人称的句子改写成了关于用户的第一人称事实——这正是画像抽取器在工作。

profile.static 是空列表。静态事实的整合需要时间,通常要积累几条相关日志,因此一次热身写入不会产生静态项。训练助手的建议工具考虑到了这一点,将 static 视为加分项而非必然项。

构建 Supermemory 代理:用 Python 开发私人训练助手

训练助手将 client.add()client.profile() 封装为两个代理工具,因此当用户聊天时,读写会自动发生。训练历史非常适合放入记忆:器械、伤病与近期举重并不存在于 LLM 的训练数据里,而且是会一场场积累的。

Title: Where Supermemory plugs into the agent loop - Description: Where Supermemory plugs into the agent loop

项目结构与代理

训练助手足够小,整个项目只需要两个 Python 文件,加上您已经有的 pyproject.toml

supermemory-trainer/
├── .env            	# your real keys (gitignored)
├── .env.example    	# placeholders, committed
├── .gitignore
├── .python-version
├── main.py         	# agent definition, system prompt, REPL loop
├── pyproject.toml
└── tools.py        	# log_workout and suggest_next_session

tools.py 保存接下来要编写的两个记忆支持工具。 log_workout 通过 client.add() 向 Supermemory 写入训练记录。 suggest_next_session 通过 client.profile() 读取用户画像。 main.py 导入二者并组装代理。

多数 main.py 都是 OpenAI Agents SDK 的样板代码。系统提示中的一句话完成了 Supermemory 相关的约束:所有关于用户的事实必须通过工具调用返回。代理被声明自己没有记忆。这条规则让训练助手具备了记忆支撑。

打开 main.py,先添加导入与系统提示:

import asyncio
 
from agents import Agent, Runner, SQLiteSession
 
from tools import log_workout, suggest_next_session
 
SYSTEM_PROMPT = """You are a personal exercise trainer who logs the user's
workouts and recommends what to do next.
 
You have no memory of the user's history on your own. Every fact about the
user lives in Supermemory and reaches you only through tool calls.
 
Two rules, no exceptions:
 
1. Whenever the user reports completing a workout, call log_workout immediately, before responding. Extract the exercise, sets, reps, weight, and any notes from what they said. If a value is missing, ask one short follow-up question instead of guessing. After logging, confirm in one short sentence and stop. Do NOT recommend the next session unless the user asks for one.
 
2. When the user explicitly asks what to do next (or asks for a recommendation, suggestion, or plan), call suggest_next_session first. Never recommend from your own training data. The tool returns the user's
 recent activity, stable preferences, and matching past sessions. Reference those facts directly in your reply.
 
Keep replies concise (2-4 sentences). Be specific: name the exercise, sets, reps, and weight. Honor any injuries or equipment constraints the tool surfaces.
"""

系统提示中的两条规则都会将模型引导至 Supermemory。

规则 1 强制在用户报告训练完成时调用 log_workout,确保每次训练都写入记忆库。规则 2 强制在做出任何建议之前调用 suggest_next_session,确保每条建议都以 Supermemory 的认知为基础。

如果跳过这些规则,代理会用自己的训练数据作答,从而违背了记忆层的初衷。

现在在同一文件中定义代理与聊天循环:

def build_agent() -> Agent:
	return Agent(
    	name="Trainer",
    	instructions=SYSTEM_PROMPT,
    	tools=[log_workout, suggest_next_session],
    	model="gpt-5",
	)
 
 
async def chat() -> None:
	agent = build_agent()
	session = SQLiteSession(session_id="trainer-cli")
 
	print("Trainer ready. Type a message, or 'exit' to quit.\n")
	while True:
    	try:
        	message = input("You: ").strip()
    	except (EOFError, KeyboardInterrupt):
        	print()
        	break
    	if not message:
        	continue
    	if message.lower() in {"exit", "quit"}:
        	break
 
    	result = await Runner.run(agent, message, session=session)
    	print(f"\nTrainer: {result.final_output}\n")
 
 
if __name__ == "__main__":
	asyncio.run(chat())

其中两行尤为关键。tools=[log_workout, suggest_next_session] 注册了两个记忆支持工具。每个工具(位于 tools.py 中)的 @function_tool 装饰器告知 SDK 它们可被调用。没有装饰器,即使构造调用成功,运行时代理也没有可用工具。

SQLiteSession(session_id="trainer-cli") 在当前 Python 进程内保留短期轮次历史。Supermemory 则跨进程保存长期的用户事实。关闭 Python 进程会丢弃 SQLite 会话,但 Supermemory 中的数据会保留。

重要:请以脚本方式运行 main.py,不要在 Jupyter 单元中运行,因为 Jupyter 的事件循环会与 asyncio.run() 冲突。同步的 Supermemory() 客户端可在异步工具函数中工作,因为 Agents SDK 会在线程池中运行工具。关于 SDK 的更多细节,请参阅 OpenAI Agents SDK 教程

编写训练记录工具

log_workout 是代理记忆的写入侧。该函数从代理接收结构化参数:动作名称、组数、次数、重量与可选备注。它将这些信息转为一句简短的英文句子,并通过 client.add() 交给 Supermemory。嵌入与抽取流水线随后在 Supermemory 内部运行,训练助手无需再做任何处理。

打开 tools.py,从导入与共享客户端开始:

from agents import function_tool
from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
 
USER_ID = "demo_user"
 
client = Supermemory()

load_dotenv() 在导入时运行,使得在构造 Supermemory() 之前,SUPERMEMORY_API_KEY 已经存在于环境变量中。如果在加载环境变量之前构造客户端,您会得到一个未认证的客户端,首次调用会返回令人困惑的 401。两个工具函数共享同一个客户端与同一个 USER_ID 常量。

在客户端下方添加日志工具:

@function_tool
def log_workout(
	exercise: str,
	sets: int,
	reps: int,
	weight: float,
	notes: str = "",
) -> str:
	"""Log a completed workout to the user's memory.
 
	Args:
    	exercise: Name of the exercise.
    	sets: Number of sets performed.
    	reps: Number of reps per set.
    	weight: Weight in pounds. Pass 0 for bodyweight or cardio.
    	notes: Optional notes about the session.
	"""
	print(f"[log_workout] {exercise=} {sets=} {reps=} {weight=} {notes=}")
 
	content = f"Performed {exercise}: {sets} sets of {reps} reps at {weight} lbs."
	if notes:
    	content += f" Notes: {notes}"
 
	response = client.add(content=content, container_tag=USER_ID)
	print(f"[log_workout] -> id={response.id} status={response.status}")
	return f"Logged {exercise} ({sets}x{reps} @ {weight} lb)."

@function_tool 的文档字符串是 LLM 在决定是否调用工具时能看到的内容。 Args: 区块对应参数级的说明。二者共同构成了代理与函数的契约。

该工具将一条普通句子发送给 client.add(),而非 JSON。Supermemory 的画像抽取器读取自然语言并从中推断事实。JSON 在技术上也可行,但由于缺少可供总结的叙述,抽取质量会下降。“Performed bench press: 4 sets of 5 reps at 185.0 lbs” 这类清晰句子会让抽取器更好发挥。

两个 print() 调用会将每次工具调用写到终端:先是解析后的参数,再是响应。

[log_workout] exercise='bench press' sets=4 reps=5 weight=185.0 notes=''
[log_workout] -> id=xY7AK3qLzBPx5Vd2HnRf1M status=queued

status="queued" 与之前热身脚本的返回一致。原始日志已被存储,但在流水线完成之前,client.profile() 不会将其作为搜索结果返回。稍后您会添加等待验证步骤。

编写训练建议工具

suggest_next_session 是读取侧,也是静态/动态拆分发挥作用的地方。一次 client.profile(container_tag=USER_ID, q=focus) 调用就能在一次往返中返回用户的三种视图。

稳定偏好通过 profile.static 返回,当前活动通过 profile.dynamic 返回,最匹配的过往记忆通过 search_results.results 返回。该工具的任务是把这三种视图整合为一段上下文,让代理可以直接引用。

在记录了几次训练后,该工具会产生如下输出:

Recent activity:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
Closest matching past entries:
- Trains at home instead of a gym
- Performed deadlift: 3 sets of 5 reps at 225.0 lbs
- Performed bench press: 4 sets of 5 reps at 185.0 lbs
- Performed 5k run in 26 minutes
- Reports no knee pain during bench press

代理会读取这段内容,并基于用户的真实历史给出建议。如果没有 Supermemory 的画像,您也需要自己构建相同的上下文:单独的语义搜索、自建画像存储、再合并结果。一次 client.profile() 调用替代了这三步。

tools.py 中,将以下代码添加到 log_workout 之后:

@function_tool
def suggest_next_session(focus: str) -> str:
	"""Fetch the user's training history and preferences for a given focus.
 
	Returns a context string the agent can use to recommend the next session.
	The agent is responsible for the actual recommendation. This tool only
	surfaces what Supermemory knows about the user.
 
	Args:
    	focus: What the user wants to train next (e.g. "upper body", "legs",
        	"cardio", "today"). Drives semantic search against past logs.
	"""
	print(f"[suggest_next_session] focus={focus!r}")
	profile = client.profile(container_tag=USER_ID, q=focus)
 
	static_facts = profile.profile.static
	dynamic_facts = profile.profile.dynamic
	matches = profile.search_results.results
 
	print(
    	f"[suggest_next_session] static={len(static_facts)} "
    	f"dynamic={len(dynamic_facts)} matches={len(matches)}"
	)
 
	sections = []
	if static_facts:
    	sections.append("Stable preferences and constraints:")
    	sections.extend(f"- {fact}" for fact in static_facts)
	if dynamic_facts:
    	sections.append("Recent activity:")
    	sections.extend(f"- {fact}" for fact in dynamic_facts)
	if matches:
    	sections.append("Closest matching past entries:")
    	for r in matches[:5]:
        	sections.append(f"- {r['memory']}")
 
	if not sections:
    	return (
        	"No prior training history found for this user. "
        	"Ask the user about their goals, equipment, and recent training."
    	)
	return "\n".join(sections)

client.profile(container_tag=USER_ID, q=focus) 返回一个 ProfileResponse 对象。经过 5 条简短日志后,工具所读取的三个字段大致如下:

profile.profile.static        	# [] (list[str])
profile.profile.dynamic       	# ["Performed bench press: 4 sets of 5 reps at 185.0 lbs", ...]
profile.search_results.results	# [{"memory": "...", "similarity": 0.631, ...}, ...] (list[dict])

每条搜索结果是一个 Python 字典,而不是 Pydantic 对象。使用 r["memory"] 获取文本,使用 r["similarity"] 获取分数。完整字典包含以下键:

  • id

  • memory

  • rootMemoryId

  • metadata

  • updatedAt

  • version

  • similarity

  • filepath

  • documents

Supermemory 的 OpenAI Agents SDK 集成页上的 r.memory or r.chunk 代码片段在 supermemory==3.37.0 下会抛出 AttributeError。请使用中括号访问。

static 此处为空,所以工具会以 if static_facts: 进行分支。对于最初十来条日志,dynamicsearch_results 分支承担主要工作。

Supermemory 也会应用默认的相似度阈值。您只提到过一次的事实,未必会在每次查询中返回。上述 5 条日志在 q="today" 查询下都返回了,但更具体的查询字符串可能返回更少结果。 if matches: 分支可以优雅处理这种情况。

运行会话 1:记录训练

启动会话 1,并记录几次训练,为稍后的读取填充一些内容。运行脚本:

uv run python main.py

依次记录卧推、5 公里跑、硬拉,以及一句偏好声明:“我只在家训练,不去健身房。”代理每次训练会触发一次 log_workout,工具的 print() 输出会在终端显示每次调用。

Title: Session 1 terminal showing three log_workout calls - Description: Session 1 terminal showing three log_workout calls

示例输出。由于模型具备非确定性,您的代理措辞可能不同。

三行 status=queued 表示 Supermemory 正在接手处理。每一行都对应一份文档在 Supermemory 侧经过嵌入与抽取流水线。对于这些简短日志,文档通常在约 12 秒内可通过 client.profile() 检索到。

训练助手代码并不会等待流水线完成。代理会继续,而 Supermemory 会在后台完成工作。

每条日志只会触发一次 log_workout 调用,代理随即停止。不主动推荐、不额外调用工具、不追加跟进建议。第一条系统提示规则保证了这一点。若无此规则,代理会在每次记录后立刻建议下一次训练,导致工具调用数量翻倍。

输入 exit 关闭会话 1。Python 进程结束,SQLiteSession 随之清空。训练记录与偏好声明现在以 container_tag="demo_user" 的形式,保存在与写入脚本分离的 Supermemory 中。

验证回忆并运行会话 2

在会话 2 之前,先确认会话 1 的事实可被查询。打开一个全新的 Python REPL,或将以下内容保存为短脚本:

from dotenv import load_dotenv
from supermemory import Supermemory
 
load_dotenv()
client = Supermemory()
 
prof = client.profile(container_tag="demo_user", q="training")
print(f"static  ({len(prof.profile.static)}): {prof.profile.static}")
print(f"dynamic ({len(prof.profile.dynamic)}):")
for fact in prof.profile.dynamic:
	print(f"  - {fact}")
print(f"matches ({len(prof.search_results.results)}):")
for r in prof.search_results.results[:5]:
	print(f"  - {r['memory']} (similarity={r['similarity']:.3f})")

两次会话之间捕获的真实输出:

static  (0): []
dynamic (5):
  - Trains at home instead of a gym
  - Performed deadlift: 3 sets of 5 reps at 225.0 lbs
  - Performed 5k run in 26 minutes
  - Reports no knee pain during bench press
  - Performed bench press: 4 sets of 5 reps at 185.0 lbs
matches (5):
  - Trains at home instead of a gym (similarity=0.682)
  - Performed deadlift: 3 sets of 5 reps at 225.0 lbs (similarity=0.643)
  - Performed bench press: 4 sets of 5 reps at 185.0 lbs (similarity=0.631)
  - Performed 5k run in 26 minutes (similarity=0.585)
  - Reports no knee pain during bench press (similarity=0.585)

看看 Supermemory 的抽取器生成了什么。用户仅说过一次“我只在家训练,不去健身房”。抽取器把它转成了动态事实 "Trains at home instead of a gym"

卧推日志里包含一条关于没有膝盖疼痛的备注。抽取器将这一条日志拆成了两条动态事实:一条是训练本身,一条是“无疼痛”的状态。

四条日志被规范化为五条动态事实,并返回了五条带有 0.585 至 0.682 相似度的匹配记忆片段。拆分、规范化与匹配都不在训练助手代码中执行。如果 dynamic 为空,请再等 10 秒重跑一次片段。有时处理队列会出现尖峰。

现在在一个全新的进程中启动会话 2:

uv run python main.py

这是一个全新的 Python 解释器。与会话 1 不共享任何内存,也没有预热缓存。代理的任何回忆都来自 Supermemory。

发送一条消息:“我今天该做什么训练?”

Title: Session 2 terminal in a fresh process recalling previous workouts - Description: Session 2 terminal in a fresh process recalling previous workouts

示例输出。同一个记忆库,全新的 Python 进程。

代理调用了 suggest_next_session("today")。该工具打印 static=0 dynamic=5 matches=5。捕获的运行给出了一个在家可做的下肢训练(深蹲、箭步蹲、台阶蹬踏)。

建议与之前的日志一致,因为 Supermemory 的画像告诉了代理这些事实。卧推、硬拉和 5 公里跑属于上肢或有氧,而用户只在家训练。两类事实都来自同一次 client.profile() 调用。由于模型非确定性,您的结果措辞会不同,但回忆路径相同。

下一步:完善您的 Supermemory 代理

演示版本包含一名用户、两个工具与一个 CLI。生产版训练助手在不改动代理循环的前提下,通常沿着三个与 Supermemory 相关的方向扩展。

按真实用户作用域划分记忆。 USER_ID = "demo_user" 常量只适用于单人。生产应用会根据认证用户的 ID 计算标签,如 container_tag="user_sarah"container_tag=customer_id。不同用户之间的记忆保持隔离,因为每次读取都会回传该标签。仅需修改 tools.py 中的一处,其他代码无需变动。

添加更多由记忆支持的工具。 如卸载周、个人纪录(PR)跟踪、每周灵活性提示。每一个都是另一个 @function_tool 函数,写入调用 client.add(),读取调用 client.profile(),都针对相同的 container_tag。工具的形态不变,只是代理记录与查询的内容不同。

处理 Supermemory 的失败。try/except supermemory.APIError 包裹 client.add()client.profile(),避免 Supermemory 的瞬时故障导致代理崩溃。如果您的代理运行在受限环境中,请设置每次请求的超时。

代理循环本身与 Supermemory 无关,可以后续再改。将 CLI 前置为 Telegram、Discord 或 Slack,让用户通过文本上报训练,机器人调用 Runner.run()。或者更换框架。若您的栈已使用LangChain 集成,Supermemory 也提供LangChain 代理支持,记忆代码无需变化。

静态与动态的拆分同样适用于其他领域。

  • 客服代理:静态 = 已知问题与账户偏好;动态 = 未结工单与近期联系。
  • 编码代理:静态 = 偏好的语言与框架;动态 = 当前任务与近期修改的文件。

只要用户是事实来源,这种拆分就成立。

结语

您已用两个工具构建了一个 Python 训练助手,并在跨进程间实现了持久化记忆。 client.add() 负责写入训练记录。 client.profile() 一次调用就能把用户的静态事实、动态事实与语义匹配结果读回来,并按 container_tag 进行作用域限定。Supermemory 负责分片、嵌入、搜索与画像抽取,演示项目无需自行实现。

将其与RAG结合,同一个代理既能回答关于用户的问题,也能回答关于产品的问题。LLM Agents Explained 涵盖更广泛的代理模式,而Associate AI Engineer for Developers 路径则更深入探讨由记忆支持的代理。

Supermemory 常见问题

What is Supermemory?

Supermemory 是一项托管的记忆 API,可为 AI 代理存储、索引与检索长期上下文,使其能够在不同会话中记住用户。

How is Supermemory different from plain vector databases?

Supermemory 在存储之上提供嵌入、索引、语义搜索与画像式事实抽取,因此您可以通过一次 API 调用拿回可直接使用的记忆。

Can Supermemory handle both RAG and user memory?

是的。它既支持基于文件和 URL 的文档式 RAG,也支持面向用户的记忆,因此同一个 API 既可支撑产品知识,也可支撑个人历史。

Do I need to manage my own embedding models with Supermemory?

不需要。Supermemory 会为您运行嵌入与检索流水线;您只需发送原始文本或内容,之后无需自行管理模型或索引即可查询。

Is there a free tier for trying Supermemory?

有。提供面向测试与小型项目的免费计划,包含每月的 token 与查询上限,便于您在升级前进行集成与试验。

主题

在 DataCamp 学习 AI 工程!

Tracks

Associate AI Engineer for Developers

26小时
Learn how to integrate AI into software applications using APIs and open-source libraries. Start your journey to becoming an AI Engineer today!
查看详情Right Arrow
开始课程
查看更多Right Arrow