微信小程序 + 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大模型实战教程,欢迎访问交流。
