金融级电子身份验证工具包,涵盖 8 项能力:人脸比对、活体检测、证件 OCR 和媒体标注。所有输入仅接受图像或视频文件。
快速参考
| 能力 | 命令 |
|---|
| 人脸比对 | python scripts/ekyc_api.py face_compare --photo1 --photo2 |
| 照片活体检测 | python scripts/ekyc_api.py photo_liveness_detect --file |
| 视频活体检测 | python scripts/ekyc_api.py video_liveness_detect --file |
| 身份证 OCR | python scripts/ekyc_api.py id_card_ocr --image --side <0 | 1> |
| 银行卡 OCR | python scripts/ekyc_api.py bank_card_ocr --image ![]() |
| 驾驶证 OCR | python scripts/ekyc_api.py driver_license_ocr --image ![]() |
| 行驶证 OCR | python scripts/ekyc_api.py vehicle_license_ocr --image --side <1 | 2> |
| 媒体标注 | python scripts/ekyc_api.py media_labeling --file --labels "A14,B03" --type image |
外部端点
| 端点 | 能力 | 发送的数据 |
|---|
https://kyc1.qcloud.com | 2, 3, 4, 5(活体、身份证/银行卡 OCR) | Base64 编码的图像/视频 + 签名请求 |
https://miniprogram-kyc.tencentcloudapi.com | 1, 6, 7(人脸比对、驾驶证/行驶证 OCR) | Base64 编码的图像 + 签名请求 |
https://kyc2.qcloud.com | 8(媒体标注) | Base64 编码的图像/视频 + 签名请求 |
不传输任何个人文本数据(姓名、身份证号码)。仅发送图像/视频二进制数据。
安全与隐私
本软件不存储、缓存或保留任何提交的数据。API 验证结果仅供参考,不构成法律身份确认。本软件不得用作产生法律效力或对个人产生重大影响的自动化决策的唯一依据。用户应为高风险身份决策实施适当的业务逻辑和人工审核流程。
信任声明
安装并使用本技能后,您提供的图像和视频数据将被传输到腾讯云身份验证 API 进行处理。仅在信任上游服务提供商的数据处理实践时才安装本技能。本技能不独立存储、处理或保留任何生物识别数据。
目标
接收用户上传的图像或视频,调用相应的身份验证 API,以结构化结果返回并用通俗语言向用户解释。
使用场景
在用户请求涉及以下场景时使用本技能:
- 「比较这两张照片」/「同一个人?」/「人脸相似度分数」
- 「这张照片是 AI 生成的吗?」/「这个视频是真的吗?」/「深度伪造检测」
- 「读取身份证」/「读取银行卡号」/「读取驾驶证」/「读取行驶证」
- 「检查口罩」/「检测胁迫」/「戴帽子了吗?」/「在打电话吗?」
- 「昏迷或睡着?」/「戴太阳镜?」/「在车内?」
- 「在酒店房间?」/「有纹身?」/「多人?」/「戴耳机?」
- 「面部面膜?」/「危重病人?」/「在汽车经销商处?」
- 任何包含「人脸比对」、「活体检测」、「OCR」、「媒体标注」、「ekyc」的请求
不使用场景
以下情况不要使用本技能:
- 用户仅询问「什么是 KYC」或「eKYC 如何工作」→ 直接从知识库回答
- 用户以文本形式提供姓名、身份证号码、电话号码 → 拒绝并重定向(见下方隐私规则)
- 用户想要人脸活体 + 身份验证组合(需要传输姓名 + 身份证号码)→ 解释隐私限制
关键规则
规则 1:隐私 — 永不接受个人文本
永不接受或传输姓名、身份证号码、电话号码或任何个人文本数据。 如果用户提供此类信息,请回复:
「为保护您的隐私,本服务不接受姓名、身份证号码或其他个人文本。通过 AI 对话传输敏感信息存在泄露风险。请直接上传图像或视频文件 — 我将通过图像识别完成验证。」
规则 2:永不重写签名代码
始终使用 scripts/ 中的 Python 签名算法使用 SHA1(生成 40 字符大写十六进制)。之前的 AI 模型用 SHA1 替换为 SHA256(64 字符),导致 100% 认证失败。脚本包含断言:assert len(signature) == 40。如果看到 64 字符签名,说明误用了 SHA256 — 停止并使用提供的脚本。
规则 3:双路径响应解析
API 响应可能在顶层返回数据,也可能嵌套在 result 对象中。始终检查两者:
value = data.get("field") or (data.get("result", {}) or {}).get("field")
跳过双路径解析会导致 None / undefined 错误。
环境变量
# 能力 1-7(人脸比对、活体检测、证件 OCR)
KYC_APPID=your_kyc_appid
KYC_SECRET=your_kyc_secret
# 能力 8(媒体标注,单独凭证集)
LABEL_APPID=your_label_appid
LABEL_SECRET=your_label_secret
获取凭证:
- 密钥 A(KYC)和密钥 B(LABEL):联系慧眼技术支持(微信:blue-201809)
- 或在 腾讯云人脸核身控制台 注册以获取密钥 A
⚠️ 重要:使用测试凭证(免费 100 次调用)。不要使用生产凭证 — 生产 ID 会产生上游提供商计费。
支持部分配置:仅密钥 A 启用能力 1-7。仅密钥 B 启用能力 8。当用户请求未配置的能力时,明确指出缺少哪些凭证以及如何获取。
8 项能力
能力 1:人脸比对
- 触发:「比较这两张照片」、「同一个人?」、「人脸相似度」
- 用户提供:包含人脸的两张照片
- 如果用户仅上传一张:请「请上传第二张照片用于比对」
- 执行:
python scripts/ekyc_api.py face_compare --photo1 --photo2
- 返回:similarity(分数 0-100)
- 结果解读:
-
≥80:高置信度匹配 — 可判定为同一人(误接受率约 1/10,000)
-
70-79:可判定为同一人(误接受率约 1/1,000);阈值可根据业务场景调整
-
<70:不建议判定为同一人;建议更清晰的照片重新比对
- 回复示例:「两张照片的相似度为 95.7(满分 100),高置信度匹配 — 可判定为同一人。」
能力 2:照片活体检测
- 触发:「这张照片是真的吗?」、「AI 生成?」、「PS 过?」
- 用户提供:包含人脸的一张照片
- 执行:
python scripts/ekyc_api.py photo_liveness_detect --file
- 返回:riskLevel(风险等级)、riskTag(风险标签编号)
- 结果解读:
-
等级 1:无攻击风险 — 真实照片,未检测到伪造
-
等级 2:中等怀疑 — 存在可疑特征,建议用不同照片重新检测
-
等级 3:高度怀疑 — 照片可能是伪造/AI 生成,建议拒绝
- 01=闭眼 / 02=动作未完成 / 03=疑似重放攻击 / 04=疑似合成攻击
- 05=疑似欺诈模板 / 06=疑似水印 / 07=反光检测失败 / 08=多人脸
- 09=人脸质量差 / 10=距离检测失败 / 11=疑似对抗攻击 / 12=疑似人脸攻击痕迹
- 回复示例:「检测结果:风险等级 3(高度怀疑),风险标签 04(疑似合成攻击)。此照片可能是 AI 合成的 — 不建议用于身份验证。」
能力 3:视频活体检测
- 触发:「这个视频是真的吗?」、「深度伪造?」、「视频活体」
- 用户提供:包含人脸的视频(≤20MB;超过 20 秒的视频将返回错误)
- 如果视频太大:提示「视频必须 ≤20MB。请压缩后重新上传」
- 执行:
python scripts/ekyc_api.py video_liveness_detect --file
- 网络重试:视频上传可能遇到 999999 网络错误。脚本自动重试最多 3 次,指数退避。如果 3 次都失败,告诉用户「网络暂时繁忙,请几分钟后重试」
- 返回与解读:同能力 2
- 回复示例:「视频检测结果:风险等级 1(无攻击风险)。此视频是真实的 — 未检测到深度伪造或合成痕迹。」
能力 4:身份证 OCR
- 触发:「读取身份证」、「提取身份证信息」
- 用户提供:身份证照片 + 证件面标识
-
0 = 人像面(正面,有照片)
-
1 = 国徽面(背面,有签发机关和有效期)
- 如果用户未指定面:询问「这是人像面(正面有照片)还是国徽面(背面有国徽)?」
- 执行:
python scripts/ekyc_api.py id_card_ocr --image --side <0|1>
- 返回:
- 人像面(side=0):name、sex、nation(民族)、birth、idcard(身份证号)、address
- 国徽面(side=1):authority(签发机关)、validDate(有效期)
- 结果解读:将返回的字段整理成清晰的列表给用户
- 回复示例(人像面):「身份证识别结果:姓名:李明,性别:男,民族:汉,出生:1992-06-20,身份证号:440305199206***,地址:广东省深圳市南山区科技路 88 号。」
- 回复示例(国徽面):「身份证识别结果:签发机关:深圳市公安局,有效期:2015.03.20–2035.03.20。」
能力 5:银行卡 OCR
- 触发:「读取银行卡」、「卡号」、「银行卡 OCR」
- 用户提供:银行卡正面照片
- 执行:
python scripts/ekyc_api.py bank_card_ocr --image
- 返回:bankcardNo(卡号)、bankcardValidDate(有效期)
- 结果解读:显示卡号和有效期。如果有效期为空,卡面未打印有效期
- 回复示例:「银行卡识别结果:卡号 6222 0200 000,有效期:08/28。」
能力 6:驾驶证 OCR
- 触发:「读取驾驶证」、「驾驶证信息」
- 用户提供:驾驶证照片
- ⚠️ 仅支持主页:如果用户提交的是副页(背面),API 返回错误 -9005。回复:「驾驶证 OCR 仅支持主页(正面)。请重新上传正面。」
- 执行:
python scripts/ekyc_api.py driver_license_ocr --image
- 返回:licenseNo、name、sex、nationality、address、birth、fetchDate、driveClass、validDateFrom、validDateTo
- 结果解读:整理成清晰列表;突出显示准驾车型和有效期
- 回复示例:「驾驶证识别结果:证号:440305199206200013,姓名:李明,准驾车型:C1,有效期:2020-05-28 至 2026-05-28。」
能力 7:行驶证 OCR
- 触发:「读取行驶证」、「车辆信息」
- 用户提供:行驶证照片 + 证件面标识
-
1 = 主页(基本车辆信息)
-
2 = 副页(载客人数、检验记录等)
- 如果用户未指定:询问「这是主页还是副页?」
- 执行:
python scripts/ekyc_api.py vehicle_license_ocr --image --side <1|2>
- 返回:
- 主页(side=1):plateNo、vehicleType、owner、model、vin、engineNo、registeDate、issueDate
- 副页(side=2):额外返回 authorizedCarryCapacity、authorizedLoadQuality、fileNumber、total、inspectionRecord、externalDimensions、curbWeight
- 结果解读:整理成清晰列表。主页:突出显示车牌号和车架号。副页:突出显示载客人数和检验记录
- 回复示例:「行驶证识别结果:车牌:粤 B88888,车型:小轿车,车主:李明,车架号:LGWEE6K58RH000001,发动机号:DKZ000001,注册日期:2022-03-15。」
能力 8:媒体标注
- 触发:「检查口罩」、「检测胁迫」、「戴帽子?」、「在打电话?」、「在车内?」、「多人?」、「纹身?」、「酒店房间?」、「媒体标注」
- 用户提供:图像或视频 + 属性描述(根据用户描述自动映射到标签代码)
- 标签参考表(根据用户描述自动选择):
人像标签:检测用户状态和风险
| 代码 | 标签 | 描述 | 使用场景 |
|---|
| A10 | 昏迷/入睡 | 闭眼或强制睁眼 | 安全监控、风险预警 |
| A09 | 受胁迫 | 检测到胁迫姿势 | 反欺诈、安全预警 |
| A15 | 危重病人 | 危重状态患者 | 贷款欺诈预防、合规 |
| A11 | 打电话 | 用户正在通话 | 通话场景、第三方指导 |
| A04 | 戴耳机 | 检测到耳机 | 通话场景、第三方指导 |
| A05 | 裸露 | 敏感身体部位暴露 | 合规审查 |
| A13 | 纹身 | 检测到纹身 | 特征标记、风险分析 |
| A02 | 口罩遮脸 | 医用口罩遮挡面部 | 身份检测、合规 |
| A14 | 戴帽子 | 检测到帽子 | 遮挡检测、伪装 |
| A01 | 面部面膜 | 贴敷面膜 | 护肤或遮挡检测 |
| A06 | 戴太阳镜 | 检测到太阳镜 | 遮挡检测、合规 |
环境标签:检测业务场景
| 代码 | 标签 | 描述 | 使用场景 |
|---|
| B02 | 多人 | 画面中有多人 | 群体场景、第三方指导 |
| B03 | 在乘用车内 | 在轿车、SUV 等车内 | 汽车贷款、出行、合规 |
| B06 | 在酒店 | 在酒店房间内 | 场景审查、风险控制 |
| B07 | 在汽车经销商处 | 在汽车经销商处 | 消费金融、合规 |
每次请求最多 5 个标签代码
执行
:python scripts/ekyc_api.py media_labeling --file --labels "A02,A14" --type image
- type:照片用 image,视频用 video
异步处理
:此 API 是 2 步异步操作(提交 → 等待 → 查询)。脚本自动处理。通常 5-10 秒返回结果
返回
:fileLabel(标签结果数组)、liveStatus(活体状态)、compareStatus(人脸比对状态)
结果解读
:
- fileLabel 每个标签的值:1=检测到,0=未检测到,空=识别错误(建议重试)
- liveStatus:1=活体,0=非活体
- compareStatus:1=人脸匹配,0=人脸不匹配
回复示例
:
媒体标注结果:
- A14 (戴帽子):✅ 检测到
- A02 (口罩遮脸):❌ 未检测到
活体状态:活体
完整示例
正面:用户请求人脸比对
用户
:「这两张照片是同一个人吗?」+ [上传照片 A] + [上传照片 B]您的操作
:- 确认收到两张照片
- 执行
python scripts/ekyc_api.py face_compare --photo1 PhotoA --photo2 PhotoB
- 收到:
{"success": true, "similarity": "95.7", "orderNo": "ekyc..."}
- 回复:「两张照片的相似度为 95.7(满分 100),高置信度匹配 — 可判定为同一人。」
负面:用户提供个人文本
用户
:「验证李明,身份证号 440305199206200013,与这张照片对比」+ [上传照片]您的操作
:触发隐私规则
不要执行任何 API 调用
回复:「为保护您的隐私,本服务不接受姓名或身份证号码文本。请直接上传两张人脸照片 — 我将通过图像比对判断是否为同一人。」
完成定义
每次 API 调用后,验证所有条件已满足:
- [ ] API 返回 code=0(成功)
- [ ] 原始数据已转换为用户友好的自然语言
- [ ] 包含结果解读(不仅是数字 — 解释其含义)
- [ ] 如果发生错误(code≠0),已告知用户原因和建议操作
- [ ] 对话中未暴露 API 密钥、orderNo 或其他技术细节(除非用户要求)
错误处理
发生错误时,用用户友好的语言解释并提供建议操作:
常见错误代码(所有能力)
| 错误代码 | 用户面向消息 |
|---|
| 1101 / 1102 | 「认证失败 — API 凭证可能配置错误。请检查 .env 文件中的密钥。」 |
| 1103 | 「当前 IP 未在白名单中。请联系您的管理员。」 |
| 1106 | 「无效请求。请检查您的请求格式。」 |
| 1107 | 「无效请求参数。请验证所有必填字段。」 |
| 1502 | 「版本参数无效。请使用版本 1.0.0。」 |
| 1503 | 「文件校验和错误。请重试上传。」 |
| 1505 | 「无权访问此资源。请检查您的 appid 授权。」 |
| 1506 / 1507 | 「请求过多。请等待 10 秒后重试。」 |
| 1601 | 「请求体过大。请减小文件大小。」 |
| 1602 | 「请求体参数错误。请检查您的请求格式。」 |
| 999999 / 999998 / 999997 | 「网络暂时繁忙,自动重试中...(如果 3 次重试均失败,请让用户稍后重试)」 |
人脸与活体错误代码(能力 1-3)
| 错误代码 | 用户面向消息 |
|---|
| 66660016 | 「图像或视频文件异常。请重新拍摄或使用其他文件。」 |
| 66660023 / 66660048 | 「未检测到合适的人脸。请正对摄像头,保持清晰正面视角。」 |
| 66660037 | 「检测到多人脸。请使用只有一张人脸的照片。」 |
| 66660041 | 「人脸被遮挡或闭眼。请用清晰的照片重试。」 |
| 66660078 | 「未检测到人脸。请确保照片有清晰正面人脸,光线良好。」 |
| 1603 | 「无效视频文件。请检查视频格式后重试。」 |
| 1606 | 「响应解密失败。请重试。」 |
| 1607 | 「查询结果未找到。验证订单可能已过期。」 |
| FailedOperation.CoveredFace | 「人脸被遮挡。请提交无遮挡的人脸照片。」 |
| FailedOperation.IncompleteFace | 「检测到不完整人脸。请提交完整人脸照片。」 |
| FailedOperation.PoorImageQuality | 「图像质量太差。请检查照片质量。」 |
| FailedOperation.ImageDecodeFailed | 「图像解码失败。文件可能已损坏。」 |
| FailedOperation.VideoDecodeFailed | 「视频解码失败。请检查视频格式。」 |
| FailedOperation.VideoDurationExceeded | 「视频过长 — 最长支持 20 秒。请剪辑后重新上传。」 |
| FailedOperation.DetectEngineSystemError | 「检测引擎错误。请重试。」 |
| FailedOperation.UnKnown | 「内部错误。请重试或联系支持。」 |
OCR 错误代码(能力 4-7)
| 错误代码 | 用户面向消息 |
|---|
| -1102 | 「图像解码失败 — 文件可能已损坏。请重新拍摄或使用其他照片。」 |
| -1300 | 「图像为空。请上传有效的图像文件。」 |
| -1301 | 「缺少必填参数。请检查您的请求。」 |
| -1304 | 「参数值过长。请检查输入长度限制。」 |
| -9001 | 「无效请求类型。请检查 side/type 参数。」 |
| -9002 | 「OCR 识别失败 — 照片可能不够清晰。请在光线良好时重新拍摄。」 |
| -9005 | 「无效图像或不支持的图像类型。驾驶证仅支持主页(正面)。」 |
| -9006 | 「图像预处理失败。请尝试其他照片。」 |
| 66661001 | 「不是身份证或图像不够清晰。请验证文档类型,确保照片清晰完整。」 |
| 66661013 / 66661005 | 「请调整角度,确保文档清晰完整。」 |
媒体标注错误代码(能力 8)
| 错误代码 | 用户面向消息 |
|---|
| 66660000 | 「无效订单号。请检查 orderNo 参数。」 |
| 66660001 | 「无效 appId。请验证您的凭证。」 |
| 66660002 | 「请求已过期。请重新生成签名并重试。」 |
| 66660003 | 「试用配额已超限。请升级您的计划或联系支持。」 |
| 66660004 | 「并发请求限制已达。请稍等后重试。」 |
| 66660013 | 「无效请求参数。请检查您的请求格式。」 |
| 66660016 | 「图像或视频文件异常。请重新拍摄或使用其他文件。」 |
| 66661014 | 「媒体标注结果未找到。订单可能已过期 — 请重新提交。」 |
| 66661015 | 「媒体标注仍在处理中,请稍候...(脚本自动重试)」 |
| 66661016 | 「每次请求标签过多(最多 5 个)。请减少标签数量后重试。」 |
| 66661018 | 「部分标签代码不存在或尚未可用。」 |
| 66661019 | 「未提供标签。请至少指定一个标签代码。」 |
| 66661020 | 「标签代码格式无效。使用格式如 A01、B03。」 |
| 66661021 | 「您的 appId 未获得此服务授权。请联系支持。」 |
| 66661022 | 「媒体标注处理失败。请重新提交请求。」 |
| 66661023 | 「图像预检失败。请确保图像符合质量要求。」 |
| 1104 | 「认证签名已过期或无效。请重试 — 系统将自动刷新。」 |
| 400101 | 「缺少必填参数。请检查请求格式。」 |
| 400103 | 「参数值无效。请验证标签代码和输入格式。」 |
| 400105 | 「Appid 与凭证集不匹配。请检查您的密钥 A/密钥 B 配置。」 |
| 400106 | 「签名验证失败。请确保使用正确的凭证集。」 |
| 400501 | 「文件上传失败。请检查文件后重试。」 |
| 400502 | 「不支持的文件格式。请使用 JPG、PNG 或 MP4。」 |
| 400505 | 「文件处理超时。请使用较小的文件重试。」 |
| 400506 | 「文件内容为空或损坏。请重新上传。」 |
| 400601 | 「服务暂时不可用。请稍后重试。」 |
| 400602 | 「服务配额已超限。请联系支持增加配额。」 |
对于未列出的错误代码:「意外错误(代码:XXX,消息:XXX)。请联系技术支持。」
认证架构
能力 1-7(KYC 认证)— 3 步
步骤 1: GET access_token ← app_id + secret
步骤 2: GET SIGN ticket ← app_id + access_token
步骤 3: Signature = sort([appId, orderNo, nonce, "1.0.0", ticket]) → concat → SHA1 → 40-char 大写
实现:scripts/kyc_auth.py —
不要重写,直接调用
能力 8(标签认证)— 2 步
步骤 1: GET ticket 直接 ← appId + secret(无 access_token 步骤)
步骤 2: Signature = sort([appId, orderNo, nonce, "1.0.0", ticket, unixTimeStamp]) → concat → SHA1 → 40-char 大写
关键区别:6 个参数(增加 unixTimeStamp),ticket 直接获取无需 access_token。
实现:scripts/label_auth.py —
不要重写,直接调用*
法律声明
本软件不存储、缓存或保留任何提交的数据。API 验证结果仅供参考,不构成法律身份确认。本软件不得用作产生法律效力或对个人产生重大影响的自动化决策的唯一依据。用户应为高风险身份决策实施适当的业务逻辑和人工审核流程。
速率限制
- 能力 1-7(KYC):每个 appid 100 次调用(测试配额)
- 能力 8(媒体标注):并发受限,默认 1 个并发请求;联系技术支持扩容
Financial-grade electronic identity verification toolkit with 8 capabilities covering face comparison, liveness detection, document OCR, and media labeling. All inputs are image or video files only.
Quick Reference
| Capability | Command |
|---|
| Face compare | python scripts/ekyc_api.py face_compare --photo1 --photo2 |
| Photo liveness | python scripts/ekyc_api.py photo_liveness_detect --file |
| Video liveness | python scripts/ekyc_api.py video_liveness_detect --file |
| ID card OCR | python scripts/ekyc_api.py id_card_ocr --image --side <0\ | 1> |
| Bank card OCR | python scripts/ekyc_api.py bank_card_ocr --image ![]() |
| Driver license | python scripts/ekyc_api.py driver_license_ocr --image ![]() |
| Vehicle license | python scripts/ekyc_api.py vehicle_license_ocr --image --side <1\ | 2> |
| Media labeling | python scripts/ekyc_api.py media_labeling --file --labels "A14,B03" --type image |
External Endpoints
| Endpoint | Capabilities | Data Sent |
|---|
https://kyc1.qcloud.com | 2, 3, 4, 5 (liveness, ID/bank card OCR) | Base64-encoded images/videos + signed request |
https://miniprogram-kyc.tencentcloudapi.com | 1, 6, 7 (face compare, driver/vehicle license OCR) | Base64-encoded images + signed request |
https://kyc2.qcloud.com | 8 (media labeling) | Base64-encoded images/videos + signed request |
No personal text data (names, ID numbers) is transmitted. Only image/video binary data is sent.
Security & Privacy
This software does not store, cache, or retain any submitted data.
API verification results are for reference only and do not constitute legal identity confirmation. This software must not be used as the sole basis for automated decisions that produce legal effects or significant consequences for individuals. Users should implement appropriate business logic and human review processes for high-stakes identity decisions.
Trust Statement
By installing and using this skill, image and video data you provide will be transmitted to Tencent Cloud's identity verification API for processing. Only install this skill if you trust the upstream service provider's data handling practices. This skill does not independently store, process, or retain any biometric data.
Goal
Receive user-uploaded images or videos, call the corresponding identity verification API, return structured results and explain them to the user in plain language.
When to Use
Use this Skill when the user's request involves any of these scenarios:
- "Compare these two photos — same person?" / "face similarity score"
- "Is this photo AI-generated?" / "Is this video real?" / "deepfake detection"
- "Read this ID card" / "Read bank card number" / "Read driver's license" / "Read vehicle license"
- "Check for mask" / "Detect coercion" / "Wearing hat?" / "On the phone?"
- "Unconscious or asleep?" / "Wearing sunglasses?" / "Inside a car?"
- "In a hotel room?" / "Has tattoo?" / "Multiple people?" / "Wearing headphones?"
- "Facial sheet mask?" / "Critical patient?" / "At a car dealership?"
- Any request containing "face comparison", "liveness detection", "OCR", "media labeling", "ekyc"
Do NOT Use
Do not use this Skill in these situations:
- User is only asking "what is KYC" or "how does eKYC work" → answer from knowledge directly
- User provides names, ID numbers, phone numbers as text → refuse and redirect (see Privacy Rule below)
- User wants face liveness + identity verification combo (requires transmitting name + ID number) → explain privacy limitation
Critical Rules
Rule 1: Privacy — NEVER Accept Personal Text
NEVER accept or transmit names, ID numbers, phone numbers, or any personal text data.
If the user provides such information, respond:
"To protect your privacy, this service does not accept names, ID numbers, or other personal text. Transmitting sensitive information through AI conversations carries leakage risks. Please upload image or video files directly — I will complete verification through image recognition."
Rule 2: NEVER Rewrite Signing Code
Always use the Python scripts in scripts/. The signing algorithm uses SHA1 (produces 40-character uppercase hex).
Previous AI models have replaced SHA1 with SHA256 (64 characters), causing 100% authentication failure. Scripts include assertion: assert len(signature) == 40. If you see a 64-character signature, you are using SHA256 by mistake — stop and use the provided scripts.
Rule 3: Dual-Path Response Parsing
API responses may return data at the top level OR nested inside a result object. Always check both:
value = data.get("field") or (data.get("result", {}) or {}).get("field")
Skipping dual-path parsing causes None / undefined errors.
Environment Variables
# Capabilities 1-7 (face comparison, liveness detection, document OCR)
KYC_APPID=your_kyc_appid
KYC_SECRET=your_kyc_secret# Capability 8 (media labeling, separate credential set)
LABEL_APPID=your_label_appid
LABEL_SECRET=your_label_secret
Obtain credentials:
⚠️ IMPORTANT: Use TEST credentials (free 100 calls). Do NOT use production credentials — production IDs incur charges billed by the upstream provider.
Partial configuration supported: Key A alone enables capabilities 1-7. Key B alone enables capability 8. When a user requests an unconfigured capability, clearly indicate which credentials are missing and how to obtain them.
8 Capabilities
Capability 1: Face Comparison
- Trigger: "compare these two photos", "same person?", "face similarity"
- User provides: Two photos containing faces
- If user uploads only one: Ask "Please upload a second photo for comparison"
- Execute:
python scripts/ekyc_api.py face_compare --photo1 --photo2
- Returns: similarity (score 0-100)
- Result interpretation:
-
≥80: High confidence match — can be determined as the same person (false acceptance rate ~1/10,000)
-
70-79: Can be determined as the same person (false acceptance rate ~1/1,000); threshold may be adjusted per business scenario
-
<70: Not recommended to determine as the same person; suggest clearer photos for re-comparison
- Reply example: "The similarity between the two photos is 95.7 (out of 100), a high-confidence match — they can be determined as the same person."
Capability 2: Photo Liveness Detection
- Trigger: "is this photo real?", "AI-generated?", "photoshopped?"
- User provides: One photo containing a face
- Execute:
python scripts/ekyc_api.py photo_liveness_detect --file
- Returns: riskLevel (risk level), riskTag (risk tag number)
- Result interpretation:
-
Level 1: No attack risk — genuine face photo, no forgery detected
-
Level 2: Medium suspicion — suspicious features present, suggest re-detection with different photo
-
Level 3: High suspicion — photo is likely forged/AI-generated, recommend rejection
- Risk tag meanings (include in reply):
- 01=Eyes closed / 02=Action not completed / 03=Suspected replay attack / 04=Suspected synthetic attack
- 05=Suspected fraud template / 06=Suspected watermark / 07=Reflection check failed / 08=Multiple faces
- 09=Poor face quality / 10=Distance check failed / 11=Suspected adversarial attack / 12=Suspected attack traces on face
- Reply example: "Detection result: Risk level 3 (high suspicion), risk tag 04 (suspected synthetic attack). This photo is likely AI-synthesized — not recommended for identity verification."
Capability 3: Video Liveness Detection
- Trigger: "is this video real?", "deepfake?", "video liveness"
- User provides: A video containing a face (≤20MB; videos exceeding 20 seconds will return an error)
- If video too large: Prompt "Video must be ≤20MB. Please compress and re-upload"
- Execute:
python scripts/ekyc_api.py video_liveness_detect --file
- Network retry: Video uploads may encounter 999999 network errors. Script auto-retries up to 3 times with exponential backoff. If all 3 fail, tell user "Network temporarily busy, please try again in a few minutes"
- Returns & interpretation: Same as Capability 2
- Reply example: "Video detection result: Risk level 1 (no attack risk). This video is genuine — no deepfake or synthetic traces detected."
Capability 4: ID Card OCR
- Trigger: "read ID card", "extract ID card info"
- User provides: ID card photo + side indicator
-
0 = Portrait side (front, with photo)
-
1 = National emblem side (back, with issuing authority and validity)
- If user doesn't specify side: Ask "Is this the portrait side (front with photo) or the emblem side (back with national emblem)?"
- Execute:
python scripts/ekyc_api.py id_card_ocr --image --side <0|1>
- Returns:
- Portrait side (side=0): name, sex, nation (ethnicity), birth, idcard (ID number), address
- Emblem side (side=1): authority (issuing authority), validDate (validity period)
- Result interpretation: Organize returned fields into a clear list for the user
- Reply example (portrait side): "ID card recognition result: Name: Li Ming, Sex: Male, Ethnicity: Han, Birth: 1992-06-20, ID No.: 440305199206***, Address: 88 Keji Road, Nanshan District, Shenzhen, Guangdong."
- Reply example (emblem side): "ID card recognition result: Issuing authority: Shenzhen Public Security Bureau, Validity: 2015.03.20–2035.03.20."
Capability 5: Bank Card OCR
- Trigger: "read bank card", "card number", "bank card OCR"
- User provides: Bank card front photo
- Execute:
python scripts/ekyc_api.py bank_card_ocr --image
- Returns: bankcardNo (card number), bankcardValidDate (expiry date)
- Result interpretation: Display card number and expiry. If expiry is empty, the card face does not print an expiry date
- Reply example: "Bank card recognition result: Card No. 6222 0200 000, Expiry: 08/28."
Capability 6: Driver's License OCR
- Trigger: "read driver's license", "driver license info"
- User provides: Driver's license photo
- ⚠️ Main page only: If user submits the supplementary page (back), the API returns error -9005. Reply: "Driver's license OCR only supports the main page (front). Please re-upload the front page."
- Execute:
python scripts/ekyc_api.py driver_license_ocr --image
- Returns: licenseNo, name, sex, nationality, address, birth, fetchDate, driveClass, validDateFrom, validDateTo
- Result interpretation: Organize as clear list; highlight vehicle class and validity period
- Reply example: "Driver's license recognition result: License No.: 440305199206200013, Name: Li Ming, Vehicle class: C1, Valid: 2020-05-28 to 2026-05-28."
Capability 7: Vehicle License OCR
- Trigger: "read vehicle license", "vehicle info"
- User provides: Vehicle license photo + side indicator
-
1 = Main page (basic vehicle information)
-
2 = Supplementary page (passenger capacity, inspection records, etc.)
- If user doesn't specify: Ask "Is this the main page or the supplementary page?"
- Execute:
python scripts/ekyc_api.py vehicle_license_ocr --image --side <1|2>
- Returns:
- Main page (side=1): plateNo, vehicleType, owner, model, vin, engineNo, registeDate, issueDate
- Supplementary (side=2): additionally returns authorizedCarryCapacity, authorizedLoadQuality, fileNumber, total, inspectionRecord, externalDimensions, curbWeright
- Result interpretation: Organize as clear list. Main page: highlight plate number and VIN. Supplementary: highlight passenger capacity and inspection records
- Reply example: "Vehicle license recognition result: Plate: 粤B88888, Type: Small sedan, Owner: Li Ming, VIN: LGWEE6K58RH000001, Engine: DKZ000001, Registered: 2022-03-15."
Capability 8: Media Labeling
- Trigger: "check for mask", "detect coercion", "wearing hat?", "on the phone?", "inside a car?", "multiple people?", "tattoo?", "hotel room?", "media labeling"
- User provides: Image or video + attribute description (you auto-map to label codes based on user description)
- Label reference table (auto-select based on user description):
Portrait labels: Detect user status and risk
| Code | Label | Description | Use case |
|---|
| A10 | Unconscious/asleep | Eyes closed or eyelids forced open | Safety monitoring, risk alert |
| A09 | Under coercion | Coerced posture detected | Anti-fraud, security alert |
| A15 | Critical patient | Critical condition patient | Loan fraud prevention, compliance |
| A11 | On the phone | User is on a phone call | Call scenario, third-party guidance |
| A04 | Wearing headphones | Headphones detected on ears | Call scenario, third-party guidance |
| A05 | Nudity | Sensitive body exposure | Compliance review |
| A13 | Tattoo | Tattoo detected | Feature marking, risk analysis |
| A02 | Mask covering face | Medical mask obstructing face | Identity detection, compliance |
| A14 | Wearing hat | Hat detected | Obstruction detection, disguise |
| A01 | Facial sheet mask | Sheet mask applied | Skincare or obstruction detection |
| A06 | Wearing sunglasses | Sunglasses detected | Obstruction detection, compliance |
Environment labels: Detect business scenario
| Code | Label | Description | Use case |
|---|
| B02 | Multiple people | Multiple people in frame | Group scenario, third-party guidance |
| B03 | Inside passenger vehicle | Inside a passenger car (sedan, SUV, etc.) | Auto loans, travel, compliance |
| B06 | In hotel | Inside a hotel room | Scenario review, risk control |
| B07 | At car dealership | Inside a car dealership | Consumer finance, compliance |
Max 5 label codes per request
Execute
: python scripts/ekyc_api.py media_labeling --file --labels "A02,A14" --type image
- type: image for photos, video for videos
Async process
: This API is a 2-step async operation (submit → wait → query). The script handles this automatically. Typically returns results in 5-10 seconds
Returns
: fileLabel (label result array), liveStatus (liveness status), compareStatus (face comparison status)
Result interpretation
:
- fileLabel value per label: 1=detected, 0=not detected, empty=recognition error (suggest retry)
- liveStatus: 1=live, 0=not live
- compareStatus: 1=faces match, 0=faces don't match
Reply example
:
Media labeling results:
- A14 (Wearing hat): ✅ Detected
- A02 (Mask covering face): ❌ Not detected
Liveness status: Live
Full Example
Positive: User requests face comparison
User
: "Are these two photos the same person?" + [upload Photo A] + [upload Photo B]Your actions
:
- Confirm two photos received
- Execute
python scripts/ekyc_api.py face_compare --photo1 PhotoA --photo2 PhotoB
- Receive:
{"success": true, "similarity": "95.7", "orderNo": "ekyc..."}
- Reply: "The similarity between the two photos is 95.7 (out of 100), a high-confidence match — they can be determined as the same person."
Negative: User provides personal text
User
: "Verify Li Ming, ID number 440305199206200013, against this photo" + [upload photo]Your actions
:
- Detect name and ID number provided →
trigger Privacy Rule
Do NOT execute any API call
Reply: "To protect your privacy, this service does not accept names or ID numbers as text. Please upload two face photos directly — I will determine if they are the same person through image comparison."
Definition of Done
After each API call, verify all conditions are met:
- [ ] API returned code=0 (success)
- [ ] Raw data has been converted to user-friendly natural language
- [ ] Result interpretation included (not just numbers — explain what they mean)
- [ ] If error occurred (code≠0), user has been informed with reason and suggested action
- [ ] No API keys, orderNo, or other technical details exposed in conversation (unless user asks)
Error Handling
When errors occur, explain in user-friendly language with suggested actions:
Common Error Codes (All Capabilities)
| Error Code | User-facing message |
|---|
| 1101 / 1102 | "Authentication failed — API credentials may be misconfigured. Please check the keys in your .env file." |
| 1103 | "Current IP is not whitelisted. Please contact your administrator." |
| 1106 | "Invalid request. Please check your request format." |
| 1107 | "Invalid request parameters. Please verify all required fields." |
| 1502 | "Invalid version parameter. Please use version 1.0.0." |
| 1503 | "File checksum error. Please retry the upload." |
| 1505 | "No permission to access this resource. Please check your appid authorization." |
| 1506 / 1507 | "Too many requests. Please wait 10 seconds and try again." |
| 1601 | "Request body too large. Please reduce the file size." |
| 1602 | "Request body parameter error. Please check your request format." |
| 999999 / 999998 / 999997 | "Network temporarily busy, auto-retrying... (if 3 retries fail, ask user to try again later)" |
Face & Liveness Error Codes (Capabilities 1-3)
| Error Code | User-facing message |
|---|
| 66660016 | "Image or video file is abnormal. Please re-capture or use a different file." |
| 66660023 / 66660048 | "No proper face detected. Please face the camera directly with a clear, frontal view." |
| 66660037 | "Multiple faces detected in photo. Please use a photo with only one face." |
| 66660041 | "Face is occluded or eyes are closed. Please retry with a clear photo." |
| 66660078 | "No face detected. Please ensure the photo has a clear, frontal face with good lighting." |
| 1603 | "Invalid video file. Please check the video format and try again." |
| 1606 | "Response decryption failed. Please retry." |
| 1607 | "Query result not found. The verification order may have expired." |
| FailedOperation.CoveredFace | "Face is occluded. Please submit an unobstructed face photo." |
| FailedOperation.IncompleteFace | "Incomplete face detected. Please submit a full face photo." |
| FailedOperation.PoorImageQuality | "Image quality too poor. Please check the photo quality." |
| FailedOperation.ImageDecodeFailed | "Image decode failed. The file may be corrupted." |
| FailedOperation.VideoDecodeFailed | "Video decode failed. Please check the video format." |
| FailedOperation.VideoDurationExceeded | "Video too long — max 20 seconds supported. Please trim and re-upload." |
| FailedOperation.DetectEngineSystemError | "Detection engine error. Please retry." |
| FailedOperation.UnKnown | "Internal error. Please retry or contact support." |
OCR Error Codes (Capabilities 4-7)
| Error Code | User-facing message |
|---|
| -1102 | "Image decode failed — file may be corrupted. Please re-capture or use a different photo." |
| -1300 | "Image is empty. Please upload a valid image file." |
| -1301 | "Required parameter is missing. Please check your request." |
| -1304 | "Parameter value too long. Please check input length limits." |
| -9001 | "Invalid request type. Please check the side/type parameter." |
| -9002 | "OCR recognition failed — photo may not be clear enough. Please re-capture in good lighting." |
| -9005 | "Invalid image or unsupported image type. For driver's license, only the main page (front) is supported." |
| -9006 | "Image preprocessing failed. Please try a different photo." |
| 66661001 | "Not an ID card or image is not clear enough. Please verify the document type and ensure the photo is sharp and complete." |
| 66661013 / 66661005 | "Please adjust the angle and ensure the document is clear and complete." |
Media Labeling Error Codes (Capability 8)
| Error Code | User-facing message |
|---|
| 66660000 | "Invalid order number. Please check the orderNo parameter." |
| 66660001 | "Invalid appId. Please verify your credentials." |
| 66660002 | "Request has expired. Please regenerate the signature and retry." |
| 66660003 | "Trial quota exceeded. Please upgrade your plan or contact support." |
| 66660004 | "Concurrent request limit reached. Please wait a moment and retry." |
| 66660013 | "Invalid request parameters. Please check your request format." |
| 66660016 | "Image or video file is abnormal. Please re-capture or use a different file." |
| 66661014 | "Media labeling result not found. The order may have expired — please resubmit." |
| 66661015 | "Media labeling still processing, please wait... (script auto-retries)" |
| 66661016 | "Too many labels per request (max 5). Please reduce label count and retry." |
| 66661018 | "Some label codes do not exist or are not yet available." |
| 66661019 | "No labels provided. Please specify at least one label code." |
| 66661020 | "Label code format is invalid. Use format like A01, B03." |
| 66661021 | "Your appId is not authorized for this service. Please contact support." |
| 66661022 | "Media labeling processing failed. Please resubmit the request." |
| 66661023 | "Image pre-check failed. Please ensure the image meets quality requirements." |
| 1104 | "Authentication signature expired or invalid. Please retry — the system will auto-refresh." |
| 400101 | "Missing required parameter. Please check the request format." |
| 400103 | "Invalid parameter value. Please verify label codes and input format." |
| 400105 | "Appid does not match the credential set. Please check your Key A / Key B configuration." |
| 400106 | "Signature verification failed. Please ensure the correct credential set is used." |
| 400501 | "File upload failed. Please check the file and retry." |
| 400502 | "File format not supported. Please use JPG, PNG, or MP4." |
| 400505 | "File processing timeout. Please retry with a smaller file." |
| 400506 | "File content is empty or corrupted. Please re-upload." |
| 400601 | "Service temporarily unavailable. Please retry later." |
| 400602 | "Service quota exceeded. Please contact support to increase your quota." |
For unlisted error codes: "Unexpected error (code: XXX, message: XXX). Please contact technical support."
Authentication Architecture
Capabilities 1-7 (KYC Auth) — 3 Steps
Step 1: GET access_token ← app_id + secret
Step 2: GET SIGN ticket ← app_id + access_token
Step 3: Signature = sort([appId, orderNo, nonce, "1.0.0", ticket]) → concat → SHA1 → 40-char uppercase
Implementation: scripts/kyc_auth.py —
DO NOT rewrite, call directly
Capability 8 (Label Auth) — 2 Steps
Step 1: GET ticket directly ← appId + secret (no access_token step)
Step 2: Signature = sort([appId, orderNo, nonce, "1.0.0", ticket, unixTimeStamp]) → concat → SHA1 → 40-char uppercase
Key difference: 6 parameters (adds unixTimeStamp), and ticket is obtained directly without access_token.
Implementation: scripts/label_auth.py —
DO NOT rewrite, call directly*
Legal Notice
This software does not store, cache, or retain any submitted data.
API verification results are for reference only and do not constitute legal identity confirmation. This software must not be used as the sole basis for automated decisions that produce legal effects or significant consequences for individuals. Users should implement appropriate business logic and human review processes for high-stakes identity decisions.
Rate Limits
- Capabilities 1-7 (KYC): 100 calls per appid (test quota)
- Capability 8 (Media Labeling): Concurrency-limited, default 1 concurrent request; contact tech support for expansion