-
Notifications
You must be signed in to change notification settings - Fork 33
/
gpt.go
96 lines (88 loc) · 2.15 KB
/
gpt.go
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
package service
import (
"context"
"fmt"
"time"
"github.com/gin-gonic/gin"
"github.com/patrickmn/go-cache"
gogpt "github.com/sashabaranov/go-gpt3"
)
// 企业微信 token 缓存,请求频次过高可能有一些额外的问题
var conversationCache = cache.New(5*time.Minute, 5*time.Minute)
type ChatGPT struct {
client *gogpt.Client
ctx context.Context
userId string
}
func Chat(c *gin.Context) {
question := c.Query("question")
conversationId := c.Query("conversationId")
ret, err := AskOnConversation(question, conversationId, weworkConversationSize)
if err != nil {
c.JSON(500, err.Error())
return
}
c.JSON(200, ret)
}
func AskOnConversation(question, conversationId string, size int) (string, error) {
var messages = []gogpt.ChatCompletionMessage{}
key := fmt.Sprintf("cache:conversation:%s", conversationId)
data, found := conversationCache.Get(key)
if found {
messages = data.([]gogpt.ChatCompletionMessage)
}
messages = append(messages, gogpt.ChatCompletionMessage{
Role: "user",
Content: question,
})
fmt.Println(messages)
pivot := size
if pivot > len(messages) {
pivot = len(messages)
}
messages = messages[len(messages)-pivot:]
conversationCache.Set(key, messages, 12*time.Hour)
chat := NewGPT(openAiKey, conversationId)
defer chat.Close()
answer, err := chat.Chat(messages)
if err != nil {
fmt.Print(err.Error())
}
return answer, err
}
func (c *ChatGPT) Chat(messages []gogpt.ChatCompletionMessage) (answer string, err error) {
var msg = gogpt.ChatCompletionMessage{}
msg.Role = "system"
req := gogpt.ChatCompletionRequest{
Model: gogpt.GPT3Dot5Turbo,
Messages: messages,
}
resp, err := c.client.CreateChatCompletion(c.ctx, req)
if err != nil {
return "", err
}
answer = resp.Choices[0].Message.Content
for len(answer) > 0 {
if answer[0] == '\n' {
answer = answer[1:]
} else {
break
}
}
return answer, err
}
func NewGPT(ApiKey, UserId string) *ChatGPT {
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-ctx.Done()
cancel()
}()
return &ChatGPT{
client: gogpt.NewClient(ApiKey),
ctx: ctx,
userId: UserId,
}
}
func (c *ChatGPT) Close() {
c.ctx.Done()
}