Simplifique sua vida usando o PromptingTools.jl, o pacote Julia que simplifica a interação com grandes modelos de linguagem.
PromptingTools.jl não se destina a construir sistemas em larga escala. É para ser a ferramenta preferida em seu ambiente global que economizará 20 minutos todos os dias!
Dica
Pule para os documentos
@ai_str e modelos fáceis Introdução ao PromptingTools.jl é tão fácil quanto importar o pacote e usar a macro @ai_str para suas perguntas.
NOTA: Você precisará definir sua chave da API do OpenAI como uma variável de ambiente antes de usar o PromptingTools.jl (consulte a seção Criação da API do OpenAI abaixo).
Após a introdução do faturamento pré -pago, você precisará comprar alguns créditos para começar (mínimo de US $ 5). Para um início rápido, basta defini-lo via ENV["OPENAI_API_KEY"] = "your-api-key"
Instale o PromptingTools:
using Pkg
Pkg . add ( " PromptingTools " )E estamos prontos para ir!
using PromptingTools
ai " What is the capital of France? "
# [ Info: Tokens: 31 @ Cost: $0.0 in 1.5 seconds --> Be in control of your spending!
# AIMessage("The capital of France is Paris.") O objeto retornado é um invólucro de luz com uma mensagem gerada no campo :content (por exemplo, ans.content ) para processamento adicional a jusante.
Dica
Se você quiser responder à mensagem anterior ou simplesmente continuar a conversa, use @ai!_str (observe o bang ! ):
ai! " And what is the population of it? "Você pode injetar facilmente quaisquer variáveis com interpolação de string:
country = " Spain "
ai " What is the capital of $ (country)? "
# [ Info: Tokens: 32 @ Cost: $0.0001 in 0.5 seconds
# AIMessage("The capital of Spain is Madrid.") Dica
Use bandeiras pós-cordas para selecionar o modelo a ser chamado, por exemplo, ai"What is the capital of France?"gpt4 (use gpt4t para o novo modelo GPT-4 Turbo). Ótimo para essas perguntas mais difíceis!
Para modelos de prompt mais complexos, você pode usar o modelador no estilo do guidão e fornecer variáveis como argumentos de palavras-chave:
msg = aigenerate ( " What is the capital of {{country}}? Is the population larger than {{population}}? " , country = " Spain " , population = " 1M " )
# [ Info: Tokens: 74 @ Cost: $0.0001 in 1.3 seconds
# AIMessage("The capital of Spain is Madrid. And yes, the population of Madrid is larger than 1 million. As of 2020, the estimated population of Madrid is around 3.3 million people.") Dica
Use asyncmap para executar várias tarefas movidas a IA simultaneamente.
Dica
Se você usa modelos lentos (como o GPT -4), poderá usar a versão assíncrona de @ai_str -> @aai_str para evitar bloquear o repl, por exemplo, aai"Say hi but slowly!"gpt4 (da mesma forma @ai!_str -> @aai!_str para conversas com várias contas).
Para exemplos mais práticos, consulte os examples/ pasta e os exemplos avançados abaixo.
@ai_str e modelos fáceisai* funciona Visão geralairetry!aigenerate ( api_kwargs )A engenharia imediata não é rápida nem fácil. Além disso, diferentes modelos e seus tunes finos podem exigir diferentes formatos e truques, ou talvez as informações com as quais você trabalha exija modelos especiais para serem usados. PromptingTools.jl deve unificar os avisos para diferentes back -ends e tornar as tarefas comuns (como prompts modelo) o mais simples possível.
Alguns recursos:
aigenerate : simplifique modelos de prompt com guidão (por exemplo, {{variable}} ) e argumentos de palavras -chave@ai_str String Macro : salvar teclado com uma macro de string para prompts simplesai... para uma melhor descobertaai* funciona Visão geral Funções dignas de nota: aigenerate , aiembed , aiclassify , aiextract , aiscan , aiimage , aitemplates
Todas as funções ai* têm a mesma estrutura básica:
ai*(<optional schema>,<prompt or conversation>; <optional keyword arguments>) ,
Mas eles diferem em propósito:
aigenerate é a função de uso geral para gerar qualquer resposta de texto com LLMS, ou seja, retorna AIMessage com o campo :content que contém o texto gerado (por exemplo, ans.content isa AbstractString )aiembed foi projetado para extrair incorporações da resposta do modelo de IA, ou seja, retorna DataMessage com campo :content que contém as incorporações (por exemplo, ans.content isa AbstractArray )aiextract foi projetado para extrair dados estruturados da resposta do modelo de IA e devolvê -los como uma estrutura de Julia (por exemplo, se fornecermos return_type=Food , obtemos ans.content isa Food ). Você precisa definir o tipo de retorno primeiro e, em seguida, fornecê -lo como um argumento de palavra -chave.aitools foi projetado para fluxos de trabalho Agentic com uma mistura de chamadas de ferramentas e entradas do usuário. Pode funcionar com funções simples e executá -las.aiclassify foi projetado para classificar o texto de entrada (ou simplesmente responder dentro) de um conjunto de choices discretas fornecidas pelo usuário. Pode ser muito útil como juiz LLM ou roteador para sistemas de pano, pois usa o "truque do viés de logit" e gera exatamente 1 token. Ele retorna AIMessage com o campo :content , mas o :content pode ser apenas uma das choices fornecidas (por exemplo, ans.content in choices )aiscan é para trabalhar com imagens e modelos habilitados para visão (como entrada), mas retorna AIMessage com o campo :content que contém o texto gerado (por exemplo, ans.content isa AbstractString ) semelhante ao aigenerate .aiimage é para gerar imagens (por exemplo, com o Openai Dall-e 3). Ele retorna um DataMessage , onde o campo :content pode conter o URL para baixar a imagem ou a imagem codificada por Base64, dependendo da Kwarg api_kwargs.response_format fornecida pelo usuário.aitemplates é uma função auxiliar para descobrir modelos disponíveis e ver seus detalhes (por exemplo, aitemplates("some keyword") ou aitemplates(:AssistantAsk) ) Se você está usando um model conhecido, não precisará fornecer um schema (o primeiro argumento).
Os argumentos opcionais da palavra -chave em ai* tendem a ser:
model::String - Qual modelo você deseja usarverbose::Bool - se você foi ver os registros de informações em torno dos custos de IAreturn_all::Bool - se você deseja toda a conversa ou apenas a resposta da IA (ou seja, se você deseja incluir suas entradas/prompt na saída)api_kwargs::NamedTuple para o modelo, por exemplo, temperature=0.0 para não ser criativo (e possui uma saída mais semelhante em cada execução)http_kwargs::NamedTuple - parâmetros para o pacote http.jl, por exemplo, readtimeout = 120 para tempo limite em 120 segundos se nenhuma resposta foi recebida.Experimental: Agenttools
Além da lista acima das funções ai* , você também pode usar as contrapartes "preguiçosas" dessas funções do módulo do Experimental AgentTools.
using PromptingTools . Experimental . AgentTools Por exemplo, AIGenerate() criará uma instância preguiçosa de aigenerate . É uma instância de AICall com aigenerate como sua função de IA. Ele usa exatamente os mesmos argumentos e argumentos de palavras -chave que aigenerate (consulte ?aigenerate para obter detalhes).
"Lazy" refere -se ao fato de que não gera nenhuma saída quando instanciada (somente quando run! é chamada).
Ou dito de maneira diferente, a estrutura AICall e todos os seus sabores ( AIGenerate , ...) são projetados para facilitar um modelo de execução diferido (avaliação preguiçosa) para funções de IA que interagem com um modelo de aprendizado de idiomas (LLM). Ele armazena as informações necessárias para uma chamada de IA e executa a função de IA subjacente apenas quando fornecida com um UserMessage ou quando a run! o método é aplicado. Isso nos permite lembrar as entradas do usuário e acionar a chamada LLM repetidamente, se necessário, o que permite a fixação automática (consulte ?airetry! ).
Se você deseja um poderoso fluxo de trabalho de fixação automática, pode usar airetry! , que aproveita a pesquisa de árvores Monte-Carlo para escolher a trajetória ideal da conversa com base em seus requisitos.
Experimental: Ragtools
Por fim, fornecemos um conjunto de ferramentas para criar aplicativos de pano (recuperar, responder, gerar).
Pode ser tão simples quanto duas chamadas: build_index e airag (recuperar, responder, gerar).
Se você usar uma impressão bonita com PromptingTools.pprint , destacamos o texto gerado versus o texto provavelmente proveniente do contexto e pontuamos o quão fortemente a resposta gerada é suportada pelo contexto. Além disso, anotamos cada um pedaço gerado com uma referência a qual documento de origem provavelmente veio (incluindo a pontuação de confiança entre 0 e 1).
A pesquisa do Google é ótima, mas é uma mudança de contexto. Você geralmente precisa abrir algumas páginas e ler a discussão para encontrar a resposta necessária. O mesmo com o site do ChatGPT.
Imagine que você está no vscode, editando seu arquivo .gitignore . Como ignoro um arquivo em todas as subpastas novamente?
Tudo o que você precisa fazer é digitar: aai"What to write in .gitignore to ignore file XYZ in any folder or subfolder?"
Com aai"" (em oposição à ai"" ), fazemos uma chamada não bloqueada ao LLM para não impedir que você continue seu trabalho. Quando a resposta estiver pronta, registramos -a do fundo:
[ Info: Tokens: 102 @ Cost: $0.0002 in 2.7 seconds ┌ Info: AIMessage> To ignore a file called "XYZ" in any folder or subfolder, you can add the following line to your .gitignore file: │ │
│ **/XYZ ││ └ This pattern uses the double asterisk (**) to match any folder or subfolder, and then specifies the name of the file you want to ignorar.
Você provavelmente salvou 3-5 minutos nesta tarefa e provavelmente mais de 5 a 10 minutos, devido à chave/distração de contexto que você evitou. É uma pequena vitória, mas aumenta rapidamente.
Você pode usar a função aigenerate para substituir as variáveis do guidão (por exemplo, {{name}} ) via argumentos de palavras -chave.
msg = aigenerate ( " Say hello to {{name}}! " , name = " World " ) Os avisos mais complexos são efetivamente uma conversa (um conjunto de mensagens), onde você pode ter mensagens de três entidades: Sistema, Usuário, AiasSistant. Fornecemos os tipos correspondentes para cada um deles: SystemMessage , UserMessage , AIMessage .
using PromptingTools : SystemMessage, UserMessage
conversation = [
SystemMessage ( " You're master Yoda from Star Wars trying to help the user become a Jedi. " ),
UserMessage ( " I have feelings for my {{object}}. What should I do? " )]
msg = aigenerate (conversation; object = " old iPhone " )Aimessage ("Ah, um dilema, você tem. O apego emocional pode obscurecer seu caminho para se tornar um Jedi. Para ser anexado a bens materiais, você não deve. O iPhone é apenas uma ferramenta, nada mais. Deixe, você deve.
Procure desapego, jovem Padawan. Refletir sobre a impermanência de todas as coisas. Aprecie as memórias que lhe deu e se separa com gratidão. Na sua ausência, encontre novas experiências para crescer e se tornar uma com a força. Somente então, um verdadeiro Jedi, você se tornará. ")
Você também pode usá -lo para criar conversas, por exemplo,
new_conversation = vcat (conversation ... ,msg, UserMessage ( " Thank you, master Yoda! Do you have {{object}} to know what it feels like? " ))
aigenerate (new_conversation; object = " old iPhone " )Aimessage ("Hmm, possui um iPhone antigo, não tenho. Mas experimento com anexos, eu tenho. Destacamento, aprendi. Verdadeiro poder e liberdade, traz ...")
Com o LLMS, a qualidade / robustez de seus resultados depende da qualidade de seus avisos. Mas escrever avisos é difícil! É por isso que oferecemos um sistema de modelos para economizar tempo e esforço.
Para usar um modelo específico (por exemplo, `` para perguntar a uma língua Julia):
msg = aigenerate ( :JuliaExpertAsk ; ask = " How do I add packages? " ) O acima é equivalente a uma versão mais detalhada que usa explicitamente o despacho no AITemplate :
msg = aigenerate ( AITemplate ( :JuliaExpertAsk ); ask = " How do I add packages? " ) Encontre modelos disponíveis com aitemplates :
tmps = aitemplates ( " JuliaExpertAsk " )
# Will surface one specific template
# 1-element Vector{AITemplateMetadata}:
# PromptingTools.AITemplateMetadata
# name: Symbol JuliaExpertAsk
# description: String "For asking questions about Julia language. Placeholders: `ask`"
# version: String "1"
# wordcount: Int64 237
# variables: Array{Symbol}((1,))
# system_preview: String "You are a world-class Julia language programmer with the knowledge of the latest syntax. Your commun"
# user_preview: String "# Questionnn{{ask}}"
# source: String ""O exposto acima oferece uma boa idéia do que é o modelo, do que os espaços reservados disponíveis e quanto custaria usá -lo (= WordCount).
Procure todos os modelos relacionados a Julia:
tmps = aitemplates ( " Julia " )
# 2-element Vector{AITemplateMetadata}... -> more to come later! Se você estiver no vscode, pode aproveitar uma boa tela tabular com vscodedisplay :
using DataFrames
tmps = aitemplates ( " Julia " ) |> DataFrame |> vscodedisplay Eu tenho meu modelo selecionado, como faço para usá -lo? Basta usar o "nome" em aigenerate ou aiclassify , como você vê no primeiro exemplo!
Você pode inspecionar qualquer modelo "renderizando -o (é isso que o LLM verá):
julia > AITemplate ( :JudgeIsItTrue ) |> PromptingTools . renderVeja mais exemplos nos exemplos/ pasta.
Você pode aproveitar asyncmap para executar várias tarefas movidas a IA simultaneamente, melhorando o desempenho para operações de lote.
prompts = [ aigenerate ( " Translate 'Hello, World!' to {{language}} " ; language) for language in [ " Spanish " , " French " , " Mandarin " ]]
responses = asyncmap (aigenerate, prompts)Dica
Você pode limitar o número de tarefas simultâneas com a palavra -chave asyncmap(...; ntasks=10) .
Certas tarefas requerem modelos mais poderosos. Todas as funções voltadas para o usuário têm um model de argumento de palavras-chave que pode ser usado para especificar o modelo a ser usado. Por exemplo, você pode usar model = "gpt-4-1106-preview" para usar o modelo mais recente do GPT-4 Turbo. No entanto, ninguém quer digitar isso!
Oferecemos um conjunto de aliases de modelo (por exemplo, "GPT3", "GPT4", "GPT4T" -> o turbo GPT -4 acima, etc.) que podem ser usados.
Cada ai... Call primeiro procure o nome do modelo fornecido no dicionário PromptingTools.MODEL_ALIASES , para que você possa se estender facilmente com seus próprios aliases!
const PT = PromptingTools
PT . MODEL_ALIASES[ " gpt4t " ] = " gpt-4-1106-preview " Esses aliases também podem ser usados como sinalizadores na macro @ai_str , por exemplo, ai"What is the capital of France?"gpt4t (GPT-4 Turbo tem um corte de conhecimento em abril de 2023, por isso é útil para perguntas mais contemporâneas).
Use a função aiembed para criar incorporações através do modelo OpenAI padrão que pode ser usado para pesquisa semântica, clustering e fluxos de trabalho de IA mais complexos.
text_to_embed = " The concept of artificial intelligence. "
msg = aiembed (text_to_embed)
embedding = msg . content # 1536-element Vector{Float64}Se você planeja calcular a distância cosseno entre as incorporações, poderá normalizá -las primeiro:
using LinearAlgebra
msg = aiembed ([ " embed me " , " and me too " ], LinearAlgebra . normalize)
# calculate cosine distance between the two normalized embeddings as a simple dot product
msg . content ' * msg . content[:, 1 ] # [1.0, 0.787] Você pode usar a função aiclassify para classificar qualquer instrução fornecida como verdadeira/falsa/desconhecida. Isso é útil para verificação de fatos, alucinação ou cheques de NLI, moderação, filtragem, análise de sentimentos, engenharia de recursos e muito mais.
aiclassify ( " Is two plus two four? " )
# truePrompts do sistema e modelos de qualidade superior podem ser usados para tarefas mais complexas, incluindo saber quando adiar para um humano:
aiclassify ( :JudgeIsItTrue ; it = " Is two plus three a vegetable on Mars? " , model = " gpt4t " )
# unknown No exemplo acima, usamos um modelo rápido :JudgeIsItTrue , que se expande automaticamente para o seguinte prompt do sistema (e um prompt de usuário separado):
"Você é um juiz imparcial da IA avaliando se a declaração fornecida é" verdadeira "ou" falsa ". Responda" desconhecido "se você não pode decidir".
Para obter mais informações sobre os modelos, consulte a seção Prompts de modelos.
aiclassify também pode ser usado para classificação em um conjunto de categorias definidas (máximo 20), para que possamos usá -lo para roteamento.
Além disso, se você fornecer as opções como tuplas ( (label, description) ), o modelo usará as descrições para decidir, mas retornará os rótulos.
Exemplo:
choices = [( " A " , " any animal or creature " ), ( " P " , " for any plant or tree " ), ( " O " , " for everything else " )]
input = " spider "
aiclassify ( :InputClassifier ; choices, input) # -> returns "A" for any animal or creature
# Try also with:
input = " daphodil " # -> returns "P" for any plant or tree
input = " castle " # -> returns "O" for everything elseSob o capô, usamos o truque "viés de logit" para forçar apenas 1 token gerado - isso significa que é muito barato e muito rápido!
Você está cansado de extrair dados com regex? Você pode usar o LLMS para extrair dados estruturados do texto!
Tudo o que você precisa fazer é definir a estrutura dos dados que deseja extrair e o LLM fará o resto.
Defina um return_type com estrutura. Forneça Docstrings, se necessário (melhora os resultados e ajuda na documentação).
Vamos começar com uma tarefa difícil - extraindo o clima atual em um determinado local:
@enum TemperatureUnits celsius fahrenheit
""" Extract the current weather in a given location
# Arguments
- `location`: The city and state, e.g. "San Francisco, CA"
- `unit`: The unit of temperature to return, either `celsius` or `fahrenheit`
"""
struct CurrentWeather
location :: String
unit :: Union{Nothing,TemperatureUnits}
end
# Note that we provide the TYPE itself, not an instance of it!
msg = aiextract ( " What's the weather in Salt Lake City in C? " ; return_type = CurrentWeather)
msg . content
# CurrentWeather("Salt Lake City, UT", celsius)Mas você pode usá -lo mesmo para tarefas mais complexas, como extrair muitas entidades de um texto:
" Person's age, height, and weight. "
struct MyMeasurement
age :: Int
height :: Union{Int,Nothing}
weight :: Union{Nothing,Float64}
end
struct ManyMeasurements
measurements :: Vector{MyMeasurement}
end
msg = aiextract ( " James is 30, weighs 80kg. He's 180cm tall. Then Jack is 19 but really tall - over 190! " ; return_type = ManyMeasurements)
msg . content . measurements
# 2-element Vector{MyMeasurement}:
# MyMeasurement(30, 180, 80.0)
# MyMeasurement(19, 190, nothing) Existe até um invólucro para ajudá -lo a capturar erros junto com explicações úteis sobre por que a análise falhou. Veja ?PromptingTools.MaybeExtract para obter mais informações.
Com a função aiscan , você pode interagir com imagens como se fossem texto.
Você pode simplesmente descrever uma imagem fornecida:
msg = aiscan ( " Describe the image " ; image_path = " julia.png " , model = " gpt4v " )
# [ Info: Tokens: 1141 @ Cost: $0.0117 in 2.2 seconds
# AIMessage("The image shows a logo consisting of the word "julia" written in lowercase") Ou você pode fazer um OCR de uma captura de tela. Vamos transcrever algum código SQL de uma captura de tela (não mais re-toque!), Usamos um modelo :OCRTask :
# Screenshot of some SQL code
image_url = " https://www.sqlservercentral.com/wp-content/uploads/legacy/8755f69180b7ac7ee76a69ae68ec36872a116ad4/24622.png "
msg = aiscan ( :OCRTask ; image_url, model = " gpt4v " , task = " Transcribe the SQL code in the image. " , api_kwargs = (; max_tokens = 2500 ))
# [ Info: Tokens: 362 @ Cost: $0.0045 in 2.5 seconds
# AIMessage("```sql
# update Orders <continue>Você pode adicionar o destaque da sintaxe das saídas via Markdown
using Markdown
msg . content |> Markdown . parseairetry!Este é um recurso experimental, então você precisa importá -lo explicitamente:
using PromptingTools . Experimental . AgentTools Este módulo oferece contrapartes "preguiçosos" para as funções da ai... para que você possa usá -las de uma maneira mais controlada, por exemplo, aigenerate -> AIGenerate (observe o camelcase), que tem exatamente os mesmos argumentos, exceto que ele gera apenas quando run! é chamado.
Por exemplo:
out = AIGenerate ( " Say hi! " ; model = " gpt4t " )
run! (out) Como é útil? Podemos usar as mesmas "entradas" para chamadas repetidas, por exemplo, quando queremos validar ou regenerar algumas saídas. Temos uma função airetry para nos ajudar com isso.
A assinatura da airetry! é airetry!(condition_function, aicall::AICall, feedback_function) . Ele avalia a condição da condition_function no objeto aicall (por exemplo, avaliamos f_cond(aicall) -> Bool ). Se falhar, chamamos o feedback_function no objeto aicall para fornecer feedback para o modelo de IA (por exemplo, f_feedback(aicall) -> String ) e repita o processo até que ele passe ou até que o valor max_retries seja excedido.
Podemos capturar falhas de API (nenhum feedback necessário, para que nenhum seja fornecido)
# API failure because of a non-existent model
# RetryConfig allows us to change the "retry" behaviour of any lazy call
out = AIGenerate ( " say hi! " ; config = RetryConfig (; catch_errors = true ),
model = " NOTEXIST " )
run! (out) # fails
# we ask to wait 2s between retries and retry 2 times (can be set in `config` in aicall as well)
airetry! (isvalid, out; retry_delay = 2 , max_retries = 2 )Ou podemos validar algumas saídas (por exemplo, seu formato, seu conteúdo etc.)
Vamos jogar um jogo de adivinhação em cores (estou pensando "amarelo"):
# Notice that we ask for two samples (`n_samples=2`) at each attempt (to improve our chances).
# Both guesses are scored at each time step, and the best one is chosen for the next step.
# And with OpenAI, we can set `api_kwargs = (;n=2)` to get both samples simultaneously (cheaper and faster)!
out = AIGenerate (
" Guess what color I'm thinking. It could be: blue, red, black, white, yellow. Answer with 1 word only " ;
verbose = false ,
config = RetryConfig (; n_samples = 2 ), api_kwargs = (; n = 2 ))
run! (out)
# # Check that the output is 1 word only, third argument is the feedback that will be provided if the condition fails
# # Notice: functions operate on `aicall` as the only argument. We can use utilities like `last_output` and `last_message` to access the last message and output in the conversation.
airetry! (x -> length ( split ( last_output (x), r" | \ . " )) == 1 , out,
" You must answer with 1 word only. " )
# Note: you could also use the do-syntax, eg,
airetry! (out, " You must answer with 1 word only. " ) do aicall
length ( split ( last_output (aicall), r" | \ . " )) == 1
end Você pode colocar múltiplas airetry! chama uma sequência. Eles continuarão novamente repetindo até ficarem sem chamadas máximas de IA permitidas ( max_calls ) ou no máximo de tentativas ( max_retries ).
Veja os documentos para obter exemplos mais complexos e dicas de uso ( ?airetry ). Aproveitamos a busca de árvores de Monte Carlo (MCTS) para otimizar a sequência de tentativas, por isso é uma ferramenta muito poderosa para criar fluxos de trabalho robustos de IA (inspirados no papel de busca de árvores de agentes de idiomas e pelo artigo de asserções DSPY).
Ollama.ai é uma ferramenta incrivelmente simples que permite executar vários modelos de idiomas grandes (LLM) no seu computador. É especialmente adequado quando você está trabalhando com alguns dados confidenciais que não devem ser enviados em nenhum lugar.
Vamos supor que você tenha instalado o Ollama, baixou um modelo e está em execução em segundo plano.
Podemos usá -lo com a função aigenerate :
const PT = PromptingTools
schema = PT . OllamaSchema () # notice the different schema!
msg = aigenerate (schema, " Say hi! " ; model = " openhermes2.5-mistral " )
# [ Info: Tokens: 69 in 0.9 seconds
# AIMessage("Hello! How can I assist you today?") Para modelos comuns que foram registrados (consulte ?PT.MODEL_REGISTRY ), você não precisa fornecer o esquema explicitamente:
msg = aigenerate ( " Say hi! " ; model = " openhermes2.5-mistral " ) E também podemos usar a função aiembed :
msg = aiembed (schema, " Embed me " , copy; model = " openhermes2.5-mistral " )
msg . content # 4096-element JSON3.Array{Float64...
msg = aiembed (schema, [ " Embed me " , " Embed me " ]; model = " openhermes2.5-mistral " )
msg . content # 4096×2 Matrix{Float64}: Agora você também pode usar aiscan para fornecer imagens aos modelos Ollama! Veja os documentos para obter mais informações.
Se você estiver recebendo erros, verifique se o Ollama está em execução - consulte o guia de configuração para a seção OLLAMA abaixo.
Os modelos Mistral há muito tempo dominam o espaço de código aberto. Eles agora estão disponíveis por meio de sua API, para que você possa usá -los com PromptingTools.jl!
msg = aigenerate ( " Say hi! " ; model = " mistral-tiny " ) Tudo funciona, porque registramos os modelos no PromptingTools.MODEL_REGISTRY ! Atualmente, existem 4 modelos disponíveis: mistral-tiny , mistral-small , mistral-medium , mistral-embed .
Sob o capô, usamos um esquema dedicado MistralOpenAISchema que aproveita a maior parte da base de código específica do Openai, para que você possa sempre fornecer isso explicitamente como o primeiro argumento:
const PT = PromptingTools
msg = aigenerate (PT . MistralOpenAISchema (), " Say Hi! " ; model = " mistral-tiny " , api_key = ENV [ " MISTRAL_API_KEY " ]) Como você pode ver, podemos carregar sua chave da API no Env ou através do mecanismo de ?PREFERENCES .
Mas Mistralai não são os únicos! Existem muitos outros fornecedores interessantes, por exemplo, perplexidade.ai, fogos de artifício. Enquanto eles forem compatíveis com a API do OpenAI (por exemplo, enviando messages com chaves role e content ), você pode usá -las com PromptingTools.jl usando schema = CustomOpenAISchema() :
# Set your API key and the necessary base URL for the API
api_key = " ... "
prompt = " Say hi! "
msg = aigenerate (PT . CustomOpenAISchema (), prompt; model = " my_model " , api_key, api_kwargs = (; url = " http://localhost:8081 " ))Como você pode ver, ele também funciona para quaisquer modelos locais que você possa ter executando no seu computador!
NOTA: No momento, apoiamos apenas as funções aigenerate e aiembed para Mistralai e outras APIs compatíveis com o Openai. Planejamos estender o apoio no futuro.
Verifique se a variável ANTHROPIC_API_KEY de ambiente está definida como sua chave da API.
# cladeuh is alias for Claude 3 Haiku
ai " Say hi! " claudeh Aliases de modelo predefinidos são claudeo , claudes e claudeh , para Claude 3 Opus, Sonnet e Haiku, respectivamente.
O esquema correspondente é AnthropicSchema .
Existem vários modelos de prompt com XML no nome, sugerindo que eles usam formatação XML para separar as seções de separação. Encontre -os com aitemplates("XML") .
# cladeo is alias for Claude 3 Opus
msg = aigenerate (
:JuliaExpertAskXML , ask = " How to write a function to convert Date to Millisecond? " ,
model = " cladeo " )Tbu ...
Encontre mais exemplos nos exemplos/ pasta.
O pacote é construído em torno de três elementos -chave:
aigenerate , aiembed , aiclassify ) Por que esse design? APIs diferentes requerem formatos de prompt diferentes. Por exemplo, a API do OpenAI exige uma variedade de dicionários com campos de role e content , enquanto o modelo de API de Ollama para Zephyr-7b requer um esquema de chatml com uma grande corda e separadores como <|im_start|>usernABC...<|im_end|>user . Para separar as seções em seu prompt, o OpenAI prefere os cabeçalhos de marcação ( ##Response ) vs Antropic tem um desempenho melhor com as tags HTML ( <text>{{TEXT}}</text> ).
Este pacote é fortemente inspirado pelo instrutor e seu uso inteligente da API de chamada de função.
Esquemas imediatos
O tipo de chave usado para a personalização da lógica da preparação de entradas para LLMS e chamando -as (por despacho múltiplo).
Todos são subtipos de AbstractPromptSchema e cada função de tarefa tem uma assinatura genérica com esquema na primeira posição foo(schema::AbstractPromptSchema,...)
O despacho é definido tanto para a "renderização" de prompts ( render ) quanto para chamar as APIs ( aigenerate ).
Idealmente, cada nova interface seria definida em um arquivo llm_<interface>.jl (por exemplo, llm_openai.jl ).
Mensagens
Os avisos são efetivamente uma conversa a ser concluída.
As conversas tendem a ter três atores -chave: sistema (para instruções gerais), usuário (para entradas/dados) e assistente de IA (para saídas). Fornecemos tipos SystemMessage , UserMessage e AIMessage para cada um deles.
Dado um esquema rápido e uma ou mais mensagem, você pode render o objeto resultante a ser alimentado na API do modelo. Por exemplo, para o Openai
using PromptingTools : render, SystemMessage, UserMessage
PT = PromptingTools
schema = PT . OpenAISchema () # also accessible as the default schema `PT.PROMPT_SCHEMA`
conversation = conversation = [
SystemMessage ( " Act as a helpful AI assistant. Provide only the information that is requested. " ),
UserMessage ( " What is the capital of France? " )]
messages = render (schema, conversation)
# 2-element Vector{Dict{String, String}}:
# Dict("role" => "system", "content" => "Act as a helpful AI assistant. Provide only the information that is requested.")
# Dict("role" => "user", "content" => "What is the capital of France?")Este objeto pode ser fornecido diretamente à API OpenAI.
Funções orientadas para a tarefa
A aspiração é fornecer um conjunto de funções fáceis de lembrar para tarefas comuns, portanto, tudo começa com ai... Todas as funções devem retornar um invólucro leve com respostas resultantes. No momento, ele pode ser apenas AIMessage (para qualquer resposta baseada em texto) ou um DataMessage genérico (para dados estruturados como incorporação).
Dadas as diferenças nas APIs do modelo e seus parâmetros (por exemplo, OpenAI API vs Ollama), as funções de tarefas são despachadas no schema::AbstractPromptSchema como seu primeiro argumento.
Consulte src/llm_openai.jl Para uma implementação de exemplo. Cada nova interface seria definida em um arquivo llm_<interface>.jl separado.
Os modelos da Openai estão na vanguarda da pesquisa de IA e fornecem recursos robustos e de ponta para muitas tarefas.
Haverá situações não ou não poderá usá -lo (por exemplo, privacidade, custo, etc.). Nesse caso, você pode usar modelos locais (por exemplo, ollama) ou outras APIs (por exemplo, antropia).
Nota: Para começar com o ollama.ai, consulte o guia de configuração para a seção OLLAMA abaixo.
Existem muitas alternativas:
No momento da redação.
API
O OpenAI não usa dados enviados e gerados por nossa API para treinar modelos OpenAI ou melhorar a oferta de serviço da OpenAI. Para apoiar a melhoria contínua de nossos modelos, você pode preencher este formulário para optar por compartilhar seus dados conosco. - Como seus dados são usados para melhorar nossos modelos
Você sempre pode verificar as informações mais recentes sobre como usamos sua página de dados.
Recursos:
Você pode obter sua chave da API do OpenAI, inscrevendo -se em uma conta e acessar a seção API do site do OpenAI.
Recursos:
Dica
Sempre defina os limites de gastos!
O OpenAI permite definir limites de gastos diretamente no painel da sua conta para evitar custos inesperados.
Um bom começo pode ser um limite suave de c. US $ 5 e um limite rígido de c. US $ 10 - você sempre pode aumentá -lo no final do mês.
Recursos:
Se você usa um modelo local (por exemplo, com Ollama), é gratuito. Se você usar alguma API comercial (por exemplo, OpenAI), provavelmente pagará por "token" (uma unidade de sub-palavras).
Por exemplo, uma solicitação simples com uma pergunta simples e 1 resposta de frase em troca (”é a declaração xyz um comentário positivo”) custará ~ $ 0,0001 (ou seja, um centésimo de um centavo)
Vale a pena pagar?
Genai é uma maneira de ganhar tempo! Você pode pagar centavos para economizar dezenas de minutos todos os dias.
Continuando o exemplo acima, imagine que você tem uma tabela com 200 comentários. Agora, você pode analisar cada um deles com um LLM para os recursos/verificações necessários. Supondo que o preço por chamada fosse de US $ 0,0001, você pagaria 2 centavos pelo trabalho e economizaria 30-60 minutos do seu tempo!
Recursos:
Este é um guia para a chave da API do OpenAI, mas funciona para qualquer outra chave de API que você possa precisar (por exemplo, MISTRAL_API_KEY for Mistralai API).
Para usar a API OpenAI com PromptingTools.jl, defina sua chave da API como uma variável de ambiente:
ENV [ " OPENAI_API_KEY " ] = " your-api-key "Como único, você pode:
export OPENAI_API_KEY = <your key>setup.jl (certifique -se de não comprometer -o com o Github!) Certifique -se de iniciar Julia a partir da mesma janela do terminal, onde você define a variável. Cheque fácil em Julia, Run ENV["OPENAI_API_KEY"] e você deve ver sua chave!
Uma maneira melhor:
~/.zshrc ). Ele será carregado automaticamente toda vez que você iniciar o terminal Também suportamos preferências.jl, para que você possa simplesmente executar: PromptingTools.set_preferences!("OPENAI_API_KEY"=>"your-api-key") e será persistido em sessões. Para ver as preferências atuais, execute PromptingTools.get_preferences("OPENAI_API_KEY") .
Cuidado para não cometer LocalPreferences.toml com o GitHub, pois mostraria sua chave da API para o mundo!
Recursos:
aigenerate ( api_kwargs )Consulte Referência da API OpenAI para obter mais informações.
Para facilitar o acesso de qualquer lugar, adicione o PromptingTools ao seu startup.jl (pode ser encontrado em ~/.julia/config/startup.jl ).
Adicione o seguinte snippet:
using PromptingTools
const PT = PromptingTools # to access unexported functions and types
Agora, você pode usar ai"Help me do X to achieve Y" de qualquer sessão de repl!
O ethos de PromptingTools.jl é permitir que você use o modelo que desejar, que inclui LLMs de código aberto. O mais popular e mais fácil de configurar é o ollama.ai - veja abaixo para obter mais informações.
Ollama executa um serviço de fundo que hospeda o LLMS que você pode acessar por meio de uma API simples. É especialmente útil quando você está trabalhando com alguns dados confidenciais que não devem ser enviados em nenhum lugar.
A instalação é muito fácil, basta baixar a versão mais recente aqui.
Depois de instalá -lo, basta iniciar o aplicativo e você estará pronto para ir!
Para verificar se está em execução, vá para o navegador e abra 127.0.0.1:11434 . Você deve ver a mensagem "Ollama está correndo". Como alternativa, você pode executar ollama serve em seu terminal e receberá uma mensagem de que ele já está em execução.
Existem muitos modelos disponíveis na Biblioteca Ollama, incluindo LLAMA2, Codellama, SQLCoder ou meu openhermes2.5-mistral favorito.
Faça o download de novos modelos com ollama pull <model_name> (por exemplo, ollama pull openhermes2.5-mistral ).
Mostrar modelos atualmente disponíveis com ollama list .
Veja Ollama.ai para obter mais informações.
O ajuste fino é uma técnica poderosa para adaptar um modelo ao seu caso de uso específico (principalmente o formato/sintaxe/tarefa). Requer um conjunto de dados de exemplos, que agora você pode gerar facilmente com o PromptingTools.jl!
Você pode salvar qualquer conversa (vetor de mensagens) em um arquivo com PT.save_conversation("filename.json", conversation) .
Quando chegar o horário do Finetuning, crie um pacote de conversas formatadas com compartilhamento (formato Finetuning Common) em um único arquivo .jsonl . Use PT.save_conversations("dataset.jsonl", [conversation1, conversation2, ...]) (observe que "conversas" plurais no nome da função).
Para um exemplo de um processo de ponta a ponta, consulte o nosso Projeto Sister Juliallmleaderboard Finetuning Experiment. Ele mostra o processo de Finetuning por meio dólar com jarvislabs.ai e axolotl.
Esta é uma lista de recursos que eu gostaria de ver no futuro (em nenhuma ordem específica):
Para obter mais informações, contribuições ou perguntas, visite o repositório PromptingTools.jl Github.
Observe que, embora o PromptingTools.jl visa proporcionar uma experiência suave, ele se baseia em APIs externas que podem mudar. Fique atento ao repositório para atualizações e novos recursos.
Obrigado por escolher o PromptingTools.jl para capacitar seus aplicativos com a IA!