오류를 조기에 포착하고 유형 안전을 시행하며 프롬프트를 관리하는 구조화 된 방법을 제공하는 유형 안전, 검증 된 프롬프트 관리 시스템. 가변 유효성 검사에 Pydantic 모델을 사용하고 Prompt 렌더링을 위해 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을 선택적 변수의 값으로 사용하면 프롬프트에서
None렌더링됩니다. 예 : "테스트 예제{{var}}var가NoneTest example None로 렌더링됩니다. 이것은 jinja의 기본 동작입니다. 따라서 Jinja2 템플릿에서이를 처리해야합니다. 예{{if var}}{{var | default('default value')}}또는 처리하려고합니다.
라이브러리는 클래스 정의 중에 프롬프트 템플릿을 확인합니다.
모든 변수는 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.pyTyped-Prompt는 일반적인 LLM 상호 작용 패턴과 일치하는 두 부분 프롬프트 구조를 사용합니다.
시스템 프롬프트 : AI 모델에 대한 컨텍스트 또는 지침을 제공합니다. 이것을 두 가지 방법으로 정의 할 수 있습니다.
system_prompt_template 클래스 속성으로 사용자 프롬프트 : 모델로 전송 될 실제 프롬프트 템플릿이 포함되어 있습니다. 이것은 항상 prompt_template 클래스 속성에 정의됩니다.
유형 홍보의 변수는 세 가지 보완 메커니즘을 통해 처리됩니다.
변수 모델 : 핵심 변수를 정의하는 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 Basemodel 서브 클래스 system_prompt_template : 선택 사항 [str] - 시스템 프롬프트 템플릿prompt_template : str- 사용자 프롬프트 템플릿variables : t- 변수 모델의 인스턴스 render(**extra_vars) -> RenderOutput : 제공된 변수로 두 프롬프트를 렌더링합니다.렌더링 된 프롬프트에 대한 구조화 된 액세스를 제공하는 이름의 이름 :
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 -> ...