Skip to content

Commit

Permalink
Merge pull request #36 from fanchunke/feature/add-gpt3.5-api
Browse files Browse the repository at this point in the history
feat: 增加 GPT 3.5 API 支持
  • Loading branch information
fanchunke authored Mar 6, 2023
2 parents 9f372d1 + 78321aa commit ae122e3
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 22 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,9 @@ docker compose up -d

### 3. 配置企业微信

* URL 配置格式:`http://ip:port/wecom/receive`
* URL 配置格式
- text-davinci-003 版本:`http://ip:port/wecom/receive`
- gpt-3.5-turbo 版本:`http://ip:port/wecom/receive/v2`
* 在企业微信后台,添加可信IP地址

## FAQ
Expand Down Expand Up @@ -100,6 +102,9 @@ dataSource="file:chatgpt?_fk=1&parseTime=True&loc=Local"

## Changelog

### v0.1.4
- 增加 `gpt-3.5-turbo` API 的支持

### v0.1.3
- 添加makefile,docker-compose自动build MySQL等 [#14](https://github.com/fanchunke/chatgpt-wecom/pull/14)

Expand Down
Binary file added chatgpt
Binary file not shown.
4 changes: 2 additions & 2 deletions docker/callback.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ RUN go build -ldflags '-linkmode external -extldflags "-static"' -o /bin/chatgpt
# Step 3: Final
FROM alpine:latest
WORKDIR /home/works/program
COPY ./conf/chatgpt.conf ./chatgpt.conf
COPY ./conf/chatgpt.conf ./conf/chatgpt.conf
COPY --from=builder /bin/chatgpt-wecom .

EXPOSE 8000
CMD ["./chatgpt-wecom", "-conf=chatgpt.conf"]
CMD ["./chatgpt-wecom", "-conf=conf/chatgpt.conf"]
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ module github.com/fanchunke/chatgpt-wecom
go 1.19

require (
github.com/fanchunke/xgpt3 v0.1.3
github.com/fanchunke/xgpt3 v0.1.4
github.com/gin-contrib/pprof v1.4.0
github.com/gin-gonic/gin v1.8.2
github.com/go-resty/resty/v2 v2.7.0
github.com/go-sql-driver/mysql v1.7.0
github.com/mattn/go-sqlite3 v1.14.16
github.com/rs/xid v1.4.0
github.com/rs/zerolog v1.29.0
github.com/sashabaranov/go-gpt3 v1.1.0
github.com/sashabaranov/go-openai v1.4.1
github.com/spf13/viper v1.15.0
gopkg.in/natefinch/lumberjack.v2 v2.2.1
)
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,8 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
github.com/envoyproxy/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
github.com/fanchunke/xgpt3 v0.1.3 h1:KWhXjCMPUNA0t4XcxnjycD+oli58/NvPk6ASmc+j2K4=
github.com/fanchunke/xgpt3 v0.1.3/go.mod h1:2L7ZPmyoU3YuMwv1rp0g8EnBdqzwr3YHDOWrefzwoRY=
github.com/fanchunke/xgpt3 v0.1.4 h1:enFF6c3WqINLW+piXCCJhK74y/fqL6jzYv8X/JOrg6E=
github.com/fanchunke/xgpt3 v0.1.4/go.mod h1:4qo09rxP/yHMQLmsSM21yYA4ARzSt4sAzCiFSZAWW7I=
github.com/frankban/quicktest v1.14.3 h1:FJKSZTDHjyhriyC81FLQ0LY93eSai0ZyR/ZIkd3ZUKE=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
Expand Down Expand Up @@ -222,8 +222,8 @@ github.com/rs/xid v1.4.0 h1:qd7wPTDkN6KQx2VmMBLrpHkiyQwgFXRnkOLacUiaSNY=
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
github.com/rs/zerolog v1.29.0 h1:Zes4hju04hjbvkVkOhdl2HpZa+0PmVwigmo8XoORE5w=
github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6usyD0=
github.com/sashabaranov/go-gpt3 v1.1.0 h1:94w3N8Sx5VBSLAXFm4+dWrxWR4h1ID1wUftChJ0Ji5A=
github.com/sashabaranov/go-gpt3 v1.1.0/go.mod h1:BIZdbwdzxZbCrcKGMGH6u2eyGe1xFuX9Anmh3tCP8lQ=
github.com/sashabaranov/go-openai v1.4.1 h1:EofA9Ipo0JcG0FFTF5zI7i13Fpkn4+frWBH8AqbRJ6Q=
github.com/sashabaranov/go-openai v1.4.1/go.mod h1:lj5b/K+zjTSFxVLijLSTDZuP7adOgerWeFyZLUhAKRg=
github.com/sergi/go-diff v1.0.0 h1:Kpca3qRNrduNnOQeazBd0ysaKrUJiIuISHxogkT9RPQ=
github.com/spf13/afero v1.9.3 h1:41FoI0fD7OR7mGcKE/aOiLkGreyf8ifIOQmJANWogMk=
github.com/spf13/afero v1.9.3/go.mod h1:iUV7ddyEEZPO5gA3zD4fJt6iStLlL+Lg4m2cihcDf8Y=
Expand Down
58 changes: 52 additions & 6 deletions internal/api/receive.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,29 @@ import (
"github.com/fanchunke/xgpt3"

"github.com/rs/zerolog/log"
gogpt "github.com/sashabaranov/go-gpt3"
openai "github.com/sashabaranov/go-openai"
)

type versionType string

const (
callbackVersionV1 versionType = "v1"
callbackVersionV2 versionType = "v2"
)

type callbackHandler struct {
cfg *config.Config
xgpt3Client *xgpt3.Client
wecomClient *wecom.WeComApp
version versionType
}

func NewCallbackHandler(cfg *config.Config, xgpt3Client *xgpt3.Client, wecomClient *wecom.WeComApp) *callbackHandler {
func NewCallbackHandler(cfg *config.Config, xgpt3Client *xgpt3.Client, wecomClient *wecom.WeComApp, version versionType) *callbackHandler {
return &callbackHandler{
cfg: cfg,
xgpt3Client: xgpt3Client,
wecomClient: wecomClient,
version: version,
}
}

Expand All @@ -38,7 +47,14 @@ func (h *callbackHandler) OnIncomingMessage(ctx context.Context, msg *message.Rx

// 获取回复
if !closeSession {
reply, err = h.getGPTResponse(context.Background(), msg.AgentId, msg.FromUserName, content)
var handler func(ctx context.Context, agentId int64, userId string, content string) (string, error)
if h.version == callbackVersionV1 {
handler = h.getOpenAICompletion
} else {
handler = h.getOpenAIChatCompletion
}

reply, err = handler(context.Background(), msg.AgentId, msg.FromUserName, content)
if err != nil {
log.Error().Err(err).Msgf("Get GPT Response error: %v", err)
return err
Expand Down Expand Up @@ -71,10 +87,10 @@ func (h *callbackHandler) OnIncomingMessage(ctx context.Context, msg *message.Rx
return nil
}

func (h *callbackHandler) getGPTResponse(ctx context.Context, agentId int64, userId, content string) (string, error) {
func (h *callbackHandler) getOpenAICompletion(ctx context.Context, agentId int64, userId, content string) (string, error) {
// 获取 GPT 回复
req := gogpt.CompletionRequest{
Model: gogpt.GPT3TextDavinci003,
req := openai.CompletionRequest{
Model: openai.GPT3TextDavinci003,
MaxTokens: 1500,
Prompt: content,
TopP: 1,
Expand Down Expand Up @@ -115,3 +131,33 @@ func (h *callbackHandler) sendTextMessage(ctx context.Context, agentId int64, us

return nil
}

func (h *callbackHandler) getOpenAIChatCompletion(ctx context.Context, agentId int64, userId, content string) (string, error) {
// 获取 GPT 回复
req := openai.ChatCompletionRequest{
Model: openai.GPT3Dot5Turbo,
MaxTokens: 1500,
Messages: []openai.ChatCompletionMessage{
{
Role: openai.ChatMessageRoleUser,
Content: content,
},
},
TopP: 1,
Temperature: 0.9,
PresencePenalty: 0.6,
User: userId,
}
resp, err := h.xgpt3Client.CreateChatCompletionWithChannel(ctx, req, fmt.Sprintf("%d", agentId))
if err != nil {
return "", fmt.Errorf("CreateCompletion failed: %w", err)
}

if len(resp.Choices) == 0 {
return "", fmt.Errorf("Empty GPT Choices")
}

// 发送回复给用户
reply := strings.TrimSpace(resp.Choices[0].Message.Content)
return reply, nil
}
20 changes: 15 additions & 5 deletions internal/api/router.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,23 @@ func NewRouter(cfg *config.Config, xgpt3Client *xgpt3.Client, wecomApp *wecom.We
r.Use(middleware.AccessHandler())
r.GET("/healthz", r.Healthz)

callback := NewCallbackHandler(cfg, xgpt3Client, wecomApp)
msgHandler, err := wecomApp.RxMessageHandler(callback)
callbackV1 := NewCallbackHandler(cfg, xgpt3Client, wecomApp, callbackVersionV1)
msgHandlerV1, err := wecomApp.RxMessageHandler(callbackV1)
if err != nil {
log.Error().Err(err).Msgf("Init RxMessageHandler failed: %s", err)
log.Error().Err(err).Msgf("Init RxMessageHandler V1 failed: %s", err)
return nil, err
}
r.GET("/wecom/receive", gin.WrapH(msgHandler))
r.POST("/wecom/receive", gin.WrapH(msgHandler))

callbackV2 := NewCallbackHandler(cfg, xgpt3Client, wecomApp, callbackVersionV2)
msgHandlerV2, err := wecomApp.RxMessageHandler(callbackV2)
if err != nil {
log.Error().Err(err).Msgf("Init RxMessageHandler V2 failed: %s", err)
return nil, err
}

r.GET("/wecom/receive", gin.WrapH(msgHandlerV1))
r.POST("/wecom/receive", gin.WrapH(msgHandlerV1))
r.GET("/wecom/receive/v2", gin.WrapH(msgHandlerV2))
r.POST("/wecom/receive/v2", gin.WrapH(msgHandlerV2))
return r, nil
}
4 changes: 2 additions & 2 deletions internal/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,14 @@ import (
"github.com/fanchunke/xgpt3/conversation/ent/chatent"

"github.com/rs/zerolog/log"
gogpt "github.com/sashabaranov/go-gpt3"
"github.com/sashabaranov/go-openai"
)

func Run(cfg *config.Config) {
log.Info().Msgf("Config: %v", cfg)

// 初始化 gpt client
gptClient := gogpt.NewClient(cfg.GPT.ApiKey)
gptClient := openai.NewClient(cfg.GPT.ApiKey)

// 初始化数据库 client
dbConf := cfg.Database
Expand Down

0 comments on commit ae122e3

Please sign in to comment.