graphrag_core/critic/
mod.rs1use crate::core::{GraphRAGError, Result};
7use crate::ollama::OllamaClient;
8use serde::{Deserialize, Serialize};
9use std::sync::Arc;
10
11#[derive(Debug, Clone, Serialize, Deserialize)]
13pub struct EvaluationResult {
14 pub score: f32,
16 pub grounded: bool,
18 pub feedback: String,
20}
21
22pub struct Critic {
24 client: Arc<OllamaClient>,
25}
26
27impl Critic {
28 pub fn new(client: Arc<OllamaClient>) -> Self {
30 Self { client }
31 }
32
33 pub async fn evaluate(
37 &self,
38 query: &str,
39 context: &[String],
40 answer: &str,
41 ) -> Result<EvaluationResult> {
42 let context_text = context.join("\n\n");
43
44 let prompt = format!(
45 "You are a strict critic for a RAG system. Your job is to evaluate the quality of a generated answer based on the provided query and retrieved context.\n\
46 \n\
47 Query: '{}'\n\
48 \n\
49 Retrieved Context:\n\
50 {}\n\
51 \n\
52 Generated Answer:\n\
53 {}\n\
54 \n\
55 Evaluate the answer on: \n\
56 1. Grounding: Is every claim in the answer supported by the context? \n\
57 2. Relevance: Does it answer the user's query? \n\
58 3. Completeness: Is it missing critical info present in the context? \n\
59 \n\
60 Return ONLY a raw JSON object with these keys: \n\
61 - 'score': float between 0.0 and 1.0 \n\
62 - 'grounded': boolean \n\
63 - 'feedback': string explanation \n\
64 \n\
65 JSON Response:",
66 query, context_text, answer
67 );
68
69 let response_text = self.client.generate(&prompt).await?;
70
71 let cleaned_json = response_text
73 .trim()
74 .trim_start_matches("```json")
75 .trim_start_matches("```")
76 .trim_end_matches("```")
77 .trim();
78
79 let evaluation: EvaluationResult =
80 serde_json::from_str(cleaned_json).map_err(|e| GraphRAGError::Generation {
81 message: format!(
82 "Failed to parse critic response: {}. Text: {}",
83 e, cleaned_json
84 ),
85 })?;
86
87 Ok(evaluation)
88 }
89
90 pub async fn refine(
92 &self,
93 query: &str,
94 current_answer: &str,
95 feedback: &str,
96 ) -> Result<String> {
97 let prompt = format!(
98 "You are an expert editor refining an answer for a RAG system.\n\
99 \n\
100 Original Query: '{}'\n\
101 \n\
102 Current Answer:\n\
103 {}\n\
104 \n\
105 Critique/Feedback:\n\
106 {}\n\
107 \n\
108 Please rewrite the answer to address the critique while maintaining accuracy and relevance. \n\
109 Return ONLY the refined answer text.",
110 query, current_answer, feedback
111 );
112
113 self.client.generate(&prompt).await
114 }
115}