目录
摘要
一、前言
二、扣子API
1. 扣子的API文档理解
2. 对话API深度理解
2.1 bot_id
2.2 additional_messages
2.2.1 role
2.2.2 type
2.2.3 content_type
2.2.4 content
2.3 stream
三、.js文件——发起对话(逻辑代码)
1. 纯文本text对话
1.1 content传入内容包装
2. 图片多模态object_string对话
2.1 上传文件获取文件id
2.2 wx.request访问扣子API(文件和图片)
四、总结
摘要
本系列文章实现了运用国内扣子Coze与微信开发者工具实现一个简单的微信小程序页面,一个与自定义AI语言交互问答的功能。本系列文章详细讲解的从创建bot到微信小程序页面还有接口的编写。后续可能会加入后端Java+SpringBoot的逻辑功能来丰富项目。
成果预览:
专栏相关操作 传送==>(^_^)
01、创建自定义Bot
02、微信小程序对话页面简单设计
03、微信小程序js逻辑和接口实现
一、前言
本文主要讲的是运用开发者工具调用微信的API接口并且连接Coze的API接口,实现可以通过微信小程序与自定义的Bot进行AI对话。
一个星期前扣子提供的API只有一个,当时为了处理逻辑我采用的是微信开发者+SpringBoot后端框架来编写,但是上周突然发现扣子更新了API文档,添加了巨巨巨巨巨巨巨多的API接口,开心之后又开始悲催的改改改(呜呜呜~~~)
因为是这种情况,感觉简单的对话再采用前后端的方式就比较繁琐,扣子的新的API可以实现大部分的功能,因此简单的对话我暂时去掉的后端的部分,让微信小程序直接与扣子通信,后期增加其他功能再添加后端部分。
二、扣子API
1. 扣子的API文档理解
在扣子的主页的左下角有一个扣子API,点击之后就有了快速开始的教程,其中先获取个人访问令牌的部分已经在【扣子coze+微信开发者工具】实现ai自定义对话01中讲过,可以参考传送门(上面上面)。
先看目录,API接口之前的部分基本都讲过。 接口分为Bot、会话、消息、对话、文件、知识库、错误码7个部分。
其中,会话、消息、对话我刚开始很难区分,就不断反复看文档,我的理解是这样的:
会话就是一个全新的对话页面,一个用户可以与一个Bot有多个会话;消息每条发送的消息,包括用户发的和Bot发的,单位为(条),一条消息;消息的API接口可以直接更改对话过程中的消息内容,包括已经发送过得消息;对话一般就是一问一答,用户向Bot发起一个提问,Bot回答,这样一个过程为对话;会话中可以有多个对话,多个消息;对话一般为两条消息。
我目前的功能主要是一个简单的对话,因此并没有采用会话,而只有对话,后期会逐渐增加关于会话、消息的功能。
2. 对话API深度理解
对话的又分为发起对话、查看对话详情、查看对话消息详情、提交工具执行结果。
这里我们主要来分析“发起对话”这一部分。
官方给出的解释是:调用此接口发起一次对话,支持添加上下文和流式响应。
通俗来说就是可以带着已经和Bot说过的话再向它提问,他给出的方式呢可以是非流式响应也可以是流式响应,官方的文档给出的内容非常的多,也给了很多例子,但是没有给出用Java和JS方式怎么去调用。
我用postman测了很多,然后再用Java语言和JS去编写测试。因为后端被我去掉,所以这里也不再展示,只展示用微信开发者工具调用的方式。
基础信息官方写的简介明了,重点在于Body部分。
2.1 bot_id
要进行会话聊天的 Bot ID。
进入 Bot 的 开发页面,开发页面 URL 中 bot 参数后的数字就是 Bot ID。例如https://www.coze.cn/space/341****/bot/73428668*****,bot ID 为73428668*****。
要确保已经完成了【扣子coze+微信开发者工具】实现ai自定义对话01 中的获取个人访问令牌的部分。
2.2 additional_messages
对话的附加信息。可以通过此字段传入本次对话中用户的问题。
当 auto_save_history=true 时,additional_messages 会作为消息先添加到会话中,然后作为上下文传给大模型。当 auto_save_history=false 时,additional_messages 只会作为附加信息传给大模型,additional_messages 和模型返回等本次对话的所有消息均不会添加到会话中。additional_messages的内容格式有 role、type、content、content_type、meta_data。
2.2.1 role
分为user和assistant,当用小程序向扣子发送消息时都是作为user发送消息。
2.2.2 type
消息类型。当作为user发消息时,type只能为query,可以不写。
2.2.3 content_type
text:文本。object_string:多模态内容,即文本和文件的组合、文本和图片的组合。card:卡片。此枚举值仅在接口响应中出现,不支持作为入参。2.2.4 content
可以为text内容和object_string多模态内容。
当content_type为text时只能发送文本内容;当content_type为object_string时,可以发送文本、文件、图片混合输入。
如果想要发送文件或者图片时,要先将图片和文件上传给Bot(用到目录中的文件部分的API),这样Bot会返回给用户一个照片或者文件的id,客户端再携带着这个id调用此方法。
也可以不用id用url,但是必须是文件或图片内容的在线地址,必须是可公共访问的有效地址。
只发送文本消息时,建议采用直接text。
2.3 stream
是否启用流式返回。
如果是 false(默认)则是非流式响应,但是在对话中,非流式响应只会返回本次对话的所有数据,比如本次对话的 chat_id、状态等,并不会返回对问题的回答内容,需要去调用“查看对话消息详情”这一接口。这也是可以实现的。
如果是true则是流式响应,服务端以数据流的形式逐条发送给客户端,包括触发的各种事件。在返回到的数据流中,当第一次出现event事件为conversation.message.completed时,会一次性返回回答的所有内容。所以当小程序对话想获取Bot的回答内容可以针对此条数据进行拦截,也可以调用其他方式实时展示流式响应(我查了一下微信小程序采用流式响应还需要第三方或者其他方式比较麻烦,因此我暂时先采用数据拦截的方式)。
流式响应事件的其他内容可以去官方文档里再去仔细查看。
三、.js文件——发起对话(逻辑代码)
1. 纯文本text对话
1.1 content传入内容包装
角色为用户user;content为向Bot发送的内容;消息类型为纯文本text。
"additional_messages": [ { "role": "user", "content": query, "content_type": "text" } ]
1.2 wx.request访问扣子API(纯文本)
访问成功则打印数据流,访问失败通过reject返回错误信息。
wx.request({ url: "https://api.coze.cn/v3/chat", method: 'POST', header: { 'Authorization': 'Bearer 自己的个人访问令牌', 'content-type': 'application/json' }, data: { "bot_id": "自己的Bot_id", "user_id": "自己的user_id", "stream": true, "additional_messages": [ { "role": "user", "content": query, "content_type": "text" } ] }, success: (res) => { console.log(res.data); resolve(res.data); }, fail: (err) => { // console.error("Request failed:", err); reject(err); // 如果请求失败,通过reject传递错误信息 } });
2. 图片多模态object_string对话
2.1 上传文件获取文件id
图片路径通过微信的接口wx.chooseMedia进行获取(微信原本的wx.chooseImage已经不能用了,现在统一为wx.chooseMedia)
wx.chooseMedia({ count: 1,// 最多多少,这里设为最多一张 mediaType: ['image', 'video'],//图片或者视频 sourceType: ['album', 'camera'], maxDuration: 30, camera: 'back', //后置相机 success: (res) => { const tempFilePath = res.tempFiles[0].tempFilePath; // 创建一个新的图片消息对象 const im = { sender: 'user', content: tempFilePath, type: 'image', }; this.data.messages.push(im); this.setData({ messages: this.data.messages, }); this.uploadFile(tempFilePath); }, fail: (err) => { console.error("Choosing media failed:", err); }, });
将上述代码获得的图片路径传给wx的上传文件的接口;
async uploadFile(tempFilePath) {//图片路径 wx.uploadFile({ url: 'https://api.coze.cn/v1/files/upload', // 图片上传API地址 header: { 'Authorization': 'Bearer 自己的私人访问令牌', 'content-type': 'multipart/form-data' }, filePath: tempFilePath, name: 'file',//name必须为file formData: { 'file': tempFilePath }, // 附加的表单数据,如有需要 //调用返回 success: (res) => { wx.hideLoading(); const data = res.data; const file = JSON.parse(data); this.data.fileId = file.data.id console.log(this.data.fileId); }, fail: (err) => { this.setData({ uploading: false }) console.log(err.errMsg); }, }); },
这样打印出来的fileId就是我们后面需要再传递的文件id。
2.2 wx.request访问扣子API(文件和图片)
其中的message是用户向Bot发送的内容;fileId为我们刚刚获取的文件id;content_type改为object_string。
这里需要注意的是:content内容中的格式,官方文档给的是
"content": "[{\"type\":\"text\",\"text\":\"你好我有一个帽衫,我想问问它好看么,你帮我看看\"},{\"type\":\"image\",\"file_id\":\"{{file_id_2}}\"},{\"type\":\"file\",\"file_id\":\"{{file_id_1}}\"}]",
但是用这个格式并不能发送成功,查了一下与JSON格式相关,就转换了一下格式才成功:
"content": `[{"type":"text","text":"${message}"},{"type":"image","file_id":"${this.data.fileId}"}]`,
实现:
wx.request({ url: "https://api.coze.cn/v3/chat", method: 'POST', header: { 'Authorization': 'Bearer 自己的个人访问令牌', 'content-type': 'application/json' }, data: { "bot_id": "自己的bot_id, "user_id": "自己的用户id", "stream": true, "additional_messages": [ { "role": "user", "content": `[{"type":"text","text":"${message}"},{"type":"image","file_id":"${this.data.fileId}"}]`, "content_type": "object_string" } ] }, success: (res) => { console.log(res.data); resolve(res.data); this.setData({ fileId: '',// 清空fileId以便下次保存 }); }, fail: (err) => { reject(err); // 如果请求失败,通过reject传递错误信息 } });
这样就可以获取到Bot的流式响应回答,再很对event事件进行拦截便可以获得想要的回答。
虽然Bot的回答不是很令人满意(应该是缺少相关插件和文本),但是效果基本可以呈现,后续再进行调整改进!
四、总结
本文介绍了扣子的API官方文档,还有使用微信开发者工具输入内容和获取本机图片,调用扣子的API实现AI通信。
作者为正在学习的在读研究生,希望可以与大家交流学习,欢迎指正!!
后续会持续改进更新完善系统,增加其他功能。
如需获取全部代码可以联系作者。(拜托拜托~一键三连~)