# 旧 64 AI 工具能力盘点(迁移覆盖基线) > 目的:现有 64 个元数据工具(`ai_tool`/`ai_tool_detail_params`)→ 迁到 5 个通用工具(Read/Query/KgSearch/AskUser/ProposeWrite)时,**不能丢**的业务语义清单。 > 关键发现:**这 64 个不是"薄读"——其中 25 个是写操作,内含大量业务逻辑**(BtnCopyTo 单据流转引擎 + 报价定价引擎)。 ## 执行机制(证据) - `AppStartupRunner.initCache()` 载入 → `DynamicToolProvider.init()` 每行建一个 `ToolSpecification`+`ToolExecutor`(按 `sSceneId` 分桶)。 - **LLM 面向的 executor 只收集/校验参数**,不跑业务逻辑;真正执行在用户确认后 `XlyErpService.doDynamicTool()` → `DynamicToolProvider.doDynamicTool()`。 - **`iBizType` 是操作类型判别键**(`executeToolAfter`):`1|4`=存储过程写;`2`=`sBizContent` 字面 SQL;`3`=HTTP(当前 0 工具用);`doDynamicTool` 里 `4|5`=ERP 表单 API 读;`8`=NL2SQL/向量。 ## 按操作类型分布(共 64) | iBizType | 类型 | 数量 | 参数 | 覆盖工具 | |---|---|---|---|---| | 8 | read-nl2sql(NL→SQL + Milvus 向量兜底) | 33 | 0(纯 NL) | **Query (+KgSearch)** | | 4 | read-list→确认→write-copyto(BtnCopyTo 流转) | 21 | 16 | **Query+AskUser+ProposeWrite** | | 1 | write-proc 报价定价(bQuo) | 4 | 78 | **AskUser+ProposeWrite**(最复杂) | | 5 | read-erpapi(表单 REST 读,可导出) | 3 | 8 | **Read/Query** | | 1 | read-aggregate 工单成本(**配置损坏**) | 1 | 1 | Query(需先修) | | 2 | read-fixedsql(手写 SELECT + 数据权限函数) | 1 | 0 | Query | | 7 | chat(无执行) | 1 | 0 | —(不属 5 工具) | form-backed 61;3 个无业务表单(`queryWorkOrderCost` 空 `sSrcFormId`;`queryTodayTask`+`chat` 用通用 KPI 模块)。`sSrcSlaveId` 全 NULL(未用)。 ## 覆盖映射(按新工具) - **Query** ≈ 35(33 nl2sql + queryTodayTask + queryWorkOrderCost) - **ProposeWrite** = 25 写(21 copyto + 4 报价),全部人在环确认 - **AskUser** = 缺参/消歧/确认循环(type-4 选行、type-1 报价 13–25 参数) - **Read** = 3 个表单明细读(type-5) - **KgSearch** = 33 个 nl2sql 里内嵌的 Milvus 向量兜底(每工具一个 collection + 字段映射) ## ⚠️ 迁移绝不能丢的语义(最重要) 1. **每表单的 NL2SQL 接地 + 表范围**(`sInputTabelName`、`sStructureMemo`)——没它 Query 既丢正确性、又丢**权限/范围边界**(33 工具)。注:安全调查发现这个范围**只在"喂模型"时生效、执行期不强制** → 新 Query 必须把它变成**强制 allowlist**。 2. **每表单的向量 collection + 字段映射**(`sVectorfiled/sVectorjson/…`)驱动 KgSearch,以及 SQL-vs-向量的 `routeQuery` 决策。 3. **学习到的 SQL few-shot 缓存 + 自修复循环**:`ai_global_agent_question_sql` 缓存、5 次带错重试、`ai_sql_error_history`。 4. **BtnCopyTo 单据流转引擎(21 工具)**:源→目标表单对、`operateType` **合并 vs 分单**(一个/多个单据)、行→`sSlaveId` 解析、`Sp_Ai_AddCommonAfterNew`、`sCopyTo/sCopyToSrcId` 打开已建单据。→ 通用 ProposeWrite **必须带 源/目标表单对 + 选择模式**,不能只给一堆行。**(这正是我建的 `viw_kg_edge_flow` 提供的映射。)** 5. **报价定价引擎(4 工具)**:分组参数(产品/部件)、动态部件增删(拼音克隆)、`sDynamicParamRuleSql` 动态参数、枚举/常量/SQL 选项列表、`sParamMissMemo` 缺参提示、`Sp_Ai_AddQuoQuoAfter` 定价。→ **复杂到应单独做成一个 Skill/专用能力,别硬塞通用 ProposeWrite。** 6. **参数归一化 + 外键消歧**(`applyValues`):名称→id 解析、"不存在"拒绝、"存在多个请选择"编号消歧、中↔英/CONST 反查、`sDefaultValue`、类型感知必填(数值 d 字段 0=空)、只校验首个必填参的怪癖、date 强制 `yyyy-MM-dd` 注入当前日期、`bConfirmAfter`。→ 映射到 **AskUser + KG 字段字典**。 7. **ERP-API 读路径(type-5 + type-4 的读半段)**:走 ERP token、表单权限、列可见性 `bVisible`、聚合过程(AR/AP/进度)、Excel 导出。→ 直连 DB 的 Query **会绕过**这些。 8. **数据权限**:`fun_get_jurisdiction`(queryTodayTask)、表单权限——通用 Query 必须保留。 9. **多租户/会话上下文**(`executeToolAfter` 注入 `sUserId/sBrandsId/sSubsidiaryId/sSrcFormId/sControlName`)——每个 proc 都要。 10. **防重复 + 确认门**:单次调用锁 `toolExecuted`、`isConfirmed`(确认/生成/全部确认)、`iActionType=1` 清记忆。 ## 需清理的配置异常(别原样迁) - `queryWorkOrderCost`:type 1 但 `sBizContent` 空、无表单 → 空 proc,需先查清目标数据源。 - `queryTodayTask`+`chat`:用通用非业务表单 id。 - `sSrcSlaveId` 全 NULL;`iBizType 3`(HTTP)定义了但 0 工具使用。 ## 对架构的启示 - **ProposeWrite 需分两类**:copyto(源→目标+合并/分单,靠 KG 映射)与 报价(结构化多部件填单+定价,做成 Skill)。 - **KgSearch + KG 视图正好承接** BtnCopyTo 的源→目标映射(`viw_kg_edge_flow`)与参数消歧(`viw_kg_field_dict`)。 - **Query 的"每表单范围"必须从"喂模型软约束"升级为"执行期强制 allowlist"**(与安全调查一致)。