دمج نماذج اللغة الكبيرة بسهولة في رمز Python الخاص بك. ما عليك سوى استخدام ديكورات @prompt و @chatprompt لإنشاء وظائف تعيد الإخراج المنظم من LLM. قم بخلط استعلامات LLM والاتصال بالوظيفة مع رمز Python العادي لإنشاء منطق معقد.
FunctionCall و ParallelFunctionCall .async def عند تحديد وظيفة Magentic.pip install magenticأو باستخدام الأشعة فوق البنفسجية
uv add magentic قم بتكوين مفتاح Openai API عن طريق تعيين متغير بيئة OPENAI_API_KEY . لتكوين مزود LLM مختلف ، انظر التكوين للمزيد.
يتيح لك Decorator @prompt تحديد قالب لمطالبة نموذج لغة كبيرة (LLM) كدالة Python. عندما يتم استدعاء هذه الوظيفة ، يتم إدخال الوسائط في القالب ، ثم يتم إرسال هذه المطالبة إلى LLM التي تولد إخراج الوظيفة.
from magentic import prompt
@ prompt ( 'Add more "dude"ness to: {phrase}' )
def dudeify ( phrase : str ) -> str : ... # No function body as this is never executed
dudeify ( "Hello, how are you?" )
# "Hey, dude! What's up? How's it going, my man?" سيحترم الديكور @prompt نوع الإرجاع التعليق التوضيحي للوظيفة المزينة. يمكن أن يكون هذا أي نوع مدعوم من قبل Pydantic بما في ذلك نموذج pydantic .
from magentic import prompt
from pydantic import BaseModel
class Superhero ( BaseModel ):
name : str
age : int
power : str
enemies : list [ str ]
@ prompt ( "Create a Superhero named {name}." )
def create_superhero ( name : str ) -> Superhero : ...
create_superhero ( "Garden Man" )
# Superhero(name='Garden Man', age=30, power='Control over plants', enemies=['Pollution Man', 'Concrete Woman'])انظر المخرجات المهيكلة للمزيد.
يعمل Decorator @chatprompt تمامًا مثل @prompt ولكنه يسمح لك بتمرير رسائل الدردشة كقالب بدلاً من موجه نص واحد. يمكن استخدام هذا لتوفير رسالة نظام أو لضغط قليلة على المكان الذي تقدم فيه استجابات مثال لتوجيه إخراج النموذج. سيتم ملء حقول التنسيق التي تدل عليها الأقواس المجعد {example} في جميع الرسائل (باستثناء FunctionResultMessage ).
from magentic import chatprompt , AssistantMessage , SystemMessage , UserMessage
from pydantic import BaseModel
class Quote ( BaseModel ):
quote : str
character : str
@ chatprompt (
SystemMessage ( "You are a movie buff." ),
UserMessage ( "What is your favorite quote from Harry Potter?" ),
AssistantMessage (
Quote (
quote = "It does not do to dwell on dreams and forget to live." ,
character = "Albus Dumbledore" ,
)
),
UserMessage ( "What is your favorite quote from {movie}?" ),
)
def get_movie_quote ( movie : str ) -> Quote : ...
get_movie_quote ( "Iron Man" )
# Quote(quote='I am Iron Man.', character='Tony Stark')انظر الدردشة التي تدفع للمزيد.
يمكن أن تقرر LLM أيضًا استدعاء وظائف. في هذه الحالة ، تُرجع الدالة المزيفة @prompt كائن FunctionCall يمكن استدعاؤه لتنفيذ الوظيفة باستخدام الوسائط التي توفرها LLM.
from typing import Literal
from magentic import prompt , FunctionCall
def search_twitter ( query : str , category : Literal [ "latest" , "people" ]) -> str :
"""Searches Twitter for a query."""
print ( f"Searching Twitter for { query !r } in category { category !r } " )
return "<twitter results>"
def search_youtube ( query : str , channel : str = "all" ) -> str :
"""Searches YouTube for a query."""
print ( f"Searching YouTube for { query !r } in channel { channel !r } " )
return "<youtube results>"
@ prompt (
"Use the appropriate search function to answer: {question}" ,
functions = [ search_twitter , search_youtube ],
)
def perform_search ( question : str ) -> FunctionCall [ str ]: ...
output = perform_search ( "What is the latest news on LLMs?" )
print ( output )
# > FunctionCall(<function search_twitter at 0x10c367d00>, 'LLMs', 'latest')
output ()
# > Searching Twitter for 'Large Language Models news' in category 'latest'
# '<twitter results>'انظر الوظيفة تدعو المزيد.
في بعض الأحيان ، تتطلب LLM إجراء مكالمات وظيفية واحدة أو أكثر لإنشاء إجابة نهائية. سيقوم @prompt_chain Decorator بحل كائنات FunctionCall تلقائيًا وتمرير الإخراج مرة أخرى إلى LLM للمتابعة حتى يتم الوصول إلى الإجابة النهائية.
في المثال التالي ، عندما يتم تسمية describe_weather ، يقوم LLM أولاً باستدعاء وظيفة get_current_weather ، ثم يستخدم نتيجة هذا لصياغة إجابته النهائية التي يتم إرجاعها.
from magentic import prompt_chain
def get_current_weather ( location , unit = "fahrenheit" ):
"""Get the current weather in a given location"""
# Pretend to query an API
return {
"location" : location ,
"temperature" : "72" ,
"unit" : unit ,
"forecast" : [ "sunny" , "windy" ],
}
@ prompt_chain (
"What's the weather like in {city}?" ,
functions = [ get_current_weather ],
)
def describe_weather ( city : str ) -> str : ...
describe_weather ( "Boston" )
# 'The current weather in Boston is 72°F and it is sunny and windy.' يمكن توفير وظائف LLM التي يتم إنشاؤها باستخدام @prompt و @chatprompt و @prompt_chain functions للديكورات الأخرى @prompt / @prompt_chain ، تمامًا مثل وظائف Python العادية. يتيح ذلك وظائف LLM المعقدة بشكل متزايد ، مع السماح باختبار المكونات الفردية وتحسينها في عزلة.
يمكن استخدام فئة StreamedStr (و AsyncStreamedStr ) لدفق إخراج LLM. يتيح لك ذلك معالجة النص أثناء إنشاءه ، بدلاً من تلقي الإخراج بأكمله مرة واحدة.
from magentic import prompt , StreamedStr
@ prompt ( "Tell me about {country}" )
def describe_country ( country : str ) -> StreamedStr : ...
# Print the chunks while they are being received
for chunk in describe_country ( "Brazil" ):
print ( chunk , end = "" )
# 'Brazil, officially known as the Federative Republic of Brazil, is ...' يمكن إنشاء StreamedStr المتعددة في نفس الوقت لدفق مخرجات LLM بشكل متزامن. في المثال أدناه ، يستغرق توليد الوصف لبلدان متعددة نفس الوقت تقريبًا في بلد واحد.
from time import time
countries = [ "Australia" , "Brazil" , "Chile" ]
# Generate the descriptions one at a time
start_time = time ()
for country in countries :
# Converting `StreamedStr` to `str` blocks until the LLM output is fully generated
description = str ( describe_country ( country ))
print ( f" { time () - start_time :.2f } s : { country } - { len ( description ) } chars" )
# 22.72s : Australia - 2130 chars
# 41.63s : Brazil - 1884 chars
# 74.31s : Chile - 2968 chars
# Generate the descriptions concurrently by creating the StreamedStrs at the same time
start_time = time ()
streamed_strs = [ describe_country ( country ) for country in countries ]
for country , streamed_str in zip ( countries , streamed_strs ):
description = str ( streamed_str )
print ( f" { time () - start_time :.2f } s : { country } - { len ( description ) } chars" )
# 22.79s : Australia - 2147 chars
# 23.64s : Brazil - 2202 chars
# 24.67s : Chile - 2186 chars يمكن أيضًا بث المخرجات المهيكلة من LLM باستخدام نظام التعليق Iterable نوع الإرجاع (أو AsyncIterable ). يسمح هذا بمعالجة كل عنصر أثناء إنشاء العنصر التالي.
from collections . abc import Iterable
from time import time
from magentic import prompt
from pydantic import BaseModel
class Superhero ( BaseModel ):
name : str
age : int
power : str
enemies : list [ str ]
@ prompt ( "Create a Superhero team named {name}." )
def create_superhero_team ( name : str ) -> Iterable [ Superhero ]: ...
start_time = time ()
for hero in create_superhero_team ( "The Food Dudes" ):
print ( f" { time () - start_time :.2f } s : { hero } " )
# 2.23s : name='Pizza Man' age=30 power='Can shoot pizza slices from his hands' enemies=['The Hungry Horde', 'The Junk Food Gang']
# 4.03s : name='Captain Carrot' age=35 power='Super strength and agility from eating carrots' enemies=['The Sugar Squad', 'The Greasy Gang']
# 6.05s : name='Ice Cream Girl' age=25 power='Can create ice cream out of thin air' enemies=['The Hot Sauce Squad', 'The Healthy Eaters']انظر البث للمزيد.
يمكن استخدام الوظائف / coroutines غير المتزامنة للاستعلام عن LLM بشكل متزامن. هذا يمكن أن يزيد بشكل كبير من السرعة الإجمالية للجيل ، كما يسمح أيضًا بالشموس غير المتزامن الآخر أثناء الانتظار على إخراج LLM. في المثال أدناه ، تقوم LLM بإنشاء وصف لكل رئيس أمريكي أثناء انتظاره في القائمة التالية. يوضح قياس الأحرف التي تم إنشاؤها في الثانية أن هذا المثال يحقق تسريعًا 7x على المعالجة التسلسلية.
import asyncio
from time import time
from typing import AsyncIterable
from magentic import prompt
@ prompt ( "List ten presidents of the United States" )
async def iter_presidents () -> AsyncIterable [ str ]: ...
@ prompt ( "Tell me more about {topic}" )
async def tell_me_more_about ( topic : str ) -> str : ...
# For each president listed, generate a description concurrently
start_time = time ()
tasks = []
async for president in await iter_presidents ():
# Use asyncio.create_task to schedule the coroutine for execution before awaiting it
# This way descriptions will start being generated while the list of presidents is still being generated
task = asyncio . create_task ( tell_me_more_about ( president ))
tasks . append ( task )
descriptions = await asyncio . gather ( * tasks )
# Measure the characters per second
total_chars = sum ( len ( desc ) for desc in descriptions )
time_elapsed = time () - start_time
print ( total_chars , time_elapsed , total_chars / time_elapsed )
# 24575 28.70 856.07
# Measure the characters per second to describe a single president
start_time = time ()
out = await tell_me_more_about ( "George Washington" )
time_elapsed = time () - start_time
print ( len ( out ), time_elapsed , len ( out ) / time_elapsed )
# 2206 18.72 117.78انظر Asyncio للمزيد.
functions إلى @prompt على وظائف Async/coroutine. عندما يتم استدعاء كائنات FunctionCall المقابلة ، يجب انتظار النتيجة.Annotated لتوفير الأوصاف والبيانات الوصفية الأخرى لمعلمات الوظيفة. راجع وثائق Pydantic حول استخدام Field لوصف وسيطات الوظائف.@prompt و @prompt_chain أيضًا حجة model . يمكنك تمرير مثيل من OpenaiChatModel لاستخدام GPT4 أو تكوين درجة حرارة مختلفة. انظر أدناه.@prompt من خلال اتباع دفتر الملاحظات على سبيل المثال للحصول على DataFrame Pandas. يدعم Magentic متعددة "الخلفية" (مزودي LLM). هذه هي
openai : الواجهة الخلفية الافتراضية التي تستخدم حزمة openai Python. يدعم جميع ميزات Magentic. from magentic import OpenaiChatModelanthropic : يستخدم حزمة بيثون anthropic . يدعم جميع ميزات Magentic ، ومع ذلك يتم استلام استجابات البث حاليًا في وقت واحد. pip install " magentic[anthropic] " from magentic . chat_model . anthropic_chat_model import AnthropicChatModellitellm : يستخدم حزمة litellm Python لتمكين الاستعلام عن LLMs من العديد من مقدمي الخدمات المختلفين. ملاحظة: قد لا تدعم بعض النماذج جميع ميزات magentic EG الدالة/الإخراج المهيكلة والتدفق. pip install " magentic[litellm] " from magentic . chat_model . litellm_chat_model import LitellmChatModelmistral : يستخدم حزمة openai Python مع بعض التعديلات الصغيرة لجعل استعلامات API متوافقة مع واجهة برمجة تطبيقات Mistral. يدعم جميع ميزات Magentic ، ولكن لا يتم بث مكالمات الأدوات (بما في ذلك المخرجات المهيكلة) حتى يتم استلامها في وقت واحد. ملاحظة: قد يتحول نسخة مستقبلية من Magentic إلى استخدام حزمة Python mistral . from magentic . chat_model . mistral_chat_model import MistralChatModel يمكن تكوين الواجهة الخلفية و LLM ( ChatModel ) المستخدمة من قبل magentic بعدة طرق. عندما يتم استدعاء وظيفة أرجواني ، يتبع ChatModel لاستخدامه ترتيب التفضيل هذا
ChatModel كوسيطة model إلى Magentic Decoratorwith MyChatModel:ChatModel العالمية التي تم إنشاؤها من متغيرات البيئة والإعدادات الافتراضية في src/magentic/settings.py from magentic import OpenaiChatModel , prompt
from magentic . chat_model . litellm_chat_model import LitellmChatModel
@ prompt ( "Say hello" )
def say_hello () -> str : ...
@ prompt (
"Say hello" ,
model = LitellmChatModel ( "ollama_chat/llama3" ),
)
def say_hello_litellm () -> str : ...
say_hello () # Uses env vars or default settings
with OpenaiChatModel ( "gpt-3.5-turbo" , temperature = 1 ):
say_hello () # Uses openai with gpt-3.5-turbo and temperature=1 due to context manager
say_hello_litellm () # Uses litellm with ollama_chat/llama3 because explicitly configuredيمكن تعيين متغيرات البيئة التالية.
| متغير البيئة | وصف | مثال |
|---|---|---|
| Magentic_backend | الحزمة لاستخدامها كخلفية LLM | الإنسان / openai / litellm |
| magentic_anthropic_model | نموذج الإنسان | كلود-3-هايكو -20240307 |
| magentic_anthropic_api_key | مفتاح واجهة برمجة تطبيقات الأنثروبور لاستخدامه من قبل Magentic | SK -.... |
| magentic_anthropic_base_url | عنوان URL الأساسي لواجهة برمجة تطبيقات متوافقة مع الإنسان | http: // localhost: 8080 |
| magentic_anthropic_max_tokens | الحد الأقصى لعدد الرموز المولدة | 1024 |
| magentic_anthropic_temperature | درجة حرارة | 0.5 |
| magentic_litellm_model | نموذج Litellm | كلود -2 |
| magentic_litellm_api_base | عنوان URL الأساسي للاستعلام | http: // localhost: 11434 |
| magentic_litellm_max_tokens | Litellm Max عدد الرموز المولدة | 1024 |
| magentic_litellm_temperature | درجة حرارة litellm | 0.5 |
| magentic_mistral_model | نموذج سوء | ميسترا لارج لاتست |
| magentic_mistral_api_key | مفتاح واجهة برمجة تطبيقات Mistral لاستخدامه من قبل Magentic | xeg ... |
| magentic_mistral_base_url | عنوان URL الأساسي لواجهة برمجة التطبيقات المتوافقة مع سوء المدى | http: // localhost: 8080 |
| magentic_mistral_max_tokens | الحد الأقصى لعدد الرموز المولدة | 1024 |
| magentic_mistral_seed | بذرة لأخذ العينات الحتمية | 42 |
| magentic_mistral_temperature | درجة حرارة | 0.5 |
| magentic_openai_model | نموذج Openai | GPT-4 |
| magentic_openai_api_key | مفتاح Openai API لاستخدامه من قبل Magentic | SK -.... |
| magentic_openai_api_type | الخيارات المسموح بها: "Openai" ، "Azure" | أزور |
| magentic_openai_base_url | عنوان URL الأساسي لواجهة برمجة التطبيقات المتوافقة مع OpenAI | http: // localhost: 8080 |
| magentic_openai_max_tokens | Openai Max عدد الرموز المولدة | 1024 |
| magentic_openai_seed | بذرة لأخذ العينات الحتمية | 42 |
| magentic_openai_temperature | درجة حرارة Openai | 0.5 |
عند استخدام الواجهة الخلفية openai ، قم بتعيين متغير بيئة MAGENTIC_OPENAI_BASE_URL أو باستخدام OpenaiChatModel(..., base_url="http://localhost:8080") في الكود يتيح لك استخدام magentic مع أي واجهة برمجة تطبيقات على eg eg azure openai ، litellm Openai Proxy Server ، Localai. لاحظ أنه إذا لم تدعم API مكالمات الأدوات ، فلن تتمكن من إنشاء وظائف سريعة تعيد كائنات Python ، ولكن ستعمل ميزات magentic الأخرى.
لاستخدام Azure مع الواجهة الخلفية Openai ، ستحتاج إلى تعيين متغير بيئة MAGENTIC_OPENAI_API_TYPE إلى "Azure" أو استخدام OpenaiChatModel(..., api_type="azure") ، وكذلك تعيين متغيرات البيئة التي تحتاجها حزمة Openai للوصول إلى Azure. انظر https://github.com/openai/openai-python#microsoft-azure-openai
سوف يرفع العديد من المداخن من النوع تحذيرات أو أخطاء للوظائف مع ديكور @prompt بسبب عدم وجود جسم أو قيمة إرجاع. هناك عدة طرق للتعامل مع هذه.
empty-body . # pyproject.toml
[ tool . mypy ]
disable_error_code = [ " empty-body " ]... (هذا لا يرضي mypy) أو raise . @ prompt ( "Choose a color" )
def random_color () -> str : ...# type: ignore[empty-body] في كل وظيفة. في هذه الحالة ، يمكنك إضافة docstring بدلاً من ... @ prompt ( "Choose a color" )
def random_color () -> str : # type: ignore[empty-body]
"""Returns a random color."""