Migration Guide¶
This guide explains best practices for creating and managing prompt migrations.
Migration Naming¶
Use a consistent naming pattern for your revision IDs:
XXX_descriptive_name
Where XXX
is a numeric prefix that ensures migrations are applied in the correct order.
Examples:
- 001_initial_system
- 002_add_weather_questions
- 010_refactor_system_prompt
Writing Migration Functions¶
Migrations should be pure functions that take a prompts dictionary and return a modified dictionary:
@prompt_revision("001_initial", "Add system prompt")
def migrate(prompts):
# Add new prompts
prompts["SYSTEM"] = "You are a helpful assistant."
# Or modify existing ones (if you know they exist)
if "USER_GREETING" in prompts:
prompts["USER_GREETING"] = "Updated greeting"
return prompts
Migration Best Practices¶
1. Make Migrations Idempotent¶
Migrations should be safe to run multiple times:
@prompt_revision("002_fix_typo", "Fix typo in system prompt")
def fix_typo(prompts):
if "SYSTEM" in prompts and "assisstant" in prompts["SYSTEM"]:
prompts["SYSTEM"] = prompts["SYSTEM"].replace("assisstant", "assistant")
return prompts
2. Keep Migrations Small and Focused¶
Each migration should do one logical change:
# Good: Focused on one type of prompt
@prompt_revision("003_add_weather", "Add weather prompts")
def add_weather(prompts):
prompts["WEATHER_QUESTION"] = "What's the weather like today?"
prompts["WEATHER_FOLLOW_UP"] = "Would you like a detailed forecast?"
return prompts
# Instead of combining unrelated changes
3. Document Your Changes¶
Add clear descriptions to your migrations:
@prompt_revision(
"004_format_change",
"Changed format of response prompts to include variable placeholders"
)
def update_format(prompts):
# Implementation
return prompts
4. Testing Migrations¶
Test your migrations to ensure they work as expected:
# test_migrations.py
from promptmigrate.manager import PromptManager, prompt_revision
def test_migration():
# Create a test migration
@prompt_revision("test_001", "Test migration")
def test_migrate(prompts):
prompts["TEST"] = "Test value"
return prompts
# Apply it to an empty prompts dict
manager = PromptManager(prompt_file=Path("test_prompts.yaml"))
manager.upgrade()
# Verify it worked
assert manager.TEST == "Test value"
Organizing Migrations¶
Option 1: Chronological Files¶
promptmigrate_revisions/
├── __init__.py
├── rev_001_initial.py
├── rev_002_add_weather.py
└── rev_003_refactor.py
Option 2: Module-Based Organization¶
myapp/
├── __init__.py
└── prompts/
├── __init__.py
└── revisions/
├── __init__.py
├── core.py # Core prompts
├── weather.py # Weather-related prompts
└── user.py # User interaction prompts
With module loading in your application:
# Load all revision modules
import importlib
import pkgutil
pkg = "myapp.prompts.revisions"
pkg_mod = importlib.import_module(pkg)
for _, name, _ in pkgutil.walk_packages(pkg_mod.__path__, f"{pkg_mod.__name__}."):
importlib.import_module(name)
Advanced Migration Patterns¶
1. Conditional Migrations¶
Apply changes only if certain conditions are met:
@prompt_revision("005_conditional", "Update prompts based on condition")
def conditional(prompts):
# Only update if we have the old format
if "SYSTEM" in prompts and not prompts["SYSTEM"].startswith("You are"):
prompts["SYSTEM"] = "You are " + prompts["SYSTEM"]
return prompts
2. Renaming Prompts¶
When renaming prompts, create a migration that handles both keys:
@prompt_revision("006_rename", "Rename GREETING to WELCOME")
def rename_greeting(prompts):
if "GREETING" in prompts:
prompts["WELCOME"] = prompts["GREETING"]
del prompts["GREETING"]
return prompts
3. Marking Prompts as Deprecated¶
Instead of removing prompts, mark them as deprecated:
@prompt_revision("007_deprecate", "Mark old prompts as deprecated")
def deprecate_prompts(prompts):
if "OLD_PROMPT" in prompts:
prompts["OLD_PROMPT_DEPRECATED"] = prompts["OLD_PROMPT"]
prompts["OLD_PROMPT"] = "[DEPRECATED] Please use NEW_PROMPT instead. " + prompts["OLD_PROMPT"]
return prompts
Auto-Generated Migrations¶
PromptMigrate supports automatically creating migrations from manual changes to your prompts.yaml
file.
Using the Auto-Revision Command¶
# Detect changes and create a revision
promptmigrate auto-revision
The system will automatically:
1. Compare the current prompts.yaml with the state after the last applied migration
2. Identify added, modified, and removed prompts
3. Generate a new migration file with appropriate code
4. Register the migration so it can be applied with promptmigrate upgrade
Example Auto-Generated Migration¶
Here's an example of what an auto-generated migration might look like:
"""Auto-generated migration from manual changes to prompts.yaml on 2025-05-13 14:22:45."""
from promptmigrate.manager import prompt_revision
@prompt_revision("005_auto_changes", "Auto-generated from manual changes to prompts.yaml")
def migrate(prompts):
"""Apply changes made directly to prompts.yaml."""
# Add new prompts
prompts["NEW_PROMPT"] = "This is a new prompt added manually"
# Update modified prompts
prompts["SYSTEM"] = "Updated system prompt with better instructions"
# Remove deleted prompts
if "OLD_PROMPT" in prompts:
del prompts["OLD_PROMPT"]
return prompts
Best Practices for Auto-Revision¶
- Review Before Upgrading: Always review auto-generated migrations before applying them
- Update Descriptions: Consider editing the auto-generated description to be more specific
- Combine with Manual Edits: You can modify auto-generated migrations to improve them
- Add Tests: Consider adding tests for important prompt changes