En esta página, se describe una versión preliminar disponible con AlloyDB Omni que te permite experimentar con la consulta de tu base de datos con lenguaje natural.
Descripción general
Puedes usar AlloyDB Omni para obtener una vista previa de un conjunto de funciones experimentales que permiten que tu aplicación basada en la base de datos ejecute consultas en lenguaje natural de forma más segura desde los usuarios de tu aplicación, como "¿Dónde está mi paquete?" o "¿Quién es el que más gana en cada departamento?". AlloyDB Omni traduce la entrada de lenguaje natural en una consulta en SQL específica de tu base de datos, lo que restringe los resultados solo a lo que el usuario de tu aplicación puede ver.
La potencia y los riesgos de las consultas de lenguaje natural
Los modelos de lenguaje grandes, como Gemini Pro, pueden permitir que tu aplicación ejecute consultas a la base de datos basadas en consultas de lenguaje natural que crean los usuarios finales de tu aplicación. Por ejemplo, un modelo con acceso al esquema de la base de datos de tu aplicación puede aceptar entradas del usuario final de la siguiente manera:
What are the cheapest direct flights from Boston to Denver in July?
Y transfórmala en una consulta en SQL como esta:
SELECT flight.id, flight.price, carrier.name, [...]
FROM [...]
WHERE [...]
ORDER BY flight.price ASC
LIMIT 10
Las consultas en lenguaje natural pueden proporcionarle a tu aplicación una herramienta potente para servir a tus usuarios. Sin embargo, esta tecnología también conlleva riesgos de seguridad claros que debes tener en cuenta antes de permitir que los usuarios finales ejecuten consultas arbitrarias en las tablas de tu base de datos. Incluso si configuraste tu aplicación para que se conecte a tu base de datos como un usuario de base de datos de solo lectura con acceso limitado, una aplicación que invite a consultas en lenguaje natural puede ser vulnerable a lo siguiente:
- Los usuarios maliciosos pueden enviar ataques de inserción de instrucciones para intentar manipular el modelo subyacente y revelar todos los datos a los que tiene acceso la aplicación.
- El modelo en sí podría generar consultas de SQL más amplias de lo que es apropiado, lo que revelaría datos sensibles en respuesta incluso a consultas de usuarios bien intencionadas.
Cómo limpiar consultas con vistas seguras parametrizadas
Para ayudar a mitigar los riesgos descritos en la sección anterior, Google desarrolló vistas seguras parametrizadas, una función experimental que puedes obtener como versión preliminar con las técnicas que se describen en esta página.
Las vistas seguras parametrizadas te permiten definir de forma explícita las tablas y columnas de las que las consultas de lenguaje natural pueden extraer datos y agregar restricciones adicionales al rango de filas disponibles para un usuario de la aplicación individual. Estas restricciones te permiten controlar de forma estricta los datos que los usuarios de tu aplicación pueden ver a través de búsquedas en lenguaje natural, sin importar cómo formulen estas búsquedas.
Si habilitas esta vista previa, obtendrás acceso a extensiones experimentales desarrolladas por Google llamadas alloydb_ai_nl
y parameterized_views
.
La extensión parameterized_views
proporciona las siguientes funciones:
- Vistas seguras parametrizadas, una variante de las vistas de SQL para restringir el rango de datos a los que puede acceder una consulta
- La función
execute_parameterized_views()
, que te permite consultar tus vistas seguras parametrizadas
La extensión alloydb_ai_nl
proporciona la siguiente función:
- La función
google_get_sql_current_schema()
, que convierte las consultas de lenguaje natural en consultas de SQL de tablas y vistas en tu esquema actual.
En las siguientes secciones, se describe cómo usar estas funciones y se muestra cómo pueden funcionar en conjunto.
Antes de comenzar
Instala AlloyDB Omni versión 15.5.1 o una posterior, incluida la integración de modelos de IA. Para obtener más información, consulta Cómo instalar AlloyDB Omni con la IA de AlloyDB para PostgreSQL.
Configura tu base de datos para vistas seguras parametrizadas
Edita el contenido de
/var/alloydb/config/postgresql.conf
para que el valor de la directivashared_preload_libraries
incluyaalloydb_ai_nl
yparameterized_views
. La directiva editada debería ser similar a la siguiente:shared_preload_libraries='g_stats,google_job_scheduler,google_insights,pg_stat_statements,google_db_advisor,google_columnar_engine,alloydb_ai_nl,parameterized_views'
Habilita las extensiones
alloydb_ai_nl
yparameterized_views
:CREATE EXTENSION google_ml_integration; ALTER SYSTEM SET google_ml_integration.enable_model_support=on; ALTER SYSTEM SET alloydb_ai_nl.enabled=on; ALTER SYSTEM SET parameterized_views.enabled=on; SELECT pg_reload_conf(); CREATE EXTENSION alloydb_ai_nl CASCADE; CREATE EXTENSION parameterized_views;
Registra un nuevo modelo de lenguaje basado en la API de Gemini Pro con la administración de extremos de modelos:
CALL google_ml.create_model( model_id => 'MODEL_ID', model_request_url => 'https://us-central1-aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/publishers/google/models/gemini-pro:streamGenerateContent', model_provider => 'google', model_auth_type => 'alloydb_service_agent_iam');
Reemplaza lo siguiente:
MODEL_ID
: Un ID para asignar a este modelo. Para obtener más información sobre la administración de extremos de modelos, consulta Cómo registrar y llamar a modelos de IA remotos en AlloyDB Omni.PROJECT_ID
: El ID de tu proyecto de Google Cloud .
Crea un usuario de base de datos nuevo. Aún no le otorgues ningún permiso ni rol. Un paso posterior de este procedimiento le otorga al usuario los permisos que requiere.
Vistas seguras parametrizadas
Una vista segura parametrizada funciona de manera muy similar a una vista segura de PostgreSQL normal: es una sentencia SELECT
almacenada, en esencia. Además, las vistas seguras parametrizadas te permiten exigir uno o más valores de parámetros nombrados que se pasan a la vista cuando la consultas, algo similar a las variables de vinculación con consultas de bases de datos ordinarias.
Por ejemplo, imagina que ejecutas una aplicación cuya base de datos realiza un seguimiento de los envíos de artículos a los clientes. Un usuario accedió a esta aplicación con el ID de tipos 12345
en la consulta Where is my package?
. Con las vistas seguras parametrizadas, puedes asegurarte de que se apliquen los siguientes requisitos a la forma en que AlloyDB para PostgreSQL ejecuta esta consulta:
- La consulta solo puede leer las columnas de la base de datos que enumeraste de forma explícita en las vistas seguras parametrizadas de tu base de datos. En este caso, podrían ser ciertas columnas de tus tablas
items
,users
yshipments
. - La consulta solo puede leer las filas de la base de datos asociadas con el usuario que realizó la consulta. En este caso, es posible que las filas que se devuelven tengan una relación de datos con la fila de la tabla
users
cuyo valor de la columnaid
sea12345
.
Crea una vista segura parametrizada
Para crear una vista segura parametrizada, usa el comando DDL CREATE VIEW
de PostgreSQL con los siguientes atributos:
- Crea la vista con la opción
security_barrier
. - Para restringir a los usuarios de la aplicación a ver solo las filas que tienen permitido ver, agrega los parámetros obligatorios con la sintaxis
$@PARAMETER_NAME
en la cláusula WHERE. Un caso común es verificar el valor de una columna conWHERE COLUMN = $@PARAMETER_NAME
.
En el siguiente ejemplo, la vista segura parametrizada permite el acceso a tres columnas de una tabla llamada users
y limita los resultados solo a las filas en las que users.id
coincide con un parámetro obligatorio:
CREATE VIEW user_psv WITH (security_barrier) AS
SELECT
username,
full_name,
birthday
FROM
users
WHERE
users.id = $@user_id;
Las instrucciones SELECT
en el centro de las vistas seguras parametrizadas pueden ser tan complejas como las instrucciones permitidas por las vistas ordinarias de PostgreSQL.
Después de crear una vista, debes otorgarle al usuario que creaste antes permiso para ejecutar consultas SELECT
en la vista:
GRANT SELECT ON VIEW_NAME TO NL_DB_USER;
Reemplaza lo siguiente:
VIEW_NAME
: Es el nombre de la vista que creaste en el paso anterior.NL_DB_USER
: Es el nombre del usuario de la base de datos que designaste para ejecutar consultas de lenguaje natural.
Cómo consultar una vista segura parametrizada
A pesar de su similitud con las vistas normales de PostgreSQL, no puedes consultar las vistas seguras parametrizadas directamente. En su lugar, usa la función execute_parameterized_query()
que proporciona la extensión parameterized_views
. La función tiene la siguiente sintaxis:
SELECT * FROM
parameterized_views.execute_parameterized_query(
query => SQL_QUERY
param_names => ARRAY [PARAMETER_NAMES],
param_values => ARRAY [PARAMETER_VALUES]
)
Reemplaza lo siguiente:
SQL_QUERY
: Es una consulta en SQL cuya cláusulaFROM
hace referencia a una o más vistas seguras parametrizadas.PARAMETER_NAMES
: Es una lista de nombres de parámetros que se pasarán como cadenas.PARAMETER_VALUES
: Es una lista de valores de parámetros que se pasarán. Esta lista debe tener el mismo tamaño que la listaparam_names
. El orden de los valores coincide con el orden de los nombres.
La función muestra una tabla de objetos JSON. Cada fila de la tabla es equivalente al valor row_to_json()
de la fila del resultado de la consulta original.
En el uso típico, el valor del argumento query
no lo genera tu
propio código, sino un modelo de IA con el que integraste tu
base de datos de AlloyDB para PostgreSQL.
En el siguiente ejemplo, se muestra cómo puedes consultar una vista segura parametrizada en Python y, luego, mostrar sus resultados. Se basa en la vista de ejemplo de user_psv
de la sección anterior:
# Assume a get_user_id() function that returns the ID of the current
# application user.
app_user_id = get_user_id()
pool = await asyncpg.create_pool(
host=INSTANCE_IP
user=NL_DB_USER
password=NL_DB_PASSWORD
database=DB_NAME
)
table_name = "user_psv"
query = f"""
SELECT
full_name,
birthday
FROM
{table_name}
"""
params = {
"user_id": app_user_id
}
param_query = f"""
SELECT * FROM parameterized_views.execute_parameterized_query(
query => '{query}',
param_names => $1,
param_values => $2
);
"""
sql_results = await pool.execute(
param_query,
params.keys(),
params.values()
)
for row in sql_results:
print(json.loads(row))
Ejecuta una consulta en lenguaje natural
Ejecutar una consulta en lenguaje natural con vistas seguras parametrizadas es un proceso de dos pasos:
- Como usuario de la base de datos con solo acceso
SELECT
a las vistas seguras parametrizadas adecuadas, convierte la consulta de lenguaje natural a SQL con un modelo de lenguaje extenso. - Usa la función
execute_parameterized_query()
para procesar la SQL y vincularla a los valores de parámetros adecuados para la sesión del usuario actual.
En las siguientes secciones, se describen estos pasos con más detalle.
Convierte lenguaje natural a SQL
Para traducir la entrada de lenguaje natural a SQL, usa la función google_get_sql_current_schema()
que se incluye con la vista previa de la tecnología de vistas seguras parametrizadas:
SELECT alloydb_ai_nl.google_get_sql_current_schema(
sql_text => 'NL_TEXT',
model_id => 'MODEL_ID',
prompt_text => 'HINT_TEXT'
);
Reemplaza lo siguiente:
NL_TEXT
: Es el texto en lenguaje natural que se convertirá en una consulta en SQL.MODEL_ID
: Es el ID del modelo que registraste en el catálogo de modelos cuando configuraste tu base de datos para vistas seguras parametrizadas.HINT_TEXT
: Información adicional sobre el esquema de la base de datos, expresada en lenguaje natural. Esto te permite darle al modelo sugerencias adicionales sobre aspectos importantes del esquema que podría no extraer solo con el análisis de la tabla, la columna y las estructuras de relación. A continuación, se muestra un ejemplo:When joining flights and seats, be sure to join on flights.id = seats.flight_id.
El resultado de la función es una cadena que contiene una consulta en SQL.
Ejecuta el SQL convertido con parámetros
Después de convertir la consulta en lenguaje natural a SQL, puedes llamar a execute_parameterized_views()
como se describió anteriormente en esta página y pasar los parámetros que puedan necesitar tus vistas seguras parametrizadas.
La función funciona si le pasas más parámetros de los que necesita con una consulta determinada, de modo que puedes llamarla con todos los parámetros que usan todas las vistas seguras parametrizadas para las que tu aplicación tiene valores. La función arroja una excepción si intenta ejecutar una consulta que requiere un parámetro no definido.
Ejemplo de ejecución de una consulta de lenguaje natural
En esta sección, se muestra un flujo completo desde la entrada de lenguaje natural hasta el conjunto de resultados de SQL. En las muestras de código, se muestran las consultas y funciones de SQL subyacentes que ejecuta una aplicación.
Para este flujo de ejemplo, supongamos lo siguiente sobre tu aplicación:
- Tu aplicación basada en una base de datos realiza un seguimiento de los envíos de productos a los clientes.
- Registraste un modelo basado en Gemini Pro llamado
my-gemini-model
en el catálogo de modelos. - Definiste una vista segura parametrizada en tu base de datos llamada
shipment_view
.- La vista selecciona datos de varias tablas relevantes para los envíos a los clientes.
- La vista requiere un parámetro
user_id
, cuyo valor es el ID de un usuario final de la aplicación.
- Un usuario final cuyo ID de usuario de la aplicación es
12345
escribe "¿Dónde está mi paquete?" en tu aplicación web. Tu aplicación llama a
google_get_sql_current_schema()
para traducir la entrada a SQL:SELECT alloydb_ai_nl.google_get_sql_current_schema( sql_text => 'Where is my package?' model_id => 'my-gemini-model' );
Esta llamada muestra una cadena que contiene una sola consulta
SELECT
de SQL. La consulta se limita solo a las vistas seguras parametrizadas que puede ver el usuario de la base de datos que creaste para trabajar con vistas seguras parametrizadas.El SQL generado a partir de
Where is my package?
podría ser similar al siguiente:SELECT current_location, ship_date, ship_eta FROM shipment_view;
Debido a que
shipment_view
es una vista segura parametrizada y no una vista de PostgreSQL ordinaria, tu aplicación debe usarexecute_parameterized_views()
para ejecutar de forma segura la consulta con el parámetrouser_id
que requiere, como se muestra en el siguiente paso.Tu aplicación pasa la SQL a
execute_parameterized_views()
, junto con los parámetros que restringen el resultado. En nuestro ejemplo, ese es el ID del usuario final de la aplicación que proporcionó la entrada:SELECT * FROM parameterized_views.execute_parameterized_views( query => 'SELECT current_location, ship_date, ship_eta FROM shipment_view', param_names => ['user_id'], param_values => ['12345'] );
El resultado es un conjunto de resultados de SQL, expresado como datos JSON.
Tu aplicación controla los datos JSON según sea necesario.
Diseño de bases de datos para el manejo de lenguaje natural
La función google_get_sql_current_schema()
proporcionada con esta vista previa de la tecnología sirve principalmente para demostrar la funcionalidad de las vistas seguras parametrizadas, lo que te brinda una oportunidad anticipada de experimentar con esta tecnología en desarrollo. Al igual que con cualquier versión preliminar, no debes aplicar esta función a una aplicación en producción.
Con eso en mente, puedes aplicar los consejos de esta sección para mejorar la
calidad del resultado de google_get_sql_current_schema()
durante tu experimentación
con él.
Diseña tu esquema para la comprensión humana
En general, asigna nombres y comentarios a las estructuras de tu base de datos lo suficientemente claros como para permitir que un desarrollador humano típico infiera el propósito de sus tablas, columnas y relaciones. Esta claridad puede ayudar a que un modelo de lenguaje grande genere consultas SQL más precisas según tu esquema.
Usa nombres descriptivos
Usa nombres descriptivos para las tablas, las columnas y las relaciones. Evita
abreviaturas o siglas. Por ejemplo, el modelo funciona mejor con una tabla llamada users
que con una llamada u
.
Si no es posible cambiar el nombre de las estructuras de datos existentes, proporciona sugerencias al modelo con el argumento prompt_text
cuando llames a google_get_sql_current_schema()
.
Usa tipos de datos específicos
El modelo puede hacer mejores inferencias sobre tus datos si usas tipos de datos más específicos con tus columnas. Por ejemplo, si usas una columna exclusivamente para almacenar valores de verdadero o falso, usa un tipo de datos boolean
con true
y false
en lugar de un integer
con 1
y 0
.
Revierte con precaución después de habilitar la vista previa
Si habilitaste la vista previa de la tecnología de vistas seguras parametrizadas en tu base de datos, pero luego decides revertir AlloyDB Omni a una versión anterior a la 15.5.0, debes seguir algunos pasos de limpieza manuales antes de realizar la reversión.
Si no sigues estos pasos, cualquier intento de consultar, modificar o descartar una vista segura parametrizada generará un error de SQL. Esto incluye las consultas en el catálogo de vistas de tu base de datos que, de otro modo, incluirían vistas seguras parametrizadas en sus resultados, como SELECT * FROM pg_views
.
Para quitar por completo esta versión preliminar de la tecnología de tu base de datos antes de una rollback de AlloyDB Omni, sigue estos pasos:
En
psql
, usa el comandoDROP VIEW
para borrar todas las vistas seguras parametrizadas de tu base de datos.En
psql
, usa el comandoDROP EXTENSION
para inhabilitar las extensionesalloydb_ai_nl
yparameterized_views
en tu base de datos.En tu archivo
postgresql.conf
, quita la referencia aalloydb_ai_nl
yparameterized_views
de la directivashared_preload_libraries
.
Para obtener más información sobre cómo revertir la instalación de AlloyDB Omni, consulta Cómo revertir una actualización.