# cabinetTool 返回数据优化方案 ## 背景 `cabinetTool` 查询智能柜详情时,返回的 `cells` 数组可能包含大量格口信息,导致返回给 LLM 的数据量过大,影响响应效率。 ## 修改目标 1. **减少返回数据量**:列表数据(cells)只返回第一条 2. **增加统计信息**:返回中新增完整的统计信息 3. **保留完整数据**:完整数据保留在缓存中,供后续使用 4. **引导使用代码执行**:通过 prompt 说明,引导 Agent 使用 code-executor-tool 提取完整数据 ## 修改内容 ### 1. cabinet-tool.ts #### outputSchema 变更 新增 `stats` 统计字段: ```typescript outputSchema: z.object({ success: z.boolean(), message: z.string(), data: z.any().optional().describe("柜机信息(cells列表仅返回第一条,完整数据在缓存中)"), stats: z.object({ cellsTotal: z.number().describe("格口总数"), cellsFree: z.number().describe("空闲格口数"), cellsOccupied: z.number().describe("占用格口数"), cellsSmall: z.number().describe("小格数量"), cellsMedium: z.number().describe("中格数量"), cellsLarge: z.number().describe("大格数量"), cellsExtraLarge: z.number().describe("超大格数量"), }).optional().describe("统计信息"), cacheId: z.string().optional().describe("缓存ID,用于后续引用该查询结果"), expiresAt: z.number().optional().describe("缓存过期时间戳"), }), ``` #### execute 逻辑变更 1. 计算完整统计信息 2. 将简化数据(仅包含第一条 cell)返回给 LLM 3. 完整数据(含 stats)存入缓存 ```typescript const cells = response.data?.cells || []; // 计算统计信息 const stats = { cellsTotal: cells.length, cellsFree: cells.filter(c => c.usageStatus === 1).length, cellsOccupied: cells.filter(c => c.usageStatus === 2).length, cellsSmall: cells.filter(c => c.cellType === 1).length, cellsMedium: cells.filter(c => c.cellType === 2).length, cellsLarge: cells.filter(c => c.cellType === 3).length, cellsExtraLarge: cells.filter(c => c.cellType === 4).length, }; // 简化数据(仅保留第一条cell) const firstCell = cells[0] || null; const simplifiedData = { ...response.data, cells: firstCell ? [firstCell] : [], }; // 返回结果 const result = { success: response.code === 0, message: response.msg || "查询成功", data: simplifiedData, stats, }; ``` ### 2. multi-function-agent.ts #### 柜机查询说明更新 ``` 2. **柜机查询**:使用柜机工具根据柜机ID查询智能柜详细信息。返回数据中格口(cells)列表仅包含第一条,完整数据保留在缓存中。返回结果包含 stats 统计信息(总数、空闲/占用数、各类型数量)。如需获取完整格口列表,请使用代码执行工具通过 cacheId 提取。 ``` #### 代码执行示例更新 新增 cabinetTool 的缓存使用示例: ```markdown - 缓存-柜机:code: "return cacheCabinet_0?.data?.cells?.filter(c => c.usageStatus === 1)", cacheIds: ["cacheCabinet_0"] -> 获取所有空闲格口 - 缓存-柜机:code: "return cacheCabinet_0?.data?.cells?.filter(c => c.cellType === 2)", cacheIds: ["cacheCabinet_0"] -> 获取所有中格 ``` ## 返回数据结构对比 ### 修改前 ```json { "success": true, "message": "查询成功", "data": { "cabinetId": 1, "cabinetName": "柜机A", "cells": [ { "cellId": 1, "cellNo": 1, ... }, { "cellId": 2, "cellNo": 2, ... }, { "cellId": 3, "cellNo": 3, ... } // ... 更多格口 ] }, "cacheId": "cacheCabinet_1", "expiresAt": 1700000000000 } ``` ### 修改后 ```json { "success": true, "message": "查询成功", "data": { "cabinetId": 1, "cabinetName": "柜机A", "cells": [ { "cellId": 1, "cellNo": 1, ... } ] }, "stats": { "cellsTotal": 50, "cellsFree": 30, "cellsOccupied": 20, "cellsSmall": 10, "cellsMedium": 20, "cellsLarge": 15, "cellsExtraLarge": 5 }, "cacheId": "cacheCabinet_1", "expiresAt": 1700000000000 } ``` ### 缓存数据(完整) ```json { "success": true, "message": "查询成功", "data": { "cabinetId": 1, "cabinetName": "柜机A", "cells": [ { "cellId": 1, "cellNo": 1, ... }, { "cellId": 2, "cellNo": 2, ... }, { "cellId": 3, "cellNo": 3, ... } // ... 所有格口 ] }, "stats": { "cellsTotal": 50, "cellsFree": 30, "cellsOccupied": 20, "cellsSmall": 10, "cellsMedium": 20, "cellsLarge": 15, "cellsExtraLarge": 5 } } ``` ## 使用示例 ### 场景1:查询柜机概况 直接使用 cabinetTool,获取统计信息: ``` 用户:查询柜机1的概况 Agent -> cabinetTool(cabinetId: 1) -> 返回 stats 信息 ``` ### 场景2:获取所有空闲格口 使用代码执行工具通过 cacheId 提取: ``` 用户:柜机1有哪些空闲格口? Agent -> cabinetTool(cabinetId: 1) -> codeExecutorTool( code: "return cacheCabinet_0?.data?.cells?.filter(c => c.usageStatus === 1)", cacheIds: ["cacheCabinet_0"] ) -> 返回空闲格口列表 ``` ### 场景3:筛选特定类型格口 结合 context 参数筛选: ``` 用户:柜机1有哪些大格可以存放商品? Agent -> cabinetTool(cabinetId: 1) -> codeExecutorTool( code: "return cacheCabinet_0?.data?.cells?.filter(c => c.cellType === 3 && c.usageStatus === 1)", cacheIds: ["cacheCabinet_0"] ) -> 返回空闲大格列表 ``` ## 修改文件清单 | 文件 | 修改类型 | 说明 | |------|---------|------| | `src/mastra/tools/cabinet-tool.ts` | 修改 | outputSchema 新增 stats 字段,execute 逻辑简化返回数据 | | `src/mastra/agents/multi-function-agent.ts` | 修改 | 更新 instructions,说明返回数据和缓存使用方式 | | `doc/cabinet-tool-optimization.md` | 新建 | 文档总结修改方案 | ## 验证步骤 1. **构建项目**:运行 `pnpm build` 确保无编译错误 2. **启动服务**:运行 `pnpm dev` 启动开发服务器 3. **测试 API**:调用 cabinetTool,检查返回数据是否符合预期 4. **测试场景**: - 查询单个柜机,检查返回数据是否只包含第一条 cell - 使用 code-executor-tool 提取所有空闲格口 - 使用 code-executor-tool 统计格口类型分布