微信小程序接入AI大模型API完整教程:从申请到上线,手把手带你做聊天助手(附源码)

阿里云上云采购季 2核2G云服务器99元/年 续费同价

微信小程序 + AI大模型,是 2026 年最值钱的组合之一。本文带你从零到一,完整实现一个能对话的小程序 AI 助手,代码全部开源,直接拿走用。


为什么要把AI接入小程序?

微信月活用户超 13 亿,小程序是触达用户最低门槛的方式——无需下载、即开即用。而大模型 API 已经从”玩具”变成了生产力工具:

  • 客服机器人:7×24 小时自动回复,降低人力成本
  • 智能问答:产品手册、FAQ 自动化处理
  • 内容生成:小程序内写文案、改文字、生剧情
  • 教育辅导:学科问答、作业批改

这篇文章讲的是最通用的接入方案——以通义千问 API 为例(国内访问稳定、免费额度充足),打通微信小程序的完整链路。


整体架构设计

直接从小程序调用第三方 AI API 有两个问题:
1. API Key 暴露风险:前端代码可被逆向,Key 泄漏即被盗刷
2. 跨域限制:小程序只允许访问备案域名

推荐架构:小程序 → 云函数 / 后端服务 → AI API

用户输入
   ↓
微信小程序(前端)
   ↓  wx.request 调用自己的后端
云服务器 / 腾讯云函数
   ↓  安全携带 API Key
通义千问 / OpenAI / 文心 API
   ↓  流式或完整响应
小程序展示结果

本文两种方案都给:
– 方案A:微信云开发(零服务器,适合快速上线)
– 方案B:自有云服务器 + Node.js(更灵活,推荐长期使用)


前置准备

1. 注册通义千问 API

前往 dashscope.aliyun.com 注册,获取 API Key。
新用户有免费 100 万 Token 额度(qwen-turbo 模型),够测试用。

2. 微信小程序账号

  • 登录 mp.weixin.qq.com 注册小程序
  • 记录 AppID
  • 在「开发管理 → 开发设置 → 服务器域名」添加你的后端域名(必须 HTTPS)

方案A:微信云开发(推荐新手)

步骤1:开通云开发环境

在微信开发者工具中:
1. 点击「云开发」→ 开通云环境
2. 记录环境 ID(格式:xxx-xxx123456)

步骤2:创建云函数

在项目根目录 cloudfunctions/ 下新建 aiChat 文件夹:

cloudfunctions/
└── aiChat/
    ├── index.js
    └── package.json

package.json

{
  "name": "aiChat",
  "version": "1.0.0",
  "main": "index.js",
  "dependencies": {
    "node-fetch": "^2.6.7"
  }
}

index.js(核心逻辑)

const fetch = require('node-fetch');

// API Key 存在云函数环境变量中,不要硬编码!
const API_KEY = process.env.DASHSCOPE_API_KEY;

exports.main = async (event, context) => {
  const { messages, systemPrompt } = event;

  // 构造请求体
  const requestBody = {
    model: 'qwen-turbo',
    input: {
      messages: [
        {
          role: 'system',
          content: systemPrompt || '你是一个专业的AI助手,请简洁、准确地回答问题。'
        },
        ...messages
      ]
    },
    parameters: {
      result_format: 'message',
      max_tokens: 1500
    }
  };

  try {
    const response = await fetch(
      'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(requestBody)
      }
    );

    const data = await response.json();

    if (data.output && data.output.choices) {
      return {
        success: true,
        content: data.output.choices[0].message.content,
        usage: data.usage
      };
    } else {
      return {
        success: false,
        error: data.message || '请求失败'
      };
    }
  } catch (err) {
    return {
      success: false,
      error: err.message
    };
  }
};

安全提示:API Key 通过「云开发 → 云函数 → 环境变量」配置,不要写在代码里。

步骤3:部署云函数

右键 aiChat 文件夹 → 上传并部署(云端安装依赖),等待完成。


方案B:自有服务器 + Node.js

如果你有云服务器(腾讯云/阿里云均可),用 Express 搭建中间层更灵活。

服务端代码(server.js)

const express = require('express');
const fetch = require('node-fetch');
const app = express();

app.use(express.json());

// 允许小程序跨域(生产环境请限制来源)
app.use((req, res, next) => {
  res.header('Access-Control-Allow-Origin', '*');
  res.header('Access-Control-Allow-Headers', 'Content-Type');
  next();
});

const API_KEY = process.env.DASHSCOPE_API_KEY; // 从环境变量读取

app.post('/api/chat', async (req, res) => {
  const { messages, systemPrompt } = req.body;

  if (!messages || !Array.isArray(messages)) {
    return res.status(400).json({ error: 'messages 参数错误' });
  }

  try {
    const response = await fetch(
      'https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation',
      {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${API_KEY}`,
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          model: 'qwen-turbo',
          input: {
            messages: [
              { role: 'system', content: systemPrompt || '你是一个专业的AI助手' },
              ...messages
            ]
          },
          parameters: { result_format: 'message', max_tokens: 1500 }
        })
      }
    );

    const data = await response.json();
    const content = data.output?.choices?.[0]?.message?.content;

    if (content) {
      res.json({ success: true, content });
    } else {
      res.json({ success: false, error: '模型未返回内容' });
    }
  } catch (err) {
    res.status(500).json({ success: false, error: err.message });
  }
});

app.listen(3000, () => console.log('AI服务启动,端口 3000'));
# 启动(配合 PM2 守护进程)
npm install express node-fetch
DASHSCOPE_API_KEY=your_key pm2 start server.js --name ai-chat

小程序前端实现

无论用哪种方案,前端代码基本相同,只是请求方式不同。

页面结构(pages/chat/chat.wxml)

<view class="container">
  <!-- 对话列表 -->
  <scroll-view class="chat-list" scroll-y scroll-into-view="{{scrollId}}">
    <view wx:for="{{messages}}" wx:key="index" 
          class="message-item {{item.role === 'user' ? 'user' : 'assistant'}}">
      <view class="avatar">{{item.role === 'user' ? '我' : 'AI'}}</view>
      <view class="bubble">
        <text>{{item.content}}</text>
      </view>
    </view>
    <!-- 加载动画 -->
    <view wx:if="{{loading}}" class="loading-item">
      <view class="avatar">AI</view>
      <view class="bubble loading">
        <text class="dot">●</text><text class="dot">●</text><text class="dot">●</text>
      </view>
    </view>
    <view id="bottom"></view>
  </scroll-view>

  <!-- 输入区 -->
  <view class="input-area">
    <input 
      class="input-box"
      value="{{inputText}}"
      bindinput="onInput"
      placeholder="输入你的问题..."
      confirm-type="send"
      bindconfirm="sendMessage"
    />
    <button class="send-btn" bindtap="sendMessage" disabled="{{loading}}">
      {{loading ? '...' : '发送'}}
    </button>
  </view>
</view>

核心逻辑(pages/chat/chat.js)

const SYSTEM_PROMPT = '你是一个专业的AI助手,回答简洁准确,中文作答。';

Page({
  data: {
    messages: [],       // 对话历史(发给API的格式)
    displayMessages: [], // 展示用(含时间戳等)
    inputText: '',
    loading: false,
    scrollId: 'bottom'
  },

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

  async sendMessage() {
    const text = this.data.inputText.trim();
    if (!text || this.data.loading) return;

    // 添加用户消息
    const userMsg = { role: 'user', content: text };
    const newMessages = [...this.data.messages, userMsg];

    this.setData({
      messages: newMessages,
      inputText: '',
      loading: true,
      scrollId: 'bottom'
    });

    try {
      let result;

      // ===== 方案A:云开发 =====
      result = await wx.cloud.callFunction({
        name: 'aiChat',
        data: {
          messages: newMessages,
          systemPrompt: SYSTEM_PROMPT
        }
      });
      const content = result.result?.content;

      // ===== 方案B:自有服务器(注释掉方案A,打开这段)=====
      // const res = await new Promise((resolve, reject) => {
      //   wx.request({
      //     url: 'https://你的域名/api/chat',
      //     method: 'POST',
      //     data: { messages: newMessages, systemPrompt: SYSTEM_PROMPT },
      //     success: resolve,
      //     fail: reject
      //   });
      // });
      // const content = res.data?.content;

      if (content) {
        this.setData({
          messages: [...newMessages, { role: 'assistant', content }],
          loading: false,
          scrollId: 'bottom'
        });
      } else {
        throw new Error('未获取到回复');
      }
    } catch (err) {
      wx.showToast({ title: '请求失败,请重试', icon: 'none' });
      this.setData({ loading: false });
    }
  }
});

样式(chat.wxss)

.container { display: flex; flex-direction: column; height: 100vh; background: #f5f5f5; }
.chat-list { flex: 1; padding: 16rpx; }
.message-item { display: flex; margin-bottom: 24rpx; align-items: flex-start; }
.message-item.user { flex-direction: row-reverse; }
.avatar { width: 60rpx; height: 60rpx; border-radius: 50%; background: #07c160; color: #fff;
          display: flex; align-items: center; justify-content: center; font-size: 22rpx; flex-shrink: 0; }
.message-item.user .avatar { background: #576b95; }
.bubble { max-width: 70%; padding: 16rpx 20rpx; border-radius: 16rpx; background: #fff;
          margin: 0 12rpx; font-size: 28rpx; line-height: 1.6; }
.message-item.user .bubble { background: #95ec69; }
.input-area { display: flex; padding: 16rpx; background: #fff; border-top: 1rpx solid #eee; }
.input-box { flex: 1; background: #f5f5f5; border-radius: 40rpx; padding: 16rpx 24rpx; font-size: 28rpx; }
.send-btn { margin-left: 16rpx; background: #07c160; color: #fff; border-radius: 40rpx;
            font-size: 28rpx; padding: 0 32rpx; }

多模型切换对比

模型 免费额度 速度 中文效果 适合场景
通义千问 Turbo 100万 Token 快 优秀 客服、问答
通义千问 Plus 20万 Token 中 极佳 复杂推理
文心一言 付费 快 优秀 创作、写作
DeepSeek V3 500万 Token 快 优秀 代码、分析
GPT-3.5 无(付费) 快 良好 英文场景

推荐:国内小程序首选通义千问或 DeepSeek,稳定且有足够免费额度。


常见问题处理

Q1:小程序请求被拦截(合法域名校验失败)

解决:在小程序后台「开发设置 → 服务器域名」添加你的 API 域名。本地调试可勾选「不校验域名」。

Q2:响应太慢,用户体验差

解决:使用流式输出(SSE)。通义千问支持 stream: true 参数,配合小程序的 wx.request 逐步展示文字。

Q3:对话历史太长,Token 超限

解决:只保留最近 N 轮对话,或对历史消息做摘要压缩:

// 只保留最近6条消息(3轮对话)
const trimmedMessages = messages.slice(-6);

Q4:API Key 安全问题

解决:永远不要在前端代码中暴露 Key,通过云函数或后端中转,服务端通过环境变量注入。


发布上线 Checklist

  • [ ] API Key 已存入环境变量,未硬编码
  • [ ] 服务器域名已在小程序后台配置
  • [ ] 已添加请求频率限制(防刷)
  • [ ] 已配置敏感词过滤
  • [ ] 错误处理完整,用户端有友好提示
  • [ ] 对话历史有长度限制

总结

微信小程序接入 AI 大模型的完整链路就是:

申请 API → 搭建中转服务 → 前端对接 → 安全加固 → 发布上线

整个流程一个下午就能跑通,核心是不要把 API Key 暴露在前端。选择云开发方案的话,连服务器都省了,最适合独立开发者快速验证想法。

代码已整理,有问题欢迎留言交流。


关于作者

长期关注大模型应用落地与云服务器实战,专注技术在企业场景中的落地实践。

个人博客:y1cloud.cn —— 持续更新云计算、AI大模型实战教程,欢迎访问交流。

发表评论