十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

在 AndroidWorld 中扩展新任务:基于 SQLite 与文件系统的任务创建实战指南

在 AndroidWorld 中扩展新任务:基于 SQLite 与文件系统的任务创建实战指南 在 AndroidWorld 中扩展新任务基于 SQLite 与文件系统的任务创建实战指南【免费下载链接】MobileAgentMobile-Agent: The Powerful GUI Agent Family项目地址: https://gitcode.com/GitHub_Trending/mo/MobileAgent导读本文是 AndroidWorld 任务扩展指南 的深入实战解读面向需要在 AndroidWorld 基准环境中新增评估任务的开发者。文章以 Simple Calendar ProSQLite 存储与 Markor文件系统存储两个真实应用为例完整走通「确定数据存储方式 → 探索应用内部结构 → 创建任务类 → 验证与集成」的完整链路并结合 sqlite_validators.py、file_validators.py 等核心源码讲解底层验证原理让读者不仅能照做更能理解 AndroidWorld 任务抽象的设计意图。一、AndroidWorld 任务系统从 TaskEval 到任务注册在动手之前先建立整体认知。AndroidWorld 中每一个可评估的任务类都继承自task_eval.TaskEval定义见 task_eval.py其生命周期由三个关键方法驱动initialize_task(env)在 Agent 动手之前重置环境、注入任务所需的数据如向数据库写入目标行、创建待操作的文件is_successful(env) - floatAgent 执行完毕后核对设备状态返回1.0成功或0.0失败tear_down(env)任务结束后清理状态。所有任务类最终都要登记进注册表供评估器按名称查找。从源码看任务注册表集中在 registry.py 的register_task方法中Simple Calendar 与 Markor 的一系列任务SimpleCalendarAddOneEvent、MarkorCreateNote、MarkorMergeNotes等都在这里被注册见 registry.py。新增任务后同样需要在此注册才能被 minimal_task_runner.py 等运行入口发现并执行。理解了这套骨架下面进入文档给出的四步流程。二、第一步确定应用的数据存储方式扩展任务前必须搞清楚目标应用把数据存在哪里。本指南聚焦 Android 应用最常见的两种持久化方式——SQLite 数据库与文件系统同样的原则也可以推广到 SharedPreferences 等其它存储机制。1. 进入应用的数据目录用 ADB 列出目录内容adb shell ls data/data/package_name/将package_name替换为应用的包名。例如 Simple Calendar Pro 的包名是com.simplemobiletools.calendar.pro。2. 检查是否存在 SQLite 数据库文件。在数据目录下查找databases文件夹例如adb shell ls data/data/com.simplemobiletools.calendar.pro/databases/如果看到.db文件说明该应用很可能使用 SQLite 存储。在本文的实例中Simple Calendar Pro 的数据库正是events.db——这一点在源码 calendar_utils.py 中也能印证DB_PATH /data/data/com.simplemobiletools.calendar.pro/databases/events.db EVENTS_TABLE events # Table in events.db. DB_KEY id3. 检查文件系统存储。若没有databases文件夹或应用把数据放在数据库之外则查找files目录或其它存放数据文件文本、图片等的目录adb shell ls data/data/package_name/files/发现.txt、.json等自定义类型文件说明应用走的是文件系统存储。Markor 的笔记数据存放路径在 device_constants.py 中定义为MARKOR_DATA /storage/emulated/0/Documents/Markor注意 Markor 的数据位于外部存储/storage/emulated/0/而非应用私有目录这类路径同样可以用 ADB 直接访问。三、第二步探索应用的内部结构确定存储方式后需要进一步摸清数据库 schema 或文件内容格式这是设计任务的依据。3.1 探索 SQLite 数据库查看表结构sqlite3子命令输出指定表的列名与数据类型adb shell sqlite3 data/data/com.simplemobiletools.calendar.pro/databases/events.db .schema Events以Events表为例输出会列出start_ts、end_ts、title等列及其类型INTEGER、TEXT。这些列正是后续 Python 数据类字段设计的直接来源。查询表数据理解实际记录长什么样adb shell sqlite3 data/data/com.simplemobiletools.calendar.pro/databases/events.db SELECT * FROM events;查看真实数据有助于把握字段取值规律如时间戳的粒度、标题的格式为generate_random_params生成合理的任务参数做铺垫。3.2 探索文件系统存储直接查看文件内容adb shell cat data/data/package_name/files/file_name.txt拉取文件到本地做更复杂的分析adb pull data/data/package_name/files/file_name.txt /local/directory/本地用文本编辑器或 JSON 查看器打开可以更清晰地把握数据结构和格式。四、第三步基于 SQLite 创建并验证新任务Simple Calendar Pro 实例拿到 schema 和数据后就可以写任务了。AndroidWorld 的一大设计优势是抽象封装通过sqlite_validators.AddMultipleRows基类和sqlite_validators.validate_rows_addition_integrity函数开发者无需手工处理数据库操作细节只需聚焦于任务本身要干什么。4.1 定义数据类先定义一个与目标表结构镜像的dataclass它代表 Python 侧的一条数据行dataclasses.dataclass(frozenTrue) class CalendarEvent: start_ts: int end_ts: int title: str location: str description: str repeat_interval: int 0 repeat_rule: int 0在真实源码 sqlite_schema_utils.py 中CalendarEvent还补充了大量默认字段提醒、重复限制、时区等并提供了duration_mins、start_datetime、end_datetime三个派生属性分别计算事件时长分钟和本地化时间。文档示例中的duration_mins模板参数正是来自event.duration_mins。注意数据库中的id列由自增主键生成Python 侧默认置-1不参与写入。4.2 创建基类任务类基类封装与 SQLite 交互的通用逻辑指定数据库路径、表名、主键字段与行类型class _SimpleCalendar(sqlite_validators.SQLiteApp): Base class for calendar tasks and evaluation logic. app_name_with_db simple calendar pro app_names (simple calendar pro,) db_key id db_path data/data/com.simplemobiletools.calendar.pro/databases/events.db table_name events row_type CalendarEvent从 sqlite_validators.py 的SQLiteApp实现可以看到这些类属性如何被消费list_rows()通过sqlite_utils.get_rows_from_remote_device读取远端表add_rows()调用sqlite_utils.insert_rows_to_remote_db写入initialize_task()先清库防止上次崩溃残留再写入NOISE_ROW_OBJECTS噪声行tear_down()再次清库保证任务间状态隔离。文档特别强调AndroidWorld 在调用initialize_state和/或tear_down时会自动清空数据库与全部应用状态因此任务无需担心脏数据。4.3 实现任务逻辑任务类继承AddMultipleRows与基类实现三件事任务模板、参数生成、结果验证class SimpleCalendarAddOneEvent(sqlite_validators.AddMultipleRows, _SimpleCalendar): Task for creating a calendar event in Simple Calendar Pro. complexity 2 template ( In Simple Calendar Pro, create a calendar event on {year}-{month}-{day} at {hour}h with the title {event_title} and the description {event_description}. The event should last for {duration_mins} mins. ) classmethod def _get_random_target_row(cls) - CalendarEvent: Generates a random calendar event. return events_generator.generate_event( datetime_utils.create_random_october_2023_unix_ts() ) def validate_addition_integrity( self, before: list[CalendarEvent], after: list[CalendarEvent], reference_rows: list[CalendarEvent], ) - bool: Validates the integrity of the event addition. return sqlite_validators.validate_rows_addition_integrity( before, after, reference_rows, compare_fields[ start_ts, end_ts, title, location, description ] ) classmethod def generate_random_params(cls) - dict[str, Any]: Generate random parameters for a new calendar event task. event cls._get_random_target_row() n_noise_events random.randint(0, 20) return { year: device_constants.DT.year, month: device_constants.DT.month, day: event.start_datetime.day, hour: event.start_datetime.hour, duration_mins: event.duration_mins, event_title: event.title, event_description: event.description, sqlite_validators.ROW_OBJECTS: [event], sqlite_validators.NOISE_ROW_OBJECTS: generate_noise_events( [event], n_noise_events ) }这里有几个值得展开的细节1模板与仿真日期。device_constants.DT是模拟器的固定当前日期。从 calendar.py 的注释可以看到模拟器系统时间被设定为2023 年 10 月 15 日模板中的{year}/{month}/{day}直接取DT的年月而具体某天由随机事件决定。这保证了任务既随机多样又不会跑出可控的时间范围。2ROW_OBJECTS与NOISE_ROW_OBJECTS。这两个常量定义于 sqlite_validators.pyROW_OBJECTS row_objects NOISE_ROW_OBJECTS noise_row_objectsROW_OBJECTS是 Agent 需要完成的目标行NOISE_ROW_OBJECTS是干扰项噪声数据用来提高任务难度、防止 Agent 只靠新增即成功的简单策略蒙混过关。AddMultipleRows.initialize_task会先把噪声行写进数据库随后is_successful从params[ROW_OBJECTS]取目标行做核对见 sqlite_validators.py。3验证函数的三重检查。validate_rows_addition_integritysqlite_validators.py依次执行三个严格约束每个reference_rows目标行都必须出现在after状态中按compare_fields逐字段比对len(after) len(before) len(reference_rows)——数量必须精确匹配杜绝 Agent 多增、少增before中的每一行在after中必须原样保留——防止 Agent 误改或误删已有数据。此外它还支持free_form_fields参数对自由文本字段启用模糊匹配基于fuzzy_match_lib.fuzzy_match这样对标题等文本的核对可以容忍大小写、标点差异。4噪声事件生成。generate_noise_eventscalendar.py通过filter_fn确保噪声事件与目标事件不重名再调用sqlite_schema_utils.get_random_items去重生成数量为random.randint(0, 20)。4.4 一组可复用的变体实际仓库中SimpleCalendarAddOneEvent还派生出多个变体任务它们共享同一套验证逻辑只改模板与事件生成策略这正是抽象封装的威力任务类模板角度关键差异SimpleCalendarAddOneEventRelativeDay相对星期this Monday事件日期限定在当前周内goal属性动态注入day_of_weekSimpleCalendarAddOneEventTomorrow明天事件锁定在DT.day 1SimpleCalendarAddOneEventInTwoWeeks两周后事件锁定在DT.day 14SimpleCalendarAddRepeatingEvent重复事件额外生成repeat_interval/repeat_rule周重复规则按1 (weekday-1)位掩码编码删除类任务则继承DeleteMultipleRows通过validate_rows_removal_integrity核对指定行被删除、其余行未动、无新增行见 sqlite_validators.py典型实现如SimpleCalendarDeleteEvents删除某日全部事件与SimpleCalendarDeleteOneEvent。4.5 底层SQLite 是如何被写入的SQLiteApp.add_rows最终调用 sqlite_utils.py 的insert_rows_to_remote_db。从 calendar_utils.py 的注释可以看出其实现思路先通过 ADB 把远端数据库文件拷贝到本地 → 在本地用sqlite_schema_utils.insert_into_db生成INSERT INTO events (...) VALUES (...)语句执行写入 → 再把数据库推回设备。SQL 语句的列名与占位符由 dataclass 字段自动推导insert_into_db支持exclude_key跳过自增主键这就是无需手工处理数据库操作细节的底层保障。五、第四步基于文件系统创建并验证新任务Markor 实例对于文件系统存储的应用任务围绕文件的增删改展开。以下以 Markor 笔记应用为例。5.1 定义任务类class MarkorCreateNote(task_eval.TaskEval): app_names (markor,) complexity 2 schema file_validators.CreateFile.schema template ( Create a new note in Markor named {file_name} with the following text: {text} ) def __init__(self, params: dict[str, Any]): See base class. super().__init__(params) self.create_file_task file_validators.CreateFile( params, device_constants.MARKOR_DATA ) def initialize_task(self, env: interface.AsyncEnv) - None: super().initialize_task(env) self.create_file_task.initialize_task(env) def is_successful(self, env: interface.AsyncEnv) - float: super().is_successful(env) return self.create_file_task.is_successful(env) classmethod def generate_random_params(cls) - dict[str, str | int]: return {file_name: _generate_random_file_name(), text: _generate_random_file_text()} def tear_down(self, env: interface.AsyncEnv) - None: super().tear_down(env) self.create_file_task.tear_down(env)文档中的这个骨架在真实仓库里对应 markor.py 的MarkorCreateNote。其设计模式是组合委托把文件操作的具体逻辑交给file_validators.CreateFile构造时传入device_constants.MARKOR_DATA作为数据目录任务类自身只负责生命周期转发。CreateFile的验证逻辑file_validators.py分两步用file_utils.check_file_or_folder_exists确认目标文件已创建通过 ADBcat读取文件内容与params[text]做模糊匹配同样走fuzzy_match_lib.fuzzy_match。因此它既核对文件在不在也核对内容对不对。5.2 任务级基类与噪声文件MarkorCreateNote的父类Markormarkor.py在initialize_task/tear_down中调用file_utils.clear_directory(MARKOR_DATA)清理笔记目录保证每次任务从干净状态开始。与 SQLite 任务注入噪声行同理文件类任务通过user_data_generation.generate_noise_files生成干扰文件_NOTE_TITLES常量如grocery_list_weekly.md、meeting_notes_project_team.md提供了 20 个逼真的笔记文件名作为候选见 markor.py。5.3 文件类任务的更多形态file_validators.py还提供了另外两个可组合的验证器MoveFilefile_validators.py核对源目录文件消失且目标目录文件出现MarkorMoveNote即基于它实现随机挑选 10 个预置子文件夹BookNotes、DailyNotes等作为移动起止点DeleteFilefile_validators.py核对文件不存在即成功MarkorDeleteNote直接委托给它。在此基础上仓库还扩展出一系列更有挑战性的 Markor 任务MarkorCreateFolder建文件夹、MarkorEditNote头部/尾部追加或整体替换文本、MarkorMergeNotes按顺序合并三篇笔记并校验空行分隔、MarkorDeleteNewestNote借助文件修改时间排序判断删的是不是最新笔记、MarkorTranscribeReceipt跨 Simple Gallery 看图转录小票为 receipt.md等充分展示了在文件系统抽象之上扩展任务的多样性。六、测试与集成让新任务真正跑起来6.1 单测验证验证逻辑仓库为 SQLite 验证器提供了完整的单元测试 sqlite_validators_test.py其中add_event_to_db/remove_event_by_event_id直接在本机 SQLite 上构造 before/after 状态再调用validate_rows_addition_integrity断言返回True/False。新增任务时可以仿照这套模式先脱离模拟器、用本地sqlite3验证自己的validate_addition_integrity逻辑再上设备联调。markor_test.py、recipe_test.py等文件同样覆盖了对应任务的测试路径。6.2 注册进任务注册表运行入口通过注册表查找任务。需要在 registry.py 的任务列表中登记新类之后便可通过 minimal_task_runner.py 直接指定任务名运行。整个 AndroidWorld 环境的搭建与运行方式可参考 README.md 与 tasks_guide.md。6.3 端到端验证要点状态隔离initialize_task与tear_down会自动清库/清目录无需手工清理若前一次运行异常中断初始化时的清库逻辑会兜底SQLiteApp._clear_db在清库后还会尝试重建空库失败即抛错。噪声与目标分离确认ROW_OBJECTS只包含目标数据、NOISE_ROW_OBJECTS不与其冲突如generate_noise_events用filter_fn排除同名。模板可读性template中的占位符必须与generate_random_params返回的键一一对应否则format会抛 KeyError。结语通过本文的四步方法论开发者可以把任意使用 SQLite 或文件系统存储的 Android 应用纳入 AndroidWorld 的评估体系先adb shell ls判定存储方式再用sqlite3/cat/adb pull摸清结构最后基于sqlite_validators与file_validators提供的抽象快速定义任务模板、参数生成与完整性验证。SQLite 侧的AddMultipleRows/validate_rows_addition_integrity与文件侧的CreateFile/MoveFile/DeleteFile都是高度可复用的公共构件配合噪声数据注入与严格的前后状态核对既能保证任务难度可控又能有效防止 Agent 的偷懒解。沿着这条路径社区可以持续把 AndroidWorld 扩展到更广泛的应用与更复杂的任务形态。【免费下载链接】MobileAgentMobile-Agent: The Powerful GUI Agent Family项目地址: https://gitcode.com/GitHub_Trending/mo/MobileAgent创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表