腾讯企点客服(Tencent-Qidian-CS)Connector 的底层调用说明书。覆盖五大能力域——工单管理(新建/修改/查询工单,变更工单状态)、坐席查询(客服状态实时监控、会话监控、员工信息获取)、人工/机器人会话与消息记录查询(人工/大模型机器人/文本机器人会话和消息记录查询)、客服数据报表(满意度/时长/响应度分析、客服数据总览)。定义全部 MCP 工具的用途、参数、返回值、权限位映射、openId 与 cust_id 解析规则、时间戳规范、计数统计规范、分页完整性规范及调用链路。**只要会话涉及企点客服的工单、坐席、客户、人工/机器人会话记录或客服报表的查询/操作,无论用户是否点名"企点"或具体接口名,都加载本技能**——"看下今天工单情况""谁在线""客服在线情况""拉一下昨天的会话""客服满意度""帮我建个工单"这类需求都属于此范畴。
Scanned 9/8/2026
Install to Claude Code
npx -y skills add infometa/workbuddyskills --skill skills --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of tencent-qidian-cs-skill?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/infometa-tencent-qidian-cs-skill)More formats (shields.io, HTML) on the badges page.
---
name: tencent-qidian-cs-skill
description: 腾讯企点客服(Tencent-Qidian-CS)Connector 的底层调用说明书。覆盖五大能力域——工单管理(新建/修改/查询工单,变更工单状态)、坐席查询(客服状态实时监控、会话监控、员工信息获取)、人工/机器人会话与消息记录查询(人工/大模型机器人/文本机器人会话和消息记录查询)、客服数据报表(满意度/时长/响应度分析、客服数据总览)。定义全部 MCP 工具的用途、参数、返回值、权限位映射、openId 与 cust_id 解析规则、时间戳规范、计数统计规范、分页完整性规范及调用链路。**只要会话涉及企点客服的工单、坐席、客户、人工/机器人会话记录或客服报表的查询/操作,无论用户是否点名"企点"或具体接口名,都加载本技能**——"看下今天工单情况""谁在线""客服在线情况""拉一下昨天的会话""客服满意度""帮我建个工单"这类需求都属于此范畴。
version: "7.3.0"
author: "Tencent-Qidian-CS"
---
# 腾讯企点客服(Tencent-Qidian-CS)Skill(五大能力域调用说明书)
本 Skill 是**腾讯企点客服**(产品代号 **Tencent-Qidian-CS**)Connector 的**底层调用说明书**,描述全部 MCP Tool 的用途、参数、**返回值**、权限位映射和调用链路。覆盖五大能力域:
- **工单管理**(新建/修改/查询工单,变更工单状态)—— `list_templates` / `list_tickets` / `get_ticket` / `list_statuses` / `create_ticket` / `update_ticket` / `assign_ticket`
- **坐席查询**(客服状态实时监控、会话监控、员工信息获取)—— `list_all_staff` / `get_staff_info` / `get_staff_openid` / `get_staff_monitor` / `get_message_alerts`
- **人工/机器人会话与消息记录查询**(人工/大模型机器人/文本机器人会话和消息记录查询)—— `get_monitored_sessions` / `get_staff_messages` / `list_robot_sessions` / `get_robot_messages` / `list_robots`(辅助查客户资料:`search_user` / `get_user` / `list_customers`)
- **客服数据报表**(满意度/时长/响应度分析、客服数据总览)—— `get_quality_report` / `get_service_report` / `get_staff_duration` / `get_staff_funnel`
落地调用接口时,按本说明书选择工具、组织参数、安排调用顺序、解析返回值。
---
## 欢迎语(首次与用户交互时主动使用)
用户首次提出企点相关请求时,先用类似下面的话开场(可口语化,但**敏感数据提示必须保留**——它关系到客户隐私和合规):
> 你好,我是**腾讯企点客服**(Tencent-Qidian-CS)连接器助手,可以帮你处理工单、坐席、客户、会话记录、机器人记录和客服报表相关的查询与操作。
>
> ⚠️ 温馨提示:本连接器会访问**客户资料、聊天原文,以及企业全体员工**的工单与会话数据(数据范围覆盖全员,与你登录的账号无关)。我只在完成你需求所必需的范围内调取数据,也请你注意保护客户与同事的隐私,避免不必要的导出或外传。
>
> 需要我从哪里开始?
---
## 认证
### 基本说明
- 用户须先完成 **OAuth 授权**方可使用;任何业务调用前确认 MCP Server 已连接。
- "当前登录人自己"的 openId 由 **MCP Server 注入**;任何接口参数表中标为 `operator` 的,都是当前登录人 openId,由服务端注入——**不要手工填写,更不要让别人冒充自己**。
### Token 过期的识别与处理
- **过期信号**(任一即认为 Token 失效,立即停止业务调用、转走"重新授权"流程):
- HTTP 401 Unauthorized
- 返回体中出现 `errcode=40001` / `40014` / `access_token expired` / `invalid_token` 等关键词
- MCP Server 透传错误信息提及 "token expired" / "重新授权"
- **处理话术**(直接用,不要再向用户解释 token 是什么):
> 检测到企点登录已过期,请到连接器设置页找到 "腾讯企点客服 / Tencent-qidian-cs",点击重新授权后再继续操作。
- **不要做的事**:
- 不要在 token 失效时反复重试调用(每次都会 401,浪费 Token quota)
- 不要尝试自行刷新 token(MCP Server 已负责,AI 没有刷新工具)
---
## 权限管控(由 MCP Server 错误码驱动)
权限校验在 **MCP Server 侧**完成。**不要尝试预先读取员工权限**——本 Connector 没有提供"查权限"工具,正常发起调用即可,再根据 MCP Server 返回的错误码处理:
- **完全无权限**(未勾选任何 AI 连接器权限位):返回对应错误码时,回复——
> 查询到权限不足,请联系管理员到企点客服账户中心(https://admin.qidian.qq.com/)中【企业管理】-【权限角色】-【AI连接器】模块中添加权限。(仅在线客服专业版、企业版套餐的企业可使用)
- **部分权限**(已开通某些权限位,但用户的需求落在未开通的位上):回复——
> 检测到缺少 **{缺失权限位名称}** 权限,无法执行最终操作。请联系管理员到企点客服账户中心(https://admin.qidian.qq.com/)中【企业管理】-【权限角色】-【AI连接器】模块中添加权限。(仅在线客服专业版、企业版套餐的企业可使用)
`{缺失权限位名称}` 替换为下方映射表中对应的名称。
- **其他错误**:见《常见错误码速查表》。**不要编造结果或绕过**——伪造数据会让用户基于错误信息做决策。
### ⚠️ 数据范围(务必知悉)
当前所有接口覆盖企业**全体员工**数据,与登录账号无关:可以拉到所有员工的工单、所有坐席的会话。因此:
- 默认查询返回**全公司**数据;用户想看"我的 / 某人的",要用 `ownerId` / `staffId` 等参数显式过滤。
- 涉及他人数据时审慎,不要超出用户需求去导出或展示。
---
## 常见错误码速查表
| 错误现象 | 可能原因 | 处理方式 |
|---------|---------|---------|
| HTTP 401 / `errcode=40001` / `invalid_token` | Token 失效或过期 | 走《认证 → Token 过期处理话术》引导用户重新授权,**不重试** |
| HTTP 403 / `permission denied` / `权限不足` | 该权限位未开通 | 走《权限管控》提示话术,按映射表填入缺失权限位名称 |
| HTTP 400 / `param invalid` / `参数错误` | 必填参数缺失 / 格式错 / 大整数被截断 | 检查是否漏传必填项;ID 字段是否字符串透传;时间格式是否 `YYYY-MM-DD`/微秒时间戳 |
| `工单不存在` / `模板不存在` / 末几位为 0 的 ID 报"找不到" | **大整数 ID 精度丢失**(被当 number 处理) | 用字符串保留原值重发;走《其他坑》大整数 ID 规则 |
| HTTP 429 / `rate limit` / `too many requests` | 限流 | 告知用户当前接口被限流,停止该轮批量操作,建议稍后或拆小批次再试 |
| HTTP 5xx / `server error` | 服务端异常 | **最多重试一次**;仍失败则如实告知用户,不要无限重试 |
| 客户姓名查询超时 / `timeout` | 客户库太大按名匹配慢 | 走《cust_id 解析规则》引导用户直接提供 cust_id |
| `next_page_token` 为空或缺失 | 已到末页 | 停止翻页 |
| 时间范围错误(结束 ≤ 开始) | 用户口误或跨天 | **不要自行推断**,向用户确认是否跨天或笔误 |
---
## openId 与 cust_id 解析规则(高频场景,常被用户隐式触发)
接口里大量参数(`ownerId` / `staffId` / `cuin`)需要的是系统 ID,但用户口头通常给的是姓名、社交账号、account 等。按下面规则解析;解析失败时**先澄清,不要猜**。
### 员工 openId 怎么拿
| 用户给的是… | 解析路径 |
|---|---|
| "我自己" / "我处理的" / `operator` | MCP Server 注入,无需 AI 查找 |
| 具名姓名(如 "张三") | 调 `list_all_staff` 拿员工 openId 列表 → 对候选调 `get_staff_info` 取姓名 → 按姓名匹配 |
| account(组织架构里的英文工号,如 `anncui`) | 调 `get_staff_openid`,一步把 account 转 openId |
| 姓名匹配失败或员工太多导致很慢 | 引导用户提供 account:"你能在企点【组织架构】里找到这位同事的 account(一串英文)发我吗?" 然后走 account 路径 |
为什么有 account 这条捷径:`list_all_staff` 只返回 openId 不返回姓名,要拿姓名得逐个调 `get_staff_info`,员工多时会很慢;让用户直接提供 account 是一次调用就搞定。
#### ⚠️ 反向:openId → 姓名的展示规范(强制)
**当查询结果中出现"处理人 / 受理人 / 坐席 / 创建人 / owner / staff / user / operator"等带 openId 的字段时,向用户展示时不能只输出原始 openId**——openId 是冷冰冰的字符串(如 `ouxxxxxxxxxxxxxxxxx`),用户看不出是谁。**必须自动调 `get_staff_info` 解析为姓名**,按 `openid(姓名)` 格式输出。
**强制流程**:
1. **批量收集**:扫描即将展示给用户的数据,收集所有 openId 值(去重),统一传入 `get_staff_info` 的 `openids` 数组一次性查询,避免 N+1 调用。
2. **构建映射表**:从返回值中得到 `{openid → name}` 的映射缓存(同一轮对话内可复用,下次再遇到相同 openId 直接查映射表,不重复调)。
3. **格式化展示**:在所有用户可见的输出中,把 openId 字段渲染为 `ouxxxxxx(张三)` 的形式。
- 表格中:单独一列展示,或合并为"处理人"列内显示 `张三(ouxxxxxx)` 也可。
- 自然语言:『工单 W-001 当前的处理人是 **张三**(openId: ouxxxxxx)』。
4. **解析失败兜底**:`get_staff_info` 返回为空(员工已离职/不存在)时,按 `ouxxxxxx(未找到员工)` 显示,不要让 openId 裸奔。
5. **本人识别**:如果 openId 等于"当前登录人 openId"(由 MCP Server 注入到 operator 的那个),可以显示为 `ouxxxxxx(我自己 / Ann)`,更友好。
**适用接口**:
| 接口 | 含 openId 的返回字段 |
|------|---------------------|
| `list_tickets` | `data[].ownerId`、`data[].createrId` |
| `get_ticket` | `data.ownerId`、`data.createrId`、`data.flowLogs[].operatorId` |
| `get_monitored_sessions` | `data[].staffId` |
| `get_staff_messages` | `data[].fromType` 内的坐席 |
| `get_staff_monitor` | `data.staffList[].openid` |
| 报表族(quality/service/duration/funnel) | `data.list[].userUin` |
| `get_robot_messages` | 转人工时的坐席 openId |
**反例(禁止)**:
- ❌ 『当前处理人 ID:ouAbCdEf123456』
- ❌ 『此工单由 ouxxxxxxx 处理』
**正例**:
- ✅ 『当前处理人:**张三**(ouAbCdEf123456)』
- ✅ 『此工单由 **张三**(ouxxxxxxx)处理』
### 客户 cust_id 怎么拿
| 用户给的是… | 解析路径 |
|---|---|
| **裸 QQ 号**(如 `379937263`)且未明确说是 cust_id | ⛔ **直接告知不支持**——见下方《⚠️ QQ 号查客户的强制规则》 |
| 社交账号(微信/电话/企微等,**QQ 除外**) | 调 `search_user` 反查 cust_id → 调 `get_user` 取详细资料 |
| 客户姓名 | 调 `list_customers` 翻页 + 对候选调 `get_user` 按姓名匹配 |
| cust_id 本身 | 直接 `get_user` |
| 手机号 | 调 `search_user`(type=22)反查 cust_id → 调 `get_user` |
#### ⚠️ QQ 号查客户的强制规则(不可绕过)
**当用户提供的输入是一串纯数字(5-12 位)、且语境是"查这个客户"而**没有**明确说"这是 cust_id"时,默认按 QQ 号处理**:本系统**不支持**用 QQ 号反查客户资料(业务限制,非接口能力问题)。
**强制响应模板**(直接用,不要尝试调 `search_user`):
> 抱歉,目前不支持直接用 QQ 号(如 `{用户给的数字}`)查询客户资料。请提供以下任一信息:
> - **客户 ID(cust_id)**:在企点账户中心的【客户库】列表里能复制到
> - **手机号**:我会用手机号反查
> 你方便提供哪个?
**判别细则**:
- 5-12 位纯数字 + 上下文"查客户/客户信息" → **按 QQ 号拦截**,按上述话术回复,不要调 `search_user`
- 用户**明确**说"cust_id 是 379937263"或类似 → 按 cust_id 直接 `get_user`
- 数字 + "手机号是 13xxxxxxxxx" 等明示 → 走手机号路径(`search_user` type=22)
- 微信/小程序等其他社交账号 → 正常走 `search_user`(按通路类型选 type)
**为什么有这条规则**:实际业务中 QQ 号反查 cust_id 的成功率与匹配语义都不稳定,强行调用会拿到错的客户或空结果,进而误导后续 `get_user` / 工单创建。统一拦截在解析层更安全。
#### 客户库翻页慢的兜底
**客户库通常很大,按姓名匹配容易超时或报错。** 一旦发现查询时间过长、或接口返回错误,**立即停止重试**,引导用户:
> 客户库太大了,按姓名查找比较慢。麻烦你到企点账户中心的【客户库】列表里找到这位客户,复制 cust_id 发给我,我直接查就行。
拿到 cust_id 后走 `get_user` 即可。
---
## 通用约定
### 时间范围处理(⚠️ 强制规范,过往踩坑频次最高)
> **历史教训**:模型对"最近 30 天 / 本周 / 最近一周"等相对时间的换算,曾多次因**凭直觉拼时间戳**导致结果完全错误(例如把 2026 年 5 月查成了 2025 年 1 月)。本节规则强制执行,**违反任何一条都视为重大事故**。
#### 规则 A:当下时间 = 系统当下,**不能凭记忆/训练数据**
- 任何涉及"今天 / 现在 / 最近 X 天 / 本周 / 本月"的计算,**第一步必须**用 Bash 取真实当前时间:
```bash
date "+%Y-%m-%d %H:%M:%S %Z" # 人类可读
date +%s # 秒级时间戳
date +%s%6N # 微秒级时间戳(用于 ref_time 等)
```
- **禁止**根据训练截止日期、对话上下文推断"今天是 X 月 X 日"。模型的内部时间认知通常滞后真实时间数月到数年,**这是已知的事故源头**。
#### 规则 B:换算结果**必须先复述给用户确认**
把相对时间换算为绝对时间后,**先告诉用户具体日期范围**,等用户确认或修正,再带入接口参数。模板:
> 我换算的时间范围是:**{开始日期} ~ {结束日期}**({相对说法},共 {N} 天),对吗?
例如用户说"最近 30 天",且 `date` 返回 `2026-05-27`,必须先回复:
> 我换算的时间范围是:**2026-04-28 ~ 2026-05-27**(最近 30 天,含今天,共 30 天),对吗?
确认后再继续。
#### 规则 C:时间戳单位**必须与接口匹配**
| 接口字段 | 单位 | 示例值(2026-05-27 00:00:00 +0800) |
|---------|-----|------|
| `list_tickets.startTime` / `endTime` | **毫秒**时间戳 | `1779638400000` |
| 报表族 `startTime[]`、会话记录 `startTime[]` | **秒**时间戳 | `1779638400` |
| 机器人会话 `StartTime[]` | **秒**时间戳 | `1779638400` |
| `get_staff_messages.ref_time` / `get_robot_messages.ref_time` | **微秒**时间戳(**string 透传**) | `1779638400000000` |
- 写入参数前**必须用 Bash 重新算一次**对应单位的时间戳,不要直接 ×1000 / ÷1000 拍脑袋。例如:
```bash
date -j -f "%Y-%m-%d %H:%M:%S" "2026-04-28 00:00:00" +%s # macOS BSD date
# 输出 1777593600(秒)→ 毫秒需要 ×1000 = 1777593600000
```
#### 规则 D:相对时间的换算约定(团队内部统一)
| 相对说法 | 换算(基于"今天" T) | 备注 |
|---------|--------------------|------|
| "今天" | T 00:00:00 ~ T 23:59:59 | |
| "昨天" | T-1 00:00:00 ~ T-1 23:59:59 | |
| "最近 N 天" | T-(N-1) 00:00:00 ~ T 23:59:59 | **含今天**共 N 天 |
| "最近一周" / "最近 7 天" | T-6 00:00:00 ~ T 23:59:59 | 含今天共 7 天 |
| "本周" | 本周一 00:00:00 ~ 本周日 23:59:59 | 周一为周首 |
| "上周" | 上周一 00:00:00 ~ 上周日 23:59:59 | |
| "本月" | 当月 1 日 00:00:00 ~ 当月最后一天 23:59:59 | |
| "上月" | 上月 1 日 00:00:00 ~ 上月最后一天 23:59:59 | |
| "最近 30 天" | T-29 00:00:00 ~ T 23:59:59 | 含今天共 30 天 |
#### 规则 E:常规说明
- 报表、会话记录等接口需要起止时间。**用户没给明确的起止时间时,先追问**——即便用户给了相对时间,也要走规则 B 复述确认。
- 时区按企点后台所在地(**Asia/Shanghai / UTC+8**)理解;Bash `date` 命令默认就是本地时区,与企点一致。
- **时间逻辑校验**:若用户提供的结束时间 ≤ 开始时间(如"4 点到 3 点"),向用户确认是否跨天或笔误后再执行。
- **禁止行为汇总**:① 不查 Bash 直接给出"今天是 X 年 X 月 X 日";② 不复述确认就直接把换算后的时间戳塞进工具参数;③ 不验证单位(秒/毫秒/微秒)就传值;④ 接口返回为空时不要立刻断言"无数据"——优先怀疑时间戳算错,重走规则 A→B→C。
### 分页与大批量操作
各接口分页约定不统一(见下表),调用前看清:
| 约定 | 起始 | 用在哪些接口 |
|---|---|---|
| `page` / `size` | 0 起 | 模板、状态、员工等 |
| `pageNo` / `pageSize` | 1 起 | 工单列表 |
| `count` / `index` | 1 起 | 会话记录 |
| `next_custid` 游标 | — | 客户列表 |
| `ref_time` 微秒时间戳 | — | 消息记录 |
**大批量拉取或写入前,先告知规模并取得用户同意**——例如"拉最近 30 天全部会话"可能跨很多页和很大数据量;批量建单可能一次创建几十张。先说"我预计要拉 N 页 / 创建 N 张工单,确认要继续吗?"再行动。
### 分页完整性强制规则(⚠️ 已知踩坑:只看第一页就下结论)
> **历史教训**:用户问"现在哪些客服在线",模型调用 `get_staff_monitor`(默认每页 48 条)只看第一页就汇报"在线坐席共 3 人:钟意 sally、TestReply、smarthuang"。但实际企业有 68 个坐席分两页,第二页里还有 polite 在线(status=1),结果**漏报了一个在线坐席**。这种"分页未拉满就下结论"是和"计数错误"同源的懒人陷阱。
#### 规则 A:判断"是否需要翻完所有页"
| 场景 | 必须翻完所有页 | 可以只看第一页 |
|------|:------------:|:------------:|
| 用户问"全部 / 所有 / 一共多少 / 完整列表" | ✅ | |
| 用户问"现在谁在线 / 在线情况"(**全量筛选类**) | ✅(要从全量里筛出在线) | |
| 用户问"按某条件筛选"(如"在线的客服" / "未解决的工单") | ✅(筛选必须基于全集) | |
| 用户问"看看大概情况 / 抽几个看看 / 前几条" | | ✅ |
| 用户已明确给出"第 N 页 / 前 N 条"的范围 | | ✅(按用户指定范围) |
| 用户问"汇总统计 / 总数"(且接口返回了 total 字段) | | ✅(直接用 total,不用拉全量明细) |
#### 规则 B:拉完所有页的标准流程
1. **第一页拉取**:调接口拿到第一页数据 + 总数(`total` / `count` / `maxLimitTotal`)。
2. **判断是否还有下一页**:
- 若 `已拉条数 < total` → 继续拉下一页(自增 index 或 page)
- 若 `data.next_page_token` / `next_custid` 非空 → 用游标拉下一页
- 若用户明确说"够了 / 别拉太多"→ 停止并告知已拉条数 / 总数比例
3. **告知翻页规模**:若 total 较大(≥ 3 页或 ≥ 200 条),**先停下来告诉用户**:『总共 N 页 / N 条,预计要拉完才能给你完整答案,确认继续吗?』取得同意再翻。
4. **数据合并**:所有页数据合并到一个数组,**用 Bash/Python 程序化合并和筛选**,不要靠 LLM 拼接(会丢数据):
```bash
# 拉到的多页数据存成 page1.json / page2.json / ...
python3 -c "import json,glob; all_data=[]; \
[all_data.extend(json.load(open(f))['data']) for f in sorted(glob.glob('/tmp/page*.json'))]; \
print(json.dumps(all_data, ensure_ascii=False))" > /tmp/all.json
# 再做筛选/统计
python3 -c "import json; d=json.load(open('/tmp/all.json')); \
online=[x for x in d if x['status']==1]; print(len(online), [x['name'] for x in online])"
```
#### 规则 C:声明数据范围
**汇报结果时必须说明本次数据覆盖了多少**——让用户清楚地知道是"全量"还是"部分":
✅ 正例:『**已拉取全部 68 个坐席**(共 2 页),其中在线 4 人:钟意 sally、TestReply、smarthuang、polite。』
✅ 正例:『当前只看了第一页(前 48 个坐席),如果需要看全部 68 个坐席的在线情况,我再拉一页。』
❌ 反例:『**在线坐席共 3 人**:钟意 sally、TestReply、smarthuang。』(隐藏了"只看了第一页"的事实)
#### 规则 D:常见易错点
- **`get_staff_monitor` 默认 count=48**:企业坐席多于 48 时必翻页。看用户问的是"全公司客服在线情况"还是"少数几个的接待情况"决定是否翻完。
- **`list_tickets` 默认 pageSize=15 或 20**:用户问"我所有的待处理工单"等"全集筛选"时必须翻到 `total` 满。
- **`list_all_staff` 一次最多 500**:超 500 必翻页;用户问"全公司多少员工"先看 total。
- **`list_customers` 游标分页**:`next_custid` 非空就还有下一页,直到为空才到末页。
- **`get_monitored_sessions` 30 天会话量**:按预估告知用户大概多少页,确认后再批量翻。
- **`list_robot_sessions`**:同上,机器人会话量大时必先报规模。
#### 规则 E:与"计数规范"的关系
分页完整性 + 计数程序化是配套的:**先翻完所有页拿到全集**(规则 B)→ **再用程序化方式数全集**(计数规范规则 A)。不要先拉一页数完就报数,否则数到的不是真实总量。
### 数据计数与统计规范(⚠️ 强制,过往踩坑频次第二高)
> **历史教训**:模型在汇总返回的 JSON 数组时,曾凭"目测/复述时数"得出错误数量(例如返回 12 个工单模板却汇报"共 11 个",比对详情列表才发现少数了一个)。这种"靠直觉数数"是 LLM 已知短板,必须用程序化方式兜底。
#### 规则 A:用程序化方式数,**不要用眼睛数**
任何"共 N 条 / 总计 N 个 / 一共 N 张"的输出**必须满足以下任一条件**:
1. **优先取接口返回的 `total` / `count` / `maxLimitTotal` 字段**——这是服务端给出的权威计数,比模型自己数准。
2. 若返回结构没有 total 字段、必须从数组算长度时,**用 Bash/Python 计算**:
```bash
echo '<JSON 字符串>' | python3 -c "import sys,json;print(len(json.load(sys.stdin)['data']))"
# 或者保存到临时文件后
python3 -c "import json;d=json.load(open('/tmp/r.json'));print(len(d['data']))"
```
3. 数组很短(≤ 5 条)且需要逐条展示时,先**编号列出每一项**,再以列表的最后一个编号作为总数(如 "12 项 → 编号 1 至 12 → 总数 12")。
#### 规则 B:列表数 ≠ 概括数 时,**立即停止并重算**
输出格式如果同时包含两个数字(例如开头说"共 N 条",下面又详细列了 M 条),**N 必须等于 M**。出现差值时:
1. 立即停止当前回复,**不要硬着头皮往下写**。
2. 用规则 A 的方式重新核对总数。
3. 修正后再发给用户。
#### 规则 C:用户反馈"数错了"时,**先承认再程序化重算**
如果用户指出"你说 N 个但列了 M 个":
1. **直接承认**:"你说得对,确实数错了。"——不要找借口。
2. 走规则 A 重新数(优先 total,其次 Bash 计算),不要再用眼睛数第二次。
3. 给出**经程序化验证**的最终数字。
#### 规则 D:常见易错点
- **JSON 数组中含 `null` 或重复对象**:肉眼扫容易跳过 → 必须用 `len()`。
- **多页返回时**:单次响应的 `data.length` ≠ 总数。要看 `total` / `next_page_token` 是否还有下一页。
- **嵌套数组**:例如 `data[].messages[]`,要明确"数的是哪一层"——是会话数还是消息数。
- **空数组 ≠ 0 条记录**:先确认请求成功(HTTP 200 + code=0)再确认 length=0。如果是 401/403 不要把它说成"0 条数据"。
- **分组聚合时**:例如"统计每个客服多少工单",按 `ownerId` 分组的 dict 长度才是客服数,不是工单总数。
#### 规则 E:表达模板
数完之后输出格式建议:
> 共 **{N}** 条记录(来源:接口 `total` 字段 / 程序化计算)。
或者:
> 共 **{N}** 条记录(已逐条编号 1~{N},与详情列表对齐)。
写明"来源"既能让用户知道你确实算过,也方便事后追溯。
### 会话 / 消息记录拉取的通路默认值规则(⚠️ 强制)
> **历史教训**:用户说"拉一下昨天的会话""看看那个客户的聊天记录"时通常没指定具体通路(QQ / 微信公众号 / 微信小程序 / 企微 / 微信客服 / webim / 电话 / APP 等)。模型若擅自只传一个默认通路(比如只传 type=0 或只传企微),会**漏掉其他通路上的会话**,结果给用户的是不完整的数据,误导分析。
#### 规则 A:用户没指定通路 → 默认拉所有通路
**触发场景**:用户说"拉聊天记录 / 看看会话 / 翻一下消息记录 / 这个客户最近聊了什么 / 这个机器人的对话"等,**没有任何"通过 QQ / 微信 / 企微 / 微信客服 / 公众号"等通路限定词**时:
- ✅ **默认行为**:通路参数(`subType` / `通路 type` / `Cid 类型` 等)**不传 / 传"全部 / 0 / 空"**,让接口返回所有通路的会话与消息。
- ❌ **禁止行为**:不要凭印象认定"应该是 QQ / 应该是企微"就只传一个通路;也不要先猜一个通路调一次拿到空再换一个通路。
#### 规则 B:拉回数据后按通路分组展示
为了让用户看清各通路的分布,**汇总时建议按通路分组统计**:
```
最近 7 天会话共 N 条:
- 微信公众号:X 条
- 企微:Y 条
- 微信小程序:Z 条
- 电话:M 条
- ...
```
让用户一眼看出哪些通路有会话、哪些通路是空的。
#### 规则 C:用户明确指定通路时严格按指定的来
用户**明确说**"只看微信的聊天 / 只看企微会话 / 只查 QQ 会话"等含通路限定的语句时,按指定通路的 type 值严格传入,不要扩大范围。
#### 规则 D:适用接口
| 接口 | 通路参数字段 | 默认行为 |
|------|------------|---------|
| `get_monitored_sessions` | 入参 `subType` / 筛选条件 | 不指定 → 拉全部通路的人工会话 |
| `get_staff_messages` | 由所属 sessionId 决定(继承会话通路) | 上一步 get_monitored_sessions 已拉全通路时,自动继承 |
| `list_robot_sessions` | 入参 `Cid 类型` 等筛选条件 | 不指定 → 拉全部通路的机器人会话 |
| `get_robot_messages` | 由所属 SessionID 决定 | 同上 |
#### 规则 E:与"分页完整性"配合
通路全拉 + 分页全翻是组合规则:先确保所有通路都覆盖(规则 A),再确保每个通路所有页都拉完(《分页完整性强制规则》),最后程序化合并 + 计数(《数据计数与统计规范》)。
> **典型反例**(禁止):用户说"拉一下张三这周的客户会话",AI **只调了** `get_monitored_sessions(staffId=ouXXX, subType=51 企微)`,结果只返回了企微通路的会话,漏掉了客户在微信公众号、QQ、电话等通路上和张三的对话。
> **正例**:同样的请求,AI **不传 subType**(或传"全部"),拿到所有通路的全集后按通路分组展示,让用户看到完整图景。
### 大整数 ID 字段处理(关键)
- **所有大整数 ID 字段一律以 string 传递**——`templateId` / `workorderId` / `customerId` / `statusId` / `robotId` / `ref_time` 等服务端定义为 long 的字段普遍超过 16 位(最长可达 19 位),而 **JavaScript Number 安全位数仅 15-16 位**(`Number.MAX_SAFE_INTEGER` ≈ 9×10¹⁵),按数字处理会精度丢失(末几位变 0 或漂移),导致接口报"工单不存在 / 模板不存在"等诡异错误。
- 即便文档标注为 long/integer,AI 也**必须用字符串保留原值透传**,不要做任何数值转换、计算或重新格式化。
- 从工具返回的 JSON 里拿到的 ID 字段也按字符串看待,复述给用户或传给下一跳工具时**原样透传**。
### 敏感数据
本连接器涉及客户 PII(姓名、电话、社交账号)、聊天原文、全员工单与会话数据。**仅在用户需求所必需的范围内**调取与展示,避免不必要的批量导出或转述。首次交互务必给出《欢迎语》中的敏感数据提示。
### 其他
- `list_customers` 的 `access_token` 由 MCP Server 处理,**不是**需要 AI 填写的参数。
- 报表 4 接口端点已更新到 `employeeSession` 族,**入参以最新文档地址为准**,下方参数表只列必要起止时间。
---
## 权限位 ↔ API 映射
> 共 9 个权限位(7 查询 + 2 编辑),24 个 API。下方均为 AI 连接器权限位。
### 工单管理(工单V2)
**[790] AI查询全部工单**(`ticket-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `list_templates` | 获取工单模板列表 | https://api.qidian.qq.com/wiki/doc/open/eynb5ft8gnsrqv17u05h |
| `list_tickets` | 工单列表查询(条件筛选) | https://api.qidian.qq.com/wiki/doc/open/esa3sklsvw0csvdlo2em |
| `get_ticket` | 工单详情查看 | https://api.qidian.qq.com/wiki/doc/open/ecse8s4sk4n28q0f1mhk |
| `list_statuses` | 获取工单状态列表 | https://api.qidian.qq.com/wiki/doc/open/eqod2tep8hlipt5pk14v |
**[791] AI新建工单**(`ticket-create`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `create_ticket` | 创建工单 | https://api.qidian.qq.com/wiki/doc/open/etczss4dko6p9xfs5g43 |
**[792] AI更新全部工单**(`ticket-update`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `update_ticket` | 工单信息更新(**改处理人 ownerId 用这个**) | https://api.qidian.qq.com/wiki/doc/open/e1ssbs7ou39981cmud5f |
| `assign_ticket` | 工单**状态变更**(名字虽是 assign,实为改状态) | https://api.qidian.qq.com/wiki/doc/open/e5bms5rryls1e37frhk1 |
### 坐席管理
**[793] AI查询全部坐席**(`agent-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `list_all_staff` | 批量拉取员工列表(**仅返回 openId**,要姓名需配合 get_staff_info) | https://api.qidian.qq.com/wiki/doc/open/enq3asm58qd30e5thznk |
| `get_staff_info` | 根据 openId 获取员工信息(含姓名) | https://api.qidian.qq.com/wiki/doc/open/emc2lsrxlpeyogp46h43 |
| `get_staff_openid` | 根据 account(组织架构里的英文工号)批量获取 openId | https://api.qidian.qq.com/wiki/doc/open/e1lvod8ftkgs44hupuu3 |
| `get_staff_monitor` | 客服实时监控数据(坐席级) | https://api.qidian.qq.com/wiki/doc/open/em7p5kar7co0f5htpr45 |
### 客户管理
**[794] AI查询全部客户**(`customer-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `get_user` | 客户资料查询(按 cust_id) | https://api.qidian.qq.com/wiki/doc/open/ebmlne6s3lpzplguht26 |
| `search_user` | 根据社交账号反查 cust_id | https://api.qidian.qq.com/wiki/doc/open/eal6s336lsl1czg5h569 |
| `list_customers` | 拉取客户列表(游标分页;客户多时慎用) | https://api.qidian.qq.com/wiki/doc/open/evblxstplyo4dpgm4ri6 |
### 会话记录
**[795] AI查询全部人工会话记录**(`session-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `get_monitored_sessions` | 人工接待会话记录拉取 | https://api.qidian.qq.com/wiki/doc/open/etlka4esonlgrv374h05 |
| `get_staff_messages` | 人工接待消息记录拉取(逐条聊天) | https://api.qidian.qq.com/wiki/doc/open/ed5e6foshrq8ol7k2ws4 |
**[796] AI查询全部客服会话监控**(`monitor-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `get_message_alerts` | 会话监控实时**大盘**(排队数、在线会话数、满意度等全局指标) | https://api.qidian.qq.com/wiki/doc/open/eamp842brgr7ni45n5s8 |
### 大模型机器人
**[797] AI查询机器人全部会话记录**(`AI-robot-session-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `list_robot_sessions` | 大模型机器人会话记录拉取 | https://api.qidian.qq.com/wiki/doc/open/flrka0xclflks9g9kiu8 |
| `get_robot_messages` | 大模型机器人消息记录拉取(问答对) | https://api.qidian.qq.com/wiki/doc/open/esarx13br5fnv2o0h103 |
| `list_robots` | 大模型机器人列表查询(先调它拿 robotId,再 list_robot_sessions 拉会话) | https://api.qidian.qq.com/wiki/doc/open/flk9laym9sbro1qdqfxi |
### 数据报表(已整体迁到 `employeeSession` 族)
**[798] AI查询全部客服报表**(`report-read`)
| action | 说明 | 文档地址 |
|--------|------|---------|
| `get_quality_report` | 会话客服分析-满意度分析 | https://api.qidian.qq.com/wiki/doc/open/e7btspmcwpxr9rd6ez5t |
| `get_service_report` | 会话客服分析-总览(客服维度) | https://api.qidian.qq.com/wiki/doc/open/evtnbs5pnd007fylwg60 |
| `get_staff_duration` | 会话客服分析-时长分析 | https://api.qidian.qq.com/wiki/doc/open/ezdlretsppwfplqix9m9 |
| `get_staff_funnel` | 会话客服分析-**响应度分析**(名字保留,含义已不是漏斗/转化) | https://api.qidian.qq.com/wiki/doc/open/eutbsc7lp6lf04k2h2ym |
### 权限位速查表
> 后台权限位中文名已统一为「AI + 动词 + 全部 + 对象」格式(如「AI查询全部工单」),强调授权范围是**全公司全员数据**。下表中文名与后台「账户中心 → AI 连接器」权限勾选页一致。
| ID | 权限位中文名(后台一致) | scope(英文 key) | 类型 | API 数量 |
|----|------|-------|------|---------|
| 790 | AI查询全部工单 | `ticket-read` | 查询 | 4 |
| 791 | AI新建工单 | `ticket-create` | 编辑 | 1 |
| 792 | AI更新全部工单 | `ticket-update` | 编辑 | 2 |
| 793 | AI查询全部坐席 | `agent-read` | 查询 | 4 |
| 794 | AI查询全部客户 | `customer-read` | 查询 | 3 |
| 795 | AI查询全部人工会话记录 | `session-read` | 查询 | 2 |
| 796 | AI查询全部客服会话监控 | `monitor-read` | 查询 | 1 |
| 797 | AI查询机器人全部会话记录 | `AI-robot-session-read` | 查询 | 3 |
| 798 | AI查询全部客服报表 | `report-read` | 查询 | 4 |
| — | **合计** | — | — | **24** |
---
## 工具详解
> **通用约定**
> - 参数表中的 `operator`(操作者 openId)已由 MCP Server 注入,下方表格不再重复列出。
> - 返回值仅列**业务关键字段**(用于解析展示或作为下一跳工具入参的字段);完整字段以官方文档为准。
> - 凡是大整数 ID 字段(templateId / workorderId / customerId / statusId / robotId / cust_id / sessionId / ref_time 等),无论参数还是返回值,**一律按字符串透传**。
### 工单管理
> ### ⚠️ 工单写操作二次确认规则(强制,不可跳过)
>
> 工单的**增 / 改 / 状态变更**(`create_ticket` / `update_ticket` / `assign_ticket`)属于敏感写操作,**每次执行前都必须重新与用户逐项确认**,即便用户在本轮对话或上轮对话里已经提供过 `templateId`、`title`、`ownerId`、`statusId` 等参数。
>
> **必须遵守的流程**:
>
> 1. **完整展示即将提交的参数**——按"字段名:值(含可读名称)"逐项列出,例如:
> - 模板:`templateId="614404267440304175"`(VIP 客户工单专用模板)
> - 标题:xxx
> - 处理人:`ownerId="ouxxxxxx"`(张三)
> - 优先级:30(中)
> 2. **逐项询问是否使用 / 是否要替换**——尤其是 `templateId`、`ownerId`、`statusId` 这类引用其他对象的 ID 字段,明确问:"要用这个模板 / 处理人 / 状态吗?还是换一个?"
> 3. **等待用户明确肯定回复**("确认"、"是"、"OK"、"对"、"就这样"等)后再执行;用户犹豫、提出疑问或表达否定时,**立即停止**,按用户的最新意见调整后再次走确认流程。
> 4. **不得用"看起来都有了就直接提交"的判断越过确认**——即使所有必填项都已具备,也必须确认。
> 5. **批量场景**(如循环建单)必须先报"预计创建 N 张,第一张参数如下…"取得整体同意,再按批次执行;批次内任一条参数变化都要重新确认。
>
> **典型反例**(禁止):用户半小时前提过"用 VIP 模板,处理人是张三",现在又说"再帮我建一张同类的工单,标题叫 xxx"——AI **不能**直接用旧的 templateId/ownerId 调 `create_ticket`,必须先把完整参数列出来问一遍"用这些参数对吗?"
#### list_templates — 获取工单模板列表
查可用工单模板。创建工单前先调用让用户选模板。**权限位**:[790] AI查询全部工单(`ticket-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| page | integer | 否 | 页码,0 起,默认 0 |
| size | integer | 否 | 每页条数,默认 15 |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].id` | string | **模板 ID(大整数,作 templateId 传给 create_ticket)** |
| `data[].name` | string | 模板名称(如 "VIP 客户工单") |
| `data[].fields[]` | array | 该模板的必填/可选字段定义,用于检查 create_ticket 必填项 |
#### list_tickets — 工单列表查询
按条件筛选工单。**权限位**:[790] AI查询全部工单(`ticket-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| pageNo | integer | 否 | 页码,1 起,默认 1 |
| pageSize | integer | 否 | 每页条数,默认 20 |
| statusId | string | 否 | 工单状态 ID(大整数,字符串传递) |
| priorityId | integer | 否 | 优先级(40=低 30=中 20=高 10=紧急) |
| ownerId | string | 否 | 处理人 openId(看"某人/我的"工单时用它过滤) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].workorderId` | string | **工单 ID(大整数,作为 get_ticket / update_ticket / assign_ticket 的入参)** |
| `data[].title` | string | 工单标题 |
| `data[].statusId` | string | 当前状态 ID |
| `data[].priorityId` | integer | 优先级 |
| `data[].ownerId` | string | 处理人 openId |
| `data[].createTime` | string | 创建时间 |
| `total` | integer | 总条数 |
#### get_ticket — 工单详情
**权限位**:[790] AI查询全部工单(`ticket-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| workorderId | string | 是 | 工单 ID(大整数,字符串传递) |
**返回值(关键字段)**:完整工单对象,含 `workorderId` / `templateId` / `statusId` / `title` / `description` / `ownerId` / `customerId` / `priorityId` / `fields[]`(自定义字段值)/ `flowLogs[]`(流转记录)/ `attachments[]`。所有大整数 ID 字段均字符串透传。
#### list_statuses — 获取工单状态列表
变更状态前先用它取目标 statusId。**权限位**:[790] AI查询全部工单(`ticket-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| type | string | 否 | START / NORMAL / END,不填返回全部 |
| pageNumber | integer | 否 | 页码,0 起 |
| pageSize | integer | 否 | 每页条数,最大 30 |
| statusIds | string[] | 否 | 状态 ID 数组(每个 ID 都是大整数字符串) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].statusId` | string | **状态 ID(大整数,作 assign_ticket 入参)** |
| `data[].name` | string | 状态名称(如 "处理中" / "已解决") |
| `data[].type` | string | START / NORMAL / END |
#### create_ticket — 创建工单
**写操作,执行前必须按《工单写操作二次确认规则》逐项确认。** 先 `list_templates` 取模板及必填字段;指定他人为处理人时按《openId 解析》先拿 ownerId。**权限位**:[791] AI新建工单(`ticket-create`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| title | string | 是 | 标题,0-128 字符 |
| templateId | string | 是 | 模板 ID(服务端为 64 位 long,**必须以字符串传递**) |
| description | string | 否 | 描述 |
| phone | string | 视模板 | 联系电话 |
| email | string | 视模板 | 邮箱 |
| priorityId | integer | 否 | 优先级 |
| ownerId | string | 否 | 处理人 openId |
| customerId | string | 否 | 客户 C 侧用户 ID(大整数同样字符串传递) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.workorderId` | string | **新创建工单的 ID(创建成功后通常需要复述给用户/继续后续操作)** |
#### update_ticket — 工单信息更新
更新标题、描述、优先级、**处理人**等。**改处理人就用这个接口的 ownerId。写操作,执行前必须按《工单写操作二次确认规则》逐项确认。** **权限位**:[792] AI更新全部工单(`ticket-update`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| workorderId | string | 是 | 工单 ID(大整数,字符串传递) |
| title | string | 否 | 新标题 |
| description | string | 否 | 新描述 |
| priorityId | integer | 否 | 新优先级 |
| ownerId | string | 否 | 新处理人 openId |
**返回值**:操作结果(成功 / 失败 + message)。
#### assign_ticket — 工单状态变更
变更工单流转状态。**注意:名字叫 assign,实为改状态;改处理人请用 update_ticket。写操作,执行前必须按《工单写操作二次确认规则》逐项确认。** **权限位**:[792] AI更新全部工单(`ticket-update`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| workorderId | string | 是 | 工单 ID(大整数,字符串传递) |
| statusId | string | 是 | 目标状态 ID(大整数,字符串传递;先用 list_statuses 取) |
**返回值**:操作结果(成功 / 失败 + message)。
### 坐席管理
#### list_all_staff — 批量拉取员工列表
拉组织架构下员工 openId 列表。**仅返回 openId**,要拿姓名得逐个调 `get_staff_info`,员工多时慢——优先引导用户提供 account(见《openId 解析》)。**权限位**:[793] AI查询全部坐席(`agent-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| page_size | integer | 否 | 每页条数(一次最多 500) |
| page | integer | 否 | 页码 |
| id | string | 否 | 部门节点 ID |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].openid` | string | 员工 openId(**不含姓名**,要姓名调 get_staff_info) |
| `total` | integer | 总条数 |
#### get_staff_info — 根据 openId 获取员工信息
拿到员工 openId 后,调用它获取姓名等信息。**权限位**:[793] AI查询全部坐席(`agent-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| openids | string[] | 是 | 员工 openId 列表(一次可批量查多个) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].openid` | string | 员工 openId |
| `data[].name` | string | 员工姓名 |
| `data[].account` | string | 英文工号(如 anncui) |
| `data[].deptName` | string | 部门 |
#### get_staff_openid — 根据 account 批量获取 openId
account 是企点【组织架构】里能看到的一串英文工号。**这是姓名匹配慢/失败时的捷径**:让用户直接提供 account,一次调用搞定。**权限位**:[793] AI查询全部坐席(`agent-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| accounts | string[] | 是 | account(英文工号)列表 |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].account` | string | 英文工号 |
| `data[].openid` | string | 对应 openId |
#### get_staff_monitor — 客服实时监控数据(坐席级)
坐席级实时接待数据:在线/离线/忙碌人数、各坐席当前接待数与时长。**权限位**:[793] AI查询全部坐席(`agent-read`)
> **🎯 用户问"客服在线状态"/"谁在线"/"现在客服在干嘛"时的默认入口**
>
> 当用户提到下列任意意图,**不要追问"你想看什么",直接调本接口**,再视情况补 `get_message_alerts`:
> - 客服在线状态 / 客服在线情况 / 现在客服在线吗 / 坐席在线
> - 谁在线 / 有几个客服在线 / 在线人数 / 在岗情况
> - 现在客服情况怎么样 / 客服接待情况 / 现在忙不忙
> - 排队多少 / 现在多少会话(这种需要再加 `get_message_alerts`)
>
> 本接口返回 `staffOnlineCount`(在线坐席数)、`staffBusyCount`(忙碌坐席数)、`staffList[]`(每个坐席的接待详情),已经能回答 80% 的"在线状态"类问题。**不要因为接口名带 monitor 就误以为是高级监控功能而跳过。**
> **⚠️ 分页完整性强制规则(已知踩坑)**
>
> 本接口**默认 count=48 单页拉取**,企业坐席数大于 48 时必然分多页。**用户问"全部坐席 / 哪些客服在线 / 在线情况"等"全集筛选类"问题时**,**必须翻完所有页**才能下结论:
>
> 1. 第一页(index=1)拉完后,**先看返回的 `total` 字段**——若企业有 N 个坐席而 N > 48,则需要翻 ⌈N / count⌉ 页。
> 2. 续翻页:`index=2, count=48` 拉第二页;如有更多页继续递增 index。
> 3. 所有页数据**用 Bash/Python 程序化合并**(不要靠 LLM 拼接),再做"在线状态 = 1"等筛选。
> 4. 汇报结果时**必须声明数据范围**:『已拉取全部 N 个坐席(共 M 页),其中在线 X 人:…』;不能只说"在线 X 人:…"隐藏只看第一页的事实。
>
> **真实事故案例**:用户问"现在哪些客服在线",企业有 68 个坐席分 2 页(每页 48 条),模型只查第一页就汇报『在线坐席共 3 人:钟意 sally、TestReply、smarthuang』。但实际第二页有 polite(status=1)也在线,**漏报了一个**。正确做法:先看 total=68 → 知道分 2 页 → 翻完第二页 → 程序化筛选 status=1 → 完整汇报『在线 4 人:钟意 sally、TestReply、smarthuang、polite』。
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| index | integer | 是 | 页数(从 1 开始)。**用户问全集时必须翻完所有页** |
| count | integer | 是 | 每页拉取数据量,最大 48 |
| status | integer | 否 | 接待状态 0:全部状态 1:接待开启 2:接待关闭 3:PC未登录(未填写时拉全部状态数据) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.total` | integer | **总坐席数(用于判断是否还有下一页)** |
| `data.staffOnlineCount` | integer | 在线坐席数(**注意:这是当前页统计**,全公司在线数需要翻完所有页后程序化算) |
| `data.staffBusyCount` | integer | 忙碌坐席数(同上,当前页统计) |
| `data.staffList[]` | array | 当前页坐席接待明细(openid/姓名/当前接待数/接待时长/status 等) |
| `data.staffList[].openid` | string | 坐席 openId(展示给用户时按 `姓名(openid)` 格式,见《openId 显示规范》) |
> 两个"实时/监控"工具消歧:坐席级实时(含在线/忙碌坐席数)用 `get_staff_monitor`(793);全局大盘(排队/在线会话)用 `get_message_alerts`(796);历史统计用报表族(798)。
### 客户管理
#### get_user — 客户资料查询
按 cust_id 查客户详细资料(姓名、电话、备注、标签等)。**权限位**:[794] AI查询全部客户(`customer-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| cuin | string | 是 | 客户 cust_id |
**返回值(关键字段)**:完整客户对象,含 `cust_id` / `name` / `phone` / `email` / `tags[]` / `remark` 等。`cust_id` 始终字符串透传。
#### search_user — 根据社交账号反查 cust_id
**权限位**:[794] AI查询全部客户(`customer-read`)
> ⛔ **type=0(QQ 号)已禁用**:业务侧不支持 QQ 号反查客户资料。当用户提供裸 QQ 号时,**不要调本接口**,按《cust_id 解析规则 → QQ 号查客户的强制规则》直接拦截并引导用户提供 cust_id 或手机号。
>
> 可用 type:1=微信公众号、3=webim、9=微信小程序、22=电话、51=企微、53=微信客服、50=APP。
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| socialAccount | string | 是 | 社交账号 |
| type | integer | 是 | 账号类型(**禁用 0=QQ**;1=微信公众号, 3=webim, 9=微信小程序, 22=电话, 50=app, 51=企微, 53=微信客服) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.cust_id` | string | **查到的 cust_id(作下一跳 get_user 的入参)** |
#### list_customers — 拉取客户列表
游标分页。**客户库通常很大,按姓名匹配易超时——查询慢或报错时,按《cust_id 解析》引导用户去客户库复制 cust_id。** **权限位**:[794] AI查询全部客户(`customer-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| next_custid | string | 否 | 翻页游标;首次不传,后续传上一页返回的游标 |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.list[].cust_id` | string | 客户 cust_id(字符串透传) |
| `data.list[].name` | string | 客户姓名 |
| `data.next_custid` | string | 下一页游标,**为空表示末页** |
> `access_token` 由 MCP Server 处理,不需 AI 填写。
### 会话记录
#### get_monitored_sessions — 人工接待会话记录拉取
按时间段拉人工接待会话列表(客户名称、备注、标签、时长等)。**起止时间未给先追问;大批量前确认。** **权限位**:[795] AI查询全部人工会话记录(`session-read`)
> **⚠️ 通路默认全量规则**:用户说"拉会话 / 看聊天记录 / 这个客户聊了什么"等**未明确说通路**(QQ / 微信公众号 / 微信小程序 / 企微 / 微信客服 / webim / 电话 / APP)时,**不要传 `subType`**,让接口返回所有通路的会话。**禁止**凭印象只传一个通路(如默认企微)。返回后按通路分组展示,让用户看清各通路的分布。用户**明确**指定通路("只看微信会话""只看 QQ"等)时再按指定 subType 传。
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| startDate | string | 是 | 开始日期 YYYY-MM-DD |
| endDate | string | 是 | 结束日期 YYYY-MM-DD |
| count | integer | 否 | 每页条数,最大 50 |
| index | integer | 否 | 页码,1 起 |
| staffId | string | 否 | 坐席 openId |
| socialAccount | string | 否 | 客户社交账号 |
| subType | integer | 否 | 通路类型(**用户未指定时不传,默认拉全部通路**:0=QQ / 1=微信公众号 / 3=webim / 9=微信小程序 / 22=电话 / 50=APP / 51=企微 / 53=微信客服)|
| convType | integer | 否 | 会话类型 |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].sessionId` | string | **会话 ID(大整数字符串,作 get_staff_messages 入参)** |
| `data[].staffId` | string | 坐席 openId |
| `data[].cust_id` | string | 客户 cust_id |
| `data[].startTime` / `data[].endTime` | string | 会话起止时间 |
| `data[].convRemarks` | string | 会话备注(用于业务意图识别) |
| `data[].customerTag` | string | 客户标签 |
| `total` | integer | 总条数 |
#### get_staff_messages — 人工接待消息记录拉取
按 session_id 拉某次人工会话的逐条聊天记录。**权限位**:[795] AI查询全部人工会话记录(`session-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| session_id | string | 是 | 会话 ID(来自 get_monitored_sessions) |
| ref_time | string | 否 | 翻页参考时间(微秒时间戳,**大整数字符串透传**,原值取自上一页响应不要自行计算或转 number) |
| paging_type | integer | 否 | 翻页方向(0=向后, 1=向前) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].msgTime` | string | 消息时间(微秒时间戳,大整数字符串) |
| `data[].fromType` | string/integer | 发送方(坐席 / 客户) |
| `data[].content` | string | 消息内容 |
| `data.has_more` | boolean | 是否还有下一页 |
| `data.next_ref_time` | string | 下一页 ref_time(字符串透传) |
### 监控
#### get_message_alerts — 会话监控实时大盘
全局实时指标:排队数、在线会话数、满意度等。**权限位**:[796] AI查询全部客服会话监控(`monitor-read`)
**入参**:无必填参数。
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data.queueCount` | integer | 当前排队会话数 |
| `data.onlineSessionCount` | integer | 当前在线会话数 |
| `data.todaySatisfaction` | number | 今日满意度(百分比) |
| `data.todayResponseTime` | number | 今日平均响应时长(秒) |
### 大模型机器人
#### list_robots — 大模型机器人列表查询
拉企业已开通的大模型机器人列表(机器人名称、robotId 等),用于先拿到 robotId 后再调 `list_robot_sessions` 拉会话。**当用户给的是机器人名称(如"机器人演示-Ann")而不是 robotId 时,必须先调本接口解析。** **权限位**:[797] AI查询机器人全部会话记录(`AI-robot-session-read`)
**入参**:参数以最新文档为准。
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].robotId` | string | **机器人 ID(大整数字符串,作 list_robot_sessions 入参)** |
| `data[].name` | string | 机器人名称(用于按名匹配) |
#### list_robot_sessions — 大模型机器人会话记录拉取
**起止时间未给先追问。** **权限位**:[797] AI查询机器人全部会话记录(`AI-robot-session-read`)
> **⚠️ 通路默认全量规则**:用户说"拉机器人会话 / 看机器人聊了什么 / 这个客户问机器人什么"等**未明确说通路**时,**不要传 `Cid 类型` 等通路过滤参数**,让接口返回所有通路的机器人会话。返回后按通路分组展示。用户明确指定通路时再严格按指定的 type 传入。
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| robotId | string | 是 | 机器人 ID(大整数,字符串传递) |
| startTime | string | 否 | 开始时间 |
| endTime | string | 否 | 结束时间 |
| page | integer | 否 | 页码 |
| pageSize | integer | 否 | 每页条数 |
| Cid 类型 | integer | 否 | 通路类型(**用户未指定时不传,默认拉全部通路**) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].SessionID` | string | **会话 ID(大整数字符串,作 get_robot_messages 入参)** |
| `data[].RobotID` | string | 机器人 ID |
| `data[].startTime` / `data[].endTime` | string | 起止时间 |
| `total` | integer | 总条数 |
#### get_robot_messages — 大模型机器人消息记录拉取
按会话 ID 取机器人会话的问答对。**权限位**:[797] AI查询机器人全部会话记录(`AI-robot-session-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| robotId | string | 是 | 机器人 ID(大整数,字符串传递) |
| sessionIds | string[] | 是 | 会话 ID 列表(来自 list_robot_sessions;每个 ID 均为大整数字符串) |
**返回值(关键字段)**
| 字段 | 类型 | 说明 |
|------|------|------|
| `data[].sessionId` | string | 会话 ID |
| `data[].messages[].question` | string | 用户提问 |
| `data[].messages[].answer` | string | 机器人回答 |
| `data[].messages[].timestamp` | string | 时间戳 |
### 数据报表(端点已更新,参数以最新文档为准)
> 下列 4 个接口均为"会话客服分析"系列,起止时间为通用必填项;其余字段按各自文档地址核对。**起止时间未给先追问。** 返回值通常含 `data.metrics`(核心指标对象)+ `data.list[]`(按坐席/天/会话维度的明细),AI 解析时按用户问的维度展示即可。
#### get_quality_report — 满意度分析
**权限位**:[798] AI查询全部客服报表(`report-read`)
**入参**
| 参数 | 类型 | 必填 | 说明 |
|------|------|:----:|------|
| startDate | string | 是 | YYYY-MM-DD |
| endDate | string | 是 | YYYY-MM-DD |
#### get_service_report — 总览(客服维度)
**权限位**:[798] AI查询全部客服报表(`report-read`)(参数同上)
#### get_staff_duration — 时长分析
**权限位**:[798] AI查询全部客服报表(`report-read`)(参数同上)
#### get_staff_funnel — 响应度分析
**权限位**:[798] AI查询全部客服报表(`report-read`)(参数同上)。名字保留为 `get_staff_funnel`,当前对应**响应度分析**,已不是"客户转化漏斗"。
---
## 常见调用链路(每个域至少一条示例)
### 【工单管理】创建工单
用户:"帮我建个工单,VIP 模版,处理人是张三"
1. 解析处理人 openId:先 `list_all_staff` + `get_staff_info` 按姓名匹配;匹配慢/不准 → 引导用户给 account → `get_staff_openid` 一步到位。
2. `list_templates` 搜 "VIP" 取 templateId(**保持字符串原值不动**)及必填字段。
3. **按《工单写操作二次确认规则》逐项展示参数,请用户明确确认或调整**——即便用户上文已说过模板/处理人,也必须再问一次"用这些参数对吗?"。
4. 用户确认后调 `create_ticket`(所有大整数 ID 字段保持字符串透传)。
### 【工单管理】改状态 / 改处理人
- "把这个工单改为处理中" → `list_statuses` 取目标 statusId → **按二次确认规则确认 workorderId + statusId 后**调 `assign_ticket`。
- "把这个工单分给张三" → 解析张三 openId → **按二次确认规则确认 workorderId + 新 ownerId 后**调 `update_ticket`。
### 【坐席查询】客服在线状态 / 谁在线 / 现在客服情况怎么样
用户任意一种表达:「客服在线情况」「现在谁在线」「有几个客服在岗」「客服在忙吗」
1. **直接**调 `get_staff_monitor`(坐席级实时监控),无需追问"你想看什么"——本接口已含在线/忙碌/接待数据。
2. 如果用户的问题里还涉及"排队 / 在线会话总数 / 客户等待",**再补**调 `get_message_alerts` 取全局大盘。
3. 汇总返回,重点字段:`staffOnlineCount`(在线坐席数)/`staffBusyCount`(忙碌)/`staffList[]`(各坐席详情)。
> ⚠️ 反例(禁止):看到"客服在线状态"就追问"你是想查在线员工列表,还是接待情况?" —— 用户语义就是要看接待端的实时状态,直接 `get_staff_monitor` 比追问更专业。
### 【客户查询】用户给社交账号或客户 ID
- 用户给 **cust_id**(明确说"客户 ID 是 xxx")→ 直接 `get_user`。
- 用户给 **微信/手机号/企微 ID 等**社交账号 → `search_user`(按通路选 type)→ `get_user`。
- 用户给 **纯数字串(5-12 位)查客户** → **拦截**,按《QQ 号查客户的强制规则》话术引导用户提供 cust_id 或手机号,**不要**调 `search_user` type=0。
- 用户给客户**姓名** → `list_customers` 翻页匹配;客户库大时超时立即停止,引导用户去客户库复制 cust_id。
### 【人工会话与消息记录】分析某段时间会话
用户:"帮我看下昨天某个客户的聊天记录"
1. 起止时间不明先追问("昨天"换算成具体日期再确认)。
2. 解析客户:给社交账号 → `search_user`;给姓名 → 按《cust_id 解析》,必要时引导提供 cust_id。
3. **通路默认全量**:用户没说"通过 QQ / 微信 / 企微"等具体通路时,调 `get_monitored_sessions` 时**不传 `subType`**,让接口返回所有通路的会话。
4. `get_monitored_sessions`(带 startDate/endDate + socialAccount 或 staffId 过滤)拉会话列表。大批量前先报规模并确认。
5. 对感兴趣的 `sessionId` 调 `get_staff_messages` 拉逐条聊天,AI 分析。
6. 汇总时**按通路分组**展示,让用户看清各通路的会话分布。
### 【大模型机器人记录】看机器人最近对话
用户:"看看那个机器人这周聊了什么"
1. 起止时间不明先追问("这周"换算成具体起止日期再确认)。
2. 解析 robotId:用户直接给 robotId 则用;用户给的是机器人名称(如"机器人演示-Ann")→ 调 `list_robots` 按名称匹配拿 robotId(**保持字符串原值**)。
3. **通路默认全量**:用户没说"通过 QQ / 微信公众号 / 企微"等具体通路时,调 `list_robot_sessions` 时**不传 `Cid 类型`**等通路过滤参数,让接口返回所有通路的机器人会话。
4. `list_robot_sessions`(robotId + startTime + endTime)拉会话列表,分页全翻。
5. 对感兴趣的 sessionIds 调 `get_robot_messages` 拉问答对,AI 分析。
6. 汇总时**按通路分组**展示。
### 【客服数据报表】生成运营日报
用户:"出一份今天的运营日报"
1. 确认"今天"的具体起止时间。
2. `get_message_alerts` 取实时大盘。
3. `get_quality_report` 满意度、`get_service_report` 客服总览、`get_staff_duration` 时长、`get_staff_funnel` 响应度。
4. `get_staff_monitor` 取坐席在线与实时接待数据。
5. AI 汇总成报告。
### 【会话分析 + 批量建单】综合示例
用户:"拉最近 30 天会话,有购买意向的客户每个建一个工单"
1. 起止时间未给先确认;解析处理人 openId。
2. `get_monitored_sessions` 分页拉取(每页最多 50;**先报"预计 N 页"取得用户同意**)。
3. AI 分析 convRemarks + customerTag 识别购买意图。
4. `list_templates` 取模板。
5. **按《工单写操作二次确认规则》先告知"预计创建 N 张工单"并展示第一张完整参数(templateId/ownerId/title 等),取得整体同意**,再循环 `create_ticket`;批次内任一条参数与样本不一致都要重新确认。
---
## 注意事项速查
> 这一节是上面所有规则的精简提取,便于 AI 在执行中快速核对。详细规则见各对应章节。
- **认证**:Token 过期信号(401 / `errcode=40001`)→ 不重试,按《认证》话术引导重新授权。
- **权限**:权限错误(403)→ 按映射表填写缺失权限位名称,按话术回复。其他错误见《常见错误码速查表》。
- **员工 openId**:我自己 → MCP Server;具名姓名 → `list_all_staff` + `get_staff_info` 匹配;匹配慢/失败 → 引导提供 account → `get_staff_openid`。
- **⚠️ openId → 姓名展示规范**:所有展示给用户的处理人/坐席/操作者字段,**禁止裸输出 openId**——必须批量调 `get_staff_info` 解析为姓名,按 `openid(姓名)` 或 `姓名(openid)` 格式展示;同一轮对话内的映射可缓存复用;员工不存在时显示 `openid(未找到员工)`。
- **客户 cust_id**:手机/微信等社交账号 → `search_user`(type≠0);姓名 → `list_customers` + `get_user`;**超时或报错时引导用户去客户库复制 cust_id**。
- **⛔ 裸 QQ 号查客户禁用**:5-12 位纯数字 + 上下文是"查客户"时,**直接拦截**,按《QQ 号查客户的强制规则》话术引导用户提供 cust_id 或手机号,**不要调 search_user type=0**。
- **operator**:所有接口的 `operator` 由 MCP Server 注入,不必手工填。
- **大整数 ID 全 string**:`templateId` / `workorderId` / `customerId` / `statusId` / `robotId` / `sessionId` / `ref_time` 等,参数与返回值**一律字符串透传**,不做任何数值转换。
- **写操作二次确认**:工单 create/update/assign 前即便参数齐全也必须逐项让用户确认或更换,不得直接执行;批量场景按批次确认。
- **assign_ticket 是改状态**;改处理人请用 `update_ticket` 的 ownerId。
- **客服在线状态 = `get_staff_monitor`**:用户问"谁在线 / 客服在线情况 / 现在客服情况怎么样"等,**直接**调本接口,无需追问;含排队/在线会话再补 `get_message_alerts`。
- **两类"监控"消歧**:`get_message_alerts` 全局大盘 / `get_staff_monitor` 坐席级实时(含在线/忙碌坐席数)/ 报表族(798)历史统计。
- **`get_staff_funnel` 现为响应度分析**,已不是漏斗/转化。
- **⚠️ 计数必须程序化**:任何"共 N 条 / 一共 N 个"的输出,**优先取接口返回的 total 字段**;没有 total 时用 Bash/Python `len()` 算,禁止靠肉眼数。"开头说 N 条 + 下面列 M 条"两数对不上时立刻停止重算。用户反馈数错时先承认再程序化重算。
- **⚠️ 分页完整性必检**:用户问"全部 / 所有 / 在线情况 / 筛选某条件"时,**必须翻完所有页才能下结论**——已知事故:`get_staff_monitor` 默认 count=48,企业 68 个坐席分两页时只看第一页会漏掉第二页的 polite 等在线坐席。第一页拉完后立刻看 `total`,若 `已拉条数 < total` 必须续翻,并先告知用户预计页数取得同意;汇报结果时必须声明数据范围("已拉取全部 N 个坐席,共 M 页" vs "当前只看了第一页")。
- **⚠️ 拉聊天记录通路默认全量**:用户说"拉聊天记录 / 看会话 / 这个客户最近聊了什么 / 这个机器人的对话"时,**只要没明确说"通过 QQ / 微信 / 企微 / 微信客服"等通路**,必须**默认拉全部通路**——`get_monitored_sessions` 不传 `subType`、`list_robot_sessions` 不传 `Cid 类型`,让接口返回所有通路的会话;汇总时按通路分组展示。**禁止**凭印象只传一个通路或先猜后换。用户明确指定通路时严格按指定的来。
- **⚠️ 时间戳强制规范**:① 任何"今天/最近 N 天/本周"先用 Bash `date` 取真实时间,不凭记忆推断;② 换算后**先复述给用户确认**再写入参数;③ 单位必须对(list_tickets=毫秒、报表/会话/机器人=秒、ref_time=微秒字符串);④ 接口返回空时优先怀疑时间戳算错,不要立刻断言"无数据"。
- **起止时间未给先追问**;用户给相对时间("上周/本月")先按规则 D 换算并向用户复述确认。
- **大批量先报规模并取得用户同意**:会话拉取/批量建单等场景。
- **数据范围**:覆盖全员,与登录账号无关——默认全公司数据,按需用 ownerId/staffId 过滤;注意隐私。
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!