From a4af88fe373e582b414f384bd9d695271cb743cf Mon Sep 17 00:00:00 2001 From: Leonid Medovyy Date: Thu, 27 Jul 2023 11:07:34 -0700 Subject: [PATCH] added the automoderation for stories --- app/jobs/assemble_job.rb | 5 +- app/jobs/stories/kill_spammy_stories_job.rb | 2 +- app/jobs/stories/moderate_stories_job.rb | 9 +++ app/jobs/stories/moderate_story_job.rb | 83 +++++++++++++++++++++ 4 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 app/jobs/stories/moderate_stories_job.rb create mode 100644 app/jobs/stories/moderate_story_job.rb diff --git a/app/jobs/assemble_job.rb b/app/jobs/assemble_job.rb index 03a31bb..1d49568 100644 --- a/app/jobs/assemble_job.rb +++ b/app/jobs/assemble_job.rb @@ -29,7 +29,10 @@ def perform(*_args) # [x] Kill Spammy Stories Stories::KillSpammyStoriesJob.perform_now - # [x] Images from processed stories + # [x] Automatically Moderate Stories + Stories::ModerateStoriesJob.perform_now + + # [x] Images from processed & approved stories Images::CreateImageIdeasFromStoriesJob.perform_now # [x] Cleanup broken imaginations diff --git a/app/jobs/stories/kill_spammy_stories_job.rb b/app/jobs/stories/kill_spammy_stories_job.rb index 2be26bb..6589b8b 100644 --- a/app/jobs/stories/kill_spammy_stories_job.rb +++ b/app/jobs/stories/kill_spammy_stories_job.rb @@ -2,6 +2,6 @@ class Stories::KillSpammyStoriesJob < ApplicationJob queue_as :default def perform(*args) - Story.spammy_stems.update_all(invalid_json: true) + Story.spammy_stems.update_all(invalid_json: true, approved: false) end end diff --git a/app/jobs/stories/moderate_stories_job.rb b/app/jobs/stories/moderate_stories_job.rb new file mode 100644 index 0000000..536f424 --- /dev/null +++ b/app/jobs/stories/moderate_stories_job.rb @@ -0,0 +1,9 @@ +class Stories::ModerateStoriesJob < ApplicationJob + queue_as :default + + def perform(*args) + Story.needs_approval.each do |story| + Stories::ModerateStoryJob.perform_now(story:) + end + end +end diff --git a/app/jobs/stories/moderate_story_job.rb b/app/jobs/stories/moderate_story_job.rb new file mode 100644 index 0000000..ec6b902 --- /dev/null +++ b/app/jobs/stories/moderate_story_job.rb @@ -0,0 +1,83 @@ +class Stories::ModerateStoryJob < ApplicationJob + queue_as :default + include SettingsHelper + + def perform(story:) + return unless story.approved.blank? + + @client = OpenAI::Client.new + + parsed_story = JSON.parse(story.stem) + parsed_title = parsed_story['title'] + parsed_summary = parsed_story['summary'] + + puts parsed_title + puts parsed_summary + puts '---' + + system_role = <<~SYSTEM_ROLE + You are an experienced content moderator. You are reviewing potential stories to be published. + SYSTEM_ROLE + + brief = <<~BRIEF + You have received the following `news brief` with the title `#{parsed_title}` and summary + """ + #{parsed_summary} + """ + BRIEF + + question = <<~QUESTION + - It is your job to return the word 'deny' if the `news brief` is promotional nature. + - It is your job to return the word 'deny' if the `news brief` contains political content. + - It is your job to return the word 'deny' if the `news brief` contains violent content. + - It is your job to return the word 'deny' if the `news brief` sexually explicit content. + - If the `news brief` is not promotional, political or violet return `approve` + QUESTION + + messages = [ + { role: "system", content: system_role }, + { role: "user", content: brief }, + { role: "user", content: question } + ] + + invalid_json = true + counter = 0 + response = nil + + while invalid_json && counter < 4 + response = chat(messages:) + + counter += 1 + + break if response["error"].present? + + invalid_json = false if %[approve deny].include? response["choices"][0]["message"]["content"].downcase + Rails.logger.debug "invalid_json: #{invalid_json} | counter: #{counter}" + end + + if response["error"].present? + story.update(approved: false, invalid_json:) + else + decision = response["choices"][0]["message"]["content"].downcase + puts decision + + if decision == 'approve' + story.update(approved: true) + else + story.update(approved: false) + end + + puts '---' + end + end + + def chat(messages:) + @client.chat( + parameters: { + model: ENV['OPENAI_GPT_MODEL'], # Required. + messages:, + temperature: 0.7 + } + ) + end +end