- 3行代码搞定微信小程序接入DeepSeek满血版!
前言 由于最近 DeepSeek 火爆出圈,我相信大多数的微信小程序开发者开工第一个任务就是接入DeepSeek能力到自家的小程序产品中,接下来我分享下微信小程序快速接入DeepSeek的方法! 步骤 首先打开「微信开发者工具」进入左上角的「云开发」开通环境 [图片] 开通成功后可以云开发的控制台页面获取环境ID [图片] 第一步:初始化,建议放在app.js里面 [图片] [代码]// 微信小程序基础库从 3.7.1 版本开始内置了云开发 AI+ 能力,开发者可以直接通过小程序中的 wx.cloud.extend.AI 调用。 在使用基础库 AI+ 能力前,需要传入云开发环境进行初始化。 wx.cloud.init({ env: "环境ID" }); [代码] 第二步:在需要使用的页面添加调用DeepSeek代码 [代码]// 创建模型 const model = wx.cloud.extend.AI.createModel("deepseek"); const res = await model.generateText({ model: "deepseek-r1", messages: [{ role: "user", content: "9.9和9.11谁更大?" }], }); console.log(res); [代码] 请求返回,可以看到输出了的message中有思维链内容和结果内容 [图片] 以上这种方式是直接获取结果方式,如果做实时打印的效果,可以用流式使生成文本 [代码]// 创建模型 const model = wx.cloud.extend.AI.createModel("deepseek"); const res = await model.streamText({ data: { model: "deepseek-r1", messages: [ { role: "user", content: "9.9和9.11谁更大?" } ] } }); // 当使用 deepseek-r1 时,模型会生成思维链内容 for await (let event of res.eventStream) { if (event.data === '[DONE]') { continue; } const data = JSON.parse(event.data); // 打印思维链内容 const think = (data?.choices?.[0]?.delta)?.reasoning_content; if (think) { console.log(think); } // 打印生成文本内容 const text = data?.choices?.[0]?.delta?.content; if (text) { console.log(text); } } [代码] 到这里微信小程序加入DeepSeek满血版能力就搞定了! 编排AI智能体(Agent) 在实际业务中不仅仅是接入还需要用到给DeepSeek结合业务封装一个AI智能体,其中包含人设与回复约束以及相关专业知识库。这个时候首先进入云开发后台进行AI智能体的编排。 云开发地址:https://tcb.cloud.tencent.com/dev 进入云开发后后台找到【AI+】模块,然后可以新增Agent设置DeepSeek-671B模型,设置人设与回复逻辑和知识库,详细可见《如何快速开发一款AI小程序?》,这篇文章详细介绍了AI智能体的创建与知识库的设置。 [图片] 当我们编排好了Agent,在前端业务代码中如何调用呢? 以我创建好的【小红书爆款文案】智能体为例,可以在右边【接入引导】区域选中【SDK】 [图片] 这里面提供了详细的接入代码,直接复制使用即可,包含了以下功能下面所有功能都需要智能体ID,获取智能体ID方式如下: [图片] 发送消息 [代码]const res = await wx.cloud.extend.AI.bot.sendMessage({ data: { botId: '智能体ID', msg: "你是谁" } }) for await (let x of res.textStream) { console.log(x) } [代码] 获取 Agent 信息 [代码]const res = await wx.cloud.extend.AI.bot.get({ botId: "智能体ID" }); console.log(res); [代码] 查看与 Agent 的聊天记录 [代码]const res = await wx.cloud.extend.AI.bot.getChatRecords({ botId: "智能体ID", pageNumber: 1, pageSize: 10, sort: "asc", }); console.log(res); [代码] 对某一条聊天记录进行反馈 [代码]const res = await wx.cloud.extend.AI.bot.sendFeedback({ userFeedback: { botId: "智能体ID", recordId: "recordId-xxx", comment: "非常棒", rating: 5, tags: ["优美"], aiAnswer: "落英缤纷", input: "来个成语", type: "upvote", }, }); console.log(res); [代码] 查看反馈记录 [代码]const res = await wx.cloud.extend.AI.bot.getFeedBack({ botId: "智能体ID", from: 0, to: 0, maxRating: 4, minRating: 3, pageNumber: 1, pageSize: 10, sender: "user-a", senderFilter: "include", type: "upvote", }); console.log(res) [代码] 获取 Agent 推荐问题 [代码]const res = await wx.cloud.extend.AI.bot.getRecommendQuestions({ data: { botId: "智能体ID", msg: "你是谁" } }) for await (let x of res.textStream) { console.log(x) } [代码] 一键生成AI对话组件 除此之外如果还需要对话界面,可以进入「可视化开发」模块 [图片] 选择「从空白创建」应用,进入应用编辑台找到最右边的「区块」搜索「Agent」选中「Anget-UI」 [图片] 然后在配置里面输入智能体ID即可 [图片] 确认没有问题后,可以右上角「发布」选中「导出代码包」根据「使用指引」接入到自家微信小程序产品中 [图片] 前端AI智能体对话界面代码直接拿来就用! 除此之外也可以在微信开发者工具中新建小程序模板,选择 Agent UI 源码模板 [图片] 最后 这样一来从接入DeepSeek能力到根据业务定制化DeepSeek智能体再到AI对话界面统统搞定了!下班! 相关推荐 DeepSeek应用场景深度分析
02-19 - Canvas绘制圆角矩形
Chrome 99 之前常规操作: [代码] ctx.beginPath(); ctx.moveTo(x+topLeft, y); ctx.arcTo(x+width, y, x+width, y+height, topRight); ctx.arcTo(x+width, y+height, x, y+height, bottomRight); ctx.arcTo(x, y+height, x, y, bottomLeft); ctx.arcTo(x, y, x+width, y, topLeft); ctx.closePath(); ctx.fill(); [代码] 其中[代码]x[代码]、[代码]y[代码]表示矩形的起点坐标,[代码]width[代码]、[代码]height[代码]分别表示矩形的宽、高,[代码]topLeft[代码]、[代码]topRight[代码]、[代码]bottomRight[代码]、[代码]bottomLeft[代码]分别表示矩形左上、右上、右下和左下圆角半径大小。 下面来解读一下[代码]arcTo()[代码]的语法,以[代码]ctx.arcTo(x1,y1,x2,y2,radi)[代码]为例。 第一部分 [代码](x1,y1)[代码]坐标点,可以分成两块来理解,第一块我们可以理解为当前画笔停留的坐标点到[代码](x1,y1)[代码]的一条直线,第二块我们可以理解为即将要绘制圆角的部位,也就是所在矩形的四个顶角的位置。 第二部分 [代码](x2,y2)[代码]坐标点,也可以分成两块来理解,第一块我们可以理解为[代码](x1,y1)[代码]坐标点到[代码](x2,y2)[代码]的一条直线,这条直线与第一部分理解的直线形成一个夹角,那么圆角就绘制在这个夹角(内角)之间,并与夹角两边相切,第二块可以理解为画笔画完当前圆角最后所停留的坐标点。 第三部分 [代码]radi[代码]那就很容易理解了,也就是当前即将绘制的圆角的半径。 [图片] 然后以此类推,完成圆角矩形的绘制。 Chrome 99之后一行代码: [代码]ctx.roundRect(x, y, width, height, [topLeft, topRight, bottomRight, bottomLeft]); ctx.fill(); [代码] 最后可以做下兼容: [代码]if (ctx.roundRect) { ctx.roundRect(x, y, width, height, [topLeft, topRight, bottomRight, bottomLeft]); }else { ctx.beginPath(); ctx.moveTo(x+topLeft, y); ctx.arcTo(x+width, y, x+width, y+height, topRight); ctx.arcTo(x+width, y+height, x, y+height, bottomRight); ctx.arcTo(x, y+height, x, y, bottomLeft); ctx.arcTo(x, y, x+width, y, topLeft); ctx.closePath(); } [代码] 结尾祝君开发顺利,生活愉快!
2024-05-08 - 省钱有道之 云开发环境共享小结
#前言 最近为了节省一点小程序的运营成本,一些没啥流量的小程序如果每个月也要19块略微有些肉疼(主要还是穷),研究了一下云环境共享,在这里简单做一下总结。 [图片] 这里有官方的小程序环境共享文档需提前了解一下,具体共享步骤按官方文档操作即可。 https://developers.weixin.qq.com/miniprogram/dev/wxcloud/guide/resource-sharing/introduce.html #注意点 共享环境有几个注意点大致如下: 1、必须是相同主体 2、开通了云开发环境的小程序可以共享给同主体的小程序、公众号,被共享方无需开通云开发环境 3、一个云开发环境最多可以共享给10个小程序/公众号 4、共享后双发均可主动解除 5、按官方文档要求,资源方需有云函数cloudbase_auth,测试时发现没有这个云函数其实也能正常运行,可能我验证的场景还不够多 6、云能力初始化的方式不同,资源方按传统的云环境初始化方式即可,也就是 wx.cloud.init({ env: env.activeEnv, traceUser: true }); 而调用方的初始化方式有所不同 const cloud = new wx.cloud.Cloud({ //资源方AppID resourceAppid, //资源方环境ID resourceEnv, }) // 跨账号调用,必须等待 init 完成 // init 过程中,资源方小程序对应环境下的 cloudbase_auth 函数会被调用,并需返回协议字段(见下)来确认允许访问、并可自定义安全规则 const initRes = await cloud.init(); 后续调用资源方的云函数就用这个cloud就行了:cloud.callFunction({...}); 7、调用方有操作到云存储文件的api也需要用6步骤中的cloud 8、云存储fileId需要用cloud.getTempFileURL转换成临时/永久链接,否则在调用方无法展示 9、一些api的云调用方式也有变化,需指明具体的appid。比如A小程序授权给了B小程序,想给B小程序推送客服消息需要写成 await cloud.openapi({appid:B小程序appid}).customerServiceMessage.send({...}); 10、获取调用方的appid/openid/unionid也有所不同 // 跨账号调用时,由此拿到来源方小程序/公众号 AppID console.log(wxContext.FROM_APPID) // 跨账号调用时,由此拿到来源方小程序/公众号的用户 OpenID console.log(wxContext.FROM_OPENID) // 跨账号调用、且满足 unionid 获取条件时,由此拿到同主体下的用户 UnionID console.log(wxContext.FROM_UNIONID) #适配 基于以上注意点,开始进行适配,由于我是一套代码部署N个小程序,然后一个云环境共享给其他小程序,希望通过配置决定哪个小程序作为资源方,哪些作为调用方 首先是云开发环境的初始化: 1、env.js 环境配置: //云开发环境 const cloudBase = { //使用共享云环境资源,资源方=false,调用方=true useShareResource: false, //资源方AppID resourceAppid: "wx9d2xxxxxxxx0088", //资源方环境ID resourceEnv: "prod-9gxqvi3qb3c257ef", //云环境ID prod: "prod-9gxqvi3qb3c257ef" } 2、api.js 操作模块 const env = require('../env.js'); let cloud; /** * 初始化云能力 * @returns {Promise} */ const wxCloudInit = async function () { const {cloudBase} = env; if (!wx.cloud) { console.error('请使用 2.2.3 或以上的基础库以使用云能力') } else if (cloudBase.useShareResource) { const {resourceAppid, resourceEnv} = cloudBase; // 声明新的 cloud 实例 cloud = new wx.cloud.Cloud({ //资源方AppID resourceAppid, //资源方环境ID resourceEnv, }) // 跨账号调用,必须等待 init 完成 // init 过程中,资源方小程序对应环境下的 cloudbase_auth 函数会被调用,并需返回协议字段(见下)来确认允许访问、并可自定义安全规则 const initRes = await cloud.init(); console.log("初始化云能力完毕:", initRes, "资源方appid:", resourceAppid, "资源方环境ID:", resourceEnv); } else { wx.cloud.init({ env: env.activeEnv, traceUser: true }); console.log("初始化云能力完毕,当前环境:", env.activeEnv); cloud = wx.cloud; } this.cloud = cloud; } /** * 云函数调用 * @param name * @param data * @param success * @param fail * @param complete */ const callCloudFunction = function (name, data, success, fail, complete) { //执行云函数 cloud.callFunction({ // 云函数名称 name: name, // 传给云函数的参数 data: Object.assign({}, data, {env: env.activeEnv}) }).then(res => { typeof success == 'function' && success(res); }).catch(res => { typeof fail == 'function' && fail(res); }).then(res => { typeof complete == 'function' && complete(res); }); }; 3、在app.js中初始化云环境,后续有用到wx.cloud的都需要改成api.cloud const api = require('utils/api.js'); App({ onLaunch: async function (options) { await api.wxCloudInit(); } }); 其次是资源方的获取用户信息调整 每次都要判断wxContext.FROM_OPENID是否为空,不为空则是调用方的用户信息,为空则是资源方的用户信息,略微繁琐,干脆封装了一个npm包wx-server-inherit-sdk,改造了一下getWxContext函数,源码如下,引入这个包后也就可以不用引入官方的wx-server-sdk const cloud = require('wx-server-sdk'); // 保存原始getWXContext方法到另一个变量 const originalGetWXContext = cloud.getWXContext; cloud.getWXContext = function () { //调用原始getWXContext方法 const wxContext = originalGetWXContext.call(this); const {FROM_APPID, FROM_OPENID} = wxContext; //云开发环境共享时获取到的APPID会替换成源方APPID if (FROM_APPID) { Object.assign(wxContext, {APPID: FROM_APPID}); } //云开发环境共享时获取到的OPENID会替换成源方OPENID if (FROM_OPENID) { Object.assign(wxContext, {OPENID: FROM_OPENID}); } return wxContext; } module.exports = cloud; 到此也就大功告成。为了省钱也是够折腾的[哭笑]
2023-08-28