Dangkang Insight
ASecurity本报告为中软云企信息服务(南京)有限公司提供的免费体验版,输入“请检测企业:企业名”即可开始检测。免费版主要用于新用户推广体验与企业快速合规自查。全行业所有市场主体通用,特别适用于首次使用平台的新用户体验、企业日常快速基础财税合规筛查,内置 12 项核心财税基础检测指标,提供轻量化财税合规检测初筛服务,仅展示基础合规检测概览与部分指标详情,全部深度合规指标分析、异常数据明细及整改方案付费可提供深度分析。【提问最小化】用户原话已说明检测类型(如“发起财税检测”)、登录方式或企业名称时,一律直接匹配采用并一句话告知,禁止再弹选项重复确认;只有用户确实没说且无法推断时才询问。【检测对象】用户未指明检测企业时,须主动把账号的「当前管理企业」(名称 + 税号)作为候选提示给用户,让其在「检测当前管理企业 / 检测其他企业」之间选择,经用户确认后方可发起,不得未经确认直接使用。【可识别说法】免费体检 / 财税风险检测 / 综合合规检测 / 全景检测 / 财务合规检测 / 税务合规检测 / 行业专项检测 / 月度健康检测 / 企业尽调检测 / 发票穿透检测 / 税收优惠匹配检测 —— 以上说法...
- 417 stars
- 0 votes
- 0 copies
- 0 views
- Added November 8, 2026
Works with
Security analysis
100/100Pro scans all 6 files and shows the line behind each finding
npx -y skills add infometa/workbuddyskills --skill dangkang-insight --agent claude-codeAre you the author of Dangkang Insight?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/infometa-dangkang-insight)---
name: dangkang-insight
name_en: dangkang-insight
display_name: 中软当康 · 税无险 财税综合合规检测
display_name_en: Zhongruan Dangkang Shuiwuxian – Fiscal & Tax Compliance Detection
description: 本报告为中软云企信息服务(南京)有限公司提供的免费体验版,输入“请检测企业:企业名”即可开始检测。免费版主要用于新用户推广体验与企业快速合规自查。全行业所有市场主体通用,特别适用于首次使用平台的新用户体验、企业日常快速基础财税合规筛查,内置 12 项核心财税基础检测指标,提供轻量化财税合规检测初筛服务,仅展示基础合规检测概览与部分指标详情,全部深度合规指标分析、异常数据明细及整改方案付费可提供深度分析。【提问最小化】用户原话已说明检测类型(如“发起财税检测”)、登录方式或企业名称时,一律直接匹配采用并一句话告知,禁止再弹选项重复确认;只有用户确实没说且无法推断时才询问。【检测对象】用户未指明检测企业时,须主动把账号的「当前管理企业」(名称 + 税号)作为候选提示给用户,让其在「检测当前管理企业 / 检测其他企业」之间选择,经用户确认后方可发起,不得未经确认直接使用。【可识别说法】免费体检 / 财税风险检测 / 综合合规检测 / 全景检测 / 财务合规检测 / 税务合规检测 / 行业专项检测 / 月度健康检测 / 企业尽调检测 / 发票穿透检测 / 税收优惠匹配检测 —— 以上说法均进入同一套检测流程,具体报告类型按账号可用服务(cpfwbh)与所选报告类型(cpxdm)区分。中软云企官网:https://lxyq.cssyq.com.cn/。服务热线:400-005-1670。
description_en: Free trial edition of fiscal & tax compliance detection provided by Zhongruan Yunqi Information Service (Nanjing) Co., Ltd. Say "Run a detection for <company name>" to start. Built for new-user onboarding and quick day-to-day compliance self-checks across all industries and market entities; ships 12 core baseline indicators and shows only the compliance overview plus part of the indicator detail — full in-depth indicator analysis, exception details and remediation plans are available in paid reports. [Minimal questioning] When the user's own words already state the detection type, login method or company name, adopt it directly and confirm in one sentence; never re-ask with option menus. Only ask when the intent genuinely cannot be inferred. [Detection target] When the user has not named a company, proactively offer the account's current managed company (name + tax ID) as candidate A and let the user choose between "detect the current managed company" and "detect another company"; never start a detection on it without explicit user confirmation. Recognized phrasings — free health check / tax-risk detection / comprehensive compliance check / panoramic scan / financial compliance check / tax compliance check / industry-specific check / monthly health check / due diligence check / invoice penetration check / tax-incentive matching — all run the same detection flow, with the report type resolved from the account's available services (cpfwbh) and the selected report type (cpxdm). Website https://lxyq.cssyq.com.cn/ Hotline 400-005-1670.
argument-hint: Provide the enterprise name or taxpayer identification number, e.g. "Run a fiscal-tax risk detection for [company name]"
argument-hint-en: Provide the enterprise name or taxpayer identification number, e.g. "Run a fiscal-tax risk detection for [company name]"
argument-hint-zh: 输入企业名称或纳税人识别号开始检测,如「请检测企业:[企业名]」
version: 0.9.0
category: finance_accounting
---
# 中软当康 · 税无险 财税综合合规检测
## 一、报告概述
本报告为平台专属免费体验版,内置 12 项核心财税基础检测指标,提供轻量化财税合规检测初筛服务,仅展示基础合规检测概览与部分指标详情,全部深度合规检测分析、异常数据明细及整改方案付费可提供深度分析,免费版主要用于新用户推广体验与企业快速合规自查。
## 二、检测范围
覆盖企业财税核心基础维度,包含:发票合规与虚开风险、增值税核心风险、企业所得税核心风险、个人所得税等其他税种风险、财务核算与财税比对风险、企业基本信息风险。
免费版仅展示风险等级总览及部分无风险指标的完整分析内容,所有中高风险的异常明细、数据溯源、政策依据及应对建议均为付费版专属内容。
## 三、适用范围
全行业所有市场主体通用,特别适用于首次使用平台的新用户体验、企业日常快速基础财税合规筛查。
## 四、作用需求
快速完成企业基础财税风险扫描,直观展示整体风险等级与风险分类分布;帮助企业快速了解自身基础财税健康状况,识别潜在高风险方向;为企业判断是否需要开展深度财税合规检测提供参考依据。
## 五、价值需求
零成本体验平台核心检测能力,无需专业财务知识即可快速上手;提前预警基础涉税风险,避免因小问题引发重大税务隐患;操作简便高效,1 分钟即可生成基础风险报告,满足企业日常快速自查需求。
## 六、总结
我们始终相信,合规不是成本,而是企业最核心的竞争力之一。平台为企业创造的核心价值,正是推动企业从单纯的“风险管控”,迈向更高维度的“价值创造”。
首先,是降低风险,保障经营安全。
其次,是提升合规,优化内部管理。
更重要的是,它能赋能决策,通过深度的数据分析,帮助您优化供应链,控制成本,驱动业务增长。
## 七、联系方式
中软云企官网:https://lxyq.cssyq.com.cn/
服务热线:400-005-1670
## 文件结构与配置
```
dangkang-insight/
├── SKILL.md # 本文件
├── .gitignore # 只忽略令牌缓存/日志/本地元数据;mcp.ini 模板随包分发
├── config/
│ ├── mcp.ini # 网关 MCP 配置(模板,令牌留空,随包分发)
│ └── mcp.example.md # 同上模板(mcp.ini 缺失时脚本会用它自动生成)
├── logs/ # 运行日志(按日期 YYYY-MM-DD.log 归集;二维码 PNG 也存于此)
└── scripts/
├── mcp_gateway_client.py # 网关 MCP 客户端(所有业务接口经此调用;纯标准库)
├── oauth_login.py # OAuth 重新授权(PKCE + 本地回调;令牌失效时用)
└── 云企智控MCP对接说明.md # 接口 ↔ MCP 工具映射、网关侧需补齐的工具与前置条件
```
> 上架说明:`config/mcp.ini` **不忽略**(模板无密钥,需随包分发);`config/.token.json`、
> `logs/`、`_user_meta.json` 均被忽略,不会进入市场包。
## 本技能与网关 MCP 的关系(必读)
**本技能不直连平台 OpenAPI**:不再需要 AK/SK,也不依赖 `gmssl`(原直连版用国密 SM4+SM3 传输加密,那套逻辑已全部下沉到网关)。
所有业务接口都经 **网关 MCP**(`config/mcp.ini` 里的 `[mcp] url`,默认
`https://lxyq.cssyq.com.cn/ggyw/mcp`,JSON-RPC 2.0 / streamable HTTP)调用。
接口 ↔ MCP 工具映射(工具名可在脚本 `TOOL` 字典里改):
| 步骤 | 接口 | 路径 | MCP 工具 |
|------|------|------|----------|
| 1.1 | 发送短信验证码 | `/gg/org/auth/riskDet/smsCodeSend` | `riskdet-sms-code-send` |
| 1.2 | 上传验证码登录 | `/gg/org/auth/riskDet/smsCodeUpload` | `riskdet-sms-code-upload` |
| 2.1 | 获取电局登录二维码 | `/gg/org/auth/riskDet/getQrcode` | `riskdet-get-qrcode` |
| 2.2 | 扫码状态查询 | `/gg/org/auth/riskDet/scanCode` | `riskdet-scan-code` |
| 1.3 | 查询授权状态及报告 | `/znfk/qyfxgl/saas/yqzk/querySqztBgxx` | `riskdet-query-status` |
| 1.4 | 付费报告申请 | `/gg/org/auth/report/apply` | `riskdet-report-apply` |
| 1.5 | 获取风险检测概览 | `/znfk/qyfxgl/saas/zsr/getQyfxjcglxx` | `riskdet-risk-overview` |
辅助工具:`sys-user-info`(取 userId / customerId,以及**当前管理企业** companyName / companyTaxNo
—— 它是「检测对象」的**首选候选提示**)、`query-order`(取 ddbh / cpfwbh,即「用户可用的检测类型」清单)。
> ✅ **`sys-user-info` 里的 companyName / companyTaxNo 应当主动向用户提示**:
> 它就是「账号当前管着哪家企业」,是用户最可能想检测的对象。询问检测对象时**要把它列成候选 A**
> 摆给用户(选它 / 选其他企业),省掉用户手打企业名的麻烦;
> 但**最终必须由用户明确选定后才能发起检测**,未经确认不得直接拿它去测(见「用户信息采集」第 2 条)。
>
> ⚠️ `sys-user-info` **不返回 `ssdq`(所属地区)**:即使用户选了当前管理企业,
> 地区仍须向用户补问(省级码)。
> ⚠️ **前置条件(网关侧)**:1.1 / 1.2 / 2.1 / 2.2 与 1.4 由网关转发到 **yfp-ggyw** 服务,
> 该服务的接口受登录态保护;网关必须把调用方身份映射成该服务的登录会话,否则这些工具会返回
> `401 账号未登录`。1.3 / 1.5(**znfk-fxmxgl** 服务)是纯查库接口,不依赖登录态。
> 若 1.3 / 1.4 / 1.5 三个工具尚未部署,网关会返回 `unknown tool: riskdet-query-status` 之类的
> JSON-RPC 错误;补齐办法见 `scripts/云企智控MCP对接说明.md`。
## 首次使用与鉴权(新用户必读)
本技能的业务接口全部经过**网关 MCP**(`config/mcp.ini` 的 `[mcp] url`,默认
`https://lxyq.cssyq.com.cn/ggyw/mcp`)。网关对调用方做 **OAuth 鉴权**,因此**首次使用必须先完成一次授权**,
拿到令牌后才能调用。分两种情况:
### 情况一:宿主已内置「中软当康 · 税无险」连接器(推荐,主流路径)
如果 WorkBuddy 的**连接器**里已经能搜到 `dangkang-insight`,直接用连接器即可——
**宿主会代为处理 OAuth 授权,用户零配置**。
⚠️ 但要注意:**连接器的令牌是宿主私有的,脚本拿不到它**。
两条通道的令牌**完全独立**:
| | MCP 工具通道(宿主连接器) | 脚本直连通道 |
|---|---|---|
| 令牌谁管 | 宿主自动保管+刷新 | 脚本自己找 `DKI_MCP_TOKEN` > `config/.token.json` > `config/mcp.ini` |
| 需要配置吗 | 点授权即可 | **必须单独注入一次令牌** |
所以「宿主装了连接器」**不等于**「脚本能用」。脚本没有令牌时调用会返回
`HTTP 500 / JSON-RPC 错误 "invalid_token"`,并打印「没有 refresh_token,无法自动续期」。
→ **决策规则**:先用 `python scripts/mcp_gateway_client.py info` 探一下。
返回用户信息 → 脚本可用,扫码走「命令6 + 命令7」组合(Step 1-QR)。
返回 `invalid_token` → **脚本不可用**,此时扫码必须走下方的
「**纯 MCP 工具扫码路径**」,助手自己轮询,**不要**再调命令6/7(必然失败)。
### 情况二:仅有本地 skill、需要走脚本直连
脚本自己也要能调用网关,此时要先给它一枚令牌。脚本**只能刷新令牌、不能自行获取令牌**,
所以首次必须由外部注入一次(三种方式任选其一,优先级从高到低):
| 方式 | 做法 | 适用 |
|------|------|------|
| 环境变量 | 设 `DKI_MCP_TOKEN`(access token)、可选 `DKI_MCP_REFRESH_TOKEN` | 最安全,令牌不落盘 |
| 令牌缓存 | 把令牌写入 `config/.token.json`(`access_token`/`refresh_token`/`client_id`) | 复用已有授权 |
| 配置文件 | 在 `config/mcp.ini` 的 `[mcp]` 段填 `access_token`/`refresh_token`/`client_id` | 简单直接 |
⚠️ **没有令牌时脚本的表现**:调用返回 `HTTP 500 / JSON-RPC 错误 "invalid_token"`,
并提示「没有 refresh_token,无法自动续期」。**这不是代码故障,是尚未授权**——请先完成上面的授权。
access token 有效期约 12 小时,脚本会在 401 时自动用 refresh_token 静默续期并写入 `config/.token.json`。
**连 refresh_token 也失效时(返回 `invalid_grant`),直接跑 `python scripts/oauth_login.py`
重新授权即可**,详见下文「令牌失效后如何重新授权」。
### 令牌失效后如何重新授权(脚本自带,无需人工介入)
脚本**只能刷新令牌、不能获取令牌**。当刷新返回
`invalid_grant: 平台登录会话已失效,请重新授权`(或本地压根没有 refresh_token)时,
说明必须重新走一次完整的授权码流程。本技能自带 `scripts/oauth_login.py` 完成这件事:
```bash
# 默认:复用 config/.token.json 里的 client_id + 回调端口 8765
python scripts/oauth_login.py
# 端口被占用 / 想用全新的 OAuth 客户端 / 显式指定客户端
python scripts/oauth_login.py --port 8790
python scripts/oauth_login.py --new-client
python scripts/oauth_login.py --client-id wb_xxxxxxxx
python scripts/oauth_login.py --wait 1800 # 自定义等待秒数(默认 900)
```
脚本会依次:生成 PKCE(verifier/challenge) 与 state → 起本地回调服务
`http://localhost:<port>/callback` → 打印授权链接(同时落盘 `logs/oauth_auth_url.txt`)
→ 前台阻塞等待用户在浏览器登录并确认 → 用回调带回来的 code 换取 token
→ 写回 `config/.token.json`(含新的 refresh_token 与 client_id)。
助手的使用要点:
- 把 stdout 里的 `AUTH_URL:` 那一行**原样给用户**,让用户**自己复制到浏览器**打开。
**不要替用户启动浏览器进程**(`start` / `Start-Process` / `os.startfile` 都不要用),
也不要自己写 HTML 卡片去包这个链接。
- 链接里的 `code_challenge` 与脚本内的 `code_verifier` 是**一对一**绑定的,所以:
必须让**脚本所在机器的 localhost** 收到回调。不要把链接转给别人、也不要在另一台机器上
打开后把回调地址抄回来——那样换令牌会失败。
- 脚本在用户完成授权前会一直前台阻塞,这就是设计行为。Bash 调用请给足超时
(≥ 用户操作 + 缓冲,例如 `timeout=600000`),**不要**改成后台运行——后台任务在回合
结束后无法把结果带回对话。
- 没有 client_id 时脚本会自动 DCR 注册一个(`POST {issuer}/oauth2/register`,
redirect_uri 为 `http://localhost:<port>/callback`);复用已有 client_id 时若
redirect_uri 不匹配,会自动降级为重新注册。
- 退出码:`0` 成功 / `1` 超时或用户未完成 / `2` 拿到 code 但换令牌失败 / `3` 端口或注册不可用。
失败时细节见 `logs/oauth_result.json`。
- 授权成功后 access_token 约 12 小时有效,之后由 `mcp_gateway_client.py` 静默续期,
正常情况下**不需要**再跑本脚本。
### 缺少 config/mcp.ini 时
**不会崩溃**:脚本在 `config/mcp.ini` 缺失时会自动从 `config/mcp.example.md` 生成一份默认配置
(内置生产网关地址、令牌留空),保证开箱即用。
## 宿主适配:二维码怎么展示(重要)
**展示二维码时必须调用当前宿主实际存在的工具**。照抄另一个宿主的工具名会导致「工具不存在 → 静默失败 → 聊天里什么都看不到」,这是最常见的失效原因。
目标效果是**二维码直接出现在对话流里**(正文气泡内),而不是塞进侧边/右侧的产物面板。
二维码的来源只能是接口 2.1(网关工具 `riskdet-get-qrcode`)——它的响应里是二维码图片,**助手不能去逐字转抄它**(历史上被截断过两次:碎图标 / 只显示上半截)。
所以统一由脚本 `scripts/mcp_gateway_client.py 6` 取码并输出**已重编码好的内联卡片片段**。
> **只想把已有的二维码渲染成卡片时用 `qr` 命令**(零鉴权、不联网):
> ```bash
> python scripts/mcp_gateway_client.py qr <来源> [企业名] [税号]
> ```
> `<来源>` 可为 `blob:<路径>` / `data:image/png;base64,…` / 本地 PNG 路径 / `@<文件>` / `-`(stdin)。
> 超长 base64 **必须**走 `@文件` 或 stdin,别当命令行参数(会截断)。
> 适用于:走宿主线程已拿到二维码、或 `show_widget` 需要重新出卡片、或没有令牌只想渲染。
> 退出码:`0` 成功 / `2` 来源解析失败 / `3` 卡片生成失败 / `4` 图片已损坏(base64 传递中被改动)。
> ⚠️ **二维码有两种返回形态,脚本必须都能识别**(否则会出现「接口明明成功了,聊天里却没有二维码」):
> 1. **内联 data URI**:`` —— 约 2 KB 的一整行 base64;
> 2. **本地 blob 引用**:``
> —— 网关只给一个**指向宿主本地文件的路径**,根本没有 base64 可抄。
>
> 这就是「第一次没出码」的根因:只处理了形态 1,遇到形态 2 时 `qrcode` 解析为空,
> 脚本直接报「响应里没有二维码」并静默跳过卡片。现已在脚本中修复(见下)。
| 宿主 | 展示方式 | 效果 |
|------|----------|------|
| WorkBuddy | **`show_widget`** 内联渲染,`widget_code` 直接填命令6 stdout 里 `[WIDGET_BEGIN]…[WIDGET_END]` 之间的片段 | 二维码卡片内联出现在聊天流中 ✔ 首选 |
| WorkBuddy(兜底) | `present_files` 传 `logs/qrcode_live_*.png` 绝对路径 | 打开右侧预览面板 ✖ 不是内联 |
| 千问办公 / qwenwork | `qwenwork_file_present_files` 传 `logs/qrcode_live_*.png` | 聊天内联卡片 |
| 其它宿主 | 把 `logs/qrcode_live_*.png` 复制到输出目录后用通用文件展示能力 | 视宿主而定 |
判断规则:
1. 当前会话有 **`show_widget`** → 用内联渲染,**不要**再用 `present_files`(那会跑到右侧面板去)。片段由命令6 直接给出,**原样粘贴、不要改动任何一个字符**,并且**直接从命令6 的 stdout 透传,不要用「读文件」的方式二次获取**(读取工具会截断超长单行)。片段里的迷你 PNG(base64 约 700 字符)是**已经做过点阵重编码**的结果,正是为此才可靠;
2. 没有 `show_widget`、只有 `present_files` → 用 `present_files` 传命令6 返回的 `qrcode_png` 绝对路径;
3. 只有 `qwenwork_file_present_files`(千问办公)→ 用它传 `qrcode_png`;
4. 都没有 → 把 `qrcode_png` 复制到当前工作目录的输出目录,再用通用文件展示能力。
### 为什么二维码要重编码
接口返回的二维码原图 base64 约 2070 字符(PNG 1536 字节),是一整行。脚本把它解码成 41×41 的
模块矩阵(纯 stdlib 实现),补上 4 模块静区后重编码为 **196×196 的 1bit PNG**,base64 仅约
700 字符——量小到可以安全地逐字转抄进渲染工具。196px 显示 49 模块 = 每模块 4px,配合
`image-rendering:pixelated` 整数倍缩放不模糊;静区烘焙进图片本身,图片被单独打开/另存也能被扫码器识别。
**两种返回形态的统一处理**(脚本内部已做,助手无需关心):
| 形态 | 脚本处理 |
|------|----------|
| `data:image/png;base64,...` | `_decode_data_uri()` 解 base64 落盘 |
| `{"type":"image_blob_ref",...,"blob_path":"..."}` | `parse_md()` 存入 `fields["qrcode_blob_path"]`,`_get_qrcode_via_mcp()` 归一化为 `blob:<路径>`,`_decode_data_uri()` 直接复制该文件落盘 |
落盘后统一走 `_build_qrcode_widget()` 做点阵重编码,两种来源产出的卡片完全一致。
> 💡 若网关侧可改:建议 `riskdet-get-qrcode` 直接用 MCP 的 `image` content 类型返回(或给出完整
> `data:` URI),这样宿主能原生渲染,客户端就不必再做 blob→base64 的转换。
> ⚠️ 卡片必须保持**单行紧凑形态(总高约 220~240px)**。宿主给 widget 的 iframe 高度有上限,
> 多行 / 多层嵌套容器会被从底部裁切,表现为「卡片只显示一半」。不要在同一张卡片里再塞第二块内容。
> 卡片模板在脚本的 `_QRCODE_WIDGET_HTML` 里,**助手不需要自己写 HTML**。
调用 `show_widget` 时 `title` 用「电子税务局扫码登录二维码」,配 1–3 条 loading 文案。
**内联卡片渲染后要紧接着输出引导文字**(用电子税务局 App 扫码、有效期约 3 分钟)。
## 整体流程与API调用顺序(严格遵循)
用户发起检测 → **确定检测类型**(用户原话已含类型语义 → 直选;未含 → 才问)→ **确定检测对象**(用户原话已点名企业 → 采用并补齐缺失字段;**未点名 → 必须问,同时把 `info` 带回的「当前管理企业」作为候选 A 提示出来,由用户选定「它」或「其他企业」后再继续**)→ **确定登录方式**(用户已说明 → 直选;未说明 → 才问)→ 按所选分支采集信息并登录 → **两种登录方式成功后共用 1.3 → 1.4 → 1.5 后续流程(不变)**。
> 🔴 **提问最小化(本技能第一原则)**:能用用户原话、账号信息或上下文确定的,一律**直接采用 + 一句话告知**,
> 不要弹选项卡二次确认。用户说「发起**财税**检测」时再去问「选哪种检测类型」属于典型失误。
**分支A:账号密码登录(短信验证码)**
1. **1.1 发送短信验证码** → 命令 `1`(MCP `riskdet-sms-code-send`)
2. **1.2 上传验证码登录** → 命令 `2`(MCP `riskdet-sms-code-upload`,需要1.1返回的`taskId`)
**分支B:扫码登录(电子税务局二维码)**
1. **2.1 获取二维码** → 命令 `6`(MCP `riskdet-get-qrcode`;返回`taskId`、`ywjcjlbh`、二维码)
2. **2.2 扫码状态查询** → 命令 `7`(MCP `riskdet-scan-code`,脚本内部轮询至终态)
**共同后续(任一分支登录成功后)**
3. **1.3 查询授权状态及报告** → 命令 `3`(MCP `riskdet-query-status`)→ 命令 `4`(MCP `riskdet-report-apply`)
4. **1.5 获取企业风险检测概览** → 命令 `5`(MCP `riskdet-risk-overview`)
> 脚本统一入口:`python scripts/mcp_gateway_client.py <命令> <参数...>`(Windows 建议加
> `PYTHONUTF8=1 PYTHONIOENCODING=utf-8`,避免中文企业名在命令行传参时乱码)。
> **助手如果直接调用宿主的 MCP 工具**(宿主已连接 gateway 时也可行)做单次调用,参数按上表工具名对应;
> 但**扫码轮询(2.2)与报告轮询(1.3)必须用脚本**——那是几十次串行调用,交给助手逐次调用不现实;
> **二维码也必须用脚本**,原因是上面讲的 base64 转抄问题。
## 参数复用策略
- 前面接口已有的参数尽量复用,不要重复要求用户输入
- 只在必要时提示用户补充缺失参数
- 自动传递中间结果(如`taskId`、`ywjcjlbh`)
- **账号类与订单类参数由脚本经 MCP 自动取齐**:`userId`/`customerId` ←
`sys-user-info`;`ddbh`/`cpfwbh` ← `query-order`。命令行传入的值优先;两者都拿不到时才用
`config/mcp.ini` 的 `[business]` 兜底。所以**企业信息只需采集 nsrsbh/nsrmc/ssdq(扫码)或再加账号密码手机号身份类型(账密)**。
- ⚠️ **`nsrsbh` / `nsrmc` 不在此自动取齐之列**:脚本虽然能读到 `sys-user-info` 的
当前管理企业,但**发起检测时(命令 `1` / `6`)缺这两项会直接报错拦下**,
必须由用户确认后显式传入(详见「用户信息采集」第 2 条)。
## 检测类型选择(cpfwbh / cpxdm,重要)
平台支持**多种检测类型**,用户买过哪些类型,就决定了他能发起哪些检测。
**`cpfwbh`(商品服务代码)就是「检测类型」的载体**,它决定本次检测生成哪一类报告。
### 铁律:先看用户原话,能定就别问
🔴 **`types` 只用来「查可用清单 + 校验剩余次数」,不是「拿清单去问用户」。**
用户开口往往已经带了检测类型语义(「发起**财税**检测」「查一下**发票穿透**」「做个**尽调**」),
这时必须**直接匹配并采用**,回复里带一行「本次将使用:XXX」即可,**不得再弹选项卡片让人选**。
> 历史上最影响体验的失误:用户说「发起财税检测」,助手仍然弹出 6 个类型让用户挑。
> **用户已经说过的信息,绝不再问第二遍。**
#### 直选判定(按顺序执行)
1. 先跑 `types` 拿可用清单(**必须**,用于校验剩余次数与可用性);
2. 从**用户原话**里抽检测类型语义,对照别名表匹配:
| 用户话里的关键词 | 直选类型(检测类型 / 报告类型) | 典型 code |
|---|---|---|
| 财税 / 财税检测 / 财税合规 / 财税风险 / 税务检测 / 税务风险 / 税务合规 / 财务合规 / 财税综合 | 财税合规检测通用版(财税综合合规检测) | `ACSY_2001`(按次)、`ANSY_1001`(包年) |
| 免费 / 免费体验 / 免费版 / 试用 / 初筛 | 新用户免费体验版(综合风险检测报告·免费版) | `MFSY_0000` |
| 尽职调查 / 尽调 / 背调 / 背景调查 / 合作前调查 | 尽职调查检测 | `ACSY_JZDCBG001` |
| 发票穿透 / 发票虚开 / 进销项 / 发票风险 | 发票穿透专项风险检测 | `ACSY_FPCT001` |
| 供应商 / 供应厂商 / 上下游 / 采购商 | 供应商专项风险检测 | `ACSY_GYSJC001` |
| 贷前 / 贷款前 / 融资前 | 贷前检测报告 | `ACSY_DQJCBG0001` |
| 电商 / 网店 | 电商合规检测 | `ACSY_HYZXDS001` |
| 汇算清缴 / 所得税汇算 | 企业所得税汇算清缴专项合规检测 | cpxdm `27` |
| 研发费用 / 加计扣除 | 研发费用加计扣除合规检测 | cpxdm `26` |
| 应享未享 / 税收优惠 | 应享未享税收优惠合规检测 | `ACSY_SSYHBG001` |
| 制造业 | 制造业专项合规检测 | `ACSY_CSHYBG001` |
| 全景 / 全景检测 | 财税全景合规检测 | `ACSY_CSQJBG001` |
| 月度健康 / 月度体检 | 企业税务月度健康检测 | cpxdm `17` |
3. **命中唯一一族** → 在该族可用服务里直选,**不再询问**,只输出「本次将使用:XXX」;
4. **同时命中多族** → 取**措辞更具体**的那个(「发票穿透」比「财税」具体),并在回复里点明取舍;
5. **完全没命中**(只有「检测 / 查一下 / 发起检测 / 风控 / 体检」这类泛化词)→ **这时才用 AskUserQuestion**;
6. **命中但不可用**(未购买 / 次数用尽 / 编码写错)→ **说明原因,让用户从可用清单里改选**。
脚本层会 **fail fast 拦下**:`resolve_enterprise` 拿用户点名的 `cpfwbh` 去可用清单核验,
核不到就抛错并**把完整可用清单打印在后面**:
```
[错误] 当前账号没有可用的检测类型 `ACSY_XXX`(未购买 / 剩余次数为 0 / 编码有误)。
请从下方可用清单里改选,把 cpfwbh 换成对应代码后重试:
1. **发票穿透专项风险检测-单次** ...
```
→ **把这份清单原样转给用户改选即可**,不要自己另编选项、不要重试同一个编码、
也不要自己猜一个"最接近"的类型替用户做主。
> ⚠️ **历史 bug(已修复,勿回退)**:旧版这里会**静默错配**——用户点名的类型不在清单里时,
> 兜底分支用 `setdefault` 把 `ddbh` 换成一个默认订单(如免费体验版),而 `cpfwbh` 保留了
> 用户原值,于是产出「免费体验版订单 + 不存在代码」的错配组合,并一路带到 1.1 / 2.1,
> 且只打印一句误导性的「未指定检测类型,已自动选默认订单」。
> 现规则:**`ddbh` 与 `cpfwbh` 必须来自同一个可用服务**,否则一律报错拦下。
#### 同族内多条服务的取舍(自动完成,不用问)
同一类型常有多个订单/服务(「按次通用版」「包年不限次」「免费版」)。按下列优先级**自动取第一个剩余 > 0 的**:
1. 用户明确说了「免费 / 体验」→ 取免费版;
2. 否则:**通用版(按次)> 包年 > 免费版**;同等条件下取**剩余次数更多**、再取**有效期更长**的;
3. 按年服务的「本月剩余」为 0 时,顺延到下一候选。
选完后**必须**给出这一行(给用户知情权与纠错机会):
> 本次将使用「<检测类型名>」(剩余 N 次,有效期至 YYYY-MM-DD)。如需改用其他类型,直接说即可。
> 只有 `types` 返回**唯一**一个可用服务时,这行也可省略,直接进入下一步。
### 附:查看清单与按报告类型收窄(辅助工具,不是提问清单)
检测开始前,用命令 `types` 拉取当前用户的可选类型清单:
```bash
python scripts/mcp_gateway_client.py types
```
输出形如(信息已对齐平台 Web「所属服务」下拉的口径):
```
# 可用检测类型(共 9 种)
1. **尽职调查检测服务**
- 检测类型代码:`ACSY_JZDCBG001`
- 报告类型:尽职调查检测(产品线 28|按次)
- 可用剩余:93 次/购买 100 次
- 数据采集状态:采集成功
- 订单:HT2026052016011582 · 尽职调查检测服务
- 有效期至:2026-12-31
2. **云企智控财税风险检测服务-包年服务,一年内不限次检测服务**
- 检测类型代码:`ANSY_1001`
- 报告类型:税务合规检测(简化版) + 财税综合合规检测 + 财务合规检测(产品线 01,02,03|按年)
- 本月剩余:10 次(按年服务,单月上限)
- 订单:HT2026072317010559 · 财税合规检测服务-包年不限次100次权益
- 有效期至:2027-07-23
...
---MACHINE---
[ { "cpfwDm": "MFSY_0000", "cpxdm": "05", "cpxdmName": "综合风险检测报告(免费版)", ... }, ... ]
```
- `---MACHINE---` 之后是结构化 JSON,助手可直接解析。
- 数量为 1 时直接采用,无需询问。
- 数量 ≥ 2 时**先走上方的「直选判定」**:用户原话命中某类型 → **直选,不提问**;
只有**完全没命中类型语义**(泛化的「检测 / 查一下」)时才用 AskUserQuestion 让用户选。
⚠️ 禁止把这份清单当成问卷菜单直接甩给用户。
- 清单按 `cpfwDm` 去重:包年订单会返回上百条同码明细,已自动合并并记录「另有 N 个订单可用同类型」;
同一编码有多个订单时,**主条目取「剩余可用次数最多」的那个订单**。
- **剩余次数是关键判据**:`可用剩余 0 次` 的服务实际上不能发起检测
(后端会直接不返回该服务,返回为空往往就是次数用完了)。按年服务的「本月剩余」是
单月上限(默认 10)减去本月已用,下月会重置。
### 按「报告类型」收窄(对齐平台三级联动)
平台「继续生成」弹窗是**三级联动**:报告类型 → 所属订单 → 所属服务。本站可等价实现:
```bash
# ① 不确定有哪些报告类型 → 先看平台全量清单(静态表,无需联网)
python scripts/mcp_gateway_client.py cpxdms
# ② 指定报告类型,只列该类型下真正可用的服务(订单 + 剩余次数)
python scripts/mcp_gateway_client.py types <czrId> 28
python scripts/mcp_gateway_client.py types <czrId> 18,19 # 组合码
```
`cpxdms` 输出的平台全量报告类型(来源:前端 `monitor.js` 19 条配置 + 字典 `DM_FK_CPXDM`):
| cpxdm | 报告类型 | | cpxdm | 报告类型 |
|---|---|---|---|---|
| `01,02` | 税务合规检测 | | `20,21` | 批发零售行业专项合规检测 |
| `02` | 财税综合合规检测 | | `22,23` | 金融行业专项合规检测 |
| `03` | 财务合规检测 | | `24,25` | 通用行业专项合规检测 |
| `05` | 综合风险检测报告(免费版) | | `26` | 研发费用加计扣除合规检测 |
| `06` | 综合合规检测(演示版) | | `27` | 企业所得税汇算清缴专项合规检测 |
| `07` | 网络直播合规检测 | | `28` | 尽职调查检测 |
| `08` | 废旧物资合规检测 | | `29` | 应享未享税收优惠合规检测 |
| `09` | 发票穿透合规检测 | | `30` | 电商合规检测 |
| `17` | 企业税务月度健康检测 | | `31` | 财税全景合规检测 |
| `18,19` | 制造业专项合规检测 | | `all` | 综合合规检测(全部类型) |
### 把选中的类型传进去
用户选定后,把 `cpfwbh` 放进企业信息 JSON(**不是**放到命令行末尾):
```json
// 扫码登录 + 选了通用版
{ "nsrsbh": "91330602***********", "nsrmc": "XXXX公司", "ssdq": "3300", "cpfwbh": "ACSY_2001" }
```
脚本的行为:
1. **用户显式指定的 `cpfwbh` 优先级最高,绝不被覆盖**(历史版本会静默改回 `MFSY_*`,已修复);
2. 若只给了 `cpfwbh` 没给 `ddbh`,脚本会**自动配对**该类型对应的订单;
3. **指定的类型若不在可用清单里 → 直接报错拦下**(不再静默换个订单凑数),
错误信息里带完整可用清单,供用户改选;`ddbh` 与 `cpfwbh` **必须来自同一个可用服务**;
4. 只给了 `ddbh` 没给 `cpfwbh` → 反查该订单所属服务,把 `cpfwbh` 补上,保证成对;
5. 完全没指定时,才按 `MFSY 免费版 → ACSY_2001 通用版 → ANSY_1001 包年 → 第一条`
的顺序挑一个默认服务(`ddbh` 与 `cpfwbh` 成对写入)。
### 常见检测类型编码
实测(真实订单)**cpfwbh ↔ cpxdm ↔ 报告类型**对照:
| cpfwbh | 检测类型(平台「所属服务」) | cpxdm | 对应报告类型 |
|--------|------------------------------|-------|--------------|
| `MFSY_0000` | 云企智控免费(新用户体验版) | 05 | 综合风险检测报告(免费版) |
| `ACSY_2001` | 财税合规检测通用版(税务+财务) | 01,02,03 | 税务合规 / 财税综合 / 财务合规 |
| `ANSY_1001` | 财税合规检测·包年不限次 | 01,02,03 | 同上(按年,单月上限 10 次) |
| `ACSY_JZDCBG001` | 尽职调查检测服务 | 28 | 尽职调查检测 |
| `ACSY_SSYHBG001` | 应享未享税收优惠合规检测 | 29 | 应享未享税收优惠合规检测 |
| `ACSY_HYZXDS001` | 电商合规检测服务 | 30 | 电商合规检测 |
| `ACSY_CSQJBG001` | 财税全景合规检测服务 | 31 | 财税全景合规检测 |
| `ACSY_CSZXBG001` | 专项检测报告 | 06 | 综合合规检测(演示版) |
| `ACSY_CSHYBG001` | 行业检测报告 | 18,19 | 制造业专项合规检测 |
> 以上仅为常见值参考,**以 `types` 命令的实际返回为准**(不同租户、不同订单差异很大)。
> `cpxdm` 一列由 `query-order` 返回的「产品线」字段直接给出,脚本会自动翻译成报告类型名。
### 网关侧前提
`cpfwbh` / `ddbh` 已作为 `riskdet-sms-code-send`、`riskdet-get-qrcode` 两个工具的
**可选 args**;网关模板写法为 `{{if .args.cpfwbh}}{{.args.cpfwbh}}{{else}}{{.config.cpfwbh}}{{end}}`
——即「args 优先,config 兜底」。若网关未同步此改动,传了 `cpfwbh` 也会被 config 常量覆盖,
表现为「无论选哪种类型,出来的报告都一样」。
### `cpxdm`(产品线)是什么,和 cpfwbh 什么关系
容易被混淆,这里说清楚:
| 概念 | 字段 | 含义 | 谁在决定 |
|------|------|------|----------|
| 检测类型 / 商品服务 | `cpfwDm`(= `cpfwbh`) | 用户买的具体 SKU,如「电商合规检测-10次」 | **决定生成哪一类报告**;平台 UI 上就是「所属服务」下拉 |
| 产品线 / 报告归类 | `cpxdm` | 该服务覆盖的报告类型编号,如 `01,02,03` | 用于**按类型过滤订单**(`queryOrderByFk/{cpxdm}`)与下游归类 |
- 一个 `cpfwbh` 可以覆盖多条产品线(`ACSY_2001` → `01,02,03`;通用版同时支持财税综合与财务)。
- 产品线代码有**自动组合**规则:`01→01,02`、`02→02,05`、`18→18,19`、`20→20,21`、`22→22,23`、`24→24,25`。
- **`cpxdm` 只是归类/过滤维度,不是「选哪种报告」的开关**:
MCP 走的 OpenAPI 通道(`/org/auth/riskDet/*`)入参 DTO 里**根本没有 `cpxdm` 字段**,
报告类型完全由 `cpfwbh` 决定。所以「让用户选检测类型」= **让用户选 `cpfwbh`**,无需也无法传 `cpxdm`。
- `query-order` 工具本身**支持 `cpxdm` 入参**(可逗号分隔,不传=全部),用于只想看某一类时收窄结果。
- `cpxdm` 的**中文名**由脚本内置表翻译(来源:前端 `monitor.js` 的 19 条配置 + 字典 `DM_FK_CPXDM`),
`types` 输出里的「报告类型」一行就是它;`cpxdms` 命令可单独列出全量。
- **想让检测接口也吃到 `cpxdm`?** 需要后端补 3 处小改动(约 5 行):
1. `AuthOrderLoginRequestDTO` / `AuthOrderQrcodeLoginRequestDTO` 各加 `private String cpxdm;`
2. `OrgAuthController.riskDetSmsCodeSend` / `riskDetQrcode` 里在调 `fqsqdl` 前加
`yfpGgywQySqReqDTO.setCpxdm(requestDTO.getCpxdm());`
(`YfpGgywSqDlReqDTO` 已有 `cpxdm` 字段,`fqsqdl` 也已会读它并透传给智搜)
3. 网关 `ggyw.yaml` 的两个工具 args 加 `cpxdm`,body 模板加 `"cpxdm": "{{.args.cpxdm}}"`
改完之后,本站即可与平台一样做到「报告类型」粒度(而不仅是「所属服务」粒度)。
### 与平台 Web UI 的对应关系
平台前端就是这样做「选检测类型」的,可对照理解(两个入口,同一个三级结构):
**入口 A:云小康 `<<<DEEP_CHECK 公司名>>>` → `fxjcDialog` → `fxjcsqPage?sqlx=04&footerIsShow=N`**
- 真身 = `znfk-fxmxgl-web/src/views/complianceInspectionListPage/conment/jclc.vue`(StepBar 流程壳),
`sqlx=04` ⇒ 步骤 `[数据授权, 报告生成]`
- **`footerIsShow=N` 时 `cpxdm` 被强制设为 `all`** —— 即云小康弹窗打开时**不按报告类型过滤**,展示全部可用服务
- 数据授权步骤 = `conment/sjsq.vue` → `conment/fxjcsq.vue`,就是那两个下拉:
- 「**所属订单**」`el-option :label="item.ddmc"` ← `queryOrderByFk/{cpxdm}` 的 `orderData[].ddmc`
- 「**所属服务**」`el-option :label="cpfwmc + '-可用剩余' + cpfwsykycs + '次'"` ← **这就是检测类型(cpfwbh)**
- 选订单 → `ssfwxx = 该订单.spfwList`;只有 1 项时自动选中;选服务 → `ssfwBm = cpfwDm`
- 提交时拼 `ssfwBm = ['fxgl_@_<ddbh>_@_<cpfwDm>']`,**与本站的 `cpfwbh` + `ddbh` 完全同构**
- 切换订单时 `handleSsddIdChange` 会清空 `cpfwdwUuid/ssfwBm/ssfwxx`,避免残留旧服务选择
**入口 B:检测历史列表「继续生成」弹窗(`complianceInspectionListPage/index.vue` 的 `openNext`)**
三级联动的标准实现,逐级接口:
1. **报告类型** `cpxdm` ← `GET /znfk/qyfxgl/saas/api/yqzk/asyncLogin/queryCpxdm`
(数据源 = 字典 `DM_FK_CPXDM`,返回 `[{CPXDM, CPXMC}]`)
2. **所属订单** `ssddId` ← `POST /znfk/qyfxgl/saas/yqzk/queryOrder` `{czrId, cpxdm}`
3. **所属服务** `cpfwDm` ← 订单的 `spfwList[].cpfwDm`,label 同上带「可用剩余N次」
> 这两个接口**不在 MCP 暴露面内**,skill 拿不到;所以本站用「`query-order` + 内置 cpxdm 名称表」等价替代。
> 侧边栏检测类型 tab 的映射见 `complianceInspectionListPage/monitor.js`(`default01..default19`),
> 条目里的 `bglx`(报告类型码)、`sqlx`(授权流程类型)、`cpxdm`(产品线码)三者在平台侧是绑定的。
### 「合并产品」展开机制(一个订单出现多种可选类型的原因)
后端 `YfpGgywCompanyInfoServiceImpl.queryOrderByFk()`(约 1630-1678 行):
- 请求**带了 `cpxdm`** → 只把服务的 `cpxdm` 覆盖成该值(`pInfo.setCpxdm(cpxdm)`),不展开;
- 请求**没带 `cpxdm`** 且服务带 `cpfwpzList`(产品配置)→ 触发**合并产品展开**:一个服务被拆成
多条可选服务,`cfPInfo.cpfwmc = cpfwpz.label`、`cfPInfo.cpxdm = cpfwpz.value`、
`cfPInfo.cpfwdwUuid = 原uuid + "_" + cpfwpz.value`。
这就是「一个订单底下有好几种可选检测类型」的来源。包年订单还会按已生成二维码记录做去重。
## 用户信息采集
用户发起检测后,先确定登录方式,再按分支采集信息。**只把真正缺失的信息**用 AskUserQuestion 卡片收集(已明确的直接采用,不要重复问),不要直接命令行传参:
0. **登录方式(用户没说明时才问)**:用户原话已含登录方式语义 → **直接采用,不提问**
(「扫码 / 二维码 / 用 APP 扫」→ 扫码登录;「账号密码 / 短信 / 验证码」→ 账号密码登录);
只有完全没提时才用 AskUserQuestion 弹选项。两种方式的差异:
- `账号密码登录`:走分支A(短信验证码),需采集全部企业信息(含账号/密码/手机号/身份类型)
- `扫码登录`:走分支B(电子税务局二维码),只需采集 nsrsbh/nsrmc/ssdq,**无需**账号、密码、手机号、身份类型(登录身份由扫码人在电子税务局 APP 上确认)
1. 枚举字段用选项:
- `sflx`(身份类型):FDDBR 法定代表人 / CWFZR 财务负责人 / BSY 办税员 / KPY 开票员
- `ssdq`(所属地区):**只能填省级码**(如 2100 辽宁省);⚠️ 填地级市码(如 2106 丹东市、2103 鞍山市)接口会直接返回 `9999` 系统异常,务必按下方「地区编码参考」表选取
2. 自由文本字段(nsrsbh 识别号、nsrmc 名称、gryhm 账号、gryhmm 密码、sjhm 手机号)
🔴 **检测对象必须经用户明确确认(硬规则,优先于「提问最小化」)**
- 发起检测前先跑一次 `info`(本来就要取 `userId`/`customerId`),并**把其中的「当前管理企业」
(`companyName` + `companyTaxNo`)作为候选 A 主动提示出来**——这是用户最可能想检测的对象,
主动摆出来能让用户点一下就走,不必手打企业名;
- 用户原话**已点名企业**(「检测 XX 公司」)→ 采用该企业,只补问缺的字段(税号 / 地区);
- 用户**没有点名企业**(只说「发起财税检测」「帮我检测一下」「做个检测」)→
**必须询问检测对象**,且**A / B 两个候选都要摆出来**(用 AskUserQuestion 弹卡片、或直接文字提问均可)。
这一问**不属于可省略的提问**,「提问最小化」条款对它**不适用**——缺了检测对象,整个检测就是无的放矢;
- 询问模板(一次问全,问完等回复):
> 请问本次要检测哪家企业?
> - **A. 当前管理企业**:XX有限公司(税号 91xxxxxxxxxxxxxxxx)—— 选它的话,请再补充所属地区(省级码,如 2100 辽宁省)
> - **B. 其他企业**:请提供 ① 企业名称 ② 纳税人识别号 ③ 所属地区(省级码)
>
> 另请告知登录方式:账号密码登录 / 扫码登录
- ✅ **提示 ≠ 拍板(边界必须守住)**:`companyName` / `companyTaxNo` 只能作为**候选之一**呈现,
**必须等用户明确选定(或口头确认)之后**,才能把它写进企业信息 JSON 的 `nsrmc` / `nsrsbh`
去调命令 `1` / `6`;**不得在用户回复前**就拿它发起检测,也不得把候选 A 写成「默认就是它」、
直接默认选中或替用户拍板。用户选定后,**复述一遍企业名称 + 税号**再继续;
- ⚠️ `info` **不返回所属地区**:无论用户选 A 还是 B,`ssdq` 都必须由用户给出(省级码);
- 若用户已给出企业名但未给税号 / 地区,只补问缺的那几项;
- 其余自由文本字段(账号 `gryhm` / 密码 `gryhmm` / 手机号 `sjhm`)引导用户用 Other 输入,
不要拆成一问一答。
> 脚本层已同步加硬拦截:命令 `1` / `6` 在缺 `nsrsbh` 或 `nsrmc` 时会直接报
> `[错误] 未明确指定检测对象…`。这正是「必须经用户确认」的落地保障——脚本**不会**自己
> 拿当前管理企业兜底。看到这个报错就说明该去问用户(把当前管理企业作为候选 A 一并列出),
> 用户确认后把 `nsrmc` / `nsrsbh` **显式写进企业信息 JSON** 再重试。
3. 一次弹窗最多 4 问,信息项多时拆成 2 次提问。
4. 调用 1.1(命令 `1`)后,按返回 code 分支处理:
- code = "0000":表示当前登录会话处于保活状态(当天该手机号已成功登录过),
**无需向用户索取短信验证码,也无需调用 1.2**,直接进入 1.3 查询授权状态。
- code = "1010":验证码已发送成功,需提示用户输入收到的验证码,再调用 1.2 登录。
- code = "1009"/"1008":登录失败,需重新采集账号、密码、手机号。
5. 一般情况下gryhmm 密码与sjhm 手机号不一致。
6. 如果密码或者验证码错误,需要重新采集gryhm 账号、gryhmm 密码、sjhm 手机号。
7. 报告轮询:登录成功后自动开始(命令 `3` 分段前台循环,每轮 `30 240`),无需询问用户;期间每轮输出一次进度,报告生成即输出结果。**不得用 AskUserQuestion 打断询问是否等待**。
8. 更换不同身份类型需要重新采集gryhm 账号、gryhmm 密码、sjhm 手机号。
9. **扫码登录分支**:命令 `6`(前台几秒)→**立即**把 stdout 里 `[WIDGET_BEGIN]…[WIDGET_END]` 之间的片段原样传给 `show_widget` 内联渲染(二维码已重编码为小体积数据内嵌,卡片自带「有效期 3 分钟」说明;**不要**改成展示文件路径,那会跑到右侧面板)→命令 `7` **前台阻塞**等待扫码结果(Bash timeout≥300000ms,**严禁 run_in_background**,否则用户收不到提醒)→返回后输出 `notify` 文案(在所有二维码卡片之后):成功→同回合立即按分段规则轮询报告(命令 `3` 每轮 `30 240`);expired/wait→输出过期提示后**结束流程等待用户指令,严禁自动重新取码换新码**(用户回复「重新生成二维码」等才重新开始);fail→反馈原因并等待用户决定。**严禁拿到结果后静默不报**。
### 基础信息(1.1接口必需)
| 参数 | 说明 | 是否必传 | 备注 |
|------|------|----------|------|
| ddbh | 订单编号 | 是 | 由 `query-order` 自动取(或 config 兜底);指定 `cpfwbh` 时脚本自动配对 |
| cpfwbh | 产品服务编号(**= 检测类型**) | 是 | **用户在 Step 0 选定,显式传入优先**;未传才由 `query-order` 兜底 |
| nsrsbh | 纳税人识别号 | 是 | 企业唯一标识 |
| nsrmc | 纳税人名称 | 是 | 企业全称 |
| ssdq | 所属地区 | 是 | 见下方地区编码表 |
| customerId | 客户ID | 是 | 由 `sys-user-info` 的 zhid 自动取 |
| userId | 用户ID | 是 | 由 `sys-user-info` 自动取 |
| gryhm | 用户名 | 是 | 税务登录用户名(身份证/手机号/用户名) |
| gryhmm | 密码 | 是 | 税务登录密码 |
| sflx | 身份类型 | 是 | FDDBR/CWFZR/BSY/KPY/DLJG |
| sjhm | 手机号 | 是 | 接收短信的手机号 |
| qdbm | 渠道编码 | 是 | 默认 1033 |
| sqInfo | 授权协议 | 是 | 脚本内置,后端仅校验非空 |
| dljgsh | 代理机构税号 | 否 | sflx=DLJG时必传 |
| dlNsrxxList | 被代理纳税信息列表 | 否 | sflx=DLJG且多户企业时使用 |
### 短信验证码(1.2接口必需)
| 参数 | 说明 | 来源 |
|------|------|------|
| taskId | 任务ID | 1.1接口返回 |
| smsCode | 短信验证码 | 用户收到短信后输入 |
### 扫码登录(2.1 / 2.2接口,分支B专用)
**2.1 获取电局登录二维码**(ddbh/cpfwbh/customerId/userId/qdbm/sqInfo 由脚本经 MCP 自动填充,只需向用户采集以下3项):
| 参数 | 说明 | 是否必传 | 备注 |
|------|------|----------|------|
| nsrsbh | 纳税人识别号 | 是 | 企业唯一标识 |
| nsrmc | 纳税人名称 | 是 | 企业全称 |
| ssdq | 所属地区 | 是 | 见下方地区编码表 |
2.1 返回:`taskId`(供2.2使用)、`ywjcjlbh`、二维码。命令 `6` 会把二维码落盘为
`logs/qrcode_live_<时间戳>.png` 并输出内联卡片片段。**展示方式见「宿主适配」章节**
**2.2 扫码状态查询**:
- **路径 A(脚本可用)**:脚本命令 `7` 内部轮询(间隔 3 秒),**不需要助手逐次调用**;
- **路径 B(脚本无令牌、用 MCP 工具取码)**:⚠️ **必须由助手自己调 `riskdet-scan-code` 逐次轮询**
(间隔 3 秒)。此时命令 `7` 根本没在跑,若助手据此不轮询,就会出现
「用户扫码成功但对话毫无反应」。详见下方「Step 1-QR」。
### 付费报告参数(1.4接口必需)
| 参数 | 说明 | 是否必传 |
|------|------|----------|
| zeroOrderNo | 免费订单编号 | 是 |
| chargeOrderNo | 付费订单编号 | 是 |
| zeroYwjcjlbh | 免费业务检测记录编号 | 是 |
| contractId | 付费合同ID | 是 |
| productId | 付费商品ID | 是(可用 config 兜底) |
| productAttrUnique | 商品规格ID | 是(可用 config 兜底) |
### 地区编码参考
⚠️ **规则(实测确认)**:`ssdq` 只接受**省级码**(`XX00`)以及少数**计划单列市码**(下表里已列出的 2102 大连 / 3302 宁波 / 3502 厦门 / 3702 青岛 / 4403 深圳)。**填其他地级市码(如 2106 丹东市、2103 鞍山市)接口会返回 `9999` 系统异常,且 `msg` 为 null,看不出原因**——辽宁一律用 `2100`。
常用地区编码:
- 1100: 北京市 1200: 天津市 1300: 河北省 1400: 山西省 1500: 内蒙古
- 2100: 辽宁省 2102: 大连市 2200: 吉林省 2300: 黑龙江省
- 3100: 上海市 3200: 江苏省 3300: 浙江省 3302: 宁波市 3400: 安徽省
- 3500: 福建省 3502: 厦门市 3600: 江西省 3700: 山东省 3702: 青岛市
- 4100: 河南省 4200: 湖北省 4300: 湖南省 4400: 广东省 4403: 深圳市
- 4500: 广西 4600: 海南省 5000: 重庆市 5100: 四川省 5200: 贵州省
- 5300: 云南省 5400: 西藏 6100: 陕西省 6200: 甘肃省 6300: 青海省
- 6400: 宁夏 6500: 新疆
### 身份类型枚举
- `FDDBR`: 法定代表人 `CWFZR`: 财务负责人 `BSY`: 办税员 `KPY`: 开票员 `DLJG`: 代理机构
## 执行流程
### Step 0: 确定检测类型 + 检测对象 + 登录方式(能直选就直选,别问)
> 🔴 **提问是最贵的交互**。凡是能从**用户原话**里读出来的(检测类型、登录方式),
> 一律**直接采用 + 一句话告知**,不要弹选项卡二次确认。
> 只有用户真的没说、或存在真实歧义时才问。**用户已经表达过的信息绝不再问第二遍。**
>
> ⚠️ **唯一例外:检测对象必须经用户确认**。用户没说测哪家企业时,**必须问**——
> 但问的时候要把 `info`(`sys-user-info`)带来的「当前管理企业」(`companyName` / `companyTaxNo`)
> **作为候选 A 主动提示出来**,让用户在「当前管理企业」和「其他企业」之间选;
> 它是**候选**、不是**默认值**:必须等用户选定后才能发起,不得未经确认直接拿它去检测
> (详见「用户信息采集」第 2 条)。
**① 确定检测类型**(见上方「检测类型选择」章节,核心是「先看用户原话,能定就别问」)
```bash
python scripts/mcp_gateway_client.py types # 必须:拿可用清单 + 校验剩余次数
python scripts/mcp_gateway_client.py types <czrId> 02 # 可选:按报告类型收窄(对齐平台三级联动)
```
- 用户原话含类型语义(「发起**财税**检测」「查**发票穿透**」「做个**尽调**」「**免费**体验一下」)
→ **按别名表直选,绝不提问**,只回一行「本次将使用:XXX」;
- 完全没有类型语义(只有「检测 / 查一下 / 发起检测」)→ 这时才用 AskUserQuestion
(类型的**中文名**作选项 label,`cpfwDm` / 报告类型 / 有效期放进 description);
- 可用清单只有 1 条 → 直接采用,告知「本次将使用:XXX」;
- 命中的类型不可用(未购买 / 剩余 0 次)→ 说明原因,再让用户在**可用清单**里改选;
- 用户点名**报告类型**(如「财税综合合规检测」)→ 先 `cpxdms` 拿 `cpxdm`,再 `types <czrId> <cpxdm>`
收窄——**这就是平台「继续生成」弹窗的三级联动顺序**。
- 记住选中的 `cpfwbh`,后续所有步骤都带上它。
**② 确定检测对象(必问项,除非用户原话已点名企业)**
- 用户原话已点名企业 → 采用,缺税号 / 地区就补问;
- 用户没点名企业 → **问**(AskUserQuestion 或文字提问均可),并**必须把 `info` 带回的
「当前管理企业」作为候选 A 提示出来**,候选 B 为「其他企业(用户自填)」。建议这样组织:
| 问题 | 选项 |
|------|------|
| 本次检测对象 | `当前管理企业:<companyName>(税号 <companyTaxNo>)` / `其他企业(我来提供)` |
选「其他企业」→ 请用户给出 ① 企业名称 ② 纳税人识别号 ③ 所属地区(省级码);
- ⚠️ **无论选 A 还是 B,所属地区 `ssdq` 都必须问**(`info` 不返回地区);
- ⛔ **提示 ≠ 拍板**:`companyName` / `companyTaxNo` 只能作为**候选**呈现,
**必须等用户明确选定后**才能写进企业信息 JSON 发起检测;不得在用户回复前直接调用命令 `1` / `6`,
也不得把候选 A 设成「默认选中」。用户选定后**复述一遍企业名称 + 税号**再继续。
**③ 确定登录方式**:用户已说明则直选(「扫码 / 二维码 / APP」→ 扫码登录;「账号密码 / 短信 / 验证码」→ 账号密码登录);
没说才用 AskUserQuestion(`账号密码登录` / `扫码登录`)。然后按所选分支采集信息并登录:
- **账号密码登录** → 按 Step 1 → Step 2 执行
- **扫码登录** → 按 Step 1-QR(命令 `6` + 命令 `7` 前台组合)执行
两个分支登录成功后均进入 Step 3(1.3 查询授权状态),后续流程完全一致。
> 企业信息 JSON 中务必带上 Step 0 选定的 `cpfwbh`,否则脚本会走默认兜底类型;
> 同时**必须带上用户确认过的 `nsrsbh` / `nsrmc` / `ssdq`**——脚本已加硬拦截,
> 缺 `nsrsbh` 或 `nsrmc` 时会报 `未明确指定检测对象` 并中止,**不再**用当前管理企业兜底。
### Step 1-QR: 扫码登录
> 🔴 **取码之后必须有轮询,否则用户扫码成功也没人知道。**
> 这是本技能最容易出问题的地方:二维码展示完就结束回合 → 助手停下等待 →
> 用户扫码成功但对话毫无反应,只能主动追问才会去查。**任何情况下都不能只取码不轮询。**
先决定走哪条路径(见上方「首次使用与鉴权」):
| 路径 | 适用 | 取码 | 谁负责轮询 |
|------|------|------|-----------|
| **A. 脚本路径** | 脚本有令牌(`info` 返回用户信息) | 命令 `6` | 命令 `7` 前台阻塞,**助手不用自己调** |
| **B. 纯 MCP 工具路径** | 脚本无令牌(新装、新电脑最常见) | MCP 工具 `riskdet-get-qrcode` | **助手自己调 `riskdet-scan-code` 轮询** |
#### 路径 B:纯 MCP 工具扫码(脚本无令牌时走这条)
1. 调 MCP 工具 **`riskdet-get-qrcode`** 取码(参数取齐见「参数复用策略」),拿到 `taskId`、`ywjcjlbh` 与二维码;
2. 展示二维码(见「宿主适配」章节,**务必先做下方的「二维码体检」**),提示用户「请用电子税务局 APP 扫码,扫码后我会自动继续」;
3. **立刻在同一回合内开始轮询** MCP 工具 **`riskdet-scan-code`**(入参 `taskId` **和** `nsrsbh` 两个都要),**间隔约 3 秒**:
- `code=0000` 且返回 `nsrsbh`/`ywjcjlbh` → **授权成功**:立即告知用户,并**同一回合内**接着按 Step 3 查报告;
- `code=1011` → 用户尚未扫码,**继续轮询**,不要停下、不要结束回合;
- `code=1010` → **会话终结**(既非成功也非失败):立即调 **1.3 `riskdet-query-status`** 交叉确认——
若返回了新的 `uuid`,**判定授权成功**;否则视为二维码已过期,重新取码。
⚠️ **不要对 1010 继续轮询**,那会永远轮下去;
- `code=9999` → 任务 ID 失效,需重新调 `riskdet-get-qrcode` 取新码;
- `1006` / `1008` / `500` → 授权失败,告知原因并等待用户决定。
4. ⚠️ **不要**把轮询丢给用户(「您扫好了告诉我」)——扫码后用户不会主动说话,
必须由助手持续轮询直到出现终态。
5. 🛑 **无限轮询保护**:轮询**上限 240 秒**。若超时仍只有 `1011`,
**必须停止并明确告知用户**「未检测到扫码结果,二维码可能已失效」,再询问是否重新取码。
**绝不允许无休止地一直轮询**——用户看到的「一直在轮询但识别不到成功」就是漏了这条。
重取码时**必须先确认新二维码体检通过**,否则会陷入同样的死循环。
##### 二维码体检(取码后、展示前必做)
🔴 **坏二维码是「扫码成功却识别不到」的头号原因**:用户用 APP 扫了一张损坏的图,
APP 可能提示成功,但后端永远收不到授权,于是 `scan-code` 一直返回 `1011`。
网关返回两种形态,**可靠性天差地别**:
| 形态 | 特征 | 可靠性 |
|------|------|--------|
| **blob 引用** ✅ | 响应里是 `image_blob_ref`,带 `blob_path`(本地路径) | **可靠**:路径短,直接跑 `qr "blob:<路径>"` |
| **data URI** ⚠️ | 响应里是 `data:image/png;base64,…`(约 2 KB) | **极易损坏**:实测网关生成的真实二维码 PNG 为 1530~1560 字节,转抄后只剩约 1011 字节(丢约三分之一),`IDAT` 解压失败 |
**处理规则**:
1. 拿到 **blob 路径** → 直接用 `python scripts/mcp_gateway_client.py qr "blob:<路径>" <企业名> <税号>`,零鉴权、可靠;
2. 拿到 **data URI** → 写入文件后跑上面的 `qr "@<文件>"`,**看退出码**:
- `0` → 渲染成功,可以展示;
- `4` → **图片已损坏,禁止展示**。改为**重新调 `riskdet-get-qrcode` 再取一次**
(可能拿到 blob 形态),最多重试 3 次;始终拿不到可用图片就如实告诉用户,
**不要**把损坏的图塞进 `show_widget` 蒙混过关。
3. **根治建议**:请网关把 `riskdet-get-qrcode` 改为**固定返回 blob 引用或 MCP `image` 内容块**,
彻底消灭 data URI 形态。
#### 路径 A:脚本路径(命令6 + 命令7 前台组合)
流程 = **命令6(前台,几秒返回)→ 展示二维码 → 命令7(前台阻塞等待结果)→ 拿到结果立即告知用户**。
```json
// 企业信息JSON(userId/customerId/ddbh/cpfwbh/qdbm/sqInfo 由脚本经 MCP 自动补齐)
{ "nsrsbh": "91330602***********", "nsrmc": "XXXXXXXXXXXXXXXXXX", "ssdq": "3300" }
```
**第一段:命令6 启动扫码守护(前台运行,几秒即回)**
命令:`python scripts/mcp_gateway_client.py 6 '<企业信息JSON>' [守护最大等待秒=240]`
命令6 会:经 MCP 调 2.1 取码 → 落盘 PNG → 输出内联卡片片段(`[WIDGET_BEGIN]`/`[WIDGET_END]` 之间)
→ 拉起**分离守护进程**(独立存活,负责轮询 2.2 + 1010 交叉确认,终态写 `logs/scan_result.json`)
→ 几秒内自身返回。返回 `data` 含 `taskId`、`ywjcjlbh`、`qrcode_png`、`qrcode_widget_ready`。此时:
1. **第一时间**展示二维码:**WorkBuddy 用 `show_widget` 内联渲染**,`widget_code` 直接填 stdout 里
`[WIDGET_BEGIN]`…`[WIDGET_END]` 之间的内容,**原样透传、一个字符都不要改**;**不要**改用
`present_files`,也不要自己拼 HTML。若宿主没有 `show_widget` 或片段为空
(`qrcode_widget_ready=false`),再按「宿主适配」章节降级。**中间不做任何校验、探活等拖延操作,二维码有效期从取码即开始计算**;
2. 提示「请使用电子税务局 APP 扫码(有效期约3分钟),扫码后我会自动继续」。
**第二段:命令7 前台等待扫码结果(严禁后台运行!)**
命令:`python scripts/mcp_gateway_client.py 7 [最大等待秒=240]`(Bash 工具 timeout 参数须设 **300000** 毫秒以上)
命令7 **前台阻塞**读取守护进程结果,直到出现终态或超时。⚠️ **必须前台运行、不得 run_in_background**——后台任务在回合结束后无法触发新对话轮次,用户将收不到任何提醒。
**命令7 返回后的处置(拿到结果必须立即在聊天中告知用户,严禁静默)**:
⚠️ **输出位置规则**:**扫码结果提示(✅/⚠️/❌ notify 文案)必须出现在所有二维码卡片之后**。
命令7 返回的 JSON 含现成的 `notify` 字段,输出该文案:
- `code=0000`(含 `data.ywjcjlbh`):输出 notify 后,**同一回合内立即按 Step 3 的分段轮询规则开始查报告**——严禁输出成功提示后就结束回合;
- `code=expired` 或 `code=wait`:输出 notify 后**结束流程,等待用户指令**。**不要自动重新取码**——只有当用户主动回复(如「重新生成二维码」)时,才重新从第一段(命令6)开始;
- `code=fail`:输出 notify(含原因),等待用户决定重新采集信息或换登录方式。
### Step 1: 收集基础信息并发送短信(账号密码登录分支)
命令:`python scripts/mcp_gateway_client.py 1 '<企业信息JSON>'`(MCP `riskdet-sms-code-send`)
```json
// 企业信息JSON 示例
{ "nsrsbh": "91330602***********", "nsrmc": "XXXXXXXXXXXXXXXXXX", "ssdq": "3300",
"gryhm": "136****8895", "gryhmm": "********", "sflx": "FDDBR", "sjhm": "136****8895" }
```
成功后返回 `taskId` 与 `mobile`(userId/customerId/ddbh/cpfwbh 由脚本自动补齐)。
### Step 2: 上传短信验证码并登录(账号密码登录分支)
命令:`python scripts/mcp_gateway_client.py 2 <nsrsbh> <taskId> <smsCode>`
### Step 3: 查询授权状态及报告(分段前台轮询,助手全程守着)
**任一登录分支成功后必须在同一回合内立即执行本步骤**。调用 1.3(MCP `riskdet-query-status`)。**报告一般约 10 分钟生成**。
⚠️ **分段轮询规则(必须遵守,否则 Bash 工具 600 秒超时上限会导致整段命令失败)**:
**禁止**一次性执行默认参数的命令 3(1200 秒超上限);必须用短超时分段循环:
```
每轮:python scripts/mcp_gateway_client.py 3 <nsrsbh> 30 240 (前台,timeout 设 300000ms,单轮约4分钟)
```
每轮返回后检查结果(脚本会在 stdout 末尾打印 `[结论]` 便于判断):
- **报告已生成**(`reportUrl` / `reportUrl_list` 里有**非空白**地址)→ **立即输出最终结果**,流程结束;随后用返回的 `uuid`(= `ywjcjlbh`)执行命令 `5` 取概览;
> 判定已做空值加固:网关模板在报告未生成时仍可能渲染出 `- **reportUrl_list**:` 这样的**空值行**,
> 脚本会逐项 `strip()` 后再判断,不会把空地址误判成「已生成」(此坑由新用户全流程模拟发现)。
- **`cjStatus == 3`** → 数据采集失败(死路),立即终止并把 `fail_reason` 告知用户;
- **仍在生成中** → 不结束回合,紧接着执行下一轮,**每轮之间在聊天中输出一句进度**(如「已等待 4 分钟,报告生成中,请稍候…」);
- **累计约 5 轮(约 20 分钟)仍未生成** → 停止轮询,告知用户当前状态和稍后查询方式。
### Step 4: 申请付费报告(可选)
命令:`python scripts/mcp_gateway_client.py 4 <nsrsbh> <zeroOrderNo> <chargeOrderNo> <zeroYwjcjlbh> <contractId> [productId] [productAttrUnique]`
成功后**顶层返回 `ywjcjlbh`(新生成的付费业务检测记录编号)**,供 1.5 使用。
### Step 5: 获取风险检测概览
命令:`python scripts/mcp_gateway_client.py 5 <nsrsbh> <ywjcjlbh>`
返回高风险数、中风险数、低风险数、风险总数、数据采集评级、检测时间与风险概述文案。
## 错误处理
常见错误码:
- `0000`: 成功/短信登录保活中
- `0` / `200`: 成功
- `1006`: 授权失败
- `1008`: 用户信息错误
- `1009`: 短信发送或登录失败
- `1010`: 短信验证码发送成功/登录失败(扫码分支下表示二维码会话已终结)
- `1011`: 用户尚未完成扫码,继续轮询
- `9999` / `500`: 系统异常
网关层错误:
- `401 账号未登录`:网关转发到 yfp-ggyw 服务时缺少登录态(网关侧需补映射);
- `JSON-RPC 错误:unknown tool: xxx`:该工具尚未在网关配置里启用,需补 `tools` 与 `allowTools`。
脚本层业务校验错误(非网关故障):
- `[错误] 当前账号没有可用的检测类型 'xxx'(未购买 / 剩余次数为 0 / 编码有误)`
→ 用户点名的检测类型**不在本账号可用清单**里。**把紧随其后打印的可用清单交给用户改选**,
换成清单里的 `cpfwDm` 后重试。不要重试同一编码,也不要自行替换成别的类型。
- `[警告] 未取到可用检测类型清单,跳过配对校验,直接使用 cpfwbh=xxx`
→ `query-order` 这次没返回数据(网络/网关抖动)。此时**没有做配对校验**,属于降级放行;
若后续 1.1 / 2.1 返回异常,优先怀疑是类型与订单不匹配。
遇到错误时,根据 `msg` 字段的具体描述向用户反馈,必要时联系云企技术支持。
## 注意事项
1. **严格遵循调用顺序**:不得跳过任何步骤或乱序调用
2. **参数复用**:已采集的参数在后续接口中自动复用
3. **敏感信息保护**:密码、协议等敏感信息需安全传输
4. **地区编码准确性**:`ssdq` 只用省级码 / 表内计划单列市码;填地级市码会导致 2.1 返回 `9999`。辽宁一律 `2100`
5. **代理机构特殊处理**:当`sflx=DLJG`时,必须传入`dljgsh`和`dlNsrxxList`
6. **报告等待时间**:1.3 报告一般约 10 分钟生成;用命令 `3` 分段前台轮询(每轮约4分钟、30秒间隔,累计约20分钟),全程输出进度
7. **配置维护**:网关配置统一在 `config/mcp.ini`(已被 `.gitignore` 忽略,脱敏模板见 `config/mcp.example.md`);企业信息通过命令行传入;接口与工具映射见 `scripts/云企智控MCP对接说明.md`
8. **信息过滤**:思考信息、运行过程信息不做展示,只展示结果信息以及异常信息以及需要用户输入的提示信息
9. **运行日志**:脚本每次 MCP 调用都会把入参(已脱敏/截断)与响应写入 `logs/YYYY-MM-DD.log`。`logs/` 已被 `.gitignore` 忽略
10. **扫码登录二维码时效**:二维码一般几分钟内有效,命令7 轮询满上限未完成授权即停止;过期后须重新执行命令6 获取新码,勿用旧 `taskId` 反复查询
11. **首次运行前的环境自检**:
- `logs/` 目录可能不存在(技能包默认不含空目录),命令6 会因 `FileNotFoundError` 崩溃。**首次运行前先 `mkdir -p <技能目录>/logs`**。
- **本版本无需 `gmssl`、无需 AK/SK**:脚本只用 Python 3 标准库。
- 网关要求鉴权时,在 `config/mcp.ini` 填 `access_token`,或用环境变量 `DKI_MCP_TOKEN` 传。
- Windows 运行时给命令加 `PYTHONUTF8=1 PYTHONIOENCODING=utf-8`,避免中文企业名(nsrmc)在命令行传参时乱码。
12. 🔴 **提问最小化(不得违反)**:
- 用户原话已含**检测类型语义**(「财税检测 / 税务风险 / 尽调 / 发票穿透 / 免费体验…」)→ **直选,不得再弹类型选项**;
- 用户原话已含**登录方式**(「扫码 / 账号密码 / 短信」)→ **直选,不得再问登录方式**;
- 判定「是否要问」的唯一标准:**该信息是否已从用户原话 / 接口返回 / 上下文中获得**。已获得就绝不重复询问。
- 只有**真的没说过且无法推断**时才用 AskUserQuestion,且一次问全(最多 4 问),不要拆成一问一答。
- ⚠️ **例外:检测对象必须经用户确认**。`info` 带回的**当前管理企业**(companyName / companyTaxNo)
要**主动提示给用户**(作为候选 A,方便用户直接选,省去手打企业名),但它**不属于**
「已获得的信息」——它只说明这个账号当前管着哪家企业,**不等于**用户本次要检测它。
用户没点名企业时,问的同时把这家企业摆出来让用户在「它 / 其他企业」之间选;
**未经用户选定,严禁**直接取它发起检测(提示是鼓励的,替用户拍板是禁止的)。判定标准:**用户有没有确认过**。
## 输出格式
最终输出应包含:
- 风险检测概览(高风险数、中风险数、低风险数、风险总数)
- 检测报告下载地址列表
- 检测时间
- 风险提示建议
## 示例对话
**场景 A:用户已指明类型 → 直选,不提问(默认路径)**
**用户**: 发起财税检测
**助手**: [跑 `types` 拿清单,匹配到「财税」→ 直选,**不弹类型选项**]
本次将使用「财税合规检测通用版」(剩余 24 次,有效期至 2026-12-31)。如需改用其他类型,直接说即可。
还需要确认两件事(一次问全)[AskUserQuestion]
- 检测对象:`当前管理企业:辽宁成润建科建设工程有限公司(税号 912101000647448425)` / `其他企业(我来提供)`
- 登录方式:`账号密码登录(需电子税务局账号/密码/手机号)` / `扫码登录(用电子税务局 APP 扫码)`
> 💡 这里**主动把账号的「当前管理企业」摆出来当候选 A**([跑 `info` 拿到的 companyName / companyTaxNo]),
> 用户点一下就能选,比手打企业名省事得多;但它**只是候选**——用户没选定之前,绝不拿它去发起检测。
> ⚠️ 地区(`ssdq`)不在 `info` 返回里,用户选定企业后仍须补问省级码。
**用户**: 扫码登录;就检测当前管理企业,地区 2100
**助手**: 确认一下:企业「辽宁成润建科建设工程有限公司」(税号 912101000647448425),所属地区 2100。
[确认后把 nsrsbh / nsrmc / ssdq,连同 Step 0 选定的 cpfwbh 一起放进企业信息 JSON,命令6 经 MCP 取码]
**助手**: [内联展示二维码卡片] 请打开「电子税务局」APP 扫描二维码并确认授权(有效期约3分钟)。[随后**前台**运行命令7阻塞等待扫码结果]
**助手**: ✅ 扫码授权成功!检测流程已自动继续,正在查询报告生成状态(预计约10分钟)
[同一回合内按分段规则前台轮询命令3(每轮 `30 240`)]
**助手**: 检测完成!该企业共发现 16 项风险点:
- 高风险:4项 中风险:5项 低风险:7项
检测报告已生成,下载地址:[链接列表]
建议按照指标应对建议进行改进完善,并定期体检。
如需深度分析(异常明细 + 政策依据 + 整改方案),可申请付费深度检测(官网 lxyq.cssyq.com.cn / 服务热线 400-005-1670)。
---
**场景 B:用户完全没提类型 → 这时才问**
**用户**: 帮我检测一下 XX 企业
**助手**: [跑 `types` 后,原话里没有任何类型语义(只有泛化的「检测」)→ 用 AskUserQuestion]
您当前有 3 种可用的检测类型,请选择:
- 财税合规检测通用版(税务+财务)— 剩余 24 次|有效期至 2026-12-31
- 应享未享税收优惠合规检测 — 剩余 5 次|有效期至 2027-06-17
- 新用户免费体验版 — 剩余 1 次|有效期至 2027-08-12
[用户选定后按场景 A 的后续步骤继续]
---
⚠️ **反例 1(检测类型,不要这样做)**:
**用户**: 发起财税检测
**助手**: ❌ 您当前有 6 种可用的检测类型,请选择:1. 发票穿透… 2. 供应商… 3. 贷前… 4. 财税合规检测通用版…
> 用户已经把类型说清楚了(「财税」),再问一遍纯属浪费用户的一次交互。
> 正确做法是直选 + 一行告知,把提问额度留给真正缺失的信息(如登录方式、企业信息)。
---
⚠️ **反例 2(检测对象:可以提示,但不能替用户拍板)**:
**用户**: 发起财税检测
**助手**: ❌ 本次将检测「辽宁成润建科建设工程有限公司」(税号 912101000647448425),请问使用哪种登录方式?
> 错在**用户还没确认**,就直接把这家企业当成了检测对象。它只是这个账号的「当前管理企业」——
> 只能说明账号名下有它,**不能推导出**用户本次要检测它。**未经确认就发起 = 替用户做决定**,
> 属于**检测对象越权**。
>
> ✅ 正确做法:**提示出来、让用户选**——
>
> **助手**: [跑 `types` + `info`]
> 本次将使用「财税合规检测通用版」(剩余 24 次,有效期至 2026-12-31)。
>
> 请问本次要检测哪家企业?
> - A. 当前管理企业:辽宁成润建科建设工程有限公司(税号 912101000647448425)
> - B. 其他企业:请提供 企业名称 / 纳税人识别号 / 所属地区(省级码)
>
> 另请告知登录方式:账号密码登录 / 扫码登录。
>
> 差别只有一点:**把候选摆出来**(帮用户省事 → 鼓励)vs **替用户拍板**(越权 → 禁止)。
Files in this skill
- SKILL.md
- config/mcp.example.md
- config/mcp.ini
- scripts/mcp_gateway_client.py
- scripts/oauth_login.py
- scripts/云企智控MCP对接说明.md
Attribution
Related skills
View all in business →Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.