Créer une application de questionnement et de réponse aux données
Introduction au PNL et à SQL
Grâce à la disponibilité de grands modèles de langage puissants, nous pouvons désormais convertir le langage naturel en SQL précis (NLP vers SQL) avec une seule légende, permettant aux utilisateurs d’exprimer leurs besoins d’informations de manière naturelle et efficace.
Dans ce blog, nous explorerons la création d’une application Web de questionnement et de réponse aux données.
Pile technologique
- Python
- Azure OpenAI
- SQLite3
Couler
Diagramme ER
Rapide
Lors d’un appel au modèle Azure OpenAI, nous devons soigneusement rédiger notre invite. La précision est cruciale, car une invite ambiguë peut entraîner des résultats inattendus.
Nous avons configuré l’invite suivante, dans laquelle nous remplaçons la requête NLP de l’utilisateur.
prompt = """ Given the following SQL tables, your job is to write queries given a user’s request. CREATE TABLE Branches ( BranchID INTEGER PRIMARY KEY, City TEXT, Country TEXT, EmployeeNumber INTEGER, GM TEXT ) CREATE TABLE IF NOT EXISTS Departments ( DepartmentID INTEGER PRIMARY KEY, Name TEXT ) CREATE TABLE IF NOT EXISTS Employees ( EmployeeID INTEGER PRIMARY KEY, Name TEXT, Position TEXT, Salary REAL, DepartmentID INTEGER, BranchID INTEGER, FOREIGN KEY (DepartmentID) REFERENCES Departments(DepartmentID), FOREIGN KEY (BranchID) REFERENCES Branches(BranchID) ) ''') Desired Format: Return valid sql query strictly for above tables otherwise return undefined Translate the following natural language query into SQL: {} SQL Query: """.format(user_nlp_query)
Azure OpenAI
Le NLP vers SQL est l’un des avantages du modèle Azure OpenAI que nous pouvons exploiter pour notre application Data Questioning and Answering. Dans le code ci-dessous, nous avons utilisé le modèle text-davinci-003, qui convertit le langage humain en SQL
# Using Azure OpenAI API from openai import AzureOpenAI api_key = config["AZURE_OPENAI_KEY"] client = AzureOpenAI( azure_endpoint="https://vc-test-openai.openai.azure.com/", api_key = api_key, api_version="2023-09-15-preview", ) response = client.completions.create( model="vc-text-davinci-003", prompt=prompt, max_tokens=1024 )
HTML
Exemples de PNL vers SQL
Vous trouverez ci-dessous quelques requêtes en langage humain que j’ai essayé de saisir via un formulaire HTML. J’ai validé leurs requêtes SQL correspondantes et leurs réponses réelles par rapport à la base de données. Il existe des situations dans lesquelles nous recevons une requête SQL qui entraîne une erreur lors de son exécution sur la base de données réelle. Nous traitons ce scénario en posant à l’utilisateur une question différente ou plus appropriée
/* 1. List all employees with their corresponding department names. */ T Employees.Name, Departments.Name FROM Employees LEFT JOIN Departments ON Employees.DepartmentID = Departments.DepartmentID; /* 2. Find the total number of employees in each department. */ SELECT DepartmentID, COUNT(*) AS Total_Employees FROM Employees GROUP BY DepartmentID; /* 3. Identify employees who are managers along with their department names. */ SELECT e.Name, e.Position, d.Name FROM Employees e JOIN Departments d ON e.DepartmentID = d.DepartmentID WHERE e.Position = 'Manager' /* 4. List all employees in the IT department with their salaries. */ SELECT EmployeeID, Name, Position, Salary FROM Employees WHERE DepartmentID = (SELECT DepartmentID FROM Departments WHERE Name="IT") /* 5. Find the average salary for employees in each department. */ SELECT DepartmentID, AVG(Salary) FROM Employees GROUP BY DepartmentID; /* 6. Identify the department with the highest total salary expense. */ SELECT Departments.Name, SUM(Employees.Salary) AS TotalExpense FROM Employees INNER JOIN Departments On Employees.DepartmentID = Departments.DepartmentID GROUP BY Departments.Name ORDER BY TotalExpense DESC LIMIT 1; /* 7. List employees who do not belong to any department. */ SELECT * FROM Employees WHERE DepartmentID IS NULL; /* 8. Find the department with the least number of employees. */ SELECT Departments.Name FROM Employees LEFT JOIN Departments ON Departments.DepartmentID = Employees.DepartmentID GROUP BY Departments.Name ORDER BY COUNT(Employees.EmployeeID) ASC LIMIT 1; /* 9. List employees who belong to the Finance department and have a salary above 1000 */ SELECT * FROM Employees WHERE DepartmentID = (SELECT DepartmentID FROM Departments WHERE Name="Finance") AND Salary > 1000; /* 10. What is the salary of employee ID 101?*/ "SELECT Salary FROM Employees WHERE EmployeeID = 101;
Hallucination
Les hallucinations font référence aux cas où le modèle génère ou prédit des requêtes SQL qui ne sont pas précises ou pertinentes par rapport à l’intention de l’utilisateur. Cela peut entraîner des opérations de base de données incorrectes ou involontaires. J’ai essayé toutes les requêtes en langage humain ci-dessus, mais cela n’a pas généré de code SQL invalide.
Défis
Les utilisateurs peuvent manipuler les données via un formulaire utilisateur ou via une invite. Nous devons gérer tous les scénarios dans lesquels l’utilisateur final ne peut récupérer que les données de l’application. Dans la section d’invite ci-dessus, j’ai inclus le format souhaité pour contraindre le modèle à générer une requête valide ; sinon, il renvoie « non défini » pour gérer les requêtes utilisateur non valides. Les utilisateurs peuvent demander tout ce qui n’est pas pertinent pour une base de données particulière.
@app.route("/qa", methods=["POST"]) def prompt_to_qa(): nlp_query = request.form.get("query") sql_query = get_sql_query(nlp_query) print(sql_query) if(sql_query.strip().lower() == "undefined"): output = "Not a valid question" else: result = str(execute_sql_query(sql_query)) check_json = is_json(result) if(check_json): output = json.loads(result) else: output = result return { "nlp_query": nlp_query, "sql_query": sql_query, "result": output}
Conclusion
Vous pouvez modifier la pile technologique mentionnée ci-dessus pour rationaliser le développement d’applications, indépendamment de l’interface utilisateur, du LLM ou de la base de données. De plus, vous pouvez exploiter des bibliothèques telles que pandas. En expérimentant différentes combinaisons de la pile technologique, nous pouvons améliorer les capacités de l’application.
Liens importants
Source link