Fermer

novembre 17, 2023

Créer une application de questionnement et de réponse aux données

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

PNL vers SQL

Diagramme ER

PNL vers SQL - Base de données

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

HTML pour Nlp vers SQL

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

novembre 17, 2023