paint-brush
Verbesserung des Chatbots durch Codegenerierung: Erstellen eines kontextsensitiven Chatbots für Veröffentlichungenvon@shanglun
1,614 Lesungen
1,614 Lesungen

Verbesserung des Chatbots durch Codegenerierung: Erstellen eines kontextsensitiven Chatbots für Veröffentlichungen

von Shanglun Wang19m2023/11/05
Read on Terminal Reader

Zu lang; Lesen

GPT-basierte Systeme werden im Wissensmanagement mit großem Erfolg eingesetzt, die aktuellen Implementierungen auf dem neuesten Stand der Technik sind jedoch nur begrenzt in der Lage, auf der Grundlage von Metadaten zu suchen. Heute bauen wir ein System auf, das sowohl eine semantische als auch eine Metadatensuche durchführen kann, wodurch die Fähigkeiten des abrufgestützten Generierungssystems erheblich verbessert werden.
featured image - Verbesserung des Chatbots durch Codegenerierung: Erstellen eines kontextsensitiven Chatbots für Veröffentlichungen
Shanglun Wang HackerNoon profile picture

Einführung

Seit ChatGPT Anfang 2023 die öffentliche Aufmerksamkeit erregte, ist das Interesse an der Kommerzialisierung großer sprachmodellbasierter Anwendungen explosionsartig gestiegen. Eine der interessantesten Anwendungen war die Schaffung von Experten-Chat-Systemen, die Anfragen in natürlicher Sprache aus einer Datenbank mit proprietärem Wissen beantworten können.


Eine der beliebtesten Techniken in diesem Bereich ist [Retrieval-Augmented Generation] (https://Retrieval Augmented Generation aws) oder RAG, das Dokumenteinbettungen verwendet, um für die Benutzerabfrage relevante Elemente zu finden, bevor ein großes Sprachmodell zum Generieren verwendet wird eine Antwort.


Die Technik ist äußerst leistungsstark, da sie äußerst kostengünstige und schnelle Suchvorgänge ermöglicht, äußerste Flexibilität für Änderungen und Weiterentwicklungen der Wissensbasis im Laufe der Zeit bietet und hochinformierte und genaue Antworten liefert, die Halluzinationen und Fehler erheblich reduzieren.


Für eine tiefergehende Analyse von RAG-Systemen und deren Implementierung können Sie meinen vorherigen Artikel hier lesen.


So leistungsfähig RAG-Systeme auch sein können, es gibt einige schwerwiegende Einschränkungen bei der Architektur. Wir haben in meinem vorherigen Artikel einige der Einschränkungen untersucht und Möglichkeiten zur Verbesserung der Architektur vorgeschlagen.


Heute werden wir eine weitere Einschränkung der einbettungsbasierten Architektur untersuchen und einen Weg vorschlagen, die Einschränkungen der Architektur zu umgehen.

Problemstellung

Einschränkungen der einbettungsbasierten RAG

Angenommen, wir sind eine Publikation, die eine Chat-Schnittstelle erstellen möchte, über die Leser und Kunden Fragen stellen können.


Natürlich können wir Fragen wie „Was ist Ihre Meinung zu X?“ beantworten. oder „Was hast du über Y gesagt?“ mit einer einfachen RAG-Implementierung, aber eine RAG-Architektur beginnt wirklich zu kämpfen, wenn Sie sich mit Fragen wie „Was haben Sie über X im Jahr 2021 gesagt?“ beschäftigen. oder „Wie hat sich Ihre Berichterstattung über Y zwischen 2021 und 2023 verändert?“


Eine der Herausforderungen bei einem auf Einbettungen basierenden RAG besteht darin, dass Einbettungsmodelle im Allgemeinen nicht in der Lage sind, Metadaten systematisch zu kodieren, und daher werden alle Suchvorgänge, die Kenntnisse über Dinge wie das Veröffentlichungsdatum oder den Namen des Autors erfordern, Ihrem RAG-System einiges an Ärger bereiten .


Wir können dieses Problem lösen, indem wir eine der aufregendsten Funktionen großer Sprachmodelle nutzen – die Codegenerierung. Wir werden uns eine reale Veröffentlichung ansehen, einen LLM-basierten Algorithmus entwerfen, der die RAG-Architektur verbessert, und einen Chatbot basierend auf dem Algorithmus erstellen.

Geschäftsproblem

Heute werfen wir einen Blick auf den CB Insights Newsletter, einen beliebten täglichen Newsletter über Startups und Technologie. Als ehemaliger Full-Stack-Entwickler bei CB Insights freute ich mich am Ende des Arbeitstages oft auf den einzigartigen Witz und die Einsicht des Gründers.


Heute werden wir das Newsletter-Archiv von CB Insights als Basisdaten verwenden, um einen Chatbot zu erstellen, der metadatenbasierte Abfragen in natürlicher Sprache auf eine Weise beantworten kann, die einer auf Vanilla Embeddings basierenden RAG-Implementierung überlegen ist.


Konkret möchten wir, dass der Chatbot Fragen beantworten kann wie:


  • Was haben Sie 2020 über Uber gesagt?


  • Wie hat sich das Schicksal von Airbnb zwischen 2016 und 2019 verändert?


  • Was sind einige bemerkenswerte Einhorn-Startups aus Indien in den 2020er Jahren?


Lasst uns anfangen!

Verwendete Technologien

Um diese Aufgabe zu erfüllen, werden wir die folgenden Technologien verwenden:

Python

Wenn Sie meine anderen Artikel verfolgt haben, sollte es keine Überraschung sein, dass ich für den größten Teil des Codes in diesem Artikel Python verwenden werde. Python verfügt über hervorragende Web-Scraping-, Datenverarbeitungs- und OpenAI-Integration, die wir heute für unser Projekt nutzen werden.

SQL

SQL ist die Abfragesprache, die Benutzern die Interaktion mit mehreren wichtigen relationalen Datenbanken ermöglicht, darunter SQLite, MySQL, PostgreSQL und SQL Server. Bei der Sprache handelt es sich um eine Reihe von Anweisungen an die Datenbank zum Abrufen, Kombinieren und Bearbeiten von Daten, bevor sie an den Benutzer zurückgegeben werden.

LLM-Codegenerierung

Die Generierung von LLM-Code ist eine Technik, die in den letzten Monaten große Aufmerksamkeit erregt hat, da mehrere Basismodelle, darunter GPT 3.5, GPT 4 und LLaMa 2, die Fähigkeit bewiesen haben, Code von überraschender Komplexität als Reaktion auf Abfragen in natürlicher Sprache zu generieren.


Speziell geschulte und abgestimmte Systeme wie Copilot von GitHub sind in der Lage, bemerkenswert intelligenten Code zu schreiben, indem sie Modelle verwenden, die speziell für die Codegenerierung entwickelt wurden, aber ein ordnungsgemäß gesteuertes Allzweck-GPT-Modell verfügt bereits über außergewöhnliche Fähigkeiten, wenn es um das Schreiben von Code geht.

Semantische Einbettung

Semantische Einbettung ist das Rückgrat der meisten RAG-Implementierungen. Mithilfe einer Reihe natürlichsprachlicher Techniken können wir Text in natürlicher Sprache in einen Zahlenvektor umwandeln, der den Textinhalt innerhalb eines semantischen Vektorraums darstellt.


Mithilfe der Vektoralgebra können wir diese Einbettungen dann manipulieren und so mithilfe mathematischer Methoden die Beziehung zwischen zwei Textkorpora bestimmen.

GPT-3.5 und GPT-4

Mit 1,7 Billionen Parametern ist GPT-4 einfach das leistungsstärkste transformatorbasierte große Sprachmodell, das derzeit auf dem Markt erhältlich ist. GPT-4 ist in der Lage, große Textmengen und komplexe Argumente zu verstehen und auf schwierige Fragen hinreichend überzeugende Antworten zu generieren.


GPT-3.5, der viel kleinere Cousin von GPT-4, ist das Modell, das ChatGPT antreibt, als es die Welt im Sturm eroberte. Es ist in der Lage, unglaublich komplexe Eingabeaufforderungen zu verarbeiten, und was ihm an reinem Denkvermögen fehlt, macht es durch Geschwindigkeit und Kosteneinsparungen wett.


Für einfachere Aufgaben schafft GPT3.5 die Balance zwischen Leistung und Genauigkeit.

Einrichten des Chatbot-Backends

Einrichten der Datenbank

Bevor wir unsere KI aufbauen, müssen wir die Daten erhalten. Zu diesem Zweck können wir die Newsletter-Archivseite von CB Insights [ https://www.cbinsights.com/newsletter/ ] nutzen, die eine Sammlung vergangener Newsletter enthält.


Um alle Links zu erhalten, können wir Pythons Anfragen und die schöne Suppenbibliothek wie folgt verwenden:

 import requests from bs4 import BeautifulSoup res = requests.get('https://www.cbinsights.com/newsletter/') soup = BeautifulSoup(res.text) article_links = [[i.text, i['href']] for i in soup.find_all('a') if 'campaign-archive' in i['href'] ]


Sobald wir die Links haben, können wir zu jedem der Links gehen und den HTML-Code des Artikels herunterladen. Mit dem Listenverständnis von Python können wir dies in einer Zeile tun:


 article_soups = [BeautifulSoup(requests.get(link[1]).text) for link in article_links]


Dies wird eine Weile dauern, aber am Ende sollten alle Links gelöscht sein.


Jetzt können wir BeautifulSoup verwenden, um die relevanten Abschnitte zu extrahieren:


 import re # SEO optimizations cause some articles to appear twice so we dedupe them. # We also remove some multiple newlines and unicode characters. def get_deduped_article_tables(article_table): new_article_tables = [] for i in article_table: text_content = re.sub(r'\n{2,}', '\n', i.replace('\xa0', '').strip()) if text_content not in new_article_tables or text_content == '': new_article_tables.append(text_content) return new_article_tables result_json = {} for soup_meta, soup_art in zip(article_links, article_soups): article_tables = [] cur_article = [] for table in soup_art.find_all('table'): if table.attrs.get('mc:variant') == 'Section_Divider': article_tables.append(get_deduped_article_tables(cur_article)) cur_article = [] else: cur_article.append(table.text) article_tables.append(get_deduped_article_tables(cur_article)) result_json[soup_meta[0]] = article_tables


Lassen Sie uns noch etwas verarbeiten und es in einen DataFrame umwandeln:


 import pandas as pd result_rows = [] for article_name, article_json in result_json.items(): article_date = article_json[0][1] for idx, tbl in enumerate(article_json[1:]): txt = '\n'.join(tbl).strip() if txt != '': result_rows.append({ 'article_name': article_name, 'article_date': article_date, 'idx': idx, 'text': txt, }) df = apd.DataFrame(result_rows)


Wenn Sie den Datenrahmen untersuchen, sollten Sie etwa Folgendes sehen:



Während wir die Daten haben, generieren wir auch die Einbettungen für die Artikel. Mit dem Ada-Einbettungsmodell von OpenAI ist dies ganz einfach.


 import openai EMBEDDING_MODEL = "text-embedding-ada-002" openai.api_key = [YOUR KEY] df['embedding'] = df['text'].map(lambda txt: openai.Embedding.create(model=EMBEDDING_MODEL, input=[txt])['data'][0]['embedding'])


Nachdem wir nun über die Daten verfügen, die wir für diese Übung verwenden, laden wir sie in eine Datenbank. Für diese Übung verwenden wir SQLite, ein leichtes, eigenständiges Datenbanksystem, das im Lieferumfang von Python enthalten ist.


Bitte beachten Sie, dass Sie in einer Produktionsumgebung wahrscheinlich eine geeignete Datenbankinstanz wie MySQL oder PostgreSQL mit geringfügigen Änderungen an der hier verwendeten SQL verwenden möchten, die allgemeine Technik jedoch dieselbe bleibt.


Um die Datenbank zu instanziieren und zu laden, führen Sie einfach Folgendes in Python aus. Beachten Sie, dass wir neben dem Artikeltext und den Einbettungen auch einige Metadaten speichern, nämlich das Veröffentlichungsdatum.


Beachten Sie außerdem, dass SQLite3 im Gegensatz zu den meisten anderen SQL-Datenbanken ein dynamisches Typisierungssystem verwendet, sodass wir die Datentypen in der Erstellungsabfrage nicht angeben müssen.


 import sqlite3 import json con = sqlite3.connect("./cbi_article.db") cur = con.cursor() cur.execute("CREATE TABLE article(name, date, idx, content, embedding_json)") con.commit() rows = [] for _, row in df.iterrows(): rows.append([row['article_name'], row['article_date'], row['idx'], row['text'], json.dumps(row['embedding'])]) cur.executemany("INSERT INTO article VALUES (?, ?, ?, ?, ?)", rows) con.commit()


Und versuchen wir, die Daten abzufragen.


 res = cur.execute(""" SELECT name, date, idx FROM article WHERE date >= DATE('now', '-2 years'); """) res.fetchall()


Sollte etwa Folgendes ergeben:




Sieht ziemlich gut aus!


Erstellen eines Codegenerators für die Metadatensuche

Nachdem wir nun die Daten in die SQLite-Datenbank geladen haben, können wir mit dem nächsten Schritt fortfahren. Denken Sie daran, dass eine der Herausforderungen bei der reinen Einbettungs-RAG-Implementierung das Fehlen flexibler Metadaten-Suchfunktionen ist.


Da wir nun jedoch die Metadaten in eine SQL-Datenbank geladen haben, können wir die Codegenerierungsfunktionen von GPT nutzen, um flexible Metadatensuchen durchzuführen.


Um SQL-Code zu generieren, können wir ein einfaches Prompt-Engineering verwenden.


 response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a SQL query writer that can construct queries based on incoming questions. Answer with only the SQL query."}, {"role": "user", "content": """ Suppose we have the SQLite database table called "article" with the following columns, which contains newsletter articles from a publication: name, date, idx, content, embedding_json Write a question that would retrieve the rows necessary to answer the following user question. Only filter on date. Do not filter on any other column. Make sure the query returns every row in the table by name. Reply only with the SQL query. User question: What did you say about the future of the fintech industry in summer of 2022? """}, ] )


Beachten Sie die folgende Eingabeaufforderung: 1) Wir geben das Datenbankschema an, halten es aber einfach. 2) Wir geben die Rückgabespalten an. 3) Wir geben die Spalten an, die zum Filtern zur Verfügung stehen. 4) Wir spezifizieren die SQL-Variante. Diese Eingabeaufforderung sollte einen SQL-Code wie den folgenden generieren:


 SELECT * FROM article WHERE date BETWEEN '2022-06-01' AND '2022-08-31'


Da der Rückgabewert nicht deterministisch ist, kommt es manchmal zu Eigenheiten in Ihrem generierten Code. Um diese Bedingungen zu bewältigen, können wir einfach eine Try-Catch-Schleife verwenden, um zu versuchen, Daten neu zu generieren. Wir möchten dies natürlich nicht endlos tun. Wenn wir also in drei Versuchen kein richtiges SQL generieren können, beenden wir einfach und greifen auf Vanilla RAG zurück.


Wir können den Filter folgendermaßen implementieren:


 res = [] for i in range(3): response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a SQL query writer that can construct queries based on incoming questions. Answer with only the SQL query."}, {"role": "user", "content": """ Suppose we have the SQLite database table called "article" with the following columns, which contains newsletter articles from a publication: name, date, idx, content, embedding_json Write a question that would retrieve the rows necessary to answer the following user question. Only filter on date. Do not filter on any other column. Make sure the query returns every row in the table by name. Reply only with the SQL query. User question: What did you say about the future of the fintech industry in summer of 2022? """}, ] ) generated_query = response.choices[0].message['content'] is_query_safe = True for no_use_word in {'DELETE', 'UPDATE', 'DROP'}: if no_use_word in generated_query.upper(): is_query_safe = False if not is_query_safe: break # the user input is likely malicious. Try to answer the question with vanilla RAG res = cur.execute(generated_query).fetchall() if len(res) > 0: break if len(res) == 0: # vanilla RAG in memory. Use a vector DB in production please. res = cur.execute('''SELECT * FROM articles''').fetchall()


Dies ist ein relativ grober Filter, sodass Sie in Produktionsanwendungsfällen wahrscheinlich mehr Prüfungen auf Relevanz und SQL-Korrektheit durchführen möchten, aber für unser Beispiel ist dies ausreichend.


Ein kurzer Hinweis zur KI-Sicherheit : Wir sollten vorsichtig sein, wenn wir Code ausführen, der von einer KI zurückgegeben wird, insbesondere wenn Benutzereingaben als Teil der Eingabeaufforderung verwendet wurden.


Wenn wir die Ausgabe nicht bereinigen, machen wir uns anfällig für Prompt-Engineering-Angriffe, bei denen der Benutzer versucht, die KI so zu manipulieren, dass sie Aktualisierungs- oder Löschanweisungen generiert.


Daher sollten wir immer prüfen, ob die Ausgabe unseren Erwartungen entspricht, bevor wir den Code auf unserem Computer ausführen.


Führen Sie den folgenden Code aus, um das abgerufene Ergebnis anzuzeigen:


 df = pd.DataFrame([{c[0]: v for c, v in zip(cur.description, row)} for row in res])


Und jetzt sollten Sie das folgende Ergebnis sehen:



Ausführen von Standard-RAG mit dem Ergebnis

Nachdem wir nun das Ergebnis der Metadatensuche haben, ist der Rest einfach. Wir berechnen die Kosinusähnlichkeit für alle abgerufenen Ergebnisse wie folgt:


 from openai.embeddings_utils import cosine_similarity q_embed = openai.Embedding.create(model=EMBEDDING_MODEL, input=[user_question])['data'][0]['embedding'] df['cosine_similarity'] = df['embedding_json'].map(lambda js: cosine_similarity(json.loads(js), q_embed))


Und jetzt können wir die Top-10-Newsletter nehmen und Prompt Engineering nutzen, um die Frage zu beantworten. Wir haben uns hier für 10 entschieden, da jeder Newsletter-Auszug relativ kurz ist.


Wenn Sie mit längeren Artikeln arbeiten, möchten Sie möglicherweise weniger Artikel verwenden oder die im Bonusabschnitt beschriebene Technik verwenden.


 answer_prompt = ''' Consider the following newsletter excerpts from the following dates: ''' for _, row in df.sort_values('cosine_similarity', ascending=False).iloc[:10].iterrows(): answer_prompt += """ ======= Date: %s ==== %s ===================== """ % (row['date'], row['content']) answer_prompt += """ Answer the following question: %s """ % user_question response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a tech analyst that can summarize the content of newsletters"}, {"role": "user", "content": answer_prompt}, ] )


Dies sollte zu einem Ergebnis ähnlich dem folgenden führen:


Die Zukunft von Fintech wurde im Sommer 2022 in verschiedenen Newslettern diskutiert. Es gab eine deutliche Verlangsamung im Fintech-Bereich, da die Finanzierung im zweiten Quartal 2022 nach einem Höchststand im Jahr 2021 in Richtung des Niveaus von 2020 sank. Der Bericht für das zweite Quartal 2022 hob den Rückgang der weltweiten Fintech-Investitionen hervor .


Allerdings schien die Zukunft der Fintech-Branche vielversprechend, da insbesondere im Zahlungsbereich eine deutliche Verlagerung hin zu Start-ups in der Frühphase zu verzeichnen war. Die weltweiten Investitionen im Zahlungssektor gingen im Vergleich zum ersten Quartal 2022 um 43 % auf 5,1 Milliarden US-Dollar im zweiten Quartal 2022 zurück, da sich die Finanzierung nach den Spitzenwerten im Jahr 2021 wieder normalisierte.


Neueinsteiger in diesem Bereich verzeichneten im Jahr 2022 bisher einen höheren Anteil an Deals (63 %), was das Interesse der Anleger an Start-ups unterstreicht. Darüber hinaus wurde berichtet, dass Fintech den Privatkundenbanken immer mehr Konkurrenz macht und sie dazu zwingt, der Digitalisierung ihrer Kerndienstleistungen Vorrang einzuräumen.


Der Bankensektor reagierte, indem er sich auf die Verbesserung des Kundenerlebnisses, insbesondere Mobile Banking, konzentrierte und dabei Technologien wie Chatbots und Kundenanalyseplattformen einsetzte. All dies deutet auf eine dynamische und wettbewerbsorientierte FinTech-Branche hin.


Was ziemlich gut ist! Wenn Sie die Antwort anhand der Antwortaufforderung überprüfen, werden Sie feststellen, dass die Statistiken alle aus dem Quellmaterial stammen. Sie werden auch feststellen, dass das Quellmaterial einige eigenwillige Formatierungen enthält, die GPT4 ignorieren konnte. Dies zeigt die Flexibilität von LLMs bei Datenzusammenfassungssystemen.

Bonus: Zusammenfassungs-Middleware

Eines der Probleme, auf die Sie bei diesem Prozess stoßen können, besteht darin, dass die endgültige Eingabeaufforderung sehr groß sein kann, wenn der Korpus extrem groß ist. Dies kann kostspielig sein, wenn Sie GPT-4 verwenden, aber eine sehr lange Eingabeaufforderung kann das Modell auch verwirren.


Um dieses Problem zu lösen, können wir die einzelnen Artikel mit GPT-3.5 vorverarbeiten und die letzte Eingabeaufforderung, die wir im letzten Schritt an GPT-4 senden, komprimieren.


 summarization_prompt = ''' Summarize the following passage and extract only portions that are relevant to answering the user question. Passage: ======= %s ======= User Questions: %s ''' (row['content'], user_question) response = openai.ChatCompletion.create( model="gpt-3.5-turbo", messages=[ {"role": "system", "content": "You are a summarizer of tech industry reports"}, {"role": "user", "content": summarization_prompt}, ] )


Anschließend können wir die Zusammenfassungen in die Eingabeaufforderung einfügen, was im Vergleich zum Platzieren des reinen Artikels in die endgültige Eingabeaufforderung erhebliche Einsparungen bringt.

Erstellen eines einfachen Frontends

Nachdem wir nun den Python-Code geschrieben haben, packen wir ihn als einfache Webanwendung.

Backend-API

Es ist relativ einfach, den Code mit Flask als Backend-API zu packen. Erstellen Sie einfach eine Funktion und verknüpfen Sie sie wie folgt mit Flask:


 import requests from bs4 import BeautifulSoup import re import pandas as pd import sqlite3 import json import openai from openai.embeddings_utils import cosine_similarity from flask import Flask, request, jsonify from flask_cors import CORS app = Flask(__name__) CORS(app) EMBEDDING_MODEL = "text-embedding-ada-002" openai.api_key = [Your OpenAI Key] db_location = [Location of your SQLite DB] def process_user_query(user_question): con = sqlite3.connect(db_location) cur = con.cursor() user_question = 'What did you say about the future of the fintech industry in summer of 2022?' res = [] for i in range(3): response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a SQL query writer that can construct queries based on incoming questions. Answer with only the SQL query."}, {"role": "user", "content": """ Suppose we have the SQLite database table called "article" with the following columns, which contains newsletter articles from a publication: name, date, idx, content, embedding_json Write a question that would retrieve the rows necessary to answer the following user question. Only filter on date. Do not filter on any other column. Make sure the query returns every row in the table by name. Reply only with the SQL query. User question: What did you say about the future of the fintech industry in summer of 2022? """}, ] ) generated_query = response.choices[0].message['content'] is_query_safe = True for no_use_word in {'DELETE', 'UPDATE', 'DROP'}: if no_use_word in generated_query.upper(): is_query_safe = False if not is_query_safe: break # the user input is likely malicious. Try to answer the question with vanilla RAG res = cur.execute(generated_query).fetchall() if len(res) > 0: break if len(res) == 0: # vanilla RAG in memory. Use a vector DB in production please. res = cur.execute('''SELECT * FROM articles''').fetchall() df = pd.DataFrame([{c[0]: v for c, v in zip(cur.description, row)} for row in res]) q_embed = openai.Embedding.create(model=EMBEDDING_MODEL, input=[user_question])['data'][0]['embedding'] df['cosine_similarity'] = df['embedding_json'].map(lambda js: cosine_similarity(json.loads(js), q_embed)) answer_prompt = ''' Consider the following newsletter excerpts from the following dates: ''' for _, row in df.sort_values('cosine_similarity', ascending=False).iloc[:10].iterrows(): answer_prompt += """ ======= Date: %s ==== %s ===================== """ % (row['date'], row['content']) answer_prompt += """ Answer the following question: %s """ % user_question response = openai.ChatCompletion.create( model="gpt-4", messages=[ {"role": "system", "content": "You are a tech analyst that can summarize the content of newsletters"}, {"role": "user", "content": answer_prompt}, ] ) return response.choices[0].message['content'] @app.route('/process_user_question', methods=["POST"]) def process_user_question(): return jsonify({ 'status': 'success', 'result': process_user_query(request.json['user_question']) }) app.run()

Und das ist eigentlich alles, was wir für das Backend tun müssen!

Frontend-Code

Da wir nur einen Endpunkt haben und in unserer Anwendung nicht viel Status benötigen, sollte der Frontend-Code ziemlich einfach sein. Denken Sie daran, dass wir in einem früheren Artikel eine React-Anwendung mit Routing eingerichtet haben, die es uns ermöglicht, Komponenten auf bestimmten Routen zu rendern.


Befolgen Sie einfach die Anweisungen in diesem Artikel, um ein React.JS-Projekt einzurichten, und fügen Sie die folgende Komponente auf einer Route Ihrer Wahl hinzu:


 import React, {useState, useEffect} from 'react'; import axios from 'axios'; const HNArticle = () => { const [result, setResult] = useState(''); const [message, setMessage] = useState(''); const [question, setQuestion] = useState(''); const askQuestion = () => { axios.post("http://127.0.0.1:5000/process_user_question", {user_question: question}) .then(r => r.data) .then(d => { console.log(d); setResult(d.result); }); } return <div className="row" style={{marginTop: '15px'}}> <div className="col-md-12" style={{marginBottom: '15px'}}> <center> <h5>Hackernoon CB Insights Demo</h5> </center> </div> <div className="col-md-10 offset-md-1 col-sm-12 col-lg-8 offset-lg-2" style={{marginBottom: '15px'}}> <ul className="list-group"> <li className="list-group-item"> <h6>Your Question</h6> <p><input className="form-control" placeholder="Question" value={question} onChange={e => setQuestion(e.target.value)} /></p> <p>{message}</p> <p> <button className="btn btn-primary" onClick={askQuestion}>Ask</button> </p> </li> {result? <li className="list-group-item"> <h6>Response</h6> {result.split("\n").map((p, i) => <p key={i}>{p}</p>)} </li>: ''} </ul> </div> </div>; } export default HNArticle;


Führen Sie den Code aus und Sie sollten eine Schnittstelle wie diese sehen:




Stellen Sie eine Frage und nach einer Weile sollten Sie die Ausgabe sehen:


Und voilà! Wir haben erfolgreich einen Chatbot mit erweiterten Abfragefunktionen entwickelt, die über ein Standard-RAG-System hinausgehen!

Abschluss

Im heutigen Artikel haben wir einen Chatbot mit leistungsstarken Funktionen zur Codegenerierung erstellt. Dies ist ein Beispiel für eine neue Klasse von LLM-Anwendungen, die derzeit von vielen KI-Pionieren entwickelt werden und die Daten, Programmiersprachen und das Verständnis natürlicher Sprache nutzen können, um mit Fachwissen generative KI-Systeme zu erstellen.


Diese Spezialsysteme sind der Schlüssel zur Erschließung der kommerziellen Rentabilität von LLM-Anwendungen, die einen Mehrwert bieten möchten, der über das hinausgeht, was direkt von Plattformanbietern wie OpenAI und Anthropic verfügbar ist.


Die Codegenerierung ist nur eine der Techniken, die durch die jüngste Generation kommerziell verfügbarer großer Sprachmodelle ermöglicht wurde.


Wenn Sie Ideen zur Kommerzialisierung von LLMs haben oder sich über KI unterhalten möchten, wenden Sie sich bitte an LinkedIn oder GitHub . Ich habe im letzten Jahr viele aufschlussreiche Gespräche mit Lesern geführt und freue mich auf viele weitere!