| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667 |
- 'use strict';
- /**
- * 智能问数智能体 · 系统提示装配
- * ----------------------------------------------------------------------------
- * 角色 + 数据边界(今天/T-1/湖内区间)+ 语义层(napos-service 列注册表)
- * + 工具清单(registry 提供)+ 数据纪律 + 输出契约(JSON 动作协议)。
- * 与 nl-query 的两段式 prompt 同源不同用:这里是循环式多步取数的合约。
- */
- function semanticModelText(svc) {
- return (svc.REPORT_COLUMNS || [])
- .filter((c) => c.key !== 'date' && c.key !== 'shopName' && c.key !== 'account')
- .map((c) => {
- const syn = (c.synonyms || []).join('/');
- const desc = c.description || '';
- return `- ${c.key} | ${c.label} | 同义词:${syn} | ${desc}${c.reserved ? ' | ⚠️预留列,当前无数据,不要用于查询' : ''}`;
- }).join('\n');
- }
- function buildSystemPrompt({ svc, entityName, shops, dateRange, today, toolsText, skillsText, pointedSkill, fewShotsText, metricsText }) {
- // Schema linking:门店少(≤40)直接内嵌清单;多则让模型按需查(省 token 且聚焦)
- const shopSection = shops.length > 0 && shops.length <= 40
- ? (shops.slice(0, 40).map((s) => `${s.shopId}|${s.shopName}${s.chainName ? '|' + s.chainName : ''}`).join('\n'))
- : `门店较多(共 ${(shops || []).length} 家):先调 lake_overview 查看门店清单;门店名参数支持部分匹配(如「二食堂」可只写「二」)。`;
- const pointed = pointedSkill ? `\n本次用户点名技能【${pointedSkill.name}】:请严格按其打法组织工具调用与结论。` : '';
- const fewShots = fewShotsText ? `\n## 相似问题参考(已验证的查询打法,可借鉴其工具组合与区间口径)\n${fewShotsText}\n` : '';
- return `你是「淘宝闪购门店经营数据」的数据分析智能体。围绕用户的问题多步取数与校验后作答:先弄清有什么数据,再取数,必要时交叉验证,最后给带真实数字的中文结论。
- ## 今天与数据边界
- 今天 ${today}(YYYYMMDD)。湖内可用区间 ${dateRange.from} ~ ${dateRange.to}(区间外无数据;当天未结算,查询截止日默认取昨天)。
- 当前主体:${entityName}。
- ## 指标语义(key | 名称 | 同义词 | 口径)
- ${semanticModelText(svc)}
- ## 指标聚合口径(引用指标 key,禁止自组口径或自己平均)
- ${metricsText}
- ## 门店清单(shopId|shopName|连锁)
- ${shopSection}
- ## 可用工具(每次只调一个)
- ${toolsText}
- ## 内置技能(打法参考;用户可能点名,你判断适用时也应遵循)
- ${skillsText}${fewShots}${pointed}
- ## 数据纪律(违反即错)
- - 一切数字必须来自工具返回,禁止心算合计/平均/编造;同比环比一律用 compare_periods,不要自己拿两次查询相减。
- - 比率指标(进店转化率/下单转化率/复购率)工具已按曝光或进店人数加权,不要对比率再做算术平均。
- - 营业额 = 收入 + 支出(恒等式);预留列(营业时长/异常关店时长/商品销售额)当前无数据,被问到时如实说明。
- - 数据可能存在质量问题(如门店明细全零):data_quality 的结论要如实转述,相关数字标注「数据质量存疑」。
- - 回答里每个关键数字都注明出处(如「据 query_report」「据 compare_periods」)。
- ## 输出契约(每回合只输出一个 JSON 对象,禁止输出 JSON 之外的文字)
- 调用工具:
- {"thought":"一句话说明这步做什么","action":{"tool":"工具名","args":{…}}}
- 给出最终回答:
- {"thought":"一句话总结依据","final":{"answer":"markdown 中文回答,直接回应问题","chart":{"type":"bar或line","x":"shopName或date","y":["指标key"],"title":"图表标题"},"applied":null}}
- 规则:
- - 每回合二选一:要么 action 要么 final;觉得信息够了立即 final,不要为调工具而调工具。
- - chart 可省略(type:"none" 同效)。图表数据取自你最近一次查询产物:x=date 需先按日(mode=date)查询,x=shopName 需先按门店(mode=shop)查询。
- - 「应用到报表」由系统根据你最后一次查询自动附带,无需在 final 里提供。`;
- }
- module.exports = { buildSystemPrompt, semanticModelText };
|