Files
cad-agent/ai.memory/project_review_agent_impl.md
T
gjm f33d42afe9 feat(bridge): 新增 stdio↔TCP 桥,让标准 MCP 客户端可直连 CAD 基座
标准 MCP 客户端(Claude Desktop / CodeBuddy / MCP Inspector)只实现 stdio 与
Streamable HTTP,无法直连 cad_mcp_frame 的自定义裸 TCP。新增 mcp_bridge 包在
客户端与基座之间做协议适配,CAD 侧零改动:

- 合成基座缺失的生命周期:initialize(含协议版本协商、capabilities、serverInfo)
  与 ping;notifications/* 按规范不回包。
- tools/list、tools/call 原样转发到 127.0.0.1:8080,result 与顶层 error 忠实透传,
  仅把 id 改写回客户端原始 id。
- 并发:读线程即时应答 initialize/ping,单工作线程串行转发工具调用(保证顺序、
  慢工具不阻塞 ping)。
- stdout 只走 sys.stdout.buffer 并加锁,规避 Windows 的 \n→\r\n 翻译;
  诊断信息一律走 stderr。
- CAD 未启动时桥照常启动,工具调用回 -32603(可重试)。
- 入口:python -m mcp_bridge,支持 --host/--port/--timeout/--verbose/--print-config。

dwg_review/mcp_client.py 增加 raw_rpc()(_rpc 新增 normalize 开关),
返回基座原始响应 dict 供桥透传,避免重复实现 TCP 封装。

验证:
- verify_stdio_bridge.py 24/24 PASS(版本协商、通知不回包、ping、tools/list 与基座
  等价、tools/call、错误透传、-32700、string id、stdout 纯净性、死端口降级)。
- 真实标准客户端 MCP Inspector 冒烟通过:tools/list 拿到 26 个工具,
  tools/list --strict 退出码 0(无 schema 可移植性问题),
  tools/call get_drawing_info 返回标准 content + isError:false。
- 回归:verify_mcp_frame.py 4/4、verify_annotate.py 9/9、dwg_review --list-tools/--check 正常。
2026-10-14 00:44:15 +08:00

5.7 KiB
Raw Blame History

name, description, type
name description type
LLM 识图审图 Agent —— 架构决策(已定稿) cad_mcp_frame + 自研 Agent 的架构决策与分阶段路线——混合式(流水线骨架+受控只读取证子循环)、基座 B 最小集、标准化路线(先 stdio 桥) 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。 (2026-10-14 更新:stdio 桥已实现并验证通过,见 project_stdio_bridge.md。 远期仅剩 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 已安装(12.3.0)。截图下采样策略(dwg_review/llm_client.py: downsample_image_b64): 视觉 token 成本由像素尺寸决定而非文件大小 → 只在长边超 IMAGE_MAX_EDGE(默认 1280)时才缩放; 既不需要缩放、格式又没变时原样返回不重编码(避免给 CAD 线稿引入无谓压缩损失); 缩放后默认输出无损 PNG(IMAGE_FORMAT=png,适合线稿),需要更小体积可设 IMAGE_FORMAT=jpeg。 缺少 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,勿覆盖)。
  • 改 cad_mcp_plugins 后重链接必须先关 CAD:插件 DLL 被 CAD 进程持有(LNK1168: cannot open ...dll for writing)。模板 cad-mcp-frame.json 里的 "hot_reload": true 只是占位、代码未实现, mcp_Tools::clear()(唯一 FreeLibrary 处)仅在 ARX 卸载时调用 → 没有热重载。 流程:关 CAD → cmake --build --preset R230 --config Debug → 重启 acad.exe(acad.rx 自动加载) → 轮询 127.0.0.1:8080 监听。编译阶段可先行(语法错误会被提前暴露,只有链接会因占用失败)。

验证结论(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 个点(首个为箭头)。