Spaces:
Sleeping
Sleeping
Download src/recommendation_explainer.py from Rachel0619/PickLLM: direct link, hf CLI and curl.
- Browser
- Download file 7.31 kB
-
https://huggingface.co/spaces/Rachel0619/PickLLM/resolve/main/src/recommendation_explainer.py
- Command line
-
hf download hf://spaces/Rachel0619/PickLLM/src/recommendation_explainer.py
-
curl -L -o recommendation_explainer.py https://huggingface.co/spaces/Rachel0619/PickLLM/resolve/main/src/recommendation_explainer.py
7.31 kB
| import os | |
| from openai import OpenAI | |
| from typing import Dict, List, Optional | |
| class RecommendationExplainer: | |
| """Generate natural language explanations for LLM recommendations using AI.""" | |
| def __init__(self): | |
| """Initialize the explainer with OpenRouter API client.""" | |
| api_key = os.environ.get('OPENROUTER_API_KEY') | |
| if not api_key: | |
| raise ValueError("OPENROUTER_API_KEY environment variable not set") | |
| self.client = OpenAI( | |
| base_url="https://openrouter.ai/api/v1", | |
| api_key=api_key, | |
| ) | |
| self.model = "z-ai/glm-4.5-air:free" | |
| def _build_prompt( | |
| self, | |
| use_case: str, | |
| recommendations: List[Dict], | |
| visual_ai_type: Optional[str] = None, | |
| model_type: Optional[str] = None | |
| ) -> str: | |
| """Build the prompt for the LLM to generate explanation.""" | |
| # Format use case | |
| use_case_formatted = use_case.replace('_', ' ').title() | |
| # Format recommendations | |
| rec_text = [] | |
| for i, rec in enumerate(recommendations, 1): | |
| rec_text.append( | |
| f"{i}. {rec['model']} by {rec['organization']}\n" | |
| f" - Arena Score: {rec['arena_score']}\n" | |
| f" - Votes: {rec['votes']}\n" | |
| f" - License: {rec['license']}\n" | |
| f" - Knowledge Cutoff: {rec.get('knowledge_cutoff', 'N/A')}" | |
| ) | |
| recommendations_text = "\n".join(rec_text) | |
| # Build the full prompt | |
| prompt = f"""A user is looking for LLM recommendations based on the following requirements: | |
| **Use Case**: {use_case_formatted} | |
| """ | |
| if visual_ai_type: | |
| prompt += f"**Visual AI Type**: {visual_ai_type.replace('_', ' ').title()}\n" | |
| if model_type: | |
| model_pref = { | |
| 'open_only': 'Open-source models only', | |
| 'proprietary_only_enterprise': 'Proprietary/Enterprise models only', | |
| 'no_preference': 'No preference on model type' | |
| }.get(model_type, 'No preference') | |
| prompt += f"**Model Preference**: {model_pref}\n" | |
| prompt += f""" | |
| Based on their requirements, we recommended these top 3 models from the LMSYS Chatbot Arena leaderboard: | |
| {recommendations_text} | |
| Please write a 3-paragraph explanation following this structure: | |
| **Paragraph 1**: Summarize the user's needs in natural language. For example: "You are looking for an open-weight model for conversational use cases, with low cost and medium latency." Make it conversational and personalized based on their use case and model preference. | |
| **Paragraph 2**: Briefly introduce the three recommended models by name and organization. DO NOT mention their Arena scores or vote counts (this info is already shown in the result cards). | |
| **Paragraph 3**: For each of the 3 models, write 2-3 sentences describing what makes it unique and its key advantages for the user's use case. Format this as a bulleted list where each bullet starts with the model name in bold (e.g., "**Gemini-2.5-Pro**: ..."). Focus on practical benefits, capabilities, and differentiators. | |
| Keep it concise, informative, and user-friendly. Avoid repeating data already visible in the cards.""" | |
| return prompt | |
| def generate_explanation( | |
| self, | |
| use_case: str, | |
| recommendations: List[Dict], | |
| visual_ai_type: Optional[str] = None, | |
| model_type: Optional[str] = None | |
| ) -> str: | |
| """ | |
| Generate a natural language explanation for why these models were recommended. | |
| Args: | |
| use_case: User's primary use case | |
| recommendations: List of top 3 recommended models with their details | |
| visual_ai_type: Visual AI type if applicable | |
| model_type: Model type preference (open/proprietary/no preference) | |
| Returns: | |
| Natural language explanation (2-3 paragraphs) | |
| """ | |
| # Build the prompt | |
| prompt = self._build_prompt(use_case, recommendations, visual_ai_type, model_type) | |
| try: | |
| completion = self.client.chat.completions.create( | |
| extra_headers={ | |
| "HTTP-Referer": "https://pickllm.com", | |
| "X-Title": "PickLLM", | |
| }, | |
| model=self.model, | |
| messages=[ | |
| { | |
| "role": "system", | |
| "content": "You are an AI assistant helping users understand LLM recommendations. Provide clear, concise explanations in 2-3 paragraphs." | |
| }, | |
| { | |
| "role": "user", | |
| "content": prompt | |
| } | |
| ], | |
| temperature=0.7, | |
| max_tokens=1000 | |
| ) | |
| explanation = completion.choices[0].message.content | |
| return explanation | |
| except Exception as e: | |
| print(f"Error generating explanation: {e}") | |
| # Fallback to static explanation | |
| return self._get_fallback_explanation(use_case, recommendations) | |
| def _get_fallback_explanation(self, use_case: str, recommendations: List[Dict]) -> str: | |
| """Provide a static fallback explanation if API fails.""" | |
| use_case_formatted = use_case.replace('_', ' ').title() | |
| return f"""Based on your requirement for {use_case_formatted}, we've selected the top-performing models from the LMSYS Chatbot Arena leaderboard. These models have been rigorously tested through thousands of community evaluations, ensuring they meet high standards for real-world performance. | |
| The recommended models represent the best options currently available, ranked by their Arena Score which reflects head-to-head comparisons in blind tests. Each model has received substantial community validation through voting, providing confidence in their capabilities for your specific use case. | |
| These rankings are continuously updated based on the latest leaderboard data, ensuring you get recommendations based on current performance metrics and community feedback.""" | |
| if __name__ == "__main__": | |
| # Test the explainer | |
| from dotenv import load_dotenv | |
| load_dotenv() | |
| explainer = RecommendationExplainer() | |
| # Test with sample data | |
| test_recommendations = [ | |
| { | |
| 'model': 'GPT-4', | |
| 'organization': 'OpenAI', | |
| 'arena_score': 1250, | |
| 'votes': 50000, | |
| 'license': 'Proprietary', | |
| 'knowledge_cutoff': '2023/09' | |
| }, | |
| { | |
| 'model': 'Claude-3-Opus', | |
| 'organization': 'Anthropic', | |
| 'arena_score': 1240, | |
| 'votes': 45000, | |
| 'license': 'Proprietary', | |
| 'knowledge_cutoff': '2023/08' | |
| }, | |
| { | |
| 'model': 'Gemini-Pro', | |
| 'organization': 'Google', | |
| 'arena_score': 1230, | |
| 'votes': 40000, | |
| 'license': 'Proprietary', | |
| 'knowledge_cutoff': '2023/11' | |
| } | |
| ] | |
| explanation = explainer.generate_explanation( | |
| use_case='conversational_knowledge', | |
| recommendations=test_recommendations, | |
| model_type='no_preference' | |
| ) | |
| print("Generated Explanation:") | |
| print("=" * 80) | |
| print(explanation) | |