CAMEL 记忆块(Memory Blocks)深度解析:ChatHistoryBlock 与 VectorDBBlock 架构与实战
CAMEL 记忆块Memory Blocks深度解析ChatHistoryBlock 与 VectorDBBlock 架构与实战【免费下载链接】camel CAMEL: The first and the best multi-agent framework. Finding the Scaling Law of Agents. https://www.camel-ai.org项目地址: https://gitcode.com/GitHub_Trending/ca/camel导读CAMEL项目根目录作为一个多智能体框架为每个 Agent 提供了可插拔的记忆系统。本文聚焦于camel.memories.blocks包——记忆系统中最基础的组成单元ChatHistoryBlock对话历史块与VectorDBBlock向量数据库块。你将理解这两种记忆块如何协同工作掌握窗口化检索、keep_rate 衰减评分、向量相似度召回等核心机制并学会如何基于MemoryBlock抽象基类在真实代码中组合出会话记忆、向量记忆与长期记忆三种 Agent 记忆形态。记忆块在 CAMEL 记忆架构中的位置在 CAMEL 中记忆系统采用分层设计其核心依赖关系如下对应 camel/memories/init.py 的导出结构MemoryBlock抽象基类定义记忆块的最小接口写记录、清空、可选删除ChatHistoryBlock与VectorDBBlock两个具体实现即本文主角位于 camel/memories/blocks/AgentMemory面向 Agent 的更高层抽象负责retrieve与get_context_creatorChatHistoryMemory、VectorDBMemory、LongtermAgentMemory三种可直接接入 Agent 的记忆封装内部委托给上面的记忆块见 camel/memories/agent_memories.py。MemoryBlock的接口定义在 camel/memories/base.pywrite_records(records)批量写入抽象方法write_record(record)单条写入的便捷封装pop_records(count)移除并返回最近的 N 条记录基类默认抛NotImplementedErrorremove_records_by_indices(indices)按索引移除记录默认抛NotImplementedErrorclear()清空全部记录抽象方法。值得注意的是MemoryBlock刻意不定义统一的retrieve接口——因为不同记忆块的检索语义差异很大滑动窗口 vs. 向量相似度这一设计让每个记忆块可以自由定义最适合自己的检索方式。ChatHistoryBlock对话历史的窗口化记忆ChatHistoryBlock位于 camel/memories/blocks/chat_history_block.py负责维护 Agent 的完整对话历史核心能力是按最近消息数量窗口检索并通过 keep_rate 为每条历史消息计算重要性分数。构造参数与默认值from camel.memories import ChatHistoryBlock # 全部使用默认值 block ChatHistoryBlock() # 指定存储后端与保留率 from camel.storages.key_value_storages.in_memory import InMemoryKeyValueStorage block ChatHistoryBlock( storageInMemoryKeyValueStorage(), # 键值存储默认 InMemoryKeyValueStorage keep_rate0.9, # 历史消息分数衰减率默认 0.9 )参数类型默认值说明storageBaseKeyValueStorageNone自动用InMemoryKeyValueStorage对话历史的键值存储后端keep_ratefloat0.9历史消息分数衰减率必须在 [0, 1] 区间否则构造时抛出ValueErrorkeep_rate的语义在历史消息中最后一条消息的分数恒为 1.0每向前回溯一步分数乘以一次keep_rate。keep_rate越高越倾向于在上下文构建时保留更多历史消息。这一分数随后会被ScoreBasedContextCreator等上下文构建器消费用于决定哪些历史记录进入最终上下文其实现见 camel/memories/context_creators/score_based.py。retrieve窗口化检索与系统消息保护retrieve(window_size)是块的核心方法window_sizeNone返回全部历史记录window_size0返回空列表但系统/开发者消息除外见下window_sizeN返回最近 N 条非系统消息并在开头保留首条 SYSTEM/DEVELOPER 消息如果存在。源码中的处理逻辑chat_history_block.py可以用两个示例概括场景一首条消息为 SYSTEM共 5 条window_size2→[system_msg] [user_msg3, user_msg4]场景二首条消息为 USER共 5 条window_size3→[user_msg3, user_msg4, user_msg5]。系统消息保护意味着无论窗口多小Agent 的 system prompt角色设定都不会被截掉保证 Agent 行为设定始终在上下文中。检索打分越近的消息分数越高retrieve返回的是List[ContextRecord]每条包含memory_record、score、timestamp三要素结构定义见 camel/memories/records.py。打分规则chat_history_block.py系统消息固定score1.0永不衰减其余消息从最近到最远分数依次乘以keep_rate即最近一条为 1.0、上一条为 0.9、再上一条为 0.81……最终按时间正序返回。写入、清空与记录删除write_records(records)将MemoryRecord序列化为 dict 后交给键值存储持久化clear()清空全部消息pop_records(count)从末尾移除最近count条记录并返回被移除的记录按时间正序。实现同样保护首条系统消息且要求count为非负整数remove_records_by_indices(indices)按当前记录列表的 0 基索引批量删除记录索引 0 的系统/开发者消息受保护不会被删除。VectorDBBlock基于向量相似度的语义记忆VectorDBBlock位于 camel/memories/blocks/vectordb_block.py负责将消息转为向量并存入向量数据库检索时按语义相似度召回最相关的历史记录——它不依赖消息的新旧而是依赖内容的相关性。构造参数与默认值from camel.memories import VectorDBBlock # 全部使用默认值 block VectorDBBlock() # 指定向量存储与嵌入模型 from camel.embeddings import OpenAIEmbedding from camel.storages.vectordb_storages import QdrantStorage block VectorDBBlock( storageQdrantStorage(vector_dim1536), # 默认按 embedding 输出维度自动创建 embeddingOpenAIEmbedding(), # 默认 OpenAIEmbedding )参数类型默认值说明storageBaseVectorStorageNone自动用QdrantStorage向量数据库存储后端embeddingBaseEmbeddingNone自动用OpenAIEmbedding将消息内容转为向量表示的嵌入模型构造时块会通过self.embedding.get_output_dim()获取向量维度并以此初始化默认的QdrantStorage(vector_dim...)保证维度一致性vectordb_block.py。retrieve以关键词查相似记录records block.retrieve(keyword如何配置缓存, limit3)keyword查询字符串会被嵌入为向量后发起相似度检索limit最多返回的相似消息条数默认3。底层流程vectordb_block.pyself.embedding.embed(keyword)将查询词转成查询向量构造VectorDBQuery(query_vector..., top_klimit)提交给存储后端VectorDBQuery定义于 camel/storages/vectordb_storages/base.pytop_k默认 1对每条查询结果构造ContextRecord其score直接取自向量检索的similarity余弦相似度等timestamp来自记录 payload。write_records过滤空内容再向量化写入时会先过滤掉 content 为空或全空白的记录避免为无意义文本浪费向量空间随后将每条有效记录包装为VectorRecord向量 payload UUID批量写入存储vectordb_block.py。clear()则清空整个向量库。注意向量记忆不支持按索引删除因为向量的分布特性决定了无法简单按位置回滚。从记忆块到 Agent 记忆三种组合方式记忆块本身不直接接入 Agent它们通过AgentMemory封装后使用实现全部在 camel/memories/agent_memories.py。ChatHistoryMemory纯对话历史对ChatHistoryBlock的一层薄封装额外支持window_size参数。当实际取回的记录数达到窗口上限时会发出UserWarning提示历史消息被截断agent_memories.py。它还实现了clean_tool_calls()可清理 FUNCTION/TOOL 角色消息以及带tool_calls的 ASSISTANT 消息用于节省 token。VectorDBMemory语义检索记忆对VectorDBBlock的封装。关键设计写入时假设最后一条 USER 输入即为当前话题_current_topic检索时用当前话题作为查询词因此最近的用户问题会驱动相似历史召回agent_memories.py。该类明确不支持pop_records与remove_records_by_indices因为向量库无法做顺序回滚。LongtermAgentMemory长期记忆二者兼得from camel.memories import LongtermAgentMemory, ChatHistoryBlock, VectorDBBlock memory LongtermAgentMemory( context_creatorcontext_creator, # BaseContextCreator 实例 chat_history_blockChatHistoryBlock(),# 默认自动创建 vector_db_blockVectorDBBlock(), # 默认自动创建 retrieve_limit3, # 向量召回条数上限 agent_idmy_agent, # 关联的 Agent ID )LongtermAgentMemory.retrieve()的合并策略非常巧妙agent_memories.pychat_history self.chat_history_block.retrieve() vector_db_retrieve self.vector_db_block.retrieve(self._current_topic, self.retrieve_limit) return chat_history[:1] vector_db_retrieve chat_history[1:]即首条系统消息 向量召回的语义相关记录 其余对话历史。这样既保证了角色设定始终在场又让 Agent 既能记住最近说了什么短期窗口又能想起很久以前的相关知识长期语义这正是 CAMEL 长期记忆能力的核心设计。write_records会把记录同时写入两个块并同步更新当前话题pop_records与remove_records_by_indices只作用于对话历史块向量记忆保持不变。配套数据结构MemoryRecord 与 ContextRecord理解记忆块需要先认识两条核心数据模型camel/memories/records.pyMemoryRecord记忆系统的基本存储单元字段包括messageBaseMessage 内容、role_at_backend后端角色枚举如 SYSTEM/USER/ASSISTANT、uuid唯一标识、extra_info附加键值、timestamp纳秒精度时间戳、agent_id。提供to_dict()/from_dict()完成序列化往返——ChatHistoryBlock正是通过它们与键值存储交互VectorDBBlock则把 dict 作为 payload 存入向量库ContextRecord检索结果包装memory_record并附带score供上下文构建器权衡取舍与timestamp。实战完整可运行的组合示例将记忆块接入一个 CAMEL Agent 的典型流程如下参考 examples/memories 目录下的官方示例from camel.memories import ( ChatHistoryBlock, LongtermAgentMemory, MemoryRecord, ScoreBasedContextCreator, VectorDBBlock, ) from camel.messages import BaseMessage from camel.types import OpenAIBackendRole, RoleType from camel.utils import OpenAITokenCounter # 1. 创建两条记忆块也可直接使用默认构造 chat_block ChatHistoryBlock(keep_rate0.9) # 对话历史衰减率 0.9 vector_block VectorDBBlock() # 向量记忆默认 OpenAIEmbedding QdrantStorage # 2. 组装长期记忆上下文构建器负责把记录按 token 预算拼装成 OpenAI 消息 memory LongtermAgentMemory( context_creatorScoreBasedContextCreator( token_counterOpenAITokenCounter(modelgpt-4o), token_limit4096, ), chat_history_blockchat_block, vector_db_blockvector_block, retrieve_limit3, agent_iddemo_agent, ) # 3. 写入记录底层同时写入两个块 record MemoryRecord( messageBaseMessage( role_nameuser, role_typeRoleType.USER, meta_dictNone, contentCAMEL 的向量记忆如何工作, ), role_at_backendOpenAIBackendRole.USER, ) memory.write_records([record]) # 4. 构建最终上下文OpenAIMessage 列表 token 总数 context_messages, total_tokens memory.get_context()get_context()是AgentMemory提供的便捷方法camel/memories/base.py它调用context_creator.create_context(memory.retrieve())最终返回可直接发给 LLM 的消息列表与 token 统计。而ScoreBasedContextCreator还带 token 计数缓存当消息数量与上次 LLM 响应一致时直接复用缓存值新增消息时用字符级估算增量累加显著减少重复的 token 计数开销score_based.py。测试验证记忆块的正确性保障仓库在 test/memories/test_blocks.py 中为两个记忆块提供了完整单元测试是理解其行为的权威参考ChatHistoryBlock默认/自定义存储注入、window_size窗口检索retrieve(window_size5)恰好返回 5 条、零窗口返回空列表、无窗口返回全部历史、空历史返回空列表、写入与清空调用存储对应方法VectorDBBlock默认组件自动创建、自定义storage/embedding注入、检索结果顺序与 payload 内容还原、写入调用storage.add、清空调用storage.clear。测试还通过create_autospec(BaseKeyValueStorage)/create_autospec(BaseVectorStorage)模拟存储层印证了两个记忆块对存储后端的依赖仅限定于抽象接口因此可以无缝替换为 Redis、MongoDB 等键值存储或 Chroma、PGVector 等向量存储存储实现见 camel/storages/key_value_storages/ 与 camel/storages/vectordb_storages/。更上层的封装测试见 test/memories/test_agent_memories.py。总结与选型建议需求场景推荐记忆块/记忆封装仅需最近的对话上下文关注 token 开销ChatHistoryBlockwindow_size或ChatHistoryMemory需要跨长对话召回语义相似的历史知识VectorDBBlock或VectorDBMemory既要短期对话、又要长期语义记忆LongtermAgentMemory内部组合两个块ChatHistoryBlock与VectorDBBlock一近一远、一序一义共同构成了 CAMEL 记忆系统的底层基石。理解它们的构造参数、检索策略与删除语义是深入定制 Agent 记忆行为如调整keep_rate控制历史保留倾向、替换存储后端实现持久化、更换嵌入模型适配多语言检索的前提。更多记忆相关模块可继续阅读 camel/memories/ 与 docs/key_modules/memory.md 获得全局视角。【免费下载链接】camel CAMEL: The first and the best multi-agent framework. Finding the Scaling Law of Agents. https://www.camel-ai.org项目地址: https://gitcode.com/GitHub_Trending/ca/camel创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考