main
团队项目 README
B 方向:本地 Agent 框架 | 小组:小牛向前冲
1. 项目概述
1.1 项目名称
本地 Agent 框架 (Local Agent Framework) — B 方向
1.2 项目目标
本项目实现一个本地文件驱动的 Agent 框架,使用服务器本地 Qwen3.5-4B 模型,支持用户通过自然语言与 Agent 交互。Agent 能够:
- 加载历史记忆和全局知识作为上下文
- 根据用户输入判断是否需要调用工具
- 调用工具(读取文件、计算表达式、搜索文件、分析表格、转换格式、执行安全代码)
- 基于工具返回结果生成最终回答
- 将本轮对话保存为记忆,供后续对话使用
整个系统采用 ReAct(Reasoning + Acting)模式:LLM 推理 → 决定调用哪个工具 → 执行工具 → 结果回填 → 再次推理,循环直到获得最终回答。
1.3 当前完成情况
| 类型 | 完成情况 |
|---|---|
| 基础要求 | ✅ 全部完成:5 个模块独立运行、Agent Loop 完整闭环、tools_schema 生成、tool_calls 执行、记忆加载与保存、本地 LLM 推理 |
| 进阶要求 | ✅ B1(5 项)、B2(5 项)、B3(5 项)、B4(4 项)、B5(5 项),全部完成 |
| 支持的主要任务类型 | 文件阅读与总结、数学计算、文件搜索、表格分析、格式转换、安全代码执行、组合任务(搜索+分析、读取+转换) |
| 当前限制 | 需要 GPU 运行真实模型推理(mock 模式可脱离 GPU 调试);B4 仅支持 Qwen3.5-4B |
2. 整体流程与模块结构
2.1 模块边界
| 模块 | 入口文件 | 负责人 | 主要职责 | 输入 | 输出 |
|---|---|---|---|---|---|
| B1 Runtime | code/b1_agent_runtime.py |
李子博 | Agent 总控调度、消息管理、循环控制 | runtime_input.json + 配置文件 |
messages.json、trace.json、final_answer.md |
| B2 Skills | code/b2_run_skill.py |
黄明涛 | 8 个具体工具函数实现 | 工具名 + 参数字典 | SkillResult(output/error/latency) |
| B3 Tool Layer | code/b3_tool_layer.py |
周炜伦 | Schema 生成、工具调用校验与执行 | tools.yaml + tool_calls | tools_schema (OpenAI 格式)、ToolMessage |
| B4 LLM | code/b4_local_agent_llm.py |
乔泽冠 | 本地 Qwen3.5-4B 推理 | messages + tools_schema | AIMessage(content 或 tool_calls) |
| B5 Memory | code/b5_memory.py |
张家为 | 记忆文档加载与保存 | memory.yaml + 记忆 ID | selected_memory、saved_memory |
2.2 系统架构图
┌──────────────────────┐
│ 用户浏览器 │
│ unified_demo:8090 │
└──────────┬───────────┘
│ runtime_input.json
▼
┌────────────────────────────────────────┐
│ B1 Agent Runtime (李子博) │
│ b1_agent_runtime.py │
│ │
│ ┌─────────────────────────────────┐ │
│ │ Agent Loop (ReAct) │ │
│ │ │ │
│ │ B4 ←── messages ──→ B1 │ │
│ │ (乔泽冠) AIMessage │ │ │
│ │ │ │ │
│ │ tool_calls │ │
│ │ ▼ │ │
│ │ B3 ←── execute ──→ B1 │ │
│ │ (周炜伦) ToolMessage │ │ │
│ │ │ │ │
│ │ B2 Skills │ │
│ │ (黄明涛) │ │
│ └─────────────────────────────────┘ │
│ │
│ B5 Memory (张家为) ←── load/save ──→ │
│ memory/ 目录 │
└────────────────────────────────────────┘
│
▼
产物: messages.json
trace.json
final_answer.md
2.3 一次完整任务的流程
- 用户输入:前端(
unified_demo_server.py端口 8090)将用户输入和配置组装为runtime_input.json,调用 B1 的run_agent() - 记忆加载:B1 调用 B5
load_memory(),从memory/目录加载全局记忆和用户指定的对话记忆 - 工具描述获取:B1 调用 B3
get_tools_schema(),从configs/tools.yaml生成 OpenAI 格式的工具描述 - 初始消息构建:B1 将 System Prompt + 记忆上下文 + 用户输入拼接为
[SystemMessage, HumanMessage] - Agent Loop(循环):
- B1 调用 B4
generate_ai_message(messages, tools_schema),B4 加载 Qwen3.5-4B 推理,返回 AIMessage - 若 AIMessage 包含
tool_calls→ B1 调用 B3execute_tool_calls(),B3 校验参数后调用 B2 的 Skill 函数,返回 ToolMessage → 追加到 messages → 回到 B4 - 若 AIMessage 无
tool_calls→ 提取 content 作为 final_answer,退出循环 - 若超过
max_turns限制 → 终止循环
- B1 调用 B4
- 产物输出:B1 写入
messages.json(完整消息序列)、trace.json(执行轨迹)、final_answer.md(最终回答) - 记忆保存:B1 调用 B5
save_memory(),将本轮对话保存为 Markdown 记忆文档,更新memory_index.json - 前端展示:B1 返回结果给前端,前端渲染最终回答和中间过程
3. 模型、数据集与外部资源
3.1 模型说明
| 项目 | 内容 |
|---|---|
| 使用模型 | Qwen3.5-4B |
| 模型来源 | https://www.modelscope.cn/models/Qwen/Qwen3.5-4B |
| 项目内相对路径 | 由 configs/model.yaml 中 model_name_or_path 指定 |
| 是否需要 GPU | 真实推理需要;mock 模式不需要 |
| 是否需要联网运行 | 不需要(模型本地加载) |
# 模型下载(通过 modelscope)
pip install modelscope
python -c "from modelscope import snapshot_download; snapshot_download('Qwen/Qwen3.5-4B', cache_dir='./Qwen3.5-4B')"
3.2 数据集 / 示例数据说明
| 数据或文件 | 用途 | 来源 | 项目内相对路径 |
|---|---|---|---|
docs/agent_intro.txt |
file_reader 读取目标 | 项目自带 | agent/data/docs/ |
docs/tool_calling.md |
file_reader 读取目标 | 项目自带 | agent/data/docs/ |
docs/search_skill_demo.md |
file_reader 读取目标 | 项目自带 | agent/data/docs/ |
tables/results.csv |
table_analyzer 分析目标 | 项目自带 | agent/data/tables/ |
tool_inputs/*.json |
B2 各 Skill 输入样例 | 项目自带 | agent/data/tool_inputs/ |
memory/ 目录 |
B5 记忆文档 | 项目自带 | agent/memory/ |
b1_fixtures/ |
B1 Fixture 模式预设数据 | 项目自带 | agent/data/b1_fixtures/ |
4. 环境安装
4.1 运行环境
| 项目 | 要求 |
|---|---|
| Python 版本 | 3.10 |
| 操作系统 / 服务器环境 | Linux (Ubuntu 20.04+) / Windows |
| GPU 要求 | 真实推理需要 GPU(Qwen3.5-4B ~8GB 显存);mock 模式无 GPU 也可调试 |
| 主要依赖 | PyYAML, torch, transformers, jieba, rank-bm25, sentence-transformers, numpy |
4.2 安装步骤
# 1. 克隆项目
git clone <项目地址>
cd assignment_B
# 2. 创建 conda 环境
conda create -n agent_env python=3.10 -y
conda activate agent_env
# 3. 安装依赖
cd agent
export PYTHONNOUSERSITE=1
pip install -r requirements.txt
# 4. 进阶功能额外依赖(B2/B5 检索+压缩)
pip install jieba rank-bm25 sentence-transformers
# 5. 配置模型路径
# 编辑 agent/configs/model.yaml,将 model_name_or_path 改为模型实际路径
常见问题:
- 模型路径不存在:检查
configs/model.yaml中model_name_or_path是否指向正确的 Qwen3.5-4B 目录 - GPU 显存不足:使用
--llm_mode mock进行调试,不需要加载模型 - rank_bm25 导入失败:在 conda 环境中
pip install rank-bm25
5. 输入文件与配置文件说明
5.1 主要配置文件
| 配置文件 | 作用 | 需要修改的字段 |
|---|---|---|
configs/tools.yaml |
B3 工具定义(8 个工具的 module/function/description/parameters/returns) | settings.data_root 指向数据目录 |
configs/memory.yaml |
B5 记忆存储路径和 max_memory_chars 上限 |
memory.root_dir、max_memory_chars |
configs/model.yaml |
B4 模型路径和推理参数 | model_name_or_path(改为实际模型路径) |
prompts/*.txt |
System Prompt 模板(4 套) | 无需修改 |
5.2 主要输入文件
| 输入文件 | 用途 | 适用场景 |
|---|---|---|
data/runtime_input.json |
file_reader 主线任务 | 全系统集成演示 |
data/runtime_input_0.json |
无工具倾向任务 | 验证模型直接回答 |
data/runtime_input_2~5.json |
calculator/file_search/table/convert 任务 | 验证不同工具 |
data/b1_fixtures/b1_fixture_input.json |
B1 Fixture 模式预设数据 | B1 独立演示(不依赖其他模块) |
data/batch_input_demo.json |
批量任务输入样例 | 批量处理演示 |
data/tool_inputs/tool_input_*.json |
每个 Skill 的输入样例 | B2 独立演示 |
6. 完整流程 Demo 运行
6.1 Demo 样例说明
| Demo | 输入文件 | 演示目的 |
|---|---|---|
| 全系统 Mock 演示 | data/runtime_input.json |
串联 B1+B3+B4+B5,B4 使用 mock 模式,验证完整 Agent Loop |
| 全系统真实模型演示 | data/runtime_input.json |
使用 Qwen3.5-4B 真实推理,端到端完成文件阅读+总结任务 |
| 批量任务演示 | data/batch_input_demo.json |
一次运行 5 个任务,每个任务使用不同工具 |
| B1 独立演示(Fixture) | data/b1_fixtures/b1_fixture_input.json |
B1 不依赖 B2-B5 和 GPU,用预设 JSON 完成消息闭环 |
6.2 运行命令
cd agent/code
# Demo 1: 全系统 Mock 演示(不需要 GPU)
python b1_agent_runtime.py \
--input ../data/runtime_input.json \
--tools_config ../configs/tools.yaml \
--memory_config ../configs/memory.yaml \
--model_config ../configs/model.yaml \
--llm_mode mock \
--outdir ../outputs/B1_runtime
# Demo 2: 全系统真实模型演示(需要 GPU)
python run_full_demo.py \
--input ../data/runtime_input.json \
--tools_config ../configs/tools.yaml \
--memory_config ../configs/memory.yaml \
--model_config ../configs/model.yaml \
--llm_mode prompt_json \
--outdir ../outputs/full_demo
# Demo 3: 批量任务演示
python b1_agent_runtime.py \
--input ../data/batch_input_demo.json \
--tools_config ../configs/tools.yaml \
--memory_config ../configs/memory.yaml \
--model_config ../configs/model.yaml \
--llm_mode mock \
--outdir ../outputs/batch_demo
# Demo 4: B1 独立演示(Fixture 模式,零依赖)
python b1_agent_runtime.py \
--input ../data/b1_fixtures/b1_fixture_input.json \
--outdir ../outputs/B1_fixture
6.3 关键参数说明
| 参数 | 说明 |
|---|---|
--input |
runtime_input.json 路径,包含 conversation_id、user_input、toolset、max_turns 等 |
--tools_config |
B3 工具配置文件(configs/tools.yaml) |
--memory_config |
B5 记忆配置文件(configs/memory.yaml) |
--model_config |
B4 模型配置文件(configs/model.yaml) |
--llm_mode |
mock(调试模式,不加载模型)或 prompt_json(真实推理) |
--outdir |
输出目录,所有产物文件写入此处 |
--resume |
从 checkpoint 恢复(B1 进阶2) |
6.4 运行成功的判断方式
- 终端无报错,输出
final_answer.md文件路径 outputs/{outdir}/messages.json消息角色顺序为system → user → assistant(tool_calls) → tool → assistant(final)outputs/{outdir}/trace.json中status=success- 全系统真实模型演示额外生成
demo_report.md汇总报告
7. 输出文件与结果说明
7.1 主要输出文件
| 输出文件 | 生成模块 | 格式 | 说明 |
|---|---|---|---|
messages.json |
B1 | JSON 数组 | 完整消息序列(System/Human/AI/Tool) |
trace.json |
B1 | JSON 对象 | 执行轨迹(状态、轮次、每轮详情、进阶功能记录) |
final_answer.md |
B1 | Markdown | 最终回答文本 |
runtime_log.jsonl |
B1 | JSONL | 每次运行的日志 |
tools_schema.json |
B3 | JSON 数组 | 8 个工具的 OpenAI 格式描述 |
tool_messages.json |
B3 | JSON 数组 | 本次执行的 ToolMessage 列表 |
tool_stats_report.md |
B3 | Markdown | 工具调用统计报告(次数/成功率/耗时) |
selected_memory.json |
B5 | JSON 对象 | 加载的记忆文档列表 |
saved_memory.json |
B5 | JSON 对象 | 保存的记忆确认信息 |
memory/conversations/{id}.md |
B5 | Markdown | 对话记忆文档 |
llm_calls/llm_call_NNN_ai_message.json |
B4 | JSON 对象 | 每次 LLM 调用的 AIMessage |
llm_calls/llm_call_NNN_raw_model_output.json |
B4 | JSON 对象 | 每次 LLM 调用的原始输出 |
batch_summary.json |
B1 | JSON 对象 | 批量任务汇总 |
batch_report.md |
B1 | Markdown | 批量任务对比报告 |
7.2 运行截图或结果图例
[在此处插入全系统 Demo 运行截图]
[在此处插入 messages.json 消息序列截图]
[在此处插入 final_answer.md 内容截图]
[在此处插入 trace.json 中 status=success 截图]
8. 协作实现说明
8.1 模块接口约定
团队通过以下方式保证模块间接口一致性:
- 统一数据格式:
common/schemas.py定义了 AIMessage、ToolMessage、SkillResult 的标准 JSON Schema - 统一路径解析:
common/path_utils.py的resolve_data_path()和resolve_from_file()确保所有模块的路径解析逻辑一致 - 配置文件驱动:B3 的
tools.yaml、B5 的memory.yaml、B4 的model.yaml三者独立,B1 通过run_agent()的参数分别传入,避免模块间隐式依赖
8.2 数据传递约定
| 传递方向 | 数据 | 格式约定 |
|---|---|---|
| B1 → B5 | 记忆 ID + 检索类型 | load_memory(ids, use_global, query, retrieval_type, top_k) |
| B5 → B1 | 记忆文档 | {status, selected_memory_docs: [{memory_id, content, ...}]} |
| B1 → B3 | 工具配置 + toolset | get_tools_schema(tools_config, toolset) |
| B3 → B1 | 工具描述 | [{type:"function", function:{name, description, parameters}}] |
| B1 → B4 | messages + tools_schema | generate_ai_message(model_config, messages, tools_schema, mode) |
| B4 → B1 | AIMessage | {role:"assistant", content, tool_calls} |
| B1 → B3 | tool_calls | [{id, name, args}] |
| B3 → B2 | Skill 函数调用 | run_skill(skill_name, input_data, data_root, output_dir) |
| B2 → B3 | SkillResult | {skill_name, status, output, error, latency_ms} |
| B3 → B1 | ToolMessage | {role:"tool", tool_call_id, name, content} |
8.3 联调中遇到的问题与解决
- B1 与 B5 之间 retrieval_type 参数传递:早期 B5 仅支持按 ID 检索。通过 B1 新增
retrieval_type参数从runtime_input.json动态读取并透传解决。 - B1 与 B4 之间 tools_schema 格式:B4 期望
use_native_tools和model_profile参数。通过runtime_input.json配置字段透传,B1 不做硬编码。 - B3 与 B2 之间 data_root 注入:B2 的
resolve_data_path()需要data_root。B3 从tools.yaml的settings.data_root读取后注入给 B2。 - Mock 与真实模式切换:通过
--llm_mode参数显式切换,B4 内部实现mock和prompt_json两条独立路径。
8.4 Git 协作
- 使用统一的 Git 仓库,每个成员负责自己模块的代码文件
- 配置文件(
tools.yaml、memory.yaml、model.yaml)由组长统一维护 - 公共工具(
common/目录)由全员共同维护,修改需同步通知
9. 已知问题与改进方向
| 问题 | 当前原因 | 可能改进 |
|---|---|---|
| 真实模型推理需要 GPU | Qwen3.5-4B 约 8GB 显存 | 可考虑使用量化模型(如 GPTQ/AWQ)降低显存需求 |
| Mock 模式下的历史压缩摘要质量一般 | B4 mock 返回固定模板回答 | 可用 prompt_json 真实推理生成更精准的摘要 |
| 向量检索首次加载模型较慢 | all-MiniLM-L6-v2 需从 HuggingFace 下载 |
可预下载到本地 |
| 记忆压缩/更新需加载 Qwen 模型 | 懒加载策略,首次使用仍需等待 | 可预加载模型到内存常驻 |
| 批量模式下各任务串行执行 | 当前 _run_batch() 为顺序循环 |
可改为并行执行(需处理 GPU 串行化问题) |
| 各模块 Demo 端口不统一 | B1:8080, B2:8081, B3:8082, 统一:8090 | 可统一为单一端口 |
Languages
Python
100%