链载Ai

标题: LlamaIndex智能体Agents开发-记忆管理 [打印本页]

作者: 链载Ai    时间: 2025-12-1 22:24
标题: LlamaIndex智能体Agents开发-记忆管理

在智能体(Agent)的设计中,记忆(Memory) 是不可或缺的组成部分。没有记忆的智能体,就像一条只能看眼前一步的鱼:它能游动,却无法真正理解自己所处的环境,也无法在长时间的交互中保持一致性。而在 LlamaIndex 框架中,记忆管理为多智能体(Multi-Agent)系统带来了持久性、上下文感和推理的深度。

一、为什么智能体需要记忆?

当我们构建 LlamaIndex Agents 时,往往会遇到以下需求:

1、上下文延续

用户提问可能是连续的,例如:

如果没有记忆,智能体在第二个问题中无法理解“他”指的是谁。

2、个性化与长期交互

一个优秀的智能体不仅要记住一次会话中的上下文,还要能在长期使用中保持“个性化”,例如记住用户的偏好、常问的问题、领域背景。

3、复杂任务协作

在 Orchestrator(编排器)调用多个专家 Agent 时,记忆能记录先前的任务结果,避免重复计算和无效调用。

换句话说,记忆就是智能体的“第二大脑”,帮助它在时间的长河中保持连续性与理性。

二、LlamaIndex 中的记忆模块

强大的 LlamaIndex 框架为我们提供了非常便捷的记忆管理模块。开发者无需从零开始构建复杂的记忆系统,只需几行代码,就能为你的 Agent 配置不同类型的记忆。

LlamaIndex 的记忆模块核心思想是:在每一次与 Agent 的交互中,自动地、智能地将对话历史加载到提示 (Prompt) 中,这样大语言模型 (LLM) 在生成下一步的回应或行动时,就能“看到”之前的对话内容。

1. LlamaIndex记忆组件架构

LlamaIndex提供了三种主要的记忆组件类型:


2. 核心记忆组件 - Memory类

Memory类是LlamaIndex中最主要的记忆组件,它提供了以下功能:


基本使用方法:

fromllama_index.core.memoryimportMemory
# 创建基本记忆实例memory = Memory.from_defaults( session_id="my_session", token_limit=40000, # 令牌限制 token_flush_size=1000, # 刷新大小 chat_history_token_ratio=0.7, # 聊天历史令牌比例)


3. 记忆块类型 - MemoryBlock

LlamaIndex提供了三种主要的记忆块类型:

(1) StaticMemoryBlock(静态记忆块)

用于存储固定的、不变的信息:

fromllama_index.core.memoryimportStaticMemoryBlock
static_block =StaticMemoryBlock( name="core_info", static_content="My name is Logan, and I live in Saskatoon. I work at LlamaIndex.", priority=0,)


(2) FactExtractionMemoryBlock(事实提取记忆块)

使用LLM从对话中提取关键事实:

fromllama_index.core.memoryimportFactExtractionMemoryBlock
fact_block = FactExtractionMemoryBlock( name="extracted_info", llm=Settings.llm, # 用于提取事实的LLM max_facts=50, # 最大事实数量 priority=1,)


(3) VectorMemoryBlock(向量记忆块)

使用向量存储进行语义检索的记忆块:

fromllama_index.core.memoryimportVectorMemoryBlockfromllama_index.vector_stores.chromaimportChromaVectorStoreimportchromadb
# 创建向量存储client = chromadb.EphemeralClient()vector_store = ChromaVectorStore( chroma_collection=client.get_or_create_collection("test_collection"))
vector_block = VectorMemoryBlock( name="vector_memory", vector_store=vector_store, embed_model=Settings.embed_model, similarity_top_k=2, # 检索的相似文档数量 retrieval_context_window=5, # 检索上下文窗口 priority=2,)


4. 组合使用记忆组件

将多个记忆块组合使用,创建强大的记忆系统:

from llama_index.core.memory import Memory, InsertMethod
# 定义记忆块blocks = [ StaticMemoryBlock( name="core_info", static_content="My name is Logan, and I live in Saskatoon. I work at LlamaIndex.", priority=0, ), FactExtractionMemoryBlock( name="extracted_info", llm=Settings.llm, max_facts=50, priority=1, ), VectorMemoryBlock( name="vector_memory", vector_store=vector_store, embed_model=Settings.embed_model, priority=2, ),]
# 创建组合记忆系统memory = Memory.from_defaults( session_id="my_session", token_limit=30000, chat_history_token_ratio=0.02, # 低比例,更多内容刷新到长期记忆 token_flush_size=500, memory_blocks=blocks, insert_method=InsertMethod.USER, # 插入方法,可以是USER或SYSTEM)

5. 在代理中使用记忆组件

将LlamaIndex的记忆组件与智能体Agents结合使用:

fromllama_index.core.agent.workflowimportFunctionAgentfromllama_index.core.llmsimportChatMessage
asyncdefagent_with_memory_example(): # 创建记忆系统 memory = Memory.from_defaults( session_id="my_session", token_limit=30000, chat_history_token_ratio=0.7, token_flush_size=1000, )
# 创建代理 agent = FunctionAgent( tools=[multiply_tool, add_tool, weather_tool, search_tool], llm=Settings.llm, system_prompt="你是一个有用的助手,可以使用提供的工具来回答问题和执行任务。", )
# 模拟对话 queries = [ "你好,我叫小明", "记住我的名字", "我的名字是什么?", "计算 203 乘以 45", "计算 304.3 乘以 2.1", ]
forqueryinqueries: # 使用记忆运行代理 response =awaitagent.run(user_msg=query, memory=memory) print(f"用户:{query}") print(f"助手:{response}") print("-"*40)
# 查看记忆内容 chat_history =awaitmemory.aget() print(f"记忆中的消息数量:{len(chat_history)}")

6. 手动管理记忆

除了在代理中使用,您还可以手动管理记忆:

fromllama_index.core.llmsimportChatMessage
# 添加消息到记忆awaitmemory.aput_messages([ ChatMessage(role="user", content="Hello, world!"), ChatMessage(role="assistant", content="Hello, world to you too!"),])
# 获取当前记忆chat_history =awaitmemory.aget()formsginchat_history: print(f"{msg.role}:{msg.content}")
# 获取所有记忆all_messages =awaitmemory.aget_all()print(f"总消息数:{len(all_messages)}")
# 清除记忆memory.reset()

7. 实际应用示例

以下是一个使用LlamaIndex记忆组件的完整示例:


安装包:

pipinstallllama-index-vector-stores-chroma

核心代码:

# ================== 初始化 大模型 Langfuse ==================fromcommon.bedrock_model_loaderimportmodel_loadersimportcommon.langfuse_init_client# ================== 初始化大模型 Langfuse end ==================importasynciofromllama_index.core.agent.workflowimportFunctionAgentfromllama_index.core.memoryimportMemory, VectorMemoryBlock, FactExtractionMemoryBlockfromllama_index.core.llmsimportChatMessagefromllama_index.vector_stores.chromaimportChromaVectorStoreimportchromadbfromfun_collimport*
classLlamaIndexConversationalAgent: """使用LlamaIndex记忆组件的对话代理"""
def__init__(self, tools, system_prompt:str): # 创建向量存储 client = chromadb.EphemeralClient() vector_store = ChromaVectorStore( chroma_collection=client.get_or_create_collection("conversation_collection") )
# 定义记忆块 blocks = [ FactExtractionMemoryBlock( name="facts", # llm=Settings.llm, max_facts=100, priority=1, ), VectorMemoryBlock( name="vector_memory", vector_store=vector_store, # embed_model=Settings.embed_model, similarity_top_k=3, priority=2, ), ]
# 创建记忆系统 self.memory = Memory.from_defaults( session_id="conversation_session", token_limit=40000, chat_history_token_ratio=0.7, token_flush_size=1000, memory_blocks=blocks, insert_method="user", )
# 创建代理 self.agent = FunctionAgent( tools=tools, # llm=Settings.llm, system_prompt=system_prompt, )
asyncdefrun(self, query:str) ->str: """运行代理,使用LlamaIndex记忆""" # 运行代理,自动使用记忆 response =awaitself.agent.run(user_msg=query, memory=self.memory) returnstr(response)
# 使用示例asyncdefllamaindex_conversational_agent_example(): # 创建系统提示 system_prompt =""" 你是一个有用的助手,可以使用提供的工具来回答问题和执行任务。 你有对话记忆能力,可以记住之前的对话内容,提供连贯的交互体验。 """
# 创建对话代理 agent = LlamaIndexConversationalAgent( tools=[multiply_tool, add_tool, weather_tool, search_tool], system_prompt=system_prompt, )
# 模拟对话 queries = [ "你好,我叫小明", "记住我的名字", "我的名字是什么?", "计算乘法我需要传入什么样的数字", "计算乘法可以传0吗?", "203 和 45", "304.3 和 2.1", ]
forqueryinqueries: response =awaitagent.run(query) print(f"用户:{query}") print(f"助手:{response}") print("@-=====----======-------=====#####@@")
if__name__ =="__main__": asyncio.run(llamaindex_conversational_agent_example())

结果:

用户: 你好,我叫小明助手: 你好,小明!很高兴认识你。有什么我可以帮助你的吗?@-=====----======-------=====#####@@用户: 记住我的名字助手: 好的,我已经记住你的名字是小明。有什么我可以为你做的吗?用户: 我的名字是什么?助手: 你的名字是小明。还有什么我可以帮助你的吗?@-=====----======-------=====#####@@用户: 计算乘法我需要传入什么样的数字助手: 要使用乘法计算工具,你需要提供两个数字。这两个数字可以是整数或小数。例如,你可以输入 `multiply(3, 5)` 来计算 3 和 5 的乘积,或者输入 `multiply(2.5, 3.5)` 来计算 2.5 和 3.5 的乘积。
如果你有具体的数字需要计算,请告诉我,我可以帮你进行计算。@-=====----======-------=====#####@@用户: 计算乘法可以传0吗?助手: 可以的,你可以传入0来进行乘法计算。根据乘法的性质,任何数乘以0都等于0。例如,你可以输入 `multiply(0, 5)` 或 `multiply(3, 0)`,结果都会是0。
如果你有具体的数字需要计算,请告诉我,我可以帮你进行计算。@-=====----======-------=====#####@@fun_coll- multiply 中的参数:a=203, b=45用户: 203 和 45助手: 203 和 45 的乘积是 9135。还有什么我可以帮助你的吗?@-=====----======-------=====#####@@fun_coll- multiply 中的参数:a=304.3, b=2.1用户: 304.3 和 2.1助手: 304.3 和 2.1 的乘积是 639.03。还有什么我可以帮助你的吗?@-=====----======-------=====#####@@

LlamaIndex内置的记忆组件提供了强大、灵活的记忆管理功能。通过使用Memory类和各种MemoryBlock,您可以轻松实现短期和长期记忆管理、语义检索、事实提取等高级功能,而无需自己实现这些复杂的逻辑。

三、参数详解

1、Memory的核心参数说明

self.memory=Memory.from_defaults(session_id="conversation_session",token_limit=40000,#总令牌限制chat_history_token_ratio=0.7,#聊天历史占用的令牌比例token_flush_size=1000,#触发刷新到长期记忆的令牌大小memory_blocks=blocks,#记忆块配置insert_method="user",#插入方法)

token_limit(总令牌限制)


chat_history_token_ratio(聊天历史令牌比例)


token_flush_size(刷新令牌大小)


2、记忆块配置

FactExtractionMemoryBlock(事实提取记忆块)

FactExtractionMemoryBlock( name="facts", llm=Settings.llm, max_facts=100, # 最大提取事实数量 priority=1, # 优先级)

max_facts :控制从对话中提取的事实数量,影响长期记忆的容量


VectorMemoryBlock(向量记忆块)

VectorMemoryBlock(name="vector_memory",vector_store=vector_store,embed_model=Settings.embed_model,similarity_top_k=3,#检索时的相似文档数量priority=2,)

similarity_top_k :控制从向量记忆中检索的相关对话数量

总结

LlamaIndex的记忆系统通过分层机制控制对话轮次:


想要控制对话轮次,可以调整以下参数:


通过这些参数的组合使用,可以精确控制LlamaIndex记忆系统中的对话轮次和记忆管理行为。


本文可与《LlamaIndex的Memory使用说明》结合起来看。







欢迎光临 链载Ai (http://www.lianzai.com/) Powered by Discuz! X3.5