Memary
Memary 是一款专为自主智能体(Autonomous Agents)打造的开源记忆层工具。它旨在解决当前 AI 智能体缺乏长期记忆和上下文连贯性的痛点,通过模拟人类的记忆机制,让智能体能够像人一样存储、检索并利用过往经验来辅助推理和决策,从而向通用人工智能(AGI)迈出关键一步。
这款工具特别适合 AI 开发者、研究人员以及希望构建具备持续学习能力的智能体应用的工程师使用。Memary 的核心亮点在于其灵活的架构设计:它不仅支持本地部署的模型(如通过 Ollama 运行的 Llama 3 和 LLaVA),也兼容 OpenAI 等云端服务,允许用户轻松切换不同模型。此外,它内置了对 FalkorDB 和 Neo4j 等图数据库的支持,能够高效地管理复杂的记忆关联。通过简单的配置,开发者即可为智能体赋予“记住”过往交互、理解用户画像并据此优化任务执行的能力,是构建高智商、拟人化 AI 代理的理想基础设施。
使用场景
一位开发者正在构建一个能够长期陪伴用户、协助管理复杂个人项目的自主 AI 助手,该助手需要跨越数周甚至数月持续跟踪任务进度与用户偏好。
没有 Memary 时
- 记忆碎片化:AI 助手无法有效存储历史对话中的关键信息(如用户的项目目标、代码风格偏好),每次交互都像“失忆”般重新开始,导致重复询问相同背景。
- 上下文丢失:在处理长周期任务(如软件开发迭代)时,助手难以关联几天前的决策逻辑,经常给出与之前约定相冲突的建议。
- 开发成本高:开发者需手动设计复杂的数据库 schema 和检索逻辑来模拟记忆功能,耗费大量时间编写样板代码而非优化核心智能。
- 缺乏推理连贯性:由于缺少类似人类的短期与长期记忆分层机制,助手在进行多步推理时容易逻辑断层,无法像人类一样“回想”起之前的线索。
使用 Memary 后
- 类人记忆模拟:Memary 自动为助手构建了分层记忆系统,能精准记录并调用用户的个性化设定与历史决策,让助手越用越“懂”用户。
- 长程上下文关联:借助内置的记忆检索机制,助手能瞬间关联数周前的项目细节,确保在长期任务中保持逻辑一致性和执行连贯性。
- 开箱即用的记忆层:开发者只需几行代码即可集成 Memary,无需从零搭建记忆架构,直接利用其支持的 Ollama 本地模型或云端 API 快速部署。
- 动态记忆更新:Memary emulate 人类记忆的遗忘与强化机制,自动筛选高价值信息存入长期记忆,使助手的推理过程更加流畅且符合直觉。
Memary 通过赋予自主代理类人的记忆能力,将原本割裂的交互转化为连续、深度的智能协作,极大降低了构建高阶 AGI 应用的门槛。
运行环境要求
- 未说明
- 非必需
- 若使用本地模型(Ollama),需根据具体模型(如 Llama 3 8B/40B, LLaVA)自行配置相应 GPU 资源
- 若使用 OpenAI API 则无需本地 GPU
未说明(运行本地大模型通常建议 16GB+)

快速开始
管理您的智能体记忆
智能体能够促进类人推理,是迈向通用人工智能(AGI)以及理解人类自身的重要一步。记忆是人类处理任务的关键组成部分,在构建人工智能智能体时也应给予同等重视。memary 模拟人类记忆,以推动这些智能体的发展。
快速入门 🏁
安装 memary
- 使用 pip:
请确保您使用的 Python 版本不超过 3.11.9,然后运行以下命令:
pip install memary
- 本地安装:
i. 创建一个使用上述指定版本 Python 的虚拟环境。
ii. 安装 Python 依赖项:
pip install -r requirements.txt
指定所用模型
截至撰写本文时,memary 假设已安装本地模型,并且目前支持通过 Ollama 提供的所有模型:
- 使用 Ollama 在本地运行的 LLM(建议默认为
Llama 3 8B/40B)或gpt-3.5-turbo - 使用 Ollama 在本地运行的视觉模型(建议默认为
LLaVA)或gpt-4-vision-preview
除非明确指定,否则 memary 将默认使用本地运行的模型。此外,memary 还允许开发者 轻松切换已下载的模型。
运行 memary
步骤
[可选] 如果您使用 Ollama 在本地运行模型,请按照此 仓库 中的说明操作。
确保存在一个包含必要凭据的
.env文件。.env
OPENAI_API_KEY="YOUR_API_KEY" PERPLEXITY_API_KEY="YOUR_API_KEY" GOOGLEMAPS_API_KEY="YOUR_API_KEY" ALPHA_VANTAGE_API_KEY="YOUR_API_KEY" 数据库使用(参见 API 信息): FALKORDB_URL="falkor://[[username]:[password]]@[falkor_host_url]:port" 或 NEO4J_PW="YOUR_NEO4J_PW" NEO4J_URL="YOUR_NEO4J_URL"获取 API 凭据:
API 信息
- OpenAI 密钥
- FalkorDB
- 登录 → 点击“订阅” → 在仪表板上创建一个免费实例 → 使用凭据(用户名、密码、falkor_host_url 和端口)。
- Neo4j
- 点击“免费开始” → 创建一个免费实例 → 打开自动下载的文本文件并使用凭据。
- Perplexity 密钥
- Google 地图
- 密钥在 Google Cloud 控制台的“API 和服务”选项卡中的“凭据”页面生成。
- Alpha Vantage
- 建议使用 https://10minutemail.com/ 生成临时邮箱使用。
更新用户角色,可在
streamlit_app/data/user_persona.txt中找到,使用位于streamlit_app/data/user_persona_template.txt中的用户角色模板。已提供说明——将大括号替换为相关信息。[可选] 如有需要,更新系统角色,可在
streamlit_app/data/system_persona.txt中找到。[可选] 多图谱——使用 FalkorDB 的用户可以生成多个图谱,并在其 ID 之间切换,这些 ID 对应不同的智能体。这使得不同智能体的记忆和知识上下文能够无缝切换和管理。
运行:
cd streamlit_app
streamlit run app.py
基本用法
from memary.agent.chat_agent import ChatAgent
system_persona_txt = "data/system_persona.txt"
user_persona_txt = "data/user_persona.txt"
past_chat_json = "data/past_chat.json"
memory_stream_json = "data/memory_stream.json"
entity_knowledge_store_json = "data/entity_knowledge_store.json"
chat_agent = ChatAgent(
"个人智能体",
memory_stream_json,
entity_knowledge_store_json,
system_persona_txt,
user_persona_txt,
past_chat_json,
)
在初始化时,可根据需要传入 ['search', 'vision', 'locate', 'stocks'] 子集作为 include_from_defaults,以使用不同的默认工具集。
多图谱
当使用 FalkorDB 数据库时,您可以创建多个智能体。以下是为不同用户设置个人智能体的示例:
# 用户 A 的个人智能体
chat_agent_user_a = ChatAgent(
"个人智能体",
memory_stream_json_user_a,
entity_knowledge_store_json_user_a,
system_persona_txt_user_a,
user_persona_txt_user_a,
past_chat_json_user_a,
user_id='user_a_id'
)
# 用户 B 的个人智能体
chat_agent_user_b = ChatAgent(
"个人智能体",
memory_stream_json_user_b,
entity_knowledge_store_json_user_b,
system_persona_txt_user_b,
user_persona_txt_user_b,
past_chat_json_user_b,
user_id='user_b_id'
)
添加自定义工具
def multiply(a: int, b: int) -> int:
"""将两个整数相乘并返回结果"""
return a * b
chat_agent.add_tool({"multiply": multiply})
有关为 LlamaIndex ReAct Agent 创建自定义工具的更多信息,请参阅 此处。
移除自定义工具
chat_agent.remove_tool("multiply")
核心概念 🧪
memary 当前的结构如下面的示意图所示。
截至撰写本文时,上述系统设计中,路由智能体、知识图谱和记忆模块均已集成到位于 src/agent 目录下的 ChatAgent 类中。
这些组件的原始源代码也可在其各自的目录中找到,包括基准测试、笔记本和更新内容。
原则
memary 以尽可能少的开发人员实现工作,无缝集成到您现有的代理中。我们通过坚持几项原则来实现这一点。
自动生成的记忆
- 初始化 memary 后,随着代理的交互,代理记忆会自动更新。这种自动生成方式使我们能够捕获所有记忆,并在您的仪表板上轻松显示。此外,我们还支持无需或仅需少量代码即可将数据库组合在一起!
记忆模块
- 根据当前数据库的状态,memary 会跟踪用户的偏好,并在您的仪表板上显示这些信息以便分析。
系统改进
- memary 模仿人类记忆随时间演变和学习的方式。我们将在仪表板上展示您的代理改进的速度。
回溯记忆
- memary 会自动记录所有聊天内容,以便您可以回溯代理的执行过程,并访问特定时间点的代理记忆(即将推出)。
代理
为了使没有现有代理的开发者也能使用 memary,我们设置了一个简单的代理实现。我们使用 ReAct 代理,根据提供的工具来规划并执行查询。
虽然我们并未强调为代理配备大量工具,但搜索工具对于从知识图谱中检索信息至关重要。该工具会基于现有节点查询知识图谱以获取响应;如果不存在相关实体,则会执行外部搜索。其他默认代理工具包括由 LLaVa 提供支持的计算机视觉工具,以及使用 geocodder 和 Google 地图的位置工具。
注意:在未来的版本发布中,目前用于演示目的的 ReAct 代理将被从软件包中移除,以便 memary 能够支持来自任何提供商的任何类型的代理。
def external_query(self, query: str):
messages_dict = [
{"role": "system", "content": "务必精确简洁。"},
{"role": "user", "content": query},
]
messages = [ChatMessage(**msg) for msg in messages_dict]
external_response = self.query_llm.chat(messages)
return str(external_response)
def search(self, query: str) -> str:
response = self.query_engine.query(query)
if response.metadata is None:
return self.external_query(query)
else:
return response
知识图谱

知识图谱 ↔ 大型语言模型
- memary 使用图数据库来存储知识。
- 我们使用 Llama Index 根据文档向图存储中添加节点。
- 对于外部查询,则使用 Perplexity(mistral-7b-instruct 模型)。
知识图谱用例
- 将最终的代理响应注入到现有的知识图谱中。
- memary 采用一种递归式检索方法来搜索知识图谱:首先确定查询中的关键实体,然后构建一个包含这些实体且最大深度为 2 的子图,最后利用该子图来构建上下文。
- 当查询中存在多个关键实体时,memary 会使用多跳推理,将多个子图合并成一个更大的子图进行搜索。
- 这些技术相比一次性搜索整个知识图谱,能够显著降低延迟。
def query(self, query: str) -> str:
# 获取 React 代理的响应
response = self.routing_agent.chat(query)
self.routing_agent.reset()
# 将响应写入文件,以便后续写回知识图谱
with open("data/external_response.txt", "w") as f:
print(response, file=f)
# 写回知识图谱
self.write_back()
return response
def check_KG(self, query: str) -> bool:
"""检查查询是否存在于知识图谱中。
Args:
query (str): 需要在知识图谱中检查的查询
Returns:
bool: 如果查询存在于知识图谱中则返回 True,否则返回 False
"""
response = self.query_engine.query(query)
if response.metadata is None:
return False
return generate_string(
list(list(response.metadata.values())[0]["kg_rel_map"].keys())
)
内存模块

内存模块由记忆流和实体知识库组成。该模块的设计受到微软研究院提出的K-LaMP的启发。
内存流
内存流会捕获所有被插入到知识图谱中的实体及其相关时间戳。这一流反映了用户的知识广度,即用户接触过但未深入理解的概念。
- 时间线分析:绘制交互的时间线,突出显示高互动时刻或话题焦点的变化。这有助于理解用户兴趣随时间的演变。
def add_memory(self, entities):
self.memory.extend([
MemoryItem(str(entity),
datetime.now().replace(microsecond=0))
for entity in entities
])
- 提取主题:在交互中寻找反复出现的主题或话题。这种主题分析可以帮助我们在用户明确表达之前就预测其兴趣或问题。
def get_memory(self) -> list[MemoryItem]:
return self.memory
实体知识库
实体知识库会跟踪存储在内存流中每个实体的引用频率和最近一次引用时间。该知识库反映了用户的知识深度,即用户对某些概念比其他概念更为熟悉。
- 按相关性对实体进行排序:结合频率和近期性对实体进行排序。如果某个实体被频繁提及(计数高)且最近被引用,则说明该实体可能非常重要,用户对该概念也非常了解。
def _select_top_entities(self):
entity_knowledge_store = self.message.llm_message['knowledge_entity_store']
entities = [entity.to_dict() for entity in entity_knowledge_store]
entity_counts = [entity['count'] for entity in entities]
top_indexes = np.argsort(entity_counts)[:TOP_ENTITIES]
return [entities[index] for index in top_indexes]
- 对实体进行分类:根据实体的性质或其出现的上下文(例如技术术语、个人兴趣)将实体分组。这种分类有助于快速获取针对用户查询的相关信息。
def _convert_memory_to_knowledge_memory(
self, memory_stream: list) -> list[KnowledgeMemoryItem]:
"""将内存流中的记忆转换为实体知识库,通过分组实体实现
返回:
knowledge_memory (list): KnowledgeMemoryItem列表
"""
knowledge_memory = []
entities = set([item.entity for item in memory_stream])
for entity in entities:
memory_dates = [
item.date for item in memory_stream if item.entity == entity
]
knowledge_memory.append(
KnowledgeMemoryItem(entity, len(memory_dates),
max(memory_dates)))
return knowledge_memory
- 突出显示随时间的变化:识别实体排名或分类随时间发生的显著变化。最常提及实体的变化可能表明用户兴趣或知识结构发生了转变。
- 关于内存模块的更多信息请参见这里。

新上下文窗口

注意:我们利用与用户相关的关键分类实体和主题,以便使智能体的回答更贴合用户的当前兴趣/偏好以及知识水平/专业程度。新的上下文窗口由以下内容组成:
- 智能体响应
def get_routing_agent_response(self, query, return_entity=False):
"""从ReAct获取响应"""
response = ""
if self.debug:
# 将ReAct智能体的步骤写入单独文件,并修改格式以便在.txt文件中可读
with open("data/routing_response.txt", "w") as f:
orig_stdout = sys.stdout
sys.stdout = f
response = str(self.query(query))
sys.stdout.flush()
sys.stdout = orig_stdout
text = ""
with open("data/routing_response.txt", "r") as f:
text = f.read()
plain = ansi_strip(text)
with open("data/routing_response.txt", "w") as f:
f.write(plain)
else:
response = str(self.query(query))
if return_entity:
# 上述查询已将最终响应添加到知识图谱中,因此实体会存在于知识图谱中
return response, self.get_entity(self.query_engine.retrieve(query))
return response
- 最相关实体
def get_entity(self, retrieve) -> list[str]:
"""retrieve 是一个 QueryBundle 对象列表。
一个检索到的 QueryBundle 对象具有“node”属性,
而该属性又包含“metadata”属性。
例如对于“kg_rel_map”:
kg_rel_map = {
'Harry': [['DREAMED_OF', '未知关系'], ['FELL_HARD_ON', '水泥地面']],
'Potter': [['WORE', '圆形眼镜'], ['HAD', '梦境']]
}
参数:
retrieve (list[NodeWithScore]): NodeWithScore 对象列表
返回:
list[str]: 字符串实体列表
"""
entities = []
kg_rel_map = retrieve[0].node.metadata["kg_rel_map"]
for key, items in kg_rel_map.items():
# key 是问题中的实体
entities.append(key)
# items 是 [关系, 实体] 的列表
entities.extend(item[1] for item in items)
if len(entities) > MAX_ENTITIES_FROM_KG:
break
entities = list(set(entities))
for exceptions in ENTITY_EXCEPTIONS:
if exceptions in entities:
entities.remove(exceptions)
return entities
- 聊天历史(已摘要以避免令牌溢出)
def _summarize_contexts(self, total_tokens: int):
"""总结上下文。
参数:
total_tokens (int): 响应中的总令牌数
"""
messages = self.message.llm_message["messages"]
# 前两条消息分别是系统和用户角色
if len(messages) > 2 + NONEVICTION_LENGTH:
messages = messages[2:-NONEVICTION_LENGTH]
del self.message.llm_message["messages"][2:-NONEVICTION_LENGTH]
else:
messages = messages[2:]
del self.message.llm_message["messages"][2:]
message_contents = [message.to_dict()["content"] for message in messages]
llm_message_chatgpt = {
"model": self.model,
"messages": [
{
"role": "user",
"content": "请将之前的对话总结成50字左右:"
+ str(message_contents),
}
],
}
response, _ = self._get_gpt_response(llm_message_chatgpt)
content = "总结的过往对话:" + response
self._add_contexts_to_llm_message("assistant", content,index=2)
logging.info(f"上下文已成功总结。 \n 总结内容:{response}")
logging.info(f"驱逐后总令牌数:{total_tokens*EVICTION_RATE}")
许可证
memary 采用 MIT 许可证发布。
版本历史
v0.1.52024/10/22v0.1.42024/09/09v0.1.32024/05/27v0.1.22024/05/21v0.1.12024/05/09v0.1.02024/05/02常见问题
相似工具推荐
openclaw
OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你
stable-diffusion-webui
stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。
everything-claude-code
everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上
ComfyUI
ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。
gemini-cli
gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。
markitdown
MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器