MOSAIC:本地工具调用与记忆增强 Agent 框架
东北大学综合实训 II · B 方向 Agent 智能体团队项目
MOSAIC(Memory-Oriented Skill-powered Agent with Interactive Coordination)是一套基于 Python 3.10 和本地 Qwen3.5-4B 的模块化 Agent 框架。项目把运行时、工具函数、工具调用层、本地模型和 Memory 拆分为 B1-B5 五个模块,通过统一的 AIMessage、ToolMessage 和 SkillResult 数据结构完成从用户输入到工具执行、最终回答和记忆读写的可追踪闭环。
团队代码库:https://gitea.bytevibe.dev/gary/agent
1. 项目概述
1.1 项目名称
MOSAIC: Memory-Oriented Skill-powered Agent with Interactive Coordination
1.2 项目目标
项目面向本地大模型的工具增强任务,解决本地 LLM 难以稳定执行文件读取、计算、检索、代码运行和记忆管理等外部动作的问题。系统的目标是让模型只负责理解任务和提出 tool_calls,由确定性的工具层完成校验与执行,再把结构化结果返回给模型生成最终回答。
1.3 当前完成情况
| 类型 | 完成情况 |
|---|---|
| 基础要求 | 完成 B1-B5 独立入口、统一消息协议、基础工具调用、Memory 读写、日志和完整 Agent 联调。 |
| 进阶要求 | 完成 10 个 B2 Skill、B3 Schema 推断/审计/恢复/缓存/统计、B4 Plan-and-Execute、本地模型 prompt_json 决策、B5 关键词/向量检索与长记忆压缩,以及 B1 checkpoint、批量和多轮运行能力。 |
| 支持的主要任务类型 | 文本问答、文件读取、本地文档检索、表格统计、格式转换、PDF/DOCX/PPTX 读取、受限 Python 执行、单元测试验证、Web 搜索和记忆增强回答。 |
| 当前限制 | 真实 prompt_json 运行需要本地模型和较充足的计算资源;Web 搜索受网络环境影响;B5 的自动 Memory 更新默认关闭;Python 沙箱属于课程演示级隔离,不作为生产级安全执行环境。 |
2. 整体流程与模块结构
2.1 模块边界
| 模块 / 阶段 | 入口文件 / 入口函数 | 主要职责 | 输入 | 输出 |
|---|---|---|---|---|
| B1 Agent Runtime | code/b1_agent_runtime.py::run_agent |
读取任务、维护消息历史、控制轮次、协调 B3/B4/B5、汇总运行产物。 | Runtime JSON、工具/模型/Memory 配置 | messages.json、trace.json、final_answer.md |
| B2 Skill Layer | code/b2_run_skill.py、skills/*.py |
提供计算、文件、检索、表格、转换、文档解析和受限代码执行能力。 | Skill JSON 或 B3 注入的函数参数 | SkillResult、生成文件、Skill 日志 |
| B3 Tool Layer | code/b3_tool_layer.py |
生成和审计 tools_schema,校验/恢复 tool call,动态调用 B2,并处理缓存和统计。 |
configs/tools.yaml、AIMessage.tool_calls |
ToolMessage、Schema、调用日志 |
| B4 Local LLM | code/b4_local_agent_llm.py、code/b4/ |
使用 mock 或本地 Qwen3.5-4B 生成标准 AIMessage,决定工具调用或最终回答。 |
messages、tools_schema、模型配置 |
AIMessage、模型输出和推理日志 |
| B5 Memory | code/b5_memory.py |
加载、检索、截断、压缩和保存本地 Memory,并维护索引。 | Memory 配置、ID、query、messages/trace/answer | selected_memory.json、saved_memory.json、Memory Markdown |
| 完整 Demo | code/run_full_demo.py |
以 B1 integrated 模式运行完整 Agent,并汇总结果。 | Runtime 输入和三类配置 | 完整运行产物、demo_report.md |
2.2 系统架构图或流程图
flowchart LR
User[用户输入] --> B1[B1 Agent Runtime]
B1 --> B5[B5 Memory]
B1 --> B3[B3 Tool Layer]
B1 --> B4[B4 Local LLM]
B4 -->|AIMessage / tool_calls| B1
B3 -->|动态导入并执行| B2[B2 Skill Layer]
B2 --> Data[本地文档 / 表格 / 输入样例]
B2 --> Web[Mock 或真实 Web Search]
B2 -->|SkillResult| B3
B3 -->|ToolMessage| B1
B1 --> Outputs[Messages / Trace / Final Answer / Memory]
数据流核心是:B4 只生成 AIMessage,B3 根据 tools.yaml 校验并执行 tool_calls,B2 返回可 JSON 序列化的 SkillResult,B3 再将其封装为 ToolMessage,最后 B1 把工具结果交回 B4。
2.3 一次完整任务的流程
- B1 读取
data/runtime_input_b2_document_reader.json(或其他runtime_input*.json)、系统提示词、工具配置、模型配置和 Memory 配置。 - B5 按手动 ID、关键词或向量策略检索记忆,并把选中的内容注入初始消息。
- B3 根据
configs/tools.yaml生成当前toolset的tools_schema。 - B4 接收
messages + tools_schema,生成最终回答型或工具调用型AIMessage。 - B3 对工具名、参数、必填字段和类型进行校验,必要时修复可恢复的格式错误。
- B3 动态调用 B2 Skill。B2 执行成功返回业务对象,异常返回带
error.code的结构化结果。 - B3 将结果写入
ToolMessage,B1 追加消息并再次调用 B4 生成最终回答。 - B1 将
messages.json、trace.json、tool_messages.json、final_answer.md和日志写入独立输出目录;需要保存时由 B5 写入会话或全局 Memory。
3. 模型、数据集与外部资源
3.1 模型说明
| 项目 | 内容 |
|---|---|
| 主模型 | Qwen/Qwen3.5-4B,本地 Transformers 推理,用于 B4 工具决策和最终回答。 |
| 主模型路径 | 默认由 configs/model.yaml 指向仓库外的 ../../Qwen3.5-4B;单独克隆团队仓库后需要按本机路径修改 model_name_or_path 和 tokenizer_name_or_path。 |
| 嵌入模型 | BAAI/bge-small-zh-v1.5,由 B5 的 FastEmbed 向量检索使用。 |
| 嵌入缓存 | 默认位于 models/embedding_models/fast-bge-small-zh-v1.5,可在 configs/memory.yaml 中调整。 |
| GPU 要求 | B2、B3、B1 mock 和关键词 Memory 可使用 CPU;真实 Qwen 推理和 Memory LLM 压缩建议使用 GPU。 |
| 联网要求 | mock 模式和本地 Skill 不需要联网;web_search live 模式以及首次下载模型/嵌入模型需要网络。 |
项目不把大模型权重和运行环境提交到 Git。没有模型时可以使用 --llm_mode mock 完成模块协议和工具链路验收。
3.2 数据集 / 示例数据说明
| 数据或文件 | 用途 | 来源 | 项目内相对路径 |
|---|---|---|---|
| Runtime 输入 | 完整 Agent、B1 和 B5 集成演示 | 项目构造 | data/runtime_input*.json |
| Skill 输入 | B2 各 Skill 正常/异常运行 | 项目构造 | data/tool_inputs/ |
| Tool Call 输入 | B3 Schema、执行、恢复、缓存和统计演示 | 项目构造 | data/messages/ |
| Memory 输入 | B5 保存、检索和压缩演示 | 项目构造 | data/memory_inputs/ |
| 本地文档 | 文件读取、检索和文档解析 | 项目自带 | data/docs/、data/documents/ |
| 表格样例 | CSV/TSV 分析 | 项目自带 | data/tables/ |
4. 环境安装
4.1 运行环境
| 项目 | 要求 |
|---|---|
| Python | 3.10 |
| 服务器验证环境 | Linux/CUDA 环境;B2、B3 和 mock 模式也支持无 GPU 验收。 |
| 主要依赖 | PyTorch、Transformers、PyYAML、jieba、FastEmbed、ONNX Runtime、PyMuPDF 等,详见 requirements.txt。 |
| 前端 | 原生 HTML/CSS/JavaScript;完整 Agent WebUI 和 B2 Skill WebUI 使用 Python HTTP 服务提供静态页面。 |
4.2 安装步骤
git clone https://gitea.bytevibe.dev/gary/agent.git
cd agent
conda create -n agent python=3.10 -y
conda activate agent
export PYTHONNOUSERSITE=1
pip install -r requirements.txt
然后准备 Qwen3.5-4B 和可选的 BAAI 嵌入模型,并修改 configs/model.yaml、configs/memory.yaml 中的本地路径。运行命令默认从 agent/code 目录执行:
cd code
常见问题:模型路径不存在时使用 mock 模式验收;显存不足时降低模型生成参数或只运行 B2/B3;FastEmbed 启用 local_files_only 时应先准备本地缓存。
5. 输入文件与配置文件说明
5.1 主要配置文件
| 配置文件 | 作用 | 需要修改的字段 |
|---|---|---|
configs/tools.yaml |
定义 basic_tools/extended_tools、Skill 模块、参数和返回结构。 |
default_toolset、settings.data_root、工具参数 |
configs/model.yaml |
定义 B4 本地模型和生成参数。 | model_name_or_path、tokenizer_name_or_path、torch_dtype、device_map |
configs/memory.yaml |
定义 Memory 路径、字符预算、向量检索和压缩策略。 | root_dir、max_memory_chars、向量缓存和压缩配置 |
configs/expert_models.yaml |
B4 专家模型/资源选择扩展配置。 | 模型条目及适用任务 |
5.2 主要输入文件
| 输入文件 | 用途 | 适用场景 |
|---|---|---|
data/runtime_input_b2_document_reader.json |
完整 B1 integrated 任务 | 完整系统演示 |
data/runtime_input_b5_auto_memory.json |
B5 自动向量 Memory 检索 | 集成演示 |
data/runtime_input_b5_keyword_memory.json |
B5 关键词 Memory 检索 | 集成演示 |
data/tool_inputs/tool_input_*.json |
B2 Skill 正常样例 | 模块演示 |
data/tool_inputs/tool_input_*_error.json |
B2 异常样例 | 错误处理和安全边界 |
data/messages/b3_tool_call_*.json |
B3 Tool Call 样例 | 工具校验、恢复、缓存和统计 |
data/memory_inputs/ |
B5 保存、长记忆和摘要输入 | Memory 演示 |
6. 完整流程 Demo 运行
6.1 Demo 样例说明
| Demo | 输入文件 / 输入内容 | 演示目的 |
|---|---|---|
| 本地模型完整 Agent | data/runtime_input_b2_document_reader.json |
验证 B1-B5 的消息、工具和 Memory 闭环。 |
| Mock 完整链路 | data/runtime_input_b2_calculator.json |
无 GPU/无模型时验证模块协议和产物生成。 |
| B2 Skill Console | data/tool_inputs/ 下的正常/异常样例 |
在浏览器中选择 Skill、执行工具并查看 SkillResult。 |
| 完整 Agent WebUI | 用户输入 + extended_tools |
浏览器中观察用户消息、ToolMessage、最终回答和 Trace。 |
6.2 运行命令
完整本地模型流程:
cd agent/code
python run_full_demo.py \
--input ../data/runtime_input_b2_document_reader.json \
--tools_config ../configs/tools.yaml \
--memory_config ../configs/memory.yaml \
--model_config ../configs/model.yaml \
--llm_mode prompt_json \
--outdir ../outputs/full_demo
无 GPU 的协议验收:
cd agent/code
python run_full_demo.py \
--input ../data/runtime_input_b2_calculator.json \
--tools_config ../configs/tools.yaml \
--memory_config ../configs/memory.yaml \
--model_config ../configs/model.yaml \
--llm_mode mock \
--outdir ../outputs/full_demo_mock
mock 模式使用规则生成工具调用,主要用于验证 B1-B5 的接口、消息流和产物完整性,不用于评价本地模型的任务理解能力;需要测试真实工具选择时使用 --llm_mode prompt_json。
B2 Skill WebUI:
cd agent/code
python b2_webui_server.py --host 127.0.0.1 --port 18087
浏览器访问 http://127.0.0.1:18087/。完整 Agent WebUI 使用:
cd agent/code
python full_demo_webui_server.py --host 127.0.0.1 --port 18088
浏览器访问 http://127.0.0.1:18088/。
6.3 关键参数说明
| 参数 | 说明 |
|---|---|
--input |
Runtime 任务、conversation、toolset、最大轮次和 Memory 策略。 |
--tools_config |
B2/B3 工具定义、Schema 参数和数据根目录。 |
--memory_config |
B5 存储、检索、压缩和字符预算。 |
--model_config |
B4/B5 的本地模型配置。 |
--llm_mode |
prompt_json 使用本地模型;mock 使用规则模拟并跳过模型加载。 |
--outdir |
本次运行的独立输出目录,建议每次使用新目录。 |
6.4 运行成功的判断方式
- 进程退出码为 0,且没有配置或模块加载错误;
trace.json中的status为success;messages.json按顺序包含system、user、assistant,发生工具调用时还包含tool;final_answer.md非空;tools_schema.json、tool_messages.json和selected_memory.json可以正常解析;- 启用 Memory 保存时,输出目录或 Memory 根目录中出现对应保存结果和索引更新。
7. 输出文件与结果说明
7.1 主要输出文件
| 输出文件 | 生成模块 / 阶段 | 格式 | 说明 |
|---|---|---|---|
outputs/full_demo/messages.json |
B1 | JSON | 完整消息流。 |
outputs/full_demo/trace.json |
B1 | JSON | 状态、轮次、LLM、工具、Memory 和错误轨迹。 |
outputs/full_demo/final_answer.md |
B1/B4 | Markdown | 最终回答。 |
outputs/full_demo/tools_schema.json |
B3 | JSON | 当前模型可见的工具说明。 |
outputs/full_demo/tool_messages.json |
B3 | JSON | 工具执行后生成的标准 ToolMessage。 |
outputs/full_demo/tool_call_log.jsonl |
B3 | JSONL | 参数、恢复、缓存、状态和耗时日志。 |
outputs/full_demo/selected_memory.json |
B5 | JSON | 选中的 Memory、检索信息和截断结果。 |
outputs/full_demo/demo_report.md |
Full Demo | Markdown | 一次完整运行的状态、消息流、最终回答和产物清单。 |
outputs/B2_skills/*_result.json |
B2 | JSON | 各 Skill 的 SkillResult。 |
outputs/B3_tools/tool_stats_report.json |
B3 | JSON | 工具调用次数、成功率、失败率、耗时和缓存统计。 |
7.2 运行结果与结果图例
典型完整运行的消息角色顺序为:
system -> user -> assistant(tool_calls) -> tool -> assistant(final)
典型成功产物会同时包含 trace.json、messages.json、final_answer.md、tools_schema.json 和 tool_messages.json。B2 的具体运行截图和 Skill 结果图例位于个人 B2 仓库的 docs/images/;团队运行后可在 outputs/full_demo/ 和 outputs/B3_tools/ 中查看原始产物。outputs/ 下的运行结果属于可重新生成的实验产物,不要求作为源代码提交。
8. 协作实现说明
团队采用 B1-B5 分层协作,并以统一数据契约降低模块之间的耦合:
| 成员 / 模块 | 主要工程范围 | 协作接口 |
|---|---|---|
| 刘海强 / B1 | Runtime、消息管理、多轮运行和产物汇总 | 调用 B3/B4/B5,维护完整 messages 和 trace。 |
| 淦方毅 / B2 | 基础/扩展 Skill、统一执行入口和 B2 WebUI | 向 B3 提供可动态导入的 Python 函数和 SkillResult。 |
| 王稳淞 / B3+B5 | Tool Schema、工具校验执行、Memory 检索与保存 | 向 B1/B4 提供 tools_schema、ToolMessage 和 Memory 上下文。 |
| 程宇山 / B4 | 本地 LLM、AIMessage、Plan-and-Execute 和评估 | 消费 messages/tools_schema,返回标准 AIMessage。 |
协作约定如下:
common/schemas.py统一AIMessage、ToolMessage和SkillResult的字段与状态;configs/tools.yaml统一工具名、函数名、参数和返回说明;- B2 Skill 的函数名必须与 Schema 中的
function一致,输出必须是可 JSON 序列化对象; - B3 统一注入
data_root和output_dir,避免模型直接接触内部路径; - 使用 JSON/JSONL/Markdown 产物保存可复查证据;
- B1 提供 mock/integrated 两种模式,降低模型和 GPU 不可用时的联调成本;
- 各模块通过 Git 提交合并,并使用独立输出目录避免不同实验相互覆盖。
9. 已知问题与改进方向
| 问题 | 当前原因 | 可能改进 |
|---|---|---|
| 本地模型部署成本较高 | Qwen3.5-4B 需要模型权重和较充足的显存/内存。 | 增加量化模型、模型常驻和请求队列。 |
| Web 搜索受网络影响 | live 模式依赖外部搜索站点和当前网络。 | 保留 mock fixture,并增加可替换搜索后端。 |
| Memory 自动更新默认关闭 | 自动写回需要冲突处理、版本控制和回滚策略。 | 增加版本化 Memory、人工审核和可回滚更新。 |
| 向量检索依赖本地嵌入缓存 | 首次运行需要准备 FastEmbed 模型缓存。 | 增加缓存检查脚本和离线初始化包。 |
| Python 沙箱不是生产级隔离 | 当前依赖 AST 检查、最小内建、子进程和超时。 | 使用容器/Firejail,并增加 CPU、内存、文件系统、网络和进程数限制。 |
| 配置路径依赖运行环境 | 模型和嵌入模型路径通常位于团队仓库之外。 | 增加启动前路径审计,并提供相对路径配置模板。 |
10. 项目链接
- 团队完整代码库:https://gitea.bytevibe.dev/gary/agent
- B1 个人模块仓库:https://gitea.bytevibe.dev/Leon/b1-agent-runtime
- B2 个人模块仓库:https://gitea.bytevibe.dev/gary/agent-B2
- B3 个人模块仓库:https://gitea.bytevibe.dev/Wws/AgentWwsPart
- B4 个人模块仓库: https://github.com/Cys710/Agent-B4
- B5 个人模块仓库:https://gitea.bytevibe.dev/Wws/AgentWwsPart