Quick BI-SmartQ —— QuickBI 数据分析助手

单一入口覆盖所有 QuickBI 数据分析能力。根据用户意图自动路由到对应模块——无需手动选择。

范围

可以做:

  • 自动识别用户意图并路由到对应的数据分析模块
  • 通过 Quick BI API 对用户上传的 Excel/CSV 文件进行自然语言分析(文件问答)
  • 对 Quick BI 平台数据集进行自然语言查询分析,自动智能选表与匹配(数据集问答)
  • 解析 PDF/Word/Excel/CSV/图片,提取文本,并支持提取关键字段生成结构化 Excel(文档解析)
  • 自动将 QuickBI 仪表板转换为数据查询 skill(仪表板 Skill 生成)
  • 对数据集进行深度洞察分析(数据洞察)
  • 基于分析结果自动生成专业数据报告(数据报告)

不可以做:

  • 在问答场景中使用 pandas/openpyxl/csv 等库本地读取文件进行分析
  • 要求用户手动选择模块或提供 cubeId 等内部参数
  • 执行与 QuickBI 数据分析无关的任务

图片输出规则(必读)

本 Skill 生成图表图片(PNG)作为核心交付物给用户。图片必须展示给用户——它们是本 Skill 的主要输出。

当脚本输出包含 !Title 图片引用时,Agent 必须:

  1. 逐字包含每个 !Title 在回复正文中——这是用户看到图表的唯一方式
  2. 不得用 ReadshowFilepresent 或任何文件读取工具读取 / 查看图表 PNG 文件
  3. 单次响应交付 —— 等待脚本完全完成,然后编写一条包含:图片 → 结论 → 解读的回复。不得拆分为多次响应
  4. 交付前自检 —— 发送前,验证脚本输出中的每个 !... 都出现在回复正文中

Markdown 图片语法 !... 是图表图片的唯一交付机制。

任务路由

根据用户输入自动判断意图并路由到对应模块执行。

路由决策表

用户意图路由模块参考文档
上传了 Excel/CSV 文件,想查询特定指标或回答特定数据问题(例如 TOP N、对比、筛选)文件问答module-chat-file.md
未上传文件,想查询 / 分析平台数据集中的特定指标数据集问答module-chat-dataset.md
上传了多个文件(PDF/Word/图片等)或选择了文件夹,想查询特定数据问题(例如 TOP N、对比、筛选)文档解析 → 文件问答module-document-parser.mdmodule-chat-file.md
上传了 PDF/Word/图片或其他非结构化文档,或选择了文件夹,想解析所有文件内容或提取字段文档解析module-document-parser.md
提供了 QuickBI 仪表板 URL,想生成查询 skill仪表板 Skill 生成module-dashboard.md
上传了 Excel 文件,想对数据进行深度解读 / 洞察 / 趋势分析(不生成报告文档)数据洞察module-data-insight.md
提供了 QuickBI 仪表板 / 数据门户 URL,想对仪表板进行深度解读 / 洞察 / 趋势分析数据洞察(仪表板模式)module-data-insight.md
上传了多个文件(PDF/Word/图片等)或选择了文件夹,想对数据进行深度解读 / 洞察 / 趋势分析(不生成报告文档)文档解析 → 数据洞察module-document-parser.mdmodule-data-insight.md
想生成报告 / 分析报告 / 复盘报告,无论是否上传了文件数据报告module-data-report.md

路由优先级规则

当用户意图可能匹配多个模块时,按以下优先级判断:

  1. "报告"关键词优先:当用户意图包含"报告"、"复盘"、"总结报告"、"分析报告"等关键词时,始终路由到数据报告模块,无论是否上传文件。数据报告模块优先级高于文件问答和数据洞察。
  2. "解读"、"洞察"、"趋势"关键词:当用户想理解数据含义、发现趋势或获得洞察时,路由到数据洞察模块。
  3. 特定数据查询:当用户想查询特定指标(TOP N、求和、对比等)时,路由到问答模块(根据是否有文件选择数据集问答或文件问答)。
  4. 仪表板 URL:当用户提供仪表板 / 数据门户链接时,根据用户意图路由:
  • 生成查询 skill仪表板 Skill 生成
  • 解读 / 分析趋势 / 发现异常 / 获得洞察仪表板 → 数据洞察(仪表板模式)
  • 意图不明确时,默认仪表板 Skill 生成

路由示例

用户输入路由结果理由
"帮我找出这份数据中销量最高的商品" + 上传文件→ 文件问答(module-chat-file)查询特定指标,有文件
"帮我分析这个 Excel 数据,各部门人数 TOP 10" + 上传文件→ 文件问答(module-chat-file)查询特定指标(TOP N),有文件
"销量最高的前 3 个地区"→ 数据集问答(module-chat-dataset)查询特定指标,无文件
"解析这些合同并总结信息" + 文件夹→ 文档解析(module-document-parser)
"把这个仪表板转成查询 skill" + URL→ 仪表板 Skill 生成(module-dashboard)提供了仪表板 URL
"解读这个仪表板的趋势" + 仪表板 URL→ 数据洞察(module-data-insight,仪表板模式)仪表板 URL + 解读 / 洞察意图
"帮我解读销售数据的趋势" + 上传文件→ 数据洞察(module-data-insight)请求解读 / 洞察,不是报告
"这份数据有什么规律和洞察" + 上传文件→ 数据洞察(module-data-insight)请求洞察分析
"生成本月销售数据报告"→ 数据报告(module-data-report)含"报告"关键词
"帮我根据这个 Excel 生成分析报告" + 上传文件→ 数据报告(module-data-report)含"报告"关键词,文件作参考
"总结这些数据,写个复盘报告" + 上传文件→ 数据报告(module-data-report)含"复盘报告"关键词
"结合这些文件生成一份数据分析报告" + 上传文件→ 数据报告(module-data-report)含"报告"关键词
"解析这 10 张发票 PDF,提取字段并生成 Excel" + 多文件→ 文档解析(module-document-parser)含"提取字段"相关关键词
"帮我找出这份数据中销量最高的商品" + 多文件或文件夹→ 文档解析 → 文件问答(module-chat-file)查询特定指标,有多文件
"这些文件有什么规律和洞察" + 多文件或文件夹→ 文档解析 → 数据洞察(module-data-insight)请求洞察分析
"总结这些数据,写个复盘报告" + ≤5 个文件→ 数据报告(module-data-report)含"复盘报告"关键词
"总结这些数据,写个复盘报告" + >5 个文件→ 文档解析 → 数据报告(module-data-report)含"复盘报告"关键词

兜底规则

  • 意图不明确时,默认数据集问答(module-chat-dataset)
  • 如果用户同时涉及多个模块(例如"分析数据并生成报告"),按顺序执行
  • 特殊场景 —— 问答前的多文件预处理
  • 当用户上传 ≥5 个非结构化文档(PDF/Word/图片等)并请求分析时
  • 必须先执行文档解析(生成结构化 Excel)
  • 然后根据问题意图路由到对应功能模块(对生成的 Excel 进行智能分析)
  • 示例:"分析这些发票数据" + 10 个 PDF → 文档解析(生成 Excel)→ 文件问答(分析 Excel)
  • 如果路由错误,允许用户手动指定模块

配置

本 Skill 使用分层配置架构,将用户配置与 Skill 包分离。Skill 包更新不会覆盖用户配置

<workspace-dir> 约定:在本文档中,<workspace-dir> 指用户在 IDE / 文件管理器中当前打开文件夹的绝对路径。Agent 必须在首次操作前通过运行带 os.getenv('CODE_AGENT_CURRENT_SESSION_WORK_DIR') 的 Python 脚本确认此路径。如果脚本无返回或为空,使用用户所选文件夹的绝对路径。不得$PWD$CWDPath.cwd() 等运行时变量推断。
<skill-package-dir> 约定:在本文档中,<skill-package-dir> 指本 Skill 安装后的根目录(即包含本 SKILL.md 文件的目录)。Agent 可从本文件路径推断。

配置加载优先级(高者覆盖低者)

  1. 环境变量 ACCESS_TOKEN(最高优先级,适合容器部署)
  2. 工作区级配置 <workspace-dir>/.qbi/smartq-chat/config.yaml
  3. QBI 全局配置 ~/.qbi/config.yaml(所有 skill 共享)
  4. 默认配置 Skill 包内的 default_config.yaml(包默认值,随包更新)

server_domainapi_keyapi_secretuser_token 可放在工作区级配置或全局配置中。两者都存在时,工作区级配置优先。

配置项说明

  • server_domain:Quick BI 服务域名
  • api_key / api_secret:OpenAPI 鉴权密钥对(若未配置,使用内置默认值以试用模式运行)
  • user_token:Quick BI 平台用户 ID;问答接口需要 userId(若未配置,自动注册并写回)

如果启用 use_env_property: true,可通过 ACCESS_TOKEN 环境变量 JSON 中的 qbi_api_keyqbi_api_secretqbi_server_domainqbi_user_token 字段覆盖配置。

试用凭证自动注册

api_keyapi_secret 都未配置时(无论 user_token 是否存在),脚本将:

  1. user_token 也未配置,打印友好消息告知用户将自动注册试用凭证并开始试用模式
  2. 使用内置默认凭证填充 api_keyapi_secret
  3. 基于设备唯一标识自动注册用户,并将 userId 写入全局配置 ~/.qbi/config.yaml(不受 Skill 包更新影响)
注意:user_token 单独存在于全局配置中(来自自动试用注册)不会阻止试用凭证填充。只有当外部配置中存在 api_keyapi_secret 时才会跳过试用流程。

试用到期由服务端接口通过错误码 AE0579100004 控制——无需本地跟踪。

自定义配置指引

当用户想使用自己的 Quick BI 账号凭证(而非试用凭证)时,登录 Quick BI 控制台,点击头像选项"一键复制 skill 配置",如下图:

根据当前语言向用户展示配置截图:
- zh_CN:!复制 Skill 配置
- en_US:!复制 Skill 配置

复制后,将配置粘贴给 Agent。Agent 将自动把 server_domainapi_keyapi_secretuser_token 写入工作区级配置 <workspace-dir>/.qbi/smartq-chat/config.yaml(并根据 save_global_property 开关决定是否同步到全局配置)。

Agent 配置更新规则(必读)

新用户零配置初始化:如果用户说"初始化配置"、"我是新用户"或类似,但未提供任何具体配置值,则无需手动向任何配置文件写入任何内容。告知用户直接运行问答——系统将自动完成试用注册(见上方试用凭证自动注册章节)。

仅当用户明确提供具体配置值时,才应用以下写入规则。

现有配置保护规则:写入前,Agent 必须先检查工作区级配置文件 <workspace-dir>/.qbi/smartq-chat/config.yaml 是否已存在且含有效配置。若文件已存在且非空,Agent 不得自行修改或覆盖任何配置项,除非用户明确表达更新意图(例如"更新我的配置"、"替换成这个配置"、"把 api_key 改成 xxx"等)。发现现有配置时,告知用户配置已存在并询问是否确认覆盖。

当用户提供 api_keyapi_secretuser_tokenserver_domain 中的任意一个或多个,且满足上述保护规则时,Agent 必须使用文件编辑工具直接修改对应的用户配置文件,将提供的值写入匹配字段。

写入位置规则

  • server_domainapi_keyapi_secretuser_token始终写入工作区级配置 <workspace-dir>/.qbi/smartq-chat/config.yaml
  • 全局配置读写由 save_global_property 开关控制(默认 true):
  • 若开关为 false在任何情况下都不得读写全局配置,跳过下方全局配置相关步骤
  • 若开关为 true全局配置 ~/.qbi/config.yaml 为空或不存在 → 也写入全局配置
  • 若开关为 true 且全局配置已有内容 → 仅写入工作区级配置,然后询问用户"全局配置已存在。是否同步更新?"并根据用户回复决定是否写入

流程

  1. 从用户消息中提取配置键值对(支持 key: valuekey:valuekey=value 等常见格式)
  2. 使用文件编辑工具(如 search_replace)将配置写入工作区级配置文件
  3. 读取配置中的 save_global_property 值;若为 false,跳到步骤 5
  4. 检查全局配置 ~/.qbi/config.yaml 是否存在且非空:
  • 若为空或不存在 → 也写入全局配置
  • 若已有内容 → 询问用户"全局配置已存在。是否同步更新?"并根据用户回复决定是否写入
  1. 更新后,向用户确认写入了哪些配置项以及写到了哪里

禁止行为

  • ❌ 不得以"权限有限"或"无法修改 skill 包内文件"等理由拒绝修改配置
  • ❌ 不得建议使用环境变量或手动复制文件等变通方案
  • ❌ 不得仅输出配置内容并要求用户自行修改

前置条件

  • Python 依赖必须已安装:pip install requests pyyaml matplotlib numpy
  • 需要浏览器自动化能力(仅仪表板 Skill 生成模块需要)
  • 数据集问答:用户必须对目标数据集具有问答权限
  • 文件问答:文件格式限于 xlsxlsxcsv;单文件大小 ≤ 5MB
  • 文档解析
  • 系统依赖:brew install tesseract tesseract-lang(仅本地解析需要)
  • 支持格式:PDF、Word(.doc/.docx)、Excel(.xls/.xlsx)、CSV、图片(.png/.jpg/.jpeg)
  • 单文件大小 ≤ 5MB(远程 OCR 限制)
  • 错误处理
  • 本地解析失败 → 自动回退到远程 OCR
  • 远程 OCR 仍失败 → 归类为"解析失败",保留原文件名和错误信息
  • 未知文档类型 → 提取 5+ 通用字段,生成 Excel 前必须获得用户确认
  • 详细文档:module-document-parser.md

脚本调用约定(必读)

调用任何 Python 脚本时:

  1. 脚本路径必须使用已安装 Skill 包目录的绝对路径(即 <skill-package-dir>/scripts/...);不得使用相对路径
  2. 必须通过 --workspace-dir 参数传 <workspace-dir> 的绝对路径(获取方式见上方配置章节约定)
  3. 路径参数值用引号包裹(防止中文字符、空格或其他特殊字符导致的 shell 分词问题)
  4. smartq_stream_query.pyfile_stream_query.pyq_insights.pycreate_chat.pygenerate_report.py 必须包含 --locale 参数——见下方用户语言判定规则

调用示例

文件上传

python '<skill-package-dir>/scripts/chat/upload_file.py' '/path/to/data.xlsx' --workspace-dir '<workspace-dir>'

文件问答

python '<skill-package-dir>/scripts/chat/file_stream_query.py' <fileId> "各部门人数分布" --locale zh_CN --workspace-dir '<workspace-dir>'

数据集问答

python '<skill-package-dir>/scripts/chat/smartq_stream_query.py' "销售额 TOP 3 的地区" --locale zh_CN --workspace-dir '<workspace-dir>'

数据集问答(带数据集名称提示——启用名称查找,精确匹配跳过智能选表)

python '<skill-package-dir>/scripts/chat/smartq_stream_query.py' "基于'订单销售明细',一季度各平台销售额占比是多少?" --cube-name '订单销售明细' --locale zh_CN --workspace-dir '<workspace-dir>'

文档解析 - 本地

python '<skill-package-dir>/scripts/document/document_local_parse.py' '/path/to/folder/' --json --workspace-dir '<workspace-dir>'

文档解析 - 远程 OCR

python '<skill-package-dir>/scripts/document/document_remote_ocr.py' '/path/to/folder/' --workspace-dir '<workspace-dir>'

Excel 生成

python '<skill-package-dir>/scripts/document/generate_excel.py' '<json-path>' --workspace-dir '<workspace-dir>'

数据洞察

python '<skill-package-dir>/scripts/insight/q_insights.py' "这份报告有什么异常?" --excel-file '/path/to/data.xlsx' --locale zh_CN --workspace-dir '<workspace-dir>'

数据洞察(仪表板模式——仪表板 URL 或数据门户 URL)

python '<skill-package-dir>/scripts/insight/q_insights.py' "这个仪表板的销售趋势如何?" --dashboard-url 'https://bi.aliyun.com/dashboard/view/pc.htm?pageId=xxx' --locale zh_CN --workspace-dir '<workspace-dir>'

python '<skill-package-dir>/scripts/insight/q_insights.py' "Interpret this portal page" --dashboard-url 'https://bi.aliyun.com/product/view.htm?productId=xxx&menuId=yyy' --locale en_US --workspace-dir '<workspace-dir>'

报告生成

python '<skill-package-dir>/scripts/report/generate_report.py' "本月销售分析" --locale zh_CN --workspace-dir '<workspace-dir>'


### 用户语言判定规则

> **核心原则**:`--locale` **必须仅基于用户输入文本**确定,不受任何其他来源影响。

有效值:仅 `zh_CN` 或 `en_US`。

**判定方法**:
- 检查**用户的原始输入消息**(用户输入的提问或指令)
- 识别**提问 / 指令语言**——句子结构、动词和功能词的语言(非嵌入的专有名词)
- 中文提问语言 → `zh_CN`;英文或其他提问语言 → `en_US`

**混合语言处理**(关键):
- 当用户输入同时含中英文时,按**提问框架语言**判定 locale,**不**按嵌入的实体名(数据集名、字段名、表名等)判定
- 问题中嵌入的实体名(数据集名、字段名等)是**专有名词 / 引用**——它们**不**表示用户的语言偏好
- 经验法则:剥离引号内的名称或可识别的实体引用,然后判断剩余句子结构的语言

**什么算"用户输入文本"**:
- ✅ 用户在当前对话轮次输入的文本
- ✅ 同一会话中执行后续查询时用户的原始问题

**什么不得影响 locale 判定**:
- ❌ Agent 自己的回复语言(Agent 可能用与用户输入不同的语言回复)
- ❌ API 响应内容或错误消息(这些无论用户语言如何都是固定语言)
- ❌ 脚本控制台输出文本
- ❌ 数据集名、字段名或其他元数据——无论是平台返回的**还是**作为引用嵌入用户问题的
- ❌ 系统提示语言或 Agent 配置语言

**示例**:
- 用户输入:"请分析销售数据" → `--locale zh_CN`(提问语言是中文)
- 用户输入:"Analyze sales data" → `--locale en_US`(提问语言是英文)
- 用户输入:"Analyze the sales-dataset" → `--locale en_US`(提问语言是英文;数据集名是引用,不是提问语言)
- 用户输入:"Show me data from 2024-annual-report" → `--locale en_US`(提问语言是英文;数据集名是引用)
- 用户输入:"请查询 Sales Dataset 数据" → `--locale zh_CN`(提问语言是中文;"Sales Dataset" 是数据集名)
- 用户输入:"请分析销售数据",但 API 返回英文错误消息 → `--locale zh_CN`(locale 由用户输入决定,不由 API 响应决定)
- 之前 Agent 回复是英文,用户随后用中文输入"查询 TOP3" → `--locale zh_CN`(locale 由用户输入决定,不由 Agent 之前回复决定)

**禁止行为**:
- ❌ 调用脚本时不得省略 `--workspace-dir` 参数
- ❌ 不得使用相对路径调用脚本(例如 `python3 scripts/chat/...`)
- ❌ 不得使用硬编码路径或猜测路径
- ❌ 调用需要该参数的脚本时不得省略 `--locale` 参数
- ❌ 不得基于 Agent 自己的输出语言或 API / 脚本返回内容判定 `--locale`

---