Es passiert an einem Donnerstag. Der Agent reagiert schon seit einer Woche schlecht, und als Sie endlich die Systemabfrage öffnen, verstehen Sie, warum: achttausend Token, alle in einem Block. Immer im Kontext. Selbst wenn der Benutzer nur darum bittet, eine E-Mail zu übersetzen.
Das nennt man Aufblähung der Eingabeaufforderung. Und es ist der schnellste Weg, einen KI-Agenten gleichzeitig dumm und teuer zu machen.
In den letzten Monaten habe ich mehrmals an ein und demselben internen Assistenten für WebWakeUp gearbeitet und bin jedes Mal in der gleichen Sackgasse gelandet: ein einzelner Agent, der zu viele verschiedene Dinge tun muss (Meta-Beschreibungen im Stil von Kunde X schreiben, PDFs auf Vorlagen generieren, Nachforschungen über Mitbewerber anstellen, Support-Tickets beantworten), und eine Systemaufforderung, die mit jeder neuen hinzugefügten Fähigkeit wächst. Das Modell beginnt, die Regeln zu verwirren, die Antworten fallen flach, die Kosten steigen. Klassisch.
Dann überflog ich die Anthropic-Dokumentation auf der Agent-Fähigkeiten, Ich habe die benötigten Teile behalten und versucht, das Muster selbst gehostet in n8n einzubringen. Es funktioniert. Es funktioniert gut. Aber mit ein paar Unterschieden, die ich nicht überall geschrieben finde, also reden wir hier darüber.
Was folgt, ist eine technische Lektüre, in einer Version, die noch in Arbeit ist. Ich bin noch am Testen, betrachten Sie es also als eine offene Baustelle, nicht als fertiges Handbuch. Wenn Sie Dinge sehen, die nicht stimmen, schreiben Sie mir: Das Stück ist dafür gedacht.
Ein KI-Agent hat Kosten pro Schicht, die proportional zur Größe seiner Systemansage sind. Wenn Sie alle Anweisungen für alle möglichen Aufgaben in die Systemeingabeaufforderung aufnehmen, zahlen Sie diesen Preis auch dann, wenn der Benutzer nach der Zeit fragt. Wenn Sie sie hingegen weglassen, weiß der Agent nicht, wie er etwas Bestimmtes tun soll. Dieses Problem ist so alt wie die ersten ausgeklügelten Eingabeaufforderungen, und hier hat Anthropic zum ersten Mal seine Hand ins Spiel gebracht, und zwar ganz geschickt.
Die Antwort, die sie konstruiert haben, heißt schrittweise Offenlegung, was mit “schichtweises Laden des Kontexts” übersetzt werden kann. Der Agent sieht bei allen Schichten nur ein sehr kleines Poster und lädt den Rest nur, wenn er wirklich gebraucht wird.
Das Anthropic-Muster unterteilt die Kontextladung in drei Ebenen. Sie getrennt zu halten, ist der Schlüssel zur ganzen Geschichte.
Stufe eins, immer geladen. Nur Name und Beschreibung jeder Fähigkeit, jeweils eine Zeile. Dreißig oder fünfzig Token pro Fähigkeit. Kostet wenig, befindet sich in der System-Eingabeaufforderung und dient dem LLM zur Erkennung (um zu sehen, ob die Anfrage des Benutzers mit einer der verfügbaren Fähigkeiten übereinstimmt).
Stufe zwei, auf Spiel geladen. Wenn der LLM eine relevante Fähigkeit erkennt, ruft er ein Tool auf, das die vollständigen Anweisungen für diese Fähigkeit liefert. Fünfhundert, tausend, zweitausend Token: das hängt von der Fertigkeit ab. Sie werden nur für diesen Zug (oder nachfolgende Züge, solange sie benötigt werden) in den Kontext eingefügt, sie werden nicht bei jeder Anfrage neu geladen.
Stufe drei, geladen auf Anfrage der Fähigkeit selbst. Eine Fähigkeit kann in ihren Anweisungen sagen: “Wenn die Situation X ist, lesen Sie auch die Beispieldatei”. Der Agent ruft ein zweites Tool auf, lädt die zusätzlichen Referenzen herunter und behält sie nur so lange im Kontext, wie er sie braucht. Lange Beispiele, Grenzfälle, Referenztabellen, leben hier.
Das Ergebnis ist, dass die Eingabeaufforderung des Systems lebenslang klein bleibt, selbst wenn fünfzig oder hundert Fertigkeiten im Katalog sind. Sie zahlen nur für die zusätzlichen Token, wenn der Benutzer eine Anfrage stellt, die sie rechtfertigt. Kein Wasser, keine leeren Kosten.
Anthropic verwendet es offensichtlich in seinen Produkten (Claude Code, seine Skills, das Agent SDK). Die Frage ist: Kann dasselbe Muster in n8n repliziert werden, ohne etwas zu erfinden? Die Antwort ist ja, und fast alles wird mit nativen Nodes gemacht.
Das Spielzeug besteht aus vier Teilen: AI Agent (Version 3.1, ab 1.82.0 ist es Tools Agent fixed und das ist gut so), Call n8n Workflow Tool (Version 2.2), Execute Workflow Trigger (Version 1.1), Postgres (Version 2.6). Und ein kleiner Code-Knoten, um das Manifest zu erstellen. Anhalten.
Die Idee ist einfach. Meine “Skill-Dateien” leben nicht als .md auf dem Dateisystem (wie bei Anthropic), sondern als Zeilen einer Postgres-Tabelle. Eigentlich sind es zwei Tabellen: eine für die Fähigkeiten, eine für ihre zusätzlichen Referenzen. Der MAIN_AGENT erstellt zu Beginn jeder Sitzung eine SELECT aller aktiven Fähigkeiten und erstellen das Manifest an Ort und Stelle. Die Sub-Workflows, die als Werkzeuge offengelegt werden, dienen dem Modell dazu, bei Bedarf zu fragen: “Gib mir Fähigkeit X” oder “Gib mir Referenz Y von Fähigkeit X”.
Kein benutzerdefinierter Code, keine externen Plugins, keine zusätzlichen APIs, die Sie pflegen müssen. Nur Knoten.
Hier spiele ich mit einer Meinung und halte mir die Türen offen: Ich lese es so, Sie sagen es mir.
n8n hat die Daten-Tabellen durch mehrere Versionen integriert. Native, über die Schnittstelle verwaltete Tabellen mit einem exponierten REST-API-Endpunkt (/Datentabellen), um auch von außerhalb damit zu interagieren, nativer CSV-Import/Export, eingeschränkter Zugriff pro Projekt. Für das Prototyping eines solchen Systems sind sie perfekt: Sie können einen Workflow in einer halben Stunde einrichten, Zeilen werden per Mausklick bearbeitet, und wenn Sie ein externes Panel benötigen, ist die API da.
Aber um ein Skill-System darauf zu setzen, von dem wir behaupten, dass es Monate, Jahre hält und wächst, gibt es dokumentierte Einschränkungen, die abgewogen werden müssen. Nichts Dramatisches, keine “geschlossene Box”, aber präzise Grenzen, die die Wahl verändern.
Säulen-Typen: Boolesch, Datum, Zahl, String. Kein JSON, kein VECTOR, kein BLOB. Also keine Einbettung in dieselbe Tabelle, keine willkürlich strukturierte Nutzlast.
FilterGleich, Nicht gleich, Größer als und Kleiner als (mit oder ohne Gleichheit), Ist leer, Ist nicht leer. Kein LIKE, kein Volltext, keine Ähnlichkeit. Für den Musterabgleich von Fähigkeiten rufen Sie das Manifest ab und Amen, keine serverseitige Vorfilterung.
BetriebEinfügen, Aktualisieren, Upsert, Löschen, Get auf Zeilen. Erstellen, Löschen, Auflisten, Aktualisieren von Tabellen. Kein rohes SQL.
Aufbewahrungskappe50MB standardmäßig für alle Datentabellen einer Instanz. Bei selbst gehosteten Instanzen, die über die Umgebungsvariable N8N_DATA_TABLES_MAX_SIZE_BYTES. n8n warnt bei 80%, blockiert Einfügen und Aktualisieren bei 100%. Für einen textuellen Skill-Katalog mag das für eine lange Zeit ausreichen, aber es ist eine Obergrenze, die Sie im Auge behalten sollten.
Kein Zugriff vom Knoten Code: wortwörtliches Zitat aus den Docs, “Direkter programmatischer Zugriff auf Datentabellen von einem Code-Knoten aus wird nicht unterstützt”.” Bei der oben beschriebenen Architektur, bei der ein Code-Knoten das Manifest verpackt, ist dies ein direktes Problem. Machbar (Knoten setzen nach einem Get-many anstelle von Code), aber die Form ändert sich.
Die Dokumentation schweigt sich über drei Dinge aus, daher behaupte ich dies nicht: native Versionierung, Verhalten bei starker Konkurrenz und ob n8n-Backups den Inhalt von Datentabellen enthalten. Ich weiß es nicht, ich werde nachsehen. Wenn Sie genaue Hinweise zu diesen drei Punkten haben, schreiben Sie mir.
Zusammenfassend kann ich sagen, dass ich mich trotzdem für Postgres entscheide, und dafür gibt es fünf Gründe, die alle konkret sind.
Erste, Ich möchte die 50MB Obergrenze aus dem Kopf haben. Eine Skill Registry, die durch Versionierung und Historie wachsen könnte, soll nicht von einem Schwellenwert abhängig sein.
Laut, Ich möchte die serverseitige Ähnlichkeitssuche an dem Tag, an dem die Fähigkeiten hundert oder mehr sind. pgvector ist bereit, bei den Datentabellen ist kein VECTOR-Typ am Horizont zu sehen.
Dritte, Ich möchte, dass der Code-Knoten frei ist, um Daten zu lesen und zu packen. Ich brauche ihn heute für die KI-Agent-Pipeline und morgen für die Export- und Backup-Pipelines.
Vierte, Ich möchte rohes SQL für den Tag, ich brauche eine Aggregation, einen JOIN, einen History Trigger. Der History-Trigger in Postgres ist eine Funktion für zehn Zeilen, bei Datentabellen muss er von Hand im Workflow erstellt werden.
Quinto, Ich habe kein Problem mit einem zusätzlichen Container. Meine n8n-Instanz befindet sich bereits in Docker Compose, fügen Sie ein Postgres mit Image hinzu pgvector/pgvector:pg16 kostet nichts an betrieblicher Reibung.
Wenn das Ziel eine kleine Spalte wäre, zehn oder zwanzig feste Fertigkeiten ohne Anspruch auf Wachstum, wäre Data Tables eine absolut vertretbare Wahl. In meinem Fall, mit einem Wachstumshorizont, den ich noch nicht kenne, den ich aber nicht blockieren möchte, habe ich den zusätzlichen Container genommen.
Vielleicht liege ich falsch. Wenn jemand ein Skill-System für Datentabellen in echtem Maßstab einführen würde (hundert, zweihundert Einträge, mit Historie und externer Verwaltung über die API /Datentabellen), würde ich sie gerne hören: Die Debatte ist eröffnet.
Dedizierter Container, keine Wiederverwendung von n8n. Ich möchte in der Lage sein, separate Backups zu erstellen, ich möchte die operative Datenbank von n8n nicht mit meinen Anwendungsdaten beschmutzen, ich möchte in der Lage sein, das ganze Spielzeug eines Tages woanders hin zu migrieren, ohne n8n auseinandernehmen zu müssen. Auf diese Weise ist es sauberer.
Ein wichtiger Punkt, den ich später bestätigte: das richtige Bild ist pgvector/pgvector:pg16, nicht postgres:16-alpine. Es handelt sich um ein Standard-Postgres plus die vorinstallierte pgvector-Erweiterung. Ohne die aktivierte Erweiterung verhält es sich wie ein Vanilla Postgres, null Overhead. Aber an dem Tag, an dem Sie die Ähnlichkeitssuche für den Sprung zu manifest-via-RAG aktivieren möchten, sind Sie schon dabei: keine Image-Migration, keine pg_dump kalt, keine Zeit verschwendet.
Dienstleistungen:
wwu-skills-db:
Bild: pgvector/pgvector:pg16
container_name: wwu-skills-db
Neustart: sofern nicht gestoppt
Umgebung:
POSTGRES_DB: wwu_skills
POSTGRES_USER: wwu_skills_user
POSTGRES_PASSWORD: ${WWU_SKILLS_DB_PASSWORD}
volumes:
- wwu_skills_data:/var/lib/postgresql/data
Netzwerke:
- n8n_network
Volumes:
wwu_skills_data:
Netzwerke:
n8n_network:
extern: true
Kein offener Port auf dem Host. Nur n8n spricht mit diesem Postgres über das interne Docker-Netzwerk. Das Passwort befindet sich in einer Umgebungsvariablen, nicht in der Datei.
Das eigentliche Schema. Drei Tabellen: Fähigkeiten, skill_references, skills_history. Und einen Auslöser, der bei jedem UPDATE archivieren Sie die vorherige Version, die Versionierung ist also kostenlos.
CREATE SCHEME IF NOT EXISTS skills_mgmt;
-- Tag 1: Aktivieren Sie die Erweiterung. Null Kosten, wenn nicht verwendet.
CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE skills_mgmt.skills (
name VARCHAR(80) PRIMARY KEY,
description TEXT NOT NULL,
content TEXT NOT NULL,
active BOOLEAN NOT NULL DEFAULT TRUE,
version INTEGER NOT NULL DEFAULT 1,
-- Einbettungsspalte, vorerst löschbar. Die Dimension entspricht Ihrer Einbettung
-- Modell: 1536 für text-embedding-3-small, 3072 für text-embedding-3-large.
beschreibung_einbettung vektor(1536),
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
CHECK (name ~ '^[a-z0-9-]+$')
);
CREATE TABLE skills_mgmt.skills_references (
id SERIAL PRIMARY KEY,
skill_name VARCHAR(80) NOT NULL
REFERENCES skills_mgmt.skills(name) ON DELETE CASCADE,
reference_name VARCHAR(120) NOT NULL,
content TEXT NOT NULL,
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
UNIQUE (skill_name, reference_name),
CHECK (referenz_name ~ '^[a-z0-9_.-]+$')
);
CREATE TABLE skills_mgmt.skills_history (
id BIGSERIAL PRIMARY KEY,
name VARCHAR(80) NOT NULL,
beschreibung TEXT,
inhalt TEXT,
version INTEGER,
archived_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
);
CREATE OR REPLACE FUNCTION skills_mgmt.fn_skills_history()
GIBT DEN TRIGGER ALS $$ ZURÜCK
BEGIN
INSERT INTO skills_mgmt.skills_history(Name, Beschreibung, Inhalt, Version)
VALUES (OLD.name, OLD.description, OLD.content, OLD.version);
NEW.version := OLD.version + 1;
NEW.updated_at := NOW();
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER trg_skills_history
BEFORE UPDATE ON skills_mgmt.skills
FOR EACH ROW EXECUTE FUNCTION skills_mgmt.fn_skills_history();
CREATE INDEX idx_skills_active
ON skills_mgmt.skills(active) WHERE active = TRUE;
I CHECK auf Namen sind nicht unbedingt notwendig, da die Abfragen durch den n8n Postgres-Knoten parametrisiert werden und die Injektion bereits abgedeckt ist. Aber es werden weitere Klammern gesetzt: Wenn jemand die Arbeitsabläufe umgeht und von Hand einfügt, lässt zumindest die Datenbank keine fremden Bezeichner durch.
Der HNSW-Index für die Ähnlichkeitssuche wird erst erstellt, wenn Sie die Spalte tatsächlich ausgefüllt haben beschreibung_einbettung. Die Erstellung eines leeren Feldes für eine NULL-Spalte ist sinnlos und verbraucht Speicher.
Drei separate Arbeitsabläufe. Ein Hauptarbeitsablauf und zwei kleine Arbeitsabläufe, die nur als Hilfsmittel dienen.
tool_load_skillDrei Knoten und das war's. Workflow-Auslöser ausführen mit inputSource: workflowInputs und eine einzige Eingabe deklariert { name: "skill_name", type: "string" }. Postgres im Modus executeQuery mit der unten stehenden Abfrage. Ein Knoten Setzen Sie final, die die Ausgabe normalisiert und entweder { skill_name, content } oder { error }.
SELECT Name, Beschreibung, Inhalt
FROM skills_mgmt.skills
WHERE name = $1 AND active = TRUE
LIMIT 1;
Der Parameter $1 ist gefüllt mit options.queryReplacement gleich ={ $json.skill_name }}. Keine String-Verkettung in der Abfrage, keine Injektion möglich, n8n bereinigt den Wert, bevor er ihn an den Treiber weitergibt. Dokumentiert, geprüft, vergessen.
tool_load_referenceIdentisch mit dem vorherigen, zwei Eingänge anstelle von einem: skill_name e referenz_name. Abfrage mit zwei Parametern, queryReplacement gleich ={{ $json.skill_name }},={{ $json.reference_name }}.
SELECT Inhalt
FROM skills_mgmt.skills_references
WHERE skill_name = $1 AND reference_name = $2
LIMIT 1;
MAIN_AGENTDer eigentliche Arbeitsablauf, derjenige, auf den der Client oder das interne System trifft. Vier Knoten in einer Reihe plus AI Agent-Unterknoten.
skills_mgmt.skills mit wobei: aktiv = wahr, outputColumns: Name, Beschreibung, returnAll: true. Laden Sie das Poster hoch.Der Code-Knoten ist das einzige Stück Code im ganzen System. Nichts Esoterisches:
/**
* Erstellen Sie einen kompakten JSON-Index für die Systemansage.
* Halten Sie die Beschreibung kurz, jedes Zeichen kostet Token bei jeder Umdrehung.
*/
const rows = $input.all().map(i => i.json);
const index = rows.map(r => ({
name: r.name,
Beschreibung: r.Beschreibung
}));
return [{ json: { skills_index: JSON.stringify(index, null, 2) } }];
Die Systemnachricht des KI-Agenten. Ja, er akzeptiert n8n-Ausdrücke: Ich habe dies direkt am TypeScript-Typ des Knotens bestätigt, systemMessage: string | Expression | PlaceholderValue. Also:
Sie sind der KI-Agent der WWU.
BEVOR Sie eine nicht-triviale Aufgabe ausführen, scannen Sie den SKILLS_INDEX unten nach einer passenden Fertigkeit.
Wenn eine Fähigkeit mit der Benutzeranfrage übereinstimmt, MÜSSEN Sie das Tool `load_skill` mit dessen
mit dem genauen Namen aufrufen, BEVOR Sie eine Ausgabe erzeugen. Erfinden Sie niemals Namen für Fertigkeiten. Produzieren Sie niemals ein
Ergebnis, das eine Fertigkeit verwenden soll, ohne sie vorher zu laden.
Wenn eine geladene Fertigkeit Sie anweist, eine Referenzdatei zu lesen, rufen Sie `load_reference`
nur dann auf, wenn die aktuelle Aufgabe diesen Detailgrad tatsächlich benötigt.
SKILLS_INDEX:
{{ $('Build Index').item.json.skills_index }}
Die beiden Workflow-Tools müssen mit zwei besonders raffinierten Dingen konfiguriert werden. Erstens, die Beschreibung des Tools, denn der LLM liest es und entscheidet, ob es aufgerufen wird. Verbringen Sie fünf Minuten damit, es richtig zu schreiben, das erspart Ihnen später stundenlange Fehlleitungen.
Zweitens müssen die Eingabeparameter des Sub-Workflows ausgefüllt werden, indem Sie auf die Schaltfläche “AI” auf dem Feld klicken, so dass das Modell den Wert über $fromAI(). Kodieren Sie sie niemals fest, setzen Sie niemals statische Ausdrücke darauf, sonst wird das Tool dumm und der LLM knallt dagegen.
Der Benutzer schreibt: “Schreiben Sie mir die Meta-Beschreibung für die E-Mail-Marketing-Seite”. Die Runde ist dies, erzählt in den beiden Zeitformen.
Zeit eins, die Vorbereitung des Kontextes. Der Chat-Trigger empfängt die Nachricht. Der Postgres-Knoten zieht die Zeilen mit den aktiven Fähigkeiten heraus (Name und Beschreibung, kein Inhalt), der Code-Knoten packt sie in einen wenige KB großen JSON-String, und der KI-Agent startet mit der Systemnachricht, die bereits mit dem Manifest versehen ist. All dies ist bei jeder Anfrage gleich und kostet nur sehr wenig.
Zeit zwei, Aktivierung der Fähigkeiten. Das Modell liest das Manifest, erkennt die wwu-meta-description, Anrufe load_skill unter Angabe des genauen Namens. Der Sub-Workflow führt die parametrisierte Abfrage aus und gibt den vollständigen Inhalt der Fähigkeit zurück. Das Modell liest ihn und entscheidet, ob es die zusätzlichen Referenzen benötigt (und wenn ja, ruft es load_reference), dann schreiben Sie die Meta-Beschreibung nach den Regeln, die Sie gerade geladen haben.
Der Punkt, unten.
Die System-Eingabeaufforderung bleibt die gleiche Größe wie bei zehn oder zweihundert Fertigkeiten. Die Kosten pro Runde ändern sich kaum. Die Kosten pro Eingabeaufforderung steigen nur im Verhältnis zu der Anzahl der tatsächlich geladenen Fertigkeiten, und das ist normalerweise eine. Vielleicht auch zwei. Niemals alle auf einmal.
Der ehrliche Teil des Artikels. Ich bin am Testen, und es gibt Dinge, zu denen ich gerne tausend weitere Meinungen hätte.
Unterknoten mit Ausdrücken und Erst-Einträgen. In den n8n-Dokumenten wird dies ausdrücklich erwähnt: Unterknoten, die ein Array von Elementen erhalten, lösen nur das erste auf. Wenn Sie aus irgendeinem Grund mehrere Elemente an den Werkzeug-Workflow übergeben, sieht der LLM nur das erste. Das bedeutet: Behalten Sie die Einweg-Tools mit nur einer Eingabe und einer Ausgabe bei. Kein Stapel.
Die Erinnerung beschmutzt sich selbst. Wenn Sie einen langen Speicherpuffer anlegen, landen die Antworten der Hilfsmittel im Gesprächsverlauf und werden bei jedem nachfolgenden Zug an die Vorlage zurückgeschickt. Der Inhalt einer Fertigkeit, die vor einer halben Stunde geladen wurde, ist immer noch da. Das ist eine bekannte Auswirkung des Musters, kein Fehler, aber wenn Sie das nicht wissen, ist es für Sie ein gefundenes Fressen. Ich versuche folgende Lösungen: Verwenden Sie einen Kurzzeitspeicher oder einen Summenspeicher. Ich muss noch entscheiden, welche Lösung sich in der Produktion besser bewährt.
Die Qualität der Beschreibung ist mehr wert als die des Inhalts. Das Modell wählt die zu ladende Fähigkeit anhand der Beschreibung aus, nicht anhand des Inhalts. Eine Fertigkeit, die gut geschrieben ist, aber eine vage Beschreibung enthält, wird ignoriert. Eine Fertigkeit, die mittelmäßig geschrieben ist, aber eine klare Beschreibung hat, wird immer aufgerufen. Verbringen Sie dort Zeit, nicht anderswo.
Größenbeschränkungen für Systemnachrichten und Nutzdaten. n8n dokumentiert keine festen Grenzen. In der Praxis setzt Ihnen das zugrunde liegende Modell die Grenze. Bei zweihundert Fähigkeiten mit je einer Zeile Beschreibung sind Sie bei sechzehn KB Manifest, was immer noch überschaubar ist. Ab fünfhundert sollten Sie auf das Muster Suche_Kompetenzen mit der Einbettung, weshalb pgvector von Anfang an eingebaut werden sollte, auch wenn Sie es nicht sofort verwenden.
Schnelles Nachladen von Fertigkeiten. Das Manifest wird zu Beginn der Sitzung geladen, nicht bei jeder Runde. Wenn Sie eine Fertigkeit bearbeiten, während ein Gespräch bereits geöffnet ist, sieht der LLM bis zum Ende der Sitzung weiterhin die alte Version. Für meinen Anwendungsfall ist das in Ordnung, aber wenn Sie ein System entwerfen, in dem Operatoren im Laufe des Tages Fertigkeiten bearbeiten, sollten Sie dies bedenken.
Fünf Schritte, der Reihe nach.
pgvector/pgvector:pg16, im selben Docker-Netzwerk, ohne Ports für den Host freizugeben.wwu-skills-db, Schema Fähigkeiten_mgmt, und wendet das obige SQL-Schema an.tool_load_skilldrei Knoten, exakte Kopie. Das Gleiche gilt für tool_load_reference.fähigkeiten_index. Auf den Werkzeugparametern, die Schaltfläche AI.Schritt fünf ist die Hälfte der eigentlichen Arbeit. Die ersten Ausführungen werden die Risse in der Eingabeaufforderung zeigen: falsches Routing, nicht aufgerufene Werkzeuge, geladene Fähigkeiten, die nicht benötigt werden. Das ist normal. Sie iterieren über Beschreibungen, iterieren über die Systemmeldung, Datei.
Wenn die Fähigkeiten drei oder vier Ziffern überschreiten, ist es naheliegend, das flache Manifest aus der Eingabeaufforderung zu entfernen und durch ein drittes Tool zu ersetzen: search_skills(abfrage, top_k). Intern geht es folgendermaßen vor: Es nimmt die Anfrage des Benutzers entgegen, berechnet eine Einbettung über den von Ihnen bevorzugten Anbieter (OpenAI, Voyage, Cohere, es gibt den Knoten Embeddings innerhalb von n8n), stellt eine Anfrage vector_cosine_ops auf der Fertigkeitstabelle, zieht die drei ähnlichsten Namen heraus und das war's. Das Modell sieht nur diese drei, lädt einen und arbeitet.
Die pgvector-Erweiterung ist wegen des Images bereits aktiviert, die beschreibung_einbettung Sie haben sie bereits gelöscht, Sie müssen sie nur noch füllen (ein einmaliger Workflow oder ein Trigger auf INSERT e UPDATE Aufruf des einbettenden Anbieters) und erstellen den HNSW-Index. Null Migration, null Ausfallzeit. Aus diesem Grund habe ich darauf bestanden, mit dem pgvector-Image und nicht mit dem Standard-Postgres zu beginnen.
Ich bin noch dabei, diese Architektur zu testen. Vielleicht schreibe ich in einem Monat, dass ich meine Meinung über etwas geändert habe, dass das von mir gewählte Speichermuster der Belastung nicht standhält, dass die Datentabellen in Ordnung waren und ich es umsonst kompliziert gemacht habe.
Das ist die Lektüre für den Moment. Wenn jemand einen anderen Ansatz ausprobiert hat, insbesondere im großen Maßstab (einhundert, zweihundert Fähigkeiten oder mehr), oder eine starke Meinung zu dem Gedächtnisstück hat, schreiben Sie mir bitte.
Hier eine Zusammenfassung des technischen Teils auf Englisch https://gist.github.com/mredodos/b71e2ee9a4431bbbe09a0f2ed0539df5
Sie suchen nach einem Web-Designer Experte für die Realisierung von Websites professionell?
Mein Name ist Edoardo Guzzi. Seit mehr als 10 Jahren helfe ich Unternehmen und Start-ups bei der Entwicklung leistungsstarker, SEO-optimierter und konversionsorientierter Websites.
Ich handle mit Website-Entwicklung mit WordPress und OdooE-Commerce-Erstellung, UX/UI-Optimierung und Strategien zur Verbesserung der Online-Sichtbarkeit.
Ich arbeite zwischen Schweiz und Italienbietet maßgeschneiderte Lösungen für alle, die sich im Internet von anderen abheben möchten. Erfahren Sie mehr über aifb.ch, webwakeup.co.uk.
