Skip to content
Back to skills

Indicator Query

ASecurity

通过预置指标API查询HR数据。当用户需要查询涉及计算逻辑的数据(如比率、占比、平均值、人均、趋势对比、流入流出率等)时优先使用本Skill。指标口径经过业务验证,比手写SQL更准确。

  • 417 stars
  • 0 votes
  • 0 copies
  • 4 views
  • Added September 8, 2026
databasessqlapi

Works with

  • api
  • mcp

Security analysis

A100/100

Scanned September 8, 2026

npx -y skills add infometa/workbuddyskills --skill indicator_query --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Indicator Query?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Indicator Query
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/infometa-indicator-query/badge)](https://www.skillsdirectory.com/skills/infometa-indicator-query)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: indicator-query
description: 通过预置指标API查询HR数据。当用户需要查询涉及计算逻辑的数据(如比率、占比、平均值、人均、趋势对比、流入流出率等)时优先使用本Skill。指标口径经过业务验证,比手写SQL更准确。
---

## 数据资源说明(indicator)

本 Skill 基于 `indicator` 资源(一个个预置指标的 API)执行查询:

- **内容覆盖度**:数量较少,主要覆盖占比、比例、均值等**有上级组织对比分析需求**的指标。
- **授权特点**:授权角色有限,主要授予 BP 相关角色。行权限在负责组织范围基础上,**支持上级组织指标查询**——如负责某部门的 BP,可通过本路径查询上级线、BG 的对比数据(这是相对 table/SQL 的关键优势)。
- **查询特点**:支持基于每个指标预定义好的维度进行条件查询或分组统计,相比 SQL 查询更简单、高效。

> 当问题涉及「向上对比 / 本组织范围外的统计」而 table 行权限不足时,应优先选择本路径。

### `slang_query`(业务术语)的使用边界

- **指标整体统计口径无需查询术语**:indicator 每个指标的统计口径(分子/分母定义、计算公式,如"离职率"的分子分母如何界定)已由其 `api_code` 在系统内封装完毕,直接调用即得到准确结果,**不需要**像 `hr-data-sql-builder` 那样再调用 `slang_query` 去确认整体统计口径。
- **仅用于参数取值环节的业务术语映射**:当 Step-3 处理某个参数的值时,若用户问题中使用的是业务简称/俗称(而非维度表规范码值本身),应调用 `slang_query` 查询该术语定义,据此确定其对应的规范维度值,再进行取值匹配——例如用户问"校招离职率","校招"本身不是 `recruitmentType`(招聘类型)维度下的字面码值,需先用 `slang_query` 确认"校招"对应"校园招聘",再以"校园招聘"去匹配维度取值,而不是直接拿"校招"两字去模糊匹配码值表,避免匹配不准。

## 指标权限项编码对照表

各指标在权限中台对应有独立的权限项编码,可用于在**已知用户身份**的情况下核实用户是否拥有对应指标的访问权限:

| 指标名称 | 权限项编码 |
|---|---|
| 在职人数各维度占比 | `Menu_Insight_Indicator_ER_Staff_Count_Rate_By_Dimensions` |
| 离职人次数各维度占比 | `Menu_Insight_Indicator_ER_Dimission_Count_Rate_By_Dimensions` |
| 入职人次数各维度占比 | `Menu_Insight_Indicator_ER_Hire_Count_Rate_By_Dimensions` |
| 调入人次数各维度占比 | `Menu_Insight_Indicator_ER_Transfer_In_Count_Proportion` |
| 调出人次数各维度占比 | `Menu_Insight_Indicator_ER_Transfer_Out_Count_Proportion` |
| 流入人次数各维度占比 | `Menu_Insight_Indicator_ER_InflowCountProportion` |
| 流出人次数各维度占比 | `Menu_Insight_Indicator_ER_OutflowCountProportion` |
| 流出率 | `Menu_Insight_Indicator_ER_OutflowRate` |
| 流入率 | `Menu_Insight_Indicator_ER_InflowRate` |
| 离职率 | `Menu_Insight_Indicator_ER_DimissionRate` |
| 平均年龄 | `Menu_Insight_Indicator_ER_AvgAge` |
| 平均工龄 | `Menu_Insight_Indicator_ER_AvgCareerDuration` |
| 平均司龄 | `Menu_Insight_Indicator_ER_AvgSeniorityDuration` |
| 离职率(带梯队分析) | `Menu_Insight_Indicator_ER_DimissionRate_Talent` |
| 离职人次数各维度占比(带梯队分析) | `Menu_Insight_Indicator_ER_Dimission_Count_Rate_By_Dimensions_Talent` |

> 当前尚无独立的权限项编码查询工具,本表暂作为参考映射维护;待具备基于编码核实用户权限的查询能力后,可将其补充为 Step-1 指标匹配后的前置权限判断依据。现阶段指标的实际授权情况仍以 Step-6 对 `rowPowerResult`/`checkPowerResult` 的实时校验结果为准。

# 指标查询工作流

加载本 Skill 后,严格按以下工作流顺序执行,禁止跳步。

---

## Step-1:读取指标列表 + 匹配(含指标簇识别与候选排序)

**执行动作:**
1. 检查 MCP 服务 `hr_data_service_v1` 是否可用(不可用 → 引导用户连接,终止)
2. 读取 MCP resource `data-view://indicators`(可用指标列表),将用户问题与返回的 `indicator_name` / `indicator_definition` 语义匹配,找到合适的指标及其 `api_code`、`table_name`
3. 通过 `data-view://indicators/{api_code}` 获取该指标的详细参数定义(`parameters[]`)

> ⚠️ **匹配范围要宽松,不要用字面关键词卡死**:语义匹配应基于 `indicator_name`/`indicator_definition` 的含义判断,而非要求用户问题逐字命中指标名。例如"离职率""流失率"等问题应命中名为"离职率"的指标,不要求问题中出现"率"以外的额外字面提示词。若第一次匹配为空,应再检查是否因用词差异(同义词、简称)导致漏判,而非直接判定无匹配。

**分支:**
- **无任何匹配** → 终止本 Skill,切换到 `hr-data-sql-builder`
- **匹配成功,且仅一个候选** → 记录 `api_code`、`table_name`、`parameters[]`,并对照「指标权限项编码对照表」记录该指标的权限项编码(供参考,暂不作为前置判断依据),进入 Step-2
- **匹配成功,且存在「指标簇」(同一核心指标的多个版本)** → 执行下方「指标簇识别与候选排序」,产出**有序候选列表**,取列表首位进入 Step-2;其余候选保留供 Step-6 权限失败时依次重试

### 指标簇识别与候选排序

**识别规则**:若语义匹配命中的多个指标,其核心统计口径相同、仅命名上存在"基础版"与"扩展版"关系(扩展版名称通常在基础版名称后追加括注,如"XX(带梯队分析)"),则判定为同一「指标簇」。典型示例(参见「指标权限项编码对照表」):
- 离职率 / 离职率(带梯队分析)
- 离职人次数各维度占比 / 离职人次数各维度占比(带梯队分析)

**候选排序规则**:
1. 若用户问题**明确提及**扩展版对应的额外维度语义(如提到"梯队""九宫格"等)→ 扩展版排在候选列表首位,基础版排第二。
2. 若用户问题**未提及**扩展版的额外维度语义 → 基础版排候选列表首位(维度更通用、权限覆盖角色通常更广),扩展版排第二作为备选(当基础版权限失败时,扩展版的更大维度集合仍有机会覆盖同一统计需求)。
3. 两个候选均保留在列表中,不因排序丢弃任一候选。

**产出**:`candidates = [{api_code, table_name, parameters[]}, ...]`(按上述规则排序),进入 Step-2 时仅处理 `candidates[0]`,并记录 `triedIndex = 0` 供 Step-6 使用。

---

## Step-2:理解用户意图

**执行动作:** 分析用户问题,提取三类信息:

```
1. 统计范围:在什么范围内计算?
   → 组织(如"人力资源平台部")、时间(如"2025年Q1"、"当月")
   
2. 筛选子集:用户关心的是哪个子集?
   → 如"校招员工""女性""T9以上"
   → 若无特定子集 → 标记为"无筛选"

3. 分组维度:用户是否要按某维度拆分查看?
   → 识别关键词:"各XX""按XX""XX分布""XX维度"
   → 如"各部门""按职级""各离职原因"
   → 若无分组需求 → 标记为"无分组"
```

**产出:** 三元组(范围、筛选、分组)的自然语言描述


## Step-3:逐参数处理

**执行动作:** 读取 MCP resource `data-view://dimensions`。然后遍历 Step-1 中匹配指标的 `parameters`,对每个参数**一次性完成**取值、定角色、放位置三件事。

> 跳过 `staffId`(工具自动注入)。

**对每个参数,执行以下流水线:**

```
─── ① 该参数与用户问题有关吗? ───
    特殊参数优先判断(命中即按对应规则处理,不进入下方"无关/相关"通用判断):

    a) org(组织)参数:必填,固定对应维度表 `a370651772b848cfa5dc7ef602243d69`
        → 跳过本步其余判断及①.5,直接进入②按「取值优先级」取值

    b) 默认口径参数(managerUnit / staffSubType):
        IF 用户问题中未显式提及该参数对应内容(即未主动指定管理主体/员工子类型,如未说"外包""子公司"等):
            → 直接注入固定默认值:managerUnit = ["腾讯集团本部"],staffSubType = ["正式聘用制"]
            → 跳过①.5、②(默认值为固定字符串,无需术语映射/查库),带值直接进入③
            → 进入③后按该参数自身的 common_query / is_required 属性走正常分支判断(可能落入 commonParam,也可能落入角色判断),
              **唯一强制要求**:若最终落入角色判断分支,必须归为角色A"范围",且不得被③末尾"用户没有提到的非必填参数→跳过"兜底规则跳过(该值已由①强制赋值,视同"已有值",不属于兜底规则适用范围)
        ELSE(用户显式提及,要求放开默认口径):
            → 视为用户已提供该参数取值,正常进入①.5→②→③(按用户实际指定值处理,不再套用默认值)

    其余参数,按下方通用规则判断:
    无关且非必填 → SKIP
    无关但必填   → 使用 default_value(无则向用户确认)

─── ①.5 参数值是否为业务简称/俗称?(先于②取值) ───
    IF 用户问题中该参数对应的值是业务简称/俗称(非维度表规范码值本身,如"校招""T9+"):
        → 调用 slang_query 查询该术语定义,确认其对应的规范维度值
        → 用规范值替换简称,再进入②按规范值取值/匹配
    ELSE(用户已用规范表述,或该参数是org/时间等无需术语映射的类型):
        → 跳过,直接进入②

    ⚠️ 此处 slang_query 仅用于**参数取值的术语映射**,不用于确认指标整体统计口径
      (指标口径已由 api_code 封装完毕,无需重复查术语定义,详见文首「slang_query 的使用边界」)

─── ② 取值 ───
    IF parameter_type == "List<String>":
        绝对禁止用中文名!
        在 data-view://dimensions 中找 dimension_code == parameter_code 的记录
        取 sql_script + 添加 WHERE 条件匹配用户关键词(若①.5已转换为规范值,用规范值匹配)
        调用 starrocks_query 执行 → 提取 ID
        值 = ["ID"](数组格式)
    
    ELSE (string/date/int/Float):
        先在 data-view://dimensions 中查找 dimension_code == parameter_code 的记录
        IF 找到且有 sql_script 或 dimension_desc:
            → 参考 sql_script 查询可用值,或参考 dimension_desc 了解取值规则
        ELSE:
            → 从用户输入直接提取
        值 = "字符串" 或 数字

        ⚠️ 若该参数为 org(组织)类型(已在①中确认跳过其余判断,直接进入本步取值):
        indicator API 内部使用 8 位补零组织码(orgId8,如 "00002234")。

        取值优先级(命中即停,不再往下走):
        1. **会话级缓存**:本轮对话中此前已解析过的"组织名→orgId8"映射,直接复用(首次通过②③级拿到值后即记入此缓存,仅本轮对话有效;候选簇重试时同样优先查此缓存,见 Step-6)。
        2. **静态缓存表**:见文末「附录:组织ID静态缓存表」(覆盖顶级节点+9个BG/职能线+40个线级/子公司实体,共50个组织),命中直接用缓存ID,无需查库。
        3. **查库**:①②均未命中时(如具体部门/中心/组等更细粒度组织),才查 `sql_script` → `starrocks_query`;若问题涉及**多个**组织名,须**合并为一次SQL**批量取值(`IN` 精确匹配或多个 `LIKE` 以 `OR` 拼接),禁止逐个查询;查得结果记入会话级缓存供后续复用。

        无论通过以上哪一级拿到的原始ID,若来源非 orgId8 格式(如来自 `get_current_user_data_permission` 返回的 dataScopes.Org 短码"2234"),必须先左侧补 "0" 转换为8位后再赋值("2234" → "00002234")。特殊值 "Org-All"、"global" 按原样处理,不参与补零。

─── ③ 定角色 + 放位置 ───
    IF parameter.common_query == true:
        → commonParam[code] = 值(结束)

    ELSE IF parameter.is_required == true AND (parameter.fenzi_query == true OR parameter.fenmu_query == true):
        → 必填参数优先规则,跳过下方角色判断:
        → numeratorParams[code] = 值
        → denominatorParams[code] = 值(与分子同值)

    ELSE 根据该参数在用户问题中的角色:
    
        角色A "范围"(org、时间、managerUnit、staffSubType 参数 — 界定统计范围):
            → numeratorParams[code] = 值
            → denominatorParams[code] = 值
        
        角色B "筛选"(用户要看占比的那个子集,如招聘类型、性别):
            → numeratorParams[code] = 值
            →(不放 denominatorParams)
        
        角色C "分组"(用户说"各XX"要按此维度拆分):
            前置校验:parameter.group_by_flag == true?
            校验通过 → groupByList.push(code)
            同时根据指标类型决定是否也作为范围条件放入分子分母

    ※ 角色判断规则:
    - common_query==true 的参数 → 无需判断角色,直接放 commonParam
    - is_required==true 且 fenzi_query/fenmu_query 任一为 true → 分子分母都放且同值,不进入角色判断
    - org、时间、managerUnit、staffSubType 参数 → 永远是"范围"(后两者的默认值注入已在①处理,此处不受"用户没提到→跳过"兜底规则影响)
    - 用户没有提到的非必填参数(不含 managerUnit/staffSubType,二者已由①保底注入默认值) → 跳过
    - 占比/率类指标中,用户提到的人群特征(校招/女性/T9等)→ "筛选"
    - 用户说"各XX"对应的维度 → "分组"
```

> 💡 在本流程中使用 `starrocks_query` 查维度表是正常步骤,不是切换到 hr-data-sql-builder。

**产出:**
```json
{
  "commonParam": { ... },
  "numeratorParams": { ... },
  "denominatorParams": { ... },
  "groupByList": [ ... ]
}
```

---

## Step-4:自检

**逐条确认,全部通过才可调用:**

1. 所有 `List<String>` 值为 ID 格式且用 `[]` 包裹? → 否:回 Step-3 ②
2. 所有 `is_required=true` 参数已有值? → 否:补充
3. `is_required=true` 且支持分子/分母查询的参数,是否已**同时**放入 numeratorParams 和 denominatorParams 且**值相同**? → 否:补齐两边
4. 占比/率类指标:用户的筛选子集条件**只在分子**、未误入分母? → 否:从 denominatorParams 移除
5. `groupByList` 中的 code 在 parameters 中 `group_by_flag=true`且是否需要分组查询? → 否:修正
6. 未包含 `staffId`? → 否:删除
7. org 类型参数是否已转换为8位补零格式(`orgId8`),而非来自权限元数据的短码直传? → 否:按补零规则转换后再赋值
8. **默认口径已注入?**指标若支持 `managerUnit`/`staffSubType`,是否已注入默认值 `["腾讯集团本部"]`/`["正式聘用制"]`(或用户已显式放开)? → 否:补注入
9. **分子分母键名对称校验?** numeratorParams 与 denominatorParams 中"范围"类参数的**键名必须逐字一致**(严防把 `managerUnit` 误写成 `managerType`、`flowInBeginDate` 写错等 typo 只污染一侧导致口径不对齐)。逐一比对两侧的 key 集合是否完全相同、同名 key 的值是否一致。 → 否:修正拼写并对齐两侧

---

## Step-5:调用 indicator_query

```
调用工具: indicator_query
参数:
  apiCode = Step-1 的 api_code
  queryParams = JSON.stringify(Step-3 产出的对象)
  userQuestion = 用户当前问题原文
```

---

## Step-6:处理返回结果

> **说明**:本步骤(尤其 `indicatorPowerResult`/`checkPowerResult`/`rowPowerResult` 判断)是 indicator 权限校验的**唯一实时验证点**——因 indicator 授权范围目前缺乏独立的前置查询工具(参考「指标权限项编码对照表」,待具备基于编码核实权限的能力后可补充为前置判断依据),故权限是否可用需通过实际调用结果确认。三者任一为 `false` 即代表探测到当前候选指标的真实权限边界,但**不代表整条 indicator 路径不可行**——若 Step-1 识别出该问题命中「指标簇」(存在未尝试的其余候选),必须先切换候选重试,簇内全部候选权限失败后才进入 Step-7 降级。

```
IF statusCode == 200 AND data.data 非空非null:
    → 表格展示 + 说明口径 + 洞察 → 结束

IF statusCode != 200:
    → 读 message,修正参数,回 Step-5 重试1次
    → 仍失败 → 走「候选簇重试判断」

IF statusCode == 200 BUT data.data 为空/null:
    → 检查 List<String> 参数是否误用了中文名?
      是 → 回 Step-3 ② 查维度表获取 ID,再回 Step-5
    → 检查 indicatorPowerResult / checkPowerResult
      false → 走「候选簇重试判断」
    → 重试1次仍为空 → 走「候选簇重试判断」
```

> 单个候选最多重试 1 次,禁止循环。

### 候选簇重试判断(权限失败/查询失败后,先于 Step-7 执行)

```
IF candidates 中存在 index > triedIndex 的未尝试候选:
    → triedIndex += 1
    → 取 candidates[triedIndex] 的 api_code / table_name / parameters
    → 回 Step-3 重新完成参数映射,但**仅需处理"新候选相对上一候选新增/不同的参数"**
      (同簇候选的 org、时间等"范围"类参数通常完全相同,直接复用上一候选已解析的值/已解析ID,
       不要重新查库;仅新候选独有的参数,如扩展版多出的"梯队"维度,需要新走一次①②③流水线)
    → 回 Step-5 调用
    → 结果按本 Step-6 规则重新判断(该候选同样只重试1次)
ELSE(候选簇已全部尝试,或本就只有单一候选无簇):
    → 记录本次探测到的权限/查询失败原因(用于最终告知用户)
    → 进入 Step-7 降级
```

> ❌ 禁止在候选簇尚有未尝试候选时,就以"无权限"为由提前终止流程并直接告知用户;必须遍历完候选簇才可判定 indicator 路径不可行。
> 💡 同簇候选参数复用与「会话级动态缓存」共享同一份"组织名→orgId8"映射,无需重复维护。

---

## Step-7:降级到 hr-data-sql-builder

**触发条件:** Step-6「候选簇重试判断」确认——候选簇(含单候选场景)已全部尝试且均失败。

**执行动作:**
1. 取最后一次尝试候选的 `table_name`(数据底表)
2. 切换到 `hr-data-sql-builder`,指定目标表为 `table_name`
3. 基于用户原始需求构建 SQL 并执行
4. **合并输出**:无论 SQL 执行结果是成功、为空、还是脱敏,均需与"indicator 侧各候选的失败原因"合并组织成一份连贯回答呈现给用户,不要仅停留在"指标无权限"这一句就结束——SQL 兜底结果是本次回答的必要组成部分,而非可选项。

> ❌ 禁止未走完 Step-6「候选簇重试判断」就直接写 SQL。
> ❌ 禁止在给出 SQL 结果前,先单独把"指标无权限"作为最终答案发给用户;两者必须合并为一次完整回答。

---

## 附录:组织ID静态缓存表(orgId8格式,Step-3②取值时直接查此表,命中无需查库)

覆盖范围:腾讯公司顶级节点、9个一级BG/职能线、40个线级/子公司实体,共50个组织。

| 组织名称 | orgId8 | 层级/所属体系 |
|---|---|---|
| 腾讯公司(顶级节点,全公司) | `OA000001` | 顶级节点 |
| TEG技术工程事业群 | `00000958` | BG |
| CSIG云与智慧产业事业群 | `00029294` | BG |
| IEG互动娱乐事业群 | `00000956` | BG |
| WXG微信事业群 | `00014129` | BG |
| PCG平台与内容事业群 | `00029292` | BG |
| CDG企业发展事业群 | `00000953` | BG |
| S1职能系统-职能线 | `00000078` | 职能线 |
| S2职能系统-财经线 | `00002233` | 职能线 |
| S3职能系统-HR与管理线 | `00002234` | 职能线 |
| 子公司组织 | `00055580` | BG级,直属腾讯公司 |
| 腾娱 | `00057238` | 40线,属子公司组织 |
| 运营子公司 | `00058563` | 40线,属子公司组织 |
| 腾卓 | `00061092` | 40线,属子公司组织 |
| 财付通子公司 | `00064053` | 40线,属子公司组织 |
| 恒智信 | `00079597` | 40线,属子公司组织 |
| 腾佳 | `00049518` | 50部门,属子公司组织 |
| 瑞驰 | `00052650` | 50部门,属子公司组织 |
| 实娱商管 | `00055767` | 50部门,属子公司组织 |
| 北境 | `00056518` | 50部门,属子公司组织 |
| 锦鹏 | `00056519` | 50部门,属子公司组织 |
| 内蒙古网信 | `00056723` | 50部门,属子公司组织 |
| 云链 | `00056724` | 50部门,属子公司组织 |
| 大地通途 | `00056725` | 50部门,属子公司组织 |
| 云雀 | `00056767` | 50部门,属子公司组织 |
| 世纪鲲鹏 | `00057433` | 50部门,属子公司组织 |
| 大丰证券 | `00061440` | 50部门,属子公司组织 |
| 萨罗斯 | `00072802` | 50部门,属子公司组织 |
| 银之心 | `00072805` | 50部门,属子公司组织 |
| 光合 | `00072904` | 50部门,属子公司组织 |
| 核娱 | `00072908` | 50部门,属子公司组织 |
| 随乐 | `00102605` | 50部门,属子公司组织 |
| 阿纳海姆 | `00109601` | 50部门,属子公司组织 |
| 互动娱乐发行线 | `00010307` | 40线,属IEG |
| 天美工作室群 | `00015568` | 40线,属IEG |
| 光子工作室群 | `00015576` | 40线,属IEG |
| 魔方工作室群 | `00015593` | 40线,属IEG |
| 北极光工作室群 | `00015613` | 40线,属IEG |
| 支付基础平台与金融应用线 | `00018424` | 40线,属CDG |
| 腾讯音乐娱乐 | `00021526` | 40线,属公司其他组织 |
| 微信支付线 | `00028599` | 40线,属WXG |
| 广告营销服务线 | `00029295` | 40线,属CDG |
| IEG Global | `00041298` | 40线,属IEG |
| 国内发行线 | `00043448` | 40线,属IEG |
| 在线视频BU | `00045280` | 40线,属PCG |
| 可持续社会价值事业部 | `00045320` | 40线,属CDG |
| 社交平台与应用线 | `00046606` | 40线,属PCG |
| PCG技术与内容平台 | `00047728` | 40线,属PCG |
| 腾讯新闻 | `00047790` | 40线,属PCG |
| IEG公共技术线 | `00114443` | 40线,属IEG |

**匹配规则**:用户提到"腾讯公司/全公司/集团整体" → 用 `OA000001`;提到BG/线/子公司的全称或简称(如"CSIG"、"云与智慧产业事业群"、"腾娱")→ 模糊匹配上表「组织名称」列命中对应ID。

**数据来源与维护**:BG/职能线数据经 `starrocks_query` 实查组织维表 `a370651772b848cfa5dc7ef602243d69` 核实。

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in databases →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.