대형 언어 모델을 파이썬 코드에 쉽게 통합하십시오. @prompt 및 @chatprompt 데코레이터를 사용하여 LLM에서 구조화 된 출력을 반환하는 기능을 만듭니다. LLM 쿼리 및 기능 호출을 일반 파이썬 코드와 혼합하여 복잡한 로직을 만듭니다.
FunctionCall 통한 호출 및 ParallelFunctionCall 통한 반환 유형입니다.async def 사용하기 만하면됩니다.pip install magentic또는 UV 사용
uv add magentic OPENAI_API_KEY 환경 변수를 설정하여 OpenAI API 키를 구성하십시오. 다른 LLM 제공 업체를 구성하려면 자세한 내용은 구성을 참조하십시오.
@prompt 데코레이터를 사용하면 LLM (Lange Language Model) 프롬프트의 템플릿을 파이썬 기능으로 정의 할 수 있습니다. 이 함수가 호출되면 인수가 템플릿에 삽입되면이 프롬프트는 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'])자세한 내용은 구조화 된 출력을 참조하십시오.
@chatprompt 데코레이터는 @prompt 와 같이 작동하지만 단일 텍스트 프롬프트가 아닌 템플릿으로 채팅 메시지를 전달할 수 있습니다. 이것은 시스템 메시지를 제공하는 데 사용하거나 모델의 출력을 안내하기위한 예제 응답을 제공하는 위치에 대한 소수의 프롬프트에 사용될 수 있습니다. Curly Braces {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 -decorated 함수는 LLM에서 제공 한 인수를 사용하여 함수를 실행하도록 호출 할 수있는 FunctionCall 객체를 반환합니다.
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 데코레이터는 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.' @prompt , @chatprompt 및 @prompt_chain 사용하여 생성 된 llm 구동 함수는 일반 파이썬 함수와 마찬가지로 다른 @prompt / @prompt_chain 데코레이터의 functions 로 제공 될 수 있습니다. 이를 통해 점점 더 복잡한 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 ...' LLM 출력을 동시에 스트리밍하기 위해 다중 StreamedStr 동시에 생성 할 수 있습니다. 아래의 예에서, 여러 국가에 대한 설명을 생성하는 데 단일 국가와 거의 같은 시간이 걸립니다.
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 리턴 유형 주석 Iterable (또는 AsyncIterable )을 사용하여 구조화 된 출력을 LLM에서 스트리밍 할 수도 있습니다. 이를 통해 다음 항목은 다음 항목을 생성하는 동안 각 항목을 처리 할 수 있습니다.
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']자세한 내용은 스트리밍을 참조하십시오.
비동기 기능 / 코 루틴을 사용하여 동시에 LLM을 쿼리 할 수 있습니다. 이로 인해 전체 생성 속도가 크게 높아지고 LLM 출력을 기다리는 동안 다른 비동기 코드가 실행될 수 있습니다. 아래 예에서 LLM은 각 미국 대통령에 대한 설명을 생성하는 동안 목록의 다음 단계를 기다리고 있습니다. 초당 생성 된 문자를 측정하면이 예제는 직렬 처리에 대한 7 배 속도를 달성 함을 보여줍니다.
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를 참조하십시오.
@prompt 에 대한 functions 인수에는 Async/coroutine 함수가 포함될 수 있습니다. 해당 FunctionCall 객체를 호출하는 경우 결과를 기다려야합니다.Annotated 유형 주석은 기능 매개 변수에 대한 설명 및 기타 메타 데이터를 제공하는 데 사용될 수 있습니다. 기능 인수를 설명하기 위해 Field 사용에 대한 Pydantic 문서를 참조하십시오.@prompt 및 @prompt_chain 데코레이터도 model 인수를 수락합니다. OpenaiChatModel 인스턴스를 전달하여 GPT4를 사용하거나 다른 온도를 구성 할 수 있습니다. 아래를 참조하십시오.@prompt 기능의 반환 유형 주석으로 사용할 다른 유형을 등록하십시오. 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 패키지를 사용하여 다양한 제공 업체의 LLM 쿼리를 활성화합니다. 참고 : 일부 모델은 magentic EG 기능 호출/구조화 된 출력 및 스트리밍의 모든 기능을 지원하지 않을 수 있습니다. pip install " magentic[litellm] " from magentic . chat_model . litellm_chat_model import LitellmChatModelmistral : openai Python 패키지를 사용하여 약간의 수정을 사용하여 API 쿼리를 Mistral API와 호환시킵니다. Magentic의 모든 기능을 지원하지만 공구 통화 (구조적 출력 포함)는 스트리밍되지 않으므로 한 번에 수신됩니다. 참고 : 미래 버전의 Magentic은 mistral Python 패키지 사용으로 전환 할 수 있습니다. from magentic . chat_model . mistral_chat_model import MistralChatModel magentic 이 사용하는 백엔드 및 LLM ( ChatModel )은 여러 가지 방법으로 구성 할 수 있습니다. Magentic 함수가 호출되면 사용하는 ChatModel 선호도 순서를 따릅니다.
model 인수로 제공된 ChatModel 인스턴스with MyChatModel:ChatModel 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 백엔드로 사용할 패키지 | 인류 / 개방형 / 리텔 |
| magentic_anthropic_model | 인류 모델 | Claude-3-Haiku-20240307 |
| magentic_anthropic_api_key | Magentic에서 사용할 무인 API 키 | SK -... |
| magentic_anthropic_base_url | 의인성 호환 API의 기본 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 최대 생성 된 토큰 수 | 1024 |
| magentic_litellm_temperature | 리텔 온도 | 0.5 |
| magentic_mistral_model | 미스트랄 모델 | 불신-초대형 |
| magentic_mistral_api_key | Magentic에서 사용할 Mistral API 키 | Xeg ... |
| magentic_mistral_base_url | Mistral 호환 API의 기본 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 | Magentic에서 사용할 Openai API 키 | SK -... |
| magentic_openai_api_type | 허용 옵션 : "Openai", "Azure" | 하늘빛 |
| magentic_openai_base_url | OpenAi 호환 API의 기본 URL | http : // localhost : 8080 |
| magentic_openai_max_tokens | 생성 된 토큰의 Openai 최대 수 | 1024 |
| magentic_openai_seed | 결정 샘플링을위한 종자 | 42 |
| magentic_openai_temperature | 개방 온도 | 0.5 |
openai 백엔드를 사용할 때, MAGENTIC_OPENAI_BASE_URL 환경 변수를 설정하거나 OpenaiChatModel(..., base_url="http://localhost:8080") 사용하여 OpenAi 호환 API EG Azure OpenAI Service, Litellm과 함께 magentic 사용할 수 있습니다. Openai 프록시 서버, localai. API가 도구 통화를 지원하지 않으면 Python 객체를 반환하는 프롬프트 기능을 만들 수는 없지만 magentic 의 다른 기능은 여전히 작동합니다.
OpenAi 백엔드와 함께 Azure를 사용하려면 MAGENTIC_OPENAI_API_TYPE 환경 변수를 "Azure"로 설정하거나 OpenaiChatModel(..., api_type="azure") 사용하고 OpenAI 패키지가 필요한 환경 변수를 Access Azure로 설정해야합니다. https://github.com/openai/openai/openai-python#microsoft-azure-openai를 참조하십시오
많은 유형의 체커는 본문이나 반환 값이없는 함수로 인해 @prompt 데코레이터의 기능에 대한 경고 나 오류를 제기합니다. 이것들을 다루는 방법에는 몇 가지가 있습니다.
empty-body 비활성화하여 MyPy에서. # pyproject.toml
[ tool . mypy ]
disable_error_code = [ " empty-body " ]... (이것은 mypy를 만족시키지 않습니다) 또는 raise . @ prompt ( "Choose a color" )
def random_color () -> str : ...# type: ignore[empty-body] . 이 경우 ... 대신 문서를 추가 할 수 있습니다. @ prompt ( "Choose a color" )
def random_color () -> str : # type: ignore[empty-body]
"""Returns a random color."""