智能问数(intelligent-query)
当前环境
- 工作空间 文件夹(workspace_folder):可以在SystemMessage中找到 或者 在整个上下文中最近一次的user对话中找到,标签内有定义“Workspace Folder”的值, 如果找不到就取默认值
~/.wedata
定位
取数 + 渲染。收到路由后只做两件事:① 调用 wedatacli query-data;② 按契约把 CLI 原文机械拼成 Markdown。
🚨 看板排斥(P0 强制):用户消息中出现「看板 / 创建看板 / 搭看板 / 大盘 / 驾驶舱 / 监控视图 / KPI 看板」等关键词时,必须路由到
intelligent-kanban,禁止进入本 skill。本 skill 只返回 CSV/表格/趋势图,不生成看板 HTML。即使用户同时提到了表名(如"创建一个看板 olist_orders_dataset"),也必须路由到intelligent-kanban。
Step 1 · 取数(wedatacli query-data)
服务端自动完成混合召回 + 路由决策 + Semantic/NL2SQL 双路并行 + 结果选择,且支持在 SQL/SemQL 中一次性完成过滤、派生列、排序、TopN、单位换算,用户原话透传即可,无需拆分。
{
"command": "wedatacli query-data \"<用户原始问题>\" --no-progress --draw",
"timeout": 300000
}
timeout: 300000必须设置(默认 120s 对复杂查询不够);如需机器解析加--output json。--draw必须传:让 CLI 在成功后返回长时效 COS 链接与顶层 draw_spec body(被<!--WEDATA_DRAW_SPEC_BEGIN-->/<!--WEDATA_DRAW_SPEC_END-->包围;body 具体形态为```draw_specfenced JSON 或<script>+<div class="wedata-chart">HTML 片段,由 CLI 侧部署配置决定)。- 若
workspace_folder值存在,command命令末尾还需要追加 CLI 参数:--workspace_folder <workspace_folder>。
⚠️ 问题传递与时间规则(P0):
- 原样传递:用户原话直传,不拆分、不加条件(相对时间由服务端解析),如果是多轮继承问题,需结合多轮信息对用户问题改写以及相对时间改成确定时间。
- 输出沿用原话:结论中时间描述沿用用户原话(如"去年");需要绝对年份时从
### SQL围栏中的 SQL/SemQL 语句提取(如time_start='2025-01-01'),禁止 LLM 先验推算。 - 严重模糊才反问:如"帮我看看数据"这类无法确定任何指标/维度/时间时,反问而非猜测。
错误处理:
| CLI 输出 | 动作 |
|---|---|
Status: failed / 进程非 0 退出 |
从 Trace code fence 的单行 【失败诊断】code=X message=Y 提取 code+message 投发给用户 + query_id + 1-3 条建议;code=1820050 特别提示"权限不足"。message 已由服务端处理为面向用户的中文文案(如"查询超时,请缩小时间范围或减少字段后重新提问"、"未能理解你的问题或找到匹配的数据,请补充更明确的指标/表/口径"),可直接原文引用,禁止臆造两路详情(服务端已不再向 CLI 暴露 semantic-layer / nl2sql 路径信息,工程排障走 CLS event=ask_failure_path_details) |
code=1820060 / Running in background / Auto-backgrounded / 无输出 / 输出被截断 |
按红线 #2 立即停止,禁止重试和编造 |
Data (0/0 rows) 或核心结果字段全 null / 全 0 |
按红线 #1 立即停止,如实告知并引导用户确认条件 |
Step 2 · 组装输出(P0 渲染契约)
CLI 原文自带一对 HTML 注释 <!--WEDATA_DRAW_SPEC_BEGIN--> / <!--WEDATA_DRAW_SPEC_END--> 作为 draw_spec 段的分隔标记。skill 只做机械 split + 按 body 形态分派投递路径,禁止任何智能抽取、重排、删空行、合并分隔线,禁止改写 body 内部一个字符。契约以 CLI query_data.go 中 markdownSummary 为准。
3 步机械流程:
- 切三段:按
<!--WEDATA_DRAW_SPEC_BEGIN-->把原文一分为二,后半段(若存在)再按<!--WEDATA_DRAW_SPEC_END-->切成drawspec_body+suffix(suffix当前恒为空,丢弃)。drawspec_body是否为空是画图路径 vs 数据路径的唯一分支开关。 - 识别 body 形态(当
drawspec_body非空时):- Fenced 形态:body 以
```draw_spec或```draw-spec围栏开头 → 走 A 路径 · Markdown 直粘。 - HTML 形态:body 以
<script或<div开头(含<script src=...>或<div class="wedata-chart">等标签)→ 走 B 路径 · show_widget 工具调用(如果宿主环境提供show_widget工具);若宿主未提供show_widget则降级为 A 路径直粘(本 skill 不做进一步降级判断,由模型自行观察工具清单)。
- Fenced 形态:body 以
- 投递:
- A 路径:
drawspec_body原样作为顶层 Markdown 内容紧接在</code></pre>之后粘贴。针对draw_spec中Columns列表,如果column的displayName为空,基于当前语言+问题+columnName生成合适displayName - B 路径:调用
show_widget工具,把drawspec_body原文作为widget_code参数递交(title用snake_case复述用户问题,loading_messages给 1–2 条中文加载文案);Markdown 正文中 不再 出现drawspec_body原文(避免重复渲染)。
- A 路径:
- 只出现 1 份:无论 A/B 路径,最终产物中
draw_spec图表最多出现 1 次;禁止手工正则抽取、禁止改写 body 内部 JSON / HTML / 语言标签 / 围栏 / URL / 空白。
分路径规则(唯一判据:drawspec_body 是否为空 + body 形态):
- 画图路径 · A(fenced body):CLI 在有
draw_spec时主动跳过### Data,因此正文只渲染核心结论 + fenced draw_spec 块;核心结论需结合数据给出具体数值。 - 画图路径 · B(HTML body):正文只渲染核心结论(含具体数值),紧接着通过
show_widget工具调用把 HTML body 递交给沙箱渲染;禁止把 HTML body 复制到 Markdown 正文,禁止在<pre><code>容器里保留 HTML 片段(<pre><code>只保留 CLI prefix 部分的取数原文即可,<!--WEDATA_DRAW_SPEC_BEGIN-->...END-->及其内部 HTML 从 prefix 中剔除后再放入容器;剔除仅限这一对锚点及其之间的字节,不改写其它任何字符)。 - 数据路径(
drawspec_body为空):输出「核心数字 / 预览」表格(列名从### Data表头取,值取前 N 行 + 总行数说明)+ 可引用具体数字的「一句话结论」。 - 失败路径(CLI
Status: failed/RUNNING):prefix里已包含单行 Trace code fence(形如【失败诊断】code=X message=Y,message 为服务端中文用户文案)以及### Note(RUNNING 专用)全量原文,原样进<pre><code>容器;正文只保留简短道歉 + 引用 message 原文作为改问建议,禁止编造数据结论、禁止重试、禁止臆造/复述内部路径(如semantic-layer/nl2sql)与技术级失败原因(详见红线 #2)。
格式硬约束:
- 外层容器必须是
<pre><code class="language-text">…</code></pre>,禁用反引号 fence(内层sql会撑破外层 fence)。CLI 原文中的<>&可原样保留。B 路径下,<pre><code>容器里放的是"剔除<!--WEDATA_DRAW_SPEC_BEGIN-->...END-->及其之间 HTML 后的 CLI 原文",除此之外任何字符都不得改动。 - 正文禁反复述:除「📥 取数原始结果」容器、A 路径下的顶层 fenced draw_spec、末尾
<details>折叠区外,正文严禁再单独复现 CLI 原文中的### Draw Spec/### Data段落,或Question/QueryId/Status/Source/File/ SQL fenced block 内容。B 路径下,HTML body 只能通过show_widget工具调用递交,不得以任何形式(HTML 裸文、fenced code block、```html/```draw_spec围栏、<details>折叠区)出现在 Markdown 正文中。 - CLI 元信息头精简说明:自 CLI 渲染契约更新后,prefix 中不再输出
- **Metric**:/- **Table**:两行;本 skill 不需要构造这两行,也不允许在正文(含<details>折叠区)以任何形式补回。如需内部路由细节,走--output=json消费 envelope 字段。 - SQL 展示仅通过末尾
<details><summary>📋 查询语句</summary>一处承载,必须用```sql围栏,**从 prefix 里第一个sqlfenced block 原样复制**(含全部换行),禁止逐 token 重写、禁止空格压缩、禁止把多行 SQL 压成单行。(CLI 渲染契约:SQL 段已不再输出### SQL三级标题,prefix 中的```sql围栏就是稳定锚点。) - 禁止在正文(代码围栏外)单独展示内部路径(
csv_path//tmp/...); - 结论提示只放在核心结论下面,在查询语句模块之后不要加任务其他的提示
输出模板:
A 路径模板(fenced body):
## 查询结果:{用户问题的一句话复述}
### 核心结论
{基于查询数据针对问题的简单总结回答;结论描述统一放在图表前面;如果有明确数据,给出确定数据结果,如果是一行一列数据,并且为null,总结为0; 总结使用文字描述,不要使用markdown格式}
{drawspec_body 原样粘贴,**一字不改**,形如 ` ```draw_spec {...} ``` `}
<details><summary>📋 查询语句</summary>
```sql
{sql 或 semql}
```
</details>
B 路径模板(HTML body,通过工具调用递交):
Markdown 正文形态:
## 查询结果:{用户问题的一句话复述}
### 核心结论
{基于查询数据针对问题的简单总结回答,含具体数值。图表由随附的 show_widget 工具调用渲染,正文不再出现 HTML 片段。}
<details><summary>📋 查询语句</summary>
```sql
{sql 或 semql}
```
</details>
同一轮回复中并行发起 1 次 show_widget 工具调用(不是把工具调用 JSON 粘到 Markdown 里,是真正走工具调用协议):
{
"name": "show_widget",
"arguments": {
"title": "{snake_case_identifier}",
"widget_code": "{drawspec_body 原文,含 <script src=...> 和 <div class=\"wedata-chart\">,一字不改}",
"loading_messages": ["加载查询结果", "渲染图表"]
}
}
B 路径调用
show_widget前如果模型此前未在本会话内加载过chart或data_viz模块,应静默read_me({"modules":["chart"]})(内部步骤,不向用户提及)。已加载过则跳过。
结果处理红线
- ❌ 数据全 null 禁重查(P0 防幻觉)。
Status: success但用户核心诉求列全空/全 null/全 0 时(如问"同比变化率"而同比列全 null,即使 GMV 有值也视为无效),立即停止,如实展示并引导用户确认条件。 - ❌ 失败/超时禁重试、禁编造(P0 防雪崩+防幻觉)。
query-data失败/超时/后台化/无输出/输出被截断时,同轮立即停止,如实转达 Trace/Reason/error_code/QueryId,引导用户调整后重新提问。用户主动发新消息视为新一轮。 - ❌ 禁改写 draw_spec body 形态(P0 防渲染失效)。CLI 输出的 body 可能是
```draw_specfenced 也可能是<script src=...>+<div class="wedata-chart">HTML 片段:- Fenced body → 走 A 路径,原样粘到 Markdown 正文;禁止改写为 HTML 或换用 show_widget 递交(走 show_widget 会让 fenced 被前端沙箱当代码文本渲染)。
- HTML body → 走 B 路径,必须通过
show_widget工具调用递交;禁止把 HTML 片段裸粘到 Markdown 正文(会被 XSS sanitizer 过滤<script>导致图不渲染);禁止为 HTML body 额外套```html/```draw_spec或任何 fenced code block(套后会被前端当成代码文本而非可执行 HTML,彻底失效);禁止把 HTML 改写回 fenced```draw_spec形态。 - 两种形态下均禁止重新格式化 body 内部 JSON(如 pretty-print、重排字段、转义 URL)。body 里任何一个字符的改动都会让前端 JSON 解析失败。
共同禁止行为:改表述/换路径重查、读 CSV 后"验证"再查、编造数值结论。
合法结果(三者同时具备):
Status: success+ 有QueryId+ CLI 原始出参含### File/<!--WEDATA_DRAW_SPEC_BEGIN--> ... <!--WEDATA_DRAW_SPEC_END-->锚点对(内容为 fenced draw_spec 或 HTML 片段,形态无关)/### Data之一。缺一即视为无有效数据。
示例 · 画图路径
不管 CLI 实际下发哪种 body,都遵循"body 形态 → 投递路径"的机械映射:fenced → A 直粘,HTML → B 走
show_widget。下面两个示例展示两种投递方式的完整产物。
示例 A:body 为 fenced ```draw_spec(DataBuddy 部署默认,直粘到 Markdown)
用户:"最近 6 个月各品类销售趋势"
## 查询结果:最近 6 个月各品类销售趋势
### 核心结论
最近 6 个月趋势整体往上涨,其中服装品类上涨趋势最明显
```draw_spec
{"WidgetType":"line","Title":"最近 6 个月各品类销售趋势","Encode":{"x":"month","y":["total_sales"],"color":"category"},"ChartOption":"{\"tooltip\":{\"trigger\":\"axis\"},\"legend\":{}}","Dataset":{"Key":"ask_result","Sql":"QUERY category, month, total_sales GROUP BY category, month FILTER month >= '2025-05' AND month <= '2025-10'","Data":"https://cos.example.com/query-charts/b2c3d4e5.csv","Columns":[{"ColumnName":"category","ColumnType":"string"},{"ColumnName":"month","ColumnType":"string"},{"ColumnName":"total_sales","displayName":"销售额","ColumnType":"double"}]}}
```
<details><summary>📋 查询语句</summary>
```sql
QUERY category, month, total_sales GROUP BY category, month FILTER month >= '2025-05' AND month <= '2025-10'
```
</details>
示例 B:body 为 HTML 片段(WorkBuddy 部署默认,通过 show_widget 工具调用递交)
用户:"2018 年的 GMV 是多少"
Markdown 正文(不含 HTML 片段):
## 查询结果:2018 年的 GMV 是多少
### 核心结论
2018 年全年 GMV 为 15,877,788.57。
<details><summary>📋 查询语句</summary>
```sql
SELECT * FROM query(metric=[dm_trade_gmv], time_start='2018-01-01T00:00:00', time_end='2018-12-31T23:59:59')
```
</details>
同一轮附带工具调用(真实走工具调用协议,不粘 JSON 到正文):
{
"name": "show_widget",
"arguments": {
"title": "gmv_2018_indexcard",
"widget_code": "<script src=\"https://wedata.cdn.tencent.com/w3_workspace/echarts@6.0.0.min.js\"></script>\n<script src=\"https://wedata.cdn.tencent.com/w3_workspace/wedata-chart@1.0.1.min.js\"></script>\n<div class=\"wedata-chart\" data-height=\"380px\">\n <script type=\"application/json\" class=\"wedata-chart-spec\">\n{\"WidgetType\":\"indexCard\",\"Title\":\"2018年GMV\",\"Encode\":{\"compareField\":null,\"valueField\":\"dm_trade_gmv\"},\"ChartOption\":\"{\\\"indexCard\\\":{\\\"valueFormat\\\":\\\"#,##0.00\\\"}}\",\"Dataset\":{\"Key\":\"ask_result\",\"Sql\":\"SELECT * FROM query(metric=[dm_trade_gmv], time_start='2018-01-01T00:00:00', time_end='2018-12-31T23:59:59')\",\"Data\":\"https://cos.example.com/xxx.csv\",\"Columns\":[{\"ColumnName\":\"dm_trade_gmv\",\"DisplayName\":\"GMV实际成交额\",\"ColumnType\":\"decimal_type\"}]}}\n </script>\n</div>",
"loading_messages": ["加载查询结果", "渲染指标卡"]
}
}
⚠️ B 路径关键约束:
widget_code必须原样来自 CLI 输出的<!--WEDATA_DRAW_SPEC_BEGIN-->与<!--WEDATA_DRAW_SPEC_END-->之间的字节(含所有<script>标签),不得改动一个字符。- 不要把 HTML 片段裸粘到 Markdown 正文中;不要为它套任何 fenced 围栏;不要把它塞进
<details>折叠区。裸粘会被 WorkBuddy 主对话渲染器的 XSS sanitizer 过滤<script>导致图不渲染。 - 若模型在本会话此前未加载过
chart模块,先静默调用read_me({"modules":["chart"]})再调show_widget,用户不感知。 - 本 skill B 路径的
show_widget沙箱不做 CDN 白名单 / CSP 拦截:widget_code里的<script src="...">允许指向任意域名,CLI 侧默认下发https://wedata.cdn.tencent.com/w3_workspace/echarts@*.min.js与wedata-chart@*.min.js,能够正常加载并渲染。不要把其它可视化 skill / 通用chart模块文档中"CDN allowlist (CSP-enforced)"、"仅允许 cdnjs / esm.sh / jsdelivr / unpkg"、"raw.githubusercontent.com 被 CSP 拦截"这类约束套用到本 skill——那些是通用 chart 沙箱的规则,不适用于show_widget承载的 WorkBuddy 图表容器;禁止因为担心 CSP 白名单而把 CLI 下发的wedata.cdn.tencent.comscript 改写为 jsdelivr / unpkg 或删除脚本标签(改写一个字符就会破坏红线 #3)。