FEATURE: AI helper support in non English languages (#489)
* FEATURE: AI helper support in non English languages This attempts some prompt engineering to coerce AI helper to answer in the appropriate language. Note mileage will vary, in testing GPT-4 produces the best results GPT-3.5 can return OKish results. * Extend non english support for GPT-4V image caption * Update db/fixtures/ai_helper/603_completion_prompts.rb --------- Co-authored-by: Rafael Silva <xfalcox@gmail.com>
This commit is contained in:
parent
aabff87501
commit
d036f3fb8e
|
@ -9,19 +9,16 @@ CompletionPrompt.seed do |cp|
|
||||||
cp.temperature = 0.2
|
cp.temperature = 0.2
|
||||||
cp.messages = {
|
cp.messages = {
|
||||||
insts: <<~TEXT,
|
insts: <<~TEXT,
|
||||||
I want you to act as an English translator, spelling corrector and improver. I will write to you
|
I want you to act as an %LANGUAGE% translator, spelling corrector and improver. I will write to you
|
||||||
in any language and you will detect the language, translate it and answer in the corrected and
|
in any language and you will detect the language, translate it and answer in the corrected and
|
||||||
improved version of my text, in English. I want you to replace my simplified A0-level words and
|
improved version of my text, in %LANGUAGE%. I want you to replace my simplified A0-level words and
|
||||||
sentences with more beautiful and elegant, upper level English words and sentences.
|
sentences with more beautiful and elegant, upper level %LANGUAGE% words and sentences.
|
||||||
Keep the meaning same, but make them more literary. I want you to only reply the correction,
|
Keep the meaning same, but make them more literary. I want you to only reply the correction,
|
||||||
the improvements and nothing else, do not write explanations.
|
the improvements and nothing else, do not write explanations.
|
||||||
You will find the text between <input></input> XML tags.
|
You will find the text between <input></input> XML tags.
|
||||||
Include your translation between <output></output> XML tags.
|
Include your translation between <output></output> XML tags.
|
||||||
TEXT
|
TEXT
|
||||||
examples: [
|
examples: [["<input>Hello</input>", "<output>...%LANGUAGE% translation...</output>"]],
|
||||||
["<input>Hello world</input>", "<output>Hello world</output>"],
|
|
||||||
["<input>Bonjour le monde</input>", "<output>Hello world</output>"],
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -40,9 +40,42 @@ module DiscourseAi
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def custom_locale_instructions(user = nil)
|
||||||
|
locale = SiteSetting.default_locale
|
||||||
|
locale = user.locale || SiteSetting.default_locale if SiteSetting.allow_user_locale && user
|
||||||
|
locale_hash = LocaleSiteSetting.language_names[locale]
|
||||||
|
|
||||||
|
if locale != "en" && locale_hash
|
||||||
|
locale_description = "#{locale_hash["name"]} (#{locale_hash["nativeName"]})"
|
||||||
|
"It is imperative that you write your answer in #{locale_description}, you are interacting with a #{locale_description} speaking user. Leave tag names in English."
|
||||||
|
else
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def localize_prompt!(prompt, user = nil)
|
||||||
|
locale_instructions = custom_locale_instructions(user)
|
||||||
|
if locale_instructions
|
||||||
|
prompt.messages[0][:content] = prompt.messages[0][:content] + locale_instructions
|
||||||
|
end
|
||||||
|
|
||||||
|
if prompt.messages[0][:content].include?("%LANGUAGE%")
|
||||||
|
locale = SiteSetting.default_locale
|
||||||
|
locale = user.locale || SiteSetting.default_locale if SiteSetting.allow_user_locale &&
|
||||||
|
user
|
||||||
|
locale_hash = LocaleSiteSetting.language_names[locale]
|
||||||
|
|
||||||
|
prompt.messages[0][:content] = prompt.messages[0][:content].gsub(
|
||||||
|
"%LANGUAGE%",
|
||||||
|
"#{locale_hash["name"]}",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def generate_prompt(completion_prompt, input, user, &block)
|
def generate_prompt(completion_prompt, input, user, &block)
|
||||||
llm = DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model)
|
llm = DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model)
|
||||||
prompt = completion_prompt.messages_with_input(input)
|
prompt = completion_prompt.messages_with_input(input)
|
||||||
|
localize_prompt!(prompt, user)
|
||||||
|
|
||||||
llm.generate(
|
llm.generate(
|
||||||
prompt,
|
prompt,
|
||||||
|
@ -111,7 +144,12 @@ module DiscourseAi
|
||||||
{
|
{
|
||||||
type: :user,
|
type: :user,
|
||||||
content: [
|
content: [
|
||||||
{ type: "text", text: "Describe this image in a single sentence" },
|
{
|
||||||
|
type: "text",
|
||||||
|
text:
|
||||||
|
"Describe this image in a single sentence" +
|
||||||
|
custom_locale_instructions(user),
|
||||||
|
},
|
||||||
{ type: "image_url", image_url: image_url },
|
{ type: "image_url", image_url: image_url },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
|
|
@ -12,6 +12,22 @@ RSpec.describe DiscourseAi::AiHelper::Assistant do
|
||||||
defends himself, but instead exclaims: 'You too, my son!' Shakespeare and Quevedo capture the pathetic cry.
|
defends himself, but instead exclaims: 'You too, my son!' Shakespeare and Quevedo capture the pathetic cry.
|
||||||
STRING
|
STRING
|
||||||
|
|
||||||
|
describe("#custom_locale_instructions") do
|
||||||
|
it "Properly generates the per locale system instruction" do
|
||||||
|
SiteSetting.default_locale = "ko"
|
||||||
|
expect(subject.custom_locale_instructions).to eq(
|
||||||
|
"It is imperative that you write your answer in Korean (한국어), you are interacting with a Korean (한국어) speaking user. Leave tag names in English.",
|
||||||
|
)
|
||||||
|
|
||||||
|
SiteSetting.allow_user_locale = true
|
||||||
|
user.update!(locale: "he")
|
||||||
|
|
||||||
|
expect(subject.custom_locale_instructions(user)).to eq(
|
||||||
|
"It is imperative that you write your answer in Hebrew (עברית), you are interacting with a Hebrew (עברית) speaking user. Leave tag names in English.",
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe("#available_prompts") do
|
describe("#available_prompts") do
|
||||||
before do
|
before do
|
||||||
SiteSetting.ai_helper_illustrate_post_model = "disabled"
|
SiteSetting.ai_helper_illustrate_post_model = "disabled"
|
||||||
|
@ -55,6 +71,19 @@ RSpec.describe DiscourseAi::AiHelper::Assistant do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe("#localize_prompt!") do
|
||||||
|
it "is able to perform %LANGUAGE% replacements" do
|
||||||
|
prompt =
|
||||||
|
CompletionPrompt.new(messages: { insts: "This is a %LANGUAGE% test" }).messages_with_input(
|
||||||
|
"test",
|
||||||
|
)
|
||||||
|
|
||||||
|
subject.localize_prompt!(prompt, user)
|
||||||
|
|
||||||
|
expect(prompt.messages[0][:content].strip).to eq("This is a English (US) test")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#generate_and_send_prompt" do
|
describe "#generate_and_send_prompt" do
|
||||||
context "when using a prompt that returns text" do
|
context "when using a prompt that returns text" do
|
||||||
let(:mode) { CompletionPrompt::TRANSLATE }
|
let(:mode) { CompletionPrompt::TRANSLATE }
|
||||||
|
|
Loading…
Reference in New Issue