6月16日,支付宝全新上线AI能力,把AI会话入口和服务能力进一步结合起来。这个变化很值得大部分APP团队关注:AI入口不再只是问答窗口,而是开始把服务入口前置出来。
很多APP做到一定阶段后都会遇到类似问题。账单、发票、客服、预约、权益这些能力都在APP里,但入口分散在不同页面,用户要办事的时候,未必知道入口叫什么,也未必愿意按APP原有菜单结构走。
所以这类热点真正值得拆解的,不是具体用了什么模型,而是“会话即服务”这个方向。
用户说一句“开张发票”,系统能不能直接把发票服务调出来?
用户说“查一下这个月账单”,系统能不能带着上下文打开账单明细?
这件事如果放到APP里,技术上要补的不是一个聊天框,而是一套让AI能调用业务服务的工程链路。
比较可落地的一条路,是把已有小程序能力做成Skill,让AI通过Skill Router调用小程序服务。宿主APP继续管账号、权限、支付、安全和基础导航;小程序负责承接具体业务流程;FinClip小程序容器负责运行和呈现;小程序管理平台负责版本、灰度、热更新、回滚和下架。
这篇就按一线项目视角聊一下,自有APP如果想从“功能入口很多”往“AI调服务”走,应该先改哪里。
一、如何实现可落地
很多团队做AI入口时,第一步会先接模型,做一个聊天窗口。这个动作不难,但很容易停在“能聊天”。
真正难的是后面这句:用户说完需求以后,APP能不能真的替他办事?
比如一个用户输入:
请把上周那笔订单开一张电子发票。
这里面至少有几个问题要处理:
- 这句话对应哪个业务能力;
- “上周那笔订单”能不能从上下文里找到;
- 如果有多笔订单,是否需要用户确认;
- 开票页面应该打开哪个小程序、哪个路径;
- 小程序能不能拿到订单信息、用户信息和发票抬头;
- 提交前哪些字段必须让用户二次确认;
- 出错时回到哪里。
这些问题不属于大模型本身,属于APP工程体系。模型可以识别“开发票”这个意图,但调用哪个服务、带什么参数、给什么权限、失败怎么回退,还是要由APP侧控制。
所以第一步不是把所有业务API开放给AI,而是先挑几个流程清楚的小程序,把它们整理成可调用的Skill。
二、优先选哪类小程序做Skill
不是所有功能都适合第一批接入AI会话。
项目里比较稳的做法,是先选低风险、路径短、结果明确的服务。比如查账单、开发票、客服进度、预约记录、权益查询。这类业务有几个共同点:用户意图好识别,参数相对固定,结果可以结构化返回,即使失败也容易兜底。
不建议一开始就做支付扣款、投资交易、复杂推荐这类能力。它们不是不能做,而是风控、合规、确认链路更重,早期会把问题复杂度拉得太高。
可以先做一张表:
| 业务小程序 | 适合程度 | 原因 |
|---|---|---|
| 账单查询 | 高 | 查询类服务,结果结构化 |
| 电子发票 | 高 | 流程清楚,可保留确认页 |
| 客服工单 | 高 | 可先做进度查询和分类 |
| 办事预约 | 中 | 需要时间、地点、身份信息确认 |
| 商品推荐 | 中 | 需要业务策略,不适合完全交给模型 |
| 支付购买 | 低 | 必须接强确认和风控 |
第一批不要贪多。选一到两个高频场景,把从“用户说一句话”到“小程序承接流程”跑通,比同时铺十几个Skill更有价值。
三、Skill不是一个名字,而是一份调用说明
项目里讨论Skill时,最开始很容易把它理解成一个“能力名称”。后来落到工程实现里会发现,只有名称没用,AI真正需要的是一份调用说明。
这份说明至少要包含六类信息:意图、参数、页面、权限、结果、兜底。
以电子发票为例:
{
"skillId": "invoice-skill",
"name": "电子发票",
"intents": ["开发票", "补开发票", "申请电子发票"],
"params": [
{
"name": "orderId",
"required": false,
"source": "context"
},
{
"name": "titleType",
"required": true,
"source": "user_confirm"
}
],
"miniApp": {
"appId": "invoice-miniapp",
"path": "/pages/apply/index"
},
"permissions": ["getUserInfo", "readOrder"],
"result": {
"type": "card",
"fields": ["invoiceStatus", "downloadUrl"]
},
"fallback": "native://invoice/help"
}
这段配置解决的不是页面跳转问题,而是让AI知道这个小程序能处理什么事。
如果用户说“需要开票”,AI可以匹配到invoice-skill;如果上下文里没有订单,就继续追问;如果只有一个候选订单,就把订单参数带进小程序;如果用户没有相关权限,就不要打开页面,直接走提示或兜底。
这里有个经验:Skill描述不要写得太泛。比如“订单服务”这种Skill就很难用,因为查订单、退订单、开发票、催发货都可能落在里面。更好的方式是按可执行动作拆开,一个Skill只负责一类清晰任务。
四、调用链路要有路由层,不能让AI直接打开页面
从安全和可维护性看,AI不应该直接拿着小程序路径去打开页面,中间必须有一层Skill Router。
一次调用可以拆成这样:
用户输入
→ AI识别意图
→ Skill Router匹配Skill
→ 权限与版本校验
→ 小程序容器打开页面
→ 用户确认关键动作
→ 结果回到会话

Skill Router要做几件很具体的事。
第一,判断这个Skill是否在线。业务方可能已经下架了某个小程序,也可能只给部分用户灰度。如果AI还能调用下架Skill,用户体验会直接断掉。
第二,判断宿主版本是否支持。有些Skill依赖新的宿主API,比如支付确认页、身份认证、文件下载。如果用户APP版本太低,就应该走原生兜底或提示升级。
第三,判断权限。不同小程序能调用的宿主能力不一样。账单小程序可能需要读取账单,发票小程序需要读取订单,客服小程序可能只需要用户ID。权限要按Skill配置,不要一把梭。
第四,处理失败回退。小程序打开失败、参数缺失、版本不匹配、权限不通过,都要有明确出口。
示意代码可以这样写:
type SkillCall = {
skillId: string;
appId: string;
path: string;
params: Record<string, string>;
fallback: string;
}
export async function callMiniProgramSkill(call: SkillCall) {
const skill = SkillRegistry.find(call.skillId);
if (!skill || skill.status !== 'online') {
return AIResult.fail('service unavailable');
}
if (!SkillPermission.check(call.skillId, call.params)) {
return AIResult.fail('permission denied');
}
try {
const result = await FinClipRuntime.open({
appId: call.appId,
path: call.path,
query: call.params
});
return AIResult.card(result);
} catch (error) {
Monitor.report('skill_call_failed', {
skillId: call.skillId,
appId: call.appId
});
NativeRouter.open(call.fallback, call.params);
return AIResult.fail('service fallback');
}
}
这里的FinClipRuntime.open是项目里对打开小程序能力的一层封装,不是某个固定SDK版本的原始接口。实际项目里要结合宿主端类型、SDK版本、鉴权方式和启动参数做适配。
这段代码看起来简单,但几个兜底点不能省:Skill不存在要失败,权限不通过要失败,小程序打不开要上报并回退。AI入口一旦放到用户面前,最怕的不是“不够聪明”,而是把用户带到一个不可用流程里。
五、参数补全不要全靠模型猜
做AI调服务时,参数补全是最容易被低估的地方。
比如用户说“请开上次的发票”。这里的“上次”到底是哪一单?如果用户刚从订单详情页进入AI会话,可以从页面上下文里拿到订单ID;如果没有上下文,就要拉取最近订单让用户选;如果有多笔相似订单,就不能让模型直接猜。
项目里更稳的方式,是给参数标注来源:
{
"params": [
{
"name": "orderId",
"required": true,
"source": "context_or_select"
},
{
"name": "invoiceTitle",
"required": true,
"source": "user_confirm"
},
{
"name": "email",
"required": false,
"source": "profile"
}
]
}
参数来源最好分几类:上下文、用户选择、用户确认、个人资料、系统默认值。模型可以参与理解,但关键参数不要让它直接拍板。尤其涉及订单、金额、身份信息、收件信息时,必须回到用户确认。
这也是为什么小程序承接流程比较合适。AI负责把用户带到正确服务,小程序负责展示表单、列表、按钮和确认页。用户最后看到的是一个熟悉的业务流程,而不是在聊天窗口里完成所有敏感操作。
六、小程序管理平台要管住Skill状态
如果APP里只有两三个Skill,写在配置里还能撑一阵。一旦有几十个业务小程序都接入AI会话,就必须把Skill当成资产管理。

小程序管理平台里除了小程序版本,建议把Skill元数据也管起来:
{
"skillId": "bill-skill",
"status": "online",
"miniAppId": "bill-miniapp",
"version": "2.1.0",
"entryPath": "/pages/bill/detail",
"intentTags": ["查账单", "本月账单", "上月消费"],
"requiredPermissions": ["getUserInfo", "readBill"],
"releaseRule": {
"type": "gray",
"percent": 20,
"minHostVersion": "5.8.0"
},
"fallbackVersion": "2.0.3"
}
这里的几个字段都很实用。
status决定AI能不能发现这个Skill;intentTags用于匹配意图;requiredPermissions用于控制宿主API;releaseRule用于灰度;fallbackVersion用于回滚。
FinClip小程序管理平台原本就能管理小程序上传、审核、灰度、热更新、回滚和上下架。在AI+APP场景里,可以进一步把Skill描述和小程序版本绑定起来。这样业务方上线一个小程序版本时,也能同步管理它是否允许被AI调用。
这个动作很重要。否则AI入口上线后,业务方都会希望把各自负责的功能接进去,Skill会越堆越多。如果没有审核、权限和状态管理,后面一定会失控。
七、会话即服务,不代表跳过确认
技术侧最容易被追问的一个问题是:AI既然能调服务,是不是可以自动完成操作?
早期不建议这么做。
查询类可以自动返回结果,比如查账单、查进度、查权益。申请类可以自动打开流程,但关键字段要确认,比如开发票、预约服务、提交工单。交易类必须回到宿主强确认,比如支付、购买、转账、投资。
可以按风险分三档:
| 操作类型 | AI可做什么 | 必须保留什么 |
|---|---|---|
| 查询类 | 匹配Skill并返回结果 | 权限校验 |
| 申请类 | 打开表单并补齐参数 | 用户确认页 |
| 交易类 | 带入上下文并打开页面 | 宿主强确认和风控 |
这不是保守,而是上线需要。AI调服务之后,链路上必须能追踪:用户说了什么、匹配了哪个Skill、传了哪些参数、小程序返回什么结果、是否触发人工确认。没有审计,后面出问题很难定位。
八、自有APP可以从一个场景开始
APP不需要一上来就做成超级APP。
如果是会员类APP,可以先做“查权益”;如果是金融类APP,可以先做“查账单”或“开发票”;如果是园区APP,可以先做“预约会议室”;如果是政企APP,可以先做“查办事进度”。这些场景不一定最酷,但能验证完整链路。
更稳的推进顺序是:
第一步,选一个小程序服务,不超过两个。优先选路径清楚、失败成本低的业务。
第二步,补Skill描述。写清楚意图、参数、页面路径、权限、返回结果和fallback。
第三步,接Skill Router。让AI只能通过路由层调用服务,不直接打开小程序页面。
第四步,接管理平台。支持灰度、热更新、回滚、下架和调用日志。
第五步,再扩第二批Skill。等第一批链路稳定,再做申请类或更复杂的业务。
这条路径看起来慢,但更适合真实项目。AI入口一旦给到用户,后面就是线上服务,不是Demo。
支付宝上线AI能力,给自有APP最大的提醒不是“也去做一个同款助手”,而是服务入口正在从菜单转向会话。
但没必要一下子追求大而全。真正能先落地的,是把已有小程序服务整理成Skill:让AI知道它能做什么、需要什么参数、该打开哪个小程序、结果怎么返回、失败怎么兜底。
如果企业已经在APP里接入FinClip小程序容器,这条路会更顺。已有小程序继续承接业务流程,小程序管理平台继续负责版本和发布,AI侧只需要补上Skill描述、路由匹配、权限控制和结果呈现。
用户最后感知到的变化很简单:不用再找半天入口,直接说需求,APP把对应服务带出来。