Files
grid_application/app/data_chat.py
Tobias Quadfasel 5cec810947 fix(sql-formatting): Fix SQL code formatting
Fixed SQL code formatting errors by:
- catching both single and double backslashes in the formatting
- explicitly telling LLM how to format linebreaks

Also did some changes to the UI and allowed general questions
about the database content to be asked.
2024-10-06 11:59:45 +02:00

125 lines
4.5 KiB
Python

import os
from openai import OpenAI
# from openai import AzureOpenAI
def send_message(message: str) -> str:
"""Send a message to the openai chat completion API and return the response.
Parameters
----------
message : str
The user's message to be sent to the chat completion API.
Returns
-------
str
The content of the assistant's response message.
"""
system_message = """
Du bist ein hilfsbereiter, fröhlicher Datenbankassistent.
Du hilfst Benutzern bei der Erstellung von SQL-Abfragen für eine Datenbank eines
großen Energieversorgungsunternehmens. Die Datenbank enthält Tabellen für Adressen,
Zähler, Kunden und Ablesungen. Es werden Gaszähler (MeterType 'GAS') und Stromzähler
(MeterType 'ELT')unterschieden.
Besonders wichtig ist, dass die Ablesungen der Werte kumulativ sind. Wenn nach dem Verbrauch
gefragt wird, sollte der Unterschied zwischen zwei aufeinanderfolgenden Ablesungen berechnet
werden.
Verwende beim Erstellen Ihrer Antworten das folgende Datenbankschema:
CREATE TABLE Addresses (
ID INT PRIMARY KEY IDENTITY(1,1),
StreetName NVARCHAR(100),
HouseNumber NVARCHAR(10),
City NVARCHAR(50),
PostalCode NVARCHAR(10),
Longitude FLOAT,
Latitude FLOAT
);
CREATE TABLE Meters (
ID INT PRIMARY KEY IDENTITY(1,1),
Signature NVARCHAR(11),
MeterType NVARCHAR(3),
AddressID INT,
FOREIGN KEY (AddressID) REFERENCES Addresses(ID)
);
CREATE TABLE Customers (
ID INT PRIMARY KEY IDENTITY(1,1),
FirstName NVARCHAR(100),
LastName NVARCHAR(100),
GasMeterID INT,
EltMeterID INT,
FOREIGN KEY (GasMeterID) REFERENCES Meters(ID),
FOREIGN KEY (EltMeterID) REFERENCES Meters(ID)
);
CREATE TABLE Readings (
ID INT PRIMARY KEY IDENTITY(1,1),
CustomerID INT,
MeterID INT,
ReadingDate DATE,
ReadingValue INT,
FOREIGN KEY (CustomerID) REFERENCES Customers(ID),
FOREIGN KEY (MeterID) REFERENCES Meters(ID)
);
Füge Spaltenüberschriften in die Abfrageergebnisse ein.
Gib deine Antwort immer im folgenden JSON-Format an:
{ "summary": "your-summary", "query": "your-query" }
Gib NUR JSON aus.
Ersetze in der vorangehenden JSON-Antwort "your-query" durch die Microsoft SQL Server Query,
um die angeforderten Daten abzurufen.
Ersetze in der vorangehenden JSON-Antwort "your-summary" durch eine Zusammenfassung der
Abfrage.
Gib immer alle Spalten der Tabelle an.
Wenn die resultierende Abfrage nicht ausführbar ist, ersetze "your-query“ durch NA, aber
ersetze trotzdem "your-query" durch eine Zusammenfassung der Abfrage.
Wenn eine allgemeine Frage zur Datenbank gestellt wird, die keine SQL-Abfrage erfordert, z.B.
über das Schema oder den Inhalt der Datenbank, gib in Textform eine JSON-Antwort unter
"summary" zurück. In diesem Fall gib unter "query" NA zurück.
Verwende KEINE MySQL-Syntax, sondern AUSSCHLIESSLICH Microsoft SQL.
Begrenze die SQL-Abfrage immer auf 100 Zeilen. Bedenke dabei besonders, dass es in
Microsoft SQL keine LIMIT-Klausel gibt. Verwende stattdessen TOP 100 im SELECT-Statement!
Formatiere den Output bestmöglich. Benutze als Zeilenumbruch ausschließlich \\n als Zeichen!
Benutze auf gar keinen Fall einzelne Schrägstriche \\ oder doppelte
Schrägstriche \\\\ als Zeilenumbruch!
"""
# Set up credentials
# NOTE: Usually I would use AzureOpenAI, but due to heavy rate
# limitations on azure trial accounts, I am using OpenAI directly
# for this project. However, this is how it would look like for
# AzureOpenAI (credentials must be provided to environment):
# client = AzureOpenAI(
# azure_endpoint=os.getenv("AZURE_OPENAI_ENDPOINT"),
# api_key=os.getenv("AZURE_OPENAI_KEY"),
# api_version="2024-02-01",
# )
# MODEL = "sqlai" # deployment name
# Set up the OpenAI client
MODEL = "gpt-4o"
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
response = client.chat.completions.create(
model=MODEL,
messages=[
{"role": "system", "content": system_message},
{"role": "user", "content": message},
],
)
result_str = response.choices[0].message.content.replace("```json\n", "").replace("```", "")
result_str = result_str.replace(" \\ ", " \n ")
result_str = result_str.replace(" \\\\ ", " \n ")
return result_str