Utiliser des vues paramétrées dans des applications agentiques

Pour exécuter des vues paramétrées de manière sécurisée dans des applications Bigtable qui utilisent des agents IA ou des grands modèles de langage (LLM), vous devez établir un contrôle des accès strict et transmettre les paramètres hors bande.

Configurer le contrôle des accès

Les vues logiques Bigtable fonctionnent sur un modèle de sécurité basé sur les droits du définisseur. Cela signifie que lorsque vous interrogez une vue, la requête s'exécute avec les autorisations de l'utilisateur qui a défini la vue, et non de l'utilisateur qui exécute la requête. Pour appliquer le principe du moindre privilège, accordez au compte de service de votre application des autorisations d'accès à la vue uniquement, tout en refusant les autorisations d'accès à la table source sous-jacente.

Pour configurer le contrôle des accès :

  1. Créez un rôle IAM dédié à votre application avec des autorisations minimales, par exemple le rôle bigtable.reader.
  2. N'accordez les autorisations de ce rôle qu'à la vue. Vous pouvez utiliser une condition IAM pour limiter l'autorisation bigtable.logicalViews.readRows à votre vue spécifique.
  3. Pour un contrôle des accès plus strict, refusez explicitement au rôle d'application toute autorisation sur la table de base sous-jacente à l'aide d'une stratégie de refus IAM.

Pour en savoir plus, consultez la page Contrôle des accès Bigtable avec IAM.

Injecter un paramètre de vue

Dans les applications agentiques, les valeurs des paramètres de la vue logique paramétrée, telles que les identifiants utilisateur ou les limites de locataire, doivent être fournies par le code de votre application de confiance, et non par le LLM ou l'utilisateur final. Cela isole les entrées utilisateur non fiables et les chaînes de requête générées par le modèle des entrées de votre base de données.

Pour créer un agent IA, vous pouvez utiliser le framework Agent Development Kit (ADK). ADK fournit les composants suivants pour vous aider à intégrer des vues paramétrées :

  • BigtableToolset: ensemble d'outils de base de données ADK qui configure et fournit des outils orientés base de données (en particulier execute_sql_parameterized) qui communiquent avec Bigtable. Cet ensemble d'outils extrait automatiquement les paramètres de la vue hors bande et exécute la requête SQL sur vos données.
  • ToolContext: mécanisme d'exécution qui met en bac à sable l'état spécifique à la session et les propriétés d'infrastructure, ce qui permet aux outils de résoudre les paramètres de filtrage sensibles sans les exposer au LLM.

L'image suivante montre comment les composants fonctionnent ensemble pour injecter un paramètre dans Bigtable :

Processus d'injection d'un paramètre de vue dans Bigtable.
Figure 1. Processus d'intégration de vues paramétrées dans une application agentique (cliquez pour agrandir).

Les étapes suivantes expliquent plus en détail le processus d'injection de paramètres :

  1. Votre application authentifie l'utilisateur final et obtient ses identifiants utilisateur validés et son organisation locataire.
  2. L'application reçoit une requête en langage naturel de l'utilisateur.
  3. L'application exécute l'agent ADK, en transmettant les identifiants de l'utilisateur authentifié et du locataire dans l'état de session sécurisé.
  4. Lorsque l'agent décide d'interroger la base de données, il ne détermine que les arguments de filtrage en langage naturel, tels qu'une ville, et appelle l'outil execute_sql_parameterized.
  5. L'outil de base de données sous-jacent récupère de manière sécurisée les identifiants utilisateur sensibles et les limites de locataire à partir de ToolContext, puis exécute la requête sur Bigtable.

L'exemple suivant montre comment configurer une application agentique à l'aide d'ADK pour interroger l'historique des achats d'un utilisateur.

Configurer l'ensemble d'outils Bigtable

Dans votre application Python, configurez l'ADK BigtableToolset avec les noms de paramètres que vous souhaitez résoudre hors bande (view_parameter_names). Cela mappe directement les propriétés d'infrastructure du framework, telles que user_id, et les variables de session de l'application, telles que tenant_id, à votre requête de base de données.

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"],
)

Initialiser l'agent avec l'ensemble d'outils

Transmettez l'ensemble d'outils directement à la liste tools de l'agent. L'agent détectera et exposera automatiquement l'outil execute_sql_parameterized fortement typé.

# 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],
)

Remplacez MODEL_NAME par le nom du modèle que vous souhaitez utiliser, par exemple gemini-2.5-flash.

Exécuter l'application agentique

Lors de l'exécution de l'agent, initialisez la session active avec l'identité de l'utilisateur de l'infrastructure et l'état de l'organisation de votre application.

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())

Le résultat est une liste d'enregistrements de l'historique des achats de l'utilisateur authentifié, filtrée par la ville qu'il a spécifiée dans sa requête et limitée à sa limite de locataire.

Ce processus garantit que les paramètres de sécurité sont injectés hors bande et restent complètement masqués de la manipulation du modèle de langage.