Столкнулся с проблемой при создании бота ChatGpt для telegram на Golang
package main
import (
"context"
"fmt"
"log"
"strings"
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api"
gogpt "github.com/sashabaranov/go-gpt3"
"github.com/spf13/viper"
)
type Config struct {
TelegramToken string `mapstructure:"tgToken"`
GptToken string `mapstructure:"gptToken"`
}
type GptBotStruct struct {
MaxTokensGpt int
NameBot string
}
func LoadConfig(path string) (c Config, err error) {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(path)
viper.AutomaticEnv()
err = viper.ReadInConfig()
if err != nil {
return
}
err = viper.Unmarshal(&c)
return
}
func sendChatGPT(c *gogpt.Client, sendText string, gptM GptBotStruct) string {
ctx := context.Background()
req := gogpt.CompletionRequest{
Model: gptM.NameBot,
MaxTokens: gptM.MaxTokensGpt,
Prompt: sendText,
FrequencyPenalty: 0,
PresencePenalty: 0,
}
resp, err := c.CreateCompletion(ctx, req)
if err != nil {
return "ChatGPT API error"
} else {
return resp.Choices[0].Text
}
}
func main() {
// Reading config.yaml
config, err := LoadConfig(".")
if err != nil {
panic(fmt.Errorf("fatal error with config.yaml: %w", err))
}
// Chat GPT initialization
chatGPT := gogpt.NewClient(config.GptToken)
// Telegram initialization
bot, err := tgbotapi.NewBotAPI(config.TelegramToken)
if err != nil {
log.Panic(err)
}
bot.Debug = true // set to false for suppress logs in stdout
log.Printf("Authorized on account %s", bot.Self.UserName)
// Start Telegram long polling update
u := tgbotapi.NewUpdate(0)
u.Timeout = 5
updates, _ := bot.GetUpdatesChan(u)
GptMode := GptBotStruct{
MaxTokensGpt: 3000,
NameBot: "text-davinci-003",
}
//Check message in updates
for update := range updates {
if update.Message == nil {
continue
}
checkOne := strings.HasPrefix(update.Message.Text, "/text")
checkTwo := strings.HasPrefix(update.Message.Text, "/code")
checkThree := strings.HasPrefix(update.Message.Text, "/curie")
if checkOne || checkTwo || checkThree {
if checkOne {
GptMode.MaxTokensGpt = 3000
GptMode.NameBot = "text-davinci-003"
} else if checkTwo {
GptMode.MaxTokensGpt = 4096
GptMode.NameBot = "code-davinci-002"
} else {
GptMode.MaxTokensGpt = 2048
GptMode.NameBot = "text-curie-001"
}
update.Message.Text = "Вы выбрали режим " + GptMode.NameBot
} else {
update.Message.Text = sendChatGPT(chatGPT, update.Message.Text, GptMode)
}
// Send message to Telegram
msg := tgbotapi.NewMessage(update.Message.Chat.ID, update.Message.Text)
msg.ReplyToMessageID = update.Message.MessageID
_, err = bot.Send(msg)
if err != nil {
log.Println("Error:", err)
}
}
}
При смене режима бота возвращает ошибку:
return "ChatGPT API error"
Ответы (3 шт):
error, status code: 400, message: This model's maximum context length is 2049 tokens, however you requested 2055 tokens (7 in your prompt; 2048 for the completion). Please reduce your prompt; or completion length
Вы использовали слишком длинный текст при запросе на генерацию текста. Чтобы решить эту проблему, вам нужно уменьшить размер вашего запроса, удалив лишние слова или фразы из исходного запроса. Также можно использовать более короткие запросы или разбить более длинные запросы на несколько более коротких.
Поменял код в return у функции sendChatGPT:
resp, err := c.CreateCompletion(ctx, req)
if err != nil {
return err.Error()
}
Функция CreateCompletion возвратила ошибку такого вида:
error, status code: 400, message: This model's maximum context length is 2049 tokens, however you requested 2055 tokens (7 in your prompt; 2048 for the completion). Please reduce your prompt; or completion length.
Решил проблему уменьшения ограничения максимального количества токенов:
if checkOne {
GptMode.MaxTokensGpt = 3000
GptMode.NameBot = "text-davinci-003"
} else if checkTwo {
GptMode.MaxTokensGpt = 3500
GptMode.NameBot = "code-davinci-002"
} else {
GptMode.MaxTokensGpt = 1900
GptMode.NameBot = "text-curie-001"
}
В MaxTokensGpt необходимо передать значение которое будет <= чем длина контекста у данной модели, за минусом длины самого сообщения (вопроса) (для этого надо использовать библиотеку tiktoken)
Например, если размер контекста 4096, а ваш запрос (используя tiktoken) имеет длину 1000 токенов, то MaxTokensGpt должен быть равен 4096 - 1000 = 3096 (или меньше, если хотите ограничить длину ответа)