用途: Agent快速了解项目结构,节省token 更新日期: 2025-11-24 重要变更: 项目已重构为标准Python包结构
autowzry-agent/
├── qmoba_agent/ # 主包目录
│ ├── __init__.py # 包初始化(导出常用类)
│ ├── config/ # 配置管理
│ │ ├── __init__.py
│ │ └── config.py # 配置类定义
│ ├── core/ # 核心模块
│ │ ├── __init__.py
│ │ ├── lightweight_dqn.py # 轻量级DQN(88K参数)
│ │ └── trainer.py # DQN训练器
│ ├── data/ # 数据处理
│ │ ├── __init__.py
│ │ ├── data_manager.py # 数据管理(收集+标记)
│ │ └── training_buffer.py # 训练数据加载
│ ├── environment/ # 环境交互
│ │ ├── __init__.py
│ │ ├── action_space.py # 动作空间定义
│ │ ├── compatibility.py # 兼容层(依赖注入中心)
│ │ └── game_state.py # 游戏状态检测
│ ├── utils/ # 工具函数
│ │ ├── __init__.py
│ │ ├── image_processing.py # 图像预处理
│ │ └── video_reader.py # 视频读取
│ └── autowzry_lite/ # autowzry精简版
│ └── autowzry/
│ ├── __init__.py
│ ├── version.py
│ └── wzry.py
├── scripts/ # 执行脚本
│ ├── __init__.py
│ ├── collect_from_video.py # 从视频收集数据
│ ├── collect_from_device.py # 从设备收集数据
│ ├── label_data.py # 标记数据(action+state)
│ ├── train.py # 训练模型
│ ├── battle.py # 模型测试与对战(支持离线/在线)
│ ├── check_buffer.py # Buffer数据验证(调试用)
│ ├── extract_data.py # HDF5帧范围提取
│ └── test_pipeline.py # 端到端自动化测试(开发用)
├── config/ # 配置文件目录(YAML文件)
│ └── agent.config.yaml # 主配置文件
├── docs/ # 文档
│ ├── guides/ # 使用指南
│ │ ├── README_FOR_AGENT.md # Agent快速上手
│ │ ├── quickstart.md # 用户快速开始
│ │ └── AGENT_COLLABORATION_RULES.md # Agent协作规范
│ ├── design/ # 架构设计
│ │ └── ARCHITECTURE.md # 本文件
│ └── logs/ # 开发日志
│ └── development_log.md
├── workspace/ # 运行时数据(.gitignore)
│ ├── episodes/ # HDF5数据存储
│ ├── checkpoints/ # 模型检查点
│ ├── videos/ # 视频素材
│ ├── buffer_check/ # Buffer检查输出
│ └── test_pipeline/ # 端到端测试输出
├── pyproject.toml # 项目配置(包元数据、依赖)
└── README.md # 项目主页
重要说明:
qmoba_agent/包目录下pip install -e .安装包from qmoba_agent.xxx import yyy格式sys.path操作依赖: yaml
类:
Config: autowzry-agent配置类
load(yaml_path) -> Config: 从YAML加载from_yaml(yaml_path) -> Config: 从YAML加载(推荐)default() -> Config: 获取默认配置data_dir, enable_traininguse_autowzry_lite: 是否使用本地autowzry_lite库(默认:true,false则使用已安装的autowzry)autowzry_config: autowzry库的配置文件路径(用于设备连接)buffer_capacitytrain_resolution: 训练分辨率 [height, width, channels]use_last_state: 是否使用laststate+state合并模式(默认:true)enabled_states: 启用的状态列表(默认:[‘in_battle’, ‘dead’, ‘alive’, ‘kill’, ‘assist’])enabled_actions: 启用的动作列表(默认:[‘move’])training: num_epochs, batch_size, learning_rate, gamma, samples_per_epoch
use_target_network: 是否使用目标网络(默认:true)target_update_epochs: 目标网络更新间隔(默认:5)use_amp: 是否使用混合精度训练(默认:mini模式自动开启)device: 训练设备(默认:’auto’,可选:’cpu’, ‘cuda’, ‘cuda:0’, ‘cuda:1’, etc.)checkpoint: dir, save_interval, resume_model依赖: torch, torch.nn
类:
LightweightDQN(nn.Module): DQN模型
__init__(input_channels, input_height, input_width, num_actions, mode):
input_channels: 输入通道数(由buffer决定,use_last_state=false时为3,true时为6)input_height, input_width: 输入分辨率(由config.train_resolution决定)num_actions: 动作空间维度(由action_space决定)mode: 模型规模(’mini’/’full’/’high’)forward(x) -> q_values: 前向传播,输出Q值save(path): 保存模型和超参数get_params_breakdown() -> dict: 获取参数分布统计docs/design/MODEL_DESIGN.md依赖: torch, torch.optim, matplotlib, numpy, data.training_buffer
类:
Trainer: DQN训练器
__init__(compatibility_layer, config):
train(): 训练模型
_compute_loss(batch) -> loss: 计算DQN loss(输入已是tensor)
save_model(path): 保存模型load_model(path): 加载模型plot_training_history(save_dir): 绘制训练曲线(对数坐标)并保存txt数据self.history: {‘epoch’: [], ‘loss’: []}self.model: 主网络(训练中更新的网络)self.target_model: 目标网络(用于稳定训练,每target_update_epochs同步一次)self.samples_per_epoch: 每个epoch使用的样本数self.use_sampling: 是否需要每个epoch重新采样self.action_slices: 动作切片索引self.action_rewards_tensors: 动作奖励张量(GPU计算用)self.use_amp: 是否使用AMPself.scaler: GradScaler实例(AMP启用时)依赖: h5py, numpy, cv2, environment.compatibility, environment.game_state, environment.action_space
类:
StreamingRecorder: 流式HDF5记录器(边记录边写入磁盘,避免内存爆炸)
__init__(filepath): 初始化流式记录器,创建HDF5文件
.backup(覆盖旧备份)append_frame(frame_data: Dict[str, Any]): 追加一帧数据到HDF5文件(立即写入磁盘)
finalize() -> str: 完成记录,更新文件属性,返回文件路径get_frame_count() -> int: 获取已记录的帧数DataManager: 数据管理器
__init__(compatibility_layer, action_space, game_state): 初始化(不再接受data_dir参数)create_streaming_recorder(filepath) -> StreamingRecorder: 创建流式记录器(接受完整路径)collect(filepath, max_frames, interval) -> filepath: 收集数据(使用流式写入,接受完整路径)load_dataset(filepath, keys, frame_range) -> Tuple[List[Dict], List[str], Dict]: 加载HDF5数据
save_dataset(frames, frame_names, filepath, attrs): 保存到HDF5(支持任意字段)label(filepath, overwrite=False): 标记数据(添加state_/action_字段)add_attrs(filepath, attrs): 添加自定义属性到HDF5文件info(filepath) -> Dict: 获取文件信息依赖: h5py, torch, torch.utils.data, numpy, os, datetime, random
类:
TrainingBuffer: 训练数据加载器
__init__(data_manager=None, action_space=None, game_state=None, capacity=100000, config=None)load(filepath, max_frames=None): 从HDF5加载数据到buffer
data_manager.load_dataset() 获取 (frames_data, frame_names, file_attrs)frame_name 字段用于调试追踪sample_indices(sample_size) -> List[int]: 随机采样索引get_dataloader(batch_size, shuffle, device, sample_size) -> DataLoader: 获取PyTorch DataLoader
save_to_hdf5(filepath): 保存所有buffer样本到HDF5(用于调试验证)
__len__() -> int: 总样本数BufferDataset(Dataset): PyTorch Dataset包装器
__init__(samples, device): 初始化__getitem__(idx) -> dict: 返回tensor格式的样本(已在device上)
依赖: numpy, cv2, autowzry, utils.video_reader
类:
CompatibilityLayer: 兼容层(依赖注入中心)
__init__(config, mode='online'/'offline', video_reader=None, connect=True)action_module: ActionSpace实例game_state_module: GameState实例data_manager: DataManager实例training_buffer: TrainingBuffer实例(enable_training=True时)get_screen() -> np.ndarray: 获取当前画面is_in_battle(screen) -> bool: 检测是否在战斗中is_dead(screen) -> bool: 检测死亡detect_kill_count(screen) -> int: 检测击杀数detect_assist_count(screen) -> int: 检测助攻数execute_move(cmd): 执行移动execute_attack(cmd): 执行攻击依赖: environment.compatibility
类:
ActionSpace: 动作空间定义
__init__(compatibility_layer, enabled_actions=None): 初始化
get_action_keys() -> List[str]: 获取激活的action名称get_action_dims() -> Dict[str, int]: 获取每个action的维度get_total_dim() -> int: 获取总维度get_frame_action(frame1, frame2) -> Dict[str, List[float]]: 获取当前帧的动作字典
execute_action(cmd): 执行动作(委托给兼容层)get_action_slices() -> List[Tuple[int, int]]: 获取每个action在模型输出中的索引范围get_action_rewards_list() -> List[List[float]]: 获取每个action的rewards数组(按enabled_actions顺序)actions: 动作空间定义(如 {‘move’: 4, ‘attack’: 10})action_rewards: 动作奖励权重(如 {‘move’: [0.01, 0.01, 0.01, 0.1]}),所有移动都有基础奖励0.01(和alive状态一致),向右移动10倍奖励,与state_rewards单位统一依赖: environment.compatibility
类:
GameState: 游戏状态检测和得分计算
__init__(compatibility_layer, enabled_states=None): 初始化
get_frame_state(frame1, frame2) -> dict: 获取当前帧的状态字典
sum_reward(state_dict) -> float: 根据状态字典计算总得分enabled_states: 启用的状态列表state_scores: 状态得分配置(如 {‘dead’: -2, ‘alive’: 0.01, ‘kill’: 1, ‘assist’: 1, ‘in_battle’: 0})依赖: cv2, numpy
函数:
resize_frame(frame, width, height)to_grayscale(frame)normalize(frame): 0-255 -> 0-1preprocess_frame(frame, width, height, grayscale, resize=True)stack_frames(frames)
类:FrameBuffer:
__init__(stack_size, frame_shape)add_frame(frame) -> stacked: 添加并返回堆叠帧依赖: cv2
类:
VideoReader:
__init__(video_path, frame_interval=0, target_fps=None)__iter__(), __next__() -> (idx, frame)画面数据 (RGB图像)
-> CompatibilityLayer.capture_screen()
-> DataManager.collect()
-> HDF5文件 (未标记)
-> DataManager.label()
-> HDF5文件 (已标记)
-> TrainingBuffer.load()
-> TrainingBuffer.get_dataloader()
-> Trainer.train_step()
-> 模型
说明:
标准数据文件(collect + label生成):
episode_xxx.hdf5
├── attrs (文件级属性)
│ ├── num_frames: 总帧数
│ ├── created_at: 创建时间
│ ├── labeled_at: 标记时间(可选)
│ ├── original_file: 原始文件(提取时)
│ ├── extracted_range: 提取范围(提取时)
│ └── ...
├── frame_000000/
│ ├── image: (540, 960, 3) RGB图像
│ ├── timestamp: 时间戳
│ ├── state_in_battle: bool(标记后)
│ ├── state_dead: bool(标记后)
│ ├── state_alive: bool(标记后)
│ ├── state_kill: bool(标记后)
│ ├── state_assist: bool(标记后)
│ ├── action_move: [上, 下, 左, 右] 得分(标记后)
│ └── action_attack: [目标1, ..., 目标10] 得分(标记后)
├── frame_000001/
│ └── ...
└── ...
battle.py录制文件(使用–record-interval和–output生成):
battle_record.hdf5
├── attrs (文件级属性)
│ ├── num_frames: 总帧数
│ ├── created_at: 创建时间
│ ├── finished_at: 完成时间
│ ├── recording_mode: 'streaming'
│ └── ...
├── frame_000000/
│ ├── image: (540, 960, 3) RGB图像
│ ├── timestamp: 时间戳
│ └── q_values: (total_dim,) 模型输出的Q值
├── frame_000001/
│ └── ...
└── ...
说明:
frame_XXXXXX(6位数字){
'state': (C, 540, 960), # 当前帧图像,C=3或6(取决于use_last_state)
'next_state': (C, 540, 960), # 下一帧图像,C=3或6
'frame_name': str, # 帧名称(如'frame_000042'),用于调试追踪
'move': [4], # 移动动作得分 [上, 下, 左, 右]
'reward': float # 总奖励值(状态奖励 + 动作奖励)
}
说明: