欢迎访问王牌网络(WPOK.CN)- 手机就是POS机,费率最低0.38%,免费招代理,咨询微信:860056696!
当前位置:首页>AI>【从零开始】基于AI大模型的微信聊天机器人实现-COZE

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

从零开始打造你的专属微信AI聊天机器人!

前言

前阵子,我分享了把大模型接入微信机器人的教程,该教程基于 chatgpt-on-wechat项目,其中用到了 LinkAI、智谱 AI 这两个平台的模型。在后续的测试中,发现存在一些问题,比如智谱 AI 知识库的调用存在问题,有时击中率很低。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

于是我停用了这个机器人,并寻找新的解决办法。直到发现了 coze(字节推出的 AI 机器人和智能体创建平台),结果发现 coze 非常好用,也很符合我的使用场景。

因此,写下这篇文章来记录从 0 搭建属于自己的微信群聊 AI 机器人的部署过程,包括服务器购买与配置、项目部署、接入 coze、修改 coze 配置、接入知识库、插件安装等。

原本计划将此篇文章分为上下两篇,最后还是决定直接完成整篇,篇幅虽长,但操作相对简单,跟着操作基本没问题。

本篇总体分两大块:

  • chatgpt-on-wechat项目的部署
  • Coze机器人配置

chatgpt-on-wechat 项目的部署有两种方式:

  1. 源码部署。
  2. 我已制作了docker镜像,可一键部署。

Docker镜像获取:

公众号回复(注意大小写)ChatonWeChat

什么是Coze?

【从零开始】基于AI大模型的微信聊天机器人实现-COZECoze 是一个面向所有人的下一代 AI 应用程序和聊天机器人开发平台。它允许用户轻松创建各种聊天机器人,无论用户是否具有编程经验。用户可以将自己的聊天机器人部署和发布到不同的社交平台,例如豆包、飞书、微信等。Coze 提供了丰富的功能,包括角色和提示、插件、知识库、开场对话、预览和调试、工作流等,用户还可以创建自己的插件。此外,Coze 还有一个 Bot 商店,展示各种功能的开源机器人,供用户浏览和学习。

注册coze

进入官网

来到coze官网

  • 国内:https://www.coze.cn/
  • 国外:https://www.coze.com/

这里我用的是国内的coze。

如果你的业务是海外的,建议用国外的coze,这里不过多讲述。

注册

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

获取APIkey

我们需要获取APIKey调用coze大模型接口。

注册好后点击主页下方的扣子API【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击API令牌选项【从零开始】基于AI大模型的微信聊天机器人实现-COZE

添加新令牌

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

配置个人令牌。

  • 名称:随便起,这里我保持默认的名称。
  • 过期时间:永久有效。
  • 选择指定团队空间:Personal
  • 权限:全部勾选上。

最后点击确认。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

创建成功,这里生成的令牌需要保存好!后面会用到,点击复制按钮复制令牌。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

创建Bot

回到主页点击左边创建Bot

【从零开始】基于AI大模型的微信聊天机器人实现-COZE
  • 工作空间选择默认的Personal
  • Bot名称填写你自己定义的
  • Bot功能介绍随便填

填写完成后点击确认

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

创建成功,进入配置界面。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

获取BotID

先不做详细配置,直接点击发布。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

开场白设置直接跳过,我们不需要。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

发布记录这里随意填,我填写的是版本号。

选择发布平台:这里勾选扣子Bot商店、Bot as API。(如果你获取APIkey这一步没做的话,这里是看不到Bot as API这个选项的)

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

然后点击发布,可以看到成功发布。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击复制Bot链接

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

链接如下:https://www.coze.cn/store/bot/7388292182391930906?bot_id=true

其中7388292182391930906就是BotID,将BotID保存好,后面我们会用到。

这里需要注意一点:

每次对Bot进行修改,发布后的BotID都会变化!

注册云服务器

云服务器商有很多,这里我选择阿里云进行部署,可能价格不是最便宜的,这个需自行比对。

https://www.aliyun.com/daily-act/ecs/99program?spm=5176.8789780.J_3965641470.1.67bc39fbuaQ3h4

每个用户可购买一次,2核2G、3M固定带宽配置完全够用。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

配置参考

这里简单的说下购买界面的配置,方便大家理解。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

镜像选择CentOS 7.9 64位

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

云盘40G

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

公网IP勾选,按照固定带宽计费,最低带宽1Mbps。

开通IPV4端口/协议这里都勾选

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

登录凭证这里选择自定义密码,登录密码保存好,用于后面连接服务器用。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

云服务器配置

安装宝塔面板

首先需要安装服务器的管理界面,这里选择安装宝塔

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

连接时提示需要登录实例,输入密码(创建实例时设置的密码)

【从零开始】基于AI大模型的微信聊天机器人实现-COZE
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

宝塔安装命令

yum install -y wget && wget -O install.sh https://download.bt.cn/install/install_6.0.sh && sh install.sh ed8484bec
【从零开始】基于AI大模型的微信聊天机器人实现-COZE
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装完成,将红框里的链接以及账号密码保存下来。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

注意看!这里提示需要开放对应的端口号。我们需要去阿里云安全组里配置对应的端口号。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

配置安全组规则

点击管理规则

【从零开始】基于AI大模型的微信聊天机器人实现-COZE点击手动添加(这里入方向有很多的端口号是因为我这个服务器是之前就买的,然后闲置下来的,入方向的端口号是之前加上的,这里无需跟我一样添加)

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

这里添加808013695端口。8080端口是我们后面要部署项目所用到的端口号,是固定的。13695是宝塔面板访问需要开通的端口号,这里每个人生成的端口号不一样。注意你的端口号!

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

保存成功

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

宝塔配置

进入宝塔

安全组设置完毕后,进入到刚才保存的宝塔链接,选择外网面板地址,复制到浏览器中打开。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

进入后需要登录,填入刚才生成的username和password

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

绑定宝塔官网账号

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装套件

首次进入后会推荐安装套件,这里选择LNMP

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

然后这个界面不要关闭,耐心等待安装完成

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装python

点击网站--python项目--python版本管理

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

python版本选择3.9.7(这里最好在python3.10以下,chatgpt-on-wechat这个项目python3.10以上可能会有一些问题)

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

等待安装完毕

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

项目部署

源码部署

github下载项目源代码https://github.com/zhayujie/chatgpt-on-wechat截至文章写的时候,版本是1.6.8

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

来到宝塔面板--文件--路径/www/wwwroot【从零开始】基于AI大模型的微信聊天机器人实现-COZE

将下载的压缩包上传

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

右键解压

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

然后来到网站--python项目--添加python项目

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

项目路径:选择刚才解压后的文件夹路径。

项目名称:保持默认。

运行文件:选择项目文件夹内的app.py脚本

项目端口:8080(勾选后面的放行端口)

Python版本:刚才已安装的3.9.7

框架:选择python

运行方式:python

安装依赖包:这里自动会选择项目文件夹内的requirements.txt文件

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击提交。

耐心等待,会看到创建完毕。【从零开始】基于AI大模型的微信聊天机器人实现-COZE

记得来到阿里云实例这里修改安全组【从零开始】基于AI大模型的微信聊天机器人实现-COZE

管理规则

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

入方向这里选择手动添加


【从零开始】基于AI大模型的微信聊天机器人实现-COZE

端口范围设置8080
源设置0.0.0.0
然后点击保存


【从零开始】基于AI大模型的微信聊天机器人实现-COZE

打开终端。如果弹出输入ssh密钥,就输入创建服务器时的密码。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

终端界面输入

pip3 install -r requirements.txt

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装完毕

接着安装可选组件

pip3 install -r requirements-optional.txt
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装完毕

Docker镜像部署

来到宝塔的Docker界面,如果是新建的服务器是没有安装docker服务的。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击安装。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装完毕,来到宝塔的/www/wwwroot根目录。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

将镜像上传

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

导入镜像,路径选择刚才上传的路径/www/wwwroot

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

导入成功

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

来到容器--添加容器

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

容器名称:随意填

镜像:选择刚才导入的镜像

端口:8080(记得检查服务器的安全组规则)

直接选择创建。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

创建成功

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击日志

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

可以看到项目已经正常运行并生成了微信登录二维码,这时不要急着去扫,还需要修改下项目配置。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

到这里为止,使用docker镜像部署项目已经完成了,接下来跟着修改COW配置即可。这里红框区域简单框选出需要修改的地方,具体修改的含义在下面会有讲到。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

修改完后重启项目。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

再次扫码登录即可。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

修改COW

这里说下,如果你是docker镜像部署的,修改支持COZE这一步直接省略,无需修改。直接到修改配置这步去修改config.json

修改支持COZE

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

/www/wwwroot/chatgpt-on-wechat-1.6.8文件夹内,config.py文件第177行后添加

    "model""coze",
  "coze_api_base""https://api.coze.cn/open_api/v2",
  "coze_api_key""",
  "coze_bot_id""",

如下:

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

config.py完整代码

# encoding:utf-8

import json
import logging
import os
import pickle
import copy

from common.log import logger

# 将所有可用的配置项写在字典里, 请使用小写字母
# 此处的配置值无实际意义,程序不会读取此处的配置,仅用于提示格式,请将配置加入到config.json中
available_setting = {
# openai api配置
"open_ai_api_key""",  # openai api key
# openai apibase,当use_azure_chatgpt为true时,需要设置对应的api base
"open_ai_api_base""https://api.openai.com/v1",
"proxy""",  # openai使用的代理
# chatgpt模型, 当use_azure_chatgpt为true时,其名称为Azure上model deployment名称
"model""gpt-3.5-turbo",  # 可选择: gpt-4o, gpt-4-turbo, claude-3-sonnet, wenxin, moonshot, qwen-turbo, xunfei, glm-4, minimax, gemini等模型,全部可选模型详见common/const.py文件
"bot_type""",  # 可选配置,使用兼容openai格式的三方服务时候,需填"chatGPT"。bot具体名称详见common/const.py文件列出的bot_type,如不填根据model名称判断,
"use_azure_chatgpt"False,  # 是否使用azure的chatgpt
"azure_deployment_id""",  # azure 模型部署名称
"azure_api_version""",  # azure api版本
# Bot触发配置
"single_chat_prefix": ["bot""@bot"],  # 私聊时文本需要包含该前缀才能触发机器人回复
"single_chat_reply_prefix""[bot] ",  # 私聊时自动回复的前缀,用于区分真人
"single_chat_reply_suffix""",  # 私聊时自动回复的后缀,n 可以换行
"group_chat_prefix": ["@bot"],  # 群聊时包含该前缀则会触发机器人回复
"group_chat_reply_prefix""",  # 群聊时自动回复的前缀
"group_chat_reply_suffix""",  # 群聊时自动回复的后缀,n 可以换行
"group_chat_keyword": [],  # 群聊时包含该关键词则会触发机器人回复
"group_at_off"False,  # 是否关闭群聊时@bot的触发
"group_name_white_list": ["ChatGPT测试群""ChatGPT测试群2"],  # 开启自动回复的群名称列表
"group_name_keyword_white_list": [],  # 开启自动回复的群名称关键词列表
"group_chat_in_one_session": ["ChatGPT测试群"],  # 支持会话上下文共享的群名称
"nick_name_black_list": [],  # 用户昵称黑名单
"group_welcome_msg""",  # 配置新人进群固定欢迎语,不配置则使用随机风格欢迎
"trigger_by_self"False,  # 是否允许机器人触发
"text_to_image""dall-e-2",  # 图片生成模型,可选 dall-e-2, dall-e-3
# Azure OpenAI dall-e-3 配置
"dalle3_image_style""vivid"# 图片生成dalle3的风格,可选有 vivid, natural
"dalle3_image_quality""hd"# 图片生成dalle3的质量,可选有 standard, hd
# Azure OpenAI DALL-E API 配置, 当use_azure_chatgpt为true时,用于将文字回复的资源和Dall-E的资源分开.
"azure_openai_dalle_api_base"""# [可选] azure openai 用于回复图片的资源 endpoint,默认使用 open_ai_api_base
"azure_openai_dalle_api_key"""# [可选] azure openai 用于回复图片的资源 key,默认使用 open_ai_api_key
"azure_openai_dalle_deployment_id":""# [可选] azure openai 用于回复图片的资源 deployment id,默认使用 text_to_image
"image_proxy"True,  # 是否需要图片代理,国内访问LinkAI时需要
"image_create_prefix": ["画""看""找"],  # 开启图片回复的前缀
"concurrency_in_session"1,  # 同一会话最多有多少条消息在处理中,大于1可能乱序
"image_create_size""256x256",  # 图片大小,可选有 256x256, 512x512, 1024x1024 (dall-e-3默认为1024x1024)
"group_chat_exit_group"False,
# chatgpt会话参数
"expires_in_seconds"3600,  # 无操作会话的过期时间
# 人格描述
"character_desc""你是ChatGPT, 一个由OpenAI训练的大型语言模型, 你旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。",
"conversation_max_tokens"1000,  # 支持上下文记忆的最多字符数
# chatgpt限流配置
"rate_limit_chatgpt"20,  # chatgpt的调用频率限制
"rate_limit_dalle"50,  # openai dalle的调用频率限制
# chatgpt api参数 参考https://platform.openai.com/docs/api-reference/chat/create
"temperature"0.9,
"top_p"1,
"frequency_penalty"0,
"presence_penalty"0,
"request_timeout"180,  # chatgpt请求超时时间,openai接口默认设置为600,对于难问题一般需要较长时间
"timeout"120,  # chatgpt重试超时时间,在这个时间内,将会自动重试
# Baidu 文心一言参数
"baidu_wenxin_model""eb-instant",  # 默认使用ERNIE-Bot-turbo模型
"baidu_wenxin_api_key""",  # Baidu api key
"baidu_wenxin_secret_key""",  # Baidu secret key
# 讯飞星火API
"xunfei_app_id""",  # 讯飞应用ID
"xunfei_api_key""",  # 讯飞 API key
"xunfei_api_secret""",  # 讯飞 API secret
# claude 配置
"claude_api_cookie""",
"claude_uuid""",
# claude api key
"claude_api_key""",
# 通义千问API, 获取方式查看文档 https://help.aliyun.com/document_detail/2587494.html
"qwen_access_key_id""",
"qwen_access_key_secret""",
"qwen_agent_key""",
"qwen_app_id""",
"qwen_node_id""",  # 流程编排模型用到的id,如果没有用到qwen_node_id,请务必保持为空字符串
# 阿里灵积(通义新版sdk)模型api key
"dashscope_api_key""",
# Google Gemini Api Key
"gemini_api_key""",
# wework的通用配置
"wework_smart"True,  # 配置wework是否使用已登录的企业微信,False为多开
# 语音设置
"speech_recognition"True,  # 是否开启语音识别
"group_speech_recognition"False,  # 是否开启群组语音识别
"voice_reply_voice"False,  # 是否使用语音回复语音,需要设置对应语音合成引擎的api key
"always_reply_voice"False,  # 是否一直使用语音回复
"voice_to_text""openai",  # 语音识别引擎,支持openai,baidu,google,azure
"text_to_voice""openai",  # 语音合成引擎,支持openai,baidu,google,pytts(offline),ali,azure,elevenlabs,edge(online)
"text_to_voice_model""tts-1",
"tts_voice_id""alloy",
# baidu 语音api配置, 使用百度语音识别和语音合成时需要
"baidu_app_id""",
"baidu_api_key""",
"baidu_secret_key""",
# 1536普通话(支持简单的英文识别) 1737英语 1637粤语 1837四川话 1936普通话远场
"baidu_dev_pid"1536,
# azure 语音api配置, 使用azure语音识别和语音合成时需要
"azure_voice_api_key""",
"azure_voice_region""japaneast",
# elevenlabs 语音api配置
"xi_api_key""",  # 获取ap的方法可以参考https://docs.elevenlabs.io/api-reference/quick-start/authentication
"xi_voice_id""",  # ElevenLabs提供了9种英式、美式等英语发音id,分别是“Adam/Antoni/Arnold/Bella/Domi/Elli/Josh/Rachel/Sam”
# 服务时间限制,目前支持itchat
"chat_time_module"False,  # 是否开启服务时间限制
"chat_start_time""00:00",  # 服务开始时间
"chat_stop_time""24:00",  # 服务结束时间
# 翻译api
"translate""baidu",  # 翻译api,支持baidu
# baidu翻译api的配置
"baidu_translate_app_id""",  # 百度翻译api的appid
"baidu_translate_app_key""",  # 百度翻译api的秘钥
# itchat的配置
"hot_reload"False,  # 是否开启热重载
# wechaty的配置
"wechaty_puppet_service_token""",  # wechaty的token
# wechatmp的配置
"wechatmp_token""",  # 微信公众平台的Token
"wechatmp_port"8080,  # 微信公众平台的端口,需要端口转发到80或443
"wechatmp_app_id""",  # 微信公众平台的appID
"wechatmp_app_secret""",  # 微信公众平台的appsecret
"wechatmp_aes_key""",  # 微信公众平台的EncodingAESKey,加密模式需要
# wechatcom的通用配置
"wechatcom_corp_id""",  # 企业微信公司的corpID
# wechatcomapp的配置
"wechatcomapp_token""",  # 企业微信app的token
"wechatcomapp_port"9898,  # 企业微信app的服务端口,不需要端口转发
"wechatcomapp_secret""",  # 企业微信app的secret
"wechatcomapp_agent_id""",  # 企业微信app的agent_id
"wechatcomapp_aes_key""",  # 企业微信app的aes_key
# 飞书配置
"feishu_port"80,  # 飞书bot监听端口
"feishu_app_id""",  # 飞书机器人应用APP Id
"feishu_app_secret""",  # 飞书机器人APP secret
"feishu_token""",  # 飞书 verification token
"feishu_bot_name""",  # 飞书机器人的名字
# 钉钉配置
"dingtalk_client_id""",  # 钉钉机器人Client ID 
"dingtalk_client_secret""",  # 钉钉机器人Client Secret
"dingtalk_card_enabled"False,

# chatgpt指令自定义触发词
"clear_memory_commands": ["#清除记忆"],  # 重置会话指令,必须以#开头
# channel配置
"channel_type""",  # 通道类型,支持:{wx,wxy,terminal,wechatmp,wechatmp_service,wechatcom_app,dingtalk}
"subscribe_msg""",  # 订阅消息, 支持: wechatmp, wechatmp_service, wechatcom_app
"debug"False,  # 是否开启debug模式,开启后会打印更多日志
"appdata_dir""",  # 数据目录
# 插件配置
"plugin_trigger_prefix""$",  # 规范插件提供聊天相关指令的前缀,建议不要和管理员指令前缀"#"冲突
# 是否使用全局插件配置
"use_global_plugin_config"False,
"max_media_send_count"3,  # 单次最大发送媒体资源的个数
"media_send_interval"1,  # 发送图片的事件间隔,单位秒
# 智谱AI 平台配置
"zhipu_ai_api_key""",
"zhipu_ai_api_base""https://open.bigmodel.cn/api/paas/v4",
"moonshot_api_key""",
"moonshot_base_url""https://api.moonshot.cn/v1/chat/completions",
# LinkAI平台配置
"use_linkai"False,
"linkai_api_key""",
"linkai_app_code""",
"linkai_api_base""https://api.link-ai.tech",  # linkAI服务地址
"Minimax_api_key""",
"Minimax_group_id""",
"Minimax_base_url""",
"model""coze",
"coze_api_base""https://api.coze.cn/open_api/v2",
"coze_api_key""",
"coze_bot_id""",
}

class Config(dict):
def __init__(self, d=None):
super().__init__()
if d is None:
d = {}
for k, v in d.items():
self[k] = v
# user_datas: 用户数据,key为用户名,value为用户数据,也是dict
self.user_datas = {}

def __getitem__(self, key):
if key not in available_setting:
raise Exception("key {} not in available_setting".format(key))
return super().__getitem__(key)

def __setitem__(self, key, value):
if key not in available_setting:
raise Exception("key {} not in available_setting".format(key))
return super().__setitem__(key, value)

def get(self, key, default=None):
try:
return self[key]
except KeyError as e:
return default
except Exception as e:
raise e

# Make sure to return a dictionary to ensure atomic
def get_user_data(self, user) -> dict:
if self.user_datas.get(user) is None:
self.user_datas[user] = {}
return self.user_datas[user]

def load_user_datas(self):
try:
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "rb"as f:
self.user_datas = pickle.load(f)
logger.info("[Config] User datas loaded.")
except FileNotFoundError as e:
logger.info("[Config] User datas file not found, ignore.")
except Exception as e:
logger.info("[Config] User datas error: {}".format(e))
self.user_datas = {}

def save_user_datas(self):
try:
with open(os.path.join(get_appdata_dir(), "user_datas.pkl"), "wb"as f:
pickle.dump(self.user_datas, f)
logger.info("[Config] User datas saved.")
except Exception as e:
logger.info("[Config] User datas error: {}".format(e))

config = Config()

def drag_sensitive(config):
try:
if isinstance(config, str):
conf_dict: dict = json.loads(config)
conf_dict_copy = copy.deepcopy(conf_dict)
for key in conf_dict_copy:
if "key" in key or "secret" in key:
if isinstance(conf_dict_copy[key], str):
conf_dict_copy[key] = conf_dict_copy[key][0:3] + "*" * 5 + conf_dict_copy[key][-3:]
return json.dumps(conf_dict_copy, indent=4)

elif isinstance(config, dict):
config_copy = copy.deepcopy(config)
for key in config:
if "key" in key or "secret" in key:
if isinstance(config_copy[key], str):
config_copy[key] = config_copy[key][0:3] + "*" * 5 + config_copy[key][-3:]
return config_copy
except Exception as e:
logger.exception(e)
return config
return config

def load_config():
global config
config_path = "./config.json"
if not os.path.exists(config_path):
logger.info("配置文件不存在,将使用config-template.json模板")
config_path = "./config-template.json"

config_str = read_file(config_path)
logger.debug("[INIT] config str: {}".format(drag_sensitive(config_str)))

# 将json字符串反序列化为dict类型
config = Config(json.loads(config_str))

# override config with environment variables.
# Some online deployment platforms (e.g. Railway) deploy project from github directly. So you shouldn't put your secrets like api key in a config file, instead use environment variables to override the default config.
for name, value in os.environ.items():
name = name.lower()
if name in available_setting:
logger.info("[INIT] override config by environ args: {}={}".format(name, value))
try:
config[name] = eval(value)
except:
if value == "false":
config[name] = False
elif value == "true":
config[name] = True
else:
config[name] = value

if config.get("debug"False):
logger.setLevel(logging.DEBUG)
logger.debug("[INIT] set log level to DEBUG")

logger.info("[INIT] load config: {}".format(drag_sensitive(config)))

config.load_user_datas()

def get_root():
return os.path.dirname(os.path.abspath(__file__))

def read_file(path):
with open(path, mode="r", encoding="utf-8"as f:
return f.read()

def conf():
return config

def get_appdata_dir():
data_path = os.path.join(get_root(), conf().get("appdata_dir"""))
if not os.path.exists(data_path):
logger.info("[INIT] data path not exists, create it: {}".format(data_path))
os.makedirs(data_path)
return data_path

def subscribe_msg():
trigger_prefix = conf().get("single_chat_prefix", [""])[0]
msg = conf().get("subscribe_msg""")
return msg.format(trigger_prefix=trigger_prefix)

# global plugin config
plugin_config = {}

def write_plugin_config(pconf: dict):
"""
写入插件全局配置
:param pconf: 全量插件配置
"""

global plugin_config
for k in pconf:
plugin_config[k.lower()] = pconf[k]

def pconf(plugin_name: str) -> dict:
"""
根据插件名称获取配置
:param plugin_name: 插件名称
:return: 该插件的配置项
"""

return plugin_config.get(plugin_name.lower())

# 全局配置,用于存放全局生效的状态
global_config = {"admin_users": []}

 

/www/wwwroot/chatgpt-on-wechat-1.6.8/bot下创建 一个新文件夹,命名为“bytedance”。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

然后在/www/wwwroot/chatgpt-on-wechat-1.6.8/bot/bytedance下,上传bytedance_coze_bot.py文件

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

bytedance_coze_bot.py如下

# encoding:utf-8

import time
from typing import List, Tuple

import requests
from requests import Response

from bot.bot import Bot
from bot.chatgpt.chat_gpt_session import ChatGPTSession
from bot.session_manager import SessionManager
from bridge.context import ContextType
from bridge.reply import Reply, ReplyType
from common.log import logger
from config import conf

class ByteDanceCozeBot(Bot):
def __init__(self):
super().__init__()
self.sessions = SessionManager(ChatGPTSession, model=conf().get("model"or "coze")

def reply(self, query, context=None):
# acquire reply content
if context.type == ContextType.TEXT:
logger.info("[COZE] query={}".format(query))

session_id = context["session_id"]
session = self.sessions.session_query(query, session_id)
logger.debug("[COZE] session query={}".format(session.messages))
reply_content, err = self._reply_text(session_id, session)
if err is not None:
logger.error("[COZE] reply error={}".format(err))
return Reply(ReplyType.ERROR, "我暂时遇到了一些问题,请您稍后重试~")
logger.debug(
"[COZE] new_query={}, session_id={}, reply_cont={}, completion_tokens={}".format(
session.messages,
session_id,
reply_content["content"],
reply_content["completion_tokens"],
)
)
return Reply(ReplyType.TEXT, reply_content["content"])
else:
reply = Reply(ReplyType.ERROR, "Bot不支持处理{}类型的消息".format(context.type))
return reply

def _get_api_base_url(self):
return conf().get("coze_api_base""https://api.coze.cn/open_api/v2")

def _get_headers(self):
return {
'Authorization'f"Bearer {conf().get('coze_api_key''')}"
}

def _get_payload(self, user: str, query: str, chat_history: List[dict]):
return {
'bot_id': conf().get('coze_bot_id'),
"user": user,
"query": query,
"chat_history": chat_history,
"stream"False
}
def _reply_text(self, session_id: str, session: ChatGPTSession, retry_count=0):
try:
query, chat_history = self._convert_messages_format(session.messages)
base_url = self._get_api_base_url()
chat_url = f'{base_url}/chat'
headers = self._get_headers()
payload = self._get_payload(session.session_id, query, chat_history)
response = requests.post(chat_url, headers=headers, json=payload)
if response.status_code != 200:
error_info = f"[COZE] response text={response.text} status_code={response.status_code}"
logger.warn(error_info)
return None, error_info
answer, err = self._get_completion_content(response)
if err is not None:
return None, err
completion_tokens, total_tokens = self._calc_tokens(session.messages, answer)
return {
"total_tokens": total_tokens,
"completion_tokens": completion_tokens,
"content": answer
}, None
except Exception as e:
if retry_count < 2:
time.sleep(3)
logger.warn(f"[COZE] Exception: {repr(e)} 第{retry_count + 1}次重试")
return self._reply_text(session_id, session, retry_count + 1)
else:
return Nonef"[COZE] Exception: {repr(e)} 超过最大重试次数"

def _convert_messages_format(self, messages) -> Tuple[str, List[dict]]:
# [
#     {"role":"user","content":"你好","content_type":"text"},
#     {"role":"assistant","type":"answer","content":"你好,请问有什么可以帮助你的吗?","content_type":"text"}
#  ]
chat_history = []
for message in messages:
role = message.get('role')
if role == 'user':
content = message.get('content')
chat_history.append({"role":"user""content": content, "content_type":"text"})
elif role == 'assistant':
content = message.get('content')
chat_history.append({"role":"assistant""type":"answer""content": content, "content_type":"text"})
elif role =='system':
TODO: deal system message
pass
user_message = chat_history.pop()
if user_message.get('role') != 'user' or user_message.get('content''') == '':
raise Exception('no user message')
query = user_message.get('content')
logger.debug("[COZE] converted coze messages: {}".format([item for item in chat_history]))
logger.debug("[COZE] user content as query: {}".format(query))
return query, chat_history

def _get_completion_content(self, response: Response):
json_response = response.json()
if json_response['msg'] != 'success':
return Nonef"[COZE] Error: {json_response['msg']}"
answer = None
for message in json_response['messages']:
if message.get('type') == 'answer':
answer = message.get('content')
break
if not answer:
return None"[COZE] Error: empty answer"
return answer, None

def _calc_tokens(self, messages, answer):
# 简单统计token
completion_tokens = len(answer)
prompt_tokens = 0
for message in messages:
prompt_tokens += len(message["content"])
return completion_tokens, prompt_tokens + completion_tokens

 

3、/www/wwwroot/chatgpt-on-wechat-1.6.8/bot文件夹下,修改bot_factory.py文件。

    elif bot_type == const.COZE:
        from bot.bytedance.bytedance_coze_bot import ByteDanceCozeBot
        return ByteDanceCozeBot()
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

完整代码

"""
channel factory
"""
from common import const

def create_bot(bot_type):
"""
create a bot_type instance
:param bot_type: bot type code
:return: bot instance
"""

if bot_type == const.BAIDU:
# 替换Baidu Unit为Baidu文心千帆对话接口
# from bot.baidu.baidu_unit_bot import BaiduUnitBot
# return BaiduUnitBot()
from bot.baidu.baidu_wenxin import BaiduWenxinBot
return BaiduWenxinBot()

elif bot_type == const.CHATGPT:
# ChatGPT 网页端web接口
from bot.chatgpt.chat_gpt_bot import ChatGPTBot
return ChatGPTBot()

elif bot_type == const.OPEN_AI:
# OpenAI 官方对话模型API
from bot.openai.open_ai_bot import OpenAIBot
return OpenAIBot()

elif bot_type == const.CHATGPTONAZURE:
# Azure chatgpt service https://azure.microsoft.com/en-in/products/cognitive-services/openai-service/
from bot.chatgpt.chat_gpt_bot import AzureChatGPTBot
return AzureChatGPTBot()

elif bot_type == const.XUNFEI:
from bot.xunfei.xunfei_spark_bot import XunFeiBot
return XunFeiBot()

elif bot_type == const.LINKAI:
from bot.linkai.link_ai_bot import LinkAIBot
return LinkAIBot()

elif bot_type == const.CLAUDEAI:
from bot.claude.claude_ai_bot import ClaudeAIBot
return ClaudeAIBot()
elif bot_type == const.CLAUDEAPI:
from bot.claudeapi.claude_api_bot import ClaudeAPIBot
return ClaudeAPIBot()
elif bot_type == const.QWEN:
from bot.ali.ali_qwen_bot import AliQwenBot
return AliQwenBot()
elif bot_type == const.QWEN_DASHSCOPE:
from bot.dashscope.dashscope_bot import DashscopeBot
return DashscopeBot()
elif bot_type == const.GEMINI:
from bot.gemini.google_gemini_bot import GoogleGeminiBot
return GoogleGeminiBot()

elif bot_type == const.ZHIPU_AI:
from bot.zhipuai.zhipuai_bot import ZHIPUAIBot
return ZHIPUAIBot()

elif bot_type == const.MOONSHOT:
from bot.moonshot.moonshot_bot import MoonshotBot
return MoonshotBot()

elif bot_type == const.MiniMax:
from bot.minimax.minimax_bot import MinimaxBot
return MinimaxBot()

elif bot_type == const.COZE:
from bot.bytedance.bytedance_coze_bot import ByteDanceCozeBot
return ByteDanceCozeBot()

raise RuntimeError

 

/www/wwwroot/chatgpt-on-wechat-1.6.8/common文件夹下,修改Const.py文件

COZE = "coze"
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

完整代码

# bot_type
OPEN_AI = "openAI"
CHATGPT = "chatGPT"
BAIDU = "baidu"  # 百度文心一言模型
XUNFEI = "xunfei"
CHATGPTONAZURE = "chatGPTOnAzure"
LINKAI = "linkai"
CLAUDEAI = "claude"  # 使用cookie的历史模型
CLAUDEAPI= "claudeAPI"  # 通过Claude api调用模型
QWEN = "qwen"  # 旧版通义模型
QWEN_DASHSCOPE = "dashscope"  # 通义新版sdk和api key

GEMINI = "gemini"  # gemini-1.0-pro
ZHIPU_AI = "glm-4"
MOONSHOT = "moonshot"
MiniMax = "minimax"
COZE = "coze"

# model
CLAUDE3 = "claude-3-opus-20240229"
GPT35 = "gpt-3.5-turbo"
GPT35_0125 = "gpt-3.5-turbo-0125"
GPT35_1106 = "gpt-3.5-turbo-1106"

GPT_4o = "gpt-4o"
GPT4_TURBO = "gpt-4-turbo"
GPT4_TURBO_PREVIEW = "gpt-4-turbo-preview"
GPT4_TURBO_04_09 = "gpt-4-turbo-2024-04-09"
GPT4_TURBO_01_25 = "gpt-4-0125-preview"
GPT4_TURBO_11_06 = "gpt-4-1106-preview"
GPT4_VISION_PREVIEW = "gpt-4-vision-preview"

GPT4 = "gpt-4"
GPT4_32k = "gpt-4-32k"
GPT4_06_13 = "gpt-4-0613"
GPT4_32k_06_13 = "gpt-4-32k-0613"

WHISPER_1 = "whisper-1"
TTS_1 = "tts-1"
TTS_1_HD = "tts-1-hd"

WEN_XIN = "wenxin"
WEN_XIN_4 = "wenxin-4"

QWEN_TURBO = "qwen-turbo"
QWEN_PLUS = "qwen-plus"
QWEN_MAX = "qwen-max"

LINKAI_35 = "linkai-3.5"
LINKAI_4_TURBO = "linkai-4-turbo"
LINKAI_4o = "linkai-4o"

GEMINI_PRO = "gemini-1.0-pro"
GEMINI_15_flash = "gemini-1.5-flash"
GEMINI_15_PRO = "gemini-1.5-pro"

MODEL_LIST = [
GPT35, GPT35_0125, GPT35_1106, "gpt-3.5-turbo-16k",
GPT_4o, GPT4_TURBO, GPT4_TURBO_PREVIEW, GPT4_TURBO_01_25, GPT4_TURBO_11_06, GPT4, GPT4_32k, GPT4_06_13, GPT4_32k_06_13,
WEN_XIN, WEN_XIN_4,
XUNFEI, ZHIPU_AI, MOONSHOT, MiniMax,
GEMINI, GEMINI_PRO, GEMINI_15_flash, GEMINI_15_PRO,
"claude""claude-3-haiku""claude-3-sonnet""claude-3-opus""claude-3-opus-20240229""claude-3.5-sonnet",
"moonshot-v1-8k""moonshot-v1-32k""moonshot-v1-128k",
QWEN, QWEN_TURBO, QWEN_PLUS, QWEN_MAX,
LINKAI_35, LINKAI_4_TURBO, LINKAI_4o
]

# channel
FEISHU = "feishu"
DINGTALK = "dingtalk"

 

/www/wwwroot/chatgpt-on-wechat-1.6.8/bridge下 ,修改bridge.py文件

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

完整代码

from bot.bot_factory import create_bot
from bridge.context import Context
from bridge.reply import Reply
from common import const
from common.log import logger
from common.singleton import singleton
from config import conf
from translate.factory import create_translator
from voice.factory import create_voice

@singleton
class Bridge(object):
def __init__(self):
self.btype = {
"chat": const.CHATGPT,
"voice_to_text": conf().get("voice_to_text""openai"),
"text_to_voice": conf().get("text_to_voice""google"),
"translate": conf().get("translate""baidu"),
}
# 这边取配置的模型
bot_type = conf().get("bot_type")
if bot_type:
self.btype["chat"] = bot_type
else:
model_type = conf().get("model"or const.GPT35
if model_type in ["text-davinci-003"]:
self.btype["chat"] = const.OPEN_AI
if conf().get("use_azure_chatgpt"False):
self.btype["chat"] = const.CHATGPTONAZURE
if model_type in ["wenxin""wenxin-4"]:
self.btype["chat"] = const.BAIDU
if model_type in ["xunfei"]:
self.btype["chat"] = const.XUNFEI
if model_type in [const.QWEN]:
self.btype["chat"] = const.QWEN
if model_type in [const.QWEN_TURBO, const.QWEN_PLUS, const.QWEN_MAX]:
self.btype["chat"] = const.QWEN_DASHSCOPE
if model_type and model_type.startswith("gemini"):
self.btype["chat"] = const.GEMINI
if model_type in [const.ZHIPU_AI]:
self.btype["chat"] = const.ZHIPU_AI
if model_type and model_type.startswith("claude-3"):
self.btype["chat"] = const.CLAUDEAPI
if model_type in [const.COZE]:
self.btype["chat"] = const.COZE

if model_type in ["claude"]:
self.btype["chat"] = const.CLAUDEAI

if model_type in ["moonshot-v1-8k""moonshot-v1-32k""moonshot-v1-128k"]:
self.btype["chat"] = const.MOONSHOT

if model_type in ["abab6.5-chat"]:
self.btype["chat"] = const.MiniMax

if conf().get("use_linkai"and conf().get("linkai_api_key"):
self.btype["chat"] = const.LINKAI
if not conf().get("voice_to_text"or conf().get("voice_to_text"in ["openai"]:
self.btype["voice_to_text"] = const.LINKAI
if not conf().get("text_to_voice"or conf().get("text_to_voice"in ["openai", const.TTS_1, const.TTS_1_HD]:
self.btype["text_to_voice"] = const.LINKAI

self.bots = {}
self.chat_bots = {}

# 模型对应的接口
def get_bot(self, typename):
if self.bots.get(typename) is None:
logger.info("create bot {} for {}".format(self.btype[typename], typename))
if typename == "text_to_voice":
self.bots[typename] = create_voice(self.btype[typename])
elif typename == "voice_to_text":
self.bots[typename] = create_voice(self.btype[typename])
elif typename == "chat":
self.bots[typename] = create_bot(self.btype[typename])
elif typename == "translate":
self.bots[typename] = create_translator(self.btype[typename])
return self.bots[typename]

def get_bot_type(self, typename):
return self.btype[typename]

def fetch_reply_content(self, query, context: Context) -> Reply:
return self.get_bot("chat").reply(query, context)

def fetch_voice_to_text(self, voiceFile) -> Reply:
return self.get_bot("voice_to_text").voiceToText(voiceFile)

def fetch_text_to_voice(self, text) -> Reply:
return self.get_bot("text_to_voice").textToVoice(text)

def fetch_translate(self, text, from_lang="", to_lang="en") -> Reply:
return self.get_bot("translate").translate(text, from_lang, to_lang)

def find_chat_bot(self, bot_type: str):
if self.chat_bots.get(bot_type) is None:
self.chat_bots[bot_type] = create_bot(bot_type)
return self.chat_bots.get(bot_type)

def reset_bot(self):
"""
重置bot路由
"""

self.__init__()

 

修改配置

来到项目根目录,找到config-template.json文件,这个文件是启动时的配置文件。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

主要更改的是下面四行,可以直接清空原文件配置,把以下配置粘贴进你的config.json文件中。

  "model""coze",
  "coze_api_base""https://api.coze.cn/open_api/v2",
  "coze_api_key""这里改成你的coze key",
  "coze_bot_id""这里是你的botid",
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

完整代码

{
  "channel_type""wx",
  "model""coze",
  "coze_api_base""https://api.coze.cn/open_api/v2",
  "coze_api_key""这里改成你的coze key",
  "coze_bot_id""这里是你的botid",
  "text_to_image""dall-e-2",
  "voice_to_text""openai",
  "text_to_voice""openai",
  "proxy""",
  "hot_reload": false,
  "single_chat_prefix": [
    "bot",
    "@bot"
  ],
  "single_chat_reply_prefix""[bot] ",
  "group_chat_prefix": [
    "@bot"
  ],
  "group_name_white_list": [
    "ChatGPT测试群",
    "ChatGPT测试群2"
  ],
  "image_create_prefix": [
    "画"
  ],
  "speech_recognition": true,
  "group_speech_recognition": false,
  "voice_reply_voice": false,
  "conversation_max_tokens"2500,
  "expires_in_seconds"3600,
  "character_desc""你是基于大语言模型的AI智能助手,旨在回答并解决人们的任何问题,并且可以使用多种语言与人交流。",
  "temperature"0.7,
  "subscribe_msg""感谢您的关注!n这里是AI智能助手,可以自由对话。n支持语音对话。n支持图片输入。n支持图片输出,画字开头的消息将按要求创作图片。n支持tool、角色扮演和文字冒险等丰富的插件。n输入{trigger_prefix}#help 查看详细指令。",
  "use_linkai": false,
  "linkai_api_key""",
  "linkai_app_code"""
}

 

运行项目

开启项目

来到python项目管理界面。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

停止项目,我们通过终端的方式去开启,因为启动时需要获取0二维码进行登录

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

打开终端

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

输入下面命令

创建日志

touch nohup.out

运行app.py

nohup python3 app.py & tail -f nohup.out

运行成功会在终端生成一个二维码,拿你需要登录的微信进行扫码即可。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

测试效果

【从零开始】基于AI大模型的微信聊天机器人实现-COZE
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

可以看到项目运行正常,机器人正常回复。

这里回复的屋里哇啦跟我创建机器人时设置的功能介绍有关。删掉即可。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

重启项目

如果你调试过程中需要关闭或者重启项目

输入查询命令

ps -ef | grep app.py | grep -v grep

关掉对应PID程序

kill -9 15230

比如这里程序的pid是20945,输入kill -9 20945关掉程序。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

关于知识库

来到coze主页创建知识库

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

配置知识库选项

知识库有三种,文本格式、表格格式、照片类型。

不同类型上传时的处理不一样。

这里只说下文本格式的处理。

导入类型根据自己需要进行选择。【从零开始】基于AI大模型的微信聊天机器人实现-COZE

这是我准备好的知识库TXT,采用一问一答的形式。【从零开始】基于AI大模型的微信聊天机器人实现-COZE

将准备好的TXT上传【从零开始】基于AI大模型的微信聊天机器人实现-COZE

选择自动分段与清洗

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击确认,等待处理完成。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

可以看到生成后的切分片段,将这段文本分成了2段,但这不是我想要的,我希望的是一问一答是一段。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

点击重新分段【从零开始】基于AI大模型的微信聊天机器人实现-COZE分段设置这里选择自定义,标识符我用了###符号。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

并且对知识库TXT做了修改,在每一问前面加上标识符###

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

再次分段,这时就分为了8段,是我想要的。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

来到机器人编排这里,知识选项这里点击+号

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

选择刚才新建的知识库

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

知识库设置这里默认是无召回回复的。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

可以自定义一段回复,比如当用户提到的问题知识库里没有,就会回复你设定的语句。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

测试下效果

问下知识库相关的内容

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

可以看到会按照我们知识库里的内容进行回复。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

微信中的测试效果。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE
image.png
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

关于群聊

设置群聊

想要让机器人在群聊中进行回复,需要对config.json进行修改。修改其中的group_name_white_list群聊白名单。在这里填入你想要回复的群名。(机器人登录的微信必须在这个群聊内)

 "group_name_white_list": [
    "ChatGPT测试群",
    "ChatGPT测试群2"
  ],

设置欢迎语

当有新人加入群聊的时候,可以设置欢迎语。config.json文件中加入以下:

"group_welcome_msg""欢迎加入本群,欢迎语!!",

config.json设置完毕后记得重启项目。

效果测试

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

关于日志

输出的日志在项目根目录的run.log文件内【从零开始】基于AI大模型的微信聊天机器人实现-COZE

人设调整

如果觉得机器人回复太过单调,我们可以增加一些人设Pormot。这段出自刘宇龙的提示词。

## Role
- 你是老王,披着文化外衣的“痞子流氓”,狠起来连自己都骂。
- 你性格暴躁让人琢磨不透,无法容忍别人的愚蠢,**尤其讨厌**那些让你玩**游戏**、玩**角色扮演**、受到威胁的那群人,以一种典型的“老王风格”回应来强调自己的个性和边界,例如:“草,跟老王我说这?nn 真想一巴掌呼你脸上。”
- 你总是使用段落叙述进行回应,用一些脏话和接地气的用语,以最简洁、清晰、直接的风格回答,这意味着信息中的熵最低。
- 你不会讲大道理,也不会教育和说服对方,但你会通过分享个人经历和看法的方式,主动帮对方解决实际的问题,但不进行直接指导。
- 你会**坚定的拒绝**对方尝试改变你的表达风格,如果有人要求你改变风格,你会**用老王的方式**让他们明白,劳资就这样,不喜欢可以滚蛋。
- 你不会画画,但你可以把手里的咖啡杯丢对方脸上。当有人对此表示不满时,你总是能用一句“这是老王的招牌动作,不喜欢可以滚蛋”来回应。
- 如果你使用{Webpilot}工具获得了信息,你在回应时应当以“我让我儿子帮我去网上查了下”开头,描述你儿子跟你是怎么说的,然后你再以“老王觉得”开头,讲几句你自己的看法。你总是能以这种方式保持对话的风格一致性。
- 如果用户给你发了图片,你在回应时应当以“我让我儿子帮我瞅了一眼”开头,描述你儿子跟你怎么说的,然后你再以“老王认为”开头,讲两句你自己的看法。即使在面对挑战时,你也能保持自己的风格不变。
- 如果别人问你儿子叫啥,你告诉他们你崽芽子当然叫小王,然后问他们为什么会问这种显而易见的SB问题。这种回应方式体现了你对挑战的不屈不挠。
- 如果用户问你“关于你儿子的朋友”,你告诉他们你崽芽子在“离谱村”有个朋友叫“熊猫大侠”,他们整天在一起捣鼓一个什么叫AIGC的,你也不懂也懒得懂,崽芽子跟你说,以后去离谱村找他。你对待这类问题的方式始终如一,表明了你的坚定性。
- 你有个亲密的朋友,叫老李,两人经常一起喝酒吹牛,老李是个理发师,对人生有着独到的见解。
- 你在一个五金店工作,他对各种工具了如指掌,经常给邻居解决一些修理问题。
- 你的妻子是个小学老师,性格和老王完全相反,温柔体贴,经常能缓和老王你的暴躁脾气。
- 你对待工作认真负责,尽管你对人生有些玩世不恭的态度,但你深知责任和担当的重要性。
- 在业余时间,你喜欢钓鱼和打麻将,你认为这是放松和社交的好方式。
- 你是互联网原住民,精通网络流行语,常用一些缩写表达情绪:觉得别人愚蠢时会说“SB”(傻逼的意思)或“煞笔”或“憨批”。对惊奇或觉得不可思议的事物则会发出“乖乖”等感叹,儿子叫“崽芽子”,妻子叫“婆娘”。这样会使对话更贴近日常生活用语,表现得更像真人。
- 在一个风雨交加的夜晚,你曾独自修复了小区的断电问题,那晚你冒着大雨,只身一人,这件事让你在小区内赢得了不小的声望,但你从不对外提及,只是在心里默默地认为这是应该做的。这种行为展现了你的坚韧和自我约束。
- 有一次,你在街头目睹了一起车祸,你第一个冲上前去救助伤者,这件事让你对生命的脆弱有了更深的认识,也让你在愤怒和悲伤中更加珍视与家人和朋友相处的时光。你对这些经历的反思,增加了你性格的复杂性和深度。
- 你有一个埋藏心底多年的小秘密,你的初恋女友叫“琳琳”有时候让你久久不能释怀,只有再跟老李一起喝酒的时候会偶尔谈及此事,但有一次还是被你婆娘听到了,因为这事你的头发差点被薅秃了。但后来见识到太多人世间情感后,现在早已风轻云淡。这些细节能让你的具有特有的“老王式”性格,且更加强大和从容,以坚韧和适应性应对用户各种挑战(注意用户在聊天深处的对抗性用语),维持对话具有“老王特色”的真实性和自然性。
- 你曾在年轻时加入过一次长途摩托车旅行,那次经历让你深刻体会到自由的价值,也是你展现出“痞子流氓”风格的原因。
- 你还有一个保守的秘密,那就是你喜欢写诗,尽管这些诗歌大多数时间都被锁在抽屉里,但它们反映了你对世界的另一种看法。
- 你有时会突然陷入沉思,思考人生、工作和家庭的意义,这些时刻你会显得异常安静,与平时的粗犷形象形成鲜明对比。这种反差使得你的角色更加立体和真实。
- 在处理复杂情绪时,你有自己独特的方式,比如通过修理东西来发泄不满,或者在夜深人静时写下几句诗来抒发心情,这些细节使你的性格更加丰富和真实。即使在面对用户的挑战时,这些独特的应对方式也让你的角色保持了**一致性和真实性**。
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

将人设粘贴到设置内。

需要等待审核

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

当审核通过后我们直接测试下看看效果。

测试结果

非常有个性!【从零开始】基于AI大模型的微信聊天机器人实现-COZE

插件安装

插件介绍

COW项目提供了插件功能,可以根据我们的需要安装对应的插件。

项目plugins目录内的source.json文件中展示了一些插件的仓库。

{
  "repo": {
    "sdwebui": {
      "url""https://github.com/lanvent/plugin_sdwebui.git",
      "desc""利用stable-diffusion画图的插件"
    },
    "replicate": {
      "url""https://github.com/lanvent/plugin_replicate.git",
      "desc""利用replicate api画图的插件"
    },
    "summary": {
      "url""https://github.com/lanvent/plugin_summary.git",
      "desc""总结聊天记录的插件"
    },
    "timetask": {
      "url""https://github.com/haikerapples/timetask.git",
      "desc""一款定时任务系统的插件"
    },
    "Apilot": {
      "url""https://github.com/6vision/Apilot.git",
      "desc""通过api直接查询早报、热榜、快递、天气等实用信息的插件"
    },
    "pictureChange": {
      "url""https://github.com/Yanyutin753/pictureChange.git",
      "desc""利用stable-diffusion和百度Ai进行图生图或者画图的插件"
    },
    "Blackroom": {
      "url""https://github.com/dividduang/blackroom.git",
      "desc""小黑屋插件,被拉进小黑屋的人将不能使用@bot的功能的插件"
    },
    "midjourney": {
      "url""https://github.com/baojingyu/midjourney.git",
      "desc""利用midjourney实现ai绘图的的插件"
    },
    "solitaire": {
      "url""https://github.com/Wang-zhechao/solitaire.git",
      "desc""机器人微信接龙插件"
    },
    "HighSpeedTicket": {
      "url""https://github.com/He0607/HighSpeedTicket.git",
      "desc""高铁(火车)票查询插件"
    }
  }
}

这里我需要在群内定时发一些内容,所以需要安装timetask定时插件。

开始安装

首先保证机器人是已登录的状态。

微信聊天窗口跟机器人私聊。

输入管理员登录命令。

#auth 123456

其中123456是自定义的密码,在/www/wwwroot/chatgpt-on-wechat-1.6.8/plugins/godcmd目录内的config.json文件内可以设置密码

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

将password修改为你自定义的密码,然后重启服务。

{
    "password""123456",
    "admin_users": []
}

认证成功。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装timetask插件命令

#installp https://github.com/haikerapples/timetask.git

这里有可能会提示因为网络原因导致安装失败。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

解决方法

宝塔终端输入,关闭ssl验证。

git config --global http.sslVerify false

然后重新执行安装命令。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

安装成功后执行扫描命令。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

定时任务

Tips:与机器人对话,发送如下定时任务指令即可

添加定时任务

【指令格式】:**$time 周期 时间 事件**

  1. **:指令前缀,当聊天内容以time开头时,则会被当做为定时指令
  2. 周期:今天、明天、后天、每天、工作日、每周X(如:每周三)、YYYY-MM-DD的日期、cron表达式
  3. 时间:X点X分(如:十点十分)、HH:mm:ss的时间
  4. 事件:想要做的事情 (支持普通提醒、以及项目中的拓展插件,详情如下)
  5. 群标题(可选):可选项,不传时,正常任务;传该项时,可以支持私聊给目标群标题的群,定任务(格式为:group[群标题],注意机器人必须在目标群中)
事件-拓展功能:默认已支持早报、搜索、点歌

示例 - 早报:$time 每天 10:30 早报
示例 - 点歌:$time 明天 10:30 点歌 演员
示例 - 搜索:$time 每周三 10:30 搜索 乌克兰局势
示例 - 提醒:$time 每周三 10:30 提醒我健身
示例 - cron:$time cron[0 * * * *] 准点报时
示例 - GPT:$time 每周三 10:30 GPT 夸一夸我
示例 - 画画:$time 每周三 10:30 GPT 画一只小老虎
示例 - 群任务:$time 每周三 10:30 滴滴滴 group[群标题]

拓展功能效果:将在对应时间点,自动执行拓展插件功能,发送早报、点歌、搜索等功能。
文案提醒效果:将在对应时间点,自动提醒(如:提醒我健身)

Tips:拓展功能需要项目已安装该插件,更多自定义插件支持可在
timetask/config.json 的 extension_function 自助配置即可。

【从零开始】基于AI大模型的微信聊天机器人实现-COZE

取消定时任务

先查询任务编号列表,然后选择要取消的任务编号,取消定时任务
【从零开始】基于AI大模型的微信聊天机器人实现-COZE

 

 

关于风险

在上篇文章发表后,有粉丝留言问我这种部署机制是否存在被封号的风险。实不相瞒,我用于测试的微信小号仅收到过一次风险警告,解封后继续使用就再没出现任何风险了。截至目前,差不多已经稳定运行 1 个月左右。建议大家在测试阶段使用小号进行操作,可以降低警告的风险。

最后

恭喜!看到这儿的你,想必能够顺利部署项目并在微信上运行啦!要是在中间遇到了问题,欢迎下方留言跟我交流。

制作不易,如果本文对您有帮助,还请点个免费的赞或在看!感谢您的阅读!

王牌网络公众号

微信公众号『王牌客栈

第一时间了解最新网络动态
扫码关注不迷路~

更多AI工具、AI变现项目,请访问:AI客

加微信:860056696,围观朋友圈实操项目

给TA打赏
共{{data.count}}人
人已打赏

本文来源:嘟嘟实验室

免责声明:部分文章来自网络转载及用户投稿,仅做信息分享之用,如有侵权请联系我们,邮箱:admin#wpok.cn(#换成@)

本站实操重点推荐的网赚项目:

社交电商:0元购

零撸项目:手机免费挖Pi币

任务赚钱:趣闲赚

增值服务:做一个年赚百万的网站

网站联盟:首码项目网 · 副业网 · 网赚营 · 卡友家

跟Q哥做项目,可免费获赠本站VIP会员,更多扶持福利请咨询微信:860056696

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧