feat(mcp): 基座换行分帧与 isError 映射;新增 dwg_review 审查 Agent

基座(cad_mcp_frame):
- 新增 RecvOneFrame: 以 '\n' 为消息边界分帧,去掉单次 recv(2048) 限制(上限 8MB);
  用 select 短探测兼容不发 '\n' 的旧客户端;clientSocket 设 SO_RCVTIMEO 防卸载卡死
- JSON-RPC id 支持 string/number;无 id 的通知不回包
- isError 映射: 协议级错误保留顶层 error,工具执行错误转 result.isError=true
- 响应补 '\n' 作为消息边界

Agent(新增 dwg_review 包):
- mcp_client: 唯一 TCP/JSON-RPC 封装(单飞锁/分帧/重试/兼容 error 与 isError)
- cad_tools: 从 tools/list 动态建表,含 15 个只读白名单
- phases: planning -> evidence -> review(受控只读取证子循环)-> report
- annotator: 批注回写 AI_REVIEW 层,支持 dry-run 与撤销
- config: 配置全部走环境变量;Windows 下回退读注册表以读到新设的系统变量

其它: 新增 verify_mcp_frame.py 验证脚本;.gitignore 补 Python/AutoCAD 锁文件规则;
ai.memory 记录架构决策与实测结论
This commit is contained in:
gjm committed 2026-10-13 23:44:11 +08:00
1 parent 3b1cc88262
commit ec5292debe
20 files changed
+1502 -20

No files matched your search

+66
View File
@@ -0,0 +1,66 @@
---
name: LLM 识图审图 Agent —— 架构决策(已定稿)
description: cad_mcp_frame + 自研 Agent 的架构决策与分阶段路线——混合式(流水线骨架+受控只读取证子循环)、基座 B 最小集、标准化路线(先 stdio 桥)
type: project
---
# LLM 识图审图 Agent —— 架构决策(2026-10-13 定稿)
## 决策
1. **Agent 形态:混合式自研**(非纯 ReAct、非纯流水线):确定性流水线骨架
(规划 → 逐图框取证 → 审查 → 汇总)+ 审查阶段给 LLM 一个**受控只读取证工具子循环**
(白名单 15 个只读工具,`add_*/delete_*/set_*/draw_*` 一律禁止)。
2. **审查依据**:清单驱动(`review_checklist.json`)+ LLM 自主判断。
3. **输出**:Markdown + JSON 报告 + 可选 CAD 图上批注回写(统一落 `AI_REVIEW` 层)。
4. **基座改造:只做「B 最小集」**——换行分帧(`\n` 为消息边界)、去掉单次 `recv(2048)` 限制、
`isError` 映射、`id` 支持 string/number + 通知不回包;**不做** `initialize`/`ping` 握手。
5. **标准化路线**:先自研 agent 跑通 → 再做 stdio↔TCP 桥 → 远期才考虑 Streamable HTTP。
**Why(关键结论,非显而易见)**:
- 基座是**裸 TCP 自定义传输**。规范虽允许自定义传输,但标准客户端(Claude Desktop /
CodeBuddy / MCP Inspector)**只实现 stdio 与 Streamable HTTP**——因此裸 TCP 无论怎么补
生命周期都**无法被标准客户端直连**。"能被标准客户端接入"只有两条路:**stdio 桥**
(省力、CAD 侧零改动)或 **Streamable HTTP**(彻底、要在 CAD 内做 HTTP+SSE、最贵)。
- 自研 agent 直接连 TCP,传输是否"标准"**不影响**,故**标准化不是前置条件**。
- `mcp_server.cpp` 原来**单次 `recv` 仅 2048 字节**,请求超 2KB 会被截断成 `-32700`;
这是**服务端**限制、客户端绕不过去 → 必须先改基座。
- image 内容块 `{type:image,data,mimeType}` **本就是 MCP 标准**(`source:{type,mediaType}`
是 Anthropic Messages API 的格式,别混淆),无需改。
**How to apply**:新增审图工具仍走 `cad_mcp_plugins` + `mcp_config.json`;agent 侧工具从
`tools/list` **动态发现**,加工具零代码。日后要做标准客户端接入,**从 stdio 桥起步**。
## 新增产物
- `dwg_review/`(Python 包):`config.py`(环境变量,无硬编码 Key)、`mcp_client.py`
(唯一 TCP 封装:单飞锁 + 换行分帧 + 重试 + 兼容 `error`/`isError`)、`llm_client.py`、
`cad_tools.py`(动态工具表 + 只读白名单 `READ_ONLY_TOOLS`)、`checklist.py`、
`phases/{planning,evidence,review,report}.py`、`annotator.py`、`__main__.py`。
**取代**根目录散落的 `dwg_review_agent.py` / `agent_loop.py` 等重复脚本。
- `verify_mcp_frame.py`:基座改动验证脚本(分帧 / 大报文 / string id / 通知 / isError)。
## 环境事实
- 本机 **未安装 Pillow** → 截图下采样为**可选**(缺失时原样传原图,视觉 token 成本更高)。
如需控成本:`pip install pillow`。
- 视觉模型 `deepseek-flash`。
- **`DEEPSEEK_API_KEY` 设在 Windows `Machine`(系统)级**。因新设的系统变量**不会传播到已启动
的进程**,`dwg_review/config.py` 的 `_read_env()` 在进程环境读不到时**回退读注册表**
(`HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment` → `HKCU\Environment`)。
否则 CodeBuddy 内的命令永远读不到新设的 Key。
- **AutoCAD 2020 自动加载 ARX(用户配置,不在仓库内)**:在 `bin/Debug-R230/` 下建
`acad.rx`(内容一行 `cad_mcp_frame.arx`),并把该目录加入 CAD 的**搜索路径与信任路径**。
这是 AutoCAD 官方 RX 自动加载机制,比 `acaddoc.lsp` + LISP 更直接。
- AutoCAD 2020 安装于 `C:/Program Files/Autodesk/AutoCAD 2020/`;用户配置目录
`C:/Users/gjm/AppData/Roaming/Autodesk/AutoCAD 2020/R23.1/chs/`(`acaddoc.lsp` 已用于 PDF2CAD,勿覆盖)。
## 验证结论(2026-10-13 实测通过)
- `verify_mcp_frame.py` 4/4 PASS(换行分帧 / >2KB 报文不截断 / string id 原样回显 / 通知不回包 / isError)。
- `verify_annotate.py` 9/9 PASS(批注工具无回归)。
- `dwg_review --list-tools` = 26 个工具;`--plan-only` 取证正常;全流程跑出报告。
- **受控取证子循环实测生效**:LLM 自主调用了白名单内的 `get_drawing_info`/`get_layers`/
`find_zero_length`/`find_duplicate_entities`/`get_dimensions` 做二次确认。
- 批注回写实测通过;注意 `add_leader_annotation` 的 `points` **必须 ≥2 个点**(首个为箭头)。