نظام إدارة موجه آمن من النوع ، تم التحقق من صحته لـ LLMS الذي يلتقط الأخطاء مبكرًا ، ويفرض السلامة من النوع ، ويوفر طريقة منظمة لإدارة المطالبات. يستخدم نماذج Pydantic للتحقق المتغير وقوالب Jinja2 لتقديم موجه.
ملاحظة : هذه المكتبة في التطوير المبكر وتخضع للتغيير.
لقد وجدت دائمًا أنه من الصعب إدارة المطالبات الديناميكية لـ LLMS. العملية معرضة للخطأ ، حيث يتم اكتشاف المشكلات في كثير من الأحيان فقط في وقت التشغيل. تهدف Prompt المكتوبة إلى حل هذه المشكلة من خلال توفير طريقة منظمة ومؤمّنة من النوع لإدارة المطالبات التي تلتقط الأخطاء في وقت مبكر وتفرض السلامة من النوع.
إخلاء المسئولية : هذا مشروع شخصي لحل Gripes Ive في الماضي وليس التابع لأي منظمة. إنه عمل مستمر ويخضع للتغيير.
سأضيف المزيد من الميزات والأمثلة في المستقبل. إذا كان لديك أي اقتراحات أو ملاحظات ، فلا تتردد في فتح مشكلة!
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}}Test example Noneإذا كانvarNone. هذا هو السلوك الافتراضي لـ 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.pyيستخدم Prompt المكتوبة بنية موجه من جزأين يطابق أنماط تفاعل LLM المشتركة:
موجه النظام : يوفر سياق أو تعليمات لنموذج الذكاء الاصطناعي. يمكنك تحديد هذا بطريقتين:
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 ()ملاحظة : مع محركات templating مثل Jinja2 ، يمكنك عادة قوالب إعادة التحميل الساخنة ، ولكن هذا غير مدعوم في المعرض المكتوب حيث يتم التحقق من صحة القوالب في وقت تعريف الفصل.
الفئة التأسيسية لإنشاء مطالبات منظمة.
T : الفئة الفرعية القاعدة الأطلسية تحدد بنية متغيرات القالب system_prompt_template : اختياري [STR] - قالب موجه النظامprompt_template : str - قالب موجه المستخدمvariables : T - مثيل نموذج المتغيرات render(**extra_vars) -> RenderOutput : يقدم كلا كل من المتغيرات المقدمةa namedtuple يوفر وصولًا منظمًا إلى مطالبات تم تقديمها:
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 %}
""" المساهمات مرحب بها!
تم ترخيص هذا المشروع بموجب ترخيص معهد ماساتشوستس للتكنولوجيا - راجع ملف الترخيص للحصول على التفاصيل.
سيظل الاختلاط يقدمون None في المطالبة.
اجعل Jinja2 اختياريًا ، (من أجل templating بسيط للغاية ، فقط استخدم تنسيق السلسلة على سبيل المثال f"Hello {name}" ). ربما يجب أن بدأت أبسط لول.
إخراج Openai كائنات رسالة متوافقة.
القدرة على تحديد ، وليس مجرد موجه النظام ومطالبة واحدة ، ولكن السلاسل المطالبة. eg system_prompt -> user_prompt -> assistant_response -> user_prompt -> assistant_response -> ...