微信小程序接入AI API实现智能问答功能(以百度智能云为例)

1.老规矩,先讲故事

这天我的微信小程序想实现接入一个AI页面实现用户AI智能问答功能,但发现网络上大家都比较吝啬,要么要开会员,要么不分享。导致我走了好多弯路,最后也明白了一些道理,掌握了一些新的知识。

2.AI问答功能的实现

这部分直接上代码吧(主要两个文件,小程序前端页面js文件与服务端云函数index.js文件)

//页面js文件
const app = getApp()

Page({
  data: {
    chatList: [],
    inputValue: '',
    loading: false,
    scrollToView: '',
    loadingText: '发送中...'
  },

  onLoad() {
    // 初始化聊天列表
    this.setData({
      chatList: [{
        role: 'assistant',
        content: '你好!我是徒步小智,有什么我可以帮你的吗?'
      }]
    })
  },

  onInput(e) {
    this.setData({
      inputValue: e.detail.value
    })
  },

  async sendMessage() {
    if (!this.data.inputValue.trim() || this.data.loading) return

    const userMessage = this.data.inputValue.trim()
    this.setData({
      chatList: [...this.data.chatList, {
        role: 'user',
        content: userMessage
      }],
      inputValue: '',
      loading: true,
      loadingText: '正在思考中...'
    })

    this.scrollToBottom()

    try {
      const maxRetries = 2
      let retryCount = 0
      let success = false

      while (retryCount <= maxRetries && !success) {
        try {
          //wx.cloud.callFunction调用该云函数
          const response = await wx.cloud.callFunction({
            name: 'aiChat',
            data: {
              message: userMessage
            }
          })

          if (response.result && response.result.data && response.result.data.result) {
            this.setData({
              chatList: [...this.data.chatList, {
                role: 'assistant',
                content: response.result.data.result
              }],
              loading: false,
              loadingText: '发送中...'
            })
            success = true
          } else {
            throw new Error('无效的响应数据')
          }
        } catch (error) {
          retryCount++
          if (retryCount <= maxRetries) {
            this.setData({
              loadingText: `重试第${retryCount}次...`
            })
            await new Promise(resolve => setTimeout(resolve, 1000))
          } else {
            throw error
          }
        }
      }

      this.scrollToBottom()
    } catch (error) {
      console.error('AI API调用失败:', error)
      this.setData({
        chatList: [...this.data.chatList, {
          role: 'assistant',
          content: '抱歉,我现在有点忙,请稍后再试。'
        }],
        loading: false,
        loadingText: '发送中...'
      })
      wx.showToast({
        title: '请求超时,请稍后重试',
        icon: 'none',
        duration: 2000
      })
    }
  },

  scrollToBottom() {
    const length = this.data.chatList.length
    if (length > 0) {
      this.setData({
        scrollToView: `msg-${length - 1}`
      })
    }
  }
})
//云函数/cloudfunctions/aiChat/index.js文件
const cloud = require('wx-server-sdk')
const axios = require('axios')

cloud.init({
  env: cloud.DYNAMIC_CURRENT_ENV
})

//定义一个云函数入口,使用async声明异步函数
exports.main = async (event, context) => {
  //从事件对象中解构出用户输入的message参数
  const { message } = event

  try {
    //axios({ method: 'POST', ... })使用axios发起POST请求
    const response = await axios({
      method: 'POST',
      url: 'https://qianfan.baidubce.com/v2/chat/completions',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': 'Bearer bce-v3/xxxxxx/xxxxxx'
      },
      data: {
        model: "ernie-3.5-8k",
        messages: [
          {
            role: "user",
            content: message
          }
        ]
      }
    })

    // 从响应数据中提取AI助手的回复内容
    const aiContent = response.data.choices[0].message.content

    return {
      code: 200,
      data: {
        result: aiContent
      }
    }
  } catch (error) {
    console.error('API调用错误:', error)
    return {
      code: 500,
      error: error.message
    }
  }
}

3.需要注意的问题

1.跨域问题

先说一下,我使用的是百度智能云千帆大模型服务与开发平台ModelBuilder。这是他的官方api调用示例


curl -X POST 'https://qianfan.baidubce.com/v2/chat/completions'   -H 'Content-Type: application/json'   -H 'Authorization: Bearer bce-v3/ALTAK-*****************/2d7*****************'   -d '{
    "model": "ernie-3.5-8k",
    "messages": [
        {
            "role": "user",
            "content": "你好"
        }
    ]
  }'

 我在postman上面进行测试,发现上面是完全可行的,但当我页面js文件使用 wx.request()无法实现AI API的调用。这让我十分不解,我也去配置了不检验域名,设置了域名白名单。还是无法解决,后来将调用API放进云函数使用axios网络请求库解决实现了调用。

真相大白

经过我的不蟹探究,最后发现是跨域问题。

一、跨域问题的本质
  1. 浏览器安全策略

    • 跨域限制(CORS)是浏览器强制的安全机制

    • 只存在于浏览器环境(包括小程序)

    • 服务端之间的通信没有跨域概念

  2. 错误表现示例

    // 前端直接调用会出现的错误
    Access to XMLHttpRequest at 'https://qianfan.baidubce.com/...' from origin 'https://your-domain.com'
    has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource
二、两种场景对比
场景1:前端直接调用(失败)
sequenceDiagram
    participant 浏览器/小程序 as 前端
    participant 百度API as 服务端
    前端->>服务端: wx.request(带Authorization头)
    服务端-->>前端: 响应(无CORS头)
    浏览器拦截响应 ❌

关键问题

  1. 百度API响应头没有设置 Access-Control-Allow-Origin: *

  2. 浏览器/小程序引擎拒绝解析响应

场景2:云函数中转(成功)
sequenceDiagram
    participant 浏览器/小程序 as 前端
    participant 云函数 as 服务端
    participant 百度API as 服务端
    前端->>云函数: wx.cloud.callFunction(安全)
    云函数->>百度API: axios请求(服务端到服务端)✅
    百度API-->>云函数: 原始响应(无CORS限制)
    云函数-->>前端: 返回清洗后的数据

成功关键

  1. 前端与云函数同源(或云函数已配置CORS)

  2. 云函数到百度API是服务端间通信,不受浏览器策略限制


三、云函数的优势详解
  1. 网络层面

    • 云函数部署在腾讯云/阿里云等服务器

    • 默认拥有公网访问能力

    • 无需处理证书、代理等复杂配置

  2. 协议层面

    • 服务端之间使用标准HTTP/HTTPS协议

    • 无需处理CORS、OPTIONS预检请求

  3. 安全层面

    • 前端永远看不到API密钥

    • 可在云函数做请求限流、内容过滤

    • 避免直接暴露API端点

在我的例子中,前端wx.request链接https://qianfan.baidubce.com服务端会发生跨域问题使无法正确返回,如果放云函数里使用axios方法就是服务端-服务端,就不会有不会有跨域问题

四、为什么小程序用wx.request失败?

根本原因链

小程序未配置域名白名单 → 百度API未设置CORS头 → 小程序引擎拦截响应 → 开发者工具Network显示请求被blocked

具体限制

  1. 小程序要求所有请求域名必须加入request合法域名列表

  2. 即使你配置了qianfan.baidubce.com,百度服务器也不会返回CORS头

  3. 双重限制下必然失败


五、最终结论

通过云函数中转的本质,是把原本需要浏览器处理的跨域请求,转换为服务端之间的自由通信。这种方案:

  • ✅ 彻底规避跨域问题

  • ✅ 提升安全性

  • ✅ 符合企业级应用规范

这是所有主流应用(如ChatGPT、文心一言官方应用)采用的架构设计,也是唯一符合安全规范的实现方式。

2.超时问题

在我的跨域问题解决后又发生了一个问题:
 

{"errorCode":-1,"errorMessage":"Invoking task timed out after 3 seconds","statusCode":433}

于是首先我在\miniprogram\cloudfunctions\aiChat\config.json中设置了

{
  "permissions": {
    "openapi": []
  },
  "timeout": 60,
  "triggers": [],
  "memorySize": 256
} 

但发现不起作用,于是,我又在云开发里设置超时时间改为了33s,成功解决了该问题(AI思考时间一般较长,默认3s肯定无法正确返回数据)

微信小程序接入AI API实现智能问答功能(以百度智能云为例)_第1张图片

,又是被bug上了一课的一天,下课!(看到这了,点个赞呗!)

你可能感兴趣的:(微信小程序,小程序,跨域,云开发,AI智能问答,API,超时)