Module: DSPy::Metrics

Extended by:
T::Sig
Defined in:
lib/dspy/evaluate.rb

Overview

Common metric functions for evaluation

Class Method Summary collapse

Class Method Details

.composite_and(*metrics) ⇒ Object

Composite metric - combines multiple metrics with AND logic



516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/dspy/evaluate.rb', line 516

def self.composite_and(*metrics)
  proc do |example, prediction|
    results = {}
    all_passed = true
    
    metrics.each_with_index do |metric, index|
      result = metric.call(example, prediction)
      
      if result.is_a?(Hash)
        results[:"metric_#{index}"] = result
        all_passed &&= result[:passed] || result['passed'] || false
      else
        passed = !!result
        results[:"metric_#{index}"] = { passed: passed }
        all_passed &&= passed
      end
    end
    
    results[:passed] = all_passed
    results
  end
end

.contains(field: :answer, case_sensitive: false) ⇒ Object



467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/dspy/evaluate.rb', line 467

def self.contains(field: :answer, case_sensitive: false)
  proc do |example, prediction|
    expected = extract_field(example, field)
    actual = extract_field(prediction, field)
    
    return false if expected.nil? || actual.nil?
    
    if case_sensitive
      actual.to_s.include?(expected.to_s)
    else
      actual.to_s.downcase.include?(expected.to_s.downcase)
    end
  end
end

.exact_match(field: :answer, case_sensitive: true) ⇒ Object



445
446
447
448
449
450
451
452
453
454
455
456
457
458
# File 'lib/dspy/evaluate.rb', line 445

def self.exact_match(field: :answer, case_sensitive: true)
  proc do |example, prediction|
    expected = extract_field(example, field)
    actual = extract_field(prediction, field)
    
    return false if expected.nil? || actual.nil?
    
    if case_sensitive
      expected.to_s == actual.to_s
    else
      expected.to_s.downcase == actual.to_s.downcase
    end
  end
end

.numeric_difference(field: :answer, tolerance: 0.01) ⇒ Object



489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
# File 'lib/dspy/evaluate.rb', line 489

def self.numeric_difference(field: :answer, tolerance: 0.01)
  proc do |example, prediction|
    expected = extract_field(example, field)
    actual = extract_field(prediction, field)
    
    return { passed: false, error: "Missing values" } if expected.nil? || actual.nil?
    
    begin
      expected_num = Float(expected)
      actual_num = Float(actual)
      difference = (expected_num - actual_num).abs
      passed = difference <= tolerance
      
      {
        passed: passed,
        difference: difference,
        expected: expected_num,
        actual: actual_num,
        tolerance: tolerance
      }
    rescue ArgumentError
      { passed: false, error: "Non-numeric values" }
    end
  end
end