Agilice su vida utilizando PromitingTools.jl, el paquete Julia que simplifica la interacción con modelos de idiomas grandes.
PromitingTools.jl no está destinado a construir sistemas a gran escala. ¡Está destinado a ser la herramienta de referencia en su entorno global que le ahorrará 20 minutos todos los días!
Consejo
Salta a los documentos
@ai_str y plantilla fácil Comenzarse con la solicitud de inicio de la sesión es tan fácil como importar el paquete y usar la macro @ai_str para sus preguntas.
Nota: Deberá establecer su tecla API OpenAI como una variable de entorno antes de usar solicitingTools.jl (consulte la sección Crear la clave de la API de OpenAI a continuación).
Después de la introducción de la facturación prepago, deberá comprar algunos créditos para comenzar ($ 5 mínimo). Para un inicio rápido, simplemente configúrelo a través de ENV["OPENAI_API_KEY"] = "your-api-key"
Instalar la solicitud de pisos:
using Pkg
Pkg . add ( " PromptingTools " )¡Y estamos listos 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.") El objeto devuelto es un envoltorio de luz con un mensaje generado en el campo :content (p. Ej., ans.content ) para un procesamiento posterior adicional.
Consejo
Si desea responder al mensaje anterior, o simplemente continúe con la conversación, use @ai!_str (¡observe la explosión ! ):
ai! " And what is the population of it? "Puede inyectar fácilmente cualquier variable con la interpolación de cadena:
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.") Consejo
Use flestas posteriores a la cadena para seleccionar el modelo a llamar, por ejemplo, ai"What is the capital of France?"gpt4 (use gpt4t para el nuevo modelo Turbo GPT-4). ¡Genial para esas preguntas extra duras!
Para plantillas de solicitud más complejas, puede usar la plantilla de estilo Manillars y proporcionar variables como argumentos de palabras clave:
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.") Consejo
Use asyncmap para ejecutar múltiples tareas con AI simultáneamente.
Consejo
Si usa modelos lentos (como GPT -4), puede usar @aai!_str versión async @ai!_str @ai_str -> @aai_str para evitar bloquear el repl, aai"Say hi but slowly!"gpt4 . Ej.
Para ver ejemplos más prácticos, consulte los examples/ carpeta y la sección de ejemplos avanzados a continuación.
@ai_str y plantilla fácilai*airetry!aigenerate ( api_kwargs )La ingeniería rápida no es rápida ni fácil. Además, los diferentes modelos y sus ajustes finos pueden requerir diferentes formatos y trucos de inmediato, o tal vez la información con la que trabaja requiere modelos especiales para ser utilizados. PromplingTools.jl está destinado a unificar las indicaciones para diferentes backends y hacer que las tareas comunes (como indicaciones plantadas) sean lo más simples posible.
Algunas características:
aigenerate : Simplifique las plantillas de inmediato con Handlebars (por ejemplo, {{variable}} ) y argumentos de palabras clave@ai_str cadena macro : Guardar teclas con una macro de cadena para indicaciones simplesai... para una mejor capacidad de descubrimientoai* Funciones notables: aigenerate , aiembed , aiclassify , aiextract , aiscan , aiimage , aitemplates
Todas las funciones ai* tienen la misma estructura básica:
ai*(<optional schema>,<prompt or conversation>; <optional keyword arguments>) ,
Pero difieren en el propósito:
aigenerate es la función de uso general para generar cualquier respuesta de texto con LLM, es decir, devuelve AIMessage con campo :content que contiene el texto generado (por ejemplo, ans.content isa AbstractString )aiembed está diseñado para extraer incrustaciones de la respuesta del modelo AI, es decir, devuelve DataMessage con campo :content que contiene los incrustaciones (por ejemplo, ans.content isa AbstractArray )aiextract está diseñado para extraer datos estructurados de la respuesta del modelo AI y devolverlos como una estructura de Julia (por ejemplo, si proporcionamos return_type=Food , obtenemos ans.content isa Food ). Primero debe definir el tipo de retorno y luego proporcionarlo como un argumento de palabra clave.aitools está diseñado para flujos de trabajo de agente con una combinación de llamadas de herramientas e entradas de usuario. Puede funcionar con funciones simples y ejecutarlas.aiclassify está diseñado para clasificar el texto de entrada en (o simplemente responder dentro) un conjunto de choices discretas proporcionadas por el usuario. Puede ser muy útil como juez LLM o un enrutador para sistemas RAG, ya que utiliza el "truco de sesgo logit" y genera exactamente 1 token. Devuelve AIMessage con campo :content , pero el :content puede ser solo una de las choices proporcionadas (por ejemplo, ans.content in choices )aiscan es para trabajar con imágenes y modelos habilitados para la visión (como entrada), pero devuelve AIMessage con campo :content que contiene el texto generado ( ans.content isa AbstractString . Ej aigenerateaiimage es para generar imágenes (por ejemplo, con OpenAi Dall-E 3). Devuelve un DataMessage , donde el campo :content puede contener la URL para descargar la imagen de o la imagen codificada Base64 dependiendo de la api_kwargs.response_format KWARG proporcionada por el usuario.aitemplates es una función auxiliar para descubrir plantillas disponibles y ver sus detalles (por ejemplo, aitemplates("some keyword") o aitemplates(:AssistantAsk) ) Si está utilizando un model conocido, no necesita proporcionar un schema (el primer argumento).
Los argumentos de palabras clave opcionales en ai* tienden a ser:
model::String - ¿Qué modelo desea usar?verbose::Bool - Si fue a ver registros de información en torno a los costos de IAreturn_all::Bool : si desea toda la conversación o simplemente la respuesta de IA (es decir, si desea incluir sus entradas/indicaciones en la salida)api_kwargs::NamedTuple - parámetros específicos para el modelo, por ejemplo, temperature=0.0 no es creativo (y tiene una salida más similar en cada ejecución)http_kwargs::NamedTuple - parámetros para el paquete http.jl, por ejemplo, readtimeout = 120 para salir en 120 segundos si no se recibió ninguna respuesta.Experimental: AgentTools
Además de la lista anterior de funciones ai* , también puede usar las contrapartes "perezosas" de estas funciones del módulo de agente experimental.
using PromptingTools . Experimental . AgentTools Por ejemplo, AIGenerate() creará una instancia perezosa de aigenerate . Es una instancia de AICall con aigenerate como su función AI. Utiliza exactamente los mismos argumentos y argumentos de palabras clave que aigenerate (ver ?aigenerate para más detalles).
"Lazy" se refiere al hecho de que no genera ninguna salida cuando se instancia (¡solo cuando run! se llama).
O se dijo de manera diferente, la estructura AICall y todos sus sabores ( AIGenerate , ...) están diseñados para facilitar un modelo de ejecución diferida (evaluación perezosa) para las funciones de IA que interactúan con un modelo de aprendizaje de idiomas (LLM). ¡Almacena la información necesaria para una llamada de IA y ejecuta la función AI subyacente solo cuando se suministra un UserMessage o cuando run! se aplica el método. Esto nos permite recordar las entradas de los usuarios y activar la llamada LLM repetidamente si es necesario, lo que permite la fijación automática (¡vea ?airetry! ).
Si desea un poderoso flujo de trabajo de fijación automática, ¡puede usar airetry! , que aprovecha la búsqueda de árboles de Monte-Carlo para elegir la trayectoria óptima de la conversación en función de sus requisitos.
Experimental: Ragtools
Por último, proporcionamos un conjunto de herramientas para crear aplicaciones RAG (recuperar, responder, generar).
Puede ser tan simple como dos llamadas: build_index y airag (recuperar, responder, generar).
Si luego usa bastante impresión con PromptingTools.pprint , destacamos el texto generado frente al texto probablemente obtenido del contexto y obtenemos cuán fuertemente es la respuesta generada respaldada por el contexto. Además, anotamos cada fragmento generado con una referencia de qué documento fuente es del que probablemente provenga (incluido el puntaje de confianza entre 0 y 1).
Google Search es excelente, pero es un interruptor de contexto. A menudo tiene que abrir algunas páginas y leer la discusión para encontrar la respuesta que necesita. Lo mismo con el sitio web de ChatGPT.
Imagine que está en VScode, editando su archivo .gitignore . ¿Cómo ignoro un archivo en todas las subcarpetas nuevamente?
Todo lo que necesita hacer es escribir: aai"What to write in .gitignore to ignore file XYZ in any folder or subfolder?"
Con aai"" (en oposición a ai"" ), hacemos una llamada sin bloqueo a la LLM para no evitar que continúe su trabajo. Cuando la respuesta está lista, la registramos desde el fondo:
[ 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.
Probablemente ahorró 3-5 minutos en esta tarea y probablemente otros 5-10 minutos, debido al interruptor/distracción de contexto que evitó. Es una pequeña victoria, pero se suma rápidamente.
Puede usar la función aigenerate para reemplazar las variables del manillar (p. Ej., {{name}} ) a través de argumentos de palabras clave.
msg = aigenerate ( " Say hello to {{name}}! " , name = " World " ) Las indicaciones más complejas son efectivamente una conversación (un conjunto de mensajes), donde puede tener mensajes de tres entidades: sistema, usuario, aiassistente. Proporcionamos los tipos correspondientes para cada uno de ellos: 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, un dilema, usted tiene. El apego emocional puede nublar su camino para convertirse en un Jedi. Para estar adjunto a las posesiones materiales, no debe. El iPhone no es más que una herramienta, nada más. Deja ir, debes hacerlo.
Busque destacamento, joven Padawan. Reflexionar sobre la impermanencia de todas las cosas. Aprecio los recuerdos que le dio, y agradecidamente por parte. En su ausencia, encuentre nuevas experiencias para crecer y convertirse en una con la fuerza. Solo entonces, un verdadero Jedi, te convertirás ")
También puede usarlo para construir conversaciones, por ejemplo,
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, posee un iPhone viejo, no lo hago. Pero la experiencia con los archivos adjuntos, tengo. Destacamiento, aprendí. Verdadero poder y libertad, trae ...")
Con LLMS, la calidad / robustez de sus resultados depende de la calidad de sus indicaciones. ¡Pero escribir indicaciones es difícil! Es por eso que ofrecemos un sistema de plantillas para ahorrarle tiempo y esfuerzo.
Para usar una plantilla específica (por ejemplo, `` preguntar un idioma julia):
msg = aigenerate ( :JuliaExpertAsk ; ask = " How do I add packages? " ) Lo anterior es equivalente a una versión más detallada que usa explícitamente el despacho en AITemplate :
msg = aigenerate ( AITemplate ( :JuliaExpertAsk ); ask = " How do I add packages? " ) Encuentre plantillas disponibles con 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 ""Lo anterior le da una buena idea de de qué se trata la plantilla, de qué marcadores de posición están disponibles y cuánto costaría usarla (= WordCount).
Busque todas las plantillas relacionadas con Julia:
tmps = aitemplates ( " Julia " )
# 2-element Vector{AITemplateMetadata}... -> more to come later! Si está en VScode, puede aprovechar una bonita pantalla tabular con vscodedisplay :
using DataFrames
tmps = aitemplates ( " Julia " ) |> DataFrame |> vscodedisplay Tengo mi plantilla seleccionada, ¿cómo la uso? ¡Simplemente use el "nombre" en aigenerate o aiclassify como lo ve en el primer ejemplo!
Puede inspeccionar cualquier plantilla "renderizándola" (esto es lo que verá el LLM):
julia > AITemplate ( :JudgeIsItTrue ) |> PromptingTools . renderVea más ejemplos en los ejemplos/ carpeta.
Puede aprovechar asyncmap para ejecutar múltiples tareas con alimentación de IA simultáneamente, mejorando el rendimiento para las operaciones por lotes.
prompts = [ aigenerate ( " Translate 'Hello, World!' to {{language}} " ; language) for language in [ " Spanish " , " French " , " Mandarin " ]]
responses = asyncmap (aigenerate, prompts)Consejo
Puede limitar el número de tareas concurrentes con la palabra clave asyncmap(...; ntasks=10) .
Ciertas tareas requieren modelos más poderosos. Todas las funciones orientadas al usuario tienen un model de argumento de palabras clave que se puede utilizar para especificar el modelo que se utilizará. Por ejemplo, puede usar model = "gpt-4-1106-preview" para usar el último modelo Turbo GPT-4. Sin embargo, ¡nadie quiere escribir eso!
Ofrecemos un conjunto de alias de modelo (por ejemplo, "GPT3", "GPT4", "GPT4T" -> El turbo GPT -4 anterior, etc.) que se puede usar en su lugar.
Cada ai... Llame primero busca el nombre del modelo proporcionado en el diccionario PromptingTools.MODEL_ALIASES , ¡para que pueda extenderse fácilmente con sus propios alias!
const PT = PromptingTools
PT . MODEL_ALIASES[ " gpt4t " ] = " gpt-4-1106-preview " Estos alias también se pueden usar como banderas en el macro @ai_str , por ejemplo, ai"What is the capital of France?"gpt4t (GPT-4 Turbo tiene un límite de conocimiento en abril de 2023, por lo que es útil para preguntas más contemporáneas).
Use la función aiembed para crear incrustaciones a través del modelo OperaI predeterminado que se puede usar para la búsqueda semántica, la agrupación y los flujos de trabajo de IA más complejos.
text_to_embed = " The concept of artificial intelligence. "
msg = aiembed (text_to_embed)
embedding = msg . content # 1536-element Vector{Float64}Si planea calcular la distancia coseno entre incrustaciones, puede normalizarlos primero:
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] Puede usar la función aiclassify para clasificar cualquier declaración proporcionada como verdadero/falso/desconocido. Esto es útil para verificar la verificación de hechos, las verificaciones de alucinación o NLI, moderación, filtrado, análisis de sentimientos, ingeniería de características y más.
aiclassify ( " Is two plus two four? " )
# trueLas indicaciones del sistema y los modelos de mayor calidad se pueden usar para tareas más complejas, incluido saber cuándo diferir a un humano:
aiclassify ( :JudgeIsItTrue ; it = " Is two plus three a vegetable on Mars? " , model = " gpt4t " )
# unknown En el ejemplo anterior, utilizamos una plantilla de solicitud :JudgeIsItTrue , que se expande automáticamente en el siguiente mensaje del sistema (y un mensaje de usuario separado):
"Usted es un juez de IA imparcial que evalúa si la declaración proporcionada es" verdadera "o" falsa ". Responda" desconocido "si no puede decidir".
Para obtener más información sobre las plantillas, consulte la sección de indicaciones plantadas.
aiclassify también se puede utilizar para la clasificación en un conjunto de categorías definidas (máximo 20), por lo que podemos usarlo para enrutamiento.
Además, si proporciona las opciones como tuplas ( (label, description) ), el modelo usará las descripciones para decidir, pero devolverá las etiquetas.
Ejemplo:
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 elseBajo el capó, usamos el truco de "sesgo logit" para forzar solo 1 token generado, ¡eso significa que es muy barato y muy rápido!
¿Estás cansado de extraer datos con regex? ¡Puede usar LLM para extraer datos estructurados del texto!
Todo lo que tiene que hacer es definir la estructura de los datos que desea extraer y el LLM hará el resto.
Defina un return_type con estructura. Proporcione documentos si es necesario (mejora los resultados y ayuda con la documentación).
Comencemos con una tarea difícil: extraer el clima actual en una ubicación determinada:
@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)Pero puede usarlo incluso para tareas más complejas, como extraer muchas entidades de un 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) Incluso hay un envoltorio para ayudarlo a captar errores junto con explicaciones útiles sobre por qué falló el análisis. ¿Vea ?PromptingTools.MaybeExtract para obtener más información.
Con la función aiscan , puede interactuar con las imágenes como si fueran texto.
Simplemente puede describir una imagen proporcionada:
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") O puede hacer un OCR de una captura de pantalla. Transcribamos un código SQL de una captura de pantalla (¡no más vuelto!), Usamos una plantilla :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>Puede agregar resaltado de sintaxis de las salidas a través de Markdown
using Markdown
msg . content |> Markdown . parseairetry!Esta es una característica experimental, por lo que debe importarla explícitamente:
using PromptingTools . Experimental . AgentTools Este módulo ofrece contrapartes "perezosas" a las funciones de ai... , por lo que puede usarlas de una manera más controlada, por ejemplo, aigenerate -> AIGenerate (observe el Camelcase), que tiene exactamente los mismos argumentos, excepto que genera solo cuando run! se llama.
Por ejemplo:
out = AIGenerate ( " Say hi! " ; model = " gpt4t " )
run! (out) ¿Cómo es útil? Podemos usar las mismas "entradas" para llamadas repetidas, por ejemplo, cuando queremos validar o regenerar algunas salidas. Tenemos una función airetry para ayudarnos con eso.
¡La firma de airetry! ¡Es airetry!(condition_function, aicall::AICall, feedback_function) . Evalúa la condición condition_function en el objeto aicall (por ejemplo, evaluamos f_cond(aicall) -> Bool ). Si falla, llamamos feedback_function en el objeto aicall para proporcionar comentarios para el modelo AI (por ejemplo, f_feedback(aicall) -> String ) y repite el proceso hasta que pase o hasta que se exceda el valor max_retries .
Podemos detectar fallas de API (no se necesitan retroalimentación, por lo que no se proporciona ninguna)
# 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 )O podemos validar algunas salidas (por ejemplo, su formato, su contenido, etc.)
Jugaremos un juego de adivinanzas de color (estoy pensando en "amarillo"):
# 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 ¡Puedes colocar múltiples airetry! Llama en una secuencia. Seguirán reintentos hasta que se queden sin llamadas de IA máximas permitidas ( max_calls ) o reintentos máximos ( max_retries ).
Consulte los documentos para ejemplos más complejos y consejos de uso ( ?airetry Aprovechamos la búsqueda de árboles de Monte Carlo (MCTS) para optimizar la secuencia de reintentos, por lo que es una herramienta muy poderosa para construir flujos de trabajo de IA robustos (inspirados en el documento de búsqueda de árboles del agente del lenguaje y por el documento de las afirmaciones de DSPY).
Ollama.ai es una herramienta increíblemente simple que le permite ejecutar varios modelos de idiomas grandes (LLM) en su computadora. Es especialmente adecuado cuando trabaja con algunos datos confidenciales que no deben enviarse en ningún lado.
Supongamos que ha instalado Ollama, descargado un modelo y se está ejecutando en segundo plano.
Podemos usarlo con la función 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 los modelos comunes que se han registrado (ver ?PT.MODEL_REGISTRY ), no necesita proporcionar el esquema explícitamente:
msg = aigenerate ( " Say hi! " ; model = " openhermes2.5-mistral " ) Y también podemos usar la función 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}: ¡Ahora también puede usar aiscan para proporcionar imágenes a los modelos Ollama! Vea los documentos para obtener más información.
Si está recibiendo errores, verifique que Ollama se esté ejecutando; consulte la guía de configuración para la sección Ollama a continuación.
Los modelos Mistral han estado dominando durante mucho tiempo el espacio de código abierto. Ahora están disponibles a través de su API, por lo que puede usarlos con solicitante Tools.jl!
msg = aigenerate ( " Say hi! " ; model = " mistral-tiny " ) Todo solo funciona, ¡porque hemos registrado los modelos en la PromptingTools.MODEL_REGISTRY ! Actualmente hay 4 modelos disponibles: mistral-tiny , mistral-small , mistral-medium , mistral-embed .
Bajo el capó, utilizamos un esquema dedicado MistralOpenAISchema que aprovecha la mayoría de la base de código específica de OpenAI, por lo que siempre puede proporcionarlo explícitamente como el primer argumento:
const PT = PromptingTools
msg = aigenerate (PT . MistralOpenAISchema (), " Say Hi! " ; model = " mistral-tiny " , api_key = ENV [ " MISTRAL_API_KEY " ]) Como puede ver, podemos cargar su clave API desde el env o mediante el mecanismo de preferencias. JL (ver ?PREFERENCES para obtener más información).
¡Pero Mistraali no son los únicos! Hay muchos otros proveedores emocionantes, por ejemplo, perplejidad .i, fuegos artificiales. Siempre que sean compatibles con la API de OpenAI (por ejemplo, enviando messages con claves role y content ), puede usarlos con solicitingTools.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 puede ver, ¡también funciona para cualquier modelos locales que pueda ejecutar en su computadora!
Nota: En este momento, solo apoyamos las funciones aigenerate y aiembed para Mistraalai y otras API compatibles con OpenAI. Planeamos extender el apoyo en el futuro.
Asegúrese de que la variable de entorno ANTHROPIC_API_KEY esté configurada en su clave API.
# cladeuh is alias for Claude 3 Haiku
ai " Say hi! " claudeh Los alias modelos preestablecidos son claudeo , claudes y claudeh , para Claude 3 Opus, Sonnet y Haiku, respectivamente.
El esquema correspondiente es AnthropicSchema .
Hay varias plantillas de inmediato con XML en el nombre, lo que sugiere que usan el formato XML amigable con la antrópica para separar secciones. Encuéntralos con 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 ...
Encuentre más ejemplos en los ejemplos/ carpeta.
El paquete se construye alrededor de tres elementos clave:
aigenerate , aiembed , aiclassify ) ¿Por qué este diseño? Las diferentes API requieren diferentes formatos de inmediato. Por ejemplo, la API de Openai requiere una variedad de diccionarios con campos role y content , mientras que la API de Ollama para el modelo Zephyr-7B requiere un esquema CHATML con una cadena grande y separadores como <|im_start|>usernABC...<|im_end|>user . Para separar las secciones en su mensaje, OpenAI prefiere los encabezados de Markdown ( ##Response ) vs antrópico funciona mejor con etiquetas html ( <text>{{TEXT}}</text> ).
Este paquete está fuertemente inspirado por el instructor y es un uso inteligente de la API de llamadas de funciones.
Esquemas inmediatos
El tipo de tecla utilizado para la personalización de la lógica de la preparación de entradas para LLMS y llamándolas (a través de envío múltiple).
Todos son subtipos de AbstractPromptSchema y cada función de tarea tiene una firma genérica con esquema en la primera posición foo(schema::AbstractPromptSchema,...)
El despacho se define tanto para la "representación" de las indicaciones ( render ) como para llamar a las API ( aigenerate ).
Idealmente, cada nueva interfaz se definiría en un archivo llm_<interface>.jl separado (por ejemplo, llm_openai.jl ).
Mensajes
Las indicaciones son efectivamente una conversación para completarse.
Las conversaciones tienden a tener tres actores clave: sistema (para instrucciones generales), usuario (para entradas/datos) y asistente de IA (para salidas). Proporcionamos los tipos de SystemMessage , UserMessage y AIMessage para cada uno de ellos.
Dado un esquema rápido y uno o más mensaje, puede render el objeto resultante se alimenta a la API del modelo. Por ejemplo, para 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 se puede proporcionar directamente a la API de OpenAI.
Funciones orientadas a tareas
La aspiración es proporcionar un conjunto de funciones fáciles de recordar para tareas comunes, por lo tanto, todos comienzan con ai... Todas las funciones deben devolver un envoltorio de luz con las respuestas resultantes. En este momento, solo puede ser AIMessage (para cualquier respuesta basada en texto) o un DataMessage genérico (para datos estructurados como incrustaciones).
Dadas las diferencias en las API del modelo y sus parámetros (por ejemplo, OpenAI API vs Ollama), las funciones de tareas se envían en schema::AbstractPromptSchema como su primer argumento.
Consulte src/llm_openai.jl para una implementación de ejemplo. Cada nueva interfaz se definiría en un archivo llm_<interface>.jl separado.
Los modelos de OpenAI están a la vanguardia de la investigación de IA y proporcionan capacidades robustas de última generación para muchas tareas.
Habrá situaciones no o no puede usarlo (por ejemplo, privacidad, costo, etc.). En ese caso, puede usar modelos locales (p. Ej., Ollama) u otras API (por ejemplo, antrópico).
Nota: Para comenzar con Ollama.ai, consulte la guía de configuración para la sección Ollama a continuación.
Hay muchas alternativas:
Al momento de escribir, OpenAI no utiliza las llamadas API para capacitar a sus modelos.
API
OpenAI no utiliza datos enviados y generados por nuestra API para entrenar modelos Operai o mejorar la oferta de servicios de OpenAI. Para apoyar la mejora continua de nuestros modelos, puede completar este formulario para optar por compartir sus datos con nosotros. - Cómo se utilizan sus datos para mejorar nuestros modelos
Siempre puede verificar la información más reciente en OpenAI. Cómo usamos su página de datos.
Recursos:
Puede obtener su clave API de OpenAI registrándose para una cuenta y accediendo a la sección API del sitio web de OpenAI.
Recursos:
Consejo
¡Siempre establezca los límites de gasto!
OpenAI le permite establecer límites de gasto directamente en el tablero de su cuenta para evitar costos inesperados.
Un buen comienzo puede ser un límite suave de c. $ 5 y un límite duro de c. $ 10: siempre puede aumentarlo más adelante en el mes.
Recursos:
Si usa un modelo local (por ejemplo, con Ollama), es gratis. Si utiliza alguna API comercial (por ejemplo, OpenAI), es probable que pague por "token" (una unidad de sub-palabras).
Por ejemplo, una solicitud simple con una pregunta simple y 1 respuesta de oración a cambio ("es la declaración xyz un comentario positivo") le costará ~ $ 0.0001 (es decir, una centésima centésima de un centavo)
¿Vale la pena pagar?
¡Genai es una forma de comprar tiempo! Puede pagar centavos para ahorrar decenas de minutos todos los días.
Continuando con el ejemplo anterior, imagine que tiene una tabla con 200 comentarios. Ahora, puede analizar cada uno de ellos con un LLM para las características/cheques que necesita. Suponiendo que el precio por llamada era de $ 0.0001, pagaría 2 centavos por el trabajo y ahorraría 30-60 minutos de su tiempo.
Recursos:
Esta es una guía para la clave API de OpenAI, pero funciona para cualquier otra clave API que pueda necesitar (por ejemplo, MISTRAL_API_KEY para la API de Mistraalai).
Para usar la API de OpenAI con solicitingTools.jl, establezca su clave API como una variable de entorno:
ENV [ " OPENAI_API_KEY " ] = " your-api-key "Como un único, puedes:
export OPENAI_API_KEY = <your key>setup.jl (¡asegúrese de no comprometerlo con GitHub!) Asegúrese de iniciar Julia desde la misma ventana de terminal donde establece la variable. Check en Julia, ejecute ENV["OPENAI_API_KEY"] y ¡debería ver su llave!
Una mejor manera:
~/.zshrc ). Se cargará automáticamente cada vez que inicie el terminal También admitimos Preferences.jl, por lo que simplemente puede ejecutar: PromptingTools.set_preferences!("OPENAI_API_KEY"=>"your-api-key") y se persistirá en las sesiones. Para ver las preferencias actuales, ejecute PromptingTools.get_preferences("OPENAI_API_KEY") .
¡Tenga cuidado de no cometer LocalPreferences.toml a Github, ya que mostraría su clave API al mundo!
Recursos:
aigenerate ( api_kwargs )Consulte la referencia de la API de OpenAI para obtener más información.
Para facilitar el acceso desde cualquier lugar, agregue la solicitud de sujeción a su startup.jl (se puede encontrar en ~/.julia/config/startup.jl ).
Agregue el siguiente fragmento:
using PromptingTools
const PT = PromptingTools # to access unexported functions and types
Ahora, puedes usar ai"Help me do X to achieve Y" de cualquier sesión de replica.
El espíritu de la solicitud de Tool.jl es permitirle usar cualquier modelo que desee, que incluye LLM de código abierto. El más popular y más fácil de configurar es Ollama.ai: consulte a continuación para obtener más información.
Ollama ejecuta un servicio de fondo que aloja LLM a los que puede acceder a través de una API simple. Es especialmente útil cuando trabaja con algunos datos confidenciales que no deben enviarse en ningún lado.
La instalación es muy fácil, simplemente descargue la última versión aquí.
Una vez que lo haya instalado, simplemente inicie la aplicación y esté listo para comenzar.
Para verificar si se está ejecutando, vaya a su navegador y abra 127.0.0.1:11434 . Debería ver el mensaje "Ollama se está ejecutando". Alternativamente, puede ejecutar ollama serve en su terminal y recibirá un mensaje que ya está funcionando.
Hay muchos modelos disponibles en la Biblioteca Ollama, incluidos LLAMA2, Codellama, SQLCoder o mi favorito personal openhermes2.5-mistral .
Descargue nuevos modelos con ollama pull <model_name> (por ejemplo, ollama pull openhermes2.5-mistral ).
Muestre actualmente modelos disponibles con ollama list .
Consulte Ollama.ai para obtener más información.
El ajuste fino es una técnica poderosa para adaptar un modelo a su caso de uso específico (principalmente el formato/sintaxis/tarea). Requiere un conjunto de datos de ejemplos, que ahora puede generar fácilmente con la solicitud de inicio.
Puede guardar cualquier conversación (vector de mensajes) en un archivo con PT.save_conversation("filename.json", conversation) .
Una vez que llegue el tiempo de sintonización Finet, cree un paquete de conversaciones con formato de ShareGPT (formato de ficha común) en un solo archivo .jsonl . Use PT.save_conversations("dataset.jsonl", [conversation1, conversation2, ...]) (observe que las "conversaciones" plurales en el nombre de la función).
Para obtener un ejemplo de un proceso de Finetuning de extremo a extremo, consulte nuestro Proyecto Hermano Juliallmleaderboard Finetuning Experiment. Muestra el proceso de Finetuning por medio dólar con Jarvislabs.ai y Axolotl.
Esta es una lista de características que me gustaría ver en el futuro (sin ningún orden en particular):
Para obtener más información, contribuciones o preguntas, visite el repositorio de Github de solicitante.
Tenga en cuenta que, si bien solicitarleTools.jl tiene como objetivo proporcionar una experiencia sin problemas, se basa en API externas que pueden cambiar. Estén atentos al repositorio de actualizaciones y nuevas funciones.
¡Gracias por elegir solicitingTools.jl para capacitar sus aplicaciones con AI!