Um sistema de gerenciamento de prompt validado e seguro de tipo, que captura erros antecipadamente, aplica a segurança do tipo e fornece uma maneira estruturada de gerenciar prompts. Usa modelos pydantic para validação variável e modelos Jinja2 para renderização rápida.
Nota : Esta biblioteca está em desenvolvimento inicial e sujeita a alterações.
Sempre achei desafiador gerenciar prompts dinâmicas para o LLMS. O processo é propenso a erros, com problemas frequentemente descobertos apenas em tempo de execução. O promotor digitado tem como objetivo resolver esse problema, fornecendo uma maneira estruturada e segura de tipo de gerenciar instruções que captrem erros mais cedo e aplica a segurança do tipo.
Isenção de responsabilidade : este é um projeto pessoal para resolver as que eu tinha no passado e não afiliado a nenhuma organização. É um trabalho em andamento e sujeito a alterações.
Vou adicionar mais recursos e exemplos no futuro. Se você tiver alguma sugestão ou feedback, fique à vontade para abrir um problema!
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" )
)Nota : Usar nenhum como um valor para variáveis opcionais renderizará como
Noneno prompt. por exemplo, "Exemplo de teste{{var}}renderizará comoTest example NonesevarforNone. Esse é o comportamento padrão de Jinja. Portanto, você precisa lidar com isso no seu modelo Jinja2. EG{{if var}}ou{{var | default('default value')}}ou, no entanto, você deseja manipular.
A biblioteca valida seus modelos de prompt durante a definição da classe:
Todas as variáveis são validadas através do Pydantic:
Anexe a configuração personalizada aos prompts:
Considere este exemplo:
# 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 : UserVarsA biblioteca captura erros de modelo no momento da definição.
uv add tpyed-promptou
pip install typed-promptPara mais exemplos e documentação detalhada, consulte o diretório exemplos.
Para executar os exemplos:
uv run python examples/user.pyO Typed-Prompt usa uma estrutura de prompt em duas partes que corresponde aos padrões de interação comuns LLM:
Prompt do sistema : fornece contexto ou instruções para o modelo de IA. Você pode definir isso de duas maneiras:
system_prompt_template Prompt de usuário : contém o modelo de prompt real que será enviado para o modelo. Isso é sempre definido no atributo de classe prompt_template .
As variáveis no promotor digitado são tratadas através de três mecanismos complementares:
Modelo de variáveis : um modelo pydantic que define as variáveis principais que suas necessidades rápidas:
class UserVariables ( BaseModel ):
name : str
age : int
occupation : Optional [ str ] = NoneParâmetros do método de renderização : variáveis adicionais podem ser definidas como argumentos somente de palavra-chave em um método de renderização personalizado:
def render ( self , * , learning_topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "learning_topic" ] = learning_topic
return super (). render ( ** extra_vars )Variáveis extras : as variáveis únicas podem ser passadas diretamente para o método de renderização.
A biblioteca realiza validação abrangente para capturar questões comuns mais cedo:
Para avisos complexos, você pode carregar modelos de arquivos externos:
class ComplexPrompt ( BasePrompt [ ComplexVariables ]):
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()
prompt_template : str = Path ( "templates/user_prompt.j2" ). read_text ()NOTA : Com motores de modelos como o Jinja2, você pode normalmente os modelos de recarga a quente, mas isso não é suportado no promprimento digitado, pois os modelos são validados no horário da definição da classe.
A classe fundamental para criar instruções estruturadas.
T : Uma subclasse de modelo de base pydantic que define a estrutura das variáveis de modelo system_prompt_template : opcional [STR] - Modelo de prompt do sistemaprompt_template : STR - Modelo de prompt do usuáriovariables : T - instância do modelo de variáveis render(**extra_vars) -> RenderOutput : renderiza ambos solicitam variáveis fornecidasUm nome de nome que fornece acesso estruturado aos avisos renderizados:
system_prompt : Opcional [STR] - O prompt de sistema renderizadouser_prompt : str - o prompt de usuário renderizado Estruture seus modelos para obter a máxima legibilidade e manutenção:
Use Docstrings para avisos do sistema : Quando possível, defina o sistema de sistemas no DocStrings de classe para uma melhor organização de código:
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?"Modelos complexos separados : para modelos mais longos, use arquivos externos:
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()Use a sintaxe condicional de Jinja2 para conteúdo dinâmico:
class DynamicPrompt ( BasePrompt [ Variables ]):
prompt_template : str = """
{% if expert_mode %}
Provide a detailed technical explanation of {{topic}}
{% else %}
Explain {{topic}} in simple terms
{% endif %}
""" As contribuições são bem -vindas!
Este projeto está licenciado sob a licença do MIT - consulte o arquivo de licença para obter detalhes.
Os opcionais ainda serão renderizados como None no prompt.
Torne o Jinja2 opcional (para modelar muito simples, basta usar a formatação da string, por exemplo f"Hello {name}" ). Talvez deveria começar mais simples lol.
Saída Open Objects de mensagem compatível com o Open.
A capacidade de definir, não apenas um prompt do sistema e uma única solicitação, mas solicita a correntes. Por exemplo, system_prompt -> user_prompt -> assistant_response -> user_prompt -> assistant_response -> ...