一种类型安全的,经过验证的LLMS的提示管理系统,可尽早捕获错误,实施类型安全性,并提供一种结构化的方法来管理提示。使用Pydantic模型进行可变验证和Jinja2模板进行及时渲染。
注意:该图书馆正处于早期开发状态,可能会发生变化。
我总是发现管理LLM的动态提示很具有挑战性。该过程容易出错,通常仅在运行时发现问题。键入宣传旨在通过提供一种结构化的,类型的安全方法来管理提示,以尽早发现错误并强制执行类型的安全性来解决此问题。
免责声明:这是一个个人项目,旨在解决我过去的抓地力,而不是与任何组织有联系。这是一项正在进行的工作,可能会改变。
我将来会添加更多功能和示例。如果您有任何建议或反馈,请随时打开问题!
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" )
)注意:使用无作为可选变量的值将在提示中呈现为
None。例如,“测试示例{{var}}{{if var}}{{var | default('default value')}}varNoneTest example None
库在课堂定义期间验证您的提示模板:
所有变量均通过Pydantic验证:
将自定义配置附加到提示:
考虑此示例:
# 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 : UserVars该库在定义时捕获模板错误。
uv add tpyed-prompt或者
pip install typed-prompt有关更多示例和详细的文档,请检查示例目录。
运行示例:
uv run python examples/user.py键入PROMPT使用分为两部分的提示结构,该结构与常见的LLM交互模式匹配:
系统提示:为AI模型提供上下文或说明。您可以通过两种方式来定义这一点:
system_prompt_template类属性用户提示:包含将发送到模型的实际提示模板。这始终是在prompt_template类属性中定义的。
打字prompt中的变量通过三种互补机制来处理:
变量模型:定义核心变量您提示需求的pydantic模型:
class UserVariables ( BaseModel ):
name : str
age : int
occupation : Optional [ str ] = None渲染方法参数:在自定义渲染方法中,可以将其他变量定义为仅关键字的参数:
def render ( self , * , learning_topic : str , ** extra_vars ) -> RenderOutput :
extra_vars [ "learning_topic" ] = learning_topic
return super (). render ( ** extra_vars )额外的变量:一次性变量可以直接传递给渲染方法。
图书馆进行了全面的验证,以尽早发现常见问题:
对于复杂的提示,您可以从外部文件加载模板:
class ComplexPrompt ( BasePrompt [ ComplexVariables ]):
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()
prompt_template : str = Path ( "templates/user_prompt.j2" ). read_text ()注意:使用Jinja2之类的模板引擎,您通常可以热加载模板,但是在类型启动中不支持该模板在类别定义时间验证。
创建结构化提示的基础类。
T :一个定义模板变量结构的pydantic基本模型子类system_prompt_template :可选[str] - 系统提示模板prompt_template :str-用户提示模板variables :t-变量模型的实例render(**extra_vars) -> RenderOutput :带有提供变量的两个提示一个名为Tuple,可提供对渲染提示的结构化访问:
system_prompt :可选[str] - 渲染系统提示user_prompt :str-渲染的用户提示构建模板以获得最大的可读性和可维护性:
使用DOCSTRINGS进行系统提示:在可能的情况下,在类docstrings中定义系统提示以提供更好的代码组织:
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?"单独的复杂模板:对于较长的模板,请使用外部文件:
system_prompt_template = Path ( "templates/system_prompt.j2" ). read_text ()使用Jinja2的条件语法进行动态内容:
class DynamicPrompt ( BasePrompt [ Variables ]):
prompt_template : str = """
{% if expert_mode %}
Provide a detailed technical explanation of {{topic}}
{% else %}
Explain {{topic}} in simple terms
{% endif %}
""" 欢迎捐款!
该项目是根据MIT许可证获得许可的 - 有关详细信息,请参见许可证文件。
选项仍将在提示中呈现为None 。
使Jinja2可选,(对于非常简单的模板,只需使用字符串格式即可,例如f"Hello {name}" )。也许应该开始简单的大声笑。
输出OpenAI兼容消息对象。
定义的能力,不仅是系统提示和一个提示,还要提示链。例如system_prompt -> user_prompt -> assistant_response -> user_prompt -> assistant_response -> ...