Proyecto de solicitud de texto a SQL【Prompt Engineering】

Acabamos de comenzar un proyecto de código abierto, pg-text-query, con el objetivo de crear sugerencias de modelo de lenguaje grande (LLM) listas para producción para texto a SQL. Nuestro objetivo es desarrollar una traducción de texto a SQL de primer nivel utilizando LLM, nuestro propio conocimiento profundo de la base de datos PostgreSQL y pruebas rigurosas.
inserte la descripción de la imagen aquí

Recomendación: use NSDT Designer para crear rápidamente escenas 3D programables.

1. Texto a SQL: conceptos básicos

SQL es el tercer lenguaje de programación más utilizado. Es el primer idioma que aprenden muchos aspirantes a desarrolladores. Acabamos de lanzar la traducción de texto a SQL impulsada por IA en bit.io para reducir la barrera de entrada para aprender y usar SQL, lo que permite a los usuarios centrarse en la lógica subyacente de las consultas en lugar de la sintaxis.

Puedes usarlo ahora en bit.io. En el editor de consultas de bit.io o en la API de consultas, coloque lo siguiente en la primera línea: #!translate:text. En la siguiente línea, ingrese su solicitud de idioma simple como una pregunta, por ejemplo, ¿Qué registro con el proveedor 'aws' tiene la latencia más baja?, y se traducirá en una consulta que puede editar o ejecutar.

Nuestra función Text-to-SQL utiliza el modelo Codex de OpenAI para enviar texto e información del esquema de la base de datos ("sugerencias") a OpenAI LLM. El modelo genera el SQL solicitado y lo devuelve al usuario, quien luego puede editar (si es necesario) y ejecutar la consulta.
inserte la descripción de la imagen aquí

Esto puede sonar simple, como si solo enviáramos texto a una API de terceros y devolviéramos el resultado. Por supuesto, el LLM de OpenAI hace el trabajo pesado aquí. Sin embargo, hay muchos matices involucrados en asegurarse de que sus modelos devuelvan resultados utilizables y que se devuelvan de forma rápida, eficiente y segura. Ahí es donde enfocamos nuestra energía. Las decisiones como la selección del modelo, los valores de los hiperparámetros y el contenido de las solicitudes tienen un gran impacto en la calidad de los resultados devueltos.

2. Tecnología de punta (hasta ahora)

Nuestra función de traducción de texto a SQL funciona muy bien. Pasamos mucho tiempo trabajando en las sugerencias iniciales, comparando varios modelos diferentes y ajustando los hiperparámetros del modelo. Hasta ahora, la mayoría de las mejoras a las sugerencias se han realizado mediante prueba y error: leímos mucho sobre la ingeniería de sugerencias, escribimos muchas sugerencias e iteramos sobre lo que funcionó. También aprovechamos la función de agregación de esquemas existente para pasar los detalles del esquema junto con sugerencias, lo que permite que los modelos de OpenAI devuelvan SQL con los identificadores correctos.

El indicador actual es bastante simple. Comienza pasando tres anotaciones: la primera especifica el idioma (PostgreSQL); la segunda pasa los detalles del esquema (esquema, tablas, columnas, tipos); y la tercera especifica el resultado deseado, que contiene las consultas en lenguaje natural del usuario. La última línea del indicador, SELECT 1, indica que no queremos recibir la salida SQL como comentarios, sino SQL listo para ejecutar.

-- Language PostgreSQL
-- Table penguins, columns = [species text, island text, bill_length_mm double precision, bill_depth_mm double precision, flipper_length_mm bigint, body_mass_g bigint, sex text, year bigint]
-- A PostgreSQL query to return 1 and a PostgreSQL query for {natural language query}
SELECT 1;

Con esto en mente, dada una consulta explícitamente especificada en un lenguaje simple, los modelos de OpenAI normalmente:

  • devuelve el código de trabajo correspondiente a la consulta de texto sin formato del usuario,
  • devuelve código SQL compatible con Postgres, no código de otros lenguajes u otras variantes de SQL, y
  • Incluya el identificador correcto (pero no siempre bien formado; consulte a continuación) correspondiente al esquema de la base de datos

inserte la descripción de la imagen aquí

3. Desafío

Todavía hay margen de mejora.

Uno de los principales obstáculos es enviar sugerencias concisas a los modelos Codex sin dejar de proporcionar suficiente información del esquema. Queremos brindar suficiente información sobre el esquema de la base de datos para realizar consultas utilizables sin enviar demasiados tokens en el indicador y posiblemente aumentar el costo de usar la API modelo de OpenAI.

Formatear y citar correctamente algunos identificadores es otro desafío. La salida era correcta la mayor parte del tiempo, pero en algunos casos las tablas en esquemas que no eran "públicos" tenían un formato incorrecto y los nombres de las tablas con mayúsculas o caracteres especiales entre comillas no se devolvían. Estos matices específicos de la sintaxis SQL requieren un manejo cuidadoso para garantizar un resultado preciso.

Prevenir el abuso de la funcionalidad de transformación de texto a SQL a través de la inyección de sugerencias es otro desafío importante, crítico para mantener la confianza del usuario en el sistema. Evitar el uso indebido nos ayuda a reducir nuestro enfoque y garantiza que no incurramos en costos innecesarios ni nos arriesguemos a exponer herramientas de traducción de código comunes. Por ejemplo, actualmente es posible (aunque inconveniente) generar código en otros lenguajes mediante:

#!translate:text
return a string defining a python function for adding two numbers

Esta consulta devuelve:

SELECT 'def add(x, y): return x + y'

Hay formas más fáciles de obtener código Python generado por IA y hay buenas razones para almacenar fragmentos de código en bases de datos. La simple prevención de este patrón de uso no resolverá el problema, pero todavía es valioso anticipar y prepararse para posibles patrones de uso inesperados.

Finalmente, es importante evitar que los usuarios modifiquen o eliminen datos accidentalmente. Nadie debe ejecutar código generado por LLM sin revisión. Pero también queremos ser muy conscientes de cuándo un usuario puede ejecutar una consulta que podría resultar en la modificación o pérdida de datos.

Por ejemplo, la sugerencia (bastante vaga):

#!translate:text
update the table to make it clear that all of the islands in the table are in Antarctica.

Devuelve el siguiente SQL:

UPDATE penguins SET island = 'Antarctica' WHERE island IS NOT NULL

Superponer la columna "Islas" con la Antártida probablemente no sea la intención del usuario. Tal vez la intención era agregar una columna de "continente" o agregar "(Antártida)" a cada entrada en la columna de islas, aunque la intención no está clara en el aviso. En cualquier caso, sería útil contar con las medidas de seguridad adecuadas para evitar que los usuarios realicen ciegamente tales consultas y cambien los datos accidentalmente.

Por supuesto, no estamos señalando estos desafíos por diversión. Tenemos planes para abordar estos problemas.

4. proyecto de código abierto pg-text-query

Estamos mejorando continuamente la función de traducción de texto a SQL. queremos compartir Estamos desarrollando un proyecto de código abierto para sugerencias, configuración y pruebas para interactuar con la comunidad y recopilar comentarios, y compartir ampliamente nuestros hallazgos. Los LLM a menudo se usan como generalistas: son buenos para traducir cualquier idioma a cualquier otro y responder a indicaciones de texto arbitrarias. Queremos aprender cómo hacer el mejor traductor de texto a SQL posible.

Puede comenzar a usar algunas funciones clave de inmediato: estas herramientas le permiten comenzar a mejorar de inmediato las indicaciones para la conversión de texto a SQL.

5. Patio de juegos de palabras rápidas

Clone este repositorio ; instale streamlit con pip install streamlit.py; luego, ejecute streamlit run playground/app.py desde el directorio raíz. Esto abrirá un "patio de juegos de palabras rápidas" interactivo donde puede experimentar con diferentes combinaciones de indicaciones y detalles de patrones.

inserte la descripción de la imagen aquí

Esto es útil para probar e iterar rápidamente diferentes ideas rápidas y desarrollar la intuición sobre lo que funciona y lo que no. Puede establecer "sugerencias de inicialización" (a las que el usuario final no tiene acceso), la consulta de idioma simple del usuario y los detalles del esquema, y ​​ver cómo interactúan entre sí estas diferentes partes de la consulta. El SQL se puede generar e incluso ejecutar en la base de datos en vivo. Asegúrese de verificar dos veces todo el SQL generado antes de ejecutarlo para asegurarse de no eliminar o modificar datos accidentalmente.
inserte la descripción de la imagen aquí

6. Utilidad de detalles del esquema

El módulo db_schema.py incluye utilidades para extraer datos de esquemas estructurados de las bases de datos de Postgres. Es útil proporcionar suficiente información de esquema para permitir que el modelo contenga el identificador correcto. Sin embargo, demasiada información de esquema puede comprometer una gran cantidad de tokens, lo que genera costos innecesarios y puede dejar muy pocos tokens para que el modelo genere con éxito el SQL requerido.

Puede utilizar este módulo de la siguiente manera:

import os
from pprint import pprint

import bitdotio
from dotenv import load_dotenv
from pg_text_query import get_db_schema

DB_NAME = "bitdotio/palmerpenguins"
b = bitdotio.bitdotio(os.getenv("BITIO_KEY"))

# Extract a structured db schema from Postgres
with b.pooled_cursor(DB_NAME) as cur:
db_schema = get_db_schema(cur, DB_NAME)
pprint(db_schema)

7. Generación de avisos y consultas

Puede generar avisos (basados ​​en nuestro trabajo de ingeniería de avisos hasta el momento) utilizando el módulo prompt.py, que proporciona ayuda para preparar avisos de consulta de Postgres.

# Construct a prompt that includes text description of query
prompt = get_default_prompt(
"most common species and island for each island",
db_schema,
)

# Note: prompt includes extra `SELECT 1` as a naive approach to hinting for
# raw SQL continuation
print(prompt)

Devuelve las siguientes sugerencias:

-- Language PostgreSQL
-- Table penguins, columns = [species text, island text, bill_length_mm double precision, bill_depth_mm double precision, flipper_length_mm bigint, body_mass_g bigint, sex text, year bigint]
-- A PostgreSQL query to return 1 and a PostgreSQL query for most common species and island for each island
SELECT 1;

El módulo gen_query.py es un contenedor alrededor de openai.Completion.create que maneja
el envío de solicitudes a la API de OpenAI.

# Using default OpenAI request config, which can be overriden here w/ kwargs
query = generate_query(prompt)
print(query)

Volviendo desde el mensaje anterior:

SELECT species, island, COUNT(*) FROM penguins GROUP BY species, island

8. Plan del siguiente paso

Este proyecto aún está en su infancia, pero tenemos algunas direcciones principales que queremos explorar:

  • El proyecto incluirá un conjunto de pruebas con diferentes tipos de consultas y texto requerido para probar diferentes avisos.
  • Usando este conjunto de pruebas, planeamos comparar diferentes modelos, hiperparámetros y sugerencias. ¿Algunos son más precisos que otros? ¿Podemos lograr la misma precisión con indicaciones más cortas? ¿Podemos usar modelos más rápidos o más eficientes sin sacrificar la precisión?
  • Planeamos documentar cualquier vía para el abuso de modelos, junto con estrategias de mitigación.
  • A la larga, también ajustaremos el modelo para una gran cantidad de consultas y traducciones de SQL.

Enlace original: Proyecto de solicitud de texto a SQL—BimAnt

Supongo que te gusta

Origin blog.csdn.net/shebao3333/article/details/130741976
Recomendado
Clasificación