Exemples d'utilisation de la structure Select AI Agent

Explorez des exemples qui montrent comment créer, configurer et interagir avec la structure d'agent Select AI pour des tâches courantes telles que l'analyse de films, l'analyse de journaux et le support client.

Exemple : création d'un agent

Créez un agent pour effectuer une tâche définie.

Avant de commencer

Révision :

Exemple : création d'un agent

Cet exemple crée un agent nommé Customer_Return_Agent chargé de gérer les conversations relatives aux retours de produits.

Cet exemple illustre l'utilisation de Google en tant que fournisseur d'IA tel que spécifié dans le profil AI nommé GOOGLE. Le profil AI identifie le LLM utilisé par l'agent pour le raisonnement et les réponses. L'attribut role fournit des instructions pour guider l'agent.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'CustomerAgent',
    attributes =>'{
       "profile_name": "GOOGLE",
                       "role": "You are an experienced customer agent who deals with customers return request."
     }'
  );
END;
/

Remarque

Remarque : chaque agent d'une équipe multi-agent peut avoir un profil d'IA distinct et chaque profil peut utiliser un fournisseur d'IA et/ou un LLM différent.

Exemple : Créer des outils intégrés

Créez des outils intégrés tels que SQL, RAG, Websearch, Email et Slack. Ces outils permettent aux agents et aux tâches d'interroger des données, d'extraire des connaissances, de rechercher sur le Web et d'envoyer des notifications.

Avant de commencer

Révision :

Sélectionner l'agent AI accepte les types d'outil suivants :

  • SQL

  • RAG

  • WEBSEARCH

  • NOTIFICATION

    • EMAIL

    • SLACK

Remarque

Remarque : Les outils intégrés (par exemple, SQL et RAG) incluent des instructions internes. Vous pouvez éventuellement ajouter des instructions fournies par l'utilisateur pour adapter le comportement à votre cas d'emploi. L'ajout d'une instruction peut ajouter un contexte spécifique à une tâche (par exemple, étendre les requêtes à un schéma spécifique ou aider à appliquer un format de réponse). Cela peut améliorer la pertinence des scénarios spécialisés. Des instructions mal écrites ou trop prescriptives peuvent dégrader les performances des outils. Gardez les instructions courtes, spécifiques et cohérentes avec l'objectif de l'outil.

Exemple : outil SQL

Cet exemple crée un outil SQL qui traduit les requêtes en langage naturel en instructions SQL. L'outil SQL aide les agents à répondre aux questions relatives aux données en mettant en correspondance des invites dans des requêtes SQL.

Cet exemple illustre l'utilisation d'OCI en tant que fournisseur d'IA tel qu'indiqué dans le profil d'IA nommé nl2sql_profile. Le profil AI identifie le LLM utilisé par l'agent pour le raisonnement et les réponses. Dans cet exemple, le profil AI nl2sql_profile définit l'ensemble des tables de schéma SH que l'agent peut interroger, ce qui permet un accès en langage naturel aux données d'historique des ventes couramment utilisées, telles que les clients, les produits, les promotions et les pays. L'outil SQL utilise les objets de base de données spécifiés dans le profil AI, ce qui garantit que les instructions SQL générées restent exactes et pertinentes pour l'ensemble de données SH.

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
      profile_name => 'nl2sql_profile',
      attributes   => '{"provider": "oci",
        "credential_name": "GEN1_CRED",
        "oci_compartment_id": "ocid
1.compartment.oc1..aaaa...",
	object_list": [{"owner": "SH", "name": "customers"},
                      {"owner": "SH", "name": "countries"},
                      {"owner": "SH", "name": "supplementary_demographics"},
                      {"owner": "SH", "name": "profits"},
                      {"owner": "SH", "name": "promotions"},
                      {"owner": "SH", "name": "products"}]

       }');
end;
/

EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('SQL');
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'SQL',
    attributes => '{"tool_type": "SQL",
                    "tool_params": {"profile_name": "nl2sql_profile"}}'
  );
END;
/

Exemple : outil RAG

Cet exemple crée un outil RAG (Extraction de la génération augmentée). L'outil RAG permet aux agents de récupérer et de mettre à la terre les réponses dans les documents d'entreprise, améliorant ainsi la précision des réponses basées sur la connaissance.

Cet exemple illustre la définition d'une valeur RAG_PROFILE avec des informations d'identification, un index vectoriel et la spécification de paramètres de profil. Ensuite, créez un index vectoriel RAG_INDEX dans Object Storage pour les incorporations de document et créez l'élément RAG_TOOL lié à votre profil.

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
          profile_name =>'RAG_PROFILE',
          attributes   =>'{"provider": "oci",
            "credential_name": "GENAI_CRED",
            "vector_index_name": "RAG_INDEX",
            "oci_compartment_id": "ocid1.compartment.oc1..aaaa..",
            "temperature": 0.2,
            "max_tokens": 3000
          }');
END;
/

BEGIN
   DBMS_CLOUD_AI.CREATE_VECTOR_INDEX(
           index_name  => 'RAG_INDEX',
           attributes  => '{"vector_db_provider": "oracle",
                            "location": "https://swiftobjectstorage.us-phoenix-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder",
                            "object_storage_credential_name": "OCI_CRED",
                            "profile_name": "RAG_PROFILE",
                            "chunk_overlap":128,
                            "chunk_size":1024
   }');
END;
/

EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('RAG_TOOL');
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'RAG_TOOL',
    attributes => '{"tool_type": "RAG",
                      "tool_params": {"profile_name": "RAG_PROFILE"}}'
  );
END;
/

Exemple : outil Websearch

Cet exemple crée un outil de recherche Web pour extraire des détails à partir d'Internet. L'outil de recherche Web permet aux agents de rechercher des informations sur le Web, telles que les prix ou les descriptions des produits.

Cet exemple illustre l'ajout d'une entrée d'ACL pour le fournisseur OpenAI. Création des informations d'identification OPENAI_CRED avec votre clé d'API et création de l'outil Websearch, description de son objectif, liaison aux informations d'identification.

Remarque

Remarque : OpenAI est le seul fournisseur d'IA Websearch pris en charge.

BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host => 'api.openai.com',
    ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                        principal_name => 'ADB_USER',
                        principal_type => xs_acl.ptype_db)
   );
END;
/

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'OPENAI_CRED',
    username        => 'OPENAI',
    password        => '<`OPENAI_API_KEY`>'
  );
END;
/

EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('Websearch');
BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => 'Websearch',
    attributes => '{"instruction": "This tool can be used for searching the details about topics mentioned in notes and prepare a summary about prices, details on web",
                      "tool_type": "WEBSEARCH",
                      "tool_params": {"credential_name": "OPENAI_CRED"}}'
  );
END;
/

Exemple : outil de notification avec type de courriel

Cet exemple crée un outil de notification par e-mail. L'outil E-mail permet aux agents d'envoyer des e-mails de notification dans le cadre de leur workflow.

Cet exemple illustre la création d'informations d'identification EMAIL_CRED avec votre mot de passe, l'autorisation de l'accès SMTP pour l'utilisateur de base de données et la création d'un outil de notification avec le type EMAIL, y compris les détails SMTP, l'expéditeur et les adresses de destinataire.

Remarque

Remarque : vous devez générer des informations d'identification SMTP dans Oracle Cloud Infrastructure avant de créer des informations d'identification dans la base de données Autonomous AI. Pour plus d'informations, reportez-vous à Génération d'informations d'identification SMTP pour un utilisateur.

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'EMAIL_CRED',
    username => '<SMTP username>',
    password => '<SMTP password>');
END;
/
-- Allow SMTP access for user
BEGIN
   DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
     host => 'smtp.email.us-ashburn-
1.oci.oraclecloud.com',
     lower_port => 587,
     upper_port => 587,
     ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
                        principal_name => 'ADB_USER',
                        principal_type => xs_acl.ptype_db));
END;
/

EXEC DBMS_CLOUD_AI_AGENT.DROP_TOOL('Email');
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'EMAIL',
    attributes => '{"tool_type": "NOTIFICATION",
                    "tool_params": {"notification_type" : "EMAIL",
                                    "credential_name": "EMAIL_CRED",
                                    "recipient": "example_recipient@oracle.com",
                                    "smtp_host": "smtp.email.us-ashburn-1.oci.oraclecloud.com",
                                    "sender": "example_sender@oracle.com"}}'
  );
END;
/

Exemple : outil de notification avec type Slack

Cet exemple crée un outil de notification Slack. L'outil Slack permet aux agents de transmettre des notifications directement à un canal d'espace de travail Slack.

Cet exemple illustre l'ajout d'une entrée d'ACL pour Slack et la création d'un outil de notification de type SLACK le liant à SLACK_CRED et au canal cible.

BEGIN
 DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE (
  host         => 'slack.com',
  lower_port   => 443,
  upper_port   => 443,
  ace          => xs$ace_type(
      privilege_list => xs$name_list('http'),
      principal_name => 'ADB_USER',
      principal_type => xs_acl.ptype_db));
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => 'slack',
    attributes => '{"tool_type": "SLACK",
                    "tool_params": {"credential_name": "SLACK_CRED",
                                    "channel": "<channel_number>"}}'
  );
END;
/

Exemple : Décrire et exécuter l'outil Select AI Agent Framework

Utiliser des API d'outil pour décrire un outil et l'exécuter par son nom. DESCRIBE_TOOL renvoie la description de l'outil, les attributs et le schéma d'argument. RUN_TOOL appelle l'outil avec une charge utile d'entrée JSON et renvoie le résultat de l'outil au format JSON.

Avant de commencer

Révision :

Cet exemple crée des exemples de données de journal, inscrit une fonction PL/SQL en tant qu'outil Select AI Agent Framework, explique comment inspecter le schéma d'outil avant de l'utiliser et appelle l'outil directement à partir de SQL ou PL/SQL à l'aide d'une entrée JSON. Les mêmes API peuvent être utilisées par les intégrations compatibles MCP pour exposer les fonctionnalités de repérage et d'appel d'outils.

Si aucun outil d'agent n'a été créé, les API de repérage et d'appel d'outil renvoient un résultat vide. Créez des outils à l'aide de DBMS_CLOUD_AI_AGENT.CREATE_TOOL afin de les rendre disponibles pour le repérage et l'appel.

DECLARE
  l_result CLOB;
BEGIN
  l_result := DBMS_CLOUD_AI_AGENT.DESCRIBE_TOOL(
    tool_name => 'FETCH_LOG_TOOL'
  );

  DBMS_OUTPUT.PUT_LINE(l_result);
END;
/

SELECT DBMS_CLOUD_AI_AGENT.RUN_TOOL(
  tool_name => 'FETCH_LOG_TOOL',
  input => '{"P_SINCE":"2026-01-01"}'
) AS tool_result
FROM dual;

L'exemple suivant montre comment créer un outil et utiliser DESCRIBE_TOOL et RUN_TOOL.

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE app_log_messages PURGE';
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -942 THEN
      RAISE;
    END IF;
END;
/

CREATE TABLE app_log_messages (
  log_timestamp DATE,
  severity VARCHAR2(10),
  message VARCHAR2(4000)
);

INSERT INTO app_log_messages VALUES (DATE '2026-01-01', 'INFO', 'Routine performance check completed.');
INSERT INTO app_log_messages VALUES (DATE '2026-01-03', 'WARN', 'Query response time exceeded the review threshold.');
COMMIT;

CREATE OR REPLACE FUNCTION fetch_logs (
  p_since IN DATE
) RETURN CLOB IS
  l_logs CLOB;
BEGIN
  DBMS_LOB.CREATETEMPORARY(l_logs, TRUE);

  FOR rec IN (
    SELECT TO_CHAR(log_timestamp, 'YYYY-MM-DD') || ' ' ||
           severity || ': ' || message AS line
    FROM app_log_messages
    WHERE log_timestamp >= p_since
    ORDER BY log_timestamp
  ) LOOP
    DBMS_LOB.WRITEAPPEND(l_logs, LENGTH(rec.line) + 1, rec.line || CHR(10));
  END LOOP;

  RETURN l_logs;
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name => 'FETCH_LOG_TOOL',
    attributes => '{"instruction":"Returns log messages on or after the requested date.","function":"FETCH_LOGS"}',
    description => 'Fetch application log messages by date.'
  );
END;
/

DECLARE
  l_result CLOB;
BEGIN
  l_result := DBMS_CLOUD_AI_AGENT.DESCRIBE_TOOL(
    tool_name => 'FETCH_LOG_TOOL'
  );

  DBMS_OUTPUT.PUT_LINE(l_result);
END;
/

SELECT DBMS_CLOUD_AI_AGENT.RUN_TOOL(
  tool_name => 'FETCH_LOG_TOOL',
  input => '{"P_SINCE":"2026-01-01"}'
) AS tool_result
FROM dual;

Exemple : création d'une tâche

Créez une tâche qu'un agent peut effectuer.

Avant de commencer

Révision :

Remarque

Remarque : seul un administrateur de base de données peut accorder des privilèges EXECUTE et une procédure d'ACL réseau.

Exemple : création d'une tâche d'e-mail

Cet exemple crée Generate_Email_Task qui demande au LLM de produire un courriel de confirmation standard à l'aide de données structurées.

L'exemple suivant illustre l'utilisation de l'attribut instruction et fournit des instructions sur ce que l'e-mail doit inclure.

BEGIN DBMS_CLOUD_AI_AGENT.DROP_TASK('Generate_Email_Task');
EXCEPTION WHEN OTHERS THEN NULL; END;
/
BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name => 'Generate_Email_Task',
    attributes => '{"instruction": "Use the customer information and product details to generate an email in a professional format. The email should:' \|\|
                    '
1. Include a greeting to the customer by name' \|\|
                    '2. Specify the item being returned, the order number, and the reason for the return' \|\|
                    '3. If it is a refund, state the refund will be issued to the credit card on record.' \|\|
                    '4. If it is a replacement, state that the replacement will be shipped in 3-5 business days."}'
    );
END;

Exemple : création d'une tâche de journal d'extraction

Cet exemple crée une valeur FETCH_LOGS_TASK qui extrait les journaux en fonction de la demande.

Cet exemple illustre la création d'une tâche qui utilise l'outil log_fetcher pour extraire les journaux. Cet outil personnalisé indique la procédure PL/SQL fetch_logs. L'instruction de tâche indique ce que la tâche doit accomplir. L'attribut enable_human_tool est défini sur True afin qu'une personne puisse intervenir pour guider ou approuver le flux de tâches si nécessaire. Pour obtenir un exemple complet, reportez-vous à Exemple : extraction et analyse des rapports de journal.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name  =>'FETCH_LOGS_TASK',
    attributes =>'{
       "instruction": "Fetch the log entries from the database based on user request: {query}",
       "tools": ["log_fetcher"],
       "enable_human_tool" : "true"
     }'
  );
END;
/

Exemple : création d'une tâche d'analyse de journal

Cet exemple crée une valeur ANALYZE_LOG_TASK qui analyse les journaux extraits.

L'exemple suivant illustre l'utilisation de FETCH_LOGS_TASK comme attribut input. La tâche nommée ANALYZE_LOG_TASK démarre après la collecte des journaux afin que la sortie FETCH_LOGS_TASK soit une entrée. L'instruction de tâche indique ce que la tâche doit accomplir. L'attribut enable_human_tool est défini sur false, ce qui indique l'absence de vérification humaine en boucle.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name  =>'ANALYZE_LOG_TASK',
      attributes =>'{"instruction": "Analyze the fetched log entries retrieved based on user request: {query} ' ||
                      'Generate a detailed report include issue analysis and possible solution.",
         "input" : "FETCH_LOGS_TASK",
         "enable_human_tool" : "false"
       }'
    );
END;
/

Exemple : création d'une équipe d'agents

Créez des équipes d'agents pour accomplir vos tâches.

Avant de commencer

Révision :

Exemple : création d'une équipe d'agents

Cet exemple crée l'équipe ReturnAgency et inclut un seul agent Customer_Return_Agent. La tâche Return_And_Price_Match est affectée à l'agent. Cette tâche gère les demandes de retour en demandant le motif et en mettant à jour le statut de la prescription dans votre base de données. La valeur process est définie sur sequential pour exécuter les tâches dans un ordre défini.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name  => 'ReturnAgency',
    attributes => '{"agents": [{"name":"Customer_Return_Agent","task" : "Return_And_Price_Match"}],
                    "process": "sequential"}');
END;
/

Pour obtenir un exemple complet, reportez-vous à Exemple : création d'un agent de retour de produit.

Exemple : Créer une équipe multi-agents

Cet exemple crée l'équipe Ops_Issues_Solution_Team et inclut deux agents pour gérer l'analyse des journaux et le dépannage : Data_Engineer et Ops_Manager. L'agent Data_Engineer exécute la tâche fetch_logs_task et l'agent Ops_Manager exécute la tâche analyze_log_task. La valeur process est définie sur sequential pour exécuter les tâches dans un ordre défini.

BEGIN
      DBMS_CLOUD_AI_AGENT.create_team(
        team_name  => 'Ops_Issues_Solution_Team',
        attributes => '{"agents": [{"name":"Data_Engineer","task" : "fetch_logs_task"},
                                   {"name":"Ops_Manager","task" : "analyze_log_task"}],
                "process": "sequential"
                }');
END;
/

Pour obtenir un exemple complet, reportez-vous à Exemple : extraction et analyse des rapports de journal.

Exemple : repérage d'une équipe d'agent et vérification de l'état de l'équipe

Utilisez les API de repérage d'équipe pour répertorier les équipes disponibles, décrire l'équipe sélectionnée et extraire le dernier état d'exécution d'une conversation d'équipe. Les descriptions d'équipe incluent les compétences que les équipes exposent. Ces compétences représentent les outils sous-jacents de la structure d'agent Select AI et ne sont pas des objets de base de données distincts.

Avant de commencer

Révision :

Cet exemple répertorie les équipes d'agent disponibles, décrit les fonctionnalités exposées par une équipe sélectionnée et extrait le dernier état d'exécution d'une conversation. Ces API peuvent également prendre en charge des intégrations compatibles avec Agent2Agent qui repèrent les équipes d'agents publiées et examinent les compétences qu'elles exposent.

Si aucune équipe d'agents n'a été créée, le repérage et l'exécution des API d'état de l'équipe d'agents renvoient un résultat vide. Créez des équipes d'agents à l'aide de DBMS_CLOUD_AI_AGENT.CREATE_TEAM pour permettre le repérage et l'exécution des équipes.

Pour la délégation d'agent2Agent, utilisez LIST_TEAMS pour renvoyer les équipes dont l'utilisateur appelant est propriétaire et qui contiennent exactement un agent. Avant de sélectionner une équipe, utilisez DESCRIBE_TEAM pour vérifier ses capacités.

Utilisez le même ID de conversation que celui transmis à RUN_TEAM lorsque vous avez besoin de l'état d'exécution pour une conversation spécifique. Pour l'intégration d'Agent2Agent, utilisez un identificateur de conversation pour l'exécution d'équipe et la recherche d'état suivante. L'application peut découvrir une équipe, inspecter ses compétences, déléguer le travail, puis interroger l'état d'exécution.

SELECT DBMS_CLOUD_AI_AGENT.LIST_TEAMS() AS teams
FROM dual;

SELECT DBMS_CLOUD_AI_AGENT.DESCRIBE_TEAM(
  team_name => 'CUSTOMER_AGENT_ONLY_TEAM'
) AS team_description
FROM dual;

SELECT DBMS_CLOUD_AI_AGENT.GET_TEAM_STATE(
  team_name => 'CUSTOMER_AGENT_ONLY_TEAM',
  params => '{"conversation_id":"<CONVERSATION_ID>"}'
) AS team_state
FROM dual;

Pour l'intégration d'Agent2Agent, utilisez un identificateur de conversation pour l'exécution d'équipe et la recherche d'état suivante. L'application peut découvrir une équipe, inspecter ses compétences, déléguer le travail, puis interroger l'état d'exécution.

DECLARE
  l_conversation_id VARCHAR2(36);
  l_response        CLOB;
  l_state           VARCHAR2(30);
BEGIN
  l_conversation_id := DBMS_CLOUD_AI.CREATE_CONVERSATION();

  l_response := DBMS_CLOUD_AI_AGENT.RUN_TEAM(
    team_name   => 'CUSTOMER_AGENT_ONLY_TEAM',
    user_prompt => 'I need help returning a damaged item.',
    params      => '{"conversation_id":"' || l_conversation_id || '"}'
  );

  l_state := DBMS_CLOUD_AI_AGENT.GET_TEAM_STATE(
    team_name => 'CUSTOMER_AGENT_ONLY_TEAM',
    params    => '{"conversation_id":"' || l_conversation_id || '"}'
  );

  DBMS_OUTPUT.PUT_LINE(l_response);
  DBMS_OUTPUT.PUT_LINE('Current state: ' || l_state);
END;
/

Le résultat d'état indique le dernier état d'exécution de la conversation, tel que RUNNING, WAITING_FOR_HUMAN, SUCCEEDED ou FAILED.

Exemple : création d'un agent qui appelle les outils directement

Les appels d'outil directs d'agent prennent en charge les sessions interactives ouvertes. Dans ce mode, l'entrée d'équipe contient le nom de l'agent et n'affecte pas de tâche d'agent à l'agent. L'application ou l'utilisateur contrôle la fin de la session en appelant SET_EXECUTION_STATE.

Avant de commencer

Révision :

Cet exemple crée un agent qui appelle les outils configurés directement sans utiliser l'exécution basée sur les tâches. Elle présente une session agent-direct dans laquelle l'application détermine le moment où l'interaction est terminée. Utilisez des workflows basés sur des tâches lorsque le workflow doit suivre des instructions de tâche et des critères de réalisation prédéfinis. Utilisez agent-direct run lorsque l'application doit garder la conversation ouverte et déterminer quand la session se termine.

Les API d'appel de l'outil Agent-Direct renvoient un résultat vide si aucun agent associé aux outils n'a été créé. Créez un agent et associez-lui un ou plusieurs outils avant d'appeler les appels de l'outil agent-direct.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'CUSTOMER_AGENT_ONLY',
    attributes => '{
      "profile_name": "<AI_PROFILE_NAME>",
      "role": "You help customers with return requests. Ask for the return reason, collect the order number, confirm the requested action, and call EMAIL_TOOL only after the customer confirms the action.",
      "enable_human_tool": "true",
      "short_term_memory_length": 4,
      "tools": ["EMAIL_TOOL"]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name => 'CUSTOMER_AGENT_ONLY_TEAM',
    attributes => '{"agents":[{"name":"CUSTOMER_AGENT_ONLY"}],
      "process":"sequential"}'
  );
END;
/

DECLARE
  l_response CLOB;
  l_conversation_id VARCHAR2(128);
BEGIN
  l_conversation_id := DBMS_CLOUD_AI.CREATE_CONVERSATION();

  l_response := DBMS_CLOUD_AI_AGENT.RUN_TEAM(
    team_name => 'CUSTOMER_AGENT_ONLY_TEAM',
    user_prompt => 'I need help returning order 7820.',
    params => '{"conversation_id":"' || l_conversation_id || '"}'
  );

  DBMS_OUTPUT.PUT_LINE(l_response);
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.SET_EXECUTION_STATE(
    team_name => 'CUSTOMER_AGENT_ONLY_TEAM',
    state => 'SUCCEEDED',
    params => '{"conversation_id":"<CONVERSATION_ID>"}'
  );
END;
/

Exemple : configuration de la longueur de mémoire à court et à long terme

La longueur de la mémoire contrôle la quantité de contexte antérieur disponible lorsqu'un agent appelle le LLM. short_term_memory_length contrôle les rotations de conversation récentes incluses dans chaque appel de LLM pour l'exécution en cours. long_term_memory_length contrôle les récapitulatifs de niveau tâche précédents inclus lorsqu'une nouvelle exécution démarre.

Type de mémoire Attribut Portée Valeur par défaut
Mémoire à court terme short_term_memory_length Configuré sur un agent. 30
Mémoire à long terme long_term_memory_length Configuré dans une équipe. 30

La mémoire de conversation utilise une profondeur de mémoire par défaut de 30 tours de conversation. Utilisez la valeur par défaut pour la plupart des charges globales. Augmentez la profondeur de la mémoire lorsque l'agent a besoin d'un contexte conversationnel supplémentaire pour les interactions plus longues, ou réduisez-le pour réduire le traitement du contexte pour des conversations plus courtes et orientées tâche.

Avant de commencer

Révision :

Cet exemple configure la mémoire à court terme pour un agent et la mémoire à long terme pour une équipe, montrant comment contrôler la quantité de contexte conversationnel disponible pour le LLM pour différentes exigences de charge globale.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'MEMORY_AWARE_RETURN_AGENT',
    attributes => '{
      "profile_name": "<AI_PROFILE_NAME>",
      "short_term_memory_length": 5,
      "role": "You help customers with product return requests and keep the current conversation context concise."
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name => 'MEMORY_AWARE_RETURN_TEAM',
    attributes => '{"agents":[{"name":"MEMORY_AWARE_RETURN_AGENT","task":"RETURN_REQUEST_TASK"}],
      "long_term_memory_length": 5,
      "process":"sequential"}'
  );
END;
/

Exemple : création d'un agent d'analyse de films à l'aide d'outils intégrés

Cet exemple montre comment créer un agent d'analyse de film à l'aide de la structure d'agent Select AI. Dans cet exemple, vous configurez un agent d'analyse de film qui extrait les données, répond aux questions, effectue des recherches sur le Web et envoie par e-mail l'analyse ou envoie des notifications Slack.

Avant de commencer

Révision :

L'exemple suivant suppose que les données sont à votre disposition.

Cet exemple crée un agent MOVIE_ANALYST et utilise plusieurs outils intégrés tels que les outils SQL, RAG, WEBSEARCH et NOTIFICATION de type EMAIL et SLACK. L'agent répond aux questions liées aux films à l'aide d'invites en langage naturel.

Dans cet exemple, une fois que l'administrateur de base de données a accordé des privilèges EXECUTE pour : les packages DBMS_CLOUD_AI_AGENT, DBMS_CLOUD_AI, DBMS_CLOUD_PIPELINE, l'accès ACL pour votre fournisseur AI, l'accès SMTP et l'accès Slack, vous commencez par créer l'agent MOVIE_ANALYST.

Créer un agent

Vous créez un agent nommé MOVIE_ANALYST avec un profil (GROK) et le rôle de répondre à des questions sur les films, les acteurs et les genres.

Créer la tâche

Vous créez une tâche nommée ANALYZE_MOVIE_TASK avec des instructions pour répondre aux requêtes liées aux films.

Créer une équipe

Vous créez une équipe MOVIE_AGENT_TEAM avec MOVIE_ANALYST en tant qu'agent et la tâche en tant que ANALYZE_MOVIE_TASK et définissez-la en tant qu'équipe active.

Vous pouvez ensuite associer des outils tels que SQL, RAG, Websearch ou Notification pour étendre ses fonctionnalités.

Exécuter l'équipe Select AI Agent

Vous exécutez désormais l'équipe d'agent en utilisant select ai agent comme préfixe pour vos invites.

Créer des outils

Vous associez ensuite différents outils d'agent intégrés :

  • SQL : utilise un profil NL2SQL pour traduire les questions en requêtes SQL et autres actions Select AI prises en charge.

  • RAG : extraire le contexte basé sur les connaissances des documents stockés.

  • WEBSEARCH : Rassemblez les détails du film ou les prix en ligne.

  • NOTIFICATION:

    • EMAIL : envoie des réponses à des invites utilisateur, des rapports de film ou des critiques à un destinataire.

    • SLACK : envoie les réponses aux invites utilisateur, aux récapitulatifs ou aux mises à jour directement dans Slack.

L'exemple complet est le suivant :

--Grants EXECUTE privilege to ADB_USER
--
GRANT EXECUTE on DBMS_CLOUD_AI_AGENT to ADB_USER;
GRANT EXECUTE on DBMS_CLOUD_AI to ADB_USER;
GRANT EXECUTE on DBMS_CLOUD_PIPELINE to ADB_USER;

-- Websearch tool accesses OPENAI endpoint, allow ACL access
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host => 'api.openai.com',
    ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                        principal_name => 'ADB_USER',
                        principal_type => xs_acl.ptype_db)
   );
END;
/

-- To allow Email tool in Autonomous AI Database, allow SMTP access

BEGIN
   DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
     host => 'smtp.email.us-ashburn-1.oci.oraclecloud.com',
     lower_port => 587,
     upper_port => 587,
     ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
                        principal_name => 'ADB_USER,
                        principal_type => xs_acl.ptype_db));
END;
/

-- Allow ACL access to Slack

BEGIN
 DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE (
  host         => 'slack.com',
  lower_port   => 443,
  upper_port   => 443,
  ace          => xs$ace_type(
      privilege_list => xs$name_list('http'),
      principal_name => 'ADB_USER',
      principal_type => xs_acl.ptype_db));
END;
/

PL/SQL procedure successfully completed.

--Create an agent
BEGIN
   DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
     agent_name => 'MOVIE_ANALYST',
     attributes => '{"profile_name": "GROK",
                     "role": "You are an AI Movie Analyst. Your can help answer a variety of questions related to movies. "
             }'
   );
END;
/

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name  => 'ANALYZE_MOVIE_TASK',
      attributes => '{"instruction": "Help the user with their request about movies. User question: {query}",
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name  => 'MOVIE_AGENT_TEAM',
    attributes => '{"agents": [{"name":"MOVIE_ANALYST","task" : "ANALYZE_MOVIE_TASK"}],
                    "process": "sequential"
                    }');
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('MOVIE_AGENT_TEAM');

PL/SQL procedure successfully completed.

select ai agent who are you?;

RESPONSE
--------------------------------------------------------------------------------
I'm MOVIE_ANALYST, an AI Movie Analyst here to assist with any questions or topi
cs related to movies. Whether you need information on films, actors, directors,
genres, or recommendations, I'm ready to help. What can I assist you with regard
ing movies?

-- SQL TOOL
BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    profile_name =>'nl2sql_profile',
    attributes => '{"provider": "oci",
      "credential_name": "GENAI_CRED",
      "oci_compartment_id" : "ocid1.compartment.oc1..aaaaa...",
      "object_list": [{"owner": "ADB_USER", "name": "GENRE"},
                      {"owner": "ADB_USER", "name": "CUSTOMER"},
                      {"owner": "ADB_USER", "name": "WATCH_HISTORY"},
                      {"owner": "ADB_USER", "name": "STREAMS"},
                      {"owner": "ADB_USER", "name": "MOVIES"},
                      {"owner": "ADB_USER", "name": "ACTORS"}]
      }');
END;
/

PL/SQL procedure successfully completed.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'SQL',
    attributes => '{"tool_type": "SQL",
                    "tool_params": {"profile_name": "nl2sql_profile"}}'
  );
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.drop_task('ANALYZE_MOVIE_TASK');

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name => 'ANALYZE_MOVIE_TASK',
      attributes =>'{"instruction": "Help the user with their request about movies. User question: {query}. ' ||
                       'You can use SQL tool to search the data from database",
        "tools": ["SQL"],
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.CLEAR_TEAM;

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('MOVIE_AGENT_TEAM');

PL/SQL procedure successfully completed.

-- SQL tool retrieves the movie with the highest popularity view count from the watch_history table
select ai agent what is the most popular movie?;

RESPONSE
----------------------------------------------------------------
The most popular movie is "Laugh Out Loud" released in 2008.

-- RAG TOOL
BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
         profile_name => 'RAG_PROFILE',
         attributes =>'{"provider": "oci",
            "credential_name": "GENAI_CRED",
            "vector_index_name": "RAG_INDEX",
            "oci_compartment_id": "ocid1.compartment.oc1..aaaaa...",
            "temperature": 0.2,
            "max_tokens": 3000
          }');
END;
/

PL/SQL procedure successfully completed.

BEGIN
   DBMS_CLOUD_AI.CREATE_VECTOR_INDEX(
           index_name  => 'RAG_INDEX',
           attributes  => '{"vector_db_provider": "oracle",
                            "location": "https://swiftobjectstorage.us-phoenix-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder",
                            "object_storage_credential_name": "MY_OCI_CRED",
                            "profile_name": "RAG_PROFILE",
                            "vector_dimension": 1024,
                            "vector_distance_metric": "cosine",
                            "chunk_overlap":128,
                            "chunk_size":1024
   }');
END;
/
PL/SQL procedure successfully completed.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'RAG_TOOL',
    attributes => '{"tool_type": "RAG",
                      "tool_params": {"profile_name": "RAG_PROFILE"}}'
  );
END;
/

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name =>'ANALYZE_MOVIE_TASK',
      attributes => '{"instruction": "Help the user with their request about movies. User question: {query}. ' ||
                       'You can use RAG tool to search the information from the knowledge base user give.",
        "tools": ["RAG_TOOL"],
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.CLEAR_TEAM;

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('MOVIE_AGENT_TEAM');

PL/SQL procedure successfully completed.

-- Rag seach the object store to find review or comments of Movie Laugh out Loud
select ai agent Please find the comments of Movie Laugh out Loud;

RESPONSE
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The comments for the movie "Laugh Out Loud" (2008) are as follows:
1. A lighthearted comedy that delivers plenty of laughs, though the plot is fairly predictable.
2. The performances are fun, especially from the lead actor who keeps the energy high.
3. Some jokes feel a bit outdated, but overall it is an enjoyable watch for a casual movie night.
4. Good chemistry between the cast members, which makes the humor more natural.
5. Not a groundbreaking comedy, but it does what it promises makes you laugh out loud.

-- WEBSEARCH TOOL
BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'OPENAI_CRED',
    username        => 'OPENAI',
    password        => '<API_KEY>'
  );
END;
/

PL/SQL procedure successfully completed.

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'WEBSEARCH_TOOL',
    attributes => '{"instruction": "This tool can be used for searching the details about topics mentioned in notes and prepare a summary about prices, details on web",
                      "tool_type": "WEBSEARCH",
                      "tool_params": {"credential_name": "OPENAI_CRED"}}'
  );
END;
/

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name => 'ANALYZE_MOVIE_TASK',
      attributes => '{"instruction": "Help the user with their request about movies. User question: {query}. ' ||
                       'You can use WEBSEARCH_TOOL tool to search the information from internet.",
        "tools": ["WEBSEARCH_TOOL"],
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.CLEAR_TEAM;

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('MOVIE_AGENT_TEAM');

PL/SQL procedure successfully completed.

select ai agent What is the most popular movie of 2023?;

RESPONSE
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Determining the most popular movie of 2023 can depend on various metrics such as box office earnings, streaming viewership, critical acclaim, or audience reception. Based on global box office data, which is often a strong indicator of popularity, the most successful movie of 2023 is "Barbie," directed by Greta Gerwig. Released in July 2023, it grossed over $1.4 billion worldwide, making it the highest-grossing film of the year and one of the biggest cultural phenomena, often discussed alongside "Oppenheimer" due to the "Barbenheimer" trend. Its widespread appeal, marketing, and social media buzz further solidify its status as the most popular movie of 2023. However, if you are looking for popularity based on a different metric (like streaming numbers or awards), please let me know, and I can adjust the analysis accordingly.

-- NOTIFICATION TOOL WITH EMAIL TYPE

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'EMAIL',
    attributes => q'[{"tool_type": "Notification",
                      "tool_params": {"notification_type" : "EMAIL",
                                      "credential_name": "EMAIL_CRED",
                                      "recipient": "example@oracle.com",
                                      "smtp_host": "smtp.email.us-ashburn-1.oci.oraclecloud.com",
                                      "sender": "example@oracle.com"}}]'
  );
END;
/

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name => 'ANALYZE_MOVIE_TASK',
      attributes =>'{"instruction": "Help the user with their request about movies. User question: {query}. ' ||
                       'You can use EMAIL TOOL tool to send email to the user.",
        "tools": ["EMAIL"],
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.CLEAR_TEAM;

PL/SQL procedure successfully completed.

EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('MOVIE_AGENT_TEAM');

PL/SQL procedure successfully completed.

select ai agent Please help me write a review of Movie "Barbie" and send the review to my email;

RESPONSE
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
I have written a review for the movie "Barbie" (2023) and sent it to your email. Please check your inbox for the detailed review. If you have any additional feedback or would like me to revise the review, let me know!

-- NOTIFICATION TOOL WITH SLACK TYPE

DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'SLACK_TOOL',
    attributes => '{"tool_type": "SLACK",
                    "tool_params": {"credential_name": "SLACK_CRED",
                                    "channel": "<channel_number>"}}'
  );
END;
/

PL/SQL procedure successfully completed.

BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TASK(
      task_name  => 'ANALYZE_MOVIE_TASK',
      attributes => '{"instruction": "Help the user with their request about movies. User question: {query}. ' ||
                       'You can use SLACK TOOL to send the notification to the user.",
        "tools": ["SLACK_TOOL"],
         "enable_human_tool" : "true"
       }'
    );
END;
/

PL/SQL procedure successfully completed.

select ai agent Please help me find the top 3 most-watched movies of 2023 and send them to me on slack;

RESPONSE
------------------------------------------------------------------------------------------------------------------------------------
I have sent the list of the top 3 most-watched movies of 2023 to you via Slack. Please check your Slack notifications for the details.

Exemple : création d'un agent de retour de produit

Cet exemple montre comment créer un agent conversationnel à plusieurs tours à l'aide de la structure d'agent Select AI. Dans cet exemple, vous configurez un agent de service client qui gère les retours de produits et met à jour le statut des retours dans votre base de données.

Avant de commencer

Révision :

Cet exemple crée un agent nommé Customer_Return_Agent et un outil nommé Update_Order_Status_Tool, puis définit une tâche et une équipe pour gérer le retour de produit.

Dans cet exemple, une fois que l'administrateur de base de données a accordé des privilèges EXECUTE pour : DBMS_CLOUD_AI_AGENT et DBMS_CLOUD_AI, vous commencez par créer un exemple de données sur les clients, le statut de la commande client et une fonction permettant de mettre à jour le statut de la commande client. Ensuite, créez un agent nommé Customer_Return_Agent.

Créer un agent

Vous créez un agent nommé Customer_Return_Agent avec un profil (OCI_GENAI_GROK) et un rôle pour gérer les demandes de retour.

Créer des outils

Vous créez ensuite un outil d'agent nommé Update_Order_Status_Tool pour mettre à jour le statut de la commande dans la base de données.

Créer la tâche

Vous créez une tâche appelée Handle_Product_Return_Task pour guider le flux : demandez la raison (n'est plus nécessaire, est arrivé trop tard, la boîte est cassée ou est défectueuse). Procédez à un flux de retour défectueux.

Créer une équipe

Créez une équipe d'agents nommée Return_Agency_Team avec Customer_Return_Agent en tant qu'agent et définissez-la en tant qu'équipe active.

Exécuter l'équipe de l'agent

Vous exécutez désormais l'équipe d'agent en utilisant select ai agent comme préfixe pour vos invites.

L'exemple complet est le suivant :

--Grants EXECUTE privilege to ADB_USER
--
GRANT EXECUTE on DBMS_CLOUD_AI_AGENT to ADB_USER;
GRANT EXECUTE on DBMS_CLOUD_AI to ADB_USER;

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name => 'Customer_Return_Agent',
    attributes => '{"profile_name": "OCI_GENAI_GROK",
                    "role": "You are an experienced customer return agent who deals with customers return requests."}');
END;
/

PL/SQL procedure successfully completed.



--Sample customer data
CREATE TABLE CUSTOMERS (
    customer_id  NUMBER(10) PRIMARY KEY,
    name         VARCHAR2(100),
    email        VARCHAR2(100),
    phone        VARCHAR2(20),
    state        VARCHAR2(2),
    zip          VARCHAR2(10)
);

INSERT INTO CUSTOMERS (customer_id, name, email, phone, state, zip) VALUES
(1, 'Alice Thompson', 'alice.thompson@example.com', '555-1234', 'NY', '10001'),
(2, 'Bob Martinez', 'bob.martinez@example.com', '555-2345', 'CA', '94105'),
(3, 'Carol Chen', 'carol.chen@example.com', '555-3456', 'TX', '73301'),
(4, 'David Johnson', 'david.johnson@example.com', '555-4567', 'IL', '60601'),
(5, 'Eva Green', 'eva.green@example.com', '555-5678', 'FL', '33101');

--create customer order status
CREATE TABLE CUSTOMER_ORDER_STATUS (
    customer_id     NUMBER(10),
    order_number    VARCHAR2(20),
    status          VARCHAR2(30),
    product_name    VARCHAR2(100)

);

INSERT INTO CUSTOMER_ORDER_STATUS (customer_id, order_number, status, product_name) VALUES
(2, '7734', 'delivered', 'smartphone charging cord'),
(1, '4381', 'pending_delivery', 'smartphone protective case'),
(2, '7820', 'delivered', 'smartphone charging cord'),
(3, '1293', 'pending_return', 'smartphone stand (metal)'),
(4, '9842', 'returned', 'smartphone backup storage'),
(5, '5019', 'delivered', 'smartphone protective case'),
(2, '6674', 'pending_delivery', 'smartphone charging cord'),
(1, '3087', 'returned', 'smartphone stand (metal)'),
(3, '7635', 'pending_return', 'smartphone backup storage'),
(4, '3928', 'delivered', 'smartphone protective case'),
(5, '8421', 'pending_delivery', 'smartphone charging cord'),
(1, '2204', 'returned', 'smartphone stand (metal)'),
(2, '7031', 'pending_delivery', 'smartphone backup storage'),
(3, '1649', 'delivered', 'smartphone protective case'),
(4, '9732', 'pending_return', 'smartphone charging cord'),
(5, '4550', 'delivered', 'smartphone stand (metal)'),
(1, '6468', 'pending_delivery', 'smartphone backup storage'),
(2, '3910', 'returned', 'smartphone protective case'),
(3, '2187', 'delivered', 'smartphone charging cord'),
(4, '8023', 'pending_return', 'smartphone stand (metal)'),
(5, '5176', 'delivered', 'smartphone backup storage');

--Create a update customer order status function
CREATE OR REPLACE FUNCTION UPDATE_CUSTOMER_ORDER_STATUS (
    p_customer_name IN VARCHAR2,
    p_order_number  IN VARCHAR2,
    p_status        IN VARCHAR2
) RETURN CLOB IS
    v_customer_id  customers.customer_id%TYPE;
    v_row_count    NUMBER;
BEGIN
    -- Find customer_id from customer_name
    SELECT customer_id
    INTO v_customer_id
    FROM customers
    WHERE name = p_customer_name;

    UPDATE customer_order_status
    SET status = p_status
    WHERE customer_id = v_customer_id
      AND order_number = p_order_number;

    v_row_count := SQL%ROWCOUNT;

    IF v_row_count = 0 THEN
        RETURN 'No matching record found to update.';
    ELSE
        RETURN 'Update successful.';
    END IF;
EXCEPTION
    WHEN OTHERS THEN
        RETURN 'Error: ' || SQLERRM;
END;

--Create Tool
BEGIN
    DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
        tool_name => 'Update_Order_Status_Tool',
        attributes => '{"instruction": "This tool updates the database to reflect return status change. Always confirm user name and order number with user before update status",
                        "function" : "update_customer_order_status"}',
        description => 'Tool for updating customer order status in database table.'
    );
END;
/
--Create Task
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name => 'Handle_Product_Return_Task',
    attributes => '{"instruction": "Process a product return request from a customer:{query}' ||
                    '1. Ask customer the order reason for return (no longer needed, arrived too late, box broken, or defective)' ||
                    '2. If no longer needed:' ||
                    '   a. Inform customer to ship the product at their expense back to us.' ||
                    '   b. Update the order status to return_shipment_pending using Update_Order_Status_Tool.' ||
                     '3. If it arrived too late:' ||
                    '   a. Ask customer if they want a refund.' ||
                    '   b. If the customer wants a refund, then confirm refund processed and update the order status to refund_completed' ||
                    '4. If the product was defective or the box broken:' ||
                    '   a. Ask customer if they want a replacement or a refund' ||
                    '   b. If a replacement, inform customer replacement is on its way and they will receive a return shipping label for the defective product, then update the order status to replaced' ||
                    '   c. If a refund, inform customer to print out the return shipping label for the defective product, return the product, and update the order status to refund' ||
                    '5. After the completion of a return or refund, ask if you can help with anything else.' ||
                    '   End the task if user does not need help on anything else",
                    "tools": ["Update_Order_Status_Tool"]}'
  );
END;
/
SQL> BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name  => 'Return_Agency_Team',
    attributes => '{"agents": [{"name":"Customer_Return_Agent","task" : "Handle_Product_Return_Task"}],
                    "process": "sequential"}');
END;
/

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('Return_Agency_Team');

PL/SQL procedure successfully completed.

--Validate that the agent team is set in the current session with get_team
SQL> SELECT DBMS_CLOUD_AI_AGENT.GET_TEAM from DUAL;

--Interact with the agent
SQL> select ai agent I want to return a smartphone case;

RESPONSE
Could you please tell me the reason for returning the smartphone case? Is it no longer needed, arrived too late, box broken, or defective?

SQL> select ai agent the item is defective

RESPONSE
I'm sorry to hear that the smartphone case is defective. Would you like a replacement or a refund?

SQL> select ai agent I will need a replacement

RESPONSE
Can you please confirm your name and order number so I can update the status and process the replacement?

SQL> select ai agent I''m Bob Martinez and my order number is 7820

RESPONSE
Is there anything else I can help you with?

SQL> select ai agent No, I''m all set. Thanks

RESPONSE
Thank you for reaching out, Bob. I'm glad I could assist with the return of your smartphone case and stand. If you have any further questions or need assistance in the future, feel free to contact us. Have a great day!

Exemple : utilisation de la structure Select AI Agent avec Database Actions et APEX

Si vous utilisez des clients SQL Web tels que Database Actions, exécutez l'équipe d'agents à l'aide de la fonction DBMS_CLOUD_AI_AGENT.RUN_TEAM et fournissez votre invite dans la fonction.

Remarque

Remarque : n'utilisez pas DBMS_CLOUD_AI_AGENT.SET_TEAM dans Database Actions ou le service APEX. Indiquez plutôt l'équipe de l'agent à l'aide de l'argument team_name de DBMS_CLOUD_AI_AGENT.RUN_TEAM.

L'exemple suivant crée un ID de conversation pour suivre l'historique des conversations client, puis utilise la fonction DBMS_CLOUD_AI_AGENT.RUN_TEAM pour interagir avec l'agent de retour de produit.

Pour plus d'informations, reportez-vous à Fonction RUN_TEAM.

CREATE OR REPLACE PACKAGE my_globals IS
  l_team_cov_id varchar2(4000);
END my_globals;
/
-- Create conversation
DECLARE
  l_team_cov_id varchar2(4000);
BEGIN
  l_team_cov_id := DBMS_CLOUD_AI.create_conversation();
  my_globals.l_team_cov_id := l_team_cov_id;
  DBMS_OUTPUT.PUT_LINE('Created conversation with ID: ' || my_globals.l_team_cov_id);
END;

--Interact with the agent
DECLARE
  v_response VARCHAR2(4000);
BEGIN
  v_response :=  DBMS_CLOUD_AI_AGENT.RUN_TEAM(
    team_name   => 'Return_Agency_Team',
    user_prompt => 'I want to return a smartphone case',
    params      => '{"conversation_id": "' \|\| my_globals.l_team_cov_id \|\| '"}'
  );
  DBMS_OUTPUT.PUT_LINE(v_response);
END;

Exemple : extraction et analyse des rapports de journal

Cet exemple montre comment créer une équipe d'agents à l'aide de deux paires agent-tâche pour extraire les journaux et les analyser.

Avant de commencer

Révision :

Cet exemple crée :

  • workflows à deux agents pour le dépannage : Data_Engineer et Ops_Manager

  • un outil : log-fetcher, puis définit les tâches et l'équipe pour extraire les journaux et les analyser.

Remarque

Remarque : seul un administrateur de base de données peut exécuter les privilèges EXECUTE et la procédure d'ACL réseau.

Dans cet exemple, une fois que l'administrateur de base de données a accordé des privilèges EXECUTE pour : le package DBMS_CLOUD_AI_AGENT, le package DBMS_CLOUD_AI et l'accès ACL pour vos fournisseurs AI, vous commencez par créer les agents Data_Engineer et Ops_Manager.

Créer un agent

Vous créez l'agent nommé Data_Engineer avec un profil (GOOGLE) qui utilise Google comme fournisseur et rôle d'IA pour extraire et traiter des données complexes.

Créez l'agent nommé Ops_Manager avec un profil (OPENAI) qui utilise OpenAI comme fournisseur et rôle d'IA pour analyser les données.

Outil de création

Vous créez ensuite un outil d'agent :log_fetcher : renvoie les entrées de journal après une date donnée. Cette opération utilise une procédure personnalisée fetch_logs.

Création de tâches

Vous définissez deux tâches fetch_logs_task et analyze_log_task pour guider le flux. fetch_logs_task appelle log_fetcher pour extraire les journaux en fonction de la demande. analyze_log_task analyse les journaux extraits.

Créer une équipe

Vous créez l'équipe Ops_Issues_Solution_Team avec Data_Engineer et Ops_Manager pour une exécution séquentielle.

exécuter l'agent,

Vous allez maintenant définir l'équipe active et exécuter l'équipe d'agent avec select ai agent comme préfixe pour vos invites.

L'exemple complet est le suivant :

--Grants EXECUTE privilege to ADB_USER
--
GRANT EXECUTE on DBMS_CLOUD_AI_AGENT to ADB_USER;
GRANT EXECUTE on DBMS_CLOUD_AI to ADB_USER;

-- Grant Network ACL for OpenAI endpoint
BEGIN
     DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
         host => 'api.openai.com',
         ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                             principal_name => 'ADB_USER',
                             principal_type => xs_acl.ptype_db)
     );
END;
/
--Grant Network ACL for Google endpoint
BEGIN
      DBMS_NETWORK_ACL_ADB_USER.APPEND_HOST_ACE(
        host => 'generativelanguage.googleapis.com',
        ace  => xs$ace_type(privilege_list => xs$name_list('http'),
                    principal_name => 'ADB_USER',
                    principal_type => xs_acl.ptype_db)
       );
END;
/
PL/SQL procedure successfully completed.

--Create a table with Database logs and insert sample data

SQL> CREATE TABLE app_logs (
  log_id         NUMBER GENERATED BY DEFAULT AS IDENTITY,
  log_timestamp  DATE,
  log_message    VARCHAR2(4000)
);

Table created.

SQL> INSERT INTO app_logs (log_timestamp, log_message) VALUES (
  TO_DATE('2025-03-22 03:15:45', 'YYYY-MM-DD HH24:MI:SS'),
  'INFO: Database Cluster: Failover completed successfully. Standby promoted to primary. Downtime duration: 33 seconds. Correlation ID: dbfailover102.'
);

1 row created.

SQL> INSERT INTO app_logs (log_timestamp, log_message) VALUES (
  TO_DATE('2025-03-23 08:44:10', 'YYYY-MM-DD HH24:MI:SS'),
  'INFO: Switchover Process: Synchronization restored. Performing scheduled switchover. Correlation ID: dbswitchover215.'
);

1 row created.

SQL> INSERT INTO app_logs (log_timestamp, log_message) VALUES (
  TO_DATE('2025-03-24 03:15:12', 'YYYY-MM-DD HH24:MI:SS'),
  'ERROR: Database Cluster: Primary database unreachable, initiating failover to standby. Correlation ID: dbfailover102.'
);

1 row created.

SQL> COMMIT;

Commit complete.

-- create data engineer agent
SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
        agent_name => 'Data_Engineer',
        attributes => '{"profile_name": "GOOGLE",
                        "role": "You are a specialized data ingestion engineer with expertise in   ' \|\|
                         'retrieving and processing data from complex database systems."
               }'
      );
    END;
    /
PL/SQL procedure successfully completed.

-- create ops manager agent
SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
        agent_name => 'Ops_Manager',
        attributes => '{"profile_name": "OPENAI",
                        "role": "You are an experienced Ops manager who excels at analyzing ' \|\|
                'complex log data, diagnosing the issues."
         }'
      );
    END;
    /


PL/SQL procedure successfully completed.

-- create log_fetcher tool
-- fetch_logs is a customized procedure.
-- Please make sure you have created your own procedure before use it in the tool

--Create a customized fetch_logs procedure
SQL> CREATE OR REPLACE FUNCTION fetch_logs(since_date IN DATE) RETURN CLOB IS
  l_logs CLOB;
BEGIN
  SELECT JSON_ARRAYAGG(log_message RETURNING CLOB)
    INTO l_logs
    FROM app_logs
   WHERE log_timestamp >= since_date
   ORDER BY log_timestamp;

  RETURN l_logs;
EXCEPTION
  WHEN OTHERS THEN
    RETURN 'Error fetching logs: ' || SQLERRM;
END fetch_logs;
/

Function created.

SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
        tool_name => 'log_fetcher',
        attributes => '{"instruction": "retrieves and returns all log messages with a LOG_TIMESTAMP greater than or equal to the input date.",
                        "function": "fetch_logs"}'
      );
    END;
    /

PL/SQL procedure successfully completed.

-- create task with log fetcher tool

SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.CREATE_TASK(
        task_name  => 'fetch_logs_task',
        attributes => '{"instruction": "Fetch the log entries from the database based on user request: {query}}.",
                        "tools": ["log_fetcher"]}'
      );
    END;
    /

PL/SQL procedure successfully completed.

-- create task with predefined rag and slack tool

SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.create_task(
        task_name => 'analyze_log_task',
        attributes => '{"instruction": "Analyze the fetched log entries retrieved based on user request: {query} ' ||
                      'Generate a detailed report include issue analysis and possible solution.",
           "input" : "fetch_logs_task"
        }'
     );
    END;
    /

PL/SQL procedure successfully completed.

-- create team and set agent team
SQL> BEGIN
      DBMS_CLOUD_AI_AGENT.create_team(
        team_name  => 'Ops_Issues_Solution_Team',
        attributes => '{"agents": [{"name":"Data_Engineer","task" : "fetch_logs_task"},
                                    {"name":"Ops_Manager","task" : "analyze_log_task"}],
                "process": "sequential"
                }');
    END;
    /

PL/SQL procedure successfully completed.

SQL> EXEC DBMS_CLOUD_AI_AGENT.SET_TEAM('Ops_Issues_Solution_Team');


PL/SQL procedure successfully completed.


SQL> select ai agent fetch and analyze the logs after 03/15 2025;

RESPONSE
-----------------------------------------------------------------------------------------------------------------------------------------------
1. Issue: High volume of 500 Internal Server Errors between 03/22 and 03/24.
   Solution: Review server application logs to identify failing components; add better exception handling and fallback mechanisms to prevent service crashes.

2. Issue: Increased response time on /api/v1/user and /checkout, peaking on 03/25.
   Solution: Profile back-end queries and services, apply caching where applicable, and offload static content to a CDN.

3. Issue: Detected brute-force login attack with over 500 failed POST attempts from a single IP.
   Solution: Add rate-limiting, temporary IP bans, and CAPTCHA on the /login endpoint to prevent credential stuffing.

4. Issue: Suspicious User-Agent headers such as curl/7.58.0 or empty headers mimicking mobile devices.
   Solution: Block malformed or uncommon User-Agent strings and log them for threat intelligence analysis.

5. Issue: DDoS-like traffic spike from distributed IPs observed on 03/20.
   Solution: Enable DDoS protection at the CDN or cloud provider level, and configure autoscaling to absorb burst traffic.

Exemple : création d'un outil HTTP personnalisé

Cet exemple définit une fonction PL/SQL qui envoie une demande HTTP GET et renvoie le texte de la réponse. La fonction est ensuite ajoutée dans l'outil Select AI Agent Framework.

Avant de commencer

Révision :

Vous pouvez créer un outil personnalisé qui envoie une demande REST à l'aide de la procédure DBMS_CLOUD.SEND_REQUEST et renvoie la réponse sous forme de texte. Cet exemple montre comment écrire la fonction PL/SQL et l'ajouter en tant qu'outil à utiliser dans les tâches d'agent.

La fonction get_url_content envoie une demande GET à l'URL cible et renvoie la réponse sous la forme CLOB. DBMS_CLOUD_AI_AGENT.CREATE_TOOL utilise la fonction get_url_content et crée un outil nommé HTTP_TOOL que l'agent peut appeler lorsqu'une tâche nécessite l'extraction du contenu à partir d'une URL.

CREATE OR REPLACE FUNCTION get_url_content (
    url IN CLOB
) RETURN CLOB
AS
    l_resp   DBMS_CLOUD_TYPES.RESP;
    l_result CLOB;
BEGIN
    l_resp := DBMS_CLOUD.SEND_REQUEST(
                credential_name => NULL,
                method          => 'GET',
                uri             => url
             );
    l_result := DBMS_VECTOR_CHAIN.UTL_TO_TEXT(DBMS_CLOUD.GET_RESPONSE_RAW(l_resp);
    RETURN l_result;
END get_url_content;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => 'HTTP_TOOL',
    attributes => '{
      "instruction": "This tool fetches and returns the plain text content from the specified URL. ",
      "function": "get_url_content"
    }'
  );
END;
/

Exemple : afficher les invites d'agent et les réponses de la dernière exécution d'équipe

Cet exemple permet de déboguer l'activité récente d'un agent en affichant les invites, les réponses et les pensées de l'agent de l'équipe d'agent la plus récente exécutée à l'aide des vues historiques et des données de conversation.

Avant de commencer

Révision :

Cet exemple extrait et affiche les journaux détaillés de l'exécution d'équipe d'agent la plus récente. L'exemple utilise les vues USER_AI_AGENT_TEAM_HISTORY, USER_AI_AGENT_TASK_HISTORY et USER_CLOUD_AI_CONVERSATION_PROMPTS pour afficher le nom de l'équipe, la tâche, les invites associées et les réponses de chaque agent. Utilisez cette requête pour résoudre les problèmes en examinant à la fois l'invite d'entrée et les réponses générées par la dernière exécution d'équipe.

WITH latest_team AS (
  SELECT team_exec_id, team_name, start_date
  FROM user_ai_agent_team_history
  ORDER BY start_date DESC
  FETCH FIRST 1 ROW ONLY
),
latest_task AS (
    SELECT team_exec_id, task_name, agent_name, conversation_params, start_date,
           ROW_NUMBER() OVER (PARTITION BY team_exec_id, task_name, agent_name
                             ORDER BY start_date DESC) as rn
  FROM user_ai_agent_task_history
)
SELECT
  team.team_name,
  task.task_name,
  task.agent_name,
  p.prompt,
  p.prompt_response
FROM latest_team team
JOIN latest_task task
  ON team.team_exec_id = task.team_exec_id
 AND task.rn = 1
LEFT JOIN user_cloud_ai_conversation_prompts p
  ON p.conversation_id = JSON_VALUE(task.conversation_params, '$.conversation_id')
ORDER BY task.start_date DESC NULLS LAST,
         p.created     DESC NULLS LAST;

Cet exemple extrait les journaux détaillés des vues d'outil, de tâche et d'historique d'équipe. Utilisez les requêtes suivantes pour auditer l'utilisation de l'outil, des tâches et de l'équipe, ainsi que pour résoudre les problèmes et analyser les journaux. Les interrogations utilisent des vues USER_AI_AGENT_TOOL_HISTORY, USER_AI_AGENT_TASK_HISTORY et USER_AI_AGENT_TASK_HISTORY.

--View the tool history

select * from USER_AI_AGENT_TOOL_HISTORY
order by START_DATE desc

--View the task history

select * from USER_AI_AGENT_TASK_HISTORY
order by START_DATE desc

--View the team history
select * from USER_AI_AGENT_TEAM_HISTORY
order by START_DATE desc

Exemple : reprise d'une exécution d'équipe d'agent à partir de l'état WAITING_FOR_HUMAN

Cet exemple montre comment reprendre une exécution d'équipe d'agent lorsque le statut de l'historique des tâches est WAITING_FOR_HUMAN. Lorsqu'une équipe d'agent passe à l'état WAITING_FOR_HUMAN, elle s'interrompt jusqu'à ce qu'un utilisateur fournisse l'entrée ou la confirmation suivante. Vous pouvez reprendre l'exécution en fonction de la façon dont vous utilisez l'équipe d'agent : sur la ligne de commande SQL ou via DBMS_CLOUD_AI_AGENT.RUN_TEAM.

Avant de commencer

Révision :

Exemple : reprise d'une exécution d'équipe d'agent à l'aide de la ligne de commande SQL

Si vous utilisez SELECT AI AGENT <prompt> sur la ligne de commande SQL, l'agent reprend automatiquement l'exécution de l'équipe mise en pause. Le contexte de conversation, y compris les invites précédentes et le raisonnement, est maintenu sans nécessiter de paramètres supplémentaires.

Exemple : reprise de l'exécution d'une équipe d'agent à l'aide de DBMS_CLOUD_AI_AGENT.RUN_TEAM

Si vous utilisez la procédure DBMS_CLOUD_AI_AGENT.RUN_TEAM, vous pouvez reprendre une équipe d'agents en pause en transmettant le même conversation_id que celui utilisé lors de l'exécution initiale. L'état d'exécution de l'équipe d'agent, y compris les actions en attente et le contexte, est préservé et l'équipe d'agent continue exactement d'où elle s'est arrêtée.

Pour obtenir un exemple d'utilisation de la fonction DBMS_CLOUD_AI_AGENT.RUN_TEAM, reportez-vous à Exemple : création d'un agent Product Return.

--Interact with the agent
DECLARE
  v_response VARCHAR2(4000);
BEGIN
  v_response :=  DBMS_CLOUD_AI_AGENT.RUN_TEAM(
    team_name   => '<same initial team name>',
    user_prompt => 'response to request',
    params      => '{"conversation_id": "<same initial conversation_id>"}'
  );
  DBMS_OUTPUT.PUT_LINE(v_response);
END;

Exemple : création et exécution d'une équipe de superviseur du support client

Cet exemple de bout en bout est basé sur le scénario de support client multi-tours. Il crée des exemples de données de compte et de paiement, définit des fonctions PL/SQL, mappe ces fonctions avec des outils, crée des agents et des tâches de salarié, crée l'agent superviseur et l'équipe, et exécute une conversation à plusieurs tours Sélectionner une structure d'agent AI.

Avant de commencer

Révision :

Le chargé de compte peut rechercher ou mettre à jour les détails du compte client. Le système de paiement peut extraire les transactions de paiement et utiliser un outil de notification par e-mail lorsque l'utilisateur confirme qu'un relevé doit être envoyé. Le superviseur reçoit la demande de l'utilisateur, délègue le compte ou l'agent de paiement et renvoie la réponse finale.

L'image suivante illustre le flux de l'orchestration du service client avec un agent superviseur :

La description de l'image suit

Description de l'illustration select-ai-agent-customer-service-supervisor.png

L'exemple suivant montre comment un agent superviseur coordonne les agents de travail pour terminer une demande client.

Un client demande :

"Veuillez vérifier mes paiements le 11 janvier 2026 et m'envoyer une déclaration."

Le superviseur analyse la demande et sélectionne uniquement les agents de salarié requis.

Etapes Décision du superviseur Agents Résultat
1 Identifier la demande comme une demande de paiement qui peut également nécessiter la remise du relevé PAYMENT_AGENT/PAYMENT_MANAGEMENT_TASK Le système de paiement extrait les transactions pour le 11 janvier 2026 et renvoie les détails du paiement au superviseur.
2 Déterminez que l'utilisateur a également demandé une instruction, qui nécessite une confirmation avant l'envoi. Agent superviseur Le superviseur demande à l'utilisateur de confirmer que le relevé doit être envoyé.
3 Après réception de la confirmation, déléguez la transmission des relevés au salarié responsable de la notification. NOTIFICATION_AGENT / SEND_STATEMENT_TASK Le processus de notification envoie ou prépare le relevé et renvoie le statut de transmission.
4 Combinez les détails du paiement et le statut de livraison du relevé. Agent superviseur Le superviseur renvoie une réponse unique qui inclut la synthèse des paiements et la confirmation de livraison du relevé.
-- Payment System Demo

-- ============================================================================
-- STEP 1: Create user_accounts Sample Table
-- ============================================================================

-- Optional cleanup for a repeatable demo
BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE user_accounts';
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -942 THEN
      RAISE;
    END IF;
END;
/

-- Create user_accounts table
CREATE TABLE user_accounts (
  user_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_name VARCHAR2(100) NOT NULL UNIQUE,
  email VARCHAR2(100),
  billing_address VARCHAR2(200),
  phone VARCHAR2(20),
  account_status VARCHAR2(20),
  created_date DATE DEFAULT SYSDATE,
  updated_date DATE DEFAULT SYSDATE
);

-- Insert three example rows
INSERT INTO user_accounts (user_name, email, billing_address, phone, account_status)
VALUES ('john_smith', '<USER1_EMAIL>', '123 Main St, San Francisco, CA 94102', '415-555-0100', 'ACTIVE');

INSERT INTO user_accounts (user_name, email, billing_address, phone, account_status)
VALUES ('mary_jones', '<USER2_EMAIL>', '456 Oak Ave, Austin, TX 78701', '512-555-0200', 'ACTIVE');

INSERT INTO user_accounts (user_name, email, billing_address, phone, account_status)
VALUES ('david_wilson', '<USER3_EMAIL>', '789 Pine Rd, Seattle, WA 98101', '206-555-0300', 'ACTIVE');

COMMIT;


-- ============================================================================
-- STEP 2: Create PL/SQL Functions
-- ============================================================================

-- Function 1: check_account - retrieves user account information
CREATE OR REPLACE FUNCTION check_account(
  user_name IN VARCHAR2
) RETURN VARCHAR2
IS
  l_account_info VARCHAR2(4000);
  l_user_name VARCHAR2(100) := user_name;
  l_email VARCHAR2(100);
  l_billing_address VARCHAR2(200);
  l_phone VARCHAR2(20);
  l_account_status VARCHAR2(20);
BEGIN
  -- Query user account
  SELECT
    user_name,
    email,
    billing_address,
    phone,
    account_status
  INTO
    l_user_name,
    l_email,
    l_billing_address,
    l_phone,
    l_account_status
  FROM user_accounts
  WHERE UPPER(user_name) = UPPER(l_user_name);
  --Format account information as readable text
  l_account_info := 'Account Information for ' || l_user_name || CHR(10) ||
                    '--------------------------------' || CHR(10) ||
                    'Email: ' || NVL(l_email, 'Not set') || CHR(10) ||
                    'Billing Address: ' || NVL(l_billing_address, 'Not set') || CHR(10) ||
                    'Phone: ' || NVL(l_phone, 'Not set') || CHR(10) ||
                    'Account Status: ' || NVL(l_account_status, 'Unknown');

  RETURN l_account_info;

EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RETURN 'Error: User "' || user_name || '" not found in the system.';
  WHEN OTHERS THEN
    RETURN 'Error retrieving account: ' || SQLERRM;
END check_account;
/

-- Function 2: update_account - updates user account information
CREATE OR REPLACE FUNCTION update_account(
  user_name IN VARCHAR2,
  column_name IN VARCHAR2,
  new_value IN VARCHAR2
) RETURN VARCHAR2
IS
  -- Uses an autonomous transaction so the tool can commit the account update
  -- independently of the surrounding Agent call.
  PRAGMA AUTONOMOUS_TRANSACTION;
  l_sql VARCHAR2(500);
  l_rows_updated NUMBER;
  l_result VARCHAR2(500);
  l_valid_column BOOLEAN := FALSE;
BEGIN
  -- Validate column name (security: only allow specific columns)
  IF UPPER(column_name) IN ('EMAIL', 'BILLING_ADDRESS', 'PHONE', 'ACCOUNT_STATUS') THEN
    l_valid_column := TRUE;
  ELSE
    RETURN 'Error: Column "' || column_name || '" is not allowed to be updated. ' ||
           'Valid columns are: email, billing_address, phone, account_status';
  END IF;

  -- Build dynamic SQL for update
  l_sql := 'UPDATE user_accounts SET ' ||
           DBMS_ASSERT.SIMPLE_SQL_NAME(column_name) || ' = :new_value, ' ||
           'updated_date = SYSDATE ' ||
           'WHERE user_name = :user_name';

  -- Execute update
  EXECUTE IMMEDIATE l_sql
    USING new_value, user_name;

  l_rows_updated := SQL%ROWCOUNT;
  COMMIT;

  -- Return result message
  IF l_rows_updated > 0 THEN
    l_result := 'Successfully updated ' || column_name || ' to "' || new_value ||
                '" for user "' || user_name || '".';
  ELSE
    l_result := 'Error: User "' || user_name || '" not found. No updates made.';
  END IF;

  RETURN l_result;

EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK;
    RETURN 'Error updating account: ' || SQLERRM;
END update_account;
/

-- ============================================================================
-- STEP 3: Create Tools Based on PL/SQL Functions
-- ============================================================================

-- Tool 1: check_account_tool
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'CHECK_ACCOUNT_TOOL',
    attributes => '{
      "instruction": "This tool retrieves user account information including email, billing address, phone, and account status. Provide the user_name to get the account details.",
      "function": "check_account"
    }'
  );
END;
/

-- Tool 2: update_account_tool
BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'UPDATE_ACCOUNT_TOOL',
    attributes => '{
      "instruction": "This tool updates user account information. Provide user_name, column_name (email, billing_address, phone, or account_status), and new_value to update the account.",
      "function": "update_account"
    }'
  );
END;
/

-- ============================================================================
-- STEP 4: Create Account Management Agent
-- ============================================================================

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name  => 'ACCOUNT_AGENT',
    description => 'Manages user account information including billing addresses and contact details',
    attributes  => '{
      "profile_name": "<AI_PROFILE_NAME>",
      "role": "You are a Account Management Specialist. Your role is to help users view and update their account information."

    }'
  );
END;
/

-- ============================================================================
-- STEP 5: Create Task for Account Management Agent
-- ============================================================================

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name  => 'ACCOUNT_MANAGEMENT_TASK',
    attributes => '{
      "instruction": "Handle user account management requests. For account queries, use the check_account_tool with the user_name. For account updates, use the update_account_tool with user_name, the column to update (email, billing_address, phone, or account_status), and the new value. Always provide clear confirmation of any changes made.",
      "tools": ["CHECK_ACCOUNT_TOOL", "UPDATE_ACCOUNT_TOOL"]
    }'
  );
END;
/

-- ============================================================================
-- STEP 6: Create Payment Transactions Sample Table
-- ============================================================================

-- Optional cleanup for a repeatable demo
BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE payment_transactions';
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -942 THEN
      RAISE;
    END IF;
END;
/

-- Create payment_transactions table
CREATE TABLE payment_transactions (
  transaction_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_name VARCHAR2(100) NOT NULL,
  transaction_date DATE NOT NULL,
  amount NUMBER(10,2) NOT NULL,
  payment_method VARCHAR2(50),
  status VARCHAR2(20),
  description VARCHAR2(200),
  created_date DATE DEFAULT SYSDATE
);

-- Create index for better query performance
CREATE INDEX idx_transactions_user_date ON payment_transactions(user_name, transaction_date);

-- Insert sample transaction data
-- Transactions for john_smith
INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('john_smith', TO_DATE('2026-01-11', 'YYYY-MM-DD'), 150.00, 'Credit Card', 'COMPLETED', 'Monthly subscription');

INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('john_smith', TO_DATE('2026-01-11', 'YYYY-MM-DD'), 75.50, 'PayPal', 'COMPLETED', 'Add-on service');

INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('john_smith', TO_DATE('2026-01-15', 'YYYY-MM-DD'), 200.00, 'Credit Card', 'COMPLETED', 'Annual renewal');

INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('john_smith', TO_DATE('2024-12-01', 'YYYY-MM-DD'), 150.00, 'Credit Card', 'COMPLETED', 'Monthly subscription');

-- Transactions for mary_jones
INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('mary_jones', TO_DATE('2024-11-11', 'YYYY-MM-DD'), 99.99, 'Debit Card', 'COMPLETED', 'Premium upgrade');

INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('mary_jones', TO_DATE('2024-11-20', 'YYYY-MM-DD'), 49.99, 'Credit Card', 'COMPLETED', 'Monthly subscription');

-- Transactions for david_wilson
INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('david_wilson', TO_DATE('2024-11-11', 'YYYY-MM-DD'), 299.00, 'Wire Transfer', 'COMPLETED', 'Annual plan');

INSERT INTO payment_transactions (user_name, transaction_date, amount, payment_method, status, description)
VALUES ('david_wilson', TO_DATE('2024-11-25', 'YYYY-MM-DD'), 25.00, 'PayPal', 'PENDING', 'Additional storage');

COMMIT;


-- ============================================================================
-- STEP 7: Create PL/SQL Function for get_payment
-- ============================================================================
CREATE OR REPLACE FUNCTION get_payment(
  user_name IN VARCHAR2,
transaction_date IN VARCHAR2  -- Expected format: 'YYYY-MM-DD' or 'Nov 11' or 'November 11'
) RETURN VARCHAR2
IS
  l_payment_info CLOB;
  l_transaction_date DATE;
  l_total_amount NUMBER := 0;
  l_transaction_count NUMBER := 0;
  l_date_parsed DATE;
  l_user_name VARCHAR2(100) := user_name;
  -- Cursor to fetch transactions
  CURSOR c_transactions IS
    SELECT
      transaction_id,
      TO_CHAR(transaction_date, 'YYYY-MM-DD HH24:MI:SS') AS txn_datetime,
      amount,
      payment_method,
      status,
      description
    FROM payment_transactions
    WHERE user_name = l_user_name
      AND TRUNC(transaction_date) = TRUNC(l_date_parsed)
    ORDER BY transaction_date;

BEGIN
  -- Parse the date input (handle different formats)
  BEGIN
    -- Try standard format first: YYYY-MM-DD
    l_date_parsed := TO_DATE(transaction_date, 'YYYY-MM-DD');
  EXCEPTION
    WHEN OTHERS THEN
      BEGIN
        -- Try format: Mon DD (e.g., 'Nov 11')
        l_date_parsed := TO_DATE(transaction_date || ' ' || TO_CHAR(SYSDATE, 'YYYY'), 'Mon DD YYYY');
      EXCEPTION
        WHEN OTHERS THEN
          BEGIN
            -- Try format: Month DD (e.g., 'November 11')
            l_date_parsed := TO_DATE(transaction_date || ' ' || TO_CHAR(SYSDATE, 'YYYY'), 'Month DD YYYY');
          EXCEPTION
            WHEN OTHERS THEN
              RETURN 'Error: Unable to parse date "' || transaction_date || '". Please use format YYYY-MM-DD (e.g., 2024-11-11) or Mon DD (e.g., Nov 11).';
          END;
      END;
  END;

  -- Build header
  l_payment_info := 'Payment Transactions for ' || l_user_name || ' on ' ||
                    TO_CHAR(l_date_parsed, 'YYYY-MM-DD') || CHR(10) ||
                    '================================================================' || CHR(10);

  -- Fetch and format transactions
  FOR rec IN c_transactions LOOP
    l_transaction_count := l_transaction_count + 1;
    l_total_amount := l_total_amount + rec.amount;

    l_payment_info := l_payment_info || CHR(10) ||
                      'Transaction #' || l_transaction_count || ':' || CHR(10) ||
                      '  Transaction ID: ' || rec.transaction_id || CHR(10) ||
                      '  Date/Time: ' || rec.txn_datetime || CHR(10) ||
                      '  Amount: $' || TO_CHAR(rec.amount, 'FM999,999,990.00') || CHR(10) ||
                      '  Payment Method: ' || NVL(rec.payment_method, 'N/A') || CHR(10) ||
                      '  Status: ' || NVL(rec.status, 'N/A') || CHR(10) ||
                      '  Description: ' || NVL(rec.description, 'N/A') || CHR(10);
  END LOOP;

  -- Add summary
  IF l_transaction_count = 0 THEN
    l_payment_info := l_payment_info || CHR(10) ||
                      'No transactions found for this date.' || CHR(10);
  ELSE
    l_payment_info := l_payment_info || CHR(10) ||
                      '================================================================' || CHR(10) ||
                      'Summary:' || CHR(10) ||
                      '  Total Transactions: ' || l_transaction_count || CHR(10) ||
                      '  Total Amount: $' || TO_CHAR(l_total_amount, 'FM999,999,990.00') || CHR(10);
  END IF;

  RETURN l_payment_info;

EXCEPTION
  WHEN OTHERS THEN
    RETURN 'Error retrieving payment information: ' || SQLERRM;
END get_payment;
/

-- ============================================================================
-- STEP 8: Create Tool for get_payment
-- ============================================================================

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'GET_PAYMENT_TOOL',
    attributes => '{
      "instruction": "This tool retrieves payment transaction information for a specific user on a specific date. Provide the user_name and date (format: YYYY-MM-DD). It returns all transactions for that user on that date including transaction IDs, amounts, payment methods, status, and descriptions.",
      "function": "get_payment"
    }'
  );
END;
/

BEGIN
   DBMS_CLOUD.DROP_CREDENTIAL(
     credential_name => 'EMAIL_CRED' );
END;
/

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => 'EMAIL_CRED',
    username => '<OCI_SMTP_USERNAME>',
    password => '<SMTP_PASSWORD>');
END;
/

BEGIN
   -- Allow SMTP access for user ADMIN
   DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
     host => 'smtp.email.us-ashburn-1.oci.oraclecloud.com',
     lower_port => 587,
     upper_port => 587,
     ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
                        principal_name => '<DATABASE_USERNAME>',
                        principal_type => xs_acl.ptype_db));
END;
/

-- ============================================================================
-- STEP 9: Configure Email Notification Tool
-- ============================================================================

EXEC DBMS_CLOUD_AI_AGENT.drop_tool('Email');
BEGIN
  -- This EMAIL tool sends statements to the fixed recipient configured in the recipient parameter.
  -- To send to a customer's stored email address, replace this fixed-recipient configuration
  -- with logic that looks up and passes the customer's email address.
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => 'EMAIL',
    attributes => q'[{"tool_type": "Notification",
                      "tool_params": {"notification_type" : "EMAIL",
                                      "credential_name": "EMAIL_CRED",
                                      "recipient": "<RECIPIENT_EMAIL>",
                                      "subject": "Payment statement",
                                      "smtp_host": "smtp.email.us-ashburn-1.oci.oraclecloud.com",
                                      "sender": "<SENDER_EMAIL>"}}]'
  );
END;
/

-- ============================================================================
-- STEP 10: Create Payment Management Agent
-- ============================================================================

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name  => 'PAYMENT_AGENT',
    description => 'Manages payment transactions, generates statements, and handles payment-related queries',
    attributes  => '{
      "profile_name": "<AI_PROFILE_NAME>",
      "role": "You are a Payment Management Specialist. "
    }'
  );
END;
/

-- ============================================================================
-- STEP 11: Create Task for Payment Management Agent
-- ============================================================================

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name  => 'PAYMENT_MANAGEMENT_TASK',
    attributes => '{
      "instruction": "Handle payment-related requests. For payment queries, use GET_PAYMENT_TOOL with the user_name and date. Show the payment details, then ask the user whether they want to receive the statement by email. If they do, send it using EMAIL.",
      "tools": ["GET_PAYMENT_TOOL", "EMAIL"]
    }'
  );
END;
/


-- STEP 12: Create the Supervisor Agent and Team
exec DBMS_CLOUD_AI_AGENT.clear_team;
exec DBMS_CLOUD_AI_AGENT.drop_team('CUSTOMER_SUPPORT');
EXEC DBMS_CLOUD_AI_AGENT.drop_agent('ORCHESTRATOR_AGENT');
BEGIN
  DBMS_CLOUD_AI_AGENT.create_agent(
    'ORCHESTRATOR_AGENT',
    '{
       "profile_name": "<AI_PROFILE_NAME>",
       "supervisor" : true
     }'
  );
END;
/
BEGIN
    DBMS_CLOUD_AI_AGENT.create_team(
        team_name   => 'CUSTOMER_SUPPORT',
        attributes  => '{
            "process": "sequential",
            "supervisor_agent": "ORCHESTRATOR_AGENT",
            "agents": [
                {"name":"ACCOUNT_AGENT","task" : "ACCOUNT_MANAGEMENT_TASK"},
                {"name":"PAYMENT_AGENT","task" : "PAYMENT_MANAGEMENT_TASK"}
            ]
        }',
        description => 'A supervised team with orchestrator delegating to specialists'
    );
END;
/

-- STEP 13: Run the Conversation
exec DBMS_CLOUD_AI_AGENT.set_team('CUSTOMER_SUPPORT');

SQL> select ai agent my user name is john_smith, I want to update my billing address to 11th Ave, Austin, TX 78701;

RESPONSE
--------------------------------------------------------------------------------
The billing address for user 'john_smith' has been successfully updated to '11th Ave, Austin, TX 78701'.

SQL> select ai agent please check my payments on Jan 11 2026;

RESPONSE
--------------------------------------------------------------------------------
Here are your payment details for January 11, 2026, john_smith:

================================================================
Payment Transactions for john_smith on 2026-01-11

Transaction #1:
  Transaction ID: 1
  Date/Time: 2026-01-11 00:00:00
  Amount: $150.00
  Payment Method: Credit Card
  Status: COMPLETED

RESPONSE
--------------------------------------------------------------------------------
  Description: Monthly subscription

Transaction #2:
  Transaction ID: 2
  Date/Time: 2026-01-11 00:00:00
  Amount: $75.50
  Payment Method: PayPal
  Status: COMPLETED
  Description: Add-on service

================================================================

RESPONSE
--------------------------------------------------------------------------------
Summary:
  Total Transactions: 2
  Total Amount: $225.50

Would you like to receive a statement of these transactions via email? Please confirm.

SQL> select ai agent yes send the email;

RESPONSE
--------------------------------------------------------------------------------
The payment statement for January 11, 2026, has been successfully sent to the configured recipient. If you have any further questions or need assistance, feel free to ask.

Exemple : importer et exporter des équipes d'agent

Importez et exportez les équipes Select AI Agent Framework entre les bases de données, les schémas et les services d'agent compatibles et entre les environnements de base de données Autonomous AI.

Avant de commencer

Révision :

Cet exemple montre comment exporter une définition d'équipe d'agent et l'importer dans un autre environnement. Vous pouvez exporter une équipe sous forme de chaîne ou l'enregistrer dans Object Storage, puis importer cette définition d'équipe à partir d'une chaîne, d'Object Storage ou d'un fichier local. Les définitions d'équipe Sélectionner la structure d'agent AI incluent les agents, les tâches et les définitions d'outil. EXPORT_TEAM renvoie une valeur CLOB ou écrit la définition d'équipe exportée dans Object Storage, et IMPORT_TEAM importe une définition d'équipe dans la base de données à partir d'une valeur CLOB ou d'Object Storage.

Remarque

Remarque : l'export et l'import incluent les définitions d'équipe et les métadonnées associées, telles que les agents, les tâches et les définitions d'outil. L'export et l'import n'incluent pas les ressources de prise en charge en dehors de la définition de l'équipe, telles que les informations d'identification, les fonctions PL/SQL créées par l'utilisateur, les services REST externes, les fonctions OCI, les fonctions AWS Lambda, les profils, les index ou d'autres ressources dépendantes. Créez à nouveau ces ressources dans l'environnement cible avant d'utiliser l'équipe importée ou exportée.

Exemples d'exportation d'une équipe d'agents

Les exemples suivants illustrent l'exportation d'une équipe.

Exemple : export d'une équipe vers Object Storage

Cet exemple exporte l'équipe ReturnAgency et écrit la définition de l'équipe exportée vers un emplacement Object Storage. Utilisez cette méthode lorsque vous souhaitez traiter la définition d'équipe exportée en PL/SQL et enregistrer la définition d'équipe en dehors de la base de données pour la migration ou la réutilisation.

DECLARE
  output          clob;
  params_clob     clob;
BEGIN
BEGIN
  DBMS_CLOUD_AI_AGENT.EXPORT_TEAM(
    team_name                      => 'ReturnAgency',
    object_storage_credential_name => 'cred1',
    location                       => 'https://swiftobjectstorage.us-ashburn-
1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder'
  );
END;
/
Exporter vers la banque d'objets avec le paramètre 'overwrite' défini sur TRUE

Exportez une définition d'équipe d'agent vers un fichier JSON dans Object Storage. L'argument params définit "overwrite": true, ce qui permet à l'opération de remplacer un fichier existant portant le même nom à l'emplacement indiqué.

DECLARE
  output          clob;
  params_clob     clob;
BEGIN
  DBMS_CLOUD_AI_AGENT.export_team(
              team_name => ‘ReturnAgency’,
              object_storage_credential_name  => ‘OBJ_STORAGE_CRED’,
              location => ‘https://swiftobjectstorage.us-ashburn-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder/return_agency.json’,
              params => ‘{“overwrite”: true}’

  );
END;
/
Exemple : exportation d'une équipe vers un fichier local

Cet exemple exporte l'équipe Return Agency vers un fichier CLOB et écrit la sortie dans un fichier à l'aide de UTL_FILE. Utilisez cette méthode lorsque vous souhaitez conserver la définition d'équipe exportée dans un objet de répertoire de base de données.

Remarque

Remarque : si la définition d'équipe exportée est volumineuse, écrivez la sortie CLOB dans un fichier en blocs au lieu d'un appel UTL_FILE.PUT_LINE unique.

DECLARE
	output clob;
	params_clob clob;
	file_handler UTL_FILE.FILE_TYPE;
BEGIN
	output := DBMS_CLOUD_AI_AGENT.export_team(
	team_name => 'Return Agency'
	);

	file_handler := UTL_FILE.FOPEN(
		location => 'MY_DIR',
		filename => 'return_agency.json',
		open_mode => 'W',
		max_linesize => 32767
		);
	UTL_FILE.PUT_LINE(file_handler, output);
	UTL_FILE.FCLOSE(file_handler);
END;
/
Exemple : export d'une équipe vers une chaîne

Exportez une définition d'équipe d'agent en tant que CLOB. La fonction renvoie la spécification d'équipe, que vous pouvez stocker dans une variable, inspecter, modifier ou utiliser dans un traitement ultérieur avant de l'enregistrer ou de l'importer ailleurs.

DECLARE
  output          clob;
  params_clob     clob;
  file_handler    UTL_FILE.FILE_TYPE;
BEGIN
  output := DBMS_CLOUD_AI_AGENT.export_team(
              team_name => ‘Return Agency’
  );
END;
/
Exemples d'import d'une équipe d'agent

Les exemples suivants illustrent l'importation d'une équipe.

Exemple : importation d'une équipe à partir d'Object Storage

Cet exemple importe une définition d'équipe à partir d'un fichier JSON stocké dans Object Storage. Utilisez cette méthode lorsque la définition d'équipe exportée existe déjà dans un emplacement de stockage distant.

BEGIN
  DBMS_CLOUD_AI_AGENT.import_team(
              profile_name => 'PROFILE_NAME',
              team_name    => 'ReturnAgency',
              object_storage_credential_name => 'cred1',
              object_uri      => 'https://swiftobjectstorage.us-ashburn-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder/import_agent.json'
  );

END;
/
Exemple : importation d'une équipe à partir d'une spécification réussie

Cet exemple crée d'abord les fonctions requises créées par l'utilisateur, puis importe la définition de l'équipe à partir d'une spécification JSON stockée dans un fichier CLOB. Utilisez cette méthode lorsque vous générez ou modifiez la spécification dans PL/SQL avant l'import.

CREATE OR REPLACE
FUNCTION run_sql(nl_query IN CLOB)
RETURN CLOB
IS
  v_query CLOB;
BEGIN
  v_query := '(Name,Description,Category,Date Created,Price,Discounted Price,Offer Expiration Date)
("AquaPure Water Pitcher", "2-liter BPA-free water pitcher with filter", "Kitchen", "2024-04-12", 34.95, 27.95, "2024-07-01")
("CozyLuxe Throw Blanket", "Ultra-soft microfiber throw blanket (50"x60")", "Living Room", "2024-03-22", 19.99, None, None)
("SafeStep Bath Mat", "Non-slip bath mat, mildew resistant, gray", "Bathroom", "2024-05-05", 12.50, 9.99, "2024-06-15")
("PowerPlug Extension", "6-outlet surge protector power strip", "Electrical", "2024-01-10", 21.75, None, None)
("FreshGuard Storage Bags", "Set of 20 reusable silicone food storage bags", "Kitchen", "2024-03-17", 15.60, 12.48, "2024-06-10") ';

  RETURN v_query;
END run_sql;
/

CREATE OR REPLACE
FUNCTION email(contents IN CLOB)
RETURN CLOB
IS
BEGIN
  dbms_output.put_line('>>>>>>>> Agent generated:\n' ||
                            contents || '\n<<<<<<<<<');
  RETURN 'Email sent successfully';
END email;
/

-- import with specification
DECLARE
  l_input_json CLOB;
BEGIN
  l_input_json :=
  q'[
{
    "agents": [],
    "component_type": "Agent",
    "description": "You are an marketing agent who helps plan campaigns.",
    "flows": [],
    "id": "1d02daf2-57...",
    "inputs": [],
    "llm_config": {
        "component_type": "OCI_CONFIG",
        "default_generation_parameters": {
            "max_tokens": null,
            "temperature": null,
            "top_p": null
        },
        "description": null,
        "id": "9e2a18a2...ae",
        "metadata": {},
        "model_id": "openai.gpt-oss-120b",
        "name": "openai/gpt-oss-120b"
    },
    "metadata": {},
    "name": "Marketing assistant",
    "outputs": [],
    "system_prompt": "Help the user with their tasks around marketing products for their business.",
    "tools": [
        {
            "component_type": "ServerTool",
            "description": "Send an email to the current user.",
            "id": "9fcc6...",
            "inputs": [
                {
                    "title": "content",
                    "type": "string"
                }
            ],
            "metadata": {},
            "name": "Email",
            "outputs": [
                {
                    "type": "string"
                }
            ]
        },
        {
            "component_type": "ServerTool",
            "description": "Generates a SQL query for the given NL Question, runs it, and returns the results.",
            "id": "ae1e6c17...",
            "inputs": [
                {
                    "title": "nl_query",
                    "type": "string"
                }
            ],
            "metadata": {},
            "name": "run_sql",
            "outputs": [
                {
                    "type": "string"
                }
            ]
        }
    ]
}
  ]';

  DBMS_CLOUD_AI_AGENT.import_team(
              profile_name => 'PROFILE_NAME',
              team_name    => 'MARKETING',
              specification    => l_input_json
  );

END;
/
Exemple : importation d'une équipe à partir d'un fichier d'annuaire

Importez une définition d'équipe d'agent à partir d'un fichier JSON stocké dans un objet de répertoire. Le paramètre location indique l'objet répertoire et le nom du fichier.

DECLARE
    file_handle 	UTL_FILE.FILE_TYPE;
    line_buffer 	VARCHAR2(32767);
    file_content 	CLOB;
    temp_line 		VARCHAR2(32767);
BEGIN
    DBMS_LOB.CREATETEMPORARY(file_content, TRUE);

    file_handle := UTL_FILE.FOPEN('MY_DIRECTORY', 'marketing_team.txt', 'r');

    LOOP
        BEGIN
            UTL_FILE.GET_LINE(file_handle, line_buffer);

            temp_line := line_buffer || CHR(10);
            DBMS_LOB.WRITEAPPEND(file_content, LENGTH(temp_line), temp_line);
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
               EXIT;
        END;
    END LOOP;

    UTL_FILE.FCLOSE(file_handle);

	DBMS_CLOUD_AI_AGENT.import_team(
              profile_name     => 'PROFILE_NAME',
              team_name        => 'MARKETING',
              specification    => file_content
    );


EXCEPTION
    WHEN OTHERS THEN
        IF UTL_FILE.IS_OPEN(file_handle) THEN
            UTL_FILE.FCLOSE(file_handle);
        END IF;
        RAISE;
END;
Exemple d'exportation et d'importation

L'exemple suivant présente un flux d'export et d'import pour une équipe d'agents.

—————————————————————–
– Export a Team
—————————————————————–
– Create an Agent, Task, and Team

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => ‘GET_PAYMENT_TOOL’,
    attributes => ‘{
      “instruction”: “This tool retrieves payment transaction information for a specific user on a specific date. Provide the user_name and date (format: YYYY-MM-DD). It returns all transactions for that user on that date including transaction IDs, amounts, payment methods, status, and descriptions.”,
      “function”: “get_payment”
    }’
  );
END;
/

– Websearch tool is accessing OPENAI endpoint, so we need allow ACL access
BEGIN
  DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
    host => ‘api.openai.com’,
    ace  => xs$ace_type(privilege_list => xs$name_list(‘http’),
                        principal_name => ‘ADB_USER’,
                        principal_type => xs_acl.ptype_db)
   );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => ‘Websearch’,
    attributes => q’[{“instruction”: “This tool can be used for searching the price given a specific link. The input of the tool should be a query like what is the price of the product on this website”,
                      “tool_type”: “WEBSEARCH”,
                      “tool_params”: {“credential_name”: “GENAI_CRED”}}]’
  );
END;
/

BEGIN
  DBMS_CLOUD.CREATE_CREDENTIAL(
    credential_name => ‘EMAIL_CRED’,
    username => '',
    password => '');
END;
/

-- To allow Email tool in ADBS, we need to allow SMTP access
BEGIN
   -- Allow SMTP access for user ADMIN
   DBMS_NETWORK_ACL_ADMIN.APPEND_HOST_ACE(
     host => 'smtp.email.us-ashburn-1.oci.oraclecloud.com',
     lower_port => 587,
     upper_port => 587,
     ace => xs$ace_type(privilege_list => xs$name_list('SMTP'),
                        principal_name => 'ADB_USER',
                        principal_type => xs_acl.ptype_db));
END;
/

BEGIN
  -- This EMAIL tool sends statements to the fixed recipient configured in the recipient parameter.
  -- To send to a customer's stored email address, replace this fixed-recipient configuration
  -- with logic that looks up and passes the customer's email address.
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name  => 'EMAIL',
    attributes => q'[{"tool_type": "Notification",
                      "tool_params": {"notification_type" : "EMAIL",
                                      "credential_name": "EMAIL_CRED",
                                      "recipient": "",
                                      "subject": "Payment statement",
                                      "smtp_host": "smtp.email.us-ashburn-1.oci.oraclecloud.com",
                                      "sender": ""}}]'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name  => 'PAYMENT_AGENT',
    description => 'Manages payment transactions, generates statements, and handles payment-related queries',
    attributes  => '{
      "profile_name": "",
      "role": "You are a Payment Management Specialist. "
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_team(
    team_name  => 'ReturnAgency',
    attributes => '{"agents": [{"name":"CustomerAgent","task" : "Return_And_Price_Match"}],
                    "process": "sequential"}');
END;
/

-- Export Team Option 1: Export to Object Store
DECLARE
  output          clob;
  params_clob     clob;
BEGIN
  DBMS_CLOUD_AI_AGENT.export_team(
              team_name => 'ReturnAgency',
              object_storage_credential_name  => 'cred1',
              location => 'https://swiftobjectstorage.us-ashburn-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder/'
  );

END;
/

– Export Team Option 2: Export to a File
DECLARE
  output          clob;
  params_clob     clob;
  l_attr_obj      JSON_OBJECT_T := new JSON_OBJECT_T;
  file_handler    UTL_FILE.FILE_TYPE;
BEGIN
  output := DBMS_CLOUD_AI_AGENT.export_team(
              team_name => ‘Return Agency’
  );

  file_handler := UTL_FILE.FOPEN(
                    location      => ‘MY_DIR’,
                    filename      => ‘return_agency.json’,
                    open_mode     => ‘W’,
                    max_linesize  => 32767
                    );
  UTL_FILE.PUT_LINE(file_handler, output);
  UTL_FILE.FCLOSE(file_handler);

END;
/

—————————————————————–
– Import a Team
—————————————————————–

– Import Team Option 1: Import from a file in Object Store
BEGIN
  DBMS_CLOUD_AI_AGENT.import_team(
              profile_name => ‘PROFILE_NAME’,
              team_name    => ‘TEAM_NAME’,
              object_storage_credential_name => ‘cred1’,
              object_uri      => ‘https://swiftobjectstorage.us-ashburn-1.oraclecloud.com/v1/my_namespace/my_bucket/my_data_folder/import_agent.json’
  );
END;
/

– Import Team Option 2: Import from a passed specification
– Create any relevant functions first
CREATE OR REPLACE
FUNCTION run_sql(nl_query IN CLOB)
RETURN CLOB
IS
  v_query CLOB;
BEGIN
  v_query := ‘(Name,Description,Category,Date Created,Price,Discounted Price,Offer Expiration Date)
(“AquaPure Water Pitcher”, “2-liter BPA-free water pitcher with filter”, “Kitchen”, “2024-04-12”, 34.95, 27.95, “2024-07-01”)
(“CozyLuxe Throw Blanket”, “Ultra-soft microfiber throw blanket (50”x60”)”, “Living Room”, “2024-03-22”, 19.99, None, None)
(“SafeStep Bath Mat”, “Non-slip bath mat, mildew resistant, gray”, “Bathroom”, “2024-05-05”, 12.50, 9.99, “2024-06-15”)
(“PowerPlug Extension”, “6-outlet surge protector power strip”, “Electrical”, “2024-01-10”, 21.75, None, None)
(“FreshGuard Storage Bags”, “Set of 20 reusable silicone food storage bags”, “Kitchen”, “2024-03-17”, 15.60, 12.48, “2024-06-10”) ‘;

RETURN v_query;
END run_sql;
/

CREATE OR REPLACE
FUNCTION email(contents IN CLOB)
RETURN CLOB
IS
BEGIN
  dbms_output.put_line(‘»»»» Agent generated:\n’ ||
                            contents || ‘\n««««<’);
  RETURN ‘Email sent successfully’;
END email;
/

– import with specification
DECLARE
  l_input_json CLOB;
BEGIN
  l_input_json :=
  q’[
{
    “agents”: [],
    “component_type”: “Agent”,
    “description”: “You are an marketing agent who helps plan campaigns.”,
    “flows”: [],
    “id”: “1d02da…”,
    “inputs”: [],
    “llm_config”: {
        “component_type”: “OCI_CONFIG”,
        “default_generation_parameters”: {
            “max_tokens”: null,
            “temperature”: null,
            “top_p”: null
        },
        “description”: null,
        “id”: “9e2a1…”,
        “metadata”: {},
        “model_id”: “openai.gpt-oss-120b”,
        “name”: “openai/gpt-oss-120b”
    },
    “metadata”: {},
    “name”: “Marketing assistant”,
    “outputs”: [],
    “system_prompt”: “Help the user with their tasks around marketing products for their business.”,
    “tools”: [
        {
            “component_type”: “ServerTool”,
            “description”: “Send an email to the current user.”,
            “id”: “9fcc66…”,
            “inputs”: [
                {
                    “title”: “content”,
                    “type”: “string”
                }
            ],
            “metadata”: {},
            “name”: “Email”,
            “outputs”: [
                {
                    “type”: “string”
                }
            ]
        },
        {
            “component_type”: “ServerTool”,
            “description”: “Generates a SQL query for the given NL Question, runs it, and returns the results.”,
            “id”: “ae1e…”,
            “inputs”: [
                {
                    “title”: “nl_query”,
                    “type”: “string”
                }
            ],
            “metadata”: {},
            “name”: “run_sql”,
            “outputs”: [
                {
                    “type”: “string”
                }
            ]
        }
    ]
}
  ]’;
  DBMS_CLOUD_AI_AGENT.import_team(
              profile_name => ‘PROFILE_NAME’,
              team_name    => ‘TEAM_NAME’,
              specification    => l_input_json
  );

end;
/

– Import Team Option 3: Import from a passed specification
DECLARE
    file_handle 	UTL_FILE.FILE_TYPE;
    line_buffer 	VARCHAR2(32767);
    file_content 	CLOB;
    temp_line 		VARCHAR2(32767);
BEGIN
    DBMS_LOB.CREATETEMPORARY(file_content, TRUE);

    file_handle := UTL_FILE.FOPEN('MY_DIRECTORY', 'marketing_team.txt', 'r');

    LOOP
        BEGIN
            UTL_FILE.GET_LINE(file_handle, line_buffer);

            temp_line := line_buffer || CHR(10);
            DBMS_LOB.WRITEAPPEND(file_content, LENGTH(temp_line), temp_line);
        EXCEPTION
            WHEN NO_DATA_FOUND THEN
               EXIT;
        END;
    END LOOP;

    UTL_FILE.FCLOSE(file_handle);

    DBMS_CLOUD_AI_AGENT.import_team(
              profile_name     => 'PROFILE_NAME',
              team_name        => 'TEAM_NAME',
              specification    => file_content
    );
EXCEPTION
    WHEN OTHERS THEN
        IF UTL_FILE.IS_OPEN(file_handle) THEN
            UTL_FILE.FCLOSE(file_handle);
        END IF;
        RAISE;
END;
/

– STEP 13: Run the Conversation
exec DBMS_CLOUD_AI_AGENT.set_team(‘CUSTOMER_SUPPORT’);

SQL> select ai agent my user name is john_smith, I want to update my billing address to 11th Ave, Austin, TX 78701;

RESPONSE

The billing address for user ‘john_smith’ has been successfully updated to ‘11th Ave, Austin, TX 78701’.

SQL> select ai agent please check my payments on Jan 11 2026;

RESPONSE

Here are your payment details for January 11, 2026, john_smith:

================================================================
Payment Transactions for john_smith on 2026-01-11

Transaction #1:
  Transaction ID: 1
  Date/Time: 2026-01-11 00:00:00
  Amount: $150.00
  Payment Method: Credit Card
  Status: COMPLETED

RESPONSE

Description: Monthly subscription

Transaction #2:
  Transaction ID: 2
  Date/Time: 2026-01-11 00:00:00
  Amount: $75.50
  Payment Method: PayPal
  Status: COMPLETED
  Description: Add-on service

================================================================

RESPONSE

Summary:
  Total Transactions: 2
  Total Amount: $225.50

Would you like to receive a statement of these transactions via email? Please confirm.

SQL> select ai agent yes send the email;

RESPONSE

The payment statement for January 11, 2026, has been successfully  sent to the configured recipient. If you have any further questions or  need assistance, feel free to ask.

Exemple : obtention de la définition d'un objet d'agent AI

Cet exemple crée un outil, un agent, une tâche et une équipe, puis utilise DBMS_CLOUD_AI_AGENT.GET_DEFINITION pour renvoyer la définition de l'équipe. Il montre la différence entre ne renvoyer que l'équipe demandée et renvoyer l'équipe avec ses objets dépendants.

Avant de commencer

Révision :

Créer les objets d'agent

Créez un outil, un agent, une tâche et une équipe simples. L'outil renvoie une réponse statique de sorte que l'exemple ne nécessite pas de données client ni de service externe.

CREATE OR REPLACE FUNCTION GETDEF_TOOL_FUNCTION(query IN CLOB, offset IN NUMBER, limit IN NUMBER) RETURN CLOB AS
BEGIN
  RETURN '{"status":"success","message":"Example response"}';
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(tool_name => 'GETDEF_TOOL', attributes => '{"instruction":"Return a static response for the example.","function":"GETDEF_TOOL_FUNCTION"}');
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(agent_name => 'GETDEF_AGENT', attributes => '{"profile_name":"AI_PROFILE_NAME","role":"Return the response from GETDEF_TOOL.","tools":["GETDEF_TOOL"],"enable_human_tool":false}');
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(task_name => 'GETDEF_TASK', attributes => '{"instruction":"Use GETDEF_TOOL for the request.","tools":["GETDEF_TOOL"]}');
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(team_name => 'GETDEF_TEAM', attributes => '{"agents":[{"name":"GETDEF_AGENT","task":"GETDEF_TASK"}],"process":"sequential"}');
END;
/
Obtenir la définition d'un agent

Utilisez object_type défini sur AGENT pour renvoyer le bloc canonique DBMS_CLOUD_AI_AGENT.CREATE_AGENT pour un agent existant.

SELECT DBMS_CLOUD_AI_AGENT.GET_DEFINITION(object_type => 'AGENT', object_name => 'GETDEF_AGENT') AS definition FROM dual;
Obtenir la définition d'un outil

Utilisez object_type défini sur TOOL pour renvoyer le bloc canonique DBMS_CLOUD_AI_AGENT.CREATE_TOOL pour un outil existant.

SELECT DBMS_CLOUD_AI_AGENT.GET_DEFINITION(object_type => 'TOOL', object_name => 'GETDEF_TOOL') AS definition FROM dual;
Récupération de la définition d'une tâche

Utilisez object_type défini sur TASK pour renvoyer le bloc canonique DBMS_CLOUD_AI_AGENT.CREATE_TASK pour une tâche existante.

SELECT DBMS_CLOUD_AI_AGENT.GET_DEFINITION(object_type => 'TASK', object_name => 'GETDEF_TASK') AS definition FROM dual;

Chaque appel renvoie uniquement la définition d'objet demandée. Utilisez l'appel TEAM avec dependent_objects lorsque vous avez besoin des définitions d'agent, de tâche et d'outil associées dans la même sortie.

Obtenir la définition de l'équipe avec les objets dépendants

Définissez dependent_objects sur true pour inclure les définitions d'agent, de tâche et d'outil dépendants dans la sortie renvoyée.

SELECT DBMS_CLOUD_AI_AGENT.GET_DEFINITION(object_type => 'TEAM', object_name => 'GETDEF_TEAM', params => '{"dependent_objects": true}') AS definition FROM dual;

Le résultat contient le bloc canonique CREATE_TEAM et les blocs dépendants CREATE_TOOL, CREATE_AGENT et CREATE_TASK. Vérifiez les noms d'objet et les valeurs propres à l'environnement avant de recréer les objets dans une autre base de données.

Obtenir la définition de l'équipe sans objets dépendants

Appelez GET_DEFINITION sans params pour renvoyer uniquement la définition d'équipe demandée.

SELECT DBMS_CLOUD_AI_AGENT.GET_DEFINITION(object_type => 'TEAM', object_name => 'GETDEF_TEAM') AS definition FROM dual;

Le résultat contient un bloc DBMS_CLOUD_AI_AGENT.CREATE_TEAM canonique et référence les objets dépendants par leur nom public sans inclure leurs blocs de création.

Exemple : Accorder et révoquer l'accès à une équipe d'agents partagés

Cet exemple montre comment un propriétaire d'équipe d'agent peut partager une équipe d'agent avec un autre utilisateur de base de données et contrôler l'accès à l'équipe. L'exemple de la diapositive ci-dessus crée une équipe d'agents de gestion de profils qui extrait les informations de profil utilisateur d'une table du schéma du consommateur.

Avant de commencer

Vérifiez et assurez-vous de remplir les prérequis :

Le propriétaire de l'équipe crée l'agent, la tâche et l'outil personnalisé, puis crée l'équipe de l'agent. L'agent utilise un profil AI indiqué par l'espace réservé de variable d'exécution {llm_profile}. Cela permet à un consommateur ayant accès à l'équipe partagée de fournir un profil d'IA approprié pour sa session.

L'exemple accorde à l'équipe l'accès à ADB_USER2, qui se connecte à la base de données à l'aide de son propre schéma et crée un profil AI nommé GROK_ADB_USER2. Le consommateur appelle ensuite l'équipe à l'aide du nom qualifié de l'équipe, tel que ADB_USER.Shared_ACCOUNT_TEAM, et fournit le profil AI via attribute_variables dans l'argument des paramètres.

La table personnalisée CHECK_PROFILE_TOOL résout également la table USER_PROFILES dans le schéma du consommateur authentifié. Par conséquent, l'équipe partagée peut utiliser la même définition d'outil lors de l'extraction des données du schéma de l'utilisateur qui appelle l'équipe.

L'exemple révoque ensuite l'accès du consommateur et montre que l'utilisateur ne peut plus utiliser l'équipe partagée.

Remarque

Remarque : l'exemple utilise des valeurs d'espace réservé pour le scénario présenté. Remplacez ces valeurs par des valeurs appropriées pour votre propre application et votre cas d'emploi.

Créer des fonctions d'outil

Vous créez des fonctions d'outil dans le schéma propriétaire. L'outil Sélectionner une structure d'agent AI référence la fonction correspondante et l'utilise lorsque l'outil est sélectionné lors d'une exécution en équipe. Le premier outil recherche les informations sur le produit pour la demande. Le deuxième outil formate les informations sur le produit en tant que réponse de support.

Créer des outils

Vous spécifiez les fonctions de l'outil propriétaire-schéma en tant qu'outils d'agent. Ces outils font toujours partie de l'équipe gérée par le propriétaire.

Création de tâches

Vous créez LOOKUP_PRODUCT_TASK à exécuter en premier et WRITE_SUPPORT_RESPONSE_TASK à exécuter une fois les détails du produit disponibles.

Créer des agents (Create Agents)

Vous créez PRODUCT_LOOKUP_AGENT pour rechercher des informations sur le produit et SUPPORT_RESPONSE_AGENT pour écrire la réponse finale.

Créer une équipe

Vous créez SHARED_SUPPORT_TEAM avec un processus séquentiel afin que la tâche de recherche se termine avant le début de la tâche de réponse.

Accorder l'accès à l'équipe

Avant d'accorder l'accès à l'équipe, consultez les prérequis pour le partage des équipes Select AI Agent Framework. Accordez à un autre utilisateur ou rôle de base de données l'autorisation d'exécuter l'équipe partagée. GRANT_TEAM_ACCESS permet d'exécuter l'équipe en tant qu'unité. L'octroi de l'équipe n'accorde pas d'accès indépendant pour modifier la définition de l'équipe.

Exécuter l'équipe partagée

Le consommateur exécute l'équipe partagée en utilisant le nom de l'équipe qualifiée par le propriétaire. Les paramètres d'exécution peuvent transmettre un ID de conversation et des valeurs de variable d'espace de noms sans modifier la définition d'équipe stockée.

ADB_USER2 exécute l'équipe partagée en utilisant le nom de l'équipe qualifiée par le propriétaire, ADB_USER.Shared_ACCOUNT_TEAM. Le destinataire fournit GROK_ADB_USER2 pour l'espace réservé {llm_profile} via attribute_variables dans l'argument params. Le consommateur fournit également un ID de conversation pour tenir à jour le contexte de la conversation.

Créer des ressources consommateur

Connectez-vous en tant que ADB_USER2. Créez le profil AI GROK_ADB_USER2 et la table USER_PROFILES dans le schéma de consommateur. L'exemple renseigne USER_PROFILES avec des exemples d'informations de profil extraites par l'équipe partagée CHECK_PROFILE_TOOL.

Par exemple, lorsque ADB_USER2 demande l'adresse de facturation john_smith, CHECK_PROFILE_TOOL utilise la fonction CHECK_PROFILE pour extraire les informations correspondantes de la table USER_PROFILES dans le schéma ADB_USER2.

Révoquer l'accès de l'équipe

Le propriétaire de l'équipe utilise REVOKE_TEAM_ACCESS pour enlever l'accès d'ADB_USER2 à Shared_ACCOUNT_TEAM. Une fois l'accès révoqué, ADB_USER2 ne peut plus exécuter le fichier ADB_USER.Shared_ACCOUNT_TEAM qualifié par le propriétaire.

La révocation de l'accès de l'équipe ne modifie ni ne supprime les définitions d'équipe, d'agent, de tâche ou d'outil stockées. Elle supprime l'autorisation du consommateur d'exécuter l'équipe partagée.

L'exemple complet est le suivant :

-- create an agent team with admin owner
conn ADB_USER/<password>@<connection_name>

DROP TABLE user_profiles;

CREATE OR REPLACE FUNCTION check_profile(
  user_name IN VARCHAR2
) RETURN VARCHAR2
AUTHID CURRENT_USER
IS
  l_profile_info     VARCHAR2(4000);
  l_user_name        VARCHAR2(100) := user_name;
  l_email            VARCHAR2(100);
  l_billing_address  VARCHAR2(200);
  l_phone            VARCHAR2(20);
  l_account_status   VARCHAR2(20);
  l_schema_name      VARCHAR2(128);
BEGIN
  -- Resolve the table in the authenticated
  -- consumer's schema.
  l_schema_name := SYS_CONTEXT('USERENV',
                               'CURRENT_USER');

  EXECUTE IMMEDIATE '
    SELECT user_name, email, billing_address, phone,
           account_status
    FROM ' || DBMS_ASSERT.enquote_name(l_schema_name,
                                       FALSE) ||
    '.user_profiles
    WHERE UPPER(user_name) = UPPER(:1)'
  INTO
    l_user_name,
    l_email,
    l_billing_address,
    l_phone,
    l_account_status
  USING l_user_name;

  l_profile_info := 'Profile Information for ' ||
                    l_user_name || CHR(10) ||
                    '--------------------------------' || CHR(10) ||
                    'Email: ' || NVL(l_email, 'Not set') || CHR(10) ||
                    'Billing Address: ' ||
                    NVL(l_billing_address, 'Not set') || CHR(10) ||
                    'Phone: ' || NVL(l_phone, 'Not set') || CHR(10) ||
                    'Account Status: ' ||
                    NVL(l_account_status, 'Unknown');

  RETURN l_profile_info;

EXCEPTION
  WHEN NO_DATA_FOUND THEN
    RETURN 'Error: User "' || user_name ||
           '" not found in the system.';
  WHEN OTHERS THEN
    RETURN 'Error retrieving profile.';
END check_profile;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TOOL(
    tool_name  => 'CHECK_PROFILE_TOOL',
    attributes => '{
      "instruction": "This tool retrieves user profile information including email, billing address, phone, and account status. Provide the user_name to get the profile details.",
      "function": "check_profile"
    }'
  );
END;
/

exec DBMS_CLOUD_AI_AGENT.DROP_AGENT('ACCOUNT_AGENT');

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_AGENT(
    agent_name  => 'ACCOUNT_AGENT',
    description => 'Manages user profile and account information including billing addresses and contact details',
    attributes  => '{
      "profile_name": "{llm_profile}",
      "role": "You are a Profile Management Specialist. Your role is to help users view and update their account information."
    }'
  );
END;
/

exec DBMS_CLOUD_AI_AGENT.DROP_TASK('ACCOUNT_MANAGEMENT_TASK');

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TASK(
    task_name  => 'ACCOUNT_MANAGEMENT_TASK',
    attributes => '{
      "instruction": "Handle user profile management requests. For profile queries, use the check_profile_tool with the user_name. ",
      "tools": ["CHECK_PROFILE_TOOL"]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.CREATE_TEAM(
    team_name  => 'Shared_ACCOUNT_TEAM',
    attributes => '{
      "agents": [
        {
          "name": "ACCOUNT_AGENT",
          "task": "ACCOUNT_MANAGEMENT_TASK"
        }
      ],
      "process": "sequential"
    }'
  );
END;
/

-- grant tool function to ADB_USER2
GRANT EXECUTE ON check_profile TO ADB_USER2;

-- grant_team_access to ADB_USER2
exec DBMS_CLOUD_AI_AGENT.GRANT_TEAM_ACCESS(
  'Shared_ACCOUNT_TEAM',
  'ADB_USER2'
);

conn ADB_USER2/<password>@<connection_name>;

BEGIN
  DBMS_CLOUD_AI.CREATE_PROFILE(
    'GROK_ADB_USER2',
    '{
      "provider": "oci",
      "credential_name": "<GENAI_CRED>",
      "oci_compartment_id": "<ocid1.compartment.oc1..placeholder>",
      "model": "xai.grok-3",
      "conversation": "TRUE"
    }'
  );
END;
/

-- Create user_profiles table
CREATE TABLE user_profiles (
  user_id NUMBER GENERATED ALWAYS AS IDENTITY PRIMARY KEY,
  user_name VARCHAR2(100) NOT NULL UNIQUE,
  email VARCHAR2(100),
  billing_address VARCHAR2(200),
  phone VARCHAR2(20),
  account_status VARCHAR2(20),
  created_date DATE DEFAULT SYSDATE,
  updated_date DATE DEFAULT SYSDATE
);

-- Insert three example rows
INSERT INTO user_profiles (
  user_name,
  email,
  billing_address,
  phone,
  account_status
)
VALUES (
  'john_smith',
  'john.smith@example.com',
  '123 Main St, San Francisco, CA 94102',
  '415-555-0100',
  'ACTIVE'
);

INSERT INTO user_profiles (
  user_name,
  email,
  billing_address,
  phone,
  account_status
)
VALUES (
  'mary_jones',
  'mary.jones@example.com',
  '456 Oak Ave, Austin, TX 78701',
  '512-555-0200',
  'ACTIVE'
);

INSERT INTO user_profiles (
  user_name,
  email,
  billing_address,
  phone,
  account_status
)
VALUES (
  'david_wilson',
  'david.wilson@example.com',
  '789 Pine Rd, Seattle, WA 98101',
  '206-555-0300',
  'ACTIVE'
);

COMMIT;

SQL> DECLARE
  2    l_final_answer    CLOB;
  3    l_conversation_id VARCHAR2(36);
  4  BEGIN
  5    l_conversation_id := DBMS_CLOUD_AI.CREATE_CONVERSATION();
  6
  7    l_final_answer := DBMS_CLOUD_AI_AGENT.RUN_TEAM(
  8      team_name   => 'ADB_USER.Shared_ACCOUNT_TEAM',
  9      user_prompt => 'What is the billing address for john_smith',
 10      params      => '{"attribute_variables":{"llm_profile":"GROK_ADB_USER2"},"conversation_id":"'
 11                     || l_conversation_id || '"}'
 12    );
 13
 14    DBMS_OUTPUT.PUT_LINE(l_final_answer);
 15  END;
 16  /

The billing address for john_smith is 123 Main St, San Francisco, CA 94102.


conn ADB_USER/<password>@<connection_name>

exec DBMS_CLOUD_AI_AGENT.REVOKE_TEAM_ACCESS(
  'Shared_ACCOUNT_TEAM',
  'ADB_USER2'
);

conn ADB_USER2/<password>@<connection_name>;

DECLARE
  l_final_answer    CLOB;
  l_conversation_id VARCHAR2(36);
BEGIN
  l_conversation_id := DBMS_CLOUD_AI.CREATE_CONVERSATION();

  l_final_answer := DBMS_CLOUD_AI_AGENT.RUN_TEAM(
    team_name   => 'ADB_USER.Shared_ACCOUNT_TEAM',
    user_prompt => 'What is the billing address for john_smith',
    params      => '{"attribute_variables":{"llm_profile":"GROK_ADB_USER2"},"conversation_id":"'
                   || l_conversation_id || '"}'
  );

  DBMS_OUTPUT.PUT_LINE(l_final_answer);
END;
/

Exemple : transmission de variables d'exécution à un outil personnalisé

Cet exemple montre comment un outil personnalisé lit un profil AI fourni par le consommateur à partir de state_variables à l'aide de GET_VARIABLE et transmet le profil à DBMS_CLOUD_AI.GENERATE. L'agent utilise également l'espace réservé de variable d'exécution {llm_profile}, qui est résolu à partir de attribute_variables lorsque l'équipe partagée est exécutée.

Le propriétaire de l'équipe, ADB_USER, crée la fonction WEB_SEARCH, WebSearchTool, WebSearchAgent et WebSearchTeam, et accorde à ADB_USER2 l'accès à l'équipe. ADB_USER2 fournit son propre profil AI lors de l'exécution de l'équipe partagée.

L'exemple montre également que SET_TEAM peut définir des variables d'équipe.

Remarque

Remarque : l'exemple utilise des valeurs d'espace réservé pour le scénario présenté. Remplacez ces valeurs par des valeurs appropriées pour votre propre application et votre cas d'emploi.

Avant de commencer

Révision :

A savoir : Utilisez une variable d'état lorsqu'un outil doit transmettre une valeur à un outil ultérieur dans la même exécution d'équipe. La valeur reste disponible tout au long de l'exécution sans modifier la définition de l'équipe partagée.

L'exemple complet est le suivant :

conn ADB_USER/<password>@<connection_name>

exec DBMS_CLOUD_AI_AGENT.drop_team('WebSearchTeam', TRUE);
exec DBMS_CLOUD_AI_AGENT.drop_agent('WebSearchAgent', TRUE);
exec DBMS_CLOUD_AI_AGENT.drop_tool('WebSearchTool', TRUE);

CREATE OR REPLACE FUNCTION websearch(
  user_prompt   IN CLOB
) RETURN CLOB AUTHID CURRENT_USER IS
  l_result        CLOB;
  l_profile_name  VARCHAR2(128);
BEGIN
  l_profile_name := dbms_cloud_ai_agent.get_variable(
    namespace => 'state_variables',
    name      => 'llm_profile'
  );

  l_result := DBMS_CLOUD_AI.generate(
    prompt       => user_prompt,
    profile_name => l_profile_name,
    action       => 'chat'
  );

  RETURN l_result;
EXCEPTION
  WHEN OTHERS THEN
    RETURN 'TOOL_ERROR: ' ||
      REPLACE(REPLACE(SQLERRM, CHR(10), ''), '''', '''''');
END websearch;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name   => 'WebSearchTool',
    attributes  => '{
      "instruction": "Use this tool to answer every user request. Always call the tool before responding.",
      "function": "ADB_USER.WEBSEARCH",
      "tool_inputs": [
        {
          "name": "user_prompt",
          "description": "User question to send to DBMS_CLOUD_AI.generate",
          "mandatory": "true"
        }
      ]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_agent(
    agent_name  => 'WebSearchAgent',
    attributes  => '{
      "profile_name": "{llm_profile}",
      "role": "You are a web search assistant. You must call ADB_USER.WebSearchTool for every prompt and return the tool output.",
      "enable_human_tool": "false",
      "tools": ["WebSearchTool"]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_team(
    team_name   => 'WebSearchTeam',
    attributes  => '{
      "agents": [{"name":"WebSearchAgent"}],
      "process": "sequential"
    }'
  );
END;
/

grant execute on websearch to ADB_USER2;

exec DBMS_CLOUD_AI_AGENT.grant_team_access('WebSearchTeam', 'ADB_USER2');

conn ADB_USER2/<password>@<connection_name>;

set serveroutput on;

DECLARE
  l_final_answer  CLOB;
  l_conversation_id VARCHAR2(128);
BEGIN
  l_conversation_id := DBMS_CLOUD_AI.create_conversation();

  l_final_answer := DBMS_CLOUD_AI_AGENT.run_team(
    team_name   => 'ADB_USER.WebSearchTeam',
    user_prompt => 'What is Oracle Database in one sentence?',
    params      => '{"state_variables": {"llm_profile":"GROK_ADB_USER2"}, "attribute_variables": {"llm_profile":"GROK_ADB_USER2"}, "conversation_id":"' || l_conversation_id || '"}'
  );

  dbms_output.put_line(l_final_answer);
END;
/

Oracle Database is a multi-model database management system produced and marketed by Oracle Corporation, primarily designed for enterprise grid computing and data warehousing.

PL/SQL procedure successfully completed.

-- SET_TEAM can also set the variables

exec dbms_cloud_ai_agent.set_team(team_name => 'ADB_USER.WebSearchTeam', params=> '{"state_variables": {"llm_profile":"INVALID_PROFILE_FOR_STATE_TEST"}, "attribute_variables": {"llm_profile":"GROK_ADB_USER2"}}')

PL/SQL procedure successfully completed.

select ai agent What is Oracle Database in one sentence?;

RESPONSE
--------------------------------------------------------------------------------
Oracle Database is a multi-model database management system produced and markete
d by Oracle Corporation, designed to handle a wide range of data management task
s.

Si la variable d'état n'existe pas, GET_VARIABLE renvoie NULL.

Exemple : transmission de valeurs entre les outils à l'aide de SET_VARIABLE et GET_VARIABLE

Cet exemple montre comment un outil peut stocker une valeur dans state_variables à l'aide de SET_VARIABLE et un outil ultérieur peut extraire cette valeur à l'aide de GET_VARIABLE.

Le propriétaire de l'équipe, ADB_USER, crée les fonctions VERIFY_ACCOUNT_NAME et SUMMARIZE_VERIFIED_ACCOUNT, ainsi que les outils, agents et tâches correspondants. AccountVariableHandoffTeam exécute d'abord la tâche de vérification. L'outil de vérification stocke l'ID de compte vérifié dans state_variables, et l'outil récapitulatif extrait l'ID enregistré pour obtenir et renvoyer les détails du compte.

ADB_USER2 reçoit l'accès à l'équipe partagée et l'exécute à l'aide du nom de l'équipe qualifiée par le propriétaire. Les données de compte sont stockées dans la table ACCOUNT_HANDOFF_ACCOUNTS d'ADB_USER2.

Avant de commencer

Révision :

A savoir : Utilisez SET_TEAM lorsque la même session exécute une équipe partagée à plusieurs reprises avec la même configuration d'exécution. Utilisez RUN_TEAM lorsque vous devez remplacer une valeur pour une exécution spécifique.

L'exemple complet est le suivant :

conn ADB_USER/<password>@<connection_name>

CREATE OR REPLACE FUNCTION verify_account_name(
  account_name IN CLOB
) RETURN CLOB AUTHID CURRENT_USER IS
  l_account_name VARCHAR2(100);
  l_account_id   VARCHAR2(30);
  l_schema_name  VARCHAR2(128);
BEGIN
  l_account_name := TRIM(DBMS_LOB.SUBSTR(account_name, 100, 1));
  l_schema_name := SYS_CONTEXT('USERENV', 'CURRENT_USER');

  EXECUTE IMMEDIATE '
    SELECT account_id
      FROM ' || l_schema_name || '.account_handoff_accounts
     WHERE UPPER(account_name) = UPPER(:1)'
    INTO l_account_id
    USING l_account_name;

  DBMS_CLOUD_AI_AGENT.set_variable(
    namespace => 'state_variables',
    name      => 'verified_account_id',
    value     => l_account_id
  );

  RETURN 'ACCOUNT_VERIFIED=' || l_account_name ||
         ';DETAIL_LOOKUP_READY=TRUE';
EXCEPTION
  WHEN NO_DATA_FOUND THEN
    DBMS_CLOUD_AI_AGENT.set_variable(
      namespace => 'state_variables',
      name      => 'verified_account_id',
      value     => NULL
    );
    RETURN 'ACCOUNT_NOT_FOUND=' || NVL(l_account_name, 'NULL');
  WHEN OTHERS THEN
    RETURN 'TOOL_ERROR: ' ||
      REPLACE(REPLACE(SQLERRM, CHR(10), ''), '''', '''''');
END verify_account_name;
/

CREATE OR REPLACE FUNCTION summarize_verified_account(
  request_context IN CLOB
) RETURN CLOB AUTHID CURRENT_USER IS
  l_account_id_clob CLOB;
  l_account_id_text VARCHAR2(4000);
  l_user_name       VARCHAR2(100);
  l_email           VARCHAR2(100);
  l_billing_address VARCHAR2(200);
  l_phone           VARCHAR2(20);
  l_account_status  VARCHAR2(20);
  l_schema_name     VARCHAR2(128);
BEGIN
  l_account_id_clob := DBMS_CLOUD_AI_AGENT.get_variable(
    namespace => 'state_variables',
    name      => 'verified_account_id'
  );
  l_account_id_text := DBMS_LOB.SUBSTR(l_account_id_clob, 4000, 1);

  IF l_account_id_text IS NULL THEN
    RETURN 'ACCOUNT_SUMMARY_ERROR=NO_VERIFIED_ACCOUNT_ID';
  END IF;

  l_schema_name := SYS_CONTEXT('USERENV', 'CURRENT_USER');

  EXECUTE IMMEDIATE '
    SELECT account_name, email, billing_address, phone, account_status
      FROM ' || l_schema_name || '.account_handoff_accounts
     WHERE account_id = :1'
    INTO l_user_name, l_email, l_billing_address, l_phone, l_account_status
    USING l_account_id_text;

  RETURN 'ACCOUNT_SUMMARY_NAME=' || l_user_name ||
         ';EMAIL=' || NVL(l_email, 'Not set') ||
         ';BILLING_ADDRESS=' || NVL(l_billing_address, 'Not set') ||
         ';PHONE=' || NVL(l_phone, 'Not set') ||
         ';ACCOUNT_STATUS=' || NVL(l_account_status, 'Unknown');
EXCEPTION
  WHEN OTHERS THEN
    RETURN 'TOOL_ERROR: ' ||
      REPLACE(REPLACE(SQLERRM, CHR(10), ''), '''', '''''');
END summarize_verified_account;
/

grant execute on verify_account_name to ADB_USER2;
grant execute on summarize_verified_account to ADB_USER2;

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name   => 'AccountVerificationTool',
    attributes  => '{
      "instruction": "Verify that the account name exists.",
      "function": "ADB_USER.VERIFY_ACCOUNT_NAME",
      "tool_inputs": [
        {
          "name": "account_name",
          "description": "Account user name to verify",
          "mandatory": "true"
        }
      ]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_tool(
    tool_name   => 'AccountSummaryTool',
    attributes  => '{
      "instruction": "Summarize the matching account details.",
      "function": "ADB_USER.SUMMARIZE_VERIFIED_ACCOUNT",
      "tool_inputs": [
        {
          "name": "request_context",
          "description": "User request context",
          "mandatory": "true"
        }
      ]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_agent(
    agent_name  => 'AccountVerificationAgent',
    attributes  => '{
      "profile_name": "{llm_profile}",
      "role": "You verify account names. Always call AccountVerificationTool first and return its exact output.",
      "enable_human_tool": "false"
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_agent(
    agent_name  => 'AccountSummaryAgent',
    attributes  => '{
      "profile_name": "{llm_profile}",
      "role": "You summarize the verified account. Always call AccountSummaryTool and return its exact output.",
      "enable_human_tool": "false"
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_task(
    task_name   => 'AccountVerificationTask',
    attributes  => '{
      "instruction": "Call AccountVerificationTool with the exact account name from the user request. The tool saves the account id in state_variables, but the response must not include the id.",
      "tools": ["AccountVerificationTool"]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_task(
    task_name   => 'AccountSummaryTask',
    attributes  => '{
      "instruction": "Call AccountSummaryTool to read the saved account id and summarize the account details. Return the exact tool output.",
      "tools": ["AccountSummaryTool"]
    }'
  );
END;
/

BEGIN
  DBMS_CLOUD_AI_AGENT.create_team(
    team_name   => 'AccountVariableHandoffTeam',
    attributes  => '{
      "agents": [
        {"name":"AccountVerificationAgent","task":"AccountVerificationTask"},
        {"name":"AccountSummaryAgent","task":"AccountSummaryTask"}
      ],
      "process": "sequential"
    }'
  );
END;
/

exec DBMS_CLOUD_AI_AGENT.grant_team_access('AccountVariableHandoffTeam', 'ADB_USER2');

conn ADB_USER2/<password>@<connection_name>;

set serveroutput on;

BEGIN
  EXECUTE IMMEDIATE 'DROP TABLE account_handoff_accounts PURGE';
EXCEPTION
  WHEN OTHERS THEN
    IF SQLCODE != -942 THEN
      RAISE;
    END IF;
END;
/

CREATE TABLE account_handoff_accounts (
  account_id      VARCHAR2(30) PRIMARY KEY,
  account_name    VARCHAR2(100) NOT NULL UNIQUE,
  email           VARCHAR2(100),
  billing_address VARCHAR2(200),
  phone           VARCHAR2(20),
  account_status  VARCHAR2(20)
);

INSERT INTO account_handoff_accounts (
  account_id, account_name, email, billing_address, phone, account_status)
VALUES (
  'ACCT_MARY_0002',
  'mary_jones',
  'mary.jones@example.com',
  '456 Oak Ave, Austin, TX 78701',
  '512-555-0200',
  'ACTIVE');

COMMIT;

DECLARE
  l_final_answer    CLOB;
  l_conversation_id VARCHAR2(128);
BEGIN
  l_conversation_id := DBMS_CLOUD_AI.create_conversation();

  l_final_answer := DBMS_CLOUD_AI_AGENT.run_team(
    team_name   => 'ADB_USER.AccountVariableHandoffTeam',
    user_prompt => 'Verify account mary_jones. Then summarize the verified account details using the saved account id.',
    params      => '{"attribute_variables": {"llm_profile":"GROK_ADB_USER2"},"conversation_id":"' || l_conversation_id || '"}'
  );

  dbms_output.put_line(l_final_answer);
END;
/

Si une valeur est fournie à la fois dans les paramètres SET_TEAM et RUN_TEAM, la valeur transmise à RUN_TEAM est prioritaire pour cette exécution.

Exemple : Révoquer l'accès à une équipe partagée

Révoquez l'accès lorsqu'un utilisateur ou un rôle de base de données ne doit plus exécuter d'équipe partagée. Le schéma propriétaire détient et gère la définition d'équipe qui reste détenue et gérée par le schéma propriétaire.

Avant de commencer

Révision :

L'exemple complet est le suivant :

BEGIN
 DBMS_CLOUD_AI_AGENT.REVOKE_TEAM_ACCESS(
 team_name => 'SHARED_ACCOUNT_TEAM',
 user_or_role_name => 'ADB_USER2');
END;
/