mirror of
https://github.com/discourse/discourse-ai.git
synced 2025-03-09 11:48:47 +00:00
DEV: A rake task to generate topics (#1171)
Adds a new rake task to generate topics using the AI helper model. Generate topics using ``` bundle exec rake "ai:generate_topics[Don Quijote de la Mancha\, Cien años de soledad\, Os Lusíadas\,三国演义]" ``` For now it randomly chooses a non-read-restricted category and a random bunch of users.
This commit is contained in:
parent
01893bb6ed
commit
5b63e597d0
101
lib/tasks/create_topics.rake
Normal file
101
lib/tasks/create_topics.rake
Normal file
@ -0,0 +1,101 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
namespace :ai do
|
||||
desc "Generate topics with AI post content using random users and categories. Use it this way rake ai:generate_topics['title1\,title2\,title3']"
|
||||
task :generate_topics, [:titles] => [:environment] do |task, args|
|
||||
titles = args[:titles].include?(",") ? args[:titles].split(",").map(&:strip) : [args[:titles]]
|
||||
puts "Will create #{titles.size} #{"topics".pluralize(titles.size)}: #{titles.join(", ")}"
|
||||
|
||||
titles.each do |title|
|
||||
next if Topic.find_by_title(TextCleaner.clean_title(TextSentinel.title_sentinel(title).text))
|
||||
category =
|
||||
Category
|
||||
.where.not(id: SiteSetting.uncategorized_category_id)
|
||||
.where(read_restricted: false)
|
||||
.order("RANDOM()")
|
||||
.first
|
||||
users = User.real.activated.not_suspended.where(staged: false).order("RANDOM()").limit(12)
|
||||
RateLimiter.disable
|
||||
|
||||
creator = TopicGenerator.new(title)
|
||||
first_post = creator.get_first_post
|
||||
replies_count = rand(4..10)
|
||||
replies = creator.get_replies(replies_count)
|
||||
|
||||
post = create_topic(category, first_post, title, users)
|
||||
replies.each_with_index { |reply, i| create_post(users[i + 1], post.topic_id, reply) }
|
||||
puts "'#{title}' has #{replies.size} replies"
|
||||
end
|
||||
end
|
||||
|
||||
def create_topic(category, first_post, title, users)
|
||||
puts "#{users.first.username} will create topic '#{title}' in category '#{category.name}'"
|
||||
post =
|
||||
PostCreator.create!(
|
||||
users.first,
|
||||
title: title,
|
||||
raw: first_post,
|
||||
category: category.id,
|
||||
skip_guardian: true,
|
||||
)
|
||||
puts "Created topic '#{title}' (#{post.topic_id}) in category '#{category.name}'"
|
||||
post
|
||||
end
|
||||
|
||||
def create_post(user, topic_id, raw)
|
||||
puts "#{user.username} will reply to topic #{topic_id}"
|
||||
PostCreator.create!(user, topic_id:, raw:, skip_guardian: true)
|
||||
end
|
||||
|
||||
class TopicGenerator
|
||||
def initialize(title)
|
||||
@title = title
|
||||
end
|
||||
|
||||
def get_first_post
|
||||
TopicGenerator.generate(<<~PROMPT)
|
||||
Write and opening topic about title: #{@title}.
|
||||
- content must be in the same language as title
|
||||
- content in markdown
|
||||
- content should exclude the title
|
||||
- maximum of 200 words
|
||||
PROMPT
|
||||
end
|
||||
|
||||
def get_replies(count)
|
||||
JSON.parse(
|
||||
TopicGenerator.generate(<<~PROMPT).gsub(/```json\n?|\```/, "").gsub(/,\n\n/, ",\n").strip,
|
||||
Write #{count} replies to a topic with title #{@title}.
|
||||
- respond in an array of strings within double quotes ["", "", ""]
|
||||
- each with a maximum of 100 words
|
||||
- keep to same language of title
|
||||
- each reply may contain markdown to bold, italicize, link, or bullet point
|
||||
- do not return anything else other than the array
|
||||
- the last item in the array should not have a trailing comma
|
||||
- Example return value ["I agree with you. So and so...", "It is fun ... etc"]
|
||||
PROMPT
|
||||
)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def self.generate(prompt)
|
||||
return "" if prompt.blank?
|
||||
|
||||
prompt =
|
||||
DiscourseAi::Completions::Prompt.new(
|
||||
"You are a forum user writing concise, informative posts. Keep responses focused and natural.",
|
||||
messages: [{ type: :user, content: prompt, id: "user" }],
|
||||
)
|
||||
|
||||
DiscourseAi::Completions::Llm.proxy(SiteSetting.ai_helper_model).generate(
|
||||
prompt,
|
||||
user: Discourse.system_user,
|
||||
feature_name: "topic-generator",
|
||||
)
|
||||
rescue => e
|
||||
Rails.logger.error("AI TopicGenerator Error: #{e.message}")
|
||||
""
|
||||
end
|
||||
end
|
||||
end
|
Loading…
x
Reference in New Issue
Block a user