上节课我们学习了路由的概念通过路由表和binding规则可以让不同的agent服务不同的租户并通过tier进行逐级匹配, 今天我们来学习OpenClaw智能层的概念其做法有如下初始化时加载记忆通过8次提示词加载丰富人格加载两部分记忆分别是MEMORY.md长期记忆和memory/daily/xxx.jsonl每日记忆每次用户提问时都加载两部分记忆然后先进行tf-idf余弦相似度关键词搜索的混合搜索机制并对结果进行时间衰减和MMR重排序最终将相关且多样化的记忆碎片注入系统提示词。1. 整体背景1.1. 前期8层记忆加载对应BootstrapLoader)前期8个文件分别对应如下文件身份SOUL.md人格IDENTITY.md身份TOOLS.md工具USER.md用户信息HEARTBEAT.nd心跳配置BOOTSTRAP.md引导AGENTS.md多代理MEMORY.md静态长期记忆这些文件在启动时只加载一起后续将会组装成系统提示词发送给大模型1.2. 记忆组装记忆组装发生在build_system_prompt这个函数中共分为两层记忆一个是MEMORY.md的静态内容另一个来自__auto_recall混合搜索的记忆1.3. 混合搜索和排序混合搜索策略在MemoryStore.hybrid_search中。 在该函数中首先会load所有的chunk, 然后分别经过关键词搜索使用tf-idf进行搜索得到score向量检索 使用余弦相似度比较向量相似度加权vector_weights * 0.7, keywords_weights * 0.3计算时间衰减从记忆块的path中取时间然后计算与当前时间的age_days, 应用指数衰减score * exp(-decap_rate * age_days), decay_rate0.01, 越近的记忆得分衰减越少越旧的记忆得分越低MMR目的是在保证相关性的同时增加结果的多样性避免返回内容相似的记忆。输入时经过时间衰减后的结果列表每个结果包含score相关性分数 和chunk文本。算法步骤 首先对每条结果进行分词然后初始化已选择集合为空。重复如下步骤 对于每个未选中的结果i计算MMR其中similarity使用 Jaccard 相似度基于分词集合的交并比选择 MMR 最大的结果加入已选集合MMR计算代码如下staticmethod def _mmr_rerank(results, lambda_param0.7): tokenized [MemoryStore._tokenize(r[chunk][text]) for r in results] selected [] remaining list(range(len(results))) reranked [] while remaining: best_idx -1 best_mmr float(-inf) for idx in remaining: relevance results[idx][score] max_sim 0.0 for sel_idx in selected: sim MemoryStore._jaccard_similarity(tokenized[idx], tokenized[sel_idx]) if sim max_sim: max_sim sim mmr lambda_param * relevance - (1 - lambda_param) * max_sim if mmr best_mmr: best_mmr mmr best_idx idx selected.append(best_idx) remaining.remove(best_idx) reranked.append(results[best_idx]) return reranked2. 流程设计