https://deepwiki.com/search/_744e0876-fa6d-4963-8e01-09dfd4237487?mode=fast
MemU
Item
Category)处理记忆:原始资源经提取生成离散记忆项,再按主题聚合并生成可自演进的分类摘要;支持批量记忆化与
CRUD
三层架构
- Resource:原始多模态数据(对话、文档、图像等)
。
- Item:从资源提取的离散记忆单元(偏好、技能、事件等)
。
- Category:按主题聚合的文本记忆,带可演进摘要(如
记忆化(memorize)
- 入口:
service.memorize(resource_url,modality,
步骤触发
_update_category_summaries,批量更新分类摘要增量更新(CRUD)
- 创建/更新/删除记忆项会构建
category_updates(before/after),在_patch_persist_and_index中调用_patch_category_summaries进行增量演进检索(retrieve)
- RAG:基于嵌入向量的快速检索,返回相似度分数
。
- LLM:基于语义理解的深度检索,支持查询重写与早停
示例
- 内存与
retrieve(RAG/LLM)的完整链路
/>
Notes
- 自演进机制通过
LLM
重写分类摘要实现,支持“仅添加/更新”策略,避免显式删除
。
- 增量更新可返回
need_update:以跳过无意义的改写,节省成本false
pages
explore:
- Self-Evolving
Memory
(NevaMind-AI/memU)
Citations
File:README.md
organizes
src="assets/structure.png"
/>
|-------|-------------|----------|
**Resource**
patterns
- Self-Evolving
- RAG:基于嵌入向量的快速检索,返回相似度分数
File:docs/SERVICE_API.md
(L30-35)
`MemoryService`***
pipelines
File:docs/SERVICE_API.md
memorize
Any]
Parameters
Parameter Type Required Description resource_urlstrYes URL local
process.
modalitystrYes Type resource:
"conversation","document","image","video",or
"audio".summary_promptstrNone
No Optional custom
summarization.
userdict[str,Any]
None
No User scope
(e.g.,
{"user_id":"u123"}).
Returns
{"resource":{"id":str,"url":str,"modality":str,"local_path":str,"caption":str|None,"created_at":str,"updated_at":str,#...
fields
},"items":[{"id":str,"resource_id":str,"memory_type":str,#"profile",
"behavior"
"summary":str,"created_at":str,"updated_at":str,#...
fields
},...],"categories":[{"id":str,"name":str,"description":str,"summary":str|None,#...
fields
},...],"relations":[{"item_id":str,"category_id":str,#...
fields
},...]}Example
result=awaitservice.memorize(File:docs/SERVICE_API.md
(L153-160)
print(f"[{item['memory_type']}]
{item['summary'][:80]}...")
and
memories.
**File:**docs/SERVICE_API.md
Any]
**File:**(L63-93)
self.user_model(**user).model_dump()
user
self._ensure_categories_ready(ctx,
store,
"categories_prompt_str":
"ctx":
self._run_workflow("memorize",
state)
result.get("response"))
response
response
File:src/memu/app/memorize.py
(L280-288)
asyncdef_memorize_persist_and_index(self,state:WorkflowState,step_context:Any)->WorkflowState:llm_client=self._get_step_llm_client(step_context)awaitself._update_category_summaries(state.get("category_updates",{}),ctx=state["ctx"],store=state["store"],llm_client=llm_client,)returnstateFile:src/memu/app/patch.py
(L354-362)
asyncdef_patch_persist_and_index(self,state:WorkflowState,step_context:Any)->WorkflowState:llm_client=self._get_step_llm_client(step_context)awaitself._patch_category_summaries(state.get("category_updates",{}),ctx=state["ctx"],store=state["store"],llm_client=llm_client,)returnstateFile:src/memu/app/crud.py
(L425-475)
asyncdef_patch_update_memory_item(self,state:WorkflowState,step_context:Any)->WorkflowState:memory_id=state["memory_id"]memory_payload=state["memory_payload"]ctx=state["ctx"]store=state["store"]user=state["user"]category_memory_updates:dict[str,tuple[Any,Any]]={}item=store.memory_item_repo.get_item(memory_id)ifnotitem:msg=f"Memoryitem
id
{memory_id}notfound"
raiseValueError(msg)old_content=item.summaryold_item_categories=store.category_item_repo.get_item_categories(memory_id)mapped_old_cat_ids=[cat.category_idforcatinold_item_categories]ifmemory_payload["content"]:embed_payload=[memory_payload["content"]]content_embedding=(awaitself._get_llm_client().embed(embed_payload))[0]else:content_embedding=Noneifmemory_payload["type"]ormemory_payload["content"]:item=store.memory_item_repo.update_item(item_id=memory_id,memory_type=memory_payload["type"],summary=memory_payload["content"],embedding=content_embedding,)new_cat_names=memory_payload["categories"]mapped_new_cat_ids=self._map_category_names_to_ids(new_cat_names,ctx)cats_to_remove=set(mapped_old_cat_ids)-set(mapped_new_cat_ids)cats_to_add=set(mapped_new_cat_ids)-set(mapped_old_cat_ids)forcidincats_to_remove:store.category_item_repo.unlink_item_category(memory_id,cid)category_memory_updates[cid]=(old_content,None)forcidincats_to_add:store.category_item_repo.link_item_category(memory_id,cid,user_data=dict(useror{}))category_memory_updates[cid]=(None,item.summary)ifmemory_payload["content"]:forcidinset(mapped_old_cat_ids)&set(mapped_new_cat_ids):category_memory_updates[cid]=(old_content,item.summary)state.update({"memory_item":item,"category_updates":category_memory_updates,})returnstate
File:tests/test_inmemory.py
Memorizeprint("\n[INMEMORY]
Memorizing...")memory=awaitservice.memorize(resource_url=file_path,modality="conversation",user={"user_id":"123"})forcatinmemory.get("categories",[]):print(f"
-{cat.get('name')}:{(cat.get('summary')or'')[:80]}...")queries=[{"role":"user","content":{"text":"Tell
about
preferences"}},{"role":"assistant","content":{"text":"Sure,
I'll
preferences"}},{"role":"user","content":{"text":"What
are
***y"},},#
This
rewriting]#
RAG-based
retrievalprint("\n[INMEMORY]
RETRIEVED
RAG")service.retrieve_config.method="rag"result_rag=awaitservice.retrieve(queries=queries,where={"user_id":"123"})print("
Categories:")forcatinresult_rag.get("categories",[])[:3]:print(f"
-{cat.get('name')}:{(cat.get('summary')orcat.get('description',''))[:80]}...")print("
Items:")foriteminresult_rag.get("items",[])[:3]:print(f"
[{item.get('memory_type')}]{item.get('summary','')[:100]}...")ifresult_rag.get("resources"):print("
Resources:")forresinresult_rag.get("resources",[])[:3]:print(f"
[{res.get('modality')}]{res.get('url','')[:80]}...")#
LLM-based
retrievalprint("\n[INMEMORY]
RETRIEVED
LLM")service.retrieve_config.method="llm"result_llm=awaitservice.retrieve(queries=queries,where={"user_id":"123"})print("
Categories:")forcatinresult_llm.get("categories",[])[:3]:print(f"
-{cat.get('name')}:{(cat.get('summary')orcat.get('description',''))[:80]}...")print("
Items:")foriteminresult_llm.get("items",[])[:3]:print(f"
[{item.get('memory_type')}]{item.get('summary','')[:100]}...")ifresult_llm.get("resources"):print("
Resources:")forresinresult_llm.get("resources",[])[:3]:print(f"
[{res.get('modality')}]{res.get('url','')[:80]}...")
File:tests/test_postgres.py
Memorizeprint("\n[POSTGRES]
Memorizing...")memory=awaitservice.memorize(resource_url=file_path,modality="conversation",user={"user_id":"123"})forcatinmemory.get("categories",[]):print(f"
-{cat.get('name')}:{(cat.get('summary')or'')[:80]}...")queries=[{"role":"user","content":{"text":"Tell
about
preferences"}},{"role":"assistant","content":{"text":"Sure,
I'll
preferences"}},{"role":"user","content":{"text":"What
are
***y"},},#
This
rewriting]#
RAG-based
retrievalprint("\n[POSTGRES]
RETRIEVED
RAG")service.retrieve_config.method="rag"result_rag=awaitservice.retrieve(queries=queries,where={"user_id":"123"})print("
Categories:")forcatinresult_rag.get("categories",[])[:3]:print(f"
-{cat.get('name')}:{(cat.get('summary')orcat.get('description',''))[:80]}...")print("
Items:")foriteminresult_rag.get("items",[])[:3]:print(f"
[{item.get('memory_type')}]{item.get('summary','')[:100]}...")ifresult_rag.get("resources"):print("
Resources:")forresinresult_rag.get("resources",[])[:3]:print(f"
[{res.get('modality')}]{res.get('url','')[:80]}...")#
LLM-based
retrievalprint("\n[POSTGRES]
RETRIEVED
LLM")service.retrieve_config.method="llm"result_llm=awaitservice.retrieve(queries=queries,where={"user_id":"123"})print("
Categories:")forcatinresult_llm.get("categories",[])[:3]:print(f"
-{cat.get('name')}:{(cat.get('summary')orcat.get('description',''))[:80]}...")print("
Items:")foriteminresult_llm.get("items",[])[:3]:print(f"
[{item.get('memory_type')}]{item.get('summary','')[:100]}...")ifresult_llm.get("resources"):print("
Resources:")forresinresult_llm.get("resources",[])[:3]:print(f"
[{res.get('modality')}]{res.get('url','')[:80]}...")
- 创建/更新/删除记忆项会构建
- 入口:


