legacy-tool-inventory.md 6.03 KB

旧 64 AI 工具能力盘点(迁移覆盖基线)

目的:现有 64 个元数据工具(ai_tool/ai_tool_detail_params)→ 迁到 6 类通用工具(Read/Query/KgSearch/AskUser/FormCollect/ProposeWrite)时,不能丢的业务语义清单。 关键发现:这 64 个不是"薄读"——其中 25 个是写操作,内含大量业务逻辑(BtnCopyTo 单据流转引擎 + 报价定价引擎)。

迁移进度(2026-07-23):新工具已建齐(9 个 @Tool,见 agent-architecture.md §17.1), 但旧 64 个工具一个都还没退役——AppStartupRunner 仍在启动时加载它们,旧对话端点仍对外。 本文的覆盖映射尚未做过逐条回归验证。

执行机制(证据)

  • AppStartupRunner.initCache() 载入 → DynamicToolProvider.init() 每行建一个 ToolSpecification+ToolExecutor(按 sSceneId 分桶)。
  • LLM 面向的 executor 只收集/校验参数,不跑业务逻辑;真正执行在用户确认后 XlyErpService.doDynamicTool()DynamicToolProvider.doDynamicTool()
  • iBizType 是操作类型判别键executeToolAfter):1|4=存储过程写;2=sBizContent 字面 SQL;3=HTTP(当前 0 工具用);doDynamicTool4|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 个无业务表单(queryWorkOrderCostsSrcFormIdqueryTodayTask+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 接地 + 表范围sInputTabelNamesStructureMemo)——没它 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_AddCommonAfterNewsCopyTo/sCopyToSrcId 打开已建单据。→ 通用 ProposeWrite 必须带 源/目标表单对 + 选择模式,不能只给一堆行。(这正是我建的 viw_kg_edge_flow 提供的映射。)
  5. 报价定价引擎(4 工具):分组参数(产品/部件)、动态部件增删(拼音克隆)、sDynamicParamRuleSql 动态参数、枚举/常量/SQL 选项列表、sParamMissMemo 缺参提示、Sp_Ai_AddQuoQuoAfter 定价。→ 参数收集交给 FormCollect(表单呈现)(渲染报价表单让用户填,字段由 ERP 元数据驱动,无需 Skill);写仍走单一 ProposeWrite,报价 ERP 侧自动执行。
  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. 防重复 + 确认门:单次调用锁 toolExecutedisConfirmed(确认/生成/全部确认)、iActionType=1 清记忆。

需清理的配置异常(别原样迁)

  • queryWorkOrderCost:type 1 但 sBizContent 空、无表单 → 空 proc,需先查清目标数据源。
  • queryTodayTask+chat:用通用非业务表单 id。
  • sSrcSlaveId 全 NULL;iBizType 3(HTTP)定义了但 0 工具使用。

对架构的启示

  • ProposeWrite 保持单一写工具;copyto(源→目标+合并/分单,靠 KG 映射)与报价的差异只在 ERP 执行策略(报价自动执行)。报价的多部件参数收集交给 FormCollect(表单呈现),非 Skill。
  • KgSearch + KG 视图正好承接 BtnCopyTo 的源→目标映射(viw_kg_edge_flow)与参数消歧(viw_kg_field_dict)。
  • Query 降级为 ad-hoc 兜底:预建表单/过程能答的(含 type-5 那类聚合统计)都走 Read(ERP API,权限安全);Query 只留没有现成表单能答的分析尾巴,且"每表单范围"从"软约束"升级为"执行期强制 allowlist"(与安全调查一致)。