0
0
Fork 0
mirror of https://github.com/discourse/discourse.git synced 2026-08-07 13:19:19 +08:00
discourse/plugins/discourse-ai/evals/lib/runners/hyde.rb
Roman Rizzi 3a647c8e50
FEATURE: Use evals to compare LLMs and Personas' prompts (#36027)
Implemented an eval “comparison matrix” that lets you run the same evals
across multiple personas or multiple LLMs and have a judge model declare
a winner with per-candidate scores. The CLI adds --compare
personas|llms, keeps persona selection (auto-prepending default for
persona mode), and always ensures a judge is configured. A dedicated
ComparisonRunner reuses Workbench results to build candidate outputs and
sends them to Judge#compare, which crafts a rubric-aware comparison
prompt and parses structured winner/ratings JSON. Outputs are streamed
to the console and individual run logs still get written. README
documents how to use the new flag and what each mode does.
2025-11-18 10:39:52 -03:00

56 lines
1.6 KiB
Ruby
Vendored

# frozen_string_literal: true
require_relative "base"
module DiscourseAi
module Evals
module Runners
class Hyde < Base
def self.can_handle?(feature_name)
feature_name&.start_with?("embeddings:hyde")
end
def run(eval_case, llm)
args = normalize_args(eval_case.args)
case_defs = Array(args.delete(:cases)).presence
if case_defs
case_defs.map { |case_args| run_case(args.merge(case_args.symbolize_keys), llm) }
else
run_case(args, llm)
end
end
private
def run_case(case_args, llm)
query = case_args[:query].presence || case_args[:input].presence
raise ArgumentError, "HyDE evals require :query or :input" if query.blank?
persona = resolve_persona(persona_class: DiscourseAi::Personas::ContentCreator)
user = Discourse.system_user
context =
DiscourseAi::Personas::BotContext.new(
user: user,
skip_show_thinking: true,
feature_name: "semantic_search_hyde",
messages: [{ type: :user, content: query }],
)
bot = DiscourseAi::Personas::Bot.as(user, persona: persona, model: llm)
response = capture_plain_response(bot, context).strip
wrap_result(response, { query: query })
end
def normalize_args(raw_args)
return {} if raw_args.blank?
raise ArgumentError, "HyDE evals expect args as a Hash" if !raw_args.is_a?(Hash)
raw_args.deep_symbolize_keys
end
end
end
end
end