deepseek接入微信实践
前言
主要还是对别人的项目做了一个部署,踩了不少坑,改进了项目里面的一些东西,写在这里
AI接入个人微信(大模型)
- 项目地址:
https://github.com/KouriChat/KouriChat.git
- 项目语言:纯python(我也不太会)
- 预期实现效果:一个强大牛逼的个人机器助手,可以私聊也可以拉到群里面@它聊
服务器选择
- 你可以选择个人电脑(坏处就是要一直开着,然后会弹窗自动发消息,如果消息多了会很烦)
- 也可以选择云服务器(推荐的)云服务器参考3.2
环境准备
下载
python3.11.9
,问就是试了好几个版本windows系统
一个微信小号(不介意的话你可以用自己的大号)
在你的电脑上登录你的微信号(如果你要登录小号又要登录大号,在项目启动的时候不使用大号的时候关闭大号的微信框,不然容易找错窗口)
1
2
3
4@echo off
start "" "D:\software\wechat\WeChat.exe"
start "" "D:\software\wechat\WeChat.exe"
exit微信双开脚本,用记事本编辑保存为 xxx.bat 后双击运行,其中
D:\software\wechat\WeChat.exe
替换为微信安装位置
AI申请
- 项目推荐的是硅基生命的AI:https://cloud.siliconflow.cn/models,申请后会送你一些余额,绰绰有余,亏我还先重置了10块
- 然后申请一个API密钥
运行项目
两种方式,推荐直接点击
run.bat
1
2
3
4
5
6
7
8
9
10
11
12# 手动部署,cmd一个一个执行
# 更新pip
python -m pip install -i https://mirrors.tuna.tsinghua.edu.cn/pypi/web/simple --upgrade pip
# 安装依赖
pip install -r requirements.txt
#调整配置文件
python run_config_web.py
# 启动程序 或 使用WebUI启动 (在此之前,请启动微信!不然会提示未找到窗口句柄...)
python run.py然后你会进入到一个控制台前端(一开始会让你在对话框配置,可以跳过后面配)
首先是角色设定,创建一个你自己的角色然后配置好,然后去配置中心
用户列表:这里一定要输入的是用户的昵称或者群名,且群名里面不能用英文括号(踩坑)
API注册地址:硅基流动API
AI 模型:自己选
API 密钥:2.3里面的
然后右边还有一个Prompt配置
选择好你的机器人
点击保存后回到主页,右下角应该会有一个保存成功,你的小黑框里面也应该有你刚刚修改内容,这个时候建议关闭应用重启再启动一下
如果你是双开微信,这个时候关闭你的主微信窗口(不是退出)(非机器人的那个)
然后启动,会看到项目自动检索你刚刚设置的用户昵称或者群名,然后把他们拉出来形成单独窗口(后期应该就是按照这个来找到对应的对话的)如果报错
-初始化失败:Find Control Timeou:{RegexName:'XXX',ControlType:ListItemControl}
八成是你的昵称有问题亲测可以使用-
、字母、数组、中文
项目改进
使用的时候发现,这个机器人回复的太烦了,一条一条的,发送一条消息能回七八条,应该要把他们浓缩为一条消息,
找到项目里面的
src/handlers/message.py
里面的def _handle_text_message
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33def _handle_text_message(self, content, chat_id, sender_name, username, is_group):
"""处理普通文本消息"""
logger.info("处理普通文本回复")
reply = self.get_api_response(content, chat_id)
if "</think>" in reply:
think_content, reply = reply.split("</think>", 1)
print("\n思考过程:")
print(think_content.strip())
print("\nAI回复:")
print(reply.strip())
else:
print("\nAI回复:")
print(reply)
if is_group:
reply = f"@{sender_name} {reply}"
# 发送文本回复 这里是罪魁祸首,因为AI模型回复过来的是带有斜杠的,
# if '\\' in reply:
# parts = [p.strip() for p in reply.split('\\') if p.strip()]
# for part in parts:
# self.wx.SendMsg(msg=part, who=chat_id)
# time.sleep(random.randint(2, 4))
# else:
# myl修改:不分批次发送,太烦了
reply = reply.replace("\\", ",")
self.wx.SendMsg(msg=reply, who=chat_id)
# 检查回复中是否包含情感关键词并发送表情包
print("\n检查情感关键词...")
logger.info("开始检查AI回复的情感关键词")
emotion_detected = False报错重新启动项目,成功
AI接入公众号(较小的模型)
- 项目地址:
https://github.com/NezhaFan/wechat-ai.git
- 项目语言:纯go(我是纯没用过)
- 预期实现效果:用户关注公众号后发起对话可通过大模型返回对话
微信公众号
用个人微信创建一个公众号,我是之前有然后好久没用又重新找回了一下,属于个人账号的
在公众号管理 - 设置与开发 - 开发接口管理 - 服务器配置里面去开启这个服务器配置
我这边是因为已经配置好了,可以看到他需要的是服务器地址、令牌、消息加解密密钥、消息加密方式
服务器地址就是 3.2 里面我要去申请的云服务器的IP地址(端口需要是80或者443):
http://服务器IP地址/wx
本来打算不申请服务器的,用内网穿刺,把我个人计算机作为服务器,参考https://blog.csdn.net/MC_chaoji/article/details/135036174,但是我发现这个工具对外暴露的接口是10000~40000,暴露不了微信需要的80、443
令牌随便写,等会需要写到项目配置文件里面,两者对应即可
消息加解密密钥随机生成
加密方式必须是明文模式(项目要求)
搞到这里,公众号这边算是配置完了,但是先不能启动,因为你的后端服务还没在服务器启动,所以这个时候启动是生效不了的
服务器资源申请
毫无疑问阿里云,之前申请了域名、对象存储OSS、云服务器,有点点了解,用流量卡注册了一个新号,然后白嫖了一个三个月免费福利 2核2G(卡的要死)的然后注意选windows系统(其实后面看来用linux也不是不行,只是我感觉图形化快一点直观一点)
然后需要去开一下端口(很重要):在云服务管理控制台 左侧 - 网络与安全 - 安全组 - 选择刚刚你实例的安全组
入方向/出方向里面打开你的80端口,我把ipv4、ipv6都打开了
待会微信接入的就是你的80端口(项目里面配置的,同时也是公众号配置的)
环境搭建
- 安装
Git
、go
、vscode
之前学过java,看得懂一点点,感觉go真简洁
这里没啥问题,因为磁盘就40g全在C盘,一路确定(不用该路径太爽了)
vscode里面需要再安装一下
Go
插件,然后 F1 输入Go: Install/Update Tools
(咱也不知道是干啥的,安就完事)
第三方AI申请
用的字节那个火山引擎: https://console.volcengine.com/ark/region:ark+cn-beijing/apiKey dy扫码注册后生成一个API KEY
右侧 系统管理 - 开通管理 - 选一个模型(小规模一点)- 开通服务
为什么小规模?
规模太大(比如一开始我用的deepseek-R1)模型思考的时间就长,会高于微信公众号那边的最大等待时间导致超时
接入文档里面(也可以点那个模型)- 新页面里面点击 API调用指南。
你需要得到的信息:
URL:POST https://ark.cn-beijing.volces.com/api/v3/chat/completions (这个整个平台所有模型应该都是一致的)用于后面的项目url配置
model ID:doubao-1-5-pro-32k-250115
ok,它上面写的是先使用后付费,我也没充钱,实在不放心可以去右上角 费用 那里去看
修改项目配置文件部署
完事具备,只欠东风
在服务器上打开项目里面的
config.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27# 服务端口
port: 80
# 大模型配置
llm:
# 这个是刚刚3.4里面的URL(此处有坑)
api: https://ark.cn-beijing.volces.com/api/v3
# 3.4里面第一步生成的API Key
key: 888888888888
# 3.4里面的model ID
model: doubao-1-5-pro-32k-250115
# 人物预设
prompt: 你是一只可爱的小猫咪,请每句话都带‘喵~’来回复我。
# 温度 0-2
temperature: 1.2
# 单次回复最大token 1-8192, 设置小一点可以减少回复时间
maxtokens: 300
# 记忆最近几次对话(一问一答为一次),<=0 表示不记忆
history: 4
# 公众号配置 https://mp.weixin.qq.com
wechat:
# 必填(公众号服务). 与公众号设置保持一致
token: 这个是3.1里面你填的token
# 用户关注时主动发送的消息
subscribeMsg: 你好,我是一只可爱的小猫咪,谢谢关注。llm.api 为什么不加上
/chat/completions
? 项目全局搜索:
LLM.api
,发现只有common.go
里面使用到了,它在代码里面做了一个拼接,很坑1
url := strings.TrimSuffix(config.LLM.Api, "/") + "/chat/completions"
ok,启动项目,作者在readme里面给的命令是
nohup ./wechat-ai-amd64 >> ./data.log 2>&1 &
,这是linux里面的,现在是windows环境1
go run main.go | tee data.log
我想要在控制台输出日志(用于调式,也方便自己实时观看)的同时还在 项目根目录下的
data.log
里面也输出一样的日志控制台显示就是启动好了
启动完成后返回到微信公众号那里,点击启用,完成
这个时候微信会通过
r.GET("/wx", handler.WechatCheck)
这个接口来检测能不能通(如果不能转到3.6看第一个测试方法)
测试(含代码修改)
but 我怎么知道我的服务能不能被外面访问到呢,我怎么知道哪个环节出了问题呢
首先是不管发送消息,先保证我能访问到这个服务,我在
项目根目录/iternal/handler/
加了一个ping.go
1
2
3
4
5
6
7
8
9
10package handler
import (
"net.http"
)
func PingHandler(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusOK)
w.Write([]byte("Service is running"))
}然后是
main.go
里面的func main()
加了一个1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19func main() {
r := bootstrap.New()
// 微信消息处理
r.POST("/wx", handler.ReceiveMsg)
// 用于公众号自动验证
r.GET("/wx", handler.WechatCheck)
// 用于测试 curl "http://127.0.0.1:$PORT/"
// 这里我也注释掉了,因为报错找不到这个Test
// r.GET("/", handler.Test)
// 添加一个测试接口,用于检查服务是否启动
r.GET("/ping", handler.PingHandler)
log.Printf("启动服务,测试:curl 'http://127.0.0.1:%s?msg=你好' ", config.Port)
if err := http.ListenAndServe(":"+config.Port, r); err != nil {
panic(err)
}
}这时候启动服务后,如果你的服务器地址是
123.123.123.123
,浏览器输入http://120.55.242.43/ping
如果项目成功启动且你的IP是正确的应该会输出Service is running
其次是我怎么知道用户发送的消息微信有没有成功转发到我的后端呢
在
user.go
文件中找到ReceiveMsg
方法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25func ReceiveMsg(w http.ResponseWriter, r *http.Request) {
bs, _ := io.ReadAll(r.Body)
// 打印接收到的原始 XML 消息 在这里打印一下,这样用户发送的消息你就可以在控制台看见了(打印的是一个xml格式的文本包含很多信息)
/*
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
<MsgDataId>xxxx</MsgDataId>
<Idx>xxxx</Idx>
</xml>
*/
log.Printf("收到消息: %s\n", string(bs))
msg := wechat.ParseMsg(bs)
if msg == nil {
log.Println("xml格式公众号消息接口,请勿手动调用")
wechat.EchoSuccess(w)
return
}
最后就是AI测试了,看你选的模型能不能用,如果选择的是deepseek参数比较大的模型基本上会超时,项目里面设置了会返回到用户:
抱歉,无法在微信限制时间内做出应答
这条消息,所以如果你的微信端收到了来自公众号的这个消息,排除网络因素大概率是你的模型选的太牛皮了,换一个参数少点的试试