autotrain/AGENTS.md
2026-06-11 12:18:53 +08:00

113 lines
7.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
trio: standard-v2
trio-initialized: 2026-06-08
---
# 铁路系统发票 · Agent 操作守则
> **上来先读这份**,再看 [`INDEX.md`](./INDEX.md) 找模块和导航。
>
> **通用三件套协议**见 [`../docs/trio-protocol.md`](../docs/trio-protocol.md)(文档维护节奏 / Handoff 写入 / 子项目嵌套 / 记忆三条线边界 / 语言规则 / 跨项目反例)。**本文件只列本项目专属守则**。
>
> **`trio: standard-v2`** = 本项目按当前标准维护三件套。
## 这是什么项目
铁路系统发票专项工作区,用于沉淀铁路系统相关发票资料、处理脚本、核对记录和衍生产出。
### 核心愿景Core Vision
**最终目标**:用户在 Web UI 上操作,脚本全自动完成开票、状态记录、结果文档输出。
**技术路线**
- **截屏驱动**ADB 截屏 → 视觉 LLMQwen3-VL via SiliconFlow识别页面元素、脱敏姓名、按钮位置
- **脚本编排**:视觉 LLM 返回归一化 bbox0-1000 坐标系)→ 脚本判断当前页面状态 → 决定下一步动作tap / scroll / back
- **UI 配合**Web UI 负责触发、监控进度、展示结果;脚本在子进程中运行,通过 CSV 文件与 UI 交换状态
- **对话调试**James 和 Claude Code 通过实际运行观察手机行为,持续修正脚本的判断逻辑和边界条件
**当前阶段**H5 扫码开票单页面自动化。页面结构:单个开票单下挂 N 个乘客(脱敏姓名 + 身份证类型 + 脱敏身份证号 + 「开具」按钮),需要逐人点击「开具」走完子流程,记录每个乘客的开票结果。
**已完成的路径**(保留不动):
1. 原生列表页视觉驱动批量(`android-vision-page-run`):截图 → list-rows 识行 → anchor 去重 → 点击 → 核验/发票管理子流程
2. 原生列表页 XML 驱动(`android-page-run`uiautomator dump → 解析 XML → 匹配 text/bounds
## 上手三步
1. 读 [`INDEX.md`](./INDEX.md),看项目结构和子模块导航。
2. 找到目标模块目录,**先读它的本地文档**(如 `<module>/README.md``<module>/AGENTS.md` 若存在)。
3. 看根目录或模块里有没有脚本入口、配置文件、环境变量样例。
## 项目专属硬规则
- **不要随手改 `.env` / 凭证 / `settings.json`**:敏感配置由项目所有者维护。
- **不要主动删除文件**:废弃 / 旧版本 / 半成品请移动到 `archive/``不加载/` 这类约定目录,不要 `rm`
- **不要重命名公共接口、路由、对外 API 字段**:除非明确授权,这些是契约。
- **涉及发票、金额、税号、单位名称等字段时先保留原始值**:规范化和清洗产物另存,不覆盖来源资料。
- **改动前确认是否有依赖你正在改的代码的其他模块**:先 `grep` 引用再下手。
## 目录命名约定
| 子目录 | 用途 |
|---|---|
| `data/` | 本项目自有数据与导入材料 |
| `scripts/` | 可执行脚本 |
| `src/``lib/` | 主代码 |
| `tests/` | 测试 |
| `docs/` | 详细文档 |
| `assets/` | 静态素材 |
| `templates/` | 模板文件 |
| `archive/``不加载/` | 归档区,不参与构建 |
## 项目专属"不要做的事"
- ❌ 删除文件(应该 `mv` 到归档目录)
- ❌ 自动提交 secrets / 凭证
- ❌ 覆盖原始发票资料或人工核对记录
- ❌ 未经确认修改发票字段含义、金额口径、税率口径
## 架构与关键依赖
> 本节是给 Claude Code 看的"big picture"。具体命令清单在 `INDEX.md` 的"常用操作"段;详细用法在 `docs/usage.md`。这里只写**读多个文件才能拼出来的事**。
### 四个脚本的分工
`scripts/` 下没有 `src/lib`,所有逻辑都在四个独立 Python 文件里彼此通过文件CSV / 配置 / 截图)耦合,而不是 import
| 脚本 | 角色 | 入口形式 |
|---|---|---|
| `invoice_tool.py` | 主 CLI~1700 行argparse 多子命令。覆盖:台账 / 名单 / 邮件归集 / 网页辅助页 / Android ADB 自动化 / 视觉驱动批量。所有路径常量、`run_adb`、`Config` 都在这里 | `python3 scripts/invoice_tool.py <subcmd>` |
| `web_ui.py` | 本地 HTTP 服务(端口 8765`import invoice_tool` 复用其常量和 `run_adb`,把批处理包成子进程跑 | `python3 scripts/web_ui.py` |
| `vision_fallback.py` | 视觉调用层adb 截屏 → base64 → 调 SiliconFlow Qwen3-VL grounding API → 解析归一化 bbox | `python3 scripts/vision_fallback.py {ping,detect-page,ask,list-rows}` |
| `record_step.py` | 录制工具:`adb uiautomator dump` + `screencap` 落盘到 `work/replay/<session>/<NN_label>/`,用于"人工演示 → 反推脚本" | `python3 scripts/record_step.py "label" [--new] [--list]` |
`web_ui.py` 当前调用的是旧路径 `android-page-run`XML/文字匹配),**没有接** `android-vision-page-run`。如果改 Web UI 的"开始运行"按钮,注意切换的是 `invoice_tool.py` 的子命令名。
### 两条 Android 自动化路径并存
12306 App 是脱敏姓名(`张*岩`+ 输入身份证后 8 位的开票流程。代码里有两套实现,**都保留**
1. **旧:`android-page-run` / `android-page-step`** — 走 `uiautomator dump` 读 XML按 text / bounds 匹配。问题是 12306 列表页很多控件没有 text全靠坐标。
2. **新:`android-vision-page-run`** — 截屏交给 Qwen3-VL模型返回归一化 bbox**0-1000 坐标系**,不是像素),脚本再 denormalize 到屏幕像素后 tap。流程截图 → `vision_fallback.list-rows` 识所有可见行 → anchor 去重防滑动后重复 tap → 子流程(核验 / 发票管理 / 成功页)走旧的状态机。
### 配置与外部依赖
- **ADB 路径硬编码**`invoice_tool.py:39` 写死 `/opt/homebrew/share/android-commandlinetools/platform-tools/adb`Apple Silicon Homebrew。换机器或换 Intel Mac 要改这里。
- **`config.local.json`**:除 `company_title / tax_id / receiver_email``config.example.json` 已示范)外,**视觉路径还需要一个 `vision` 段**`base_url` / `api_key` / `model`(当前用 SiliconFlow + `Qwen/Qwen3-VL-8B-Instruct`,详见 memory `reference_siliconflow_qwen_vl.md`)。`vision_fallback.load_vision_config` 缺任一键直接抛错。
- `config.local.json`、`work/`、`data/input|mail|attachments/`、`output/` 全在 `.gitignore` 里。
### 关键工作文件(都在 `work/`CSVUTF-8-BOM
| 文件 | 内容 | 写入者 |
|---|---|---|
| `passenger_roster.csv` | 名单:姓名 / 身份证号 / 后 8 位 / 来源 | `import-roster` |
| `invoice_tasks.csv` | 开票码主台账 | `import-codes` |
| `android_invoice_progress.csv` | 逐人处理结果masked_name / real_name / id_last8 / status | Android 子命令 + Web UI 读 |
| `android_page_queue.csv` | 当前可见页的待点击队列 | `android-build-page-queue` |
| `replay/<session>/` | record_step.py 的演示快照ui.xml + screen.png + texts.txt + meta.json | `record_step.py` |
CSV header 常量都集中在 `invoice_tool.py` 顶部(`TASK_HEADERS` / `ROSTER_HEADERS` / `PROGRESS_HEADERS` / `PAGE_QUEUE_HEADERS`)。改字段要同步改这里 + 所有读它的子命令。
### 测试
`tests/` 当前是空目录。没有单测 / 集成测试框架;验证靠 `--dry-run` 子命令 + 真机跑 + `work/replay/` 录制比对。新增功能不强求加测试,但如果改了 CSV schema 或 ADB 命令组合,至少跑一次 `--dry-run --max-actions 1`