Skip to content

Commit 699412a

Browse files
committed
fix: terminal error messages
1 parent afe72ca commit 699412a

3 files changed

Lines changed: 51 additions & 23 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
# Opik/Comet Configuration
2-
OPIK_API_KEY=your-comet-api-key-here
2+
OPIK_API_KEY=your-opik-api-key-here
33
OPIK_WORKSPACE_NAME=your-workspace-name
44

55
# Model Provider API Keys
66
OPENAI_API_KEY=your-openai-api-key-here
7-
GOOGLE_API_KEY=your-google-api-key-here
7+
GEMINI_API_KEY=your-gemini-api-key-here
88
OPENROUTER_API_KEY=your-openrouter-api-key-here # Optional for Qwen-VL

opik/image_classification_eval/multimodal_classification_demo.py

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ class GeminiClassifier(ImageClassifier):
132132

133133
def __init__(self, model: str = "gemini-2.0-flash-001"):
134134
super().__init__(model)
135-
self.client = track_genai(genai.Client())
135+
self.client = track_genai(genai.Client(api_key=os.getenv("GEMINI_API_KEY")))
136136

137137
@track()
138138
def classify_image(self, image_base64: str, prompt_text: str) -> Dict[str, Any]:
@@ -212,37 +212,52 @@ def create_image_dataset(num_items: int = 200) -> List[Dict[str, Any]]:
212212
return dataset_items
213213

214214

215+
def evaluate_classification(x: Dict[str, Any], classifier: ImageClassifier, system_prompt: str) -> Dict[str, Any]:
216+
"""Evaluation task that returns output in expected format"""
217+
result = classifier.process_item(x, system_prompt)
218+
219+
# Return in format expected by the metric (with 'output' key)
220+
return {
221+
"output": {"response_label": result.get("response_label", ""), "response_reason": result.get("response_reason", "")},
222+
"response": result.get("raw_response", ""),
223+
}
224+
225+
215226
def run_evaluation_with_prompt(
216227
dataset: Any, classifiers: List[ImageClassifier], prompt: opik.Prompt, experiment_tag: str, project_name: str
217228
) -> Dict[str, Any]:
218229
"""Run evaluation across all classifiers with given prompt"""
219230
results = {}
220-
metric = ImageClassificationQualityMetric()
231+
232+
# Create metrics
233+
quality_metric = ImageClassificationQualityMetric()
221234

222235
for classifier in classifiers:
223236
model_name = classifier.model.replace("/", "_").replace("-", "_")
224-
logger.info(f"Evaluating {model_name}...")
237+
print(f"\n🔍 Evaluating {model_name}...")
225238

226239
try:
227-
# Create evaluation task
228-
def eval_task(item: Dict[str, Any]) -> Dict[str, Any]:
229-
return classifier.process_item(item, prompt.format())
240+
# Create evaluation task for this classifier
241+
def task(x: Dict[str, Any]) -> Dict[str, Any]:
242+
return evaluate_classification(x, classifier, prompt.format())
230243

231244
# Run evaluation
232245
experiment = evaluate(
233246
dataset=dataset,
234-
task=eval_task,
235-
scoring_metrics=[metric],
247+
task=task,
248+
scoring_metrics=[quality_metric],
236249
experiment_name=f"{model_name}_{experiment_tag}",
237250
project_name=project_name,
238251
prompt=prompt,
239-
scoring_key_mapping={"expected_label": "expected_label"},
240252
)
241253

242254
results[model_name] = {"experiment": experiment, "status": "success"}
255+
print(f"✅ {model_name} evaluation completed")
243256

244257
except Exception as e:
245-
logger.error(f"Error evaluating {model_name}: {e}")
258+
error_msg = f"Error evaluating {model_name}: {str(e)}"
259+
logger.error(error_msg)
260+
print(f"❌ {error_msg}")
246261
results[model_name] = {"status": "error", "error": str(e)}
247262

248263
return results
@@ -266,17 +281,23 @@ def main():
266281
print("\n📊 Step 1: Creating dataset using Opik SDK")
267282
print("-" * 50)
268283

284+
dataset_name = "multimodal_images"
285+
286+
# Always create fresh dataset items for the demo
269287
dataset_items = create_image_dataset(num_items=200)
270-
dataset_name = f"multimodal_images_{get_datestamp()}"
271288

272289
try:
290+
# Try to get existing dataset
291+
dataset = client.get_dataset(name=dataset_name)
292+
print(f"✅ Using existing dataset '{dataset_name}'")
293+
# Clear existing data and insert fresh items
294+
# Note: Opik doesn't have a clear method, so we'll work with existing data
295+
except Exception:
296+
# Create new dataset if it doesn't exist
273297
dataset = client.create_dataset(name=dataset_name)
274298
dataset.insert(dataset_items)
275299
print(f"✅ Dataset '{dataset_name}' created with {len(dataset_items)} items")
276300
print(f" Columns: {', '.join(dataset_items[0].keys())}")
277-
except Exception as e:
278-
logger.error(f"Dataset creation error: {e}")
279-
return
280301

281302
# Initialize classifiers
282303
classifiers = [OpenAIClassifier("gpt-4o"), GeminiClassifier("gemini-2.0-flash-001"), OpenRouterClassifier("qwen/qwen-2-vl-7b-instruct")]
@@ -503,7 +524,7 @@ def classification_metric(dataset_item: Dict[str, Any], llm_output: str) -> Any:
503524

504525
if __name__ == "__main__":
505526
# Check for required API keys
506-
required_keys = ["OPIK_API_KEY", "OPENAI_API_KEY", "GOOGLE_API_KEY", "OPENROUTER_API_KEY"]
527+
required_keys = ["OPIK_API_KEY", "OPENAI_API_KEY", "GEMINI_API_KEY", "OPENROUTER_API_KEY"]
507528
missing_keys = [key for key in required_keys if not os.getenv(key)]
508529

509530
if missing_keys:

opik/image_classification_eval/utils.py

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -139,12 +139,12 @@ class ImageClassificationQualityMetric(BaseMetric):
139139
def __init__(self, name: str = "classification_quality"):
140140
super().__init__(name=name)
141141

142-
def score(self, output: Dict[str, Any], **kwargs) -> score_result.ScoreResult:
142+
def score(self, output: Any, **kwargs) -> score_result.ScoreResult:
143143
"""
144144
Score the image classification based on format and content quality.
145145
146146
Args:
147-
output: Model output containing label and reason
147+
output: Model output - can be dict or wrapped in another dict
148148
**kwargs: Additional context including expected values
149149
150150
Returns:
@@ -154,13 +154,20 @@ def score(self, output: Dict[str, Any], **kwargs) -> score_result.ScoreResult:
154154
# Extract expected values
155155
expected_label = kwargs.get("expected_label", "").lower()
156156

157+
# Handle nested output structure
158+
if isinstance(output, dict) and "output" in output:
159+
# Output is wrapped - extract the nested dict
160+
output_data = output["output"]
161+
else:
162+
output_data = output
163+
157164
# Extract actual values from output
158-
if isinstance(output, dict):
159-
actual_label = (output.get("response_label") or output.get("label", "")).lower()
160-
actual_reason = output.get("response_reason") or output.get("reason", "")
165+
if isinstance(output_data, dict):
166+
actual_label = (output_data.get("response_label") or output_data.get("label", "")).lower()
167+
actual_reason = output_data.get("response_reason") or output_data.get("reason", "")
161168
else:
162169
# Handle string outputs
163-
parsed = parse_json_response(str(output))
170+
parsed = parse_json_response(str(output_data))
164171
if parsed:
165172
actual_label = parsed.get("label", "").lower()
166173
actual_reason = parsed.get("reason", "")

0 commit comments

Comments
 (0)