fixes (#53)
* Minor... use username suggester in case username already exists * FIX: ensure we truncate long prompts Previously we 1. Used raw length instead of token counts for counting length 2. We totally dropped a prompt if it was too long New implementation will truncate "raw" if it gets too long maintaining meaning.
This commit is contained in:
parent
71b105a1bb
commit
e76fc77189
|
@ -4,7 +4,8 @@ class CompletionPrompt < ActiveRecord::Base
|
||||||
# TODO(roman): Remove sept 2023.
|
# TODO(roman): Remove sept 2023.
|
||||||
self.ignored_columns = ["value"]
|
self.ignored_columns = ["value"]
|
||||||
|
|
||||||
MAX_PROMPT_LENGTH = 3000
|
# GPT 3.5 allows 4000 tokens
|
||||||
|
MAX_PROMPT_TOKENS = 3500
|
||||||
|
|
||||||
enum :prompt_type, { text: 0, list: 1, diff: 2 }
|
enum :prompt_type, { text: 0, list: 1, diff: 2 }
|
||||||
|
|
||||||
|
@ -22,11 +23,19 @@ class CompletionPrompt < ActiveRecord::Base
|
||||||
.order("post_number desc")
|
.order("post_number desc")
|
||||||
.pluck(:raw, :username)
|
.pluck(:raw, :username)
|
||||||
|
|
||||||
total_prompt_length = 0
|
total_prompt_tokens = 0
|
||||||
messages =
|
messages =
|
||||||
conversation.reduce([]) do |memo, (raw, username)|
|
conversation.reduce([]) do |memo, (raw, username)|
|
||||||
total_prompt_length += raw.length
|
break(memo) if total_prompt_tokens >= MAX_PROMPT_TOKENS
|
||||||
break(memo) if total_prompt_length > MAX_PROMPT_LENGTH
|
|
||||||
|
tokens = DiscourseAi::Tokenizer.tokenize(raw)
|
||||||
|
|
||||||
|
if tokens.length + total_prompt_tokens > MAX_PROMPT_TOKENS
|
||||||
|
tokens = tokens[0...(MAX_PROMPT_TOKENS - total_prompt_tokens)]
|
||||||
|
raw = tokens.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
|
total_prompt_tokens += tokens.length
|
||||||
role = username == Discourse.gpt_bot.username ? "system" : "user"
|
role = username == Discourse.gpt_bot.username ? "system" : "user"
|
||||||
|
|
||||||
memo.unshift({ role: role, content: raw })
|
memo.unshift({ role: role, content: raw })
|
||||||
|
|
|
@ -10,8 +10,7 @@ end
|
||||||
User.seed do |u|
|
User.seed do |u|
|
||||||
u.id = -110
|
u.id = -110
|
||||||
u.name = "GPT Bot"
|
u.name = "GPT Bot"
|
||||||
u.username = "gpt_bot"
|
u.username = UserNameSuggester.suggest("gpt_bot")
|
||||||
u.username_lower = "gpt_bot"
|
|
||||||
u.password = SecureRandom.hex
|
u.password = SecureRandom.hex
|
||||||
u.active = true
|
u.active = true
|
||||||
u.admin = true
|
u.admin = true
|
||||||
|
|
|
@ -7,8 +7,11 @@ module DiscourseAi
|
||||||
Tokenizers.from_file("./plugins/discourse-ai/tokenizers/bert-base-uncased.json")
|
Tokenizers.from_file("./plugins/discourse-ai/tokenizers/bert-base-uncased.json")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.tokenize(text)
|
||||||
|
tokenizer.encode(text).tokens
|
||||||
|
end
|
||||||
def self.size(text)
|
def self.size(text)
|
||||||
tokenizer.encode(text).tokens.size
|
tokenize(text).size
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,6 +39,19 @@ RSpec.describe CompletionPrompt do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context "when prompt gets very long" do
|
||||||
|
fab!(:post_1) { Fabricate(:post, topic: topic, raw: "test " * 6000, post_number: 1) }
|
||||||
|
|
||||||
|
it "trims the prompt" do
|
||||||
|
prompt_messages = described_class.bot_prompt_with_topic_context(post_1)
|
||||||
|
|
||||||
|
expect(prompt_messages[0][:role]).to eq("system")
|
||||||
|
expect(prompt_messages[1][:role]).to eq("user")
|
||||||
|
expected_length = ("test " * (CompletionPrompt::MAX_PROMPT_TOKENS)).length
|
||||||
|
expect(prompt_messages[1][:content].length).to eq(expected_length)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context "when the topic has multiple posts" do
|
context "when the topic has multiple posts" do
|
||||||
fab!(:post_1) { Fabricate(:post, topic: topic, raw: post_body(1), post_number: 1) }
|
fab!(:post_1) { Fabricate(:post, topic: topic, raw: post_body(1), post_number: 1) }
|
||||||
fab!(:post_2) do
|
fab!(:post_2) do
|
||||||
|
|
Loading…
Reference in New Issue