Skip to content

Commit 27383af

Browse files
authored
Merge pull request #9 from lvyonghuan/main
optimize config
2 parents a1f76cc + 8617e0d commit 27383af

File tree

6 files changed

+100
-36
lines changed

6 files changed

+100
-36
lines changed

Diff for: README.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
### Windows
1616
* 双击go-cqhttp可执行文件,按照提示登录QQ,选择2正向WebSocket
1717
* 双击QQ-ChatGPT-Bot可执行文件,将openai的api_key 填入`config.cfg`中,再次运行
18-
* 如果要使用角色扮演功能,则请在config中的identity下填写想要bot扮演的角色的信息。同时,请将openai配置下的model更换成“text-davinci-003”。
18+
* 如果要使用角色预设功能,则请在`config.cfg`中的identity下填写想要bot扮演的角色的信息。同时,请将openai配置下的model更换成“text-davinci-003”。
19+
* 如果要使用连续对话,请在`config.cfg`中的context下进行设置。如果要启用角色预设,则不支持连续对话。
1920
### Linux
2021
```bash
2122
./go-cqhttp*
2223
# 按照提示操作,选择2正向websocket,将本地登录过的`sesssion.token`复制进服务器,防止tx风控
2324
./QQ-ChatGPT*
24-
# 在config.cfg填入openai的api_key
25+
# 在config.cfg填入openai的api_key
26+
# 其它配置参考windows的说明
2527
# 关掉窗口,运行:
2628
nohup ./go-cqhttp* &
2729
nohup ./QQ-ChatGPT* &
@@ -65,3 +67,5 @@ use_proxy = false ## 中国大陆地区需开启
6567
proxy_url = "http://127.0.0.1:7890"
6668
...
6769
```
70+
### 对话指令
71+
* 在启用连续对话的情景下,聊天中输入`/clean`将清除之前的对话记录。

Diff for: cmd/chatgpt/chatgpt.go

+23-18
Original file line numberDiff line numberDiff line change
@@ -99,18 +99,21 @@ func Client() (http.Client, error) {
9999
}
100100

101101
// ChooseGenerateWay 选择生成方式
102-
func ChooseGenerateWay(session string, text string) string {
102+
func ChooseGenerateWay(session string, text string, useContext bool) (string, error) {
103103
log.Println("正在调用OpenAI API生成文本...", text)
104104
if config.Cfg.Identity.UseIdentity == false {
105-
return GenerateText(session, text)
105+
return GenerateText(session, text, useContext)
106106
} else {
107107
return GenerateTextWithIdentity(text)
108108
}
109109
}
110110

111111
// GenerateText 调用openai的API生成文本
112-
func GenerateText(session string, text string) string {
113-
ms := Cache.GetMsg(session)
112+
func GenerateText(session string, text string, useContext bool) (string, error) {
113+
var ms []Messages
114+
if useContext {
115+
ms = Cache.GetMsg(session)
116+
}
114117
message := &Messages{
115118
Role: "user",
116119
Content: text,
@@ -125,7 +128,7 @@ func GenerateText(session string, text string) string {
125128
postDataBytes, err := json.Marshal(postDataTemp)
126129
if err != nil {
127130
log.Println(err)
128-
return ""
131+
return "", err
129132
}
130133
req, _ := http.NewRequest("POST", Openaiapiurl1, bytes.NewBuffer(postDataBytes))
131134
req.Header.Set("Content-Type", "application/json")
@@ -137,34 +140,36 @@ func GenerateText(session string, text string) string {
137140
resp, err := client.Do(req)
138141
if err != nil {
139142
log.Println(err)
140-
return err.Error()
143+
return err.Error(), err
141144
}
142145
defer resp.Body.Close()
143146
if resp == nil {
144147
log.Println("response is nil")
145-
return ""
148+
return "", err
146149
}
147150
body, _ := io.ReadAll(resp.Body)
148151
var openAiRcv OpenAiRcv
149152
err = json.Unmarshal(body, &openAiRcv)
150153
if err != nil {
151154
log.Println(err)
152-
return err.Error()
155+
return err.Error(), err
153156
}
154157
if len(openAiRcv.Choices) == 0 {
155158
log.Println("OpenAI API调用失败,返回内容:", string(body))
156-
return string(body)
159+
return string(body), err
157160
}
158161
// 保存上下文
159-
ms = append(ms, openAiRcv.Choices[0].Message)
160-
Cache.SetMsg(session, ms)
162+
if useContext {
163+
ms = append(ms, openAiRcv.Choices[0].Message)
164+
Cache.SetMsg(session, ms)
165+
}
161166
openAiRcv.Choices[0].Message.Content = strings.Replace(openAiRcv.Choices[0].Message.Content, "\n\n", "\n", 1)
162167
log.Printf("Model: %s TotalTokens: %d+%d=%d", openAiRcv.Model, openAiRcv.Usage.PromptTokens, openAiRcv.Usage.CompletionTokes, openAiRcv.Usage.TotalTokens)
163-
return openAiRcv.Choices[0].Message.Content
168+
return openAiRcv.Choices[0].Message.Content, err
164169
}
165170

166171
// GenerateTextWithIdentity 使用身份的时候,使用这个生成文本
167-
func GenerateTextWithIdentity(text string) string {
172+
func GenerateTextWithIdentity(text string) (string, error) {
168173
postDataTemp := postDataWithIdentity{
169174
Model: config.Cfg.OpenAi.Model,
170175
MaxTokens: config.Cfg.OpenAi.MaxTokens,
@@ -175,7 +180,7 @@ func GenerateTextWithIdentity(text string) string {
175180
postDataBytes, err := json.Marshal(postDataTemp)
176181
if err != nil {
177182
log.Println(err)
178-
return err.Error()
183+
return err.Error(), err
179184
}
180185
req, _ := http.NewRequest("POST", Openaiapiurl2, bytes.NewBuffer(postDataBytes))
181186
req.Header.Set("Content-Type", "application/json")
@@ -187,12 +192,12 @@ func GenerateTextWithIdentity(text string) string {
187192
resp, err := client.Do(req)
188193
if err != nil {
189194
log.Println(err)
190-
return err.Error()
195+
return err.Error(), err
191196
}
192197
defer resp.Body.Close()
193198
if resp == nil {
194199
log.Println("response is nil")
195-
return ""
200+
return "", err
196201
}
197202
body, _ := io.ReadAll(resp.Body)
198203
var openAiRcvWithIdentity OpenAiRcvWithIdentity
@@ -202,9 +207,9 @@ func GenerateTextWithIdentity(text string) string {
202207
}
203208
if len(openAiRcvWithIdentity.Choices) == 0 {
204209
log.Println("OpenAI API调用失败,返回内容:", string(body))
205-
return string(body)
210+
return string(body), err
206211
}
207212
openAiRcvWithIdentity.Choices[0].Text = strings.Replace(openAiRcvWithIdentity.Choices[0].Text, "\n\n", "\n", 1)
208213
log.Printf("Model: %s TotalTokens: %d+%d=%d", openAiRcvWithIdentity.Model, openAiRcvWithIdentity.Usage.PromptTokens, openAiRcvWithIdentity.Usage.CompletionTokes, openAiRcvWithIdentity.Usage.TotalTokens)
209-
return openAiRcvWithIdentity.Choices[0].Text
214+
return openAiRcvWithIdentity.Choices[0].Text, err
210215
}

Diff for: cmd/cqhttp/message.go

+19-9
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,22 @@ func (bot *Bot) HandleMsg(isAt bool, rcvMsg RcvMsg) {
6060
return
6161
}
6262
rcvMsg.Message = strings.ReplaceAll(rcvMsg.Message, config.Cfg.CqHttp.Keyword, "")
63-
bot.MQ <- &rcvMsg
64-
if strings.Contains(rcvMsg.Message, "clear") {
63+
//输入“/clean”,清理缓存的历史记录(应该是吧?这块不是我写的,但是如果输入里有clear就执行这个clear命令就太破坏了,毕竟clear算常用单词)
64+
if strings.TrimSpace(rcvMsg.Message) == "/clean" {
6565
chatgpt.Cache.Clear(strconv.FormatInt(rcvMsg.Sender.UserId, 10))
66+
err := bot.SendPrivateMsg(rcvMsg.Sender.UserId, "历史记录清理完成")
67+
if err != nil {
68+
log.Println(err)
69+
}
70+
log.Println("历史记录清理完成")
6671
return
6772
}
68-
msg := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.Sender.UserId, 10), rcvMsg.Message)
69-
var err error
73+
bot.MQ <- &rcvMsg
74+
msg, err := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.Sender.UserId, 10), rcvMsg.Message, config.Cfg.Context.PrivateContext)
7075
if msg != "" {
7176
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+msg)
7277
} else {
73-
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!")
78+
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!错误信息:\n"+err.Error())
7479
}
7580
if err != nil {
7681
log.Println(err)
@@ -86,17 +91,22 @@ func (bot *Bot) HandleMsg(isAt bool, rcvMsg RcvMsg) {
8691
return
8792
}
8893
rcvMsg.Message = strings.ReplaceAll(rcvMsg.Message, config.Cfg.CqHttp.Keyword, "")
89-
if strings.Contains(rcvMsg.Message, "clear") {
94+
if rcvMsg.Message == " /clean" {
9095
chatgpt.Cache.Clear(strconv.FormatInt(rcvMsg.GroupId, 10))
96+
err := bot.SendGroupMsg(rcvMsg.GroupId, "历史记录清理完成")
97+
if err != nil {
98+
println(err)
99+
}
100+
log.Println("历史记录清理完成")
91101
return
92102
}
93103
bot.MQ <- &rcvMsg
94-
msg := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.GroupId, 10), rcvMsg.Message)
95-
var err error
104+
msg, err := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.GroupId, 10), rcvMsg.Message, config.Cfg.Context.GroupContext)
105+
//var err error
96106
if msg != "" {
97107
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+msg)
98108
} else {
99-
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!")
109+
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!错误信息:\n"+err.Error())
100110
}
101111
if err != nil {
102112
log.Println(err)

Diff for: config.example.cfg

+9-3
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,21 @@ temperature = 0.3
2727
max_tokens = 1000
2828
# openai是否走代理,默认关闭
2929
use_proxy = false
30-
# Clash默认代理地址
30+
# 代理地址
3131
proxy_url = "http://127.0.0.1:7890"
3232

3333
# 角色信息配置
3434
[identity]
35-
# 角色扮演功能,默认关闭
35+
# 角色预设功能,默认关闭
3636
use_identity = false
37-
# 角色扮演信息(如果不想使用这个功能,请删掉prompt双引号里的内容)(设定可以参考:https://github.com/easydu2002/chat_gpt_oicq/wiki/设定AI人格---以猫娘为案例【chatGPT猫娘】)
37+
# 角色预设信息(设定可以参考:https://github.com/easydu2002/chat_gpt_oicq/wiki/设定AI人格---以猫娘为案例【chatGPT猫娘】)
3838
prompt = "(你扮演的角色名称):你要求AI扮演的角色信息\n(AI扮演的角色名称):AI的回应"
3939
# 扮演的身份名称(前面填对话者,后面填bot要扮演的角色)
4040
stop = ["(你扮演的角色名称):", "(AI扮演的角色名称):"]
4141

42+
# 连续对话相关(实际使用中,连续对话似乎会导致更多的token使用,在这里可以设置是否启用这个功能。默认关闭。另注:预设角色不支持连续对话。)
43+
[context]
44+
# 是否在私聊中启用连续对话
45+
private_context = false
46+
# 是否在群聊中启用连续对话
47+
group_context = false

Diff for: config/config.go

+43-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,10 @@ type Config struct {
2929
Prompt string `mapstructure:"prompt"`
3030
Stop []string `mapstructure:"stop"`
3131
}
32+
Context struct {
33+
PrivateContext bool `mapstructure:"private_context"`
34+
GroupContext bool `mapstructure:"group_context"`
35+
}
3236
}
3337

3438
var Cfg Config
@@ -41,7 +45,45 @@ func init() {
4145
log.Println(err)
4246
}
4347
// 自动生成配置文件
44-
_, err = f.Write([]byte("# config.toml 配置文件\n\n# cqhttp机器人配置\n[cqhttp]\n# go-cqhttp的正向WebSocket地址\nwebsocket = \"ws://127.0.0.1:8080\"\n# 群聊是否需要@机器人才能触发\nat_only = true\n# 是否开启触发关键词\nuse_keyword = false\n# 触发关键词场合 可选值: all, group, private, 开启群聊关键词建议关闭at_only\nkeyword_type = \"group\"\n# 触发关键词\nkeyword = \"对话\"\n# 生成中提醒时间秒数\ntimeout = 30\n\n# openai配置\n[openai]\n# 你的 OpenAI API Key, 可以在 https://beta.openai.com/account/api-keys 获取\napi_key = \"sk-xxxxxx\"\n# 使用的模型,默认是 gpt-3.5-turbo\nmodel = \"gpt-3.5-turbo\"\n# 对话温度,越大越随机 参照https://algowriting.medium.com/gpt-3-temperature-setting-101-41200ff0d0be\ntemperature = 0.3\n# 每次对话最大生成字符数\nmax_tokens = 1000\n# openai是否走代理,默认关闭\nuse_proxy = false\n# 代理地址\nproxy_url = \"http://127.0.0.1:7890\"\n\n# 角色信息配置\n[identity]\n# 角色扮演功能,默认关闭\nuse_identity = false\n# 角色扮演信息(如果不想使用这个功能,请删掉prompt双引号里的内容)(设定可以参考:https://github.com/easydu2002/chat_gpt_oicq/wiki/设定AI人格---以猫娘为案例【chatGPT猫娘】)\nprompt = \"(你扮演的角色名称):你要求AI扮演的角色信息\\n(AI扮演的角色名称):AI的回应\"\n# 扮演的身份名称(前面填对话者,后面填bot要扮演的角色)\nstop = [\"(你扮演的角色名称):\", \"(AI扮演的角色名称):\"]\n\n"))
48+
_, err = f.Write([]byte("# config.toml 配置文件\n\n" +
49+
"# cqhttp机器人配置\n[cqhttp]\n" +
50+
"# go-cqhttp的正向WebSocket地址\n" +
51+
"websocket = \"ws://127.0.0.1:8080\"\n" +
52+
"# 群聊是否需要@机器人才能触发\n" +
53+
"at_only = true\n" +
54+
"# 是否开启触发关键词\n" +
55+
"use_keyword = false\n" +
56+
"# 触发关键词场合 可选值: all, group, private, 开启群聊关键词建议关闭at_only\n" +
57+
"keyword_type = \"group\"\n" +
58+
"# 触发关键词\n" +
59+
"keyword = \"对话\"\n" +
60+
"# 生成中提醒时间秒数\n" +
61+
"timeout = 30\n\n" +
62+
"# openai配置\n[openai]\n" +
63+
"# 你的 OpenAI API Key, 可以在 https://beta.openai.com/account/api-keys 获取\n" +
64+
"api_key = \"sk-xxxxxx\"\n" +
65+
"# 使用的模型,默认是 gpt-3.5-turbo\n" +
66+
"model = \"gpt-3.5-turbo\"\n" +
67+
"# 对话温度,越大越随机 参照https://algowriting.medium.com/gpt-3-temperature-setting-101-41200ff0d0be\n" +
68+
"temperature = 0.3\n" +
69+
"# 每次对话最大生成字符数\n" +
70+
"max_tokens = 1000\n" +
71+
"# openai是否走代理,默认关闭\n" +
72+
"use_proxy = false\n" +
73+
"# 代理地址\n" +
74+
"proxy_url = \"http://127.0.0.1:7890\"\n\n" +
75+
"# 角色信息配置\n[identity]\n" +
76+
"# 角色预设功能,默认关闭\n" +
77+
"use_identity = false\n" +
78+
"# 角色预设信息(设定可以参考:https://github.com/easydu2002/chat_gpt_oicq/wiki/设定AI人格---以猫娘为案例【chatGPT猫娘】)\n" +
79+
"prompt = \"(你扮演的角色名称):你要求AI扮演的角色信息\\n(AI扮演的角色名称):AI的回应\"\n" +
80+
"# 扮演的身份名称(前面填对话者,后面填bot要扮演的角色)\n" +
81+
"stop = [\"(你扮演的角色名称):\", \"(AI扮演的角色名称):\"]\n\n" +
82+
"# 连续对话相关(实际使用中,连续对话似乎会导致更多的token使用,在这里可以设置是否启用这个功能。默认关闭。另注:预设角色不支持连续对话。)\n[context]\n" +
83+
"# 是否在私聊中启用连续对话\n" +
84+
"private_context = false\n" +
85+
"# 是否在群聊中启用连续对话\n" +
86+
"group_context = false\n"))
4587
if err != nil {
4688
log.Println(err)
4789
}

Diff for: main.go

-3
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,8 @@ func init() {
1111
}
1212

1313
func main() {
14-
1514
go cqhttp.Run()
1615
for {
1716
cqhttp.TimeOutCheck()
18-
1917
}
20-
2118
}

0 commit comments

Comments
 (0)