Skip to content

Commit 48d93cf

Browse files
committed
Add AnswerRelevancyAggregate & AnswerRelevancyRun
This adds a migration to the two new tables needed to store answer relevancy metrics. It also adds the corresponding models and factories. We will need to record llm multiple llm responses and metrics for each run so i've included the LlmCallsRecordable module in the AnswerRelevancyRun model.
1 parent 1a43792 commit 48d93cf

8 files changed

Lines changed: 74 additions & 1 deletion

File tree

app/models/answer.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ def self.response_for_question_routing_label(label)
5555
has_many :sources, -> { order(relevancy: :asc) }, class_name: "AnswerSource"
5656
has_one :feedback, class_name: "AnswerFeedback"
5757
has_one :topics, class_name: "AnswerTopics"
58+
has_one :answer_relevancy_aggregate, class_name: "AnswerAnalysis::AnswerRelevancyAggregate"
5859

5960
enum :status,
6061
{
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module AnswerAnalysis
2+
class AnswerRelevancyAggregate < ApplicationRecord
3+
belongs_to :answer
4+
has_many :runs, class_name: "AnswerAnalysis::AnswerRelevancyRun"
5+
end
6+
end
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module AnswerAnalysis
2+
class AnswerRelevancyRun < ApplicationRecord
3+
include LlmCallsRecordable
4+
5+
belongs_to :aggregate,
6+
class_name: "AnswerAnalysis::AnswerRelevancyAggregate",
7+
foreign_key: :answer_relevancy_aggregate_id
8+
end
9+
end
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
class AddAnswerRelevancyTables < ActiveRecord::Migration[8.0]
2+
def change
3+
create_table :answer_relevancy_aggregates, id: :uuid do |t|
4+
t.decimal :mean_score, null: false
5+
t.references :answer, type: :uuid, null: false, foreign_key: { on_delete: :cascade }, index: { unique: true }
6+
t.timestamps
7+
end
8+
9+
create_table :answer_relevancy_runs, id: :uuid do |t|
10+
t.decimal :score, null: false
11+
t.string :reason, null: false
12+
t.jsonb :llm_responses
13+
t.jsonb :metrics
14+
t.references :answer_relevancy_aggregate, type: :uuid, null: false, foreign_key: { on_delete: :cascade }
15+
t.timestamps
16+
end
17+
end
18+
end

db/schema.rb

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[8.0].define(version: 2025_12_15_161508) do
13+
ActiveRecord::Schema[8.0].define(version: 2025_12_16_092915) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "citext"
1616
enable_extension "pg_catalog.plpgsql"
@@ -33,6 +33,25 @@
3333
t.index ["created_at"], name: "index_answer_feedback_on_created_at"
3434
end
3535

36+
create_table "answer_relevancy_aggregates", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
37+
t.decimal "mean_score", null: false
38+
t.uuid "answer_id", null: false
39+
t.datetime "created_at", null: false
40+
t.datetime "updated_at", null: false
41+
t.index ["answer_id"], name: "index_answer_relevancy_aggregates_on_answer_id", unique: true
42+
end
43+
44+
create_table "answer_relevancy_runs", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
45+
t.decimal "score", null: false
46+
t.string "reason", null: false
47+
t.jsonb "llm_responses"
48+
t.jsonb "metrics"
49+
t.uuid "answer_relevancy_aggregate_id", null: false
50+
t.datetime "created_at", null: false
51+
t.datetime "updated_at", null: false
52+
t.index ["answer_relevancy_aggregate_id"], name: "index_answer_relevancy_runs_on_answer_relevancy_aggregate_id"
53+
end
54+
3655
create_table "answer_source_chunks", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
3756
t.uuid "content_id", null: false
3857
t.string "locale", null: false
@@ -173,6 +192,8 @@
173192
end
174193

175194
add_foreign_key "answer_feedback", "answers", on_delete: :cascade
195+
add_foreign_key "answer_relevancy_aggregates", "answers", on_delete: :cascade
196+
add_foreign_key "answer_relevancy_runs", "answer_relevancy_aggregates", on_delete: :cascade
176197
add_foreign_key "answer_sources", "answer_source_chunks", on_delete: :restrict
177198
add_foreign_key "answer_sources", "answers", on_delete: :cascade
178199
add_foreign_key "answer_topics", "answers", on_delete: :cascade
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
FactoryBot.define do
2+
factory :answer_relevancy_aggregate, class: "AnswerAnalysis::AnswerRelevancyAggregate" do
3+
answer
4+
mean_score { 0.5 }
5+
end
6+
end
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
FactoryBot.define do
2+
factory :answer_relevancy_run, class: "AnswerAnalysis::AnswerRelevancyRun" do
3+
association :aggregate, factory: :answer_relevancy_aggregate
4+
score { 0.5 }
5+
reason { "The answer was okay." }
6+
end
7+
end
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
RSpec.describe AnswerAnalysis::AnswerRelevancyRun do
2+
include_examples "llm calls recordable" do
3+
let(:model) { build(:answer_relevancy_run) }
4+
end
5+
end

0 commit comments

Comments
 (0)