LLM Client API
Multi-provider LLM client interface for text generation.
Overview
from src.llm_client import create_llm_client, LLMClient, OpenAIClient
Factory Function
create_llm_client
def create_llm_client(config: Dict[str, Any]) -> LLMClient:
"""
Create an LLM client from configuration.
Args:
config: Configuration dictionary with:
- provider: str ("openai", "anthropic", "openrouter")
- api_key: str
- model: str
- inference: Dict with temperature, max_completion_tokens
- base_url: Optional[str] for custom endpoints
Returns:
LLMClient instance (OpenAIClient or compatible)
Example:
>>> client = create_llm_client({
... 'provider': 'openai',
... 'api_key': 'sk-...',
... 'model': 'gpt-4o-mini',
... 'inference': {'temperature': 0.7}
... })
"""
LLMClient (Abstract Base)
from abc import ABC, abstractmethod
class LLMClient(ABC):
"""Abstract base class for LLM clients."""
@abstractmethod
def generate(self, prompt: str, **kwargs) -> str:
"""
Generate text from prompt.
Args:
prompt: Input prompt text
**kwargs: Additional generation parameters
Returns:
Generated text
"""
@abstractmethod
def generate_with_tokens(
self,
prompt: str,
**kwargs
) -> Tuple[str, int, int]:
"""
Generate text and return token counts.
Args:
prompt: Input prompt text
**kwargs: Additional generation parameters
Returns:
Tuple of (generated_text, input_tokens, output_tokens)
"""
OpenAIClient
OpenAI-compatible client implementation.
class OpenAIClient(LLMClient):
"""
OpenAI API client.
Supports:
- OpenAI API
- OpenRouter API
- Any OpenAI-compatible endpoint
"""
Constructor
def __init__(
self,
api_key: str,
model: str = "gpt-4o-mini",
temperature: float = 0.7,
max_completion_tokens: int = 2048,
base_url: Optional[str] = None,
default_headers: Optional[Dict[str, str]] = None
):
"""
Initialize OpenAI client.
Args:
api_key: API key
model: Model name
temperature: Sampling temperature (0-2)
max_completion_tokens: Maximum tokens to generate
base_url: Custom API endpoint (for OpenRouter, etc.)
default_headers: Additional headers (for OpenRouter)
"""
Methods
generate
def generate(self, prompt: str, **kwargs) -> str:
"""
Generate text from prompt.
Args:
prompt: Input text
**kwargs: Override temperature, max_tokens, etc.
Returns:
Generated text
Example:
>>> response = client.generate("Hello, world!")
>>> print(response)
"""
generate_with_tokens
def generate_with_tokens(
self,
prompt: str,
**kwargs
) -> Tuple[str, int, int]:
"""
Generate text and return token counts.
Returns:
Tuple of (text, input_tokens, output_tokens)
Example:
>>> text, inp, out = client.generate_with_tokens("Hello!")
>>> print(f"Tokens: {inp} in, {out} out")
"""
Attributes
Attribute |
Type |
Description |
|---|---|---|
|
|
Model name |
|
|
Sampling temperature |
|
|
Max output tokens |
LLMFormulator
Generates system prompts from persona features.
class LLMFormulator:
"""Generates system prompts using LLM."""
Constructor
def __init__(
self,
llm_client: LLMClient,
template_path: str,
max_retries: int = 3,
retry_delay: int = 2,
validate_output: bool = True,
min_prompt_length: int = 50
):
"""
Initialize formulator.
Args:
llm_client: LLM client for generation
template_path: Path to prompt template
max_retries: Retry attempts on failure
retry_delay: Seconds between retries
validate_output: Validate generated prompts
min_prompt_length: Minimum acceptable length
"""
Methods
formulate
def formulate(self, features: Dict[str, str]) -> str:
"""
Generate system prompt from persona features.
Args:
features: Persona feature dictionary
Returns:
Generated system prompt
Raises:
ValueError: If generation fails after retries
Example:
>>> prompt = formulator.formulate({
... 'role': 'engineer',
... 'style': 'casual'
... })
"""
Usage Examples
Basic Usage
from src.llm_client import create_llm_client
# Create client
client = create_llm_client({
'provider': 'openai',
'api_key': 'sk-...',
'model': 'gpt-4o-mini',
'inference': {
'temperature': 0.7,
'max_completion_tokens': 1024
}
})
# Generate text
response = client.generate("Write a haiku about coding")
print(response)
# With token tracking
text, input_tokens, output_tokens = client.generate_with_tokens(
"Explain Python decorators"
)
print(f"Response: {text}")
print(f"Tokens: {input_tokens} in, {output_tokens} out")
OpenRouter Usage
client = create_llm_client({
'provider': 'openrouter',
'api_key': 'sk-or-...',
'model': 'anthropic/claude-3.5-haiku',
'base_url': 'https://openrouter.ai/api/v1',
'inference': {
'temperature': 0.8
}
})
System Prompt Generation
from src.llm_client import create_llm_client, LLMFormulator
client = create_llm_client(config['api'])
formulator = LLMFormulator(
client,
template_path="prompts/persona_to_system_prompt.txt",
max_retries=3,
validate_output=True
)
prompt = formulator.formulate({
'age_band': '25_34',
'role': 'engineer',
'communication_style': 'casual'
})
print(prompt)
Error Handling
from openai import APIError, RateLimitError
try:
response = client.generate(prompt)
except RateLimitError:
print("Rate limited, waiting...")
time.sleep(60)
except APIError as e:
print(f"API error: {e}")
See Also
Configuration - API configuration
Interaction Generation - Using model pools