2026-07-14 21:30:16 +08:00
2026-07-14 21:30:16 +08:00
2026-07-14 21:07:28 +08:00

个人模块 README — B5

模块 B5:记忆文档存储与查找模块 | 负责人:张家为 20235947


1. 模块概述

1.1 模块名称

B5 — 记忆文档存储与查找模块 (Memory Storage & Retrieval)

1.2 模块说明

B5 是 Agent 系统的记忆系统,负责管理 Agent 对话的历史记忆和全局知识。它提供两种核心能力:

  1. 记忆加载(load_memory):在 Agent 启动时,根据用户指定的记忆 ID 或检索查询,从本地文件系统中读取记忆文档,注入到 System Prompt 中作为上下文
  2. 记忆保存(save_memory):在 Agent 对话结束后,将本轮对话的 messages、trace、final_answer 保存为 Markdown 记忆文档,并更新索引
B5 在系统流程中的位置:

STAGE 1(对话开始):
  B1 → load_memory(ids, use_global, query) → B5 查找记忆文档 → 返回 selected_memory

STAGE 3(对话结束):
  B1 → save_memory(conv_id, save_type, messages, trace, answer) → B5 写入记忆文档

B5 不参与 STAGE 2 的 Agent Loop,只在对话开始和结束两个阶段被调用。

1.3 完成情况概览

类型 完成情况
基础要求 ✅ 全部完成:读取 memory.yaml 配置、按 ID 加载全局+对话记忆文档、按 max_memory_chars 截断、保存记忆文档(Markdown 格式)、维护 memory_index.json 元数据索引
进阶要求 ✅ 5 项全部完成:关键词检索(BM25+中文分词)、向量检索(Sentence Transformers 语义相似度)、记忆压缩(Qwen 模型压缩冗余内容)、记忆更新(对比新旧内容+冲突检测)、向量检索 top-k 精确匹配
可独立运行的演示 ✅ CLI 独立运行(查找/保存/压缩/更新四个子命令)+ Web Demo 集成
与团队系统集成情况 ✅ 通过 load_memory() 和 save_memory() 被 B1 调用,是 B1 构建初始 messages 和保存对话产物的关键环节

2. 环境、模型与数据依赖

2.1 运行环境

项目 要求
Python 版本 3.10
必要依赖 PyYAML;进阶功能需要 jieba(中文分词)、rank-bm25(BM25 检索)、numpy、sentence-transformers(向量检索);压缩/更新需要 torch + transformers(加载 Qwen3.5-4B)
是否需要模型 基础功能不需要;进阶压缩/更新需要 Qwen3.5-4B
是否需要 GPU 基础功能不需要;压缩/更新建议 GPU
是否需要外部数据集 不需要

2.2 模型依赖

模型 来源 项目内相对路径 用途
Qwen3.5-4B https://www.modelscope.cn/models/Qwen/Qwen3.5-4B 由 memory.yaml 配置 + b5_extension.py 中 MODEL_PATH 常量决定 记忆压缩(MemoryCompressor)和记忆更新(MemoryUpdater)
all-MiniLM-L6-v2 HuggingFace 自动下载 缓存到 ~/.cache/huggingface/ 向量检索(VectorRetriever)的语义编码模型

2.3 数据集或样例数据依赖

数据或文件 来源 项目内相对路径 用途
configs/memory.yaml 项目自带 agent/configs/ 记忆存储路径、最大字符数配置
memory/memory_index.json 项目自带 agent/memory/ 记忆元数据索引
memory/global/*.md 项目自带 agent/memory/global/ 全局记忆文档
memory/conversations/*.md 项目自带 agent/memory/conversations/ 对话记忆文档
data/memory_inputs/memory_save_input.json 项目自带 agent/data/memory_inputs/ 保存记忆的样例输入

2.4 安装步骤

conda create -n b5_env python=3.10 -y
conda activate b5_env
cd agent
pip install -r requirements.txt
# 进阶功能额外依赖:
pip install jieba rank-bm25 sentence-transformers torch transformers

3. 文件结构与接口边界

3.1 文件结构

agent/
├── code/
│   ├── b5_memory.py             # 核心:记忆加载和保存(457行)
│   └── b5_extension.py          # 进阶:检索器+压缩器+更新器(739行)
│       ├── KeywordRetriever     #  BM25 关键词检索(jieba 分词)
│       ├── VectorRetriever      #  Sentence Transformers 向量检索
│       ├── MemoryCompressor     #  Qwen 模型压缩记忆文档
│       ├── MemoryUpdater        #  Qwen 模型对比新旧内容+合并
│       ├── load_all_memory_docs()  #  加载全部记忆文档(用于检索器建索引)
│       └── load_memory_doc_by_path() # 加载单个文档(用于压缩/更新)
├── memory/
│   ├── memory_index.json        # 记忆元数据索引
│   ├── global/                  # 全局记忆目录
│   │   └── *.md
│   └── conversations/           # 对话记忆目录
│       └── *.md
├── configs/
│   └── memory.yaml              # 记忆配置文件
└── B5_VERIFICATION.md           # 模块验证说明书

3.2 接口边界

类型 来源 / 去向 数据格式 说明
输入 B1 → load_memory() 函数调用(config_path + ids + query + retrieval_type) B1 在 Agent 启动时调用
输入 B1 → save_memory() 函数调用(config_path + conv_id + save_type + 产物路径) B1 在 Agent 结束后调用
输出 load_memory() → B1 selected_memory dict(含 docs 数组 + 状态 + 截断信息) 注入到 System Prompt
输出 save_memory() → B1 saved_memory dict(含 memory_id + 路径 + 时间戳) 保存确认
存储 B5 → 磁盘 Markdown 文件(memory/{type}/{conv_id}.md) 记忆文档
存储 B5 → memory_index.json JSON 对象 元数据索引

4. 基础要求实现与演示

4.1 基础功能说明

功能 入口函数 说明
记忆加载 load_memory() 按 ID 加载 + 全局记忆合并 + 按 max_memory_chars 截断
记忆保存 save_memory() 将 messages + trace + final_answer 写入 Markdown 文档 + 更新索引
索引管理 memory_index.json 记录 memory_id、类型、标题、摘要、路径、创建/更新时间

4.2 基础功能实现路径

文件 / 函数 作用
b5_memory.py:_memory_paths() 读取 memory.yaml,解析 root_dir/global_dir/conversation_dir/index_path/max_chars
b5_memory.py:_read_index() 读取 memory_index.json,返回 {memory_id: metadata} 字典
b5_memory.py:load_memory() 主加载流程:收集 ID → 逐个读取文件 → 截断 → 返回 selected_memory
b5_memory.py:_parse_memory_markdown() 解析记忆文档的 Markdown 结构(## Final Answer / ## Messages / ## Trace)
b5_memory.py:save_memory() 主保存流程:构建 Markdown → 写入文件 → 更新索引
b5_memory.py:_safe_conversation_id() 校验 conversation_id 只含合法字符

4.3 基础功能演示命令

cd agent/code

# 查找记忆
python b5_memory.py --config ../configs/memory.yaml \
  --select_memory_ids mem_conversation_conv_000 \
  --use_global_memory true --query "Agent 系统如何调用工具?" \
  --outdir ../outputs/B5_memory

# 保存对话记忆
python b5_memory.py --config ../configs/memory.yaml \
  --save_type conversation \
  --save_input_path ../data/memory_inputs/memory_save_input.json \
  --outdir ../outputs/B5_memory

观察要点:

  • selected_memory.json 包含匹配的记忆文档列表,每篇含 memory_id、content、included_chars、truncated
  • saved_memory.json 确认保存成功,memory/conversations/conv_sample_001.md 被创建
  • memory_index.json 被更新,新增或更新对应记忆的元数据

4.4 基础功能输出格式

输出文件 格式 说明
selected_memory.json JSON 对象 选中的记忆文档列表 + 状态 + 截断信息 + 错误列表
saved_memory.json JSON 对象 memory_id + 类型 + 标题 + 路径 + 时间戳
memory_log.jsonl JSONL 记忆查找/保存的累计日志
memory/{type}/{conv_id}.md Markdown 记忆文档(含 Final Answer + Messages + Trace)

5. 进阶要求实现与演示

5.1 选择的进阶要求

进阶要求 是否完成 对应文件 简要说明
进阶1:关键词检索 ✅ b5_extension.py:KeywordRetriever BM25 + jieba 中文分词 + 相关度打分
进阶2:向量检索 ✅ b5_extension.py:VectorRetriever Sentence Transformers 语义编码 + 余弦相似度
进阶3:记忆压缩 ✅ b5_extension.py:MemoryCompressor Qwen 模型压缩冗余内容,保持 Markdown 格式结构
进阶4:记忆更新 ✅ b5_extension.py:MemoryUpdater 对比新旧内容,去重/合并/冲突检测
进阶5:top-k 检索 ✅ load_memory() 参数 keyword/vector 检索时返回 top_k 个最相关文档

5.2 三种检索模式对比

load_memory() 的 retrieval_type 参数支持三种模式:

模式 实现 原理 适用场景
id(默认) 按 ID 逐个读文件 直接文件读取 精确加载已知记忆
keyword KeywordRetriever(BM25 + jieba) 对全部记忆文档建 BM25 索引,用 query 分词后搜索 关键词匹配检索
vector VectorRetriever(Sentence Transformers) 用 all-MiniLM-L6-v2 编码全部文档+query,计算余弦相似度 语义相似度检索

5.3 进阶1:关键词检索(BM25)

KeywordRetriever 实现:

  • 中文分词:使用 jieba.cut() 分词,过滤单字符
  • 索引构建:BM25Okapi 对全部文档建索引
  • 搜索:对 query 分词后计算 BM25 分数,返回 top_k 结果
  • 相关性分数:relevance_score 字段标注 BM25 分数

5.4 进阶2:向量检索(Sentence Transformers)

VectorRetriever 实现:

  • 编码模型:all-MiniLM-L6-v2(轻量、多语言支持)
  • 文档编码:model.encode() 批量编码 + 归一化
  • 相似度:np.dot(embeddings, query_embedding) 余弦相似度
  • 阈值过滤:相似度 ≥ 0.1 才返回

5.5 进阶3:记忆压缩

MemoryCompressor 使用本地 Qwen3.5-4B 模型压缩记忆文档:

  • 自动检测文档格式(standard:含章节结构 / simple:纯文本)
  • 保持原有 Markdown 格式结构不变(标题层级、JSON 代码块、元信息列表)
  • 只精简文本内容,不改变文档框架
  • 支持 max_chars 限制
# 手动压缩
python b5_memory.py --config ../configs/memory.yaml \
  --compress memory/conversations/conv_001.md \
  --outdir ../outputs/B5_memory

5.6 进阶4:记忆更新

MemoryUpdater 对比新旧内容并合并:

  • 重复信息:去重
  • 补充信息:合并到对应部分
  • 矛盾信息:标记 > **冲突提醒**:[描述差异]
  • 保持原有 Markdown 格式结构不变
# 手动更新(需要 _new.md 文件)
python b5_memory.py --config ../configs/memory.yaml \
  --update memory/conversations/conv_001.md \
  --outdir ../outputs/B5_memory

6. 与团队系统的集成说明

B5 通过两个公开函数被 B1 调用:

# B1 调用位置:b1_agent_runtime.py 第371行
from b5_memory import load_memory

# 第376-379行:加载记忆
selected_memory = load_memory(
    str(memory_file), runtime["selected_memory_ids"],
    runtime["use_global_memory"], runtime["user_input"], str(output_dir),
    retrieval_type=runtime.get("retrieval_type", "keyword"), top_k=5,
)

# 第631行:保存记忆
from b5_memory import save_memory
saved_memory = save_memory(
    str(memory_file), runtime["conversation_id"], runtime["save_memory"],
    str(output_dir / "messages.json"), str(output_dir / "trace.json"),
    str(output_dir / "final_answer.md"), str(output_dir),
)

B5 的 load_memory() 返回的 selected_memory 被 B1 的 _memory_context() 函数转换为 XML 标签后注入 System Prompt。save_memory() 在 B1 的 Agent Loop 结束后调用,仅在 save_memory != "none" 且状态为 success 时触发。


7. 已知问题与后续改进

问题 当前原因 后续改进
向量检索首次加载模型较慢 all-MiniLM-L6-v2 需从 HuggingFace 下载 可预下载到本地,或使用更轻量的模型
压缩/更新需加载 Qwen 模型 懒加载策略,但首次使用仍需等待 可预加载模型到内存常驻
记忆文档仅支持 Markdown 格式 设计如此,统一格式便于解析 可扩展支持更多格式
索引为单文件 JSON 大规模记忆时文件变大 可考虑 SQLite 替代
S
Description
No description provided
Readme
57 KiB
0 Stars 1 Watchers 0 Forks
Languages
Python 71.7%
HTML 28.3%