Stürzen Sie Ihr Leben mit der Julia -Paket, das die Interaktion mit großen Sprachmodellen vereinfacht.
Auflauftools.jl ist nicht für den Bau großer Systeme gedacht. Es soll das Werkzeug in Ihrer globalen Umgebung sein, das Sie jeden Tag 20 Minuten sparen wird!
Tipp
Springen zu den Dokumenten
@ai_str und einfacher Vorlagen Der Einstieg mit PromptingTools.jl ist so einfach wie das Importieren des Pakets und die Verwendung des @ai_str -Makros für Ihre Fragen.
Hinweis: Sie müssen Ihre OpenAI -API -Schlüssel als Umgebungsvariable festlegen, bevor Sie die Abschnitt "ProPtionTools.jl erstellen).
Nach der Einführung der Prepaid -Abrechnung müssen Sie einige Gutschriften kaufen, um loszulegen (mindestens 5 US -Dollar). Setzen Sie es für einen kurzen Start einfach über ENV["OPENAI_API_KEY"] = "your-api-key"
Installieren
using Pkg
Pkg . add ( " PromptingTools " )Und wir sind bereit zu gehen!
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.") Das zurückgegebene Objekt ist eine leichte Wrapper mit einer generierten Nachricht im Feld :content (z. B. ans.content ) für eine zusätzliche nachgeschaltete Verarbeitung.
Tipp
Wenn Sie auf die vorherige Nachricht antworten oder einfach das Gespräch fortsetzen möchten, verwenden Sie @ai!_str (beachten Sie den Knall ! ):
ai! " And what is the population of it? "Sie können Variablen leicht mit String -Interpolation injizieren:
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.") Tipp
Verwenden Sie After-String-Flags, um das aufgerufene Modell auszuwählen, z. B. ai"What is the capital of France?"gpt4 (Verwenden Sie gpt4t für das neue GPT-4-Turbo-Modell). Großartig für diese besonders harten Fragen!
Für komplexere Eingabeaufforderungsvorlagen können Sie Templating im Lenker-Stil verwenden und Variablen als Keyword-Argumente bereitstellen:
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.") Tipp
Verwenden Sie asyncmap , um mehrere KI-betriebene Aufgaben gleichzeitig auszuführen.
Tipp
Wenn Sie langsame Modelle verwenden (wie GPT -4), können Sie @aai!_str async -Version @ai!_str @ai_str -> @aai_str verwenden, um zu vermeiden, dass die Reply, z aai"Say hi but slowly!"gpt4
Weitere praktische Beispiele finden Sie im Abschnitt examples/ Ordner und im Abschnitt Erweiterte Beispiele unten.
@ai_str und einfacher Vorlagenai* Funktionenübersichtairetry!aigenerate ( api_kwargs )Schnelltechnik ist weder schnell noch einfach. Darüber hinaus erfordern unterschiedliche Modelle und ihre Feinstöcke möglicherweise unterschiedliche Eingabeaufentwicklungsformate und -tricks oder die Informationen, mit denen Sie zusammenarbeiten, müssen spezielle Modelle verwendet werden. Die Aufforderung an die Eingabeaufforderungen für verschiedene Backends und die gängigen Aufgaben (wie Vorlagenaufforderungen) sollen so einfach wie möglich vereinen.
Einige Funktionen:
aigenerate -Funktion : Vereinfachen Sie die Eingabeaufforderung Vorlagen mit Lenker (z. B. {{variable}} ) und Schlüsselwortargumenten@ai_str -String -Makro : Sparen Sie Tastenanschläge mit einem String -Makro für einfache Eingabeaufforderungenai... für eine bessere Entdeckbarkeitai* Funktionenübersicht Bemerkenswerte Funktionen: aigenerate , aiembed , aiclassify , aiextract , aiscan , aiimage , aitemplates
Alle ai* -Funktionen haben die gleiche Grundstruktur:
ai*(<optional schema>,<prompt or conversation>; <optional keyword arguments>) ,
aber sie unterscheiden sich im Zweck:
aigenerate ist die allgemeine Funktion, um eine Textantwort mit LLMs zu generieren, dh AIMessage mit Feld :content der den generierten Text enthält (z. B. ans.content isa AbstractString )aiembed wurde entwickelt, um Einbettung aus der Antwort des KI -Modells zu extrahieren, dh die DataMessage mit Feld :content mit Einbettungen (z. ans.content isa AbstractArray .aiextract wurde entwickelt, um strukturierte Daten aus der Antwort des KI -Modells zu extrahieren und sie als Julia -Struktur zurückzugeben (z. B. wenn wir return_type=Food angeben, erhalten wir ans.content isa Food ). Sie müssen zuerst den Rückgabetyp definieren und dann als Schlüsselwortargument angeben.aitools ist für agierende Workflows mit einer Mischung aus Toolsaufrufen und Benutzereingaben ausgelegt. Es kann mit einfachen Funktionen funktionieren und sie ausführen.aiclassify ist so konzipiert, dass der Eingabetxt in eine Reihe diskreter choices des Benutzers klassifiziert wird. Es kann als LLM -Richter oder Router für RAG -Systeme sehr nützlich sein, da es den "Logit -Bias -Trick" verwendet und genau 1 Token erzeugt. Es gibt AIMessage mit Feld :content zurück, aber der :content kann nur eine der bereitgestellten choices sein (z. ans.content in choices .aiscan ist für die Arbeit mit Bildern und Vision-fähigen Modellen (als Eingabe) gedacht, aber es gibt AIMessage mit Feld :content mit dem generierten Text (z. B. ans.content isa AbstractString ) ähnlich wie aigenerate zurück.aiimage dient zum Erzeugen von Bildern (z. B. mit Openai dall-e 3). Es gibt eine DataMessage zurück, wobei das Feld :content möglicherweise entweder die URL enthält, um das Bild von oder das Basis64-kodierte Bild abhängig von der vom Benutzer bereitgestellten KWARG- api_kwargs.response_format herunterzuladen.aitemplates ist eine Helferfunktion, um verfügbare Vorlagen zu entdecken und ihre Details (z. B. aitemplates("some keyword") oder aitemplates(:AssistantAsk) anzusehen. Wenn Sie ein bekanntes model verwenden, müssen Sie kein schema (das erste Argument) bereitstellen.
Optionale Keyword -Argumente in ai* sind in der Regel:
model::String - Welches Modell möchten Sie verwendenverbose::Bool - ob Sie zu Info -Protokollen zu KI -Kosten gegangen sindreturn_all::Bool - ob Sie die gesamte Konversation oder nur die KI -Antwort wünschen (dh, ob Sie Ihre Eingänge/Eingabeaufforderung in die Ausgabe einbeziehen möchten)api_kwargs::NamedTuple - Spezifische Parameter für das Modell, z temperature=0.0http_kwargs::NamedTuple - Parameter für das http.jl -Paket, z. B. readtimeout = 120 bis in 120 Sekunden, wenn keine Antwort erhalten wurde.Experimentell: AgentTools
Zusätzlich zu der obigen Liste der ai* -Funktionen können Sie auch die "faulen" Gegenstücke dieser Funktionen aus dem Modul Experimental Agentools verwenden.
using PromptingTools . Experimental . AgentTools Zum Beispiel erzeugt AIGenerate() eine faule Instanz von aigenerate . Es ist ein Beispiel von AICall mit aigenerate als KI -Funktion. Es verwendet genau die gleichen Argumente und Keyword -Argumente wie aigenerate (siehe ?aigenerate für Details).
"Lazy" bezieht sich auf die Tatsache, dass es beim Instanziieren keine Ausgabe erzeugt (nur beim run! wird aufgerufen).
Oder anders gesagt, die AICall -Struktur und alle ihre Geschmacksrichtungen ( AIGenerate , ...) sollen ein aufgeschobenes Ausführungsmodell (faule Bewertung) für KI -Funktionen ermöglichen, die mit einem Sprachlernmodell (LLM) interagieren. Es speichert die erforderlichen Informationen für einen KI -Anruf und führt die zugrunde liegende KI -Funktion nur dann aus, wenn sie mit einer UserMessage oder beim run! Methode wird angewendet. Auf diese Weise können wir uns bei Bedarf wiederholt an Benutzereingaben erinnern und den LLM -Aufruf wiederholt auslösen, was die automatische Behebung ermöglicht (siehe ?airetry! ).
Wenn Sie einen leistungsstarken automatischen Fixing-Workflow wünschen, können Sie airetry! , die die Monte-Carlo-Baumsuche nutzt, um die optimale Konversation auf der Grundlage Ihrer Anforderungen auszuwählen.
Experimentell: Ragtools
Zuletzt bieten wir eine Reihe von Werkzeugen zum Erstellen von Lappenanwendungen (abrufen, beantworten, generieren).
Es kann so einfach sein wie zwei Anrufe: build_index und airag (abrufen, antworten, generieren).
Wenn Sie dann Pretty Printing mit PromptingTools.pprint verwenden, markieren wir den generierten Text gegen Text, der wahrscheinlich aus dem Kontext entnommen wird, und wir bewerten, wie stark die generierte Antwort vom Kontext unterstützt wird. Darüber hinaus kommentieren wir jeweils ein generiertes Chunk mit einem Hinweis darauf, welches Quelldokument es wahrscheinlich stammt (einschließlich der Konfidenz -Punktzahl zwischen 0 und 1).
Die Google -Suche ist großartig, aber ein Kontextschalter. Sie müssen oft ein paar Seiten öffnen und die Diskussion durchlesen, um die Antwort zu finden, die Sie benötigen. Gleiches gilt für die Chatgpt -Website.
Stellen Sie sich vor, Sie sind in VSCODE und bearbeiten Ihre .gitignore -Datei. Wie ignoriere ich eine Datei in allen Unterordnern wieder?
Alles, was Sie tun müssen, ist zu tippen: aai"What to write in .gitignore to ignore file XYZ in any folder or subfolder?"
Mit aai"" (im Gegensatz zu ai"" Wenn die Antwort fertig ist, protokollieren wir sie aus dem Hintergrund:
[Info: Tokens: 102 @ Kosten: $ 0,0002 in 2,7 Sekunden ┌ Info: AIMESSAGE> Um eine Datei mit dem Namen "XYZ
**in einem Ordner oder Unterordner zu ignorieren, können Sie Ihrem .gitignore -Datei: │ │ ││ **/XYZ │└ └ └ └ └ └ └ └ └ └ └ └ └ └ └ └ └ └ Das doppelte Datei. zu ignorieren.
Sie haben wahrscheinlich 3-5 Minuten bei dieser Aufgabe und wahrscheinlich weitere 5-10 Minuten gespeichert, weil Sie den Kontextschalter/die von Ihnen vermiedene Ablenkung haben. Es ist ein kleiner Sieg, aber es summiert sich schnell.
Sie können die aigenerate -Funktion verwenden, um Lenkervariablen (z. B. {{name}} ) durch Schlüsselwortargumente zu ersetzen.
msg = aigenerate ( " Say hello to {{name}}! " , name = " World " ) Die komplexeren Eingabeaufforderungen sind effektiv eine Konversation (eine Reihe von Nachrichten), in der Sie Nachrichten von drei Entitäten haben können: System, Benutzer, Aiassistant. Wir stellen die entsprechenden Typen für jeden von ihnen an: 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, ein Dilemma, das Sie haben. Emotionale Bindung kann Ihren Weg zu einem Jedi werden. Um an materiellen Besitztümer verbunden zu sein, dürfen Sie nicht. Das iPhone ist nur ein Werkzeug, nichts weiter. Lassen Sie los, Sie müssen.
Suchen Sie Distanz, junge Padawan. Über die Unbeständigkeit aller Dinge nachdenken. Schätzen Sie die Erinnerungen, die es Ihnen gegeben hat, und trennen Sie sich dankbar. Finden Sie in seiner Abwesenheit neue Erfahrungen, um zu wachsen und eins mit der Kraft zu werden. Nur dann, ein wahrer Jedi, sollst du werden. ")
Sie können es auch verwenden, um Gespräche zu erstellen, z. B., z. B.
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, besitze ein altes iPhone, ich habe es nicht. Aber Erfahrung mit Anhängen, ich habe. Ablösung, ich habe gelernt. Wahre Macht und Freiheit, es bringt ...")
Bei LLMs hängt die Qualität / Robustheit Ihrer Ergebnisse von der Qualität Ihrer Eingabeaufforderungen ab. Aber das Schreiben von Eingabeaufforderungen ist schwer! Deshalb bieten wir ein Vorlagensystem an, um Ihnen Zeit und Mühe zu sparen.
Um eine bestimmte Vorlage zu verwenden (z. B. `` `eine Julia -Sprache):
msg = aigenerate ( :JuliaExpertAsk ; ask = " How do I add packages? " ) Das obige entspricht einer ausführlicheren Version, die den Versand auf AITemplate explizit verwendet:
msg = aigenerate ( AITemplate ( :JuliaExpertAsk ); ask = " How do I add packages? " ) Finden Sie verfügbare Vorlagen mit 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 ""Das obige gibt Ihnen eine gute Vorstellung davon, worum es in der Vorlage geht, welche Platzhalter verfügbar sind und wie viel es kosten würde, sie zu verwenden (= WordCount).
Suche nach allen Julia-bezogenen Vorlagen:
tmps = aitemplates ( " Julia " )
# 2-element Vector{AITemplateMetadata}... -> more to come later! Wenn Sie auf VSCODE sind, können Sie ein schönes tabellarisches Display mit vscodedisplay nutzen:
using DataFrames
tmps = aitemplates ( " Julia " ) |> DataFrame |> vscodedisplay Ich habe meine ausgewählte Vorlage, wie benutze ich sie? Verwenden Sie einfach den "Namen" in aigenerate oder aiclassify , wie Sie es im ersten Beispiel sehen!
Sie können jede Vorlage untersuchen, indem Sie sie "rendern" (dies ist, was die LLM sehen wird):
julia > AITemplate ( :JudgeIsItTrue ) |> PromptingTools . renderWeitere Beispiele finden Sie in Beispielen/ Ordner.
Sie können asyncmap nutzen, um mehrere KI-angetriebene Aufgaben gleichzeitig auszuführen und die Leistung für den Stapelbetrieb zu verbessern.
prompts = [ aigenerate ( " Translate 'Hello, World!' to {{language}} " ; language) for language in [ " Spanish " , " French " , " Mandarin " ]]
responses = asyncmap (aigenerate, prompts)Tipp
Sie können die Anzahl der gleichzeitigen Aufgaben mit dem Schlüsselwort asyncmap(...; ntasks=10) einschränken.
Bestimmte Aufgaben erfordern leistungsfähigere Modelle. Alle benutzergerichteten Funktionen verfügen über ein Keyword- model , mit dem das zu verwendende Modell angegeben werden kann. Beispielsweise können Sie model = "gpt-4-1106-preview" verwenden, um das neueste GPT-4-Turbo-Modell zu verwenden. Niemand will das jedoch eingeben!
Wir bieten eine Reihe von Modellaliase (z. B. "gpt3", "gpt4", "gpt4t" -> das obige GPT -4 -Turbo usw.), das stattdessen verwendet werden kann.
Jede ai... Call Sucht zuerst nach dem angegebenen Modellnamen im Wörterbuch PromptingTools.MODEL_ALIASES , sodass Sie sich problemlos mit Ihren eigenen Aliase ausdehnen können!
const PT = PromptingTools
PT . MODEL_ALIASES[ " gpt4t " ] = " gpt-4-1106-preview " Diese Aliase können auch als Flaggen im @ai_str Makro, z. ai"What is the capital of France?"gpt4t Verwendet werden?
Verwenden Sie die aiembed -Funktion, um Einbettungen über das Standard -OpenAI -Modell zu erstellen, das für semantische Suche, Clusterbildung und komplexere KI -Workflows verwendet werden kann.
text_to_embed = " The concept of artificial intelligence. "
msg = aiembed (text_to_embed)
embedding = msg . content # 1536-element Vector{Float64}Wenn Sie vorhaben, den Kosinusabstand zwischen Einbettungen zu berechnen, können Sie sie zuerst normalisieren:
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] Sie können die aiclassify -Funktion verwenden, um eine angegebene Anweisung als wahr/false/unbekannt zu klassifizieren. Dies ist nützlich für die Überprüfung, Halluzination oder NLI-Überprüfungen, Mäßigung, Filterung, Stimmungsanalyse, Feature Engineering und mehr.
aiclassify ( " Is two plus two four? " )
# trueSystemaufforderungen und Modelle mit höherer Qualität können für komplexere Aufgaben verwendet werden, einschließlich des Wissens, wann er sich auf einen Menschen verschieben soll:
aiclassify ( :JudgeIsItTrue ; it = " Is two plus three a vegetable on Mars? " , model = " gpt4t " )
# unknown Im obigen Beispiel haben wir eine schnelle Vorlage verwendet :JudgeIsItTrue , die automatisch in die folgende Systemaufforderung (und eine separate Benutzeraufforderung) erweitert wird:
"Sie sind ein unparteiischer KI -Richter, der bewertet, ob die angegebene Aussage" wahr "oder" falsch "ist. Antwort" unbekannt ", wenn Sie sich nicht entscheiden können."
Weitere Informationen zu Vorlagen finden Sie im Abschnitt "Vorlagen".
aiclassify kann auch zur Klassifizierung in einen Satz definierter Kategorien (maximal 20) verwendet werden, sodass wir sie zum Routing verwenden können.
Wenn Sie die Auswahlmöglichkeiten als Tupel ( (label, description) ) angeben, verwendet das Modell die Beschreibungen zur Entscheidung, aber es gibt die Beschriftungen zurück.
Beispiel:
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 elseUnter der Motorhaube verwenden wir den Trick "Logit Bias", um nur 1 erzeugtes Token zu erzwingen - das bedeutet, dass es sehr billig und sehr schnell ist!
Sind Sie es leid, Daten mit Regex zu extrahieren? Sie können LLMs verwenden, um strukturierte Daten aus Text zu extrahieren!
Alles, was Sie tun müssen, ist, die Struktur der Daten zu definieren, die Sie extrahieren möchten, und der LLM wird den Rest erledigen.
Definieren Sie einen return_type mit struktur. Stellen Sie bei Bedarf DocStrings bereit (verbessert die Ergebnisse und hilft bei der Dokumentation).
Beginnen wir mit einer schwierigen Aufgabe - das aktuelle Wetter an einem bestimmten Ort extrahieren:
@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)Sie können es jedoch auch für komplexere Aufgaben verwenden, z. B. für die Extraktion vieler Entitäten aus einem Text:
" 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) Es gibt sogar einen Wrapper, der Ihnen hilft, Fehler zusammen mit hilfreichen Erklärungen zu fangen, warum das Parsen fehlgeschlagen ist. Weitere Informationen finden Sie ?PromptingTools.MaybeExtract .
Mit der aiscan -Funktion können Sie mit Bildern interagieren, als wären sie Text.
Sie können einfach ein bereitgestelltes Bild beschreiben:
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") Oder Sie können einen OCR eines Screenshots machen. Lassen Sie uns einen SQL-Code von einem Screenshot (nicht mehr neu auf!) Transkribieren. Wir verwenden eine Vorlage :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>Sie können die Syntax -Hervorhebung der Ausgänge über Markdown hinzufügen
using Markdown
msg . content |> Markdown . parseairetry!Dies ist eine experimentelle Funktion, daher müssen Sie sie explizit importieren:
using PromptingTools . Experimental . AgentTools AIGenerate Modul bietet den ai... -Funktionen "faule" Gegenstücke, sodass Sie sie aigenerate verwenden können run! heißt.
Zum Beispiel:
out = AIGenerate ( " Say hi! " ; model = " gpt4t " )
run! (out) Wie ist es nützlich? Wir können dieselben "Eingänge" für wiederholte Anrufe verwenden, z. B. wenn wir einige Ausgänge validieren oder regenerieren möchten. Wir haben ein Funktion airetry , das uns dabei hilft.
Die Signatur des airetry! ist airetry!(condition_function, aicall::AICall, feedback_function) . Es bewertet die condition_function die auf dem aicall -Objekt (z. B. wir bewerten f_cond(aicall) -> Bool ). Wenn es fehlschlägt, rufen wir feedback_function auf dem aicall -Objekt auf, um Feedback für das AI -Modell (z. B. f_feedback(aicall) -> String ) bereitzustellen und den Vorgang zu wiederholen, bis er vergeht oder bis der Wert max_retries überschritten ist.
Wir können API -Fehler fangen (kein Feedback benötigt, daher wird keiner vorgesehen).
# 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 )Oder wir können einige Ausgänge validieren (z. B. sein Format, seinen Inhalt usw.)
Wir werden ein Farb -Ratenspiel spielen (ich denke "Gelb"):
# 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 Sie können mehrere airetry! Anrufe in einer Sequenz. Sie werden erneut wiedergeschämt, bis sie die zulässigen maximalen AI -Anrufe ( max_calls ) oder maximale Wiederholungen ( max_retries ) ausgehen.
In den Dokumenten finden Sie komplexere Beispiele und Nutzungstipps ( ?airetry ). Wir nutzen die Monte Carlo Tree Search (MCTs), um die Abfolge von Wiederholungen zu optimieren. Daher ist es ein sehr leistungsstarkes Werkzeug zum Erstellen robuster KI -Workflows (inspiriert durch das Suchpapier von Sprachagenten und durch DSPY -Assertionspapier).
Ollama.ai ist ein erstaunlich einfaches Tool, mit dem Sie mehrere große Sprachmodelle (LLM) auf Ihrem Computer ausführen können. Es ist besonders geeignet, wenn Sie mit einigen sensiblen Daten arbeiten, die nirgendwo gesendet werden sollten.
Nehmen wir an, Sie haben Ollama installiert, ein Modell heruntergeladen und es läuft im Hintergrund.
Wir können es mit der aigenerate -Funktion verwenden:
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?") Für gemeinsame Modelle, die registriert wurden (siehe ?PT.MODEL_REGISTRY
msg = aigenerate ( " Say hi! " ; model = " openhermes2.5-mistral " ) Und wir können auch die aiembed -Funktion verwenden:
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}: Sie können jetzt auch aiscan verwenden, um Ollama -Models Bilder anzubieten! Weitere Informationen finden Sie in den Dokumenten.
Wenn Sie Fehler erhalten, überprüfen Sie, ob Ollama ausgeführt wird. Siehe den Abschnitt "Setup" für Ollama unten.
Mistral-Modelle dominieren seit langem den Open-Source-Raum. Sie sind jetzt über ihre API erhältlich, sodass Sie sie mit AufregungsTools.jl verwenden können!
msg = aigenerate ( " Say hi! " ; model = " mistral-tiny " ) Es funktioniert nur, denn wir haben die Modelle in der PromptingTools.MODEL_REGISTRY registriert! Derzeit stehen 4 Modelle zur Verfügung: mistral-tiny , mistral-small , mistral-medium , mistral-embed .
Unter der Motorhaube verwenden wir ein spezielles Schema MistralOpenAISchema , das den größten Teil der OpenAI-spezifischen Codebasis nutzt, sodass Sie dies immer explizit als erstes Argument angeben können:
const PT = PromptingTools
msg = aigenerate (PT . MistralOpenAISchema (), " Say Hi! " ; model = " mistral-tiny " , api_key = ENV [ " MISTRAL_API_KEY " ]) Wie Sie sehen können, können wir Ihre API -Schlüssel entweder aus der ENV oder über den Mechanismus der Vorlieben laden (siehe ?PREFERENCES für weitere Informationen).
Aber Mistralai sind nicht die einzigen! Es gibt viele andere aufregende Anbieter, z. B. Verwirrung.ai, Fireworks.ai. Solange sie mit der OpenAI -API kompatibel sind (z. B. Senden messages mit role und content ), können Sie sie mit der Verwendung von schema = CustomOpenAISchema() verwenden:
# 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 " ))Wie Sie sehen können, funktioniert es auch für alle lokalen Modelle, die Sie möglicherweise auf Ihrem Computer ausgeführt haben!
Hinweis: Im Moment unterstützen wir nur aigenerate und aiembed Funktionen für Mistralai und andere OpenAI-kompatible APIs. Wir planen, die Unterstützung in Zukunft zu erweitern.
Stellen Sie sicher, dass die Umgebungsvariable ANTHROPIC_API_KEY auf Ihren API -Schlüssel eingestellt ist.
# cladeuh is alias for Claude 3 Haiku
ai " Say hi! " claudeh Voreinstellungsmodell -Aliase sind claudeo , claudes und claudeh für Claude 3 Opus, Sonett bzw. Haiku.
Das entsprechende Schema ist AnthropicSchema .
Der Name befindet sich mit XML mehrere schnelle Vorlagen, was darauf hindeutet, dass sie eine anthrop-freundliche XML-Formatierung für die Trennung von Abschnitten verwenden. Finden Sie sie mit 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 ...
Weitere Beispiele finden Sie in den Beispielen/ Ordner.
Das Paket basiert auf drei Schlüsselelementen:
aigenerate , aiembed , aiclassify ) Warum dieses Design? Unterschiedliche APIs erfordern unterschiedliche Eingabeaufforderungformate. Zum Beispiel erfordert die API von OpenAI eine Reihe von Wörterbüchern mit role und content , während Ollamas API für Zephyr-7b-Modell ein ChatML-Schema mit einer großen Zeichenfolge und Separatoren wie <|im_start|>usernABC...<|im_end|>user benötigt. Um Abschnitte in Ihrer Eingabeaufforderung zu trennen, bevorzugt Openai Markdown -Header ( ##Response ) gegen Anthropic mit HTML -Tags besser ( <text>{{TEXT}}</text> ).
Dieses Paket ist stark vom Ausbilder inspiriert und es wird clevere Verwendung von Funktionsaufruf -API verwendet.
Schnelle Schemas
Der Schlüsseltyp für die Anpassung der Logik für die Vorbereitung von Eingaben für LLMs und das Aufrufen (über mehrere Versand).
Alle sind Subtypen von AbstractPromptSchema , und jede Aufgabenfunktion hat eine generische Signatur mit Schema im ersten Position foo(schema::AbstractPromptSchema,...)
Der Versand ist sowohl für "Rendern" von Eingabeaufforderungen ( render ) als auch für die Aufrufen der APIs ( aigenerate ) definiert.
Im Idealfall wird jede neue Schnittstelle in einer separaten llm_<interface>.jl -Datei (z. B. llm_openai.jl ) definiert.
Nachrichten
Eingabeaufforderungen sind effektiv ein Gespräch, das abgeschlossen werden soll.
Konversationen haben in der Regel drei wichtige Akteure: System (für Gesamtanweisungen), Benutzer (für Eingaben/Daten) und AI -Assistent (für Ausgänge). Wir bieten SystemMessage , UserMessage und AIMessage -Typen für jeden von ihnen an.
Bei einem schnellen Schema und einer oder mehreren Nachricht können Sie das resultierende Objekt in die Modell -API render . ZB für 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?")Dieses Objekt kann direkt an die OpenAI -API zur Verfügung gestellt werden.
Aufgabenorientierte Funktionen
Das Aspiration besteht darin, eine Reihe einfach zu erinnerten Funktionen für gemeinsame Aufgaben zu liefern. Daher beginnen alle mit ai... Alle Funktionen sollten einen leichten Wrapper mit daraus resultierenden Antworten zurückgeben. Derzeit kann es sich nur um AIMessage (für jede textbasierte Antwort) oder eine generische DataMessage (für strukturierte Daten wie Einbettungen) handeln.
Angesichts der Unterschiede in den Modell -APIs und deren Parametern (z. B. OpenAI -API vs Ollama) werden Aufgabenfunktionen auf schema::AbstractPromptSchema als erstes Argument versandt.
Eine Beispielimplementierung finden Sie src/llm_openai.jl . Jede neue Schnittstelle wird in einer separaten llm_<interface>.jl -Datei definiert.
OpenAIs Modelle stehen an der Spitze der AI-Forschung und bieten für viele Aufgaben robuste und modernste Fähigkeiten.
Es wird Situationen geben oder nicht verwenden (z. B. Privatsphäre, Kosten usw.). In diesem Fall können Sie lokale Modelle (z. B. Ollama) oder andere APIs (z. B. anthropisch) verwenden.
Hinweis: Um mit Ollama.ai zu beginnen, finden Sie den Setup -Leitfaden für den Abschnitt Ollama unten.
Es gibt viele Alternativen:
Zum Zeitpunkt des Schreibens verwendet OpenAI die API nicht, um ihre Modelle auszubilden.
API
OpenAI verwendet keine Daten, die von unserer API übermittelt und generiert werden, um OpenAI -Modelle zu schulen oder das OpenAI -Serviceangebot zu verbessern. Um die kontinuierliche Verbesserung unserer Modelle zu unterstützen, können Sie dieses Formular ausfüllen, um Ihre Daten mit uns zu teilen. - Wie Ihre Daten verwendet werden, um unsere Modelle zu verbessern
Sie können die neuesten Informationen über die Verwendung Ihrer Datenseite von OpenAI immer überprüfen.
Ressourcen:
Sie können Ihren API -Schlüssel von OpenAI erhalten, indem Sie sich für ein Konto anmelden und auf den API -Abschnitt der OpenAI -Website zugreifen.
Ressourcen:
Tipp
Stellen Sie immer die Ausgabengrenzen ein!
Mit OpenAI können Sie die Ausgabenlimits direkt auf Ihrem Konto -Dashboard festlegen, um unerwartete Kosten zu vermeiden.
Ein guter Start könnte eine weiche Grenze von c. 5 US -Dollar und ein hartes Limit von c. 10 US -Dollar sein - Sie können ihn immer später im Monat erhöhen.
Ressourcen:
Wenn Sie ein lokales Modell (z. B. mit Ollama) verwenden, ist es kostenlos. Wenn Sie kommerzielle APIs (z. B. OpenAI) verwenden, zahlen Sie wahrscheinlich pro "Token" (eine Unterworteinheit).
Beispielsweise kostet eine einfache Anfrage mit einer einfachen Frage und 1-Satzantwort im Gegenzug (”ist Aussage xyz ein positiver Kommentar“) ~ ~ $ 0,0001 (dh einhundertstel eines Cents).
Lohnt es sich, dafür zu bezahlen?
Genai ist eine Möglichkeit, Zeit zu kaufen! Sie können Cent bezahlen, um jeden Tag zehn Minuten zu sparen.
Stellen Sie sich vor, Sie haben eine Tabelle mit 200 Kommentaren. Jetzt können Sie jeden von ihnen mit einem LLM für die Funktionen/Überprüfungen analysieren, die Sie benötigen. Unter der Annahme, dass der Preis pro Anruf 0,0001 USD betrug, zahlen Sie 2 Cent für den Job und sparen 30-60 Minuten Ihrer Zeit!
Ressourcen:
Dies ist ein Leitfaden für den API -Schlüssel von OpenAI, aber es funktioniert für jeden anderen API -Schlüssel, den Sie möglicherweise benötigen (z. B. MISTRAL_API_KEY für Mistalai -API).
Stellen Sie Ihre API -Schlüssel als Umgebungsvariable fest:
ENV [ " OPENAI_API_KEY " ] = " your-api-key "Als einmaliges können Sie:
export OPENAI_API_KEY = <your key>setup.jl ein (stellen Sie sicher, dass Sie es nicht für GitHub verpflichten!) Stellen Sie sicher, dass Sie Julia aus demselben Terminalfenster starten, in dem Sie die Variable festlegen. Einfach einchecken in Julia, run ENV["OPENAI_API_KEY"] und Sie sollten Ihren Schlüssel sehen!
Ein besserer Weg:
~/.zshrc ) hinzu. Es wird jedes Mal automatisch geladen, wenn Sie das Terminal starten Wir unterstützen auch Einstellungen.jl, sodass Sie einfach ausführen können: PromptingTools.set_preferences!("OPENAI_API_KEY"=>"your-api-key") und es wird über Sitzungen bestehen. Um die aktuellen Einstellungen anzuzeigen, führen Sie PromptingTools.get_preferences("OPENAI_API_KEY") aus.
Achten Sie darauf, dass Sie nicht LocalPreferences.toml für GitHub begehen, da dies Ihre API -Schlüssel für die Welt zeigen würde!
Ressourcen:
aigenerate ( api_kwargs )Weitere Informationen finden Sie unter OpenAI -API -Referenz.
Fügen Sie für einfachen Zugriff von überall zu Auflauftools in Ihr startup.jl hinzu (finden Sie in ~/.julia/config/startup.jl ).
Fügen Sie den folgenden Snippet hinzu:
using PromptingTools
const PT = PromptingTools # to access unexported functions and types
Jetzt können Sie nur ai"Help me do X to achieve Y" von jeder Wiederholungssitzung!
Das Ethos von PromptionTools.jl besteht darin, Ihnen das gewünschte Modell zu verwenden, das Open Source -LLMs enthält. Das beliebteste und am einfachsten zu errichtende Setup ist Ollama.ai - Weitere Informationen finden Sie weiter unten.
Ollama leitet einen Hintergrunddienst Hosting -LLMs aus, auf den Sie über eine einfache API zugreifen können. Es ist besonders nützlich, wenn Sie mit einigen sensiblen Daten arbeiten, die nirgendwo gesendet werden sollten.
Die Installation ist sehr einfach. Laden Sie einfach die neueste Version hier herunter.
Sobald Sie es installiert haben, starten Sie einfach die App und Sie sind bereit zu gehen!
Um zu überprüfen, ob es ausgeführt wird, gehen Sie zu Ihrem Browser und öffnen Sie 127.0.0.1:11434 . Sie sollten die Nachricht "Ollama läuft" sehen. Alternativ können Sie ollama serve in Ihrem Terminal ausführen und erhalten eine Nachricht, die bereits ausgeführt wird.
In der Ollama-Bibliothek sind viele Modelle erhältlich, darunter Lama2, Codellama, SQLCoder oder mein persönliches Lieblings openhermes2.5-mistral .
Laden Sie neue Modelle mit ollama pull <model_name> herunter (z ollama pull openhermes2.5-mistral ).
Zeigen Sie derzeit verfügbare Modelle mit ollama list .
Weitere Informationen finden Sie unter Ollama.ai.
Feinabstimmung ist eine leistungsstarke Technik, um ein Modell an Ihren spezifischen Anwendungsfall anzupassen (hauptsächlich das Format/die Syntax/die Aufgabe). Es erfordert einen Datensatz von Beispielen, die Sie jetzt problemlos mit AufregungsTools.jl generieren können!
Sie können jede Konversation (Vektor von Nachrichten) in einer Datei mit PT.save_conversation("filename.json", conversation) speichern.
Sobald die Finetuning-Zeit vorliegt, erstellen Sie in einer einzigen .jsonl Datei ein Bündel von mit Sharegpt-formatierten Gesprächen (gemeinsames Finetuning-Format). Verwenden Sie PT.save_conversations("dataset.jsonl", [conversation1, conversation2, ...]) (Beachten Sie, dass Plural "Gespräche" im Funktionsnamen).
Ein Beispiel für einen End-to-End-Finetuning-Prozess finden Sie in unserem Schwesterprojekt Juliallmleaderboard-Finetuning-Experiment. Es zeigt den Prozess der Finetuning für einen halben Dollar mit Jarvislabs.ai und Axolotl.
Dies ist eine Liste von Funktionen, die ich in Zukunft gerne sehen würde (in keiner bestimmten Reihenfolge):
Weitere Informationen, Beiträge oder Fragen finden Sie im Github -Repository für die Aufregung .jl Github.
Bitte beachten Sie, dass es während der Anstrengung von AufregungsTools.jl darauf abzielt, eine reibungslose Erfahrung zu bieten, die sich jedoch auf externe APIs beruht, die sich ändern können. Bleiben Sie auf dem Repository auf dem Laufenden, um Updates und neue Funktionen zu erhalten.
Vielen Dank, dass Sie sich für die Auswahl von AufregungsTools.jl entschieden haben, um Ihre Bewerbungen mit KI zu befähigen!