feat(review): agent 侧虚拟工具 inspect_region —— 按可读分辨率放大指定区域
解决三个缺口:① 放大没复用标定/瓦片数学(LLM 一次 zoom 只出一张,宽区域仍读不清);
②「看清没」由 VLM 自评(易过度自信/幻觉);③ 只能按 handle / 手算 bbox 指认,
图上看到但没 handle 的东西指认不了。
核心思路:把「放大」升级成一个语义化工具——LLM 只指认「要看哪里」,由 agent 复用
tiling.py 的标定数学算出该切几张、每张覆盖多大,用构造保证可读。
新增 dwg_review/inspect.py(agent 侧,不编 DLL):
- TOOL_SCHEMA:inspect_region(target, purpose);target 三形态 {handle} / {window} /
{label,cx,cy,span},purpose = text(8px) / line(6px)。
- InspectState:单图框内「截图标签 → 世界可见范围」登记表,支持逐级下钻
(返回的 inspect-N 可继续作为 label 指认)。
- resolve_target / _point_box:label+cx+cy → WCS。cy 是图像坐标(上→下),
世界 y 必须翻转(y = y2 - cy*H)——单测专门钉住。
- plan_tiles:复用 world_per_px + tiles_for_box + subdivide;超 INSPECT_MAX_TILES(4)
则硬失败并给出「缩小 target / 分多次请求」的指引(不静默降级);拿不到比例/像素
则退回单张并如实告知。
关键几何:CAD 的 _.ZOOM _W 是等比适配(不拉伸),故「截图上的归一化坐标」必须按
max(W/ew, H/eh) 反算真实可见范围(新增 tiling.visible_box)——直接用送进去的窗口会偏。
zoom_to_window 返回的 view 是「加过 margin 的窗口」,不是可见范围,不能混用。
证据层配套:evidence_model.make_image(..., window=) 记录每张图的可见世界范围;
capture_images 用 view_px(overall 图原始像素)+ visible_box 逐张登记。
子循环接入:_run_readonly_tool 在只读白名单校验之前拦截 inspect_region(它不在
READ_ONLY_TOOLS 里,内部只调白名单内的只读 MCP 工具);_review_tools 启用时用
inspect_region 取代三个裸视口工具;inspect_region 计入 _VIEW_TOOLS → 结束复位视口。
配置:INSPECT_ENABLED(True) / INSPECT_MAX_TILES(4)。
端到端实测(真实图纸 1 图框):取证与审查两阶段均在最大化态、结束精确还原(4 项 PASS);
LLM 的 11 次取证调用里 2 次是 inspect_region,且都显式给 window + purpose:"text"
(x[20000,115000] y[-6500,3000],即 A0 图框底部横条=标题栏所在)。
验收口径达成:报告报出标题栏乱码 ???????????????,而 get_text_content 对全图返回 0 条文字
(本图文字全在块/自定义实体内)→ 块内文字是被视觉放大读出来的。
pytest 343 passed。
This commit is contained in:
1 parent
3bc64b6c3e
commit
b757892c67
18 files changed
+1003
-45
No files matched your search
@@ -1,6 +1,6 @@
|
||||
---
|
||||
name: Agent 路线与多源架构(2026-10-15)
|
||||
description: dwg_review agent 的总目标、多源图纸分层架构(视觉为最大公约数)、工具层与 agent 层的正交分工、多源证据层、截图去 UI、grounding 实测、热力图 + 自适应瓦片规划 + VLM 分辨率标定、绘图区最大化(set_drawing_area)与空瓦片过滤、审查阶段分辨率对齐 + 放大取证闭环、后续路线
|
||||
description: dwg_review agent 的总目标、多源图纸分层架构(视觉为最大公约数)、工具层与 agent 层的正交分工、多源证据层、截图去 UI、grounding 实测、热力图 + 自适应瓦片规划 + VLM 分辨率标定、绘图区最大化(set_drawing_area)与空瓦片过滤、审查阶段分辨率对齐、agent 侧虚拟工具 inspect_region(放大取证闭环)、后续路线
|
||||
type: project
|
||||
---
|
||||
|
||||
@@ -72,13 +72,9 @@ Agent 推理层(审查逻辑 / 清单 / 规则)
|
||||
|
||||
## 后续路线(未做)
|
||||
|
||||
1. **VLM 主动放大(自适应取证)**:复用受控只读取证子循环,让 VLM 请求放大看不清处。
|
||||
- **2026-10-16 部分落地**:审查阶段已对齐分辨率 + 提示词已明确放大协议 + 视口复位,
|
||||
实测 LLM 真的会连发 `zoom_to_window`+`get_viewport_screenshot`(见下节)。
|
||||
仍缺:① 按区域放大时的 **grounding→WCS 映射**(目前靠 LLM 自己用 bbox 算窗口,够用);
|
||||
② 把「看清没」的判定**不交给 VLM**(防过度自信)——现靠回合上限 + 截图预算兜底。
|
||||
- 现有 `zoom_to_window`/`zoom_to_entity`/`get_viewport_screenshot` 已在只读白名单,
|
||||
**无需新增工具**。
|
||||
1. **VLM 主动放大(自适应取证)**:**2026-10-16 已落地**(见下节 `inspect_region`)。
|
||||
剩余可选打磨:把「看清没」的判定进一步形式化(目前靠 agent 用标定数学**构造保证**可读 +
|
||||
回合上限 + 截图预算兜底),以及 grounding→WCS 之外的其它指认方式。
|
||||
2. **PDF / 图片源**:在 `phases/evidence.collect()` 加分支,产出**同形** evidence
|
||||
(`window=None`、结构化空信封、`images` 带 label);规划阶段抽象"审查单元"
|
||||
(CAD=图框 / PDF=页 / 图片=单);批注对非 CAD 源降级(`annotator` 已天然跳过无 handle 的 issue)。
|
||||
@@ -202,3 +198,49 @@ LLM 在受控子循环里 zoom + 截图拿到的是**未最大化的 2110×462**
|
||||
→ **拍了 8 张只回灌 3 张**(其余被"已省略"占位)。改为配置项 `REVIEW_OBS_IMAGES`
|
||||
(默认 **6**,`config.py`),并把预算耗尽时的占位文案改成**明确告知模型"不要再请求截图,
|
||||
请给出结论"**(原先只说"已省略")。实测模型截图次数不变(8),但**能看到 6 张而非 3 张**。
|
||||
|
||||
## A 收尾:agent 侧虚拟工具 `inspect_region`(2026-10-16)
|
||||
|
||||
**要解决的三个缺口**:① 放大**没复用标定/瓦片数学**(LLM 一次 zoom 只出一张,宽区域仍读不清);
|
||||
② 「看清没」由 **VLM 自评**(易过度自信/幻觉);③ 只能按 handle / 手算 bbox 指认,
|
||||
**图上看到但没 handle** 的东西指认不了。
|
||||
|
||||
**核心思路**:把「放大」升级成一个**语义化工具**——LLM 只指认「要看哪里」,
|
||||
由 agent 复用 `tiling.py` 的标定数学算出该切几张、每张覆盖多大,**用构造保证可读**。
|
||||
|
||||
**新增 `dwg_review/inspect.py`**(agent 侧,**不编 DLL**):
|
||||
|
||||
- `TOOL_SCHEMA`:`inspect_region(target, purpose)`。`target` 三形态任选其一——
|
||||
`{handle}` / `{window}` / `{label, cx, cy, span}`;`purpose` = `text`(8px) / `line`(6px)。
|
||||
- `InspectState`:单图框内的「截图标签 → **世界可见范围**」登记表。初始登记取证阶段的
|
||||
`overall`/`tile-*`,每次放大再追加 `inspect-1`、`inspect-2`… → **LLM 可用上一轮返回的标签
|
||||
继续下钻**(逐级放大)。
|
||||
- `resolve_target` / `_point_box`:`label+cx+cy` → WCS。**cy 是图像坐标(上→下),
|
||||
世界 y 必须翻转**(`y = y2 - cy*H`)——最容易写错的一处,单测专门钉住。
|
||||
- `plan_tiles`:复用 `tiling.world_per_px` + `tiles_for_box` + `subdivide`。
|
||||
超出 `INSPECT_MAX_TILES`(默认 4)→ **硬失败**并给出「缩小 target / 分多次请求」的具体指引
|
||||
(不静默降级,否则等于给一堆读不清的图);拿不到比例/像素 → 退回单张并如实告知。
|
||||
|
||||
**关键几何:`tiling.visible_box`**——CAD 的 `_.ZOOM _W` 是**等比适配(不拉伸)**,
|
||||
指定窗口按视口宽高比放大到刚好装下,多余一维露出更多内容。所以「截图上的归一化坐标」
|
||||
要准确映射回 WCS,必须按 `max(W/ew, H/eh)` 反算真实可见范围,**不能**直接用送进去的窗口。
|
||||
(`zoom_to_window` 返回的 `view` 是**加过 margin 的窗口**,不是可见范围,别混用。)
|
||||
|
||||
**证据层配套**:`evidence_model.make_image(..., window=)` 记录每张图的可见世界范围;
|
||||
`capture_images` 用 `view_px`(overall 图的原始像素)+ `visible_box` 逐张登记。
|
||||
|
||||
**子循环接入**(`phases/review.py`):`_run_readonly_tool` 在**只读白名单校验之前**拦截
|
||||
`inspect_region`(它不在 `READ_ONLY_TOOLS` 里,内部只调白名单内的只读 MCP 工具);
|
||||
`_review_tools` 启用时用 `inspect_region` **取代**三个裸视口工具(`zoom_to_window` /
|
||||
`zoom_to_entity` / `get_viewport_screenshot`)——一个语义化入口比三个裸工具更好用;
|
||||
`inspect_region` 计入 `_VIEW_TOOLS` → 结束时复位视口。
|
||||
配置:`INSPECT_ENABLED`(True) / `INSPECT_MAX_TILES`(4)。
|
||||
|
||||
**端到端实测(真实图纸 1 图框,`verify_review_maximized.py`)**:
|
||||
- 取证与审查两阶段均在最大化态、结束精确还原 → 4 项全 PASS。
|
||||
- LLM 的 11 次取证调用里 **2 次是 `inspect_region`**,且**都显式给了 `window` + `purpose:"text"`**:
|
||||
`x[20000,115000] y[-6500,3000]` 与 `x[-4000,30000] y[-6500,3000]`——A0 图框
|
||||
(`y[-6434,77666]`)的**底部横条**,即**标题栏**所在。模型自己把范围收窄到横条再放大。
|
||||
- **验收口径达成**:报告报出标题栏**乱码/占位字符 `???????????????`**,
|
||||
而 `get_text_content` 对全图返回 **0 条文字**(本图文字全在块/自定义实体内)——
|
||||
即**块内文字是被视觉放大读出来的**,不是结构化数据给的。
|
||||
@@ -47,7 +47,7 @@ type: reference
|
||||
| `verify_vlm_resolution_offline.py` | **离线**(纯 PIL 合成)标定 VLM 读图下限 `R_text`/`R_line`,`--dry-run` 只出图 |
|
||||
| `verify_text_resolution.py` | **CAD 实测**标定(临时加字 + 平行线,测完 `delete_entities` 清理);`--keep` 保留 |
|
||||
| `verify_drawing_area.py` | 绘图区最大化验收:基线 → `set_drawing_area(max)` → `restore`,断言窗口矩形/最大化态/绘图区尺寸全回位(实测 3.68×) |
|
||||
| `verify_review_maximized.py` | 审查全链路验收:在 `collect`/`review_frame` 入口各采一次窗口矩形,断言**取证与审查两阶段都在最大化态**、结束精确还原;并统计子循环里的 zoom/截图调用次数 |
|
||||
| `verify_review_maximized.py` | 审查全链路验收:在 `collect`/`review_frame` 入口各采一次窗口矩形,断言**取证与审查两阶段都在最大化态**、结束精确还原;并统计子循环 zoom/截图次数 + 记录 LLM 实际调用的取证工具(含虚拟工具 `inspect_region`) |
|
||||
|
||||
> 历史:根目录 `test.py` / `test_autoagent.py` / `countOfCircle.py` / `agent_loop.py` /
|
||||
> `dwg_review_agent.py` 五个遗留调试脚本已于 2026-10-14 删除(前三个含硬编码 API Key,
|
||||
|
||||
Reference in new issue
Block a user