mod parallel;
use crate::{chat::ChatMessage, error::LLMError, LLMProvider};
pub use parallel::{ParallelEvalResult, ParallelEvaluator};
pub type ScoringFn = dyn Fn(&str) -> f32 + Send + Sync + 'static;
pub struct LLMEvaluator {
llms: Vec<Box<dyn LLMProvider>>,
scorings_fns: Vec<Box<ScoringFn>>,
}
impl LLMEvaluator {
pub fn new(llms: Vec<Box<dyn LLMProvider>>) -> Self {
Self {
llms,
scorings_fns: Vec::new(),
}
}
pub fn scoring<F>(mut self, f: F) -> Self
where
F: Fn(&str) -> f32 + Send + Sync + 'static,
{
self.scorings_fns.push(Box::new(f));
self
}
pub async fn evaluate_chat(
&self,
messages: &[ChatMessage],
) -> Result<Vec<EvalResult>, LLMError> {
let mut results = Vec::new();
for llm in &self.llms {
let response = llm.chat(messages).await?;
let score = self.compute_score(&response.text().unwrap_or_default());
results.push(EvalResult {
text: response.text().unwrap_or_default(),
score,
});
}
Ok(results)
}
fn compute_score(&self, response: &str) -> f32 {
let mut total = 0.0;
for sc in &self.scorings_fns {
total += sc(response);
}
total
}
}
pub struct EvalResult {
pub text: String,
pub score: f32,
}