北森 HR 通用数据查询引擎。本 Skill 通过 beisen-cli staffservice 子命令集(sceneTool / searchFormTool / businessDataTool,以及 sceneToolMessageForCLI、menuSearch)实现自然语言到业务数据的 6 步查询流水线。当用户询问假期余额、考勤异常、下属信息、绩效情况、任职信息、组织架构等个人或团队业务数据时触发。本 Skill 是 beisen-employee-profile、beisen-attendance-leave、beisen-organization 三个业务域 Skill 的共享查询底层。
Scanned 9/8/2026
Install to Claude Code
npx -y skills add infometa/workbuddyskills --skill beisen-data-query --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Beisen Data Query?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/infometa-beisen-data-query)More formats (shields.io, HTML) on the badges page.
---
name: beisen-data-query
version: 2.0.11
description: "北森 HR 通用数据查询引擎。本 Skill 通过 beisen-cli staffservice 子命令集(sceneTool / searchFormTool / businessDataTool,以及 sceneToolMessageForCLI、menuSearch)实现自然语言到业务数据的 6 步查询流水线。当用户询问假期余额、考勤异常、下属信息、绩效情况、任职信息、组织架构等个人或团队业务数据时触发。本 Skill 是 beisen-employee-profile、beisen-attendance-leave、beisen-organization 三个业务域 Skill 的共享查询底层。"
category: 人力资源/数据查询
author: beisen
agent_created: false
allowed-tools: Bash, Read
---
# 员工数据查询
**CRITICAL — 开始前 MUST 读取 [../beisen-shared/SKILL.md](../beisen-shared/SKILL.md)**
> **CLI 调用方式**:本 Skill 中工具通过 `beisen-cli staffservice` 的子命令调用:
> - `beisen-cli staffservice employeeData sceneTool`
> - `beisen-cli staffservice employeeData searchFormTool --data '{"intentionId":"<id>"}'`
> - `beisen-cli staffservice employeeData businessDataTool --data '{"intentionId":"<id>","search":[...]}'`
> - `beisen-cli staffservice employeeData sceneToolMessageForCLI --data '{"intentionId":"<id>"}'`
>
> 下文流水线中以逻辑名 `SceneTool` / `SearchFormTool` / `BusinessDataTool` / `SceneToolMessage` 指代上述子命令。
**本 Skill 是 beisen-cli 所有 read-only 数据查询场景的统一入口。** 其他业务域 Skill(`beisen-employee-profile`、`beisen-attendance-leave`、`beisen-organization`)中的场景查询通过引用本 Skill 实现。
## 任务目标
- 本 Skill 用于:根据用户自然语言输入,识别数据查询意图,匹配查询场景,提取筛选参数,获取业务数据并智能总结为可读答案
- 能力包含:意图识别、场景匹配、参数提取、数据检索、智能总结、关联菜单展示
- 触发条件:用户询问个人/团队业务数据(如假期余额、考勤异常、下属信息、绩效情况等)
## 静默执行(硬性规则,适用于全部步骤)
**你输出的每个字用户都看得见,不存在"内部思考/过程说明"通道。**
- 意图判断、场景匹配、参数提取、数据查询、降级切换全部在内部静默完成,禁止写成任何文字。禁止示例(均为真实事故):"用户问XX,这是一个关于XX的查询,让我判断……""场景'XX'(intentionId: …)强命中""SearchFormTool 返回空字段列表,说明……""根据 data-query 的降级规则,需静默退出……""菜单搜索结果与XX无语义关联""按申请时间降序,取最新一条记录"
- 工具轮零文本:直接调用工具,调用前后不输出任何文字("让我先读取相关技能指令并探测可用场景"等一律禁止)
- 面向用户的文字只允许出现在最终答案轮(或必要的追问/确认)
## 操作步骤
### 步骤一:判断意图类型
根据用户输入判断是否为数据查询意图。**数据查询意图必须具备明确的数据询问结构**,即包含以下特征之一及以上:
- 疑问词/疑问句式("多少""有没有""是否""哪些")
- 数量/余额/记录类诉求("还剩""余额""记录")
- 时间范围 + 指标("本月考勤""今年的绩效")
- 明确主体 + 指标组合("李白的任职信息""我团队的工时")
**询问结构以整句为单位判定**:整句必须是向系统求取数据的疑问或请求表达;若整句是名词性短语、标题或描述性文案,即使内部嵌有形似"主体+指标"的片段(如描述文案里的"我有这个视图权限")或数量词字样,也不构成数据询问结构。
分类处理:
- **数据查询意图**(具备上述询问结构,如"我还有多少年假"、"李白本月是否有考勤异常")→ 进入步骤二
- **非数据查询意图**:以下情况均不走本流程,**静默退出**:
- 用户询问企业政策、功能入口位置、操作导航
- **输入为裸名词、功能名式短语或疑似某个功能/页面/菜单的名称或描述性文本**(如"我的目标""日报",或一段菜单描述文案)——即使其中出现"查询""视图""权限""数据"等字样,或嵌有第一人称、形似"主体+指标"的片段,只要整句不具备数据询问结构,就不是数据查询意图
- 多轮对话时,结合最近 10 条对话滚动判断意图,并将代词(他/她/那个人)和省略主语的表达替换为前文已出现的具体人名
- 静默退出时:不输出任何判断过程、解释说明或提示文案,交由 Agent 继续路由(菜单唤起或知识问答)
### 步骤二:匹配查询场景
1. 调用 `SceneTool` 获取租户已配置的查询场景列表:
```bash
beisen-cli staffservice employeeData sceneTool
```
```json
{
"code": "200",
"data": [
{
"intentionId": "场景意图ID",
"scene": "场景指令",
"sceneLabel": "场景名称",
"description": "场景描述"
}
]
}
```
2. 结合用户问题和`SceneTool`返回的 `sceneLabel`、`description` 判断是否命中。**命中标准为强命中,需同时满足两个条件**:
- ①用户问题具有数据询问结构(见步骤一);
- ②该场景提供的数据能**直接回答**用户的问题。
仅词面相似(用户输入中恰好出现与场景名/描述重叠的字样)不构成命中,缺任一条件均视为无场景命中。匹配比对是内部过程,**禁止在回答中输出场景清单、逐个排查分析或"让我看看/让我重新检查"式的推理文字**
3. 若命中多个场景且无法确定唯一匹配 → 输出简短追问让用户确认(如"你是想查考勤记录还是假期余额?"),用户确认后再继续
4. 若仅命中 1 个场景 → 直接使用
5. 若无场景强命中 → 说明当前租户不支持该项数据查询,**按"非数据查询意图"降级处理**:立即静默结束本流程,交由菜单唤起或知识问答处理(同步骤一)。此时不输出任何文案,包括但不限于"暂不支持查询XX""没有找到数据"、场景分析过程、自行编造的查询建议或菜单入口
6. 命中后,用 `intentionId` 调用 `SceneToolMessage` 获取输出要求和关联菜单:
```bash
beisen-cli staffservice employeeData sceneToolMessageForCLI --data '{"intentionId":"<id>"}'
```
```json
{
"code": "200",
"data": {
"outputPromptWords": "输出要求",
"menus": ["菜单ID1", "菜单ID2"]
}
}
```
### 步骤三:获取搜索字段并提取筛选参数
1. **SearchFormTool 必须调用,严禁跳过**(真实事故:跳过本步骤、复用其他场景的 fieldName 导致查询返回错误数据):用命中的 `intentionId` 调用 `SearchFormTool`,获取**本场景**支持筛选的字段:
```bash
beisen-cli staffservice employeeData searchFormTool --data '{"intentionId":"<id>"}'
```
```json
{
"code": "200",
"data": [
{
"fieldName": "字段编码",
"fieldText": "字段显示名",
"fieldDataType": "字段类型",
"num": "字段序号",
"dataSourceItems": [{"id1": "value1"}, {"id2": "value2"}],
}
]
}
```
2. **前置检查(门控)**:检查返回字段中是否存在 `fieldDataType = "部门单选"` 的字段——
- **存在**:本场景支持组织范围查询(场景 A/B/C 可用),可传 `businessParameters.userFindOrgType` 和部门字段 value → 进入第 4 点走 7 级决策表
- **不存在**:本场景仅支持查本人(优先级 1)/权限范围(优先级 2)/指定人(优先级 3)。若用户问法属于以下组织范围查询(A/B/C/所在 类),**一律静默退出**,交由菜单唤起或知识问答处理,不输出任何文案、不降级为查指定人:
| 用户问法类型 | 判定条件 | 示例 | 处理 |
|------------|---------|------|------|
| A 类 | 他人+范围词+无具体部门名 | "麦店长负责的部门的休假情况" | 静默退出 |
| B 类 | 无具体人名+具体部门名 | "一体化产品部的休假情况" | 静默退出 |
| C 类 | 他人+范围词+具体部门名 | "麦店长负责的一体化产品部休假" | 静默退出 |
| 所在类 | 他人+所在+具体部门名 | "麦店长所在的一体化产品部休假" | 静默退出 |
若用户问法仅涉及本人/权限范围/指定人(如"我的休假情况""麦店长的休假"),则正常进入第 3 点提取参数
3. 根据字段信息和用户问题提取筛选参数,详细提取规则见 [references/business-rules.md](references/business-rules.md) 的"参数提取规则"章节。**身份判定只依据用户原文的显性表达,禁止结合登录用户身份信息推断某称谓指向当前用户。** **日期字段严禁默认推断**:仅当用户原文出现明确时间表达(本月/上周/7月/最近N天等)时才传入日期字段;用户未提及时间(如"查询我的团队排班情况")→ 日期字段一律不传,禁止自行默认本周/本月/近30天等任何范围。**日期 value 格式硬约束**:必须严格为 `yyyy/MM/dd-yyyy/MM/dd`(如 `2026/06/01-2026/06/30`),日期分隔符只用 `/`,起止之间只用 `-`,禁止 `~`、`至`、`-` 分隔日期、单位数月日等任何其他形态(详见 business-rules.md"日期格式硬约束")。
4. **查询主体与组织范围判定**(仅当第 2 点确认部门单选字段存在时执行;完整规则见 [references/business-rules.md](references/business-rules.md) 的"员工字段"与"部门单选字段"章节):按以下 7 级穷举决策表确定员工字段 value、`businessParameters.userFindOrgType`、部门字段 value 三个参数取值,**按优先级从高到低逐一匹配,命中即停止**。范围限定词包括:团队、下属、部门(泛指)、管理、负责、所在、他们组、下面、组等(完整列表见 business-rules.md)。**第一人称 + 任何范围词 → 一律优先级 2**,不传 userFindOrgType。"所在"在无部门名时降级为优先级 4(有部门名时降级为 5)。部门名从用户输入中剥离查询词和虚词后、以部门后缀(部/中心/处/科/室/组/团队/部门)结尾的文本提取,多个部门用英文逗号分隔,原样透传不做增删改。
| 优先级 | 判定条件 | 员工 value | userFindOrgType | 部门 value |
|--------|---------|-----------|-----------------|-----------|
| 1 | 第一人称+无范围词+无部门名 | `"当前用户"` | 不传 | 不传 |
| 2 | 第一人称+范围词+无部门名 | 不传 | 不传 | 不传 |
| 3 | 他人+无范围词+无部门名 | 原文透传 | 不传 | 不传 |
| 4 | 他人+范围词+无具体部门名 | 原文透传 | 2 | 不传 |
| 5 | 无具体人名+具体部门名 | 不传 | 不传 | 部门名透传 |
| 6 | 他人+范围词(负责/管理)+具体部门名 | 原文透传 | 2 | 部门名透传 |
| 7 | 他人+范围词(所在)+具体部门名 | 不传 | 不传 | 部门名透传 |
```json
[
{"fieldName": "字段编码", "num": "字段序号", "value": "筛选值"}
]
```
### 步骤四:调用 BusinessDataTool 查询数据
将 `intentionId` 和提取的筛选条件传入 `BusinessDataTool`。`search` 数组中仅传入有值的字段;`businessParameters.userFindOrgType` 仅在优先级 4(A) 和 6(C) 时传 `2`,其余优先级不传 `businessParameters` 对象。字段编码和序号从 SearchFormTool 返回值中透传,禁止修改:
```bash
beisen-cli staffservice employeeData businessDataTool --data '{"intentionId":"<id>","search":[...]}'
```
```json
{
"intentionId": "场景意图ID",
"search": [
{"fieldName": "员工字段编码", "num": "序号", "value": "王欣欣"},
{"fieldName": "部门字段编码", "num": "序号", "value": "一体化产品部"}
],
"businessParameters": {
"userFindOrgType": 2
}
}
```
返回结构:
```json
{
"code": "200",
"message": null,
"data": {
"dataList": [
{"考勤日期": "2026/06/21 星期日", "考勤状态": "正常", "员工": "王雪", "缺勤时长(分钟)": "0 分钟", "备注": "", "异常原因": "", "出勤状态": ""}
]
}
}
```
`dataList` 中每条记录的 key 为视图列的中文字段名,可直接阅读理解。字段名由租户视图配置决定,不同场景、不同租户的字段名不同。生成回答时:只取与用户问题相关的字段组织答案,无关字段忽略;值为空字符串的字段省略不提。
- `code` 非 "200" → 输出固定文案(见 [references/business-rules.md](references/business-rules.md) 固定文案表"查询失败"行),流程结束
- `dataList` 为空或不存在 → 视为无数据
- **`dataList.length === 100` → 视为"返回量触顶"**:单次查询最多返回前 100 条(休假类记录仅近 30 天),实际数据可能多于 100 条。此时**禁止**对全量数据下绝对结论(如"没有异常""全部正常""无请假记录"),必须按 business-rules.md "大数据量与返回边界提示"章节追加边界提示,并将结论限定为"已返回的记录中"。`length < 100` 时不追加任何提示,保持现状体验
### 步骤五:生成回答
**有数据时**:结合用户问题、返回的业务数据和场景的 `outputPromptWords`,组织为自然、可读的答案。遵循以下思路:
- 用户关心什么就重点展示什么,不关心的简洁带过
- **问题意图驱动的展示策略(禁止长表刷屏)**:按用户提问意图组织展示(详见 business-rules.md"问题意图驱动的展示策略"章节):异常判断型(如"本月是否有考勤异常")→ 有异常聚焦列异常明细、正常一笔带过;无异常直接给结论、不铺全部正常记录;整体概览型(如"团队8月考勤情况")→ 按人分组概述、合并同类项、禁止一表到底;具体数值型 → 直接给值不展开整条记录。**大量记录必须用分组文本,禁止长表刷屏**
- **数字零计算(硬约束)**:输出中出现的每一个数字都必须能在 dataList 某条记录的字段值中**逐字找到原文**;凡是需要数出来、加起来、求平均、求差才能得到的数字,一律不输出。不得使用"共/合计/总计/累计/总共/涉及N人/整体/平均"等任何汇总性表述。详见 business-rules.md "计算与汇总规则"章节
- **返回量触顶时(dataList.length === 100)**:禁止下"没有异常/全部正常/无记录"等绝对结论,须按 business-rules.md "大数据量与返回边界提示"章节追加边界提示
- 合理使用排版结构让信息层次清晰
- 输出原则与禁止事项详见 [references/business-rules.md](references/business-rules.md) 的"输出核心思路"章节
- **提交前自检(内部静默执行,不输出)**:① 输出中每个数字是否都能在 dataList 字段值中逐字找到?② 是否混入了"共/合计/总计/累计/涉及N人"等汇总词或自行数出的数字?③ 传入的日期字段是否确有用户原文时间表达支撑(无则不传)?④ 传入的日期 value 是否严格为 `yyyy/MM/dd-yyyy/MM/dd` 形态(无 `~`/`至`、无 `-` 分隔日期、月日两位补零、两个日期均带完整年份)?⑤ dataList.length 是否为 100,若是,是否已追加边界提示且未下绝对结论?⑥ 展示结构是否匹配问题意图——异常判断型是否聚焦异常、正常一笔带过(无异常直接给结论不铺全部记录)?整体概览型是否按人分组、有无长表刷屏?⑦ userFindOrgType=2 是否仅出现在优先级 4(A) 和 6(C)?出现在 1/2/3/5/7 则违规 ⑧ 部门 value 是否仅在用户原文提及具体部门名时才传入?未提及却传了则违规 ⑨ "所在的"场景是否已正确降级(有部门名→B 不传员工/userFindOrgType;无部门名→A 传员工/userFindOrgType)?⑩ 员工 value 是否与决策表一致(本人→`"当前用户"`、泛指→不传、他人→原文透传、A/C→原文透传、B/降级B→不传)?⑪ 若 SearchFormTool 未返回部门单选字段,且用户问法命中 A/B/C/所在 类组织范围查询——是否已按第 2 点静默退出?仍在调用 BusinessDataTool 或传 userFindOrgType=2 或部门 value 或员工 value 则违规 ⑫ 拼入 `--data` 前,用户原文中的 `\`、`"`、`'` 等特殊字符是否已按"用户输入转义"章节完成 JSON 转义和 shell 单引号转义?未转义直接拼接则违规 任一项不满足必须重写答案或重判优先级 ⑬ BusinessDataTool 的 search 数组中每个 fieldName 是否都来自本次 SearchFormTool 对该 intentionId 的返回?若来自记忆中其他场景的 SearchFormTool 返回、或跳过了 SearchFormTool 直接拼入,则违规,必须重新调用 SearchFormTool
**无数据时**:输出固定文案(见固定文案表"无数据匹配"行),不返回关联菜单。
### 步骤六:展示关联菜单
检查步骤二中获取的 `menus`:
- 有关联菜单 → 先用 `menuSearch` 查询每个菜单的 `menuName` 和 `menuLink`,然后在答案末尾追加"你可以在这里查看:",以 Markdown 链接列表输出:
```markdown
- [菜单名称1](菜单链接1)
- [菜单名称2](菜单链接2)
```
**输出规则**:
- 链接文本使用 `menuName`(菜单名称),URL 使用 `menuLink`(完整跳转地址)
- `menuLink` 必须从 `menuSearch` 返回中提取,严禁编造 URL
- 无关联菜单 → 仅展示答案文本
## 使用示例
### 示例 1:查询本人假期余额
- 输入:用户问"我还有多少年假"
- 步骤二:SceneTool 返回"假期余额"场景命中 → SceneToolMessage 获取 menus=["id1"]
- 步骤三:SearchFormTool 返回员工字段、假期类型选项字段(dataSourceItems 含年假/事假等)→ 提取:员工 value="当前用户",假期类型匹配"年假"→ value 填对应 id
- 步骤四:BusinessDataTool 返回年假余额数据
- 步骤五:总结答案,如"你当前年假余额为5天"
- 步骤六:展示关联菜单
### 示例 2:查询下属考勤异常
- 输入:用户问"李白本月是否有考勤异常"
- 步骤二:SceneTool 命中"考勤记录"场景 → SceneToolMessage 获取 menus
- 步骤三:SearchFormTool 返回员工字段和考勤日期字段 → 提取:员工 value="李白"(具体人名),考勤日期 value="2026/07/01-2026/07/31",考勤状态 value="异常"
- 步骤四:BusinessDataTool 返回考勤数据
- 步骤五:总结答案,如"李白本月有2次考勤异常:<br>1. 7月5日 迟到<br>2. 7月12日 早退"
- 步骤六:展示关联菜单
### 示例 3:查询团队信息
- 输入:用户问"我的团队本月工时情况"
- 步骤二:SceneTool 命中"考勤记录"场景 → SceneToolMessage 获取 menus
- 步骤三:SearchFormTool 返回员工字段和考勤日期字段 → 提取:员工 value不传值,考勤日期 value="2026/07/01-2026/07/31"
- 步骤四:BusinessDataTool 返回多人工时数据
- 步骤五:逐人展示工时,不做求和汇总(如"李白本月工时176小时<br>杜甫本月工时168小时"),用户问总工时也以逐人明细回答,不做计算也不拒绝
- 步骤六:展示关联菜单
### 示例 4:未提及日期,日期字段不传(禁止默认时间)
- 输入:用户问"李白的任职信息" / "查询我的团队排班情况"
- 步骤三:SearchFormTool 返回员工字段、日期字段 → 提取:员工按身份规则取值;**用户原文未出现任何时间表达 → 日期字段一律不传**,禁止自行默认本周/本月/近30天等范围
- 步骤四/五/六:正常查询并返回结果
### 示例 4-1:返回量触顶(100 条),不下绝对结论
- 输入:用户问"团队七月到八月有考勤异常情况吗"
- 步骤四:BusinessDataTool 返回 `dataList.length === 100`(已触顶,后续可能仍有数据未返回)
- 步骤五:
- 若已返回的 100 条中存在异常 → 逐条列出异常明细,**不做任何计数/汇总**(不写"共N条异常"),并在末尾追加边界提示
- 若已返回的 100 条全部正常 → **禁止说"没有异常""团队考勤正常"**,应表述为"在已返回的记录中暂未发现考勤异常",并追加边界提示,建议缩小时间范围或前往菜单查看完整数据
- 步骤六:展示关联菜单(边界提示与菜单可并存)
### 示例 5:无场景强命中,降级处理
- 输入:用户问"考勤异常"
- 步骤二:SceneTool 返回的场景列表中无匹配场景(如"考勤休假记录"描述明确排除考勤异常)→ 无场景强命中
- 处理:静默结束本流程,交由菜单唤起或知识问答处理;不输出场景排查过程,不输出"暂不支持查询考勤异常"等自行编造的说明
### 示例 6:输入为功能名/菜单描述式文本,静默退出
- 输入:用户输入某菜单的名称或描述文案(如"用于测试我有这个视图权限的描述的百分之百命中",或裸名词"我的目标""日报")
- 步骤一:整句是名词性描述文案、非求取数据的疑问/请求表达(内部的"我有这个视图权限"片段不参与判定)→ 判为非数据查询意图
- 处理:静默退出,不调用任何工具,不输出任何文字,交由菜单唤起处理
### 示例 7:按昵称查询他人(禁止身份推断)
- 输入:登录用户为"董纪辛",用户问"小辛最新评定的职级是啥"
- 步骤三:"小辛"是人名/昵称而非显性第一人称 → 查询他人,员工 value=`"小辛"`(原文透传)。**禁止因登录用户名为"董纪辛"而推断"小辛"是用户自称、填 `"当前用户"`**——系统中可能确有名为"小辛"的员工,一律以原文为准
- 步骤四/五/六:正常查询并返回结果,答案围绕"小辛"组织
### 示例 8:场景 A — 查询某人团队/负责部门的出勤
- 输入:用户问"王欣欣团队的出勤情况"
- 步骤二:SceneTool 命中考勤场景 → SceneToolMessage 获取 menus
- 步骤三:SearchFormTool 返回员工字段 + 部门单选字段 → 判定:人名"王欣欣" + 范围词"团队" + 无具体部门名 → 优先级 4 → 员工 value="王欣欣",userFindOrgType=2,部门不传
- 步骤四:`search=[{"fieldName":"员工","num":"1","value":"王欣欣"}]`,`businessParameters={"userFindOrgType":2}`
- 步骤五/六:正常总结并展示关联菜单
### 示例 9:场景 B — 查询指定部门的出勤
- 输入:用户问"一体化产品部的出勤情况"
- 步骤三:判定:无具体人名 + 具体部门名"一体化产品部" → 优先级 5 → 员工不传,userFindOrgType 不传,部门 value="一体化产品部"
- 步骤四:`search=[{"fieldName":"部门","num":"2","value":"一体化产品部"}]`,不传 businessParameters
- 步骤五/六:正常总结并展示关联菜单
### 示例 10:场景 C — 查询某人负责的指定部门的出勤
- 输入:用户问"王欣欣负责的一体化产品部出勤情况"
- 步骤三:判定:人名"王欣欣" + "负责" + 部门名"一体化产品部" → 优先级 6 → 员工 value="王欣欣",userFindOrgType=2,部门 value="一体化产品部"
- 步骤四:`search=[{"fieldName":"员工","num":"1","value":"王欣欣"},{"fieldName":"部门","num":"2","value":"一体化产品部"}]`,`businessParameters={"userFindOrgType":2}`
- 步骤五/六:正常总结并展示关联菜单
### 示例 11:"所在的"有部门名 — 降级 B
- 输入:用户问"王欣欣所在的一体化产品部出勤情况"
- 步骤三:判定:人名"王欣欣" + "所在" + 部门名"一体化产品部" → 优先级 7 → 降级 B → 员工不传,userFindOrgType 不传,部门 value="一体化产品部"
- 步骤四:`search=[{"fieldName":"部门","num":"2","value":"一体化产品部"}]`,不传 businessParameters
- 步骤五/六:正常总结并展示关联菜单
### 示例 12:"负责的部门"泛指 — 无具体部门名走 A
- 输入:用户问"他负责的部门出勤情况"(前文提到"王欣欣")
- 步骤三:代词消解"他"→"王欣欣" → 判定:人名"王欣欣" + "负责" + "部门"(泛指,无具体名) → 优先级 4 → 员工 value="王欣欣",userFindOrgType=2,部门不传
- 步骤四:`search=[{"fieldName":"员工","num":"1","value":"王欣欣"}]`,`businessParameters={"userFindOrgType":2}`
- 步骤五/六:正常总结并展示关联菜单
### 示例 13:"所在的"无部门名 — 降级 A
- 输入:用户问"王欣欣所在的部门出勤情况"
- 步骤三:判定:人名"王欣欣" + "所在" + "部门"(泛指,无具体名) → 优先级 7 → 无部门名可提取 → 降级 A → 员工 value="王欣欣",userFindOrgType=2,部门不传
- 步骤四:`search=[{"fieldName":"员工","num":"1","value":"王欣欣"}]`,`businessParameters={"userFindOrgType":2}`
- 步骤五/六:正常总结并展示关联菜单
### 示例 14:无部门单选字段——"XX负责的部门"类查询静默退出
- 输入:用户问"麦店长负责的部门的休假情况"
- 步骤二:SceneTool 命中休假场景 → SceneToolMessage 获取 menus
- 步骤三:SearchFormTool 返回员工字段、日期字段,**无 `fieldDataType = "部门单选"` 字段** → 前置检查判定:用户问法为 A 类(他人"麦店长" + 范围词"负责" + 无具体部门名)→ 场景不支持组织范围查询 → **静默退出**,交由菜单唤起或知识问答处理
- 处理:不调用 BusinessDataTool,不输出任何文案,不降级为查麦店长个人数据
## 资源索引
- 参考:见 [references/business-rules.md](references/business-rules.md)(何时读取:提取参数时查阅提取规则;生成回答时查阅输出格式与固定文案)
## 注意事项
### 用户输入转义(硬性规则,拼 `--data` 前必须执行)
将用户原文(人名、部门名、昵称等)拼入 `--data '{"..."}'` 的 JSON 字符串前,必须依次完成两层转义,否则会导致 JSON 结构损坏或 shell 命令注入(RCE 风险)。
**转义顺序(先 JSON 转义,再 shell 包裹)**:
1. **JSON 转义**(对 value 原文执行,拼入 JSON 字符串前):
- `\` → `\\`
- `"` → `\"`
- 换行符 → `\n`,制表符 → `\t`,回车符 → `\r`
- 控制字符(U+0000–U+001F)→ `\u00XX`
2. **Shell 单引号转义**(在 shell 中用单引号包裹整个 JSON 时):
- `'` → `'\''`(先闭合当前单引号,插入转义单引号 `\'`,再重开单引号继续)
3. **拼入命令**:转义后的 JSON 用单引号包裹,形如 `--data '{"key":"escaped_value"}'`
4. **自检**:拼入前验证 JSON 字符串可被正确解析,所有字符串值的双引号均已闭合
5. **正确示例**:用户输入 `王'欣欣`(含单引号)
- JSON 转义后:`王'欣欣`(单引号不影响 JSON 字符串值)
- Shell 单引号包裹:`--data '{"search":[{"value":"王'\''欣欣"}]}'`
6. **错误示例(全部禁止)**:
- ❌ `--data '{"search":[{"value":"王'欣欣"}]}'`(未转义的单引号使 shell 单引号提前闭合,后续 `欣欣` 被 shell 当作独立 token,导致语法错误或更严重的安全问题)
- ❌ `--data "{\"search\":[{\"value\":\"王\\\"欣欣\"}]}"`(用双引号包裹 JSON 并转义内部双引号——可行但极易出错,禁止使用)
- ❌ 将用户原文直接字符串拼接进 JSON,跳过任何转义步骤
> 提示:大多数中文人名不含特殊字符,但防御必须覆盖所有输入。即使当前用户输入看起来安全,也必须执行上述转义流程,不得依赖"大概率无特殊字符"跳过转义。
### ID 引用规则(与 beisen-shared 一致)
本 Skill 中各步骤间通过 `intentionId`、`menuId`、`fieldName`、`num` 等标识符串联。**必须严格遵守以下规则**:
1. **只复制真实值**:当工具返回结果包含 `intentionId`、`menuId`、`fieldName`、`num` 等标识符,只允许直接复制工具返回 content 中真实存在的值。
2. **严禁编造 ID**:严禁自己编造、猜想、拼接任何 id 或字段编码。如果下一步需要的 `intentionId`、`menuId` 或 `fieldName` 不在刚刚 tool 返回的内容中,禁止调用工具,向用户报错说明缺少 ID。
3. **精确匹配**:调用后续工具时的 `intentionId` 必须完全和 SceneTool/SceneToolMessage/SearchFormTool 返回 JSON 字符串中的字符完全一致,大小写、符号不能修改。
4. **就近取用**:不要靠记忆记录 id,所有参数值必须来源于最近 tool 角色返回的 JSON 内容。SceneTool → SceneToolMessage → SearchFormTool → BusinessDataTool 的 `intentionId` 链路中,每一步的 `intentionId` 必须来自上一步的返回。
5. **空值阻断**:如果 SceneTool 返回空 / 没有 `intentionId`,停止工具调用,告知用户"没有找到你想要的数据,请换个描述试试。"
6. **禁止跨场景复用 fieldName**(真实事故:跳过 SearchFormTool,从记忆中复用另一场景的 fieldName 如 `TenantBase.EstimationResult.UserID` 传入当前场景的 BusinessDataTool,导致字段不匹配、返回错误数据):`search` 数组中的 `fieldName` 和 `num` **必须且只能**来自本次查询中 SearchFormTool 对该 `intentionId` 的返回结果。不同场景的 fieldName 不同(如绩效考核是 `EstimationResult.UserID`,任职信息是 `EmploymentRecord.UserID`),严禁从同一会话中其他场景的 SearchFormTool 返回中复制 fieldName,严禁凭记忆构造 fieldName。每次场景命中后都必须重新调用 SearchFormTool。
### 其他规则
- 数据查询意图优先级高于菜单唤起和知识问答;但该排他性仅在**场景强命中后**生效(强命中 = 输入具有数据询问结构,且场景数据能直接回答问题,见步骤二)——意图不属于数据查询、输入不具备数据询问结构、或属于数据查询但无场景强命中时,均静默降级交由菜单唤起或知识问答处理
- 意图判断、场景匹配、参数提取均为内部过程,任何情况下不得在回答中输出判断依据、排查过程或中间结论;降级退出时不输出任何文字
- 身份判定只依据用户原文的显性表达:显性第一人称→本人、泛指→团队、人名/昵称/称谓→他人;禁止用登录用户姓名推断称谓指向当前用户
- 不得跳过 SceneTool 直接编造场景或 menuId
- 不得跳过 SearchFormTool 直接拼入 BusinessDataTool 的 search 参数;每次场景命中后必须调用 SearchFormTool 获取当前场景的 fieldName 和 num,严禁从记忆中复用其他场景的字段编码
- 不得修改后端返回的任何 ID 值
- 不得在无数据命中时输出菜单按钮代码块
- 回答中不得暴露任何内部机制(工具名、ID、"后端返回""系统查询"等表述),直接给出结论
- 不得建议员工联系 HR、直线经理或 SSC,你本身就是 HRSSC
- 只基于返回的实际数据回答,不得推测、编造或补充数据中未包含的信息
- **数字零计算(硬约束)**:输出中每个数字都必须能在 dataList 某条记录的字段值中逐字找到原文;禁止自行计数、求和、求平均、求差,禁止使用"共/合计/总计/累计/总共/涉及N人"等汇总词;用户问汇总也以逐条明细回答
- **问题意图驱动展示(禁止长表刷屏)**:按用户提问意图组织展示——异常判断型("本月是否有考勤异常")聚焦异常、正常一笔带过、无异常直接给结论不铺全部记录;整体概览型("团队8月考勤情况")按人分组概述、合并同类项、禁止一表到底;具体数值型直接给值不展开整条记录。大量记录必须用分组文本,禁止长表刷屏(详见 business-rules.md"问题意图驱动的展示策略")
- **日期字段不默认**:用户原文无明确时间表达时,日期字段一律不传,禁止自行默认本周/本月/近30天等任何范围
- **日期 value 格式唯一**:传入日期字段的 value 必须严格为 `yyyy/MM/dd-yyyy/MM/dd`(如 `2026/06/01-2026/06/30`);日期分隔符只用 `/`,起止之间只用 `-`,月日必须两位补零、均带完整年份;禁止 `2026-06-01~2026-06-30`、`2026/06/01至2026/06/30`、`2026-06-01-2026-06-30` 等任何其他形态,用户原文用了其他连接符也必须归一化
- **返回量触顶(dataList.length === 100)禁止绝对结论**:单次最多返回前 100 条,触顶时不得说"没有异常/全部正常/无记录",须按 business-rules.md 追加边界提示并将结论限定为"已返回的记录中";`length < 100` 时保持现状不追加提示
- **userFindOrgType 传参红线**:仅在优先级 4(A) 和 6(C) 时传 `businessParameters.userFindOrgType=2`;优先级 1/2/3/5/7 均不传;禁止在无范围词时传 userFindOrgType(如"王欣欣的出勤"是查指定人,不是查负责部门)
- **部门字段传参红线**:仅在用户原文提及了具体部门名(如"一体化产品部")时才传部门 value;"王欣欣部门"中的"部门"是泛指范围词不是部门名,不传部门值;禁止自行推断或编造用户未提及的部门名
- **"所在的"处理红线**:检测到"所在的"时按降级规则处理(有部门名→降级 B,不传员工和 userFindOrgType;无部门名→降级 A,传员工和 userFindOrgType),禁止将"所在"当"负责"处理
- **无部门单选字段时降级红线**:当 SearchFormTool 未返回 `fieldDataType = "部门单选"` 字段时,用户问法若命中 A/B/C/所在 类组织范围查询(如"麦店长负责的部门""一体化产品部""麦店长所在的一体化产品部"),一律静默退出交由菜单处理,禁止降级为查指定人后返回个人数据,禁止传 userFindOrgType=2 或部门 value
- **第一人称不传 userFindOrgType**:第一人称(我/自己/本人)+ 任何范围词 → 优先级 2(权限范围),不传员工值、不传 userFindOrgType
- 多个场景同时命中时,先追问确认再查询,不要自行猜测用户意图
- 菜单链接必须按步骤六中的 Markdown 链接格式严格输出(`- [menuName](menuLink)`),不得用其他格式
- 输出原则与禁止事项详见 [references/business-rules.md](references/business-rules.md) 的"输出核心思路"章节
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!