📙 In einer mehrteiligen Serie zum Erstellen von Webanwendungen mit generativer KI-Integration. Teil 1 konzentrierte sich darauf, den KI -Stack zu diskutieren und warum die Anwendungsschicht der beste Ort im Stapel ist. Überprüfen Sie es hier draußen. Teil 2 konzentrierte sich darauf, warum Ruby die beste Websprache für den Aufbau von KI -MVPs ist. Überprüfen Sie es hier draußen. Ich empfehle Ihnen dringend, beide Teile durchzulesen, bevor Sie diesen Artikel lesen, um die hier verwendete Terminologie zu verstricken.
Inhaltsverzeichnis
Einführung
In diesem Artikel werden wir ein lustiges Gedankenexperiment durchführen. Wir versuchen, die Frage zu beantworten:
Wie einfach können wir eine Webanwendung mit KI -Integration durchführen?
Meine Leser werden wissen, dass ich schätze Einfachheit sehr hoch. Einfache Net -Apps sind leichter zu verstehen, schneller zu erstellen und wartbarer. Natürlich entsteht die Komplexität, wenn die App skaliert, aus der Notwendigkeit. Aber Sie möchten immer einfach anfangen.
Wir werden eine typische Fallstudie für eine Webanwendung mit KI -Integration (RAG) durchführen und vier verschiedene Implementierungen betrachten. Wir werden mit dem komplexesten Setup beginnen, das sich aus den beliebtesten Instruments zusammensetzt, und versuchen, es Schritt für Schritt zu vereinfachen, bis wir am einfachsten möglich sind.
Warum machen wir das?
Ich möchte Entwickler dazu inspirieren, einfacher zu denken. Oft ist die Route „Mainstream“ zum Erstellen von Net -Apps oder zur Integration von KI für den Anwendungsfall viel zu komplex. Entwickler lassen sich von Unternehmen wie Google oder Apple inspirieren, ohne zu erkennen, dass Instruments, die für sie funktionieren, für Kunden, die in viel kleinerem Maßstab arbeiten, häufig unangemessen sind.
Nehmen Sie sich einen Kaffee oder Tee und lassen Sie uns eintauchen.
Stufe 1: So komplex wie es nur geht
Angenommen, ein Kunde hat Sie gebeten, eine Lag -Anwendung für ihn zu erstellen. Diese Anwendung verfügt über eine Seite, auf der Benutzer ihre Dokumente und eine andere Seite hochladen können, auf der sie mit ihren Dokumenten mit RAG chatten können. Mit dem beliebtesten Webstack, der derzeit verwendet wird, entscheiden Sie sich für die Mern Stapel (MongoDB, Specific.js, React und Node.js), um Ihre Anwendung zu erstellen.
Um die Lag -Pipelines zu bauen, die das Dokument an Parsen, Knochen, Einbettung, Abruf und vielem mehr bearbeiten, entscheiden Sie sich erneut für den beliebtesten Stapel: Langchain im Einsatz über Fastapi. In der Net -App werden API -Anrufe zu den in Fastapi definierten Endpunkten getätigt. Es muss mindestens zwei Endpunkte geben: einen zum Aufrufen der Indexierungspipeline und eine andere, um die Abfragepipeline aufzurufen. In der Praxis benötigen Sie auch Upsert- und Löschen von Endpunkten, um sicherzustellen, dass die Daten in Ihrer Datenbank synchron mit den Einbettungsdings in Ihrem Vektorspeicher synchronisiert werden.
Beachten Sie, dass Sie JavaScript für die Webanwendung und Python für die KI -Integration verwenden. Diese Duo-linguale App bedeutet, dass Sie wahrscheinlich a verwenden werden Microservices Architektur (sehen Teil 2 dieser Serie für mehr dazu). Dies ist keine strenge Anforderung, wird aber in einem solchen Setup oft gefördert.
Es gibt noch eine Auswahl zu treffen: Welche Vector -Datenbank werden Sie verwenden? Die Vektordatenbank ist der Ort, an dem Sie die von der Indexpipeline erstellten Dokumentbrocken speichern. Lassen Sie uns wieder mit der beliebtesten Wahl da draußen gehen: Tannenzapfen. Dies ist eine verwaltete Cloud -Vektor -Datenbank, die viele AI -Entwickler derzeit verwenden.
Das ganze System könnte ungefähr wie folgt aussehen:

Yikes! Hier gibt es viele bewegende Stücke. Lassen Sie uns die Dinge aufschlüsseln:
- Im unteren Rechteck haben wir die Webanwendung und das MongoDB -Backend. In der Mitte haben wir die Lag -Pipelines mit Langchain und Fastapi gebaut. Oben haben wir die Pnecone -Vektor -Datenbank. Jedes Rechteck hier stellt einen anderen Service mit seinen eigenen separaten Bereitstellungen dar. Während die Pinecone Cloud Vector -Datenbank verwaltet wird, ist der Relaxation in Ihnen.
- Ich habe Beispiele für HTTP -Anforderungen und entsprechende Antworten mit einem gepunkteten Rand eingeholt. Denken Sie daran, dass dies eine Microservices-Architektur ist. Dies bedeutet, dass HTTP-Anfragen jederzeit benötigt werden, wenn die Kommunikation zwischen den Dienstleistungen stattfindet. Der Einfachheit halber habe ich nur veranschaulicht, wie die Abfrage -Pipeline -Anrufe aussehen würden, und ich habe alle Anrufe zu öffnen, anthropisch usw. Aus Gründen der Klarheit haben ich die Anfragen/Antworten in der Reihenfolge, in der sie in einem Abfrageszenario stattfinden, nummeriert.
- Um einen Schmerzpunkt zu veranschaulichen, ist die Gewährleistung der Dokumente in Ihrer MongoDB -Datenbank mit ihren entsprechenden Einbettungen im Pinecone -Index machbar, kann aber schwierig sein. Es erfordert mehrere HTTP -Anforderungen, um von Ihrer MongoDB -Datenbank in die Cloud -Vektor -Datenbank zu gelangen. Dies ist ein Punkt der Komplexität und des Overheads für den Entwickler.
Eine einfache Analogie: Dies ist wie der Versuch, Ihr physisches Bücherregal mit einem digitalen Buchkatalog zu synchronisieren. Jedes Mal, wenn Sie ein neues Buch erhalten oder ein Buch aus Ihrem Regal spenden (stellt sich heraus, dass Sie nur das mögen Recreation of Thrones Zeigen Sie nicht das Buch), Sie müssen den Katalog manuell aktualisieren, um die Änderung widerzuspiegeln. In dieser Welt der Bücher wird eine kleine Diskrepanz Sie nicht wirklich beeinflussen, aber in der Welt der Webanwendungen kann dies ein großes Downside sein.
Stufe 2: Lassen Sie die Wolke fallen
Können wir diese Architektur einfacher machen? Vielleicht haben Sie kürzlich einen Artikel gelesen, in dem er erläutert hat, wie Postgres eine Erweiterung namens hat pgVector. Dies bedeutet, dass Sie Tinecone verzichten und nur Postgres als Ihre Vektor -Datenbank verwenden können. Idealerweise können Sie Ihre Daten von MongoDB migrieren, damit Sie nur mit einer Datenbank bleiben. Großartig! Sie refaktor Ihre Bewerbung so, dass Sie jetzt wie Folgendes aussehen:

Jetzt haben wir nur zwei Dienste, über die wir uns Sorgen machen müssen: die Webanwendung + Datenbank und die Rag -Pipelines. Noch einmal wurden alle Anrufe bei Modellanbietern weggelassen.
Was haben wir mit dieser Vereinfachung gewonnen? Jetzt deine Einbettungen und die zugehörigen Dokumente oder Stücke können in derselben Datenbank in derselben Tabelle leben. Beispielsweise können Sie einer Tabelle in PostgreSQL eine Einbettungsspalte hinzufügen, indem Sie:
ALTER TABLE paperwork
ADD COLUMN embedding vector(1536);
Die Aufrechterhaltung der Kohärenz zwischen den Dokumenten und Einbettungen sollte jetzt viel einfacher sein. Postgres ‚ ON INSERT/UPDATE
Mit Auslöbern können Sie Einbettungen an Ort finden, wodurch die Zweiphase eliminiert wird „Schreiben Sie doc/dann einbetten“ ganz tanzen.
Wenn Sie zur Analogie des Bücherregals zurückkehren, ist dies wie das Ausschalten des digitalen Katalogs und stattdessen nur ein Etikett direkt an jedem Buch. Wenn Sie sich nun um ein Buch bewegen oder eines werfen, müssen Sie ein separates System nicht aktualisieren, da die Etiketten überall hingehen, wo die Bücher gehen.
Stufe 3: Microservices Begone!
Sie haben gute Arbeit geleistet, um Dinge zu vereinfachen. Sie denken jedoch, Sie können es noch besser machen. Vielleicht können Sie eine erstellen monolithische App, Anstatt die Microservices -Architektur zu verwenden. Ein Monolith bedeutet nur, dass Ihre Anwendung und Ihre Lag -Pipelines zusammen entwickelt und eingesetzt werden. Es tritt jedoch ein Downside auf. Sie haben die Net -App in JavaScript mit dem Mern -Stack codiert. Die Lag -Pipelines wurden jedoch mit Python und Langchain gebaut, die über Fastapi eingesetzt wurden. Vielleicht können Sie versuchen, diese in einen einzelnen Behälter zu drücken und so etwas wie zu verwenden Aufsicht Um die Python- und JavaScript -Prozesse zu überwachen, ist es jedoch nicht natürlich für Polyglot -Stapel geeignet.
Sie beschließen, React/Knoten zu verlassen und stattdessen Django zu verwenden, ein Python -Net -Framework, um Ihre App zu entwickeln. Jetzt kann Ihr Rag -Pipeline -Code nur in einem Dienstprogrammmodul in Ihrer Django -App leben. Dies bedeutet, dass keine HTTP -Anfragen mehr gestellt werden, was Komplexität und Latenz beseitigt. Jedes Mal, wenn Sie Ihre Abfrage- oder Indexierungspipelines ausführen möchten, müssen Sie nur einen Funktionsaufruf tätigen. Das Spenden von Entwicklungsumgebungen und Bereitstellungen ist jetzt ein Kinderspiel. Wenn Sie Teil 2 lesen, bevorzugen Sie natürlich nicht, einen All Python -Stack zu verwenden, sondern stattdessen mit einem Alle Ruby Stack.
Sie haben noch weiter vereinfacht und haben nun die folgende Architektur:

Ein wichtiger Hinweis: In früheren Diagrammen habe ich die Webanwendung und die Datenbank zum Einfachheit halber zu einem einzigen Dienst kombiniert. Zu diesem Zeitpunkt denke ich, dass es wichtig ist zu zeigen, dass sie tatsächlich selbst getrennte Dienste selbst sind! Das tut nicht bedeuten, dass Sie noch eine Microservices -Architektur verwenden. Solange die beiden Dienste entwickelt und insgesamt bereitgestellt werden, ist dies immer noch ein Monolith.
Wow! Jetzt haben Sie nur einen einzigen Einsatz, um sich zu drehen und zu warten. Sie können Ihre Datenbank als Zubehör für Ihre Webanwendung einrichten. Dies bedeutet leider, dass Sie wahrscheinlich immer noch verwenden möchten Docker komponieren Um Ihre Datenbank- und Webanwendungsdienste gemeinsam zu entwickeln und bereitzustellen. Aber da die Pipelines jetzt gerade als Funktionen anstelle eines separaten Dienstes wirken, können Sie jetzt Fastapi verlassen! Sie müssen diese Endpunkte nicht mehr aufrechterhalten. Verwenden Sie einfach Funktionsaufrufe.
Ein bisschen technische Particulars: In diesem Diagramm zeigt die Legende an, dass die gepunktete Linie ist nicht Http, aber stattdessen a Postgres Frontend/Backend Protocol. Dies sind zwei verschiedene Protokolle am Anwendungsschicht der Web -Protokollmodell. Dies ist eine andere Anwendungsschicht als die, in der ich besprochen habe Teil 1. Die Verwendung einer HTTP -Verbindung zum Übertragen von Daten zwischen der Anwendung und der Datenbank ist theoretisch möglich, aber nicht optimum. Stattdessen haben die Schöpfer von Postgres ein eigenes Protokoll erstellt, das schlank und eng mit den Anforderungen der Datenbank gekoppelt ist.
Stufe 4: SQLite tritt in den Chat ein
„Sicher sind wir vereinfacht?“Möglicherweise fragen Sie sich.
Falsch!
Es gibt noch eine weitere Vereinfachung, die wir machen können. Anstatt Postgres zu verwenden, können wir SQLite verwenden! Sie sehen, derzeit sind Ihre App und Ihre Datenbank zwei separate Dienste, die gemeinsam bereitgestellt werden. Aber was wäre, wenn sie nicht zwei verschiedene Dienste wären, sondern dass Ihre Datenbank nur eine Datei warfare, die in Ihrer Anwendung lebt? Das kann Ihnen SQLite geben. Mit der kürzlich veröffentlichten Veröffentlichung sqlite-vec
Bibliothek kann es sogar mit Lappen umgehen, genau wie wie wie pgvector
Funktioniert für Postgres. Die Einschränkung hier ist das sqlite-vec
ist Pre-V1, aber das ist immer noch großartig für eine frühe Stufe MVP.

Wirklich erstaunlich. Sie können jetzt Docker komponieren! Dies ist wirklich ein einziger Service Webanwendung. Die Langchain -Module und Ihre Datenbank sind jetzt alle Funktionen und Dateien, die in Ihrem Repository leben.
Besorgt über die Verwendung von SQLite in einer Produktions -Webanwendung? ICH Kürzlich geschrieben darüber, wie SQLite, einst nur als Spielzeug in der Welt der Net-Apps angesehen wurde, durch einige Verbesserungen in seiner Konfiguration zu produzierbar werden kann. Tatsächlich hat Ruby on Rails 8 kürzlich diese Anpassungen standardmäßig gemacht und nun SQLite als Standarddatenbank für neue Anwendungen. Natürlich müssen Sie mit der APP wahrscheinlich zu Postgres oder einer anderen Datenbank migrieren. Denken Sie jedoch an das Mantra, das ich am Anfang erwähnt habe: Führen Sie nur die Komplexität ein, wenn sie unbedingt notwendig sind. Gehen Sie nicht davon aus, dass Ihre App mit Millionen von gleichzeitigen Schreibvorgängen in die Luft jagen wird, wenn Sie nur versuchen, Ihre ersten Benutzer zu erhalten.
Zusammenfassung
In diesem Artikel haben wir mit den traditionellen Stapeln für den Erstellen einer Webanwendung mit KI -Integration begonnen. Wir haben die Komplexität gesehen und beschlossen, Stück für Stück zu vereinfachen, bis wir das platonische Superb einfacher Apps hatten.
Aber lassen Sie sich nicht von der Einfachheit täuschen. Die App ist immer noch ein Tier. In der Tat kann es aufgrund der Einfachheit viel schneller laufen als die traditionelle App. Wenn Sie feststellen, dass die App langsamer wird, würde ich versuchen, den Server zu verkürzen, bevor ich in Betracht zieht, in eine neue Datenbank zu migrieren oder den Monolithen aufzubrechen.
Mit einer so schlanken Anwendung können Sie sich wirklich schnell bewegen. Die lokale Entwicklung ist ein Traum, und das Hinzufügen neuer Funktionen kann mit Blitzgeschwindigkeit erfolgen. Sie können immer noch Backups Ihrer SQLite -Datenbank mit etwas wie erhalten Litestream. Sobald Ihre App echte Anzeichen einer Belastung zeigt, bewegen Sie die Komplexitätsniveaus. Ich charge jedoch davon, eine neue Anwendung auf Stufe 1 zu starten.
Ich hoffe, Sie haben diese Serie zum Erstellen von Webanwendungen mit KI -Integration genossen. Und ich hoffe, ich habe Sie dazu inspiriert, einfach und nicht kompliziert zu denken!
🔥 Wenn Sie eine benutzerdefinierte Webanwendung mit generativer KI -Integration möchten, besuchen Sie losangelesaiApps.com