Mudah mengintegrasikan model bahasa besar ke dalam kode python Anda. Cukup gunakan dekorator @prompt dan @chatprompt untuk membuat fungsi yang mengembalikan output terstruktur dari LLM. Campurkan kueri LLM dan panggilan fungsi dengan kode python biasa untuk membuat logika yang kompleks.
FunctionCall dan ParallelFunctionCall return tipe.async def saat mendefinisikan fungsi magentik.pip install magenticatau menggunakan UV
uv add magentic Konfigurasikan tombol API OpenAI Anda dengan mengatur variabel lingkungan OPENAI_API_KEY . Untuk mengonfigurasi penyedia LLM yang berbeda lihat konfigurasi untuk lebih.
Dekorator @prompt memungkinkan Anda untuk mendefinisikan templat untuk prompt model bahasa besar (LLM) sebagai fungsi Python. Ketika fungsi ini dipanggil, argumen dimasukkan ke dalam templat, maka prompt ini dikirim ke LLM yang menghasilkan output fungsi.
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?" Dekorator @prompt akan menghormati anotasi tipe pengembalian dari fungsi yang dihiasi. Ini dapat berupa jenis apa pun yang didukung oleh Pydantic termasuk model 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'])Lihat output terstruktur untuk lebih.
Dekorator @chatprompt berfungsi seperti @prompt tetapi memungkinkan Anda untuk menyampaikan pesan obrolan sebagai templat daripada satu teks. Ini dapat digunakan untuk menyediakan pesan sistem atau untuk meminta beberapa pengambilan gambar di mana Anda memberikan respons contoh untuk memandu output model. Bidang format yang dilambangkan dengan kawat gigi keriting {example} akan diisi dalam semua pesan (kecuali 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')Lihat CHAT yang diminta untuk lebih.
LLM juga dapat memutuskan untuk memanggil fungsi. Dalam hal ini fungsi @prompt -Decorated mengembalikan objek FunctionCall yang dapat dipanggil untuk menjalankan fungsi menggunakan argumen yang disediakan oleh 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>'Lihat fungsi yang meminta lebih.
Terkadang LLM membutuhkan satu atau lebih panggilan fungsi atau lebih untuk menghasilkan jawaban akhir. Dekorator @prompt_chain akan menyelesaikan objek FunctionCall secara otomatis dan meneruskan output kembali ke LLM untuk melanjutkan sampai jawaban akhir tercapai.
Dalam contoh berikut, ketika describe_weather disebut LLM pertama memanggil fungsi get_current_weather , kemudian menggunakan hasil ini untuk merumuskan jawaban terakhirnya yang akan dikembalikan.
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.' Fungsi bertenaga LLM dibuat menggunakan @prompt , @chatprompt dan @prompt_chain dapat disuplai sebagai functions untuk dekorator @prompt / @prompt_chain lainnya, seperti fungsi python biasa. Ini memungkinkan fungsionalitas bertenaga LLM yang semakin kompleks, sambil memungkinkan komponen individu untuk diuji dan ditingkatkan secara terpisah.
Kelas StreamedStr (dan AsyncStreamedStr ) dapat digunakan untuk mengalirkan output LLM. Ini memungkinkan Anda untuk memproses teks saat sedang dihasilkan, daripada menerima seluruh output sekaligus.
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 ...' Beberapa StreamedStr dapat dibuat pada saat yang sama untuk melakukan stream output LLM secara bersamaan. Dalam contoh di bawah ini, menghasilkan deskripsi untuk beberapa negara membutuhkan waktu yang kira -kira sama dengan satu negara.
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 Output terstruktur juga dapat dialirkan dari LLM dengan menggunakan anotasi tipe pengembalian Iterable (atau AsyncIterable ). Ini memungkinkan setiap item untuk diproses saat yang berikutnya sedang dihasilkan.
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']Lihat streaming untuk lebih.
Fungsi / coroutine asinkron dapat digunakan untuk secara bersamaan menanyakan LLM. Ini dapat sangat meningkatkan kecepatan generasi secara keseluruhan, dan juga memungkinkan kode asinkron lainnya berjalan sambil menunggu output LLM. Dalam contoh di bawah ini, LLM menghasilkan deskripsi untuk setiap presiden AS saat menunggu yang berikutnya dalam daftar. Mengukur karakter yang dihasilkan per detik menunjukkan bahwa contoh ini mencapai speedup 7x atas pemrosesan serial.
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.78Lihat Asyncio untuk lebih.
functions untuk @prompt dapat berisi fungsi async/coroutine. Ketika objek FunctionCall yang sesuai disebut hasil harus ditunggu.Annotated dapat digunakan untuk memberikan deskripsi dan metadata lainnya untuk parameter fungsi. Lihat dokumentasi Pydantic tentang penggunaan Field untuk menggambarkan argumen fungsi.@prompt dan @prompt_chain juga menerima argumen model . Anda dapat melewati instance OpenaiChatModel untuk menggunakan GPT4 atau mengkonfigurasi suhu yang berbeda. Lihat di bawah.@prompt dengan mengikuti contoh notebook untuk dataframe pandas. Magentic mendukung beberapa "backends" (penyedia LLM). Ini
openai : Backend default yang menggunakan paket openai Python. Mendukung semua fitur Magentic. from magentic import OpenaiChatModelanthropic : Menggunakan paket python anthropic . Mendukung semua fitur Magentic, namun respons streaming saat ini diterima sekaligus. pip install " magentic[anthropic] " from magentic . chat_model . anthropic_chat_model import AnthropicChatModellitellm : Menggunakan Paket Python litellm untuk memungkinkan permintaan LLM dari banyak penyedia yang berbeda. CATATAN: Beberapa model mungkin tidak mendukung semua fitur fungsi magentic misalnya panggilan/output dan streaming terstruktur. pip install " magentic[litellm] " from magentic . chat_model . litellm_chat_model import LitellmChatModelmistral : Menggunakan paket Python openai dengan beberapa modifikasi kecil untuk membuat kueri API kompatibel dengan API Mistral. Mendukung semua fitur magentik, namun panggilan alat (termasuk output terstruktur) tidak dialirkan sehingga diterima sekaligus. CATATAN: Versi Magentic di masa depan mungkin beralih untuk menggunakan paket Python mistral . from magentic . chat_model . mistral_chat_model import MistralChatModel Backend dan LLM ( ChatModel ) yang digunakan oleh magentic dapat dikonfigurasi dalam beberapa cara. Ketika fungsi magentik dipanggil, ChatModel untuk digunakan mengikuti urutan preferensi ini
ChatModel yang disediakan sebagai argumen model untuk dekorator magentikwith MyChatModel:ChatModel dibuat dari variabel lingkungan dan pengaturan default di 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 configuredVariabel lingkungan berikut dapat diatur.
| Variabel Lingkungan | Keterangan | Contoh |
|---|---|---|
| Magentic_backend | Paket untuk digunakan sebagai backend LLM | Antropik / openai / litellm |
| Magentic_anthropic_model | Model antropik | Claude-3-haiku-20240307 |
| Magentic_anthropic_api_key | Kunci API Antropik untuk digunakan oleh Magentic | SK -... |
| Magentic_anthropic_base_url | URL dasar untuk API yang kompatibel dengan antropik | http: // localhost: 8080 |
| Magentic_anthropic_max_tokens | Jumlah maksimum dari token yang dihasilkan | 1024 |
| Magentic_anthropic_temperature | Suhu | 0,5 |
| Magentic_litellm_model | Model litellm | Claude-2 |
| Magentic_litellm_api_base | URL dasar untuk meminta | http: // localhost: 11434 |
| Magentic_litellm_max_tokens | Litellm Max Jumlah token yang dihasilkan | 1024 |
| Magentic_litellm_temperature | Suhu litellm | 0,5 |
| Magentic_mistral_model | Model Mistral | Mistral-Large-Latest |
| Magentic_mistral_api_key | Kunci API Mistral untuk digunakan oleh Magentic | Xeg ... |
| Magentic_mistral_base_url | URL dasar untuk API yang kompatibel | http: // localhost: 8080 |
| Magentic_mistral_max_tokens | Jumlah maksimum dari token yang dihasilkan | 1024 |
| Magentic_mistral_seed | Benih untuk pengambilan sampel deterministik | 42 |
| Magentic_mistral_temperature | Suhu | 0,5 |
| Magentic_openai_model | Model Openai | GPT-4 |
| Magentic_openai_api_key | Kunci API Openai untuk digunakan oleh Magentic | SK -... |
| Magentic_openai_api_type | Opsi yang Diizinkan: "Openai", "Azure" | biru langit |
| Magentic_openai_base_url | URL dasar untuk API yang kompatibel dengan openai | http: // localhost: 8080 |
| Magentic_openai_max_tokens | Openai Max Jumlah token yang dihasilkan | 1024 |
| Magentic_openai_seed | Benih untuk pengambilan sampel deterministik | 42 |
| Magentic_openai_temperature | Suhu openai | 0,5 |
When using the openai backend, setting the MAGENTIC_OPENAI_BASE_URL environment variable or using OpenaiChatModel(..., base_url="http://localhost:8080") in code allows you to use magentic with any OpenAI-compatible API eg Azure OpenAI Service, LiteLLM Openai Proxy Server, Localai. Perhatikan bahwa jika API tidak mendukung panggilan alat maka Anda tidak akan dapat membuat fungsi yang cepat yang mengembalikan objek Python, tetapi fitur lain dari magentic masih akan berfungsi.
Untuk menggunakan Azure dengan backend openai, Anda perlu mengatur variabel lingkungan MAGENTIC_OPENAI_API_TYPE ke "azure" atau menggunakan OpenaiChatModel(..., api_type="azure") , dan juga mengatur variabel lingkungan yang dibutuhkan oleh paket OpenAI untuk mengakses Azure. Lihat https://github.com/openai/openai-python#microsoft-azure-openai
Banyak pemeriksa jenis akan meningkatkan peringatan atau kesalahan untuk fungsi dengan dekorator @prompt karena fungsi tidak memiliki tubuh atau nilai pengembalian. Ada beberapa cara untuk menangani ini.
empty-body . # pyproject.toml
[ tool . mypy ]
disable_error_code = [ " empty-body " ]... (ini tidak memuaskan mypy) atau raise . @ prompt ( "Choose a color" )
def random_color () -> str : ...# type: ignore[empty-body] pada setiap fungsi. Dalam hal ini Anda dapat menambahkan docString bukannya ... @ prompt ( "Choose a color" )
def random_color () -> str : # type: ignore[empty-body]
"""Returns a random color."""