Ein typ-sicheres, validiertes Eingabeaufforderung-Managementsystem für LLMs, das Fehler frühzeitig auffängt, die Sicherheitstyps durchsetzt und eine strukturierte Möglichkeit bietet, Eingabeaufforderungen zu verwalten. Verwendet pydantische Modelle für variable Validierung und Jinja2 -Vorlagen für die Umformung.
Hinweis : Diese Bibliothek befindet sich in der frühen Entwicklung und ändert sich.
Ich habe es immer herausfordernd gefunden, dynamische Aufforderungen für LLMs zu verwalten. Der Prozess ist fehleranfällig, da Probleme, die häufig nur zur Laufzeit entdeckt werden. Typed-Prompt zielt darauf ab, dieses Problem zu lösen, indem ein strukturierter, typsicherer Weg zur Verwaltung von Eingaben zur Verfügung stellt, die Fehler frühzeitig auffängt und die Sicherheit vom Typ erzwingt.
Haftungsausschluss : Dies ist ein persönliches Projekt zur Lösung von Gripes, die ich in der Vergangenheit hatte und nicht mit einer Organisation verbunden war. Es ist eine in Arbeit, und Veränderung unterliegt.
Ich werde in Zukunft weitere Funktionen und Beispiele hinzufügen. Wenn Sie Vorschläge oder Feedback haben, können Sie ein Problem öffnen!
from typed_prompt import BasePrompt
from pydantic import BaseModel
from typing import Optional
# Define your variables
class UserVars ( BaseModel ):
name : str
expertise : str
# This works - all template variables are defined
class ValidPrompt ( BasePrompt [ UserVars ]):
"""Helping {{name}} with {{expertise}} level knowledge."""
prompt_template : str = "Explain {{topic}} to me"
variables : UserVars
def render ( self , * , topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "topic" ] = topic
return super (). render ( ** extra_vars )
# This fails immediately - 'unknown_var' not defined
class InvalidPrompt ( BasePrompt [ UserVars ]):
prompt_template : str = "What is {{unknown_var}}?" # ValueError!
variables : UserVars
# This fails - 'expertise' defined but never used
class UnusedVarPrompt ( BasePrompt [ UserVars ]):
prompt_template : str = "Hello {{name}}" # ValueError!
variables : UserVars from typing import Union
class TemplateVars ( BaseModel ):
user_type : Union [ "expert" , "beginner" ]
name : str
preferences : Optional [ dict ] = None
class ConditionalPrompt ( BasePrompt [ TemplateVars ]):
"""{% if user_type == 'expert' %}
Technical advisor for {{name}}
{% else %}
Friendly helper for {{name}}
{% endif %}"""
prompt_template : str = """
{% if preferences %}
Considering your preferences: {% for k, v in preferences.items() %}
- {{k}}: {{v}}{% endfor %}
{% endif %}
How can I help with {{topic}}?
"""
variables : TemplateVars
def render ( self , * , topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "topic" ] = topic
return super (). render ( ** extra_vars ) from typed_prompt import RenderOutput
from pydantic import BaseModel , Field
class MyConfig ( BaseModel ):
temperature : float = Field ( default = 0.7 , ge = 0 , le = 2 )
model : str = Field ( default = "gpt-4" )
class MyPrompt ( BasePrompt [ UserVars ]):
"""Assistant for {{name}}"""
prompt_template : str = "Help with {{topic}}"
variables : UserVars
config : MyConfig = Field ( default_factory = MyConfig )
def render ( self , * , topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "topic" ] = topic
return super (). render ( ** extra_vars )
# Use custom config
prompt = MyPrompt (
variables = UserVars ( name = "Alice" , expertise = "intermediate" ),
config = MyConfig ( temperature = 0.9 , model = "gpt-3.5-turbo" )
)HINWEIS : Wenn Sie keine als Wert für optionale Variablen verwenden, wird dies in der Eingabeaufforderung als
Nonegerendert. EG "Testbeispiel{{var}}rendert alsTest example NonewennvarNoneist. Dies ist das Standardverhalten von Jinja. Sie müssen dies daher in Ihrer Jinja2 -Vorlage verarbeiten. EG{{if var}}oder{{var | default('default value')}}oder du willst es verarbeiten.
Die Bibliothek bestätigt Ihre Eingabeaufforderung Vorlagen während der Klassendefinition:
Alle Variablen werden durch Pydantic validiert:
Fügen Sie die benutzerdefinierte Konfiguration an die Eingabeaufforderungen hinzu:
Betrachten Sie dieses Beispiel:
# Without typed-prompt
def create_prompt ( user_data ):
template = "Hello {{username}}, your level is {{level}}"
# Error only discovered when rendering with wrong data
return template . format ( ** user_data ) # KeyError at runtime!
# With typed-prompt
class UserPrompt ( BasePrompt [ UserVars ]):
prompt_template : str = "Hello {{unknown_var}}" # Error immediately!
variables : UserVarsDie Bibliothek fängt Vorlagenfehler zur Definitionszeit auf.
uv add tpyed-promptoder
pip install typed-promptWeitere Beispiele und detaillierte Dokumentation finden Sie im Beispielverzeichnis.
Beispiele durchführen:
uv run python examples/user.pyTyped-Prompt verwendet eine zweiteilige Eingabeaufforderungsstruktur, die gemeinsame LLM-Interaktionsmuster entspricht:
Systemaufforderung : Bietet Kontext oder Anweisungen für das KI -Modell. Sie können dies auf zwei Arten definieren:
system_prompt_template klassenklasse Benutzeraufforderung : Enthält die tatsächliche Eingabeaufforderungsvorlage, die an das Modell gesendet wird. Dies ist immer im Attribut prompt_template -Klasse definiert.
Variablen in Typed-Prompt werden durch drei komplementäre Mechanismen behandelt:
Variablenmodell : Ein pydantisches Modell, das die Kernvariablen für Ihre Eingabeaufforderung definiert:
class UserVariables ( BaseModel ):
name : str
age : int
occupation : Optional [ str ] = NoneParameter der Render-Methode : Zusätzliche Variablen können in einer benutzerdefinierten Render-Methode nur als Keyword-Argumente definiert werden:
def render ( self , * , learning_topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "learning_topic" ] = learning_topic
return super (). render ( ** extra_vars )Zusätzliche Variablen : Einmalige Variablen können direkt an die Render-Methode übergeben werden.
Die Bibliothek führt eine umfassende Validierung durch, um gemeinsame Themen frühzeitig zu fangen:
Für komplexe Eingabeaufforderungen können Sie Vorlagen aus externen Dateien laden:
class ComplexPrompt ( BasePrompt [ ComplexVariables ]):
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()
prompt_template : str = Path ( "templates/user_prompt.j2" ). read_text ()Hinweis : Mit Vorlagen-Motoren wie Jinja2 können Sie normalerweise die Vorladevorlagen heißer neu laden, dies wird jedoch nicht in typisierten Prompt unterstützt, da die Vorlagen zum Zeitpunkt der Unterrichtsdefinition validiert werden.
Die grundlegende Klasse zum Erstellen strukturierter Eingabeaufforderungen.
T : Eine pydantische Basemodell -Unterklasse, die die Struktur von Vorlagenvariablen definiert system_prompt_template : Optional [STR] - Systemeingabeaufforderung Vorlageprompt_template : str - Benutzer Eingabeaufforderung Vorlagevariables : t - Instanz des Variablenmodells render(**extra_vars) -> RenderOutput : Rendern beide Eingabeaufforderungen mit bereitgestellten Variablen rendernEin namentlicher Tupel bietet einen strukturierten Zugriff auf gerenderte Eingabeaufforderungen:
system_prompt : Optional [STR] - Die gerenderte Systemaufforderunguser_prompt : str - die gerenderte Benutzeraufforderung Strukturieren Sie Ihre Vorlagen für maximale Lesbarkeit und Wartbarkeit:
Verwenden Sie DocStrings für Systemaufforderungen : Definieren Sie nach Möglichkeit Systemanforderungen in den Klassendocstrings für eine bessere Codeorganisation:
class UserPrompt ( BasePrompt [ UserVariables ]):
"""You are having a conversation with {{name}}, a {{age}}-year-old {{occupation}}."""
prompt_template : str = "What would you like to discuss?"Separate komplexe Vorlagen : Verwenden Sie für längere Vorlagen externe Dateien:
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()Verwenden Sie die bedingte Syntax von Jinja2 für dynamischen Inhalt:
class DynamicPrompt ( BasePrompt [ Variables ]):
prompt_template : str = """
{% if expert_mode %}
Provide a detailed technical explanation of {{topic}}
{% else %}
Explain {{topic}} in simple terms
{% endif %}
""" Beiträge sind willkommen!
Dieses Projekt ist unter der MIT -Lizenz lizenziert - Einzelheiten finden Sie in der Lizenzdatei.
Die Optionen werden in der Eingabeaufforderung weiterhin als None begeben.
Machen Sie Jinja2 optional (für sehr einfache Vorlagen verwenden Sie einfach String -Formatierung, z f"Hello {name}" ). Vielleicht solltea einfacher anfangen lol.
OpenAI -kompatible Nachrichtenobjekte ausgeben.
Die Fähigkeit zu definieren, nicht nur eine Systemaufforderung und eine einzelne Eingabeaufforderung, sondern auch eine schnelle Ketten. EG system_prompt -> user_prompt -> assistant_response -> user_prompt -> assistant_response -> ...