AskIt serve como uma biblioteca dedicada ou linguagem de domínio específico projetada para agilizar a utilização de Large Language Models (LLMs), como GPT-4, Gemini, Claude, COHERE e LLama2. Ele simplifica as complexidades da engenharia imediata e erradica a necessidade de análise de respostas de LLMs, tornando as tarefas de programação mais fáceis.
Usando AskIt , você pode implantar LLMs para uma infinidade de tarefas, como:
pyaskit pode usar GPT, Gemini, Claude, COHERE ou LLama2 como backend. O pyaskit opera por meio da API OpenAI, API Gemini, API Claude e API COHERE ou API LLama2. Além do Python, o AskIt também foi implementado em TypeScript. Você pode acessar a versão TypeScript, ts-askit.
from pyaskit import ask
# Automatically parses the response to an integer
sum = ask ( int , "add 1 + 1" )
# `sum` is an integer with a value of 2
from typing import TypedDict , List
from pyaskit import ask
# Define a typed dictionary for programming languages
class PL ( TypedDict ):
name : str
year_created : int
# Automatically extracts structured information into a list of dictionaries
langs = ask ( List [ PL ], "List the two oldest programming languages." )
# `langs` holds information on the oldest programming languages in a structured format like
# [{'name': 'Fortran', 'year_created': 1957},
# {'name': 'Lisp', 'year_created': 1958}]
from pyaskit import function
@ function ( codable = False )
def translate ( s : str , lang : str ) -> str :
"""Translate {{s}} into {{lang}} language."""
s = translate ( "こんにちは世界。" , "English" )
# `s` would be "Hello, world."
from pyaskit import function
@ function ( codable = True )
def get_html ( url : str ) -> str :
"""Get the webpage from {{url}}."""
# When `codable` is set to True, the body of the function is automatically coded by an LLM.
html = get_html ( "https://github.com/katsumiok/pyaskit/blob/main/README.md" )
# `html` contains the HTML version of this README.md
Para instalar o AskIt , execute este comando em seu terminal:
pip install pyaskit
ou
pip install git+https://github.com/katsumiok/pyaskit.git
Antes de usar AskIt , você precisa definir sua chave de API como uma variável de ambiente apropriada:
OPENAI_API_KEY
GOOGLE_API_KEY
ANTHROPIC_API_KEY
CO_API_KEY
GROQ_API_KEY
Por exemplo, para usar a API OpenAI, você precisa definir sua chave de API OpenAI como uma variável de ambiente OPENAI_API_KEY
:
export OPENAI_API_KEY= < your OpenAI API key >
<your OpenAI API key>
é uma string semelhante a esta: sk-<your key>
. Você pode encontrar sua chave de API OpenAI no painel OpenAI.
Você precisa especificar o nome do modelo como uma variável de ambiente ASKIT_MODEL
:
export ASKIT_MODEL= < model name >
<model name>
é o nome do modelo que você deseja usar. O AskIt mais recente foi testado com gpt-4
, gpt-3.5-turbo-16k
, gemini-pro
, claude-2.1
e cohere-2.0
. Você pode encontrar a lista de modelos disponíveis na documentação da API OpenAI, na documentação da API Gemini, na documentação da API Claude e na documentação da API COHERE. Você também pode encontrar os modelos disponíveis no arquivo models.py
.
Antes de usar o AskIt com o Llama 2, você precisa instalá-lo. Para instalar o Llama 2, execute este comando em seu terminal:
pip install git+https://github.com/facebookresearch/llama.git
Você também precisa baixar o modelo do tokenizer e o ponto de verificação do modelo que deseja usar. Consulte a documentação do Llama 2 para obter mais detalhes.
Fornecemos um exemplo de uso do AskIt com Llama 2 no diretório de exemplos. Para executar o exemplo, execute este comando em seu terminal:
torchrun --nproc_per_node 1 examples/use_llama2.py
--ckpt_dir llama-2-7b-chat/
--tokenizer_path tokenizer.model
--max_seq_len 512 --max_batch_size 6
Aqui estão alguns exemplos básicos para ajudá-lo a se familiarizar com o AskIt :
import pyaskit as ai
s = ai . ask ( str , 'Paraphrase "Hello World!"' )
print ( s )
Para utilizar AskIt , comece importando o módulo pyaskit
. A API ask
, que recebe dois argumentos – o tipo de saída e o prompt – produz a saída do LLM no formato designado. Nesse caso, o tipo de saída é str
e o prompt é Paraphrase "Hello World!"
. Uma explicação abrangente dos tipos no AskIt é fornecida na seção Tipos. A execução deste código produzirá uma paráfrase do prompt, como:
Greetings, Planet!
function
O decorador function
permite definir uma função com um modelo de prompt. Os parâmetros de uma função definida podem ser usados como parâmetros de um modelo de prompt. Por exemplo,
from pyaskit import function
@ function ( codable = False )
def paraphrase ( text : str ) -> str :
"""Paraphrase {{text}}"""
s = paraphrase ( 'Hello World!' )
print ( s )
Onde {{text}}
representa um parâmetro de modelo e corresponde ao parâmetro de função.
define
A API define
permite a parametrização imediata usando a sintaxe do modelo:
import pyaskit as ai
paraphrase = ai . define ( str , 'Paraphrase {{text}}' )
s = paraphrase ( text = 'Hello World!' )
# s = paraphrase('Hello World!') # This is also valid
print ( s )
Neste caso, a API define
cria uma função de modelo que instrui o LLM a parafrasear o texto especificado. Invocando a função paraphrase
com 'Hello World!' retornará uma versão parafraseada deste texto. A execução deste código pode gerar algo como "Saudações, Planeta!".
A API define
permite a criação direta de funções personalizadas para aproveitar os recursos de grandes modelos de linguagem para diversas tarefas. Outros exemplos podem ser encontrados no diretório de exemplos.
Certas tarefas, como aquelas que exigem dados em tempo real, recursos externos como acesso à rede, acesso a arquivos ou acesso a banco de dados, são inadequadas para a execução do LLM. No entanto, AskIt pode lidar com essas tarefas convertendo o prompt em um programa Python em segundo plano.
O exemplo a seguir demonstra o uso do AskIt para realizar uma tarefa que necessita de acesso à rede:
import pyaskit as ai
get_html = ai . define ( str , 'Get the webpage from {{url}}' ). compile ()
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
Neste cenário, você só precisa chamar compile()
na função retornada pela API define
. A função compile
transforma o prompt em um programa Python e retorna uma função que executa esse código, comportando-se como uma função Python normal.
Embora o exemplo acima não especifique o tipo do parâmetro url
, AskIt fornece a API defun
para fazer isso. O código a seguir demonstra como definir uma função na qual o tipo do parâmetro url
é especificado como str
:
import pyaskit as ai
get_html = ai . defun ( str , { "url" : str }, 'Get the webpage from {{url}}' ). compile ()
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
O segundo argumento da API defun
é um dicionário que mapeia nomes de parâmetros para seus tipos.
Podemos fazer a mesma coisa com o seguinte código:
from pyaskit import function
@ function ( codable = True )
def get_html ( url : str ) -> str :
"""Get the webpage from {{url}}"""
html = get_html ( url = 'https://csail.mit.edu' )
print ( html )
Os Modelos de Aprendizagem de Linguagens (LLMs) oferecem a vantagem do aprendizado rápido, um recurso que o AskIt utiliza em tarefas de programação. AskIt permite que você resolva tarefas usando a técnica de Programação por Exemplo (PBE), onde você fornece exemplos da entrada e saída desejadas.
Vamos considerar a criação de uma função para adicionar dois números binários (representados como strings). Esta função aceita dois números binários e retorna sua soma, também na forma binária. O código a seguir demonstra a definição de tal função usando exemplos ilustrativos.
from pyaskit import define
training_examples = [
{ "input" : { "x" : "1" , "y" : "0" }, "output" : "1" },
{ "input" : { "x" : "1" , "y" : "1" }, "output" : "10" },
{ "input" : { "x" : "101" , "y" : "11" }, "output" : "1000" },
{ "input" : { "x" : "1001" , "y" : "110" }, "output" : "1111" },
{ "input" : { "x" : "1111" , "y" : "1" }, "output" : "10000" },
]
add_binary_numbers = define ( str , "Add {{x}} and {{y}}" , training_examples = training_examples )
sum_binary = add_binary_numbers ( x = "101" , y = "11" )
print ( sum_binary ) # Output: "1000"
Neste exemplo, a API define
recebe três argumentos: o tipo de saída, o prompt e os exemplos de treinamento. Cada entrada na lista de exemplos de treinamento é um dicionário contendo um dicionário de 'entrada' (com nomes e valores de variáveis) e uma 'saída' representando a saída esperada da função dada a entrada. A API define
então retorna uma função que aceita variáveis de entrada como argumentos de palavra-chave e gera a saída do LLM no tipo especificado.
A função add_binary_numbers
, que adiciona dois números binários, se comporta como qualquer função Python normal.
Você pode usar a função compile
para testar a função gerada usando uma lista opcional de exemplos de teste.
O código a seguir demonstra como testar a função definida acima com novos exemplos de teste:
test_examples = [
{ "input" : { "x" : "0" , "y" : "1" }, "output" : "1" },
{ "input" : { "x" : "10" , "y" : "0" }, "output" : "10" },
{ "input" : { "x" : "110" , "y" : "10" }, "output" : "1000" },
]
f = add_binary_numbers . compile ( test_examples = test_examples )
sum_binary = f ( x = "101" , y = "11" )
print ( sum_binary ) # Output: "1000"
Aqui, f
é a função gerada que opera de forma semelhante a add_binary_numbers
. Ao comparar a saída da função gerada com a saída esperada para cada exemplo de teste, AskIt garante que a função gerada se comporte conforme o esperado. Se surgir alguma discrepância, o AskIt tenta novamente a tradução. Após várias tentativas de tradução malsucedidas, o AskIt gera uma exceção.
AskIt oferece APIs para designar os tipos de saída para Modelos de Aprendizagem de Línguas (LLMs). Ao fornecer esses tipos como o primeiro argumento para as APIs ask
e define
, você pode gerenciar o formato de saída do LLM. Você também pode usar dicas de tipo fornecidas pelo Python.
A tabela a seguir descreve os vários tipos suportados pelo AskIt :
Tipo | Descrição | Exemplo de tipo | Exemplo de valor |
---|---|---|---|
int | Inteiro | t.int | 123 |
float | Número de ponto flutuante | t.float | 1.23 |
bool | Booleano | t.bool | Verdadeiro |
str | Corda | t.str | "Olá, mundo!" |
literal | Literal | t.literal(123) | 123 |
list | Lista | t.list(t.int) | [1, 2, 3] |
dict | Dicionário | t.dict({ 'a': t.int, 'b': t.str }) | {'a': 1, 'b': "abc"} |
record | Dicionário | t.record(t.str, t.int) | {'a': 1, 'b': 2} |
tuple | Tupla | t.tuple(t.int, t.str) | (1, "abc") |
union | União (múltiplos valores possíveis) | t.union(t.literal('yes'), t.literal('no')) | "sim" ou "não" |
t.literal('yes') | t.literal('no') | "sim" ou "não" | ||
t.literal('yes', 'no') | "sim" ou "não" | ||
None | Nenhum | None | Nenhum |
Observe que cada declaração de tipo ajuda o AskIt a analisar e compreender a saída desejada, garantindo que seu LLM retorne dados no formato exato que você precisa.
O modelo de prompt é uma string composta por espaços reservados para os parâmetros da função que está sendo definida. Os espaços reservados são indicados por chaves duplas {{
e }}
e só podem conter um nome de variável. Este nome de variável é então usado como parâmetro na função definida.
Os parâmetros de função podem ser definidos de duas maneiras: por argumentos de palavras-chave ou por argumentos posicionais. Para argumentos de palavra-chave, o nome da variável no espaço reservado serve como o nome do argumento de palavra-chave. Para argumentos posicionais, a sequência em que os marcadores aparecem define a ordem dos argumentos posicionais.
Considere o exemplo a seguir que demonstra como definir uma função, add
, que aceita dois argumentos x
e y
e retorna sua soma:
from pyaskit import define
import pyaskit . types as t
add = define ( t . int , '{{x}} + {{y}}' )
print ( add ( x = 1 , y = 2 )) # keyword arguments
print ( add ( 1 , 2 )) # positional arguments
Nesse caso, a função add
pode ser invocada usando palavras- y
x
como saída.
Notavelmente, se o mesmo nome de variável for usado diversas vezes no modelo de prompt, os usos subsequentes serão mapeados para a ocorrência inicial. Observe esse comportamento no exemplo a seguir:
from pyaskit import define
import pyaskit . types as t
add = define ( t . int , '{{x}} + {{y}} + {{x}} + {{z}}' )
print ( add ( x = 1 , y = 2 , z = 3 ))
print ( add ( 1 , 2 , 3 ))
Aqui, {{x}}
aparece duas vezes no modelo de prompt. A segunda ocorrência de {{x}}
mapeia de volta à primeira. Portanto, embora {{z}}
seja o quarto espaço reservado no modelo, ele se alinha com o terceiro argumento da função.
Consulte CONTRIBUTING.md para obter detalhes sobre nosso código de conduta e o processo para enviar solicitações pull para nós.
Este projeto está licenciado sob a licença MIT - consulte o arquivo LICENSE.md para obter detalhes
Se você usa nosso software em sua pesquisa, cite nosso artigo:
@misc { okuda2023askit ,
title = { AskIt: Unified Programming Interface for Programming with Large Language Models } ,
author = { Katsumi Okuda and Saman Amarasinghe } ,
year = { 2023 } ,
eprint = { 2308.15645 } ,
archivePrefix = { arXiv } ,
primaryClass = { cs.PL }
}