FIX: Better AI chat thread titles (#467)

* FIX: Better AI chat thread titles

- Fix quote removal when multi-line

- Use XML tags for better LLM output parsing

- Use stop_sequences for faster and less wasteful LLM calls

- Adds truncation as the last line of defense
This commit is contained in:
Rafael dos Santos Silva 2024-02-09 14:49:28 -03:00 committed by GitHub
parent 8b1f542238
commit 0dba6623a0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 24 additions and 2 deletions

View File

@ -23,7 +23,7 @@ module DiscourseAi
and you will generate a single attention-grabbing title. Please keep the title concise and under 15 words and you will generate a single attention-grabbing title. Please keep the title concise and under 15 words
and ensure that the meaning is maintained. The title will utilize the same language type of the chat. and ensure that the meaning is maintained. The title will utilize the same language type of the chat.
I want you to only reply the suggested title and nothing else, do not write explanations. I want you to only reply the suggested title and nothing else, do not write explanations.
You will find the chat between <input></input> XML tags. You will find the chat between <input></input> XML tags. Return the suggested title between <title> tags.
TEXT TEXT
messages: [{ type: :user, content: chat, id: "User" }], messages: [{ type: :user, content: chat, id: "User" }],
) )
@ -31,11 +31,16 @@ module DiscourseAi
DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model).generate( DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model).generate(
prompt, prompt,
user: Discourse.system_user, user: Discourse.system_user,
stop_sequences: ["</input>"],
) )
end end
def cleanup(title) def cleanup(title)
title.split("\n").first.then { _1.match?(/^("|')(.*)("|')$/) ? title[1..-2] : _1 } (Nokogiri::HTML5.fragment(title).at("title")&.text || title)
.split("\n")
.first
.then { _1.match?(/^("|')(.*)("|')$/) ? _1[1..-2] : _1 }
.truncate(100, separator: " ")
end end
def thread_content(thread) def thread_content(thread)

View File

@ -45,6 +45,23 @@ RSpec.describe DiscourseAi::AiHelper::ChatThreadTitler do
expect(result).to eq(expected_title) expect(result).to eq(expected_title)
end end
it "parses the XML" do
titles = "Here is your title <title>The solitary horse</title> my friend"
expected_title = "The solitary horse"
result = titler.cleanup(titles)
expect(result).to eq(expected_title)
end
it "truncates long titles" do
titles = "O cavalo trota pelo campo" + " Pocotó" * 100
result = titler.cleanup(titles)
expect(result.size).to be <= 100
end
end end
describe "#thread_content" do describe "#thread_content" do