【Miniapp】微信小程序AI接入实战:踩坑与解决方案

0 阅读5分钟

众所周知,微信团队重磅推出了小程序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-weixin
  • npm 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数组,包含pathnamerelatedPage字段

核心技术要点梳理

原子组件数据接收方式

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": {}
}

核心认知总结

  1. lazyCodeLoading摇树优化是把双刃剑:能减小包体积,但会裁掉未被静态引用的skill和组件,必须用占位页强制保留;
  2. AI原子组件的数据传递有特殊规则:不用properties,而是通过modelContext监听事件获取;
  3. mcp.json的组件声明是真机运行的关键:缺失会导致-80426报错;
  4. 模拟器预览有局限性,图片的渲染暂时以真机为准。

最后

为了让后续接入微信AI开发模式的同学少走弯路,我把这次接入的核心逻辑、配置模板、避坑指南整理成了一个通用模板仓库:github.com/fayeah/wx-a… ,里面包含了完整的目录结构、注入脚本、配置示例,大家可以直接fork使用。

接入微信小程序AI开发模式的过程虽然踩了很多坑,但也让我对uni-app和微信AI生态的结合有了更深入的理解。如果大家在接入过程中遇到其他问题,欢迎在评论区交流~