How to Configure Custom AI Prompts in Lifetrace: A Complete Guide
To configure custom AI prompts in Lifetrace, create or edit YAML files in the lifetrace/config/prompts/ directory, then retrieve them using the get_prompt(category, key, **kwargs) helper from lifetrace/util/prompt_loader.py.
Lifetrace centralizes all AI prompt management through a modular configuration system that supports both modern multi-file layouts and legacy single-file setups. By editing YAML definitions and leveraging the singleton PromptLoader class, you can customize AI behavior for transcription, RAG, planning, and custom features without modifying application source code. This guide explains how to configure custom AI prompts lifetrace using the actual implementation details from the freeu-group/lifetrace repository.
Understanding the Prompt Loader Architecture
The prompt system relies on a singleton PromptLoader class defined in lifetrace/util/prompt_loader.py (lines 14-25). This design ensures that prompt dictionaries are loaded exactly once per process and cached for subsequent access.
When the application initializes, the loader determines the configuration directory by calling get_config_dir() from lifetrace/util/base_paths.py (lines 54-65). This function resolves paths differently for development environments versus PyInstaller production bundles, ensuring your custom prompts are discovered regardless of deployment context.
The _load_prompts() method (lines 30-66 of prompt_loader.py) implements a hierarchical loading strategy:
- First, it scans
lifetrace/config/prompts/for any*.yamlfiles (the new modular layout) - If found, it merges all YAML contents into the internal prompt dictionary
- If the directory does not exist, it falls back to the legacy
lifetrace/config/prompt.yamlfor backward compatibility
Where to Store Custom AI Prompts
Lifetrace supports two configuration patterns. The modern approach uses a dedicated prompts directory, while the legacy approach uses a single file.
Modular Layout (Recommended):
Create individual YAML files under lifetrace/config/prompts/. Each file can contain multiple categories, allowing you to organize prompts by feature (e.g., todo.yaml, rag.yaml, transcription.yaml).
Legacy Fallback:
If you prefer a single file or need to maintain older configurations, place all prompts in lifetrace/config/prompt.yaml. The loader automatically detects this file when the prompts/ directory is absent.
Creating Custom Prompt Files
To add custom prompts for a new feature, create a YAML file in the prompts directory with a top-level category key containing your prompt definitions.
# lifetrace/config/prompts/custom_feature.yaml
custom_feature:
system_prompt: |
You are a specialized assistant for the Custom Feature module.
Provide concise, structured responses in JSON format.
user_prompt: |
Process the following data and extract key entities:
{input_data}
Use category names (like custom_feature) that match the feature identifier in your code. Define keys (like system_prompt, user_prompt) to distinguish different prompt contexts. Include placeholders like {input_data}—the loader applies Python's str.format(**kwargs) to substitute these at runtime.
Retrieving and Using Prompts in Code
Access configured prompts through the get_prompt helper function exported from lifetrace/util/prompt_loader.py.
from lifetrace.util.prompt_loader import get_prompt
# Retrieve a static system prompt
system = get_prompt("custom_feature", "system_prompt")
# Retrieve a user prompt with dynamic data injection
user = get_prompt(
"custom_feature",
"user_prompt",
input_data='{"entities": ["meeting", "deadline"]}'
)
The function signature is get_prompt(category, key, **kwargs). The loader lazily initializes on first call, caching all subsequent requests. Dynamic values passed as keyword arguments replace the curly-brace placeholders in your YAML templates.
Reloading Prompts Without Restarting
Because PromptLoader is a singleton, changes to YAML files on disk are not automatically reflected in running processes. To apply edits without restarting the service, explicitly trigger a reload:
from lifetrace.util.prompt_loader import prompt_loader
# Force reload from disk
prompt_loader.reload()
This method re-executes _load_prompts(), re-scanning the prompts/ directory or legacy file and updating the internal cache. Implement this in admin endpoints or development consoles to enable hot-reloading of AI behavior.
Real-World Usage Examples
The Lifetrace codebase consistently uses get_prompt across services to maintain separation between AI logic and prompt content.
Audio Transcription Service (lifetrace/services/audio_service.py, line 511):
system_prompt = get_prompt("transcription_optimization", "system_assistant")
user_prompt = get_prompt(
"transcription_optimization",
"user_prompt",
text=transcribed_text,
)
RAG Service (lifetrace/llm/rag_service.py, line 344):
prompt = get_prompt("rag", "contextualization_prompt", context=document_chunks)
These examples demonstrate the standard pattern: import the helper, specify the category matching your YAML filename or top-level key, select the specific prompt key, and pass runtime variables as keyword arguments.
Summary
- Lifetrace stores AI prompts in YAML files under
lifetrace/config/prompts/(modular) orlifetrace/config/prompt.yaml(legacy). - The
PromptLoadersingleton inlifetrace/util/prompt_loader.pymanages loading and caching viaget_config_dir()resolution. - Retrieve prompts in code using
get_prompt(category, key, **kwargs)to inject dynamic values with Python string formatting. - Call
prompt_loader.reload()to refresh prompts from disk without application restart. - Services like
audio_service.pyandrag_service.pydemonstrate production usage of this configuration system.
Frequently Asked Questions
How does Lifetrace handle missing prompt directories?
If the lifetrace/config/prompts/ directory does not exist, the PromptLoader automatically falls back to loading lifetrace/config/prompt.yaml. This backward-compatible behavior ensures existing single-file configurations continue to function while allowing migration to the modular layout.
Can I use variables inside my YAML prompt templates?
Yes. Include Python format string placeholders like {variable_name} in your YAML values. When calling get_prompt("category", "key", variable_name="value"), the loader passes these kwargs to str.format(), replacing placeholders with runtime data before returning the final string.
Why are my prompt changes not appearing in the application?
The PromptLoader caches prompts in memory as a singleton. Changes to YAML files require calling prompt_loader.reload() to re-read from disk, or you must restart the application process. This design optimizes performance by avoiding repeated file system access during normal operation.
Where is the configuration directory located in production builds?
The get_config_dir() function in lifetrace/util/base_paths.py detects PyInstaller bundles and resolves the path relative to the executable location. In development, it uses the project root. This ensures lifetrace/config/prompts/ is correctly discovered regardless of whether running from source or a compiled distribution.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →