promptlab / optimizer.py
auroprashad's picture
Upload folder using huggingface_hub
76c05cb verified
Raw
History Blame Contribute Delete
6.86 kB
import os
from huggingface_hub import InferenceClient
from openai import OpenAI
import anthropic
def load_system_prompt(filename: str) -> str:
"""Helper to load system prompts from files."""
try:
# Resolve absolute path relative to current module
current_dir = os.path.dirname(os.path.abspath(__file__))
path = os.path.join(current_dir, "prompts", filename)
with open(path, "r", encoding="utf-8") as f:
return f.read()
except Exception as e:
# Fallback prompts if file read fails
if "optimizer" in filename:
return "You are an expert prompt engineer. Optimize the prompt structure."
else:
return "You are a prompt auditor. Critique the prompt and output JSON with overall score, weaknesses, and suggestions."
def run_llm_call(provider: str, api_key: str, model_name: str, system_prompt: str, user_prompt: str) -> str:
"""
Standardized interface to call different LLM providers.
Supports Hugging Face, OpenAI, Gemini, and Anthropic.
"""
provider = provider.lower()
clean_key = api_key.strip() if api_key else None
if provider == "hugging face":
# If model_name is not full path, use default Qwen
if not model_name or "/" not in model_name:
model_name = "Qwen/Qwen2.5-72B-Instruct"
# Use Hugging Face serverless client (checking UI token first, then local/Space credentials)
from huggingface_hub import get_token
token = clean_key if clean_key else get_token()
client = InferenceClient(model=model_name, token=token)
messages = [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
]
import time
max_retries = 3
for attempt in range(max_retries):
try:
response = client.chat_completion(
messages=messages,
max_tokens=2048,
temperature=0.7
)
return response.choices[0].message.content
except Exception as e:
if attempt == max_retries - 1:
err_str = str(e).lower()
if "token" in err_str or "auth" in err_str or "unauthorized" in err_str or "api_key" in err_str or "401" in err_str or "402" in err_str or "403" in err_str or "payment" in err_str or "forbidden" in err_str or "permission" in err_str:
raise ValueError(
"A Hugging Face Token with 'Make calls to Inference Providers' scope is required. "
"Please create a token at huggingface.co/settings/tokens, making sure to check "
"the 'Inference' -> 'Make calls to Inference Providers' scope under permissions. "
"Then, enter it in the sidebar. If you are the Space owner, save this token as a Space Secret "
"named 'HF_TOKEN' in your Settings tab to let it run out-of-the-box for all visitors!"
)
raise e
time.sleep(2)
elif provider == "openai":
token = clean_key if clean_key else os.environ.get("OPENAI_API_KEY")
if not token:
raise ValueError("OpenAI API Key is required. Please set it in the sidebar settings.")
client = OpenAI(api_key=token)
name = model_name if model_name else "gpt-4o-mini"
response = client.chat.completions.create(
model=name,
messages=[
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
temperature=0.7,
max_tokens=2048
)
return response.choices[0].message.content
elif provider == "google gemini":
token = clean_key if clean_key else os.environ.get("GEMINI_API_KEY")
if not token:
raise ValueError("Google Gemini API Key is required. Please set it in the sidebar settings.")
name = model_name if model_name else "gemini-1.5-flash"
import requests
url = f"https://generativelanguage.googleapis.com/v1beta/models/{name}:generateContent?key={token}"
headers = {"Content-Type": "application/json"}
payload = {
"contents": [
{"parts": [{"text": user_prompt}]}
],
"systemInstruction": {
"parts": [{"text": system_prompt}]
},
"generationConfig": {
"temperature": 0.7,
"maxOutputTokens": 2048
}
}
response = requests.post(url, headers=headers, json=payload)
response.raise_for_status()
result = response.json()
return result["candidates"][0]["content"]["parts"][0]["text"]
elif provider == "anthropic":
token = clean_key if clean_key else os.environ.get("ANTHROPIC_API_KEY")
if not token:
raise ValueError("Anthropic API Key is required. Please set it in the sidebar settings.")
client = anthropic.Anthropic(api_key=token)
name = model_name if model_name else "claude-3-5-sonnet-20240620"
response = client.messages.create(
model=name,
max_tokens=2048,
system=system_prompt,
messages=[
{"role": "user", "content": user_prompt}
],
temperature=0.7
)
return response.content[0].text
else:
raise ValueError(f"Unknown API provider: {provider}")
def optimize_prompt(
raw_prompt: str,
provider: str,
api_key: str,
model_name: str,
target_model: str,
prompt_type: str,
optimization_level: str,
goal: str
) -> str:
"""
Constructs the optimization instructions, formats variables, and queries the LLM.
"""
if not raw_prompt.strip():
return "Please enter a prompt to optimize."
base_system = load_system_prompt("optimizer.txt")
# Inject parameters into the run-time context
run_context = (
f"\n\n--- OPTIMIZATION INSTRUCTIONS FOR THIS RUN ---\n"
f"Target Model for output: {target_model}\n"
f"Prompt Domain/Category: {prompt_type}\n"
f"Optimization Level requested: {optimization_level}\n"
f"Primary optimization goal: {goal}\n"
f"Now, optimize the following prompt accordingly:\n"
)
system_prompt = base_system + run_context
optimized_text = run_llm_call(
provider=provider,
api_key=api_key,
model_name=model_name,
system_prompt=system_prompt,
user_prompt=raw_prompt
)
return optimized_text.strip()