B3 Schema 与 B5 Memory 个人模块

东北大学综合实训Ⅱ - B 方向 Agent 智能体
负责人:王稳淞(20235870)

团队项目说明 · 个人结题技术报告 · 团队完整代码库

B3 与 B5 个人模块架构

1. 模块概述

1.1 模块名称

B3:说明生成与工具调用模块 + B5:记忆文档存储与查找模块

1.2 模块说明

本仓库是我在 B 方向本地 Agent 框架中负责部分的独立交付仓库,包含 B3、B5 的基础要求、当前启用的进阶功能、演示输入和服务器验证产物。

  • B3 位于模型决策与真实工具之间:把工具配置转换为 LLM 可读的 tools_schema,校验 B4 产生的 tool_calls,调用 B2 Skill,并以标准 ToolMessage 返回执行结果。
  • B5 位于 Agent 上下文入口和运行结束位置:加载全局/会话记忆、自动检索相关记忆、控制注入长度,并把一次运行的回答、消息和轨迹保存为可长期复用的 Markdown 记忆。

两部分共同解决了本地 Agent 的两个关键工程问题:一是让模型看到的工具说明与 Python 实现保持一致,二是让跨轮次运行能够检索、压缩和复用历史信息。

1.3 完成情况概览

类型 完成情况
B3 基础要求 读取 tools.yaml;按 toolset 生成 OpenAI Function Calling 风格 Schema;接收、校验和执行 tool_calls;生成 ToolMessage 与 JSONL 日志
B3 进阶要求 Python 函数签名推断/合并 Schema;可恢复格式错误修复;相同 name + args 的成功结果缓存
B5 基础要求 手动加载全局/会话记忆;长度预算与截断;保存 Markdown 记忆;维护 memory_index.json 与操作日志
B5 进阶要求 jieba 关键词 Top-K;本地 FastEmbed 中文向量检索;本地 Qwen 长记忆结构化摘要压缩
可独立演示 code/b3_tool_layer.py、code/b5_memory.py、code/b35_webui_server.py
团队集成 B1 直接导入 B3/B5 函数;B5 上下文注入 System Message;B3 ToolMessage 回流 B1/B4;运行结束调用 B5 保存

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

2.1 运行环境

项目 要求
Python 3.10
操作系统 Linux 优先;macOS/Windows 可运行无 GPU 的基础与关键词演示
基础依赖 PyYAML、jieba
向量检索依赖 numpy、fastembed、onnxruntime
LLM 压缩依赖 PyTorch、Transformers、Accelerate
GPU B3、B5 基础功能和向量检索不要求;Qwen 4B 压缩建议使用 GPU
网络 首次下载模型需要;配置完成后可离线运行

2.2 模型依赖

模型 来源 项目内相对路径 用途
Qwen3.5-4B Qwen/Qwen3.5-4B models/Qwen3.5-4B/ 超长 Memory 的本地结构化摘要压缩
BAAI/bge-small-zh-v1.5 BAAI/bge-small-zh-v1.5 models/embedding_models/fast-bge-small-zh-v1.5/ 512 维中文语义向量检索

模型权重体积较大,按提交要求不纳入 Git。准备方式示例:

# Qwen 模型
huggingface-cli download Qwen/Qwen3.5-4B \
  --local-dir models/Qwen3.5-4B

# 让 FastEmbed 建立其本地缓存目录
python -c "from fastembed import TextEmbedding; TextEmbedding(model_name='BAAI/bge-small-zh-v1.5', cache_dir='models/embedding_models/fast-bge-small-zh-v1.5')"

配置文件默认使用仓库相对路径。模型准备完成后,local_files_only: true 可保证推理阶段不访问外网。

2.3 数据与样例

数据或文件 来源 路径 用途
B3 标准/异常 Tool Call 自行构造 data/messages/b3_*.json Schema、错误恢复、缓存和异常边界演示
B5 长对话输入 自行构造 data/memory_inputs/memory_save_long_input.json 触发 LLM 摘要压缩
世界杯 Memory 集 自行构造 memory_keyword_football/ 关键词与向量检索的可复现对照样例
表格样例 项目自带 data/tables/results.csv B3 调用 B2 table_analyzer
服务器验证产物 实际运行 evidence/outputs/ 报告中的指标与截图证据

2.4 安装步骤

git clone https://gitea.bytevibe.dev/Wws/AgentWwsPart.git
cd AgentWwsPart

conda create -n agent-wws python=3.10 -y
conda activate agent-wws
pip install -r requirements.txt

如果只验收 B3 基础功能和 B5 关键词检索,可先安装最小依赖:

pip install PyYAML jieba

3. 文件结构与接口边界

3.1 文件结构

AgentWwsPart/
├── code/
│   ├── b3_tool_layer.py           # B3 Schema、校验、恢复、缓存与工具执行
│   ├── b5_memory.py               # B5 加载、检索、压缩与保存
│   ├── b35_webui_server.py        # B3/B5 联合演示服务
│   └── common/                    # JSON、路径、日志与公共消息结构
├── configs/
│   ├── tools.yaml                 # 工具定义与 toolset
│   ├── memory.yaml                # 保存/压缩配置
│   ├── memory_keyword_football.yaml # 检索演示配置
│   └── model_b5_local.yaml        # 本地 Qwen 配置
├── skills/                        # B3 演示依赖的 B2 Skill 接口实现
├── data/
│   ├── messages/                  # B3 输入样例
│   ├── memory_inputs/             # B5 保存与压缩输入样例
│   └── tables/                    # 工具执行样例数据
├── memory/                        # 基础全局/会话记忆
├── memory_keyword_football/       # 检索评测记忆集与索引
├── webui_b35/                     # B3/B5 WebUI 静态资源
├── evidence/outputs/              # 精选服务器运行产物
├── docs/images/                   # 架构图与结果图
├── TEAM_README.md                 # 团队项目说明
├── FINAL_REPORT.md                # 个人结题技术报告
└── README.md                      # 当前个人模块说明

3.2 接口边界

类型 来源 / 去向 数据格式 说明
B3 输入 tools.yaml / B1 / B4 YAML、AIMessage.tool_calls 获取工具定义或接收模型工具调用
B3 输出 B1 / B4 / 输出目录 tools_schema、ToolMessage[]、JSONL 提供模型可读 Schema 和可追踪执行结果
B3 下游 B2 Skill Python 函数调用 注入 data_root / output_dir 后执行真实工具
B5 输入 B1 / CLI memory ID、query、messages、trace、answer 选择、检索或保存记忆
B5 输出 B1 / 输出目录 JSON、Markdown 返回选中上下文并记录保存结果
B5 存储 本地 Memory 目录 memory_index.json + *.md 索引与正文分离,支持全局/会话两类记忆

4. 基础要求实现与演示

4.1 B3 基础功能

B3 基础流程为:

tools.yaml + toolset
  -> 读取工具定义
  -> 生成 OpenAI 风格 tools_schema
  -> 接收 AIMessage.tool_calls
  -> 校验工具名、required 参数和 JSON 类型
  -> 调用 B2 Skill
  -> SkillResult -> ToolMessage + tool_call_log.jsonl

核心实现:

文件 / 函数 作用
code/b3_tool_layer.py::get_tools_schema 选择 toolset、构造函数 Schema、输出审计报告
code/b3_tool_layer.py::_validate_args 检查必填字段、未知参数、JSON 类型和数组元素类型
code/b3_tool_layer.py::execute_tool_calls 调用 Skill、包装错误、构造 ToolMessage 与日志
code/common/schemas.py 统一 AIMessage、ToolMessage、SkillResult 数据结构

独立演示:

cd code

# 生成基础 Schema
python b3_tool_layer.py \
  --tools_config ../configs/tools.yaml \
  --toolset basic_tools \
  --schema_source config \
  --export_schema \
  --outdir ../outputs/B3_basic_schema

# 执行标准 Tool Call
python b3_tool_layer.py \
  --tools_config ../configs/tools.yaml \
  --toolset basic_tools \
  --tool_calls ../data/messages/ai_message_with_tool_calls.json \
  --execute \
  --outdir ../outputs/B3_basic_execute

主要输出:tools_schema.json、tool_schema_report.json、tool_schema_audit.json、tool_messages.json、tool_call_log.jsonl。

4.2 B5 基础功能

B5 基础流程为:

memory.yaml + memory_index.json
  -> 按 ID / 全局开关选择记忆
  -> 校验路径不越界
  -> 按 max_memory_chars 组装上下文
  -> selected_memory.json

messages + trace + final answer
  -> 构造 Markdown 记忆
  -> 更新 memory_index.json
  -> saved_memory.json + memory_log.jsonl

核心实现:

文件 / 函数 作用
code/b5_memory.py::_memory_paths 解析并校验 Memory 根目录与字符预算
code/b5_memory.py::load_memory 加载、去重、截断并记录异常
code/b5_memory.py::save_memory 保存全局/会话 Markdown,维护索引与日志
code/b5_memory.py::_safe_conversation_id 防止非法 conversation ID 导致路径穿越

独立演示:

cd code

# 按 ID 加载记忆
python b5_memory.py \
  --config ../configs/memory_keyword_football.yaml \
  --select_memory_ids mem_football_worldcup_goalkeeper \
  --use_global_memory true \
  --outdir ../outputs/B5_basic_load

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

5. 进阶要求实现与演示

5.1 已完成的进阶要求

进阶要求 完成状态 对应实现
B3-1 从 Python 函数自动生成 Schema 已完成 _json_schema_from_annotation、_infer_parameters_from_function、_schema_audit
B3-2 可恢复错误有限修复 已完成 _coerce_value、_recover_tool_call
B3-3 Tool Call 结果缓存 已完成 _cache_key、_read_cache、_write_cache
B5-1 关键词 Top-K 已完成 extract_keywords、search_memory_topk
B5-2 长记忆摘要压缩 已完成 _summarize_with_llm、_compress_memory_document
B5-4 本地向量检索 已完成 search_memory_vector_topk

5.2 B3-1:函数签名推断、合并与审计

B3 支持三种 Schema 来源:

  • config:完全使用 tools.yaml;
  • inferred:读取 Python 函数签名、类型注解、默认值和 required 参数;
  • merged:以真实签名为边界,同时保留 YAML 中更适合 LLM 的人工描述。

data_root 和 output_dir 属于运行时注入参数,不向 LLM 暴露。审计报告会检查缺失、多余、类型不一致和 required 不一致。

signature = inspect.signature(function)
for name, param in signature.parameters.items():
    if name in INJECTED_PARAMETERS:
        injected.append(name)
        continue
    schema = _json_schema_from_annotation(type_hints.get(name, param.annotation))

演示命令:

python code/b3_tool_layer.py \
  --tools_config configs/tools.yaml \
  --toolset extended_tools \
  --schema_source merged \
  --export_schema \
  --outdir outputs/B3_schema_merged

服务器产物显示 10 个工具全部 aligned,warning_tools = 0: 查看报告。

5.3 B3-2:可恢复错误修复

执行前先严格校验;仅对确定可恢复的表示错误进行一次规范化,然后重新校验。支持:

  • 工具名、参数名和字符串首尾空格;
  • 数字字符串转 integer/number;
  • true/false/yes/no 转布尔值;
  • JSON 字符串转数组、对象或完整 args 字典。

缺失 required 参数、未知工具等语义错误不会被猜测修复,而是转换为 status=error 的 ToolMessage,避免 Agent 主循环崩溃。

python code/b3_tool_layer.py \
  --tools_config configs/tools.yaml \
  --toolset basic_tools \
  --tool_calls data/messages/b3_tool_call_recoverable_errors.json \
  --execute \
  --outdir outputs/B3_recovery

恢复日志证据

5.4 B3-3:成功结果缓存

缓存键由规范化后的 name + args 计算 SHA-256。参数 JSON 使用稳定排序,因此键顺序不同但语义相同的调用可命中同一缓存。系统只缓存成功结果,错误不会污染后续运行。

payload = json.dumps(
    {"name": name, "args": args},
    ensure_ascii=False,
    sort_keys=True,
    separators=(",", ":"),
)
cache_key = hashlib.sha256(payload.encode("utf-8")).hexdigest()

缓存命中证据

5.5 B5-1:关键词 Top-K 检索

查询首先由 jieba 分词并过滤停用词。为提高精确度,系统统计关键词文档频率,把高频泛化词与特异词分组,并以以下权重评分:

score = title_hits × 3 + summary_hits × 2 + content_hits

结果同时保留命中词、标题/摘要/正文命中数、过滤阈值和读取异常,便于复现实验。

python code/b5_memory.py \
  --config configs/memory_keyword_football.yaml \
  --query "世界杯中门将的职责是什么?" \
  --retrieval_mode keyword \
  --top_k 2 \
  --min_score 10 \
  --outdir outputs/B5_keyword

现有结果扫描 7 篇文档,Top-1 为“世界杯门将扑救记忆”,得分 13: 查看 selected_memory.json。

5.6 B5-2:本地 Qwen 结构化摘要压缩

保存前先构造完整 Markdown;超过 compression.max_doc_chars 时,把 final_answer + messages + trace 交给本地 Qwen,要求只返回包含以下字段的 JSON:

answer_summary / key_facts / message_summary / trace_summary / open_issues

系统支持从不完整但可识别的模型文本中恢复字段,同时对最终文档再次执行字符预算检查。当前版本采用 LLM-only compression:本地 Qwen 失败时显式报错,不使用规则截断伪装成功。

python code/b5_memory.py \
  --config configs/memory.yaml \
  --model_config configs/model_b5_local.yaml \
  --save_type conversation \
  --save_input_path data/memory_inputs/memory_save_long_input.json \
  --outdir outputs/B5_compress_llm

服务器验证结果:3662 -> 1325 字符,压缩率约 63.8%,parse_error = null。 保存报告 · LLM 摘要

5.7 B5-4:离线中文向量检索

本功能使用 FastEmbed + ONNX Runtime 在 CPU 上加载 BAAI/bge-small-zh-v1.5,对查询与候选记忆编码并计算归一化向量点积。模型和缓存准备完成后,local_files_only=true,无需外网。

python code/b5_memory.py \
  --config configs/memory_keyword_football.yaml \
  --query "足球比赛中守门员负责哪些任务,点球时如何做扑救判断?" \
  --retrieval_mode vector \
  --top_k 2 \
  --use_global_memory true \
  --outdir outputs/B5_vector

现有结果扫描 9 篇文档,Top-1 相似度为 0.739173: 查看 selected_memory.json。相似度用于排序,不被解释为固定概率。

5.8 综合验证结果

B3/B5 验证结果

6. 与团队系统的集成

团队 B1 在 integrated 模式中直接导入:

from b3_tool_layer import get_tools_schema, execute_tool_calls
from b5_memory import load_memory, search_memory_topk, search_memory_vector_topk, save_memory

完整调用关系:

  1. B1 读取用户输入和配置;
  2. B5 按 manual/keyword/vector 选择记忆,B1 将正文拼入 System Message;
  3. B3 生成 tools_schema,供 B4 决策;
  4. B4 返回 tool_calls 后,B3 校验并调用 B2 Skill;
  5. B3 将 ToolMessage 返回,B4 继续生成最终回答;
  6. 运行成功且启用保存时,B1 调用 B5 写回 Memory;
  7. trace.json.memory_retrieval 记录检索模式、Top-K 和实际选中 ID。

团队完整实现与 WebUI 位于:gary/agent。

7. B3/B5 联合 WebUI

python code/b35_webui_server.py --host 127.0.0.1 --port 18089

浏览器打开 http://127.0.0.1:18089/。WebUI 提供 Schema 导出、Tool Call 执行、手动加载、关键词检索、向量检索和 Memory 保存/压缩入口,并展示本次运行产物。

8. 已知问题与后续改进

问题 当前原因 后续改进
本地 Qwen 压缩资源消耗较高 4B 模型加载需要较多显存/内存 增加量化模型与异步压缩队列
向量检索每次重新编码候选文档 当前样例规模较小,优先保证逻辑透明 增加持久化向量索引和增量更新
关键词评分规则依赖领域词分布 手工停用词和固定权重对跨领域适应有限 引入 BM25、领域停用词配置和混合重排
自动 Memory 更新当前停用 合并与冲突策略尚未达到稳定交付标准 补充版本化、人工审核和可回滚机制后再启用
README 旧稿曾包含已下线功能 早期实现范围大于最终个人交付范围 当前仓库以实际启用代码和验证产物为唯一依据

9. 仓库链接

S
Description
No description provided
Readme
20 MiB
0 Stars 1 Watchers 0 Forks
Languages
Python 89.9%
JavaScript 4.3%
CSS 4%
HTML 1.8%