AskIt sirve como una biblioteca dedicada o un lenguaje de dominio específico diseñado para optimizar la utilización de modelos de lenguaje grandes (LLM) como GPT-4, Gemini, Claude, COHERE y LLama2. Simplifica las complejidades de la ingeniería rápida y elimina la necesidad de analizar las respuestas de los LLM, lo que simplifica las tareas de programación.
Con AskIt , puede implementar LLM para una multitud de tareas, como:
pyaskit puede usar GPT, Gemini, Claude, COHERE o LLama2 como backend. pyaskit opera a través de la API OpenAI, la API Gemini, la API Claude y la API COHERE o LLama2. Además de Python, AskIt también se implementó en TypeScript. Puede acceder a la versión 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 AskIt , ejecute este comando en su terminal:
pip install pyaskit
o
pip install git+https://github.com/katsumiok/pyaskit.git
Antes de usar AskIt , debe configurar su clave API como una variable de entorno adecuada:
OPENAI_API_KEY
GOOGLE_API_KEY
ANTHROPIC_API_KEY
CO_API_KEY
GROQ_API_KEY
Por ejemplo, para utilizar la API de OpenAI, debe configurar su clave de API de OpenAI como una variable de entorno OPENAI_API_KEY
:
export OPENAI_API_KEY= < your OpenAI API key >
<your OpenAI API key>
es una cadena que se parece a esta: sk-<your key>
. Puede encontrar su clave API de OpenAI en el panel de OpenAI.
Debe especificar el nombre del modelo como variable de entorno ASKIT_MODEL
:
export ASKIT_MODEL= < model name >
<model name>
es el nombre del modelo que desea utilizar. El último AskIt se prueba con gpt-4
, gpt-3.5-turbo-16k
, gemini-pro
, claude-2.1
y cohere-2.0
. Puede encontrar la lista de modelos disponibles en la documentación de la API OpenAI, la documentación de la API Gemini, la documentación de la API Claude y la documentación de la API COHERE. También puede encontrar los modelos disponibles en el archivo models.py
.
Antes de usar AskIt con Llama 2, debes instalarlo. Para instalar Llama 2, ejecute este comando en su terminal:
pip install git+https://github.com/facebookresearch/llama.git
También necesitas descargar el modelo de tokenizador y el punto de control del modelo que deseas utilizar. Consulte la documentación de Llama 2 para obtener más detalles.
Proporcionamos un ejemplo del uso de AskIt con Llama 2 en el directorio de ejemplos. Para ejecutar el ejemplo, ejecute este comando en su 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
A continuación se muestran algunos ejemplos básicos que le ayudarán a familiarizarse con AskIt :
import pyaskit as ai
s = ai . ask ( str , 'Paraphrase "Hello World!"' )
print ( s )
Para utilizar AskIt , comience importando el módulo pyaskit
. La API ask
, que toma dos argumentos (el tipo de salida y el mensaje), produce la salida del LLM en el formato designado. En este caso, el tipo de salida es str
y el mensaje es Paraphrase "Hello World!"
. En la sección Tipos se proporciona una explicación completa de los tipos en AskIt . La ejecución de este código generará una paráfrasis del mensaje, como por ejemplo:
Greetings, Planet!
function
. El decorador function
permite definir una función con una plantilla de solicitud. Los parámetros de una función definida se pueden utilizar como parámetros de una plantilla de solicitud. Por ejemplo,
from pyaskit import function
@ function ( codable = False )
def paraphrase ( text : str ) -> str :
"""Paraphrase {{text}}"""
s = paraphrase ( 'Hello World!' )
print ( s )
Donde {{text}}
representa un parámetro de plantilla y corresponde al parámetro de función.
define
La API define
permite la parametrización rápida utilizando la sintaxis de plantilla:
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 )
En este caso, la API define
crea una función con plantilla que indica al LLM que parafrasee el texto especificado. Invocar la función paraphrase
con '¡Hola mundo!' devolverá una versión parafraseada de este texto. La ejecución de este código podría generar algo como "¡Saludos, planeta!".
La API define
permite la creación sencilla de funciones personalizadas para aprovechar las capacidades de modelos de lenguaje grandes para diversas tareas. Se pueden encontrar más ejemplos en el directorio de ejemplos.
Ciertas tareas, como aquellas que requieren datos en tiempo real, recursos externos como acceso a la red, acceso a archivos o acceso a bases de datos, no son adecuadas para la ejecución de LLM. Sin embargo, AskIt puede manejar estas tareas convirtiendo el mensaje en un programa Python en segundo plano.
El siguiente ejemplo demuestra el uso de AskIt para abordar una tarea que requiere acceso a la red:
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 )
En este escenario, solo necesita llamar compile()
en la función devuelta por la API define
. La función compile
transforma el mensaje en un programa Python y devuelve una función que ejecuta este código, comportándose como una función Python normal.
Si bien el ejemplo anterior no especifica el tipo de parámetro url
, AskIt proporciona la API defun
para hacerlo. El siguiente código demuestra cómo definir una función en la que el tipo de url
del parámetro se especifica 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 )
El segundo argumento de la API defun
es un diccionario que asigna nombres de parámetros a sus tipos.
Podemos hacer lo mismo con el siguiente 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 )
Los modelos de aprendizaje de idiomas (LLM) ofrecen la ventaja del aprendizaje en pocas oportunidades, una capacidad que AskIt utiliza en tareas de programación. AskIt le permite resolver tareas utilizando la técnica de Programación por ejemplo (PBE), donde proporciona ejemplos de las entradas y salidas deseadas.
Consideremos la creación de una función para sumar dos números binarios (representados como cadenas). Esta función acepta dos números binarios y devuelve su suma, también en forma binaria. El siguiente código demuestra la definición de dicha función mediante ejemplos 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"
En este ejemplo, la API define
toma tres argumentos: el tipo de salida, el mensaje y los ejemplos de entrenamiento. Cada entrada en la lista de ejemplos de entrenamiento es un diccionario que contiene un diccionario de 'entrada' (con nombres y valores de variables) y una 'salida' que representa la salida esperada de la función dada la entrada. Luego, la API define
devuelve una función que acepta variables de entrada como argumentos de palabras clave y genera la salida del LLM en el tipo especificado.
La función add_binary_numbers
, que suma dos números binarios, se comporta como cualquier función normal de Python.
Puede utilizar la función compile
para probar la función generada utilizando una lista opcional de ejemplos de prueba.
El siguiente código demuestra cómo probar la función definida anteriormente con nuevos ejemplos de prueba:
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"
Aquí, f
es la función generada que funciona de manera similar a add_binary_numbers
. Al comparar el resultado de la función generada con el resultado esperado para cada ejemplo de prueba, AskIt garantiza que la función generada se comporte como se esperaba. Si surge alguna discrepancia, AskIt vuelve a intentar la traducción. Después de varios intentos fallidos de traducción, AskIt genera una excepción.
AskIt ofrece API para designar los tipos de salida para modelos de aprendizaje de idiomas (LLM). Al proporcionar estos tipos como primer argumento para ask
y define
las API, puede administrar el formato de salida del LLM. También puede utilizar las sugerencias de tipo proporcionadas por Python.
La siguiente tabla describe los distintos tipos admitidos por AskIt :
Tipo | Descripción | Ejemplo de tipo | Ejemplo de valor |
---|---|---|---|
int | Entero | t.int | 123 |
float | Número de coma flotante | t.float | 1.23 |
bool | booleano | t.bool | Verdadero |
str | Cadena | t.str | "¡Hola Mundo!" |
literal | Literal | t.literal(123) | 123 |
list | Lista | t.list(t.int) | [1, 2, 3] |
dict | Diccionario | t.dict({ 'a': t.int, 'b': t.str }) | {'a': 1, 'b': "abc"} |
record | Diccionario | t.record(t.str, t.int) | {'a': 1, 'b': 2} |
tuple | tupla | t.tuple(t.int, t.str) | (1, "abc") |
union | Unión (múltiples valores posibles) | t.union(t.literal('yes'), t.literal('no')) | "sí o no" |
t.literal('yes') | t.literal('no') | "sí o no" | ||
t.literal('yes', 'no') | "sí o no" | ||
None | Ninguno | None | Ninguno |
Tenga en cuenta que cada declaración de tipo ayuda a AskIt a analizar y comprender el resultado deseado, lo que garantiza que su LLM devuelva datos en el formato preciso que necesita.
La plantilla de solicitud es una cadena compuesta de marcadores de posición para los parámetros de la función que se define. Los marcadores de posición se indican con llaves dobles {{
y }}
y solo pueden contener un nombre de variable. Este nombre de variable se utiliza luego como parámetro en la función definida.
Los parámetros de función se pueden definir de dos maneras: mediante argumentos de palabras clave o mediante argumentos posicionales. Para los argumentos de palabras clave, el nombre de la variable dentro del marcador de posición sirve como nombre del argumento de la palabra clave. Para los argumentos posicionales, la secuencia en la que aparecen los marcadores de posición define el orden de los argumentos posicionales.
Considere el siguiente ejemplo que demuestra cómo definir una función, add
, y
acepta dos argumentos x
y devuelve su suma:
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
En este caso, la función add
se puede invocar usando palabras clave o argumentos posicionales, con la suma de x
y
como salida.
En particular, si el mismo nombre de variable se utiliza varias veces en la plantilla de solicitud, los usos posteriores se asignan a la aparición inicial. Observe este comportamiento en el siguiente ejemplo:
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 ))
Aquí, {{x}}
aparece dos veces en la plantilla de mensaje. La segunda aparición de {{x}}
se remonta a la primera. Por lo tanto, aunque {{z}}
es el cuarto marcador de posición en la plantilla, se alinea con el tercer argumento de la función.
Consulte CONTRIBUTING.md para obtener detalles sobre nuestro código de conducta y el proceso para enviarnos solicitudes de extracción.
Este proyecto tiene la licencia MIT; consulte el archivo LICENSE.md para obtener más detalles.
Si utiliza nuestro software en su investigación, cite nuestro artículo:
@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 }
}