Bezieht sich auf das sorgfältige Design und die Optimierung von Eingaben (z. B. Abfragen oder Anweisungen), um das Verhalten und die Reaktionen generativer KI -Modelle zu leiten. Eingabeaufforderungen werden typischerweise entweder mit dem deklarativen oder dem imperativen Paradigma oder einer Mischung aus beiden strukturiert. Die Wahl des Paradigmas kann einen großen Einfluss auf die Genauigkeit und Relevanz der resultierenden Modellausgabe haben. Dieser Artikel bietet einen konzeptionellen Überblick über deklarative und crucial Aufforderung, erörtert Vorteile und Einschränkungen jedes Paradigmas und berücksichtigt die praktischen Auswirkungen.

Das was und das wie

In einfachen Worten drücken deklarative Aufforderungen aus Was sollte erledigt werden, während zwingende Eingabeaufforderungen angeben Wie etwas sollte getan werden. Angenommen, Sie sind mit einem Freund in einer Pizzeria. Sie sagen dem Kellner, dass Sie den Neapolitaner haben werden. Da Sie nur die gewünschte Pizza erwähnen, ohne genau anzugeben, wie Sie es vorbereiten möchten, ist dies ein Beispiel für eine deklarative Aufforderung. In der Zwischenzeit hat Ihr Freund – der einige ganz besondere kulinarische Vorlieben hat und Lust auf eine maßgeschneiderte Pizza hat Alle Quattro Stagioni – Erzählt dem Kellner genau, wie sie es mögen würde; Dies ist ein Beispiel für eine crucial Eingabeaufforderung.

Deklarative und crucial Ausdrucksparadigmen haben eine lange Geschichte im Pc, wobei einige Programmiersprachen ein Paradigma gegenüber dem anderen bevorzugen. Eine Sprache wie C wird tendenziell zur imperativen Programmierung verwendet, während eine Sprache wie Prolog auf deklarative Programmierung ausgerichtet ist. Betrachten Sie beispielsweise das folgende Downside, die Vorfahren einer Individual namens Charlie zu identifizieren. Wir kennen die folgenden Fakten über Charlies Verwandte: Bob ist Charlies Elternteil, Alice ist Bobs Elternteil, Susan ist Daves Elternteil und John ist Alices Elternteil. Basierend auf diesen Informationen zeigt der folgende Code, wie wir Charlies Vorfahren mit Prolog identifizieren können.

father or mother(alice, bob).
father or mother(bob, charlie).
father or mother(susan, dave).
father or mother(john, alice).

ancestor(X, Y) :- father or mother(X, Y).
ancestor(X, Y) :- father or mother(X, Z), ancestor(Z, Y).

get_ancestors(Individual, Ancestors) :- findall(X, ancestor(X, Individual), Ancestors).

?- get_ancestors(charlie, Ancestors).

Obwohl die Prolog -Syntax zunächst seltsam erscheinen magazine, drückt sie tatsächlich das Downside aus, das wir auf prägnante und intuitive Weise lösen möchten. Erstens legt der Code die bekannten Tatsachen dar (dh der, wer ist, der der der ist, der ist). Es definiert dann rekursiv das Prädikat ancestor(X, Y)was bewertet zu true, wenn X ist ein Vorfahr von Y. Schließlich das Prädikat findall(X, Purpose, Listing) löst den Prolog -Dolmetscher aus, um wiederholt zu bewerten Purpose und alle erfolgreichen Bindungen von speichern X In Listing. In unserem Fall bedeutet dies, alle Lösungen an zu identifizieren ancestor(X, Individual) und sie in der Variablen speichern Ancestors. Beachten Sie, dass wir die Implementierungsdetails (das „Wie“) keiner dieser Prädikate (das „Was“) angeben.

Im Gegensatz dazu identifiziert die nachstehende C -Implementierung Charlies Vorfahren, indem es in sorgfältigen Particulars genau so beschreibt, wie dies getan werden sollte.

#embody <stdio.h>
#embody <string.h>

#outline MAX_PEOPLE 10
#outline MAX_ANCESTORS 10

// Construction to characterize father or mother relationships
typedef struct {
    char father or mother(20);
    char baby(20);
} ParentRelation;

ParentRelation relations() = {
    {"alice", "bob"},
    {"bob", "charlie"},
    {"susan", "dave"},
    {"john", "alice"}
};

int numRelations = 4;

// Verify if X is a father or mother of Y
int isParent(const char *x, const char *y) {
    for (int i = 0; i < numRelations; ++i) {
        if (strcmp(relations(i).father or mother, x) == 0 && strcmp(relations(i).baby, y) == 0) {
            return 1;
        }
    }
    return 0;
}

// Recursive perform to examine if X is an ancestor of Y
int isAncestor(const char *x, const char *y) {
    if (isParent(x, y)) return 1;
    for (int i = 0; i < numRelations; ++i) {
        if (strcmp(relations(i).baby, y) == 0) {
            if (isAncestor(x, relations(i).father or mother)) return 1;
        }
    }
    return 0;
}

// Get all ancestors of an individual
void getAncestors(const char *individual, char ancestors()(20), int *numAncestors) {
    *numAncestors = 0;
    for (int i = 0; i < numRelations; ++i) {
        if (isAncestor(relations(i).father or mother, individual)) {
            strcpy(ancestors(*numAncestors), relations(i).father or mother);
            (*numAncestors)++;
        }
    }
}

int essential() {
    char individual() = "charlie";
    char ancestors(MAX_ANCESTORS)(20);
    int depend;

    getAncestors(individual, ancestors, &depend);

    printf("Ancestors of %s:n", individual);
    for (int i = 0; i < depend; ++i) {
        printf("%sn", ancestors(i));
    }

    return 0;
}

Heutzutage können wir die zunehmende Verfügbarkeit von Merkmalsbibliotheken und APIs und die Konsolidierung architektonischer Greatest Practices (z. B. Programmierung an Schnittstellen, Konfiguration über Code) auf das „Was“ konzentrieren, ohne sich um das „Wie“ zu sorgen müssen. Wie in dem kurzen Video unten vorgeschlagen, kann und sollte viel Code auf deklarative Weise geschrieben werden.

https://www.youtube.com/watch?v=e7fbf7r3x6i

Von der Programmierung bis zur Aufforderung

Wenn wir uns als den nächsten Evolutionsschritt in der Programmierung als den nächsten Evolutionsschritt vorstellen, verfolgt die Reise von maschinenorientierten Sprachen wie Meeting und C auf menschlichere Sprachen wie Java und Python-, dann wird die Relevanz von deklarativen und imperativen Paradigmen zur Erfordernis des Ingenieurwesens zu erkennen. Obwohl wir jetzt ein generatives KI Was ist zu erreichen gegen Wie es ist zu erreichen.

Betrachten Sie das Szenario eines Entwicklers, der einen AI -Assistenten verwenden möchte, um Code zu generieren – insbesondere Python -Code, um den Kosinusabstand zwischen zwei Vektoren zu berechnen. Im Folgenden finden Sie drei Versionen einer Aufforderung, die der Entwickler schreibt, um ihr Ziel zu erreichen. Model 1 ist deklarativ, Model 2 ist unabdingbar und Model 3 ist ein Hybrid der beiden. Der Code, der durch das GPT-4-Modell von OpenAI als Reaktion auf jede dieser Eingabeaufforderungen generiert wird, wird ebenfalls bereitgestellt.

Eingabeaufforderung Model 1 (deklarativ)

Schreiben Sie eine kurze und schnelle Funktion in Python, um den Kosinusabstand zwischen zwei Eingangsvektoren zu berechnen.

Ergebnis:

import numpy as np

def cosine_distance(u, v):
    u = np.array(u)
    v = np.array(v)
    return 1 - np.dot(u, v) / (np.linalg.norm(u) * np.linalg.norm(v))

Eingabeaufforderung Model 2 (Imperativ)

Schreiben Sie eine Python -Funktion Cosinus_Distance (V1, V2), die den Kosinusabstand zwischen zwei Vektoren berechnet. Befolgen Sie diese Schritte mit nur integrierten Funktionen:

1. Erhöhen Sie eine ValueError -Ausnahme, wenn V1 oder V2 leer sind oder ob V1 und V2 unterschiedliche Längen haben.

2. Berechnen Sie das Punktprodukt von V1 und V2.

3. Berechnen Sie die Größe jedes Vektors und erhöhen Sie einen ValueError, wenn eine der beiden Größen Null ist.

V.

5. Machen Sie 1 minus die Kosinus -Ähnlichkeit, um einen Kosinusabstand zu erhalten.

S.

Ergebnis:

import math

def cosine_distance(v1, v2):
    # Step 1: Enter validation
    if not v1 or not v2:
        increase ValueError("Enter vectors should not be empty.")
    if len(v1) != len(v2):
        increase ValueError("Vectors should be of the identical size.")

    # Step 2: Compute dot product
    dot_product = sum(a * b for a, b in zip(v1, v2))

    # Step 3: Compute magnitudes
    mag_v1 = math.sqrt(sum(a ** 2 for a in v1))
    mag_v2 = math.sqrt(sum(b ** 2 for b in v2))

    if mag_v1 == 0 or mag_v2 == 0:
        increase ValueError("Vectors should not have zero magnitude.")

    # Step 4 & 5: Compute cosine similarity and distance
    cosine_similarity = dot_product / (mag_v1 * mag_v2)
    cosine_distance = 1 - cosine_similarity

    # Step 6: Return outcome
    return cosine_distance

Eingabeaufforderung Model 3 (Hybrid)

Schreiben Sie eine schnelle Python -Funktion, die den Kosinusabstand zwischen zwei Vektoren V1 und V2 unter Verwendung relevanter optimierter Funktionen von Numpy und Scipy berechnet. Die Funktion sollte die Eingangsvektoren (nicht leere, gleiche Länge) validieren und ungültige Eingänge mit Ausnahmen ordnungsgemäß verarbeiten.

Ergebnis:

import numpy as np
from scipy.spatial.distance import cosine

def cosine_distance(v1, v2):
    # Convert inputs to NumPy arrays
    v1 = np.asarray(v1, dtype=np.float64)
    v2 = np.asarray(v2, dtype=np.float64)

    # Validation checks
    if v1.dimension == 0 or v2.dimension == 0:
        increase ValueError("Enter vectors should be non-empty.")
    if v1.form != v2.form:
        increase ValueError("Vectors should have the identical form.")
    if not np.any(v1) or not np.any(v2):
        increase ValueError("Vectors should not be zero vectors.")

    # Compute cosine distance utilizing optimized perform
    return cosine(v1, v2)

Pferde für Kurse

Die drei Eingabeaufforderungen und ihre jeweiligen AI-generierten Implementierungen implizieren unterschiedliche Kompromisse und können für verschiedene Personas und Szenarien in der Praxis geeignet sein.

Die deklarative Eingabeaufforderung (Model 1) ist kurz und einfach. Es gibt keine Particulars des genauen algorithmischen Ansatzes an, das stattdessen nur die Aufgabe auf hoher Ebene ausdrückt. Daher fördert es Kreativität und Flexibilität bei der Implementierung. Der Nachteil einer solchen Aufforderung ist natürlich, dass das Ergebnis möglicherweise nicht immer reproduzierbar oder strong ist. Im obigen Fall könnte der von der deklarativen Eingabeaufforderung generierte Code bei Inferenzaufrufen erheblich variieren und keine Kantenfälle behandeln, was ein Downside sein kann, wenn der Code für die Verwendung in der Produktion vorgesehen ist. Trotz dieser Einschränkungen zählen typische Personas, die das deklarative Paradigma bevorzugen können, Produktmanager, UX-Designer und Enterprise-Area-Experten, denen kein Coding-Fachwissen vorliegt und möglicherweise keine KI-Antworten für Produktionsstörungen benötigt. Softwareentwickler und Datenwissenschaftler können auch deklarative Aufforderung verwenden, schnell einen ersten Entwurf zu generieren, es wird jedoch erwartet, dass sie den Code anschließend überprüfen und verfeinern. Natürlich muss man bedenken, dass die Zeit, die zur Verbesserung des Code für den generierten A-Generium erforderlich ist, die Zeit, die durch das Schreiben einer kurzen deklarativen Eingabeaufforderung erst einmal gespeichert wird, absagen kann.

Im Gegensatz dazu lässt die crucial Eingabeaufforderung (Model 2) nur sehr wenig dem Zufall überlassen – jeder algorithmische Schritt wird im Element angegeben. Die Abhängigkeiten von nicht standardmäßigen Paketen werden ausdrücklich vermieden, was bestimmte Probleme bei der Produktion umgehen kann (z. B. Veränderungen oder Abschreibungen in Paketen von Drittanbietern, Schwierigkeiten beim Debugieren des seltsamen Codeverhaltens, der Exposition gegenüber Sicherheitsanfälligkeiten, Installationsaufwand). Die größere Kontrolle und Robustheit sind jedoch auf Kosten einer ausführlichen Eingabeaufforderung, die quick genauso mühelig intensiv sein kann wie das direkte Schreiben des Code. Typische Personas, die sich für eine crucial Aufforderung entscheiden, können Softwareentwickler und Datenwissenschaftler umfassen. Während sie in der Lage sind, den tatsächlichen Code von Grund auf neu zu schreiben, ist es möglicherweise effizienter, stattdessen Pseudocode in ein generatives KI -Modell zu versorgen. Beispielsweise kann ein Python -Entwickler Pseudocode verwenden, um schnell Code in einer anderen und weniger vertrauten Programmiersprache wie C ++ oder Java zu generieren, wodurch die Wahrscheinlichkeit syntaktischer Fehler und die Zeit verringert wird, die sie debuggen.

Schließlich versucht die Hybrid -Eingabeaufforderung (Model 3), das Beste aus beiden Welten zu kombinieren, wobei imperativen Anweisungen die wichtigsten Implementierungsdetails festgelegt werden (z. B. die Verwendung von Numpy und Scipy) und ansonsten deklarative Formulierungen einsetzt, um die allgemeine schnelle und leicht zu folgen. Hybridaufforderungen bieten Freiheit innerhalb eines Rahmens und leiten die Implementierung, ohne sie vollständig einzusperrten. Typische Personas, die sich möglicherweise zu einer Mischung deklarativer und imperativer Aufforderung stützen können, sind hochrangige Entwickler, Datenwissenschaftler und Lösungsarchitekten. Beispielsweise möchte ein Datenwissenschaftler im Fall der Codegenerierung einen Algorithmus unter Verwendung erweiterter Bibliotheken optimieren, die ein generatives KI -Modell möglicherweise standardmäßig nicht auswählt. In der Zwischenzeit muss ein Lösungsarchitekt möglicherweise ausdrücklich die KI von bestimmten Komponenten von Drittanbietern ablenken, um den architektonischen Richtlinien einzuhalten.

Letztendlich sollte die Wahl zwischen deklarativen und imperativen schnellen Ingenieurwesen für generative KI eine absichtliche sein und die Vor- und Nachteile jedes Paradigmas im angegebenen Anwendungskontext abwägen.

Von admin

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert