248 lines
6.3 KiB
Markdown
248 lines
6.3 KiB
Markdown
# LLMUtils
|
|
|
|
A Python utility library for managing LLM prompts with Jinja2 template support and JSON schemas.
|
|
|
|
## Installation
|
|
|
|
### Install using uv
|
|
|
|
```bash
|
|
uv add git+https://git.project-insanity.de/gmarth/LLMUtils.git
|
|
```
|
|
|
|
### Install using pip
|
|
|
|
```bash
|
|
pip install git+https://git.project-insanity.de/gmarth/LLMUtils.git
|
|
```
|
|
|
|
## Features
|
|
|
|
- **Jinja2 Template Engine**: Full support for loops, conditionals, filters, and complex data structures
|
|
- **Smart Prompt Management**: Load and manage prompt templates with variable substitution
|
|
- **On-demand Loading**: Prompts are loaded lazily at runtime for better performance
|
|
- **Caching Support**: Optional caching to avoid repeated disk reads
|
|
- **JSON Schema Support**: Associate structured output schemas with prompts
|
|
- **Variable Validation**: Automatic validation of required template variables
|
|
- **Flexible API**: Fill variables at retrieval or on-demand
|
|
|
|
## Quick Start
|
|
|
|
### Basic Usage
|
|
|
|
```python
|
|
from llmutils.prompt_manager import PromptManager
|
|
|
|
# Get a prompt template
|
|
result = PromptManager.get_prompt('greeting')
|
|
print(result.variables) # See required variables: {'name', 'age'}
|
|
print(result.template) # View the template: "Hello {{name}}, you are {{age}} years old"
|
|
|
|
# Fill the template
|
|
filled = result.fill(name='Alice', age=30)
|
|
print(filled) # "Hello Alice, you are 30 years old"
|
|
```
|
|
|
|
### Pre-filling Variables
|
|
|
|
```python
|
|
# Fill variables during retrieval
|
|
result = PromptManager.get_prompt('greeting', name='Alice', age=30)
|
|
print(result.prompt) # Already filled: "Hello Alice, you are 30 years old"
|
|
```
|
|
|
|
### Validation
|
|
|
|
```python
|
|
result = PromptManager.get_prompt('greeting')
|
|
|
|
# Check if variables are valid
|
|
if not result.validate(name='Alice'):
|
|
missing = result.get_missing_variables(name='Alice')
|
|
print(f"Missing variables: {missing}") # {'age'}
|
|
|
|
# Fill with all required variables
|
|
filled = result.fill(name='Alice', age=30)
|
|
```
|
|
|
|
### Advanced Jinja2 Features
|
|
|
|
```python
|
|
# Using lists and loops
|
|
result = PromptManager.get_prompt('task_list')
|
|
filled = result.fill(
|
|
tasks=['Write code', 'Review PR', 'Deploy'],
|
|
priority='high'
|
|
)
|
|
|
|
# Using conditionals
|
|
result = PromptManager.get_prompt('status_report')
|
|
filled = result.fill(
|
|
error='Connection timeout', # Will show error message
|
|
items=[] # Will show "No items"
|
|
)
|
|
|
|
# Using complex nested data
|
|
result = PromptManager.get_prompt('user_profile')
|
|
filled = result.fill(
|
|
user={
|
|
'name': 'Alice',
|
|
'roles': ['admin', 'developer'],
|
|
'projects': [
|
|
{'name': 'Project A', 'status': 'active'},
|
|
{'name': 'Project B', 'status': 'completed'}
|
|
]
|
|
}
|
|
)
|
|
```
|
|
|
|
### JSON Schema Support
|
|
|
|
```python
|
|
# Get prompt with associated schema
|
|
result = PromptManager.get_prompt('task_prompt')
|
|
|
|
if result.schema:
|
|
print("This prompt has a structured output schema")
|
|
print(result.schema) # The JSON schema dictionary
|
|
```
|
|
|
|
## Configuration
|
|
|
|
```python
|
|
from pathlib import Path
|
|
from llmutils.prompt_manager import PromptManager
|
|
|
|
# Configure custom prompts directory (default: ./prompts)
|
|
PromptManager.configure(path=Path('/custom/prompts/location'))
|
|
|
|
# Disable caching for development
|
|
PromptManager.configure(caching=False)
|
|
|
|
# Clear cache to force reload
|
|
PromptManager.reload_prompts()
|
|
```
|
|
|
|
## Prompt Files
|
|
|
|
Place your prompt templates in the `prompts/` directory:
|
|
|
|
- `prompts/greeting.md` - Markdown file with template
|
|
- `prompts/greeting.json` - Optional JSON schema for structured output
|
|
|
|
### Simple Template Example (`greeting.md`):
|
|
```markdown
|
|
Hello {{name}},
|
|
|
|
You are {{age}} years old.
|
|
```
|
|
|
|
### Jinja2 Template Examples
|
|
|
|
#### Lists and Loops (`task_list.md`):
|
|
```markdown
|
|
Priority: {{ priority }}
|
|
|
|
Tasks to complete:
|
|
{% for task in tasks %}
|
|
- {{ task }}
|
|
{% endfor %}
|
|
|
|
Total: {{ tasks | length }} tasks
|
|
```
|
|
|
|
#### Conditionals (`status_report.md`):
|
|
```markdown
|
|
{% if error %}
|
|
⚠️ ERROR: {{ error }}
|
|
{% else %}
|
|
✅ All systems operational
|
|
{% endif %}
|
|
|
|
{% if items %}
|
|
Items ({{ items | length }}):
|
|
{% for item in items %}
|
|
{{ loop.index }}. {{ item }}
|
|
{% endfor %}
|
|
{% else %}
|
|
No items to process.
|
|
{% endif %}
|
|
```
|
|
|
|
#### Complex Data (`user_profile.md`):
|
|
```markdown
|
|
# User: {{ user.name }}
|
|
|
|
## Roles
|
|
{{ user.roles | join(', ') }}
|
|
|
|
## Projects
|
|
{% for project in user.projects %}
|
|
- {{ project.name }} [{{ project.status | upper }}]
|
|
{% endfor %}
|
|
```
|
|
|
|
### JSON Schema Example (`greeting.json`):
|
|
```json
|
|
{
|
|
"type": "object",
|
|
"properties": {
|
|
"response": {
|
|
"type": "string"
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
## API Reference
|
|
|
|
### ManagedPrompt Class
|
|
|
|
The `ManagedPrompt` dataclass returned by `get_prompt()`:
|
|
|
|
- `template: str` - The original Jinja2 template string
|
|
- `name: str` - The prompt name
|
|
- `variables: Set[str]` - Required template variables (auto-extracted from Jinja2)
|
|
- `schema: Optional[Dict]` - Associated JSON schema
|
|
- `prompt: str` - Property that returns filled prompt or template
|
|
- `fill(**kwargs) -> str` - Fill template with variables using Jinja2
|
|
- `validate(**kwargs) -> bool` - Check if all variables provided
|
|
- `get_missing_variables(**kwargs) -> Set[str]` - Get missing variables
|
|
|
|
### PromptManager Methods
|
|
|
|
- `get_prompt(prompt_name, **kwargs) -> ManagedPrompt` - Get a prompt template
|
|
- `get_schema(prompt_name) -> Optional[Dict]` - Get just the schema
|
|
- `has_schema(prompt_name) -> bool` - Check if prompt has schema
|
|
- `list_prompts() -> Dict` - List all available prompts
|
|
- `get_prompt_info(prompt_name) -> Dict` - Get detailed prompt information
|
|
- `configure(path=None, caching=None)` - Configure settings
|
|
- `reload_prompts()` - Clear the cache
|
|
|
|
### Jinja2 Template Features
|
|
|
|
The library supports all standard Jinja2 features:
|
|
|
|
#### Filters
|
|
- `{{ items | length }}` - Get length of list
|
|
- `{{ name | upper }}` - Convert to uppercase
|
|
- `{{ name | lower }}` - Convert to lowercase
|
|
- `{{ skills | join(', ') }}` - Join list items
|
|
- `{{ data | tojson }}` - Convert to JSON
|
|
- `{{ price | round(2) }}` - Round numbers
|
|
|
|
#### Loops
|
|
- `{% for item in items %}...{% endfor %}` - Iterate over lists
|
|
- `{{ loop.index }}` - Current iteration (1-indexed)
|
|
- `{{ loop.index0 }}` - Current iteration (0-indexed)
|
|
- `{% for key, value in dict.items() %}...{% endfor %}` - Iterate over dictionaries
|
|
|
|
#### Conditionals
|
|
- `{% if condition %}...{% endif %}` - Simple conditional
|
|
- `{% if condition %}...{% else %}...{% endif %}` - If/else
|
|
- `{% if condition %}...{% elif other %}...{% else %}...{% endif %}` - Multiple conditions
|
|
|
|
## License
|
|
|
|
MIT
|