Skip to content

Commit

Permalink
Merge pull request #9 from lvyonghuan/main
Browse files Browse the repository at this point in the history
optimize config
  • Loading branch information
SuInk authored Mar 31, 2023
2 parents a1f76cc + 8617e0d commit 27383af
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 36 deletions.
8 changes: 6 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
### Windows
* 双击go-cqhttp可执行文件,按照提示登录QQ,选择2正向WebSocket
* 双击QQ-ChatGPT-Bot可执行文件,将openai的api_key 填入`config.cfg`中,再次运行
* 如果要使用角色扮演功能,则请在config中的identity下填写想要bot扮演的角色的信息。同时,请将openai配置下的model更换成“text-davinci-003”。
* 如果要使用角色预设功能,则请在`config.cfg`中的identity下填写想要bot扮演的角色的信息。同时,请将openai配置下的model更换成“text-davinci-003”。
* 如果要使用连续对话,请在`config.cfg`中的context下进行设置。如果要启用角色预设,则不支持连续对话。
### Linux
```bash
./go-cqhttp*
# 按照提示操作,选择2正向websocket,将本地登录过的`sesssion.token`复制进服务器,防止tx风控
./QQ-ChatGPT*
# 在config.cfg填入openai的api_key
# 在config.cfg填入openai的api_key
# 其它配置参考windows的说明
# 关掉窗口,运行:
nohup ./go-cqhttp* &
nohup ./QQ-ChatGPT* &
Expand Down Expand Up @@ -65,3 +67,5 @@ use_proxy = false ## 中国大陆地区需开启
proxy_url = "http://127.0.0.1:7890"
...
```
### 对话指令
* 在启用连续对话的情景下,聊天中输入`/clean`将清除之前的对话记录。
41 changes: 23 additions & 18 deletions cmd/chatgpt/chatgpt.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,18 +99,21 @@ func Client() (http.Client, error) {
}

// ChooseGenerateWay 选择生成方式
func ChooseGenerateWay(session string, text string) string {
func ChooseGenerateWay(session string, text string, useContext bool) (string, error) {
log.Println("正在调用OpenAI API生成文本...", text)
if config.Cfg.Identity.UseIdentity == false {
return GenerateText(session, text)
return GenerateText(session, text, useContext)
} else {
return GenerateTextWithIdentity(text)
}
}

// GenerateText 调用openai的API生成文本
func GenerateText(session string, text string) string {
ms := Cache.GetMsg(session)
func GenerateText(session string, text string, useContext bool) (string, error) {
var ms []Messages
if useContext {
ms = Cache.GetMsg(session)
}
message := &Messages{
Role: "user",
Content: text,
Expand All @@ -125,7 +128,7 @@ func GenerateText(session string, text string) string {
postDataBytes, err := json.Marshal(postDataTemp)
if err != nil {
log.Println(err)
return ""
return "", err
}
req, _ := http.NewRequest("POST", Openaiapiurl1, bytes.NewBuffer(postDataBytes))
req.Header.Set("Content-Type", "application/json")
Expand All @@ -137,34 +140,36 @@ func GenerateText(session string, text string) string {
resp, err := client.Do(req)
if err != nil {
log.Println(err)
return err.Error()
return err.Error(), err
}
defer resp.Body.Close()
if resp == nil {
log.Println("response is nil")
return ""
return "", err
}
body, _ := io.ReadAll(resp.Body)
var openAiRcv OpenAiRcv
err = json.Unmarshal(body, &openAiRcv)
if err != nil {
log.Println(err)
return err.Error()
return err.Error(), err
}
if len(openAiRcv.Choices) == 0 {
log.Println("OpenAI API调用失败,返回内容:", string(body))
return string(body)
return string(body), err
}
// 保存上下文
ms = append(ms, openAiRcv.Choices[0].Message)
Cache.SetMsg(session, ms)
if useContext {
ms = append(ms, openAiRcv.Choices[0].Message)
Cache.SetMsg(session, ms)
}
openAiRcv.Choices[0].Message.Content = strings.Replace(openAiRcv.Choices[0].Message.Content, "\n\n", "\n", 1)
log.Printf("Model: %s TotalTokens: %d+%d=%d", openAiRcv.Model, openAiRcv.Usage.PromptTokens, openAiRcv.Usage.CompletionTokes, openAiRcv.Usage.TotalTokens)
return openAiRcv.Choices[0].Message.Content
return openAiRcv.Choices[0].Message.Content, err
}

// GenerateTextWithIdentity 使用身份的时候,使用这个生成文本
func GenerateTextWithIdentity(text string) string {
func GenerateTextWithIdentity(text string) (string, error) {
postDataTemp := postDataWithIdentity{
Model: config.Cfg.OpenAi.Model,
MaxTokens: config.Cfg.OpenAi.MaxTokens,
Expand All @@ -175,7 +180,7 @@ func GenerateTextWithIdentity(text string) string {
postDataBytes, err := json.Marshal(postDataTemp)
if err != nil {
log.Println(err)
return err.Error()
return err.Error(), err
}
req, _ := http.NewRequest("POST", Openaiapiurl2, bytes.NewBuffer(postDataBytes))
req.Header.Set("Content-Type", "application/json")
Expand All @@ -187,12 +192,12 @@ func GenerateTextWithIdentity(text string) string {
resp, err := client.Do(req)
if err != nil {
log.Println(err)
return err.Error()
return err.Error(), err
}
defer resp.Body.Close()
if resp == nil {
log.Println("response is nil")
return ""
return "", err
}
body, _ := io.ReadAll(resp.Body)
var openAiRcvWithIdentity OpenAiRcvWithIdentity
Expand All @@ -202,9 +207,9 @@ func GenerateTextWithIdentity(text string) string {
}
if len(openAiRcvWithIdentity.Choices) == 0 {
log.Println("OpenAI API调用失败,返回内容:", string(body))
return string(body)
return string(body), err
}
openAiRcvWithIdentity.Choices[0].Text = strings.Replace(openAiRcvWithIdentity.Choices[0].Text, "\n\n", "\n", 1)
log.Printf("Model: %s TotalTokens: %d+%d=%d", openAiRcvWithIdentity.Model, openAiRcvWithIdentity.Usage.PromptTokens, openAiRcvWithIdentity.Usage.CompletionTokes, openAiRcvWithIdentity.Usage.TotalTokens)
return openAiRcvWithIdentity.Choices[0].Text
return openAiRcvWithIdentity.Choices[0].Text, err
}
28 changes: 19 additions & 9 deletions cmd/cqhttp/message.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,17 +60,22 @@ func (bot *Bot) HandleMsg(isAt bool, rcvMsg RcvMsg) {
return
}
rcvMsg.Message = strings.ReplaceAll(rcvMsg.Message, config.Cfg.CqHttp.Keyword, "")
bot.MQ <- &rcvMsg
if strings.Contains(rcvMsg.Message, "clear") {
//输入“/clean”,清理缓存的历史记录(应该是吧?这块不是我写的,但是如果输入里有clear就执行这个clear命令就太破坏了,毕竟clear算常用单词)
if strings.TrimSpace(rcvMsg.Message) == "/clean" {
chatgpt.Cache.Clear(strconv.FormatInt(rcvMsg.Sender.UserId, 10))
err := bot.SendPrivateMsg(rcvMsg.Sender.UserId, "历史记录清理完成")
if err != nil {
log.Println(err)
}
log.Println("历史记录清理完成")
return
}
msg := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.Sender.UserId, 10), rcvMsg.Message)
var err error
bot.MQ <- &rcvMsg
msg, err := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.Sender.UserId, 10), rcvMsg.Message, config.Cfg.Context.PrivateContext)
if msg != "" {
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+msg)
} else {
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!")
err = bot.SendPrivateMsg(rcvMsg.Sender.UserId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!错误信息:\n"+err.Error())
}
if err != nil {
log.Println(err)
Expand All @@ -86,17 +91,22 @@ func (bot *Bot) HandleMsg(isAt bool, rcvMsg RcvMsg) {
return
}
rcvMsg.Message = strings.ReplaceAll(rcvMsg.Message, config.Cfg.CqHttp.Keyword, "")
if strings.Contains(rcvMsg.Message, "clear") {
if rcvMsg.Message == " /clean" {
chatgpt.Cache.Clear(strconv.FormatInt(rcvMsg.GroupId, 10))
err := bot.SendGroupMsg(rcvMsg.GroupId, "历史记录清理完成")
if err != nil {
println(err)
}
log.Println("历史记录清理完成")
return
}
bot.MQ <- &rcvMsg
msg := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.GroupId, 10), rcvMsg.Message)
var err error
msg, err := chatgpt.ChooseGenerateWay(strconv.FormatInt(rcvMsg.GroupId, 10), rcvMsg.Message, config.Cfg.Context.GroupContext)
//var err error
if msg != "" {
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+msg)
} else {
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!")
err = bot.SendGroupMsg(rcvMsg.GroupId, "[CQ:reply,id="+strconv.FormatInt(rcvMsg.MessageId, 10)+"]"+"生成错误!错误信息:\n"+err.Error())
}
if err != nil {
log.Println(err)
Expand Down
12 changes: 9 additions & 3 deletions config.example.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,21 @@ temperature = 0.3
max_tokens = 1000
# openai是否走代理,默认关闭
use_proxy = false
# Clash默认代理地址
# 代理地址
proxy_url = "http://127.0.0.1:7890"

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

# 连续对话相关(实际使用中,连续对话似乎会导致更多的token使用,在这里可以设置是否启用这个功能。默认关闭。另注:预设角色不支持连续对话。)
[context]
# 是否在私聊中启用连续对话
private_context = false
# 是否在群聊中启用连续对话
group_context = false
44 changes: 43 additions & 1 deletion config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ type Config struct {
Prompt string `mapstructure:"prompt"`
Stop []string `mapstructure:"stop"`
}
Context struct {
PrivateContext bool `mapstructure:"private_context"`
GroupContext bool `mapstructure:"group_context"`
}
}

var Cfg Config
Expand All @@ -41,7 +45,45 @@ func init() {
log.Println(err)
}
// 自动生成配置文件
_, 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"))
_, err = f.Write([]byte("# config.toml 配置文件\n\n" +
"# cqhttp机器人配置\n[cqhttp]\n" +
"# go-cqhttp的正向WebSocket地址\n" +
"websocket = \"ws://127.0.0.1:8080\"\n" +
"# 群聊是否需要@机器人才能触发\n" +
"at_only = true\n" +
"# 是否开启触发关键词\n" +
"use_keyword = false\n" +
"# 触发关键词场合 可选值: all, group, private, 开启群聊关键词建议关闭at_only\n" +
"keyword_type = \"group\"\n" +
"# 触发关键词\n" +
"keyword = \"对话\"\n" +
"# 生成中提醒时间秒数\n" +
"timeout = 30\n\n" +
"# openai配置\n[openai]\n" +
"# 你的 OpenAI API Key, 可以在 https://beta.openai.com/account/api-keys 获取\n" +
"api_key = \"sk-xxxxxx\"\n" +
"# 使用的模型,默认是 gpt-3.5-turbo\n" +
"model = \"gpt-3.5-turbo\"\n" +
"# 对话温度,越大越随机 参照https://algowriting.medium.com/gpt-3-temperature-setting-101-41200ff0d0be\n" +
"temperature = 0.3\n" +
"# 每次对话最大生成字符数\n" +
"max_tokens = 1000\n" +
"# openai是否走代理,默认关闭\n" +
"use_proxy = false\n" +
"# 代理地址\n" +
"proxy_url = \"http://127.0.0.1:7890\"\n\n" +
"# 角色信息配置\n[identity]\n" +
"# 角色预设功能,默认关闭\n" +
"use_identity = false\n" +
"# 角色预设信息(设定可以参考:https://github.com/easydu2002/chat_gpt_oicq/wiki/设定AI人格---以猫娘为案例【chatGPT猫娘】)\n" +
"prompt = \"(你扮演的角色名称):你要求AI扮演的角色信息\\n(AI扮演的角色名称):AI的回应\"\n" +
"# 扮演的身份名称(前面填对话者,后面填bot要扮演的角色)\n" +
"stop = [\"(你扮演的角色名称):\", \"(AI扮演的角色名称):\"]\n\n" +
"# 连续对话相关(实际使用中,连续对话似乎会导致更多的token使用,在这里可以设置是否启用这个功能。默认关闭。另注:预设角色不支持连续对话。)\n[context]\n" +
"# 是否在私聊中启用连续对话\n" +
"private_context = false\n" +
"# 是否在群聊中启用连续对话\n" +
"group_context = false\n"))
if err != nil {
log.Println(err)
}
Expand Down
3 changes: 0 additions & 3 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,8 @@ func init() {
}

func main() {

go cqhttp.Run()
for {
cqhttp.TimeOutCheck()

}

}

0 comments on commit 27383af

Please sign in to comment.