智能客服(机器人)产品由商家配置端和业务服务端组合完成。
为协助服务商理解运作模式,特提供产品模块图与架构示意图作为参考。通过可视化呈现系统核心模块及交互逻辑,使服务商能直观把握技术实现路径与功能集成关系,从而优化协作效率。
对于 AI PaaS ,均使用平台供给的云资源,服务直接部署在平台内。
注意:禁止使用开发者自己持有的阿里云账号下的资源。
消费者消息通过奇门接口给到AI封闭环境服务端,内部AI应用与AI模型进行处理后,返回消费者侧。 奇门接口可参考文档下方运行时能力介绍。
商家侧应用可保持使用原小程序,但需要更改调用的云应用appId,具体id在开发完成后联系内部小二获取。
其他说明:
1)开发者所使用的VPC环境无公网访问。
2)请求只能通过官方奇门场景或者小程序容器请求到开发者的服务器。
针对【智能客服】解决方案,ISV 需要针对节点进行开发,其中前台服务节点可以承接产品的配置面板、商家操作后台的开发,AI 服务节点则用于 AI 能力的开发,涉及模型开发、部署、调用以及 AI 业务逻辑。
AppKey 同时会涉及到平台的数据权限划分,在该模式下,语料的使用将被授权给 AI 服务节点,仅在该节点内可以使用语料的实时数据。
对于已经开发并上线客服机器人产品的 ISV,仅需在原解决方案中部署 AI 服务,无需创建新应用。如无【AI 服务】入口,可联系淘宝开放平台小二处理。
在封闭VPC环境内:
1)开发者所使用的 VPC 环境无公网访问权限,仅可通过官方奇门场景或小程序容器发起请求到开发者服务器。
2)云资源访需通过Top API获取临时AKSK,临时AKSK必须缓存30分钟至1小时,禁止每次调用都请求Top API。
下图是运行时可能的流程概述:
注意:
1) 运行时消息切流:需要对接新的奇门消息接口,消息会根据商家切流。
2) 千牛侧灰度:使用新的云应用appId请求,具体appId请联系只桃获取。建议:小程序保留新旧环境的两套页面,本期开发者服务端自己存储白名单商家,前端根据是否命中白名单确定展示的新旧页面。具体商家白名单与运营沟通确定,需要运行时切流时间与名单保持同步一致。 后续大规模切流,平台提供是否命中切流的判断接口。
奇门网关针对新零售场景系统间通信协作难题,通过高可用架构设计,有效保障网络与通信安全并提升系统接入稳定性。其业务场景可分为三类:自定义场景、聚石塔内外互通场景及官方集成场景。
本方案中采用官方集成场景,官方集成场景为阿里内部系统与服务商系统间标准化对接方案,场景以及API由阿里官方定义,服务商需要选择指定的场景做接入。服务商可基于指定业务场景完成系统接入,并需提前与对应业务小二确认业务细节。奇门只作为数据传输通道,对于业务问题请咨询对应的阿里业务小二,更多信息请参考官方定义奇门接口场景。
1)官方场景:客服语料开放场景
2)接口名称:qimen.taobao.message.chatrobot.sync
说明:入参参数中event(消息体)的更多说明,请参考机器人协议文档说明。
3)服务地址格式:https://mappcloud-gw.taobao.com/invokeChatRobot/conversation?cloudAppId=xxx&cloudEnv=xxx&path=xxx
① 域名:https://mappcloud-gw.taobao.com
② 调用路径:/invokeChatRobot/conversation
③ 调用方法:POST
④ 调用param:
i)cloudAppId:指定具体应用 ID。
ii)cloudEnv:应用环境,自测填test,正式服务填online。
iii)path:应用路径。
4)接口接收格式
注意:如需进行验签操作,应使用网关返回参数(param)中的 sign 字段值,奇门生成的 sign 可忽略。
body: 消息那边传过来的json (event格式) param: target_app_key:"350xxxx" app_key:"350xxxx" method:"qimen.taobao.message.chatrobot.sync" open_id:"AAGX2xxxxxx8PkxrluZ" main_user_open_id:"AAGX2pNxxxxxxkxrluZ" sign:"AACCE83xxxxxxC5B660298B4" timestamp:"2025-05-21 16:45:35"
TMC采用分布式消息中间件作为技术底座,其核心架构遵循事件驱动架构(EDA)原则,通过消息队列(Message Queue)实现异步通信。TMC消息作为数字化转型的关键使能技术,正在重构订单与商品管理的底层逻辑。通过技术创新与架构优化,企业不仅能实现业务流程的智能化升级,更能构建面向未来的弹性供应链体系。
更多信息,请参考消息服务使用介绍。
名称:AI封闭环境临时token获取
接口:taobao.open.aipaas.token.get
权限包:【AIPaaS封闭环境 】 没有则联系亦雀添加。
注意:
1) 为防止限流,在使用该接口获取 token和 AKSK 时,必须做缓存处理,建议缓存时长30-50min,禁止每次使用都请求 top。
2)云资源临时AKSK仅限封闭环境使用,严禁在非封闭环境中使用。请严格遵守数据安全规范,恪守平台安全准则,杜绝违规操作。
开发者按业务场景进行合理的缓存设计与实现,以下仅为临时AKSK获取的测试demo示例,禁止直接用于生产环境。
public class StsManager {
private static final String TOP_URL = "http://gw.api.taobao.com/router/rest";
private static final String TOP_B_APPKEY = "xxx";
private static final String TOP_APPSECRET = "xxxxxx";
private static final String cacheKeySplit = "#";
private final LoadingCache<String, TmpCredentialsDTO> runtimeCredentialsCache = CacheBuilder.newBuilder()
.expireAfterWrite(35, TimeUnit.MINUTES) // 本地缓存, 30-50min
.maximumSize(200) // 设置最大缓存条目数 目前数量不会很大
.build(new CacheLoader<String, TmpCredentialsDTO>() {
@Override
public TmpCredentialsDTO load(String key) throws Exception {
return loadRuntimeAksk(key);
}
});
public TmpCredentialsDTO getRuntimeAkSkCache(String resourceType, String env, String instanceId) {
if (StringUtils.isBlank(resourceType)
|| StringUtils.isBlank(env)
|| StringUtils.isBlank(instanceId)) {
throw new RuntimeException("getRuntimeAkSkCache error ");
}
String key = generateKey(resourceType, env, instanceId);
try {
TmpCredentialsDTO sts = runtimeCredentialsCache.get(key);
// 判断是否在 10 分钟内过期
// 1. 解析 UTC 时间字符串为 Instant
Instant expirationTime = Instant.parse(sts.getExpiration());
// 2. 获取当前时间
Instant now = Instant.now();
// 3. 计算时间差(从当前时间到过期时间)
Duration duration = Duration.between(now, expirationTime);
// 4. 判断差值是否小于 10 分钟
log.error("sts.getExpiration= {} system now= {} timeToExpire= {}", sts.getExpiration(), now.toString(), duration.toMinutes());
if (duration.toMinutes() < 10) {
// 距离过期还剩 <= 10 分钟,触发异步刷新
try {
runtimeCredentialsCache.refresh(key);
} catch (Exception e) {
// 如果 refresh 抛出异常Guava 不会自动捕获,这里可以日志监控处理
log.error("Failed to refresh cache for key: " + key ,e);
}
}
return sts;
} catch (ExecutionException e) {
log.error("getRuntimeAkSkCache error", e);
throw new RuntimeException("getRuntimeAkSkCache ExecutionException ");
}
}
private TmpCredentialsDTO loadRuntimeAksk(String key) {
if (StringUtils.isBlank(key)) {
log.error("loadRuntimeAksk error, key={}", key);
throw new RuntimeException("loadRuntimeAksk error ");
}
String[] parts = key.split(cacheKeySplit);
String env = parts[0];
String resourceType = parts[1];
String instanceId = parts[2];
return getTempAkSk(resourceType, env, instanceId);
}
public TmpCredentialsDTO getTempAkSk(String resourceType, String env, String instanceId) {
// create Client
TopApiClient client = new DefaultTopApiClient(TOP_B_APPKEY, TOP_APPSECRET, TOP_URL);
Defaultability apiPackage = new Defaultability(client);
// create domain
TaobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest taobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest = new TaobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest();
taobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest.setResourceType(resourceType);
taobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest.setEnv(env);
taobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest.setInstanceId(instanceId);
// create request
TaobaoOpenAipaasTokenGetRequest request = new TaobaoOpenAipaasTokenGetRequest();
request.setAiAppOpenCredentialsRequest(taobaoOpenAipaasTokenGetAiAppOpenCredentialsRequest);
TaobaoOpenAipaasTokenGetResponse response = null;
try {
response = apiPackage.taobaoOpenAipaasTokenGet(request);
} catch (IOException e) {
log.error("getTempAkSk resourceType:{},env:{} res={}", resourceType, env, JSON.toJSONString(response), e);
e.printStackTrace();
}
if (!response.isSuccess()) {
log.error("getTempAkSk error resourceType:{},env:{} res={}", resourceType, env, JSON.toJSONString(response));
System.out.println(response.getSubMsg());
}
log.warn("getTempAkSk debug resourceType:{},env:{} res={}", resourceType, env, JSON.toJSONString(response));
TmpCredentialsDTO tmpCredentialsDTO = new TmpCredentialsDTO();
BeanUtils.copyProperties(response.getResult(), tmpCredentialsDTO);
return tmpCredentialsDTO;
}
private String generateKey(String resourceType, String env, String instanceId) {
StringBuilder builder = new StringBuilder();
builder.append(env);
builder.append(cacheKeySplit);
builder.append(resourceType);
builder.append(cacheKeySplit);
builder.append(instanceId);
;
return builder.toString();
}
}
接口:https://open.taobao.com/api.htm?docId=72814&docType=2
权限包:【AIPaaS封闭环境 】 没有则联系亦雀添加。
注意:
1) 为防止限流,在使用该接口获取 token和 AKSK 时,必须做缓存处理,建议缓存时长30-50min,禁止每次使用都请求 top。
接口:https://open.taobao.com/api.htm?docId=72934&docType=2
权限包:【AIPaaS封闭环境 】 没有则联系亦雀添加。
注意:
1) 为防止限流,在使用该接口必须做缓存处理,建议缓存时长5min,禁止每次消息使用都请求 top。
2)消息只会发送到新环境或者旧环境中的一个,因此消息接受的地方不需要调用该接口判断商家是否在新环境中。 一般只在商家打开B端小程序的时候,判断商家是否要展示新环境的相关页面使用。
SDK java示例
private static final String TOP_URL = "http://gw.api.taobao.com/router/rest";
// create Client
TopApiClient client = new DefaultTopApiClient(TOP_B_APPKEY,TOP_APPSECRET,TOP_URL);
Defaultability apiPackage = new Defaultability(client);
// create domain
// create domain
TaobaoOpenAipaasGrayCheckAiAppCheckHitRequest taobaoOpenAipaasGrayCheckAiAppCheckHitRequest = new TaobaoOpenAipaasGrayCheckAiAppCheckHitRequest();
// create request
TaobaoOpenAipaasGrayCheckRequest request = new TaobaoOpenAipaasGrayCheckRequest();
request.setAiAppCheckHitRequest(taobaoOpenAipaasGrayCheckAiAppCheckHitRequest);
TaobaoOpenAipaasGrayCheckResponse response = apiPackage.taobaoOpenAipaasGrayCheck(request,session);
if(!response.isSuccess()){
System.out.println(response.getSubMsg());
}
System.out.println(JSON.toJSONString(response));