diff --git a/README.md b/README.md index a9a0eb2..69c711a 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ - **全局搜索**: 在项目中搜索文本内容 - **撤销/重做**: 管理编辑器的撤销栈 - **特效管理**: 创建和修改粒子系统 -- **并发安全**: 指令队列串行化执行,防止编辑器卡死 +- **并发安全**: 指令队列串行化执行,队列上限 100 条(超限返回 HTTP 429),防止编辑器卡死 - **超时保护**: IPC 通信和指令队列均有超时兜底机制 - **属性保护**: 组件核心属性黑名单机制,防止 AI 篡改 `node`/`uuid` 等引用导致崩溃 - **AI 容错**: 参数别名映射(`operation`→`action`、`save`→`update`/`write`),兼容大模型幻觉 @@ -113,7 +113,7 @@ Args: [你的项目所在盘符]:/[项目路径]/packages/mcp-bridge/src/mcp-pro - **描述**: 获取当前场景的完整节点树结构(支持分页避免长数据截断)。如果要查询具体组件属性请配合 manage_components。 - **参数**: - `nodeId`: 指定的根节点 UUID。如果不传则获取整个场景的根 (可选)。 - - `depth`: 遍历的深度限制,默认为 2。用来防止过大场景导致返回数据超长 (可选)。 + - `depth`: 遍历的深度限制,默认为 2。用来防止过大场景导致返回数据超长 (可选)。每层最多返回 50 个子节点,超出部分通过 `childrenTruncated` 字段标注。 - `includeDetails`: 是否包含坐标、缩放等杂项详情,默认为 false (可选)。 ### 5. update_node_transform diff --git a/docs/UPDATE_LOG.md b/docs/UPDATE_LOG.md index 66667ae..138bd3f 100644 --- a/docs/UPDATE_LOG.md +++ b/docs/UPDATE_LOG.md @@ -410,3 +410,24 @@ - **验证**: 创建的预制体文件结构与编辑器原生拖拽创建的预制体完全一致,可正常打开编辑、实例化使用,控制台零报错。 ps: 感谢 @亮仔😂 😁 🐔否? 提供的反馈以及操作日志 + +--- + +## 性能优化与防御性增强 (2026-03-04) + +### 1. JSON 响应压缩输出 (`src/main.js`) + +- **问题**: MCP 工具调用返回结果时使用 `JSON.stringify(result, null, 2)` 格式化输出,凭空增加约 20-40% 的响应体积,消耗额外 Token 且对 AI 工具毫无意义。 +- **修复**: 移除缩进参数,改为 `JSON.stringify(result)` 压缩输出。 +- **效果**: 响应体积减少 20-40%,直接降低 AI 模型的 Token 消耗成本。 + +### 2. 指令队列长度限制 (`src/main.js`) + +- **问题**: `commandQueue` 数组无最大长度限制,理论上在极端情况下可能无限增长。 +- **修复**: 新增 `MAX_QUEUE_LENGTH = 100` 常量。`enqueueCommand` 入口检查队列长度,超限时直接 reject 并返回 HTTP 429 状态码,同时记录告警日志。 +- **保护**: 在 `enqueueCommand` 调用处补充 `.catch()` 处理 reject,确保 HTTP 响应正常关闭,避免 unhandled promise rejection。 + +### 3. 层级树子节点数量上限 (`src/scene-script.js`) + +- **问题**: `get-hierarchy` 的 `dumpNodes` 递归遍历子节点时无数量限制,若某个节点下有数百个同级子节点,返回数据量巨大。 +- **修复**: 新增 `MAX_CHILDREN_PER_LEVEL = 50` 安全上限。每层最多返回 50 个子节点,超出部分在返回数据中通过 `childrenTruncated` 字段标注被截断的数量,帮助 AI 知悉还有更多子节点未列出。 diff --git a/docs/注意事项.md b/docs/注意事项.md index e6baaef..3a67791 100644 --- a/docs/注意事项.md +++ b/docs/注意事项.md @@ -132,6 +132,7 @@ 1. 队列在 `processNextCommand` 的 `catch` 块中有防死锁保护,即使某个指令抛出异常也不会永久阻塞后续指令。 2. `batchExecute` 内部也已从并行 `forEach` 改为串行链式执行。 3. 队列长度会在日志中显示(`REQ -> [toolName] (队列长度: N)`),可用于排查积压问题。 + 4. **队列长度限制**:队列上限为 100 条。超限时新请求会被直接拒绝并返回 HTTP 429 状态码,防止极端情况下内存无限增长。 ### 9.2 `refresh_editor` 路径要求 @@ -153,6 +154,7 @@ - **最佳实践**: - **默认使用 `depth: 2`** (默认限制) 来逐步探查。 - **结合 `nodeId` 参数**:找到关键模块(例如 `Canvas/LoginPanel`)的 UUID 后,再单独向该 `nodeId` 请求下一层的结构,而非每次从根部拉取。 +- **子节点数量上限**:每层最多返回 50 个子节点。如果某节点的子节点数超过 50,返回数据中会包含 `childrenTruncated` 字段标注被截断的数量。此时可通过 `nodeId` 参数指定该节点单独获取完整子节点列表。 ### 10.2 大对象与长数组截断