Utilizzare le visualizzazioni con parametri nelle applicazioni con agenti

Per eseguire in sicurezza le visualizzazioni con parametri nelle applicazioni Bigtable che utilizzano agenti AI o modelli linguistici di grandi dimensioni (LLM), devi stabilire un controllo degli accessi rigoroso e passare i parametri fuori banda.

Configurare controllo dell'accesso

Le visualizzazioni logiche di Bigtable operano su un modello di sicurezza dei diritti del definer. Ciò significa che quando esegui una query su una visualizzazione, la query viene eseguita con le autorizzazioni dell'utente che ha definito la visualizzazione, non dell'utente che esegue la query. Per applicare il principio del privilegio minimo, concedi al service account della tua applicazione le autorizzazioni per accedere solo alla visualizzazione, negando le autorizzazioni alla tabella di origine sottostante.

Segui questi passaggi per configurare controllo dell'accesso:

  1. Crea un ruolo IAM dedicato per la tua applicazione con autorizzazioni minime, ad esempio il ruolo bigtable.reader.
  2. Concedi a questo ruolo le autorizzazioni di sola visualizzazione. Puoi utilizzare una condizione IAM per limitare l'autorizzazione bigtable.logicalViews.readRows alla tua visualizzazione specifica.
  3. Per controllo dell'accesso più rigoroso, nega esplicitamente al ruolo dell'applicazione qualsiasi autorizzazione sulla tabella di base sottostante utilizzando un criterio di negazione IAM.

Per saperne di più, consulta Controllo controllo dell'accesso Bigtable con IAM.

Inserire un parametro di visualizzazione

Nelle applicazioni con agenti, i valori dei parametri per la visualizzazione logica con parametri, come le credenziali utente o i limiti del tenant, devono essere forniti dal codice dell'applicazione attendibile, non dall'LLM o dall'utente finale. In questo modo, l'input utente non attendibile e le stringhe di query generate dal modello vengono isolati dagli input del database.

Per creare un agente AI, puoi utilizzare il framework Agent Development Kit (ADK). ADK fornisce i seguenti componenti che ti aiutano a integrare le visualizzazioni con parametri:

  • BigtableToolset: il set di strumenti di database ADK che configura e fornisce strumenti rivolti al database (in particolare execute_sql_parameterized) che comunicano con Bigtable. Questo set di strumenti estrae automaticamente i parametri della visualizzazione fuori banda ed esegue la query SQL sui dati.
  • ToolContext: il meccanismo di runtime che esegue il sandboxing dello stato specifico della sessione e delle proprietà dell'infrastruttura, consentendo agli strumenti di risolvere i parametri di filtro sensibili senza esporli all'LLM.

L'immagine seguente mostra come i componenti interagiscono per inserire un parametro in Bigtable:

Il processo di inserimento di un parametro di visualizzazione in Bigtable.
Figura 1. Il processo di integrazione delle visualizzazioni con parametri in un'applicazione con agenti (fai clic per ingrandire).

I passaggi seguenti spiegano ulteriormente il processo di inserimento dei parametri:

  1. La tua applicazione autentica l'utente finale e ottiene le sue credenziali utente verificate e l'organizzazione del tenant.
  2. L'applicazione riceve una query in linguaggio naturale dall'utente.
  3. L'applicazione esegue l'agente ADK, passando gli identificatori dell'utente autenticato e del tenant nello stato della sessione sicura.
  4. Quando l'agente decide di eseguire una query sul database, determina solo gli argomenti di filtro in linguaggio naturale, ad esempio una città, e richiama lo strumento execute_sql_parameterized.
  5. Lo strumento di database sottostante recupera in modo sicuro le credenziali utente sensibili e i limiti del tenant da ToolContext ed esegue la query su Bigtable.

L'esempio seguente mostra come configurare un'applicazione con agenti utilizzando ADK per eseguire una query sulla cronologia degli acquisti di un utente.

Configurare il set di strumenti Bigtable

Nell'applicazione Python, configura BigtableToolset ADK con i nomi dei parametri che vuoi risolvere fuori banda (view_parameter_names). In questo modo, le proprietà dell'infrastruttura del framework, come user_id, e le variabili di sessione dell'applicazione, come tenant_id, vengono mappate direttamente alla query del database.

import google.auth
from google.adk.agents.llm_agent import LlmAgent
from google.adk.tools.bigtable.bigtable_credentials import BigtableCredentialsConfig
from google.adk.tools.bigtable.bigtable_toolset import BigtableToolset

# 1. Initialize credentials (using Application Default Credentials here)
credentials, _ = google.auth.default()
credentials_config = BigtableCredentialsConfig(credentials=credentials)

# 2. Configure the BigtableToolset
# Passing view_parameter_names=["user_id", "tenant_id"] instructs the toolset
# to automatically extract both parameters from the ToolContext at runtime
# and inject them into the query's view_parameters.
bigtable_toolset = BigtableToolset(
    credentials_config=credentials_config,
    view_parameter_names=["user_id", "tenant_id"],
)

Inizializzare l'agente con il set di strumenti

Passa il set di strumenti direttamente all'elenco tools dell'agente. L'agente rileverà ed esporrà automaticamente lo strumento execute_sql_parameterized con tipo sicuro.

# 3. Create the agent and expose the toolset
agent = LlmAgent(
    model="MODEL_NAME",
    name="purchase_history_agent",
    description="An agent that retrieves multi-tenant purchase history.",
    instruction="You are an assistant that helps users find their purchase history within their tenant.",
    tools=[bigtable_toolset],
)

Sostituisci MODEL_NAME con il nome del modello che vuoi utilizzare, ad esempio gemini-2.5-flash.

Eseguire l'applicazione con agenti

Quando esegui l'agente, inizializza la sessione attiva con l'identità utente dell'infrastruttura e lo stato dell'organizzazione dell'applicazione.

import asyncio
from google.adk.runners import Runner
from google.adk.sessions import InMemorySessionService
from google.genai import types

async def main():
    # 4. Initialize session service
    session_service = InMemorySessionService()

    # 5. Create a session for the authenticated user and store their specific
    # organization tenant in the state.
    authenticated_user_id = "user-anwesha-123"
    organization_tenant_id = "tenant-corp-alpha"

    session = await session_service.create_session(
        user_id=authenticated_user_id, # Resolved from tool_context.user_id
        # Resolved from tool_context.state["tenant_id"]
        state={"tenant_id": organization_tenant_id},
        app_name="purchase_history_app",
    )

    runner = Runner(
        app_name="purchase_history_app",
        agent=agent,
        session_service=session_service,
    )

    # 6. Simulate a user query
    user_query = "What did I buy in New York?"
    content = types.Content(role="user", parts=[types.Part(text=user_query)])

    # The runner runs the agent.
    # When the agent calls execute_sql_parameterized, the ADK framework resolves
    # both "user_id" and "tenant_id" out-of-band and passes them to Bigtable
    # as view parameters, completely hidden from the LLM.
    events = runner.run(
        session_id=session.id,
        user_id=session.user_id,
        new_message=content,
    )

    for event in events:
        if event.content and event.content.parts:
            print(f"Agent: {event.content.parts[0].text}")

if __name__ == "__main__":
    asyncio.run(main())

Il risultato è un elenco di record della cronologia acquisti per l'utente autenticato, filtrati in base alla città specificata nella query e limitati al limite del tenant.

Questo processo garantisce che i parametri di sicurezza vengano inseriti fuori banda e rimangano completamente nascosti dalla manipolazione del modello linguistico.