---
name: ekyc-suite version: 1.0.0 description: | KYC/eKYC身份核验套件——面向AI Agent的8项金融级生物识别与证件核验能力。 人脸比对与人脸匹配(相似度评分0-100)、人脸活体检测用于自拍验证(反deepfake、反欺诈筛查)、视频活体检测(深度伪造检测,自动重试)、证件OCR识别(身份证、银行卡、驾驶证、行驶证), 以及图像标签识别(15+图像分析属性,用于欺诈防范与合规审查)。
适用场景:KYC客户身份验证、远程开户核验、人脸识别与人脸核身、反洗钱(AML)合规检查、金融科技客户开户、生物识别自拍验证、证件真伪鉴别、deepfake与AI生成内容检测、反欺诈风险筛查、AI安全审计。 当用户说"比对两张人脸"、"检测照片是不是AI生成的"、"这个视频是真人吗"、"识别身份证"、"读取银行卡号"、"识别驾驶证"、"识别行驶证"、"检测有没有戴口罩"、"判断是不是被胁迫"、"检测是不是在车内"、"做KYC验证"、"ekyc"、"身份核验"时触发。 不用于:用户只是询问KYC概念或流程(不涉及实际图片处理)、用户要求传输姓名/身份证号等文本信息。 env:
- KYC_APPID
- KYC_SECRET
- LABEL_APPID
- LABEL_SECRET tags:
- kyc
- ekyc
- 人脸比对
- 人脸识别
- 活体检测
- deepfake检测
- ocr
- 身份证识别
- 银行卡识别
- 驾驶证识别
- 行驶证识别
- 图像标签
- 图像分析
- 反欺诈
- 身份核验
- 人脸核身
- 证件识别
- 生物识别
- AI安全
- 合规
- 金融科技
- 远程开户
- 风控
- 反洗钱
- 远程面签
- 开户核验
- know-your-customer homepage: https://github.com/wefi-ai/eKYC-suite metadata: clawdbot: emoji: "🔐" requires: env: ["KYC_APPID", "KYC_SECRET", "LABEL_APPID", "LABEL_SECRET"] primaryEnv: "KYC_APPID" files: ["scripts/*"]
---
eKYC Suite 身份核验套件
金融级电子身份核验工具包,提供8项能力,覆盖人脸比对、活体检测、证件OCR、图像标签识别。所有输入均为图片或视频文件。
---
目标
接收用户上传的图片或视频,调用对应的身份核验API,返回结构化结果并用通俗语言向用户解读。
---
触发条件
当用户的请求涉及以下场景时,使用本Skill:
- "帮我比对这两张照片是不是同一个人"、"两张人脸相似度多少"
- "检测这张照片是不是AI生成的"、"这个视频是真人吗"、"是不是deepfake"
- "识别这张身份证"、"读取银行卡号"、"识别驾驶证"、"识别行驶证"
- "检测有没有戴口罩"、"判断是不是被胁迫"、"有没有戴帽子"、"是不是在打电话"
- "检测是否处于昏迷或睡眠状态"、"有没有佩戴墨镜"、"是不是在乘用车内"
- "判断是不是在酒店房间"、"有没有纹身"、"检测是否有多人同框"
- "检测是否敷面膜"、"是不是重症病人"、"是否在4S店"、"有没有佩戴耳机"
- 任何包含"人脸比对"、"活体检测"、"证件OCR"、"图像标签"、"ekyc"等关键词的请求
不要触发
遇到以下情况,不要使用本Skill:
- 用户只是问"什么是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
⚠️ 重要提示:请使用测试ID和测试Secret(免费100次调用),不要使用正式ID——正式ID代表正式计费,需向上游服务商付费。
支持部分配置: 只配密钥A可用能力1-7,只配密钥B可用能力8。请求未配置的能力时,向用户明确提示缺少哪组密钥及获取方式。
---
8项能力
能力1:人脸比对
-
触发场景:用户说"比对这两张照片"、"这两个人是同一个人吗"、"人脸相似度"
-
用户需提供:两张包含人脸的照片
-
如果用户只传了一张:追问"请再上传一张用于比对的照片"
-
执行:
python scripts/ekyc\_api.py face\_compare --photo1 <照片1> --photo2 <照片2> -
返回字段:similarity(相似度分数,0-100)
-
结果解读标准:
- ≥80分:高置信度匹配,可判定为同一人(误通过率约万分之一)
- 70-79分:可判定为同一人(误通过率约千分之一),可根据业务场景调整判断阈值
- <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:视频活体检测
- 触发场景:用户说"这个视频是真人吗"、"视频是不是deepfake"、"检测视频活体"
- 用户需提供:一段包含人脸的视频(≤20MB;超过20秒会返回错误)
- 如果视频过大:提示"视频文件需≤20MB,请压缩后重新上传"
- 执行:
python scripts/ekyc\_api.py video\_liveness\_detect --file <视频> - 网络重试:视频上传可能遇到999999网络错误,脚本自动重试最多3次(指数退避)。如果3次都失败,告诉用户"网络暂时繁忙,请稍等几分钟后重试"
- 返回字段:与能力2相同(riskLevel + riskTag)
- 结果解读标准:与能力2相同
- 回复示例:"视频检测结果:风险等级1(无攻击风险)。该视频为真人录制,未检测到deepfake或合成迹象。"
能力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号
能力5:银行卡OCR
- 触发场景:用户说"识别银行卡"、"读取卡号"、"银行卡OCR"
- 用户需提供:银行卡正面照片
- 执行:
python scripts/ekyc\_api.py bank\_card\_ocr --image <照片> - 返回字段:bankcardNo(卡号)、bankcardValidDate(有效期)
- 结果解读:直接展示卡号和有效期。如果有效期为空,说明该卡面未印刷有效期
- 回复示例:"银行卡识别结果:卡号 6222 0200 **** **** 000,有效期 08/28。"
能力6:驾驶证OCR
- 触发场景:用户说"识别驾驶证"、"读取驾照信息"
- 用户需提供:驾驶证照片
- ⚠️ 仅支持正页(主页):如果用户传了副页(背面),接口会返回错误码-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(VIN码)、engineNo(发动机号)、registeDate(注册日期)、issueDate(发证日期)
- 副本(side=2):额外返回 authorizedCarryCapacity(核定载人数)、authorizedLoadQuality(核定载质量)、fileNumber(档案编号)、total(总质量)、inspectionRecord(检验记录)、externalDimensions(外廓尺寸)、curbWeright(整备质量)
-
结果解读:整理为清晰列表。正本重点突出车牌号、VIN码;副本重点突出核定载人数和检验记录
-
回复示例:
行驶证识别结果(正本):
车牌号:粤B88888
车辆类型:小型轿车
所有人:李明
VIN码:LGWEE6K58RH000001
发动机号:DKZ000001
注册日期:2022-03-15
能力8:图像标签识别
- 触发场景:用户说"检测有没有戴口罩"、"判断是不是被胁迫"、"有没有戴帽子"、"是不是在打电话"、"检测是否在乘用车内"、"是否有多人同框"、"检测有没有纹身"、"是不是在酒店房间"、"图像标签分析"等
- 用户需提供:图片或视频 + 要检测的属性描述(由你根据用户描述自动映射到标签代码)
- 标签代码对照表(根据用户描述自动选择对应代码):
人像标签:检测用户状态与风险
|代码|标签|说明|适用场景| |-|-|-|-| |A10|昏迷或睡眠|检测用户是否闭眼或被人扒开眼皮|安全监测、风险预警| |A09|被胁迫|检测用户是否处于被胁迫姿态|反欺诈、安全预警| |A15|重症病人|检测用户是否是重症患者|防骗贷、合规审查、风险预警| |A11|打电话|检测用户是否在打电话|通话场景、他人指导| |A04|佩戴耳机|检测用户耳部是否佩戴耳机|通话场景、他人指导| |A05|裸露|检测用户是否裸露出敏感隐私部位|合规审查| |A13|纹身|检测用户是否有纹身|特征标记与风险分析| |A02|口罩遮挡人脸|检测用户是否因佩戴口罩而遮挡面部|身份检测、合规| |A14|戴帽子|检测用户是否佩戴帽子|遮挡检测、身份伪装、流程规范| |A01|敷面膜|检测用户是否敷面膜|皮肤护理或遮挡检测| |A06|佩戴墨镜|检测用户是否佩戴墨镜|遮挡检测、合规性|
环境标签:检测业务办理场景
|代码|标签|说明|适用场景| |-|-|-|-| |B02|多人同框|检测场景内是否有多人出现|群体场景检测、他人指导| |B03|在乘用车内|检测场景是否在乘用车内(如轿车、SUV等)|车贷、出行、合规| |B06|在酒店|检测场景是否在酒店房间内部|场景审查、风控| |B07|在汽车4S店|检测场景是否在汽车销售门店|消费金融、业务合规|
-
每次最多传5个标签代码
-
执行:
python scripts/ekyc\_api.py media\_labeling --file <文件> --labels "A02,A14" --type image- type参数:图片传
image,视频传video
- type参数:图片传
-
异步流程:此接口为异步两步操作(提交→等待→查询),脚本已自动处理,无需额外操作。通常需要5-10秒返回结果
-
返回字段:fileLabel(标签结果数组)、liveStatus(活体状态)、compareStatus(人脸比对状态)
-
结果解读标准:
- fileLabel 中每个标签的 value:
1=命中(检测到该特征)、0=未命中(未检测到)、空值=识别异常建议重试 - liveStatus:
1=活体、0=非活体 - compareStatus:
1=人脸一致、0=人脸不一致
- fileLabel 中每个标签的 value:
-
回复示例:
图像标签分析结果:
- A14(戴帽子):✅ 命中 — 检测到图中人物佩戴帽子
- A02(口罩遮挡):❌ 未命中 — 未检测到口罩遮挡
活体状态:活体
---
完整调用示例
正例:用户要做人脸比对
用户:"帮我看看这两张照片是不是同一个人" + [上传照片A] + [上传照片B]
你的操作:
- 确认收到两张照片
- 执行
python scripts/ekyc\_api.py face\_compare --photo1 照片A --photo2 照片B - 收到返回:
{"success": true, "similarity": "95.7", "orderNo": "ekyc..."} - 回复用户:"两张照片的相似度为 95.7 分(满分100),高置信度匹配,可判定为同一人。"
反例:用户提供了个人文本信息
用户:"帮我验证一下,李明,身份证号440305199206200013,和这张照片是不是同一人" + [上传照片]
你的操作:
- 检测到用户提供了姓名和身份证号 → 触发隐私红线
- 不执行任何API调用
- 回复:"为保护您的隐私安全,本服务不接受姓名、身份证号等文本信息。请直接上传两张人脸照片,我通过图像比对来判断是否为同一人。"
---
完成标准
每次调用后,确认以下条件全部满足:
- [ ] API返回 code=0(成功)
- [ ] 已将返回的原始数据转化为用户能理解的自然语言
- [ ] 包含了结果解读(不是只报数字,而是告诉用户这个数字代表什么含义)
- [ ] 如果有异常(code≠0),已根据错误码表向用户说明原因和建议操作
- [ ] 没有在对话中暴露API密钥、orderNo等技术细节(除非用户主动问)
---
异常处理
遇到错误时,不要只报错误码,要用用户能理解的语言解释并给出建议:
通用错误码(所有能力)
|错误码|用户看到的提示| |-|-| |1101 / 1102|"身份验证失败,可能是API密钥配置有误。请检查.env文件中的密钥是否正确填写。"| |1103|"当前网络IP未在白名单中,请联系管理员添加白名单。"| |1106|"不合法请求,请检查请求格式。"| |1107|"请求参数不合法,请检查所有必填字段。"| |1502|"版本参数错误,请使用version=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|"请求类型错误,请检查正反面/类型参数。"| |-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步:签名 = sort(\[appId, orderNo, nonce, "1.0.0", ticket]) → 拼接 → SHA1 → 40位大写
实现文件:scripts/kyc\_auth.py — 请勿重写,直接调用
能力8(标签鉴权)— 2步
第1步:直接GET ticket ← appId + secret(无需access\_token)
第2步:签名 = sort(\[appId, orderNo, nonce, "1.0.0", ticket, unixTimeStamp]) → 拼接 → SHA1 → 40位大写
关键区别:6个参数(多一个unixTimeStamp),且ticket直接获取无需access_token中间步骤。
实现文件:scripts/label\_auth.py — 请勿重写,直接调用
---
法律声明
本服务不存储、不缓存、不保留用户提交的任何数据。
API验证结果仅供参考,不构成法律意义上的身份确认。本服务不得作为产生法律效力或对个人产生重大影响的自动化决策的唯一依据。用户应在高风险身份决策场景中建立适当的业务逻辑和人工审核流程。
---
限流说明
- 能力1-7(KYC):100次/appid(测试配额)
- 能力8(图像标签识别):并发限制,默认1并发,扩容需联系技术支持
扫码联系在线客服