众所周知,微信团队重磅推出了小程序AI能力,于是我破不待地开始研究。
微信 AI 生态到底是干啥的
微信 AI 生态,本质是把微信里的"小程序"从"用户打开的应用",改造成"微信 AI 助手可以自动调用的工具"。微信想做那个超级入口(对话框),你的小程序退到后面当"能力供给方"。
具体来说,用户在微信 AI 对话框说一句话("画张大海"),微信的大模型负责理解意图 + 挑工具,然后通过"小程序 MCP 协议"调用你封装的原子接口(generateImage),你的接口去调后端出图,再把结果塞进一张原子组件卡片渲染在对话流里。
接入小程序AI
以文生图为例落地第一个SKILL。整个过程踩了不少坑,也沉淀了一些可复用的经验,最终还整理了一个通用的接入模板仓库(github.com/fayeah/wx-a… ),今天就把这些实战经验分享出来。
背景:Uni-app接入的特殊处理
不同于原生微信小程序,uni-app的构建逻辑不会自动生成AI开发模式所需的agent配置,也不会打包ai-skills目录。为了解决这个问题,写了一个注入脚本scripts/inject-ai-skill.js,在build:mp-weixin构建完成后,把agent配置、分包、相关文件补到dist/build/mp-weixin目录下。
对应的npm脚本也做了封装:
npm run inject:ai:仅注入到开发环境产物dist/dev/mp-weixinnpm run build:ai:先执行build:mp-weixin构建,再注入到生产环境产物dist/build/mp-weixin
踩坑实录:8个核心问题的解决思路
整个接入过程中遇到的问题五花八门,从编译入口找不到到真机上传报错,整理了按出现顺序排列的8个核心问题,每个问题都对应明确的根因和解决方案:
1. 找不到「小程序AI编译」入口
现象:微信开发者工具里看不到AI编译相关选项
根因:AI编译入口藏在编译模式下拉菜单里,且需要两个前提——安装Nightly Electron Build版本(2.02.2606082+)、小程序appid已开通「AI开发模式」权限
解法:切换编译模式到AI模式,联系运营申请开通权限
2. module ... index.js is not defined
现象:运行时提示skill入口文件未定义
根因:uni-app的lazyCodeLoading摇树优化会裁掉没有被静态引用的skill入口文件
解法:在占位页_holder里通过require('../draw-skill/index.js')强制引用,确保打包时不会被剔除
3. Cannot use import statement
现象:运行时报ES模块语法错误
根因:虽然关闭了uni产物的es6/enhance,但Vant组件依赖ESM语法需要转译
解法:通过注入脚本把dist目录下配置的es6/enhance/postcss设为true,开启转译
4. 登录接口返回LOGIN_FAILED
现象:调用mp_login接口登录失败
根因:请求头缺失后端要求的公共头信息
解法:复刻前端请求工具类里的公共头
5. componentPath not found
现象:提示找不到原子组件路径
根因:lazyCodeLoading把未被引用的原子组件也裁掉了
解法:在_holder页面的usingComponents里声明组件,同时页面内添加<draw-card/>标签强制引用
6. AI卡片空白,数据未绑定
现象:卡片渲染出来但没有内容
根因:想当然用properties接收数据,不符合AI组件的数据传递规则
解法:通过wx.modelContext.getContext(this)获取上下文,监听NotificationType.Result事件,数据实际在data.result.structuredContent里
7. 模拟器中图片空白
现象:模拟器里卡片图片不显示,真机正常
根因:agent-render预览帧运行在沙箱中,目前无法正常渲染图片
解法:以真机显示效果为准,同时把域名加入downloadFile合法域名
8. 真机上传报错-80426
现象:真机调试上传代码报-80426错误
根因:mcp.json里引用了componentPath,但未声明组件
解法:在mcp.json中添加components数组,包含path、name、relatedPage字段
核心技术要点梳理
原子组件数据接收方式
AI原子组件不能通过properties接收数据,官方文档3.4.1明确了数据契约,核心代码如下:
const modelCtx = wx.modelContext.getContext(this)
const { NotificationType } = wx.modelContext
modelCtx.on(NotificationType.Result, (data) => {
...
})
mcp.json组件声明
真机上传不报错的关键是在mcp.json里声明组件,示例如下:
{
"apis": [
{
"name": "generateImage",
"description": "根据用户的文字描述生成图片。适用于用户想画一张图、生成创意图片、海报、壁纸等场景。",
"_meta": {
"ui": {
"componentPath": "components/draw-card/index"
}
},
"inputSchema": {
"type": "object",
"properties": {
"prompt": {
"type": "string",
"description": "图片内容的文字描述,越具体越好,可包含主体、风格、色调、场景等。"
},
"aspect_ratio": {
"type": "string",
"description": "画面比例。1:1 正方形,9:16 竖屏/壁纸,16:9 横屏,3:4 或 4:3 其他。默认 1:1。",
"enum": ["1:1", "9:16", "16:9", "3:4", "4:3"]
}
},
"required": ["prompt"]
},
"outputSchema": {
"type": "object",
"properties": {
"prompt": { "type": "string" },
"aspect_ratio": { "type": "string" },
"images": {
"type": "array",
"items": {
"type": "object",
"properties": {
"image_url": { "type": "string" }
}
}
}
}
}
}
],
"components": [
{
"path": "components/draw-card/index",
"name": "draw-card",
"relatedPage": "pages/index/index"
}
]
}
project.config.json 文件声明,其中packOptions很重要,否则真机调试时skill部分不会上传。
{
"setting": {
"es6": true,
"postcss": true,
"minified": true,
"uglifyFileName": false,
"enhance": true,
"packNpmRelationList": [],
"babelSetting": {
"ignore": [],
"disablePlugins": [],
"outputPath": ""
},
"useCompilerPlugins": false
},
"compileType": "miniprogram",
"simulatorPluginLibVersion": {},
"packOptions": {
"ignore": [],
"include": [{"type": "folder", "value": "ai-skills"}]
},
"appid": "xxx",
"editorSetting": {}
}
核心认知总结
lazyCodeLoading摇树优化是把双刃剑:能减小包体积,但会裁掉未被静态引用的skill和组件,必须用占位页强制保留;- AI原子组件的数据传递有特殊规则:不用properties,而是通过
modelContext监听事件获取; - mcp.json的组件声明是真机运行的关键:缺失会导致-80426报错;
- 模拟器预览有局限性,图片的渲染暂时以真机为准。
最后
为了让后续接入微信AI开发模式的同学少走弯路,我把这次接入的核心逻辑、配置模板、避坑指南整理成了一个通用模板仓库:github.com/fayeah/wx-a… ,里面包含了完整的目录结构、注入脚本、配置示例,大家可以直接fork使用。
接入微信小程序AI开发模式的过程虽然踩了很多坑,但也让我对uni-app和微信AI生态的结合有了更深入的理解。如果大家在接入过程中遇到其他问题,欢迎在评论区交流~