context.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. package chatgpt
  2. import (
  3. "fmt"
  4. "strings"
  5. gogpt "github.com/sashabaranov/go-openai"
  6. )
  7. var (
  8. DefaultAiRole = "AI"
  9. DefaultHumanRole = "Human"
  10. DefaultCharacter = []string{"helpful", "creative", "clever", "friendly", "lovely", "talkative"}
  11. DefaultBackground = "The following is a conversation with AI assistant. The assistant is %s"
  12. DefaultPreset = "\n%s: Cześć!\n%s: Jestem asystentem AI, co mogę dla Ciebie zrobić?"
  13. )
  14. type ChatContext struct {
  15. background string // 对话背景
  16. preset string // 预设对话
  17. maxSeqTimes int // 最大对话次数
  18. aiRole *role // AI角色
  19. humanRole *role // 人类角色
  20. old []conversation // 旧对话
  21. restartSeq string // 重新开始对话的标识
  22. startSeq string // 开始对话的标识
  23. seqTimes int // 对话次数
  24. }
  25. type conversation struct {
  26. role *role
  27. prompt string
  28. }
  29. type role struct {
  30. name string
  31. }
  32. func NewContext() *ChatContext {
  33. return &ChatContext{
  34. aiRole: &role{name: DefaultAiRole},
  35. humanRole: &role{name: DefaultHumanRole},
  36. background: fmt.Sprintf(DefaultBackground, strings.Join(DefaultCharacter, ", ")+"."),
  37. maxSeqTimes: 10,
  38. preset: fmt.Sprintf(DefaultPreset, DefaultHumanRole, DefaultAiRole),
  39. old: []conversation{},
  40. seqTimes: 0,
  41. restartSeq: "\n" + DefaultHumanRole + ": ",
  42. startSeq: "\n" + DefaultAiRole + ": ",
  43. }
  44. }
  45. func (c *ChatContext) SetHumanRole(role string) {
  46. c.humanRole.name = role
  47. c.restartSeq = "\n" + c.humanRole.name + ": "
  48. }
  49. func (c *ChatContext) SetAiRole(role string) {
  50. c.aiRole.name = role
  51. c.startSeq = "\n" + c.aiRole.name + ": "
  52. }
  53. func (c *ChatContext) SetMaxSeqTimes(times int) {
  54. c.maxSeqTimes = times
  55. }
  56. func (c *ChatContext) GetMaxSeqTimes() int {
  57. return c.maxSeqTimes
  58. }
  59. func (c *ChatContext) SetBackground(background string) {
  60. c.background = background
  61. }
  62. func (c *ChatContext) SetPreset(preset string) {
  63. c.preset = preset
  64. }
  65. func (c *ChatGPT) ChatWithContext(question string) (answer string, err error) {
  66. question = question + "."
  67. if len(question) > c.maxQuestionLen {
  68. return "", OverMaxQuestionLength
  69. }
  70. if c.ChatContext.seqTimes >= c.ChatContext.maxSeqTimes {
  71. return "", OverMaxSequenceTimes
  72. }
  73. var promptTable []string
  74. promptTable = append(promptTable, c.ChatContext.background)
  75. promptTable = append(promptTable, c.ChatContext.preset)
  76. for _, v := range c.ChatContext.old {
  77. if v.role == c.ChatContext.humanRole {
  78. promptTable = append(promptTable, "\n"+v.role.name+": "+v.prompt)
  79. } else {
  80. promptTable = append(promptTable, v.role.name+": "+v.prompt)
  81. }
  82. }
  83. promptTable = append(promptTable, "\n"+c.ChatContext.restartSeq+question)
  84. prompt := strings.Join(promptTable, "\n")
  85. prompt += c.ChatContext.startSeq
  86. if len(prompt) > c.maxText-c.maxAnswerLen {
  87. return "", OverMaxTextLength
  88. }
  89. req := gogpt.CompletionRequest{
  90. Model: gogpt.GPT3Dot5TurboInstruct,
  91. MaxTokens: c.maxAnswerLen,
  92. Prompt: prompt,
  93. Temperature: 0.9,
  94. TopP: 1,
  95. N: 1,
  96. FrequencyPenalty: 0,
  97. PresencePenalty: 0.5,
  98. User: c.userId,
  99. Stop: []string{c.ChatContext.aiRole.name + ":", c.ChatContext.humanRole.name + ":"},
  100. }
  101. resp, err := c.client.CreateCompletion(c.ctx, req)
  102. if err != nil {
  103. return "", err
  104. }
  105. resp.Choices[0].Text = formatAnswer(resp.Choices[0].Text)
  106. c.ChatContext.old = append(c.ChatContext.old, conversation{
  107. role: c.ChatContext.humanRole,
  108. prompt: question,
  109. })
  110. c.ChatContext.old = append(c.ChatContext.old, conversation{
  111. role: c.ChatContext.aiRole,
  112. prompt: resp.Choices[0].Text,
  113. })
  114. c.ChatContext.seqTimes++
  115. return resp.Choices[0].Text, nil
  116. }