| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100 |
- 'use strict';
- /**
- * 智能问数智能体 · 工具注册表
- * ----------------------------------------------------------------------------
- * 清单(manifestText,注入系统提示)与派发(get)单一事实源。
- * 模型给出的工具名先在此求交(未注册即拒绝并回注可用清单,防幻觉工具名),
- * 参数再经各工具 sanitize 钳制。本期全部工具只读(湖查询/校验),无写操作。
- */
- const lake = require('./lake.js');
- const compare = require('./compare.js');
- const cross = require('./cross.js');
- const peer = require('./peer.js');
- const entity = require('./entity.js');
- const cloud = require('./cloud.js');
- const report = require('./report.js');
- const TOOLS = [
- {
- name: 'lake_overview',
- desc: '摸底当前主体:门店/连锁清单、湖内可用日期区间、各粒度行数、最近一次同步结果。分析类问题的第一步,先看有什么数据再取数。',
- argsDoc: '{}(无参数)',
- sanitize: lake.overviewSanitize,
- handler: lake.overviewHandler,
- },
- {
- name: 'query_report',
- desc: '查经营数据。mode=detail 日期×门店明细 / mode=shop 按门店汇总(排行/TopN)/ mode=date 按日期汇总(趋势)。区间自动钳制在湖内(截止默认昨天)。',
- argsDoc: '{"mode":"shop","from":"YYYYMMDD","to":"YYYYMMDD","shops":["门店名,可部分匹配"],"metrics":["grossAmt","validOrderCnt"],"sort":"grossAmt","sortDir":"desc","limit":10}(from/to/metrics 缺省=近30天/营业额)',
- sanitize: lake.querySanitize,
- handler: lake.queryHandler,
- },
- {
- name: 'compare_periods',
- desc: '同比/环比对比:本期 vs 等长基期。自动做门店集合对齐(开/闭店单列)、比率加权、缺失日清单、收入+支出=营业额恒等式校验。凡问「变化/对比/为什么涨跌」一律用它,不要自己相减。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD","gap":0,"metrics":["grossAmt","validOrderCnt"],"shops":["门店名"]}(缺省=湖内最后7天 vs 紧邻前7天;gap=两期间隔天数,同比可用 gap 留空+自定 from/to 跨年)',
- sanitize: compare.compareSanitize,
- handler: compare.compareHandler,
- },
- {
- name: 'data_quality',
- desc: '数据体检:门店明细全零行、层间一致性(门店合计 vs 连锁 vs 公司)、恒等式、日期连续性、预留列状态、最近同步结果。回答前对数据可信度存疑时调用。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD"}(缺省=全湖区间)',
- sanitize: lake.qualitySanitize,
- handler: lake.qualityHandler,
- },
- {
- name: 'cross_check',
- desc: '层间一致性核对(可单独抽查指定区间):按日核对 门店合计 vs 连锁合计 vs 公司行(营业额+有效订单),>0.5% 容差记不一致。环比/对比结论出来前建议抽查一次。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD"}(缺省=全湖区间)',
- sanitize: cross.crossSanitize,
- handler: cross.crossHandler,
- },
- {
- name: 'raw_inspect',
- desc: '查某行 raw 原始字段(取数接口自带:环比差值/上期对比/同行均值排名),用于源侧交叉验证——本地算的数字 vs 接口自带的数字。字段按「包含匹配」取,命名以接口原样为准。',
- argsDoc: '{"date":"YYYYMMDD","shops":["门店名"],"keys":["gross_amt"]}(keys 缺省匹配营业额与单量相关字段)',
- sanitize: peer.rawSanitize,
- handler: peer.rawHandler,
- },
- {
- name: 'peer_benchmark',
- desc: '同行对标:门店自身值 vs 同行均值 vs 排名(来自全字段落库的 raw *_mall_avg/_rank)。凡问「对标/排名/同行」一律用它。',
- argsDoc: '{"field":"gross_amt","from":"YYYYMMDD","to":"YYYYMMDD","shops":["门店名"]}(field 蛇形命名,可用:valid_order_cnt/gross_amt/income_amt/expense_amt/exp_uv/order_user_cnt/clk_exp_rate/ord_clk_rate/per_actual_pay 等)',
- sanitize: peer.benchSanitize,
- handler: peer.benchHandler,
- },
- {
- name: 'cross_entity',
- desc: '跨主体(跨校/多账号)对比:湖内全部主体本期 vs 基期的营业额与有效订单。凡问「几家店/哪个食堂/跨校」类问题用它。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD"}(缺省=当前主体湖内最后 7 天)',
- sanitize: entity.entitySanitize,
- handler: entity.entityHandler,
- },
- {
- name: 'aitable_verify',
- desc: '湖↔云只读比对:本地数据湖 vs 钉钉 AI 表格三表(行数 + 营业额抽样值)。凡结论涉及「云端数据是否同步/两边数据是否一致」时用它;云端未启用时优雅降级。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD"}(缺省=全湖区间)',
- sanitize: cloud.cloudSanitize,
- handler: cloud.cloudHandler,
- },
- {
- name: 'build_report',
- desc: '生成经营分析 HTML 报告(KPI 概览/逐日趋势/门店明细,可打印导出 PDF)。用户要「报告/周报/导出」时调用,回答中提示点击「查看分析报告」。',
- argsDoc: '{"from":"YYYYMMDD","to":"YYYYMMDD"}(缺省=全湖区间)',
- sanitize: report.reportSanitize,
- handler: report.reportHandler,
- },
- ];
- function get(name) {
- return TOOLS.find((t) => t.name === name) || null;
- }
- function manifestText() {
- return TOOLS.map((t) => `- ${t.name}:${t.desc}\n 参数:${t.argsDoc}`).join('\n');
- }
- module.exports = { TOOLS, get, manifestText };
|