Agent IA

Traduit de l'original en espagnol. Lire en espagnol

Dans ce tutoriel, nous allons apprendre à créer un agent d’intelligence artificielle (IA) capable de répondre à des questions à l’aide d’Active Directory et d’une base de connaissances (KB). Nous utiliserons LangChain et Azure pour cela.

iStock AI Generator

Les agents

L’idée principale des agents est d’utiliser un modèle de langage pour choisir une séquence d’actions à effectuer. Dans les chaînes, la séquence d’actions est prédéfinie (dans le code). Dans les agents, un modèle de langage sert de moteur de raisonnement pour décider quelles actions entreprendre et dans quel ordre.

Configuration de l’environnement

Avant de commencer, nous devons définir quelques variables d’environnement et obtenir un token d’accès Azure. Pour cela, placez un fichier .env dans le même répertoire avec les informations suivantes :

AZURE_TENANT_ID = "00000000-0000-0000-0000-000000000000"
AZURE_CLIENT_ID = "00000000-0000-0000-0000-000000000000"
AZURE_CLIENT_SECRET = "xxxxx"

Une fois le fichier .env en place, nous ajouterons le code nécessaire pour obtenir le token.

import os
from azure.identity import ChainedTokenCredential, EnvironmentCredential
from dotenv import load_dotenv
load_dotenv()

credential = ChainedTokenCredential(EnvironmentCredential())
access_token = credential.get_token("https://cognitiveservices.azure.com/.default")

Configuration du modèle et des variables d’environnement

Ensuite, nous allons configurer le modèle Azure OpenAI et définir les variables d’environnement nécessaires.

os.environ["AZURE_OPENAI_ENDPOINT"] = "https://zerogap.openai.azure.com/"
os.environ["AZURE_OPENAI_API_KEY"] = access_token.token
os.environ["OPENAI_API_TYPE"] = "azure_ad"
os.environ["OPENAI_DEPLOYMENT"] = "zerogap-openai-ue2-gpt4-turbo"

Initialisation des outils d’IA

Nous allons initialiser le modèle de conversation Azure OpenAI, la classe AzureOpenAIEmbeddings et le modèle d’embeddings.

from langchain.chat_models import AzureChatOpenAI
from langchain.embeddings import AzureOpenAIEmbeddings

llm = AzureChatOpenAI(openai_api_version="2023-07-01-preview", azure_deployment="zerogap-openai-ue2-gpt4-turbo", temperature=0.5)

embeddings = AzureOpenAIEmbeddings(
    azure_deployment="zerogap-openai-ue2-ada",
    openai_api_version="2023-07-01-preview",
    chunk_size=1000
)

Configuration de la base vectorielle et du retriever

Nous allons charger les documents depuis le répertoire persistant, en supposant que la KB est déjà chargée dans une base de données vectorielle (plus d’informations ici : QA AI Bot avec un LLM local et des documents – The Zero Gap Zone).

from langchain.vectorstores import Chroma

persist_directory = "chroma_db_generic"
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embeddings)
vectordb.get()

retriever = vectordb.as_retriever(search_type="similarity", search_kwargs={"k": 5})

Outils pour interagir avec Active Directory et la base de connaissances

Créer des outils pour interagir avec Active Directory et obtenir des informations de la base de connaissances.

import subprocess
from langchain.tools import Tool

def get_ad_user(search_query):
    ps_command = f'get-aduser -Filter {{Name -like "*{search_query}*"}} -Properties Office, OfficePhone | Select-Object Name, Office, OfficePhone'
    result = subprocess.run(["powershell", ps_command], capture_output=True, text=True)
    return result.stdout

run_ad_tool = Tool.from_function(
    name="get_ad_user",
    description="Get user information from Active Directory",
    func=get_ad_user
)

def get_kb(question):
    context = retriever.invoke(question)
    formated_context = format_docs(context)
    return formated_context

run_kb_tool = Tool.from_function(
    name="get_kb",
    description="Get information from the Knowledge Base",
    func=get_kb
)

tools = [run_ad_tool, run_kb_tool]

Création et exécution de l’agent IA

Nous allons définir un modèle de prompt et la fonction qui exécute l’agent.

from langchain.agents import AgentExecutor, create_react_agent
from langchain.prompts import PromptTemplate

react_prompt = PromptTemplate.from_template("""
You are an assistant for question-answering tasks. Follow these instructions step by step:

1. If the question is about a person, try to get more information from Active Directory.
2. If the question is not about a person, try to get more information from your Knowledge Base
3. If you can not find the answer, respond with 'Sorry, I do not know'

These are examples:

Example 1:
Question: Who is John Doe?
Thought: The question is about a person, I should use the Active Directory tool.
Action: get_ad_user
Action Input: John Doe
Observation: The get_ad_user tool indicates John Doe is an Actor in Friends.
Thought: I now have the final answer.
Final Answer: John Doe is an Actor in the TV Show Friends.

Example 2:
Question: What is a transistor?
Thought: The question is not about a person, I need to use the Knowledge Base tool.
Action: get_kb
Action Input: What is a transistor?
Observation: A transistor is a semiconductor device used to amplify or switch electrical signals and power. It is one of the basic building blocks of modern electronics.
Thought: I now have the final answer.
Final Answer: A transistor is a semiconductor device used to amplify or switch electrical signals and power. It is one of the basic building blocks of modern electronics

You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}
""")

def run_agent(question):
    agent = create_react_agent(
        llm=llm,
        prompt=react_prompt,
        tools=tools
    )
    agent_executor = AgentExecutor(
        agent=agent,
        verbose=True,
        tools=tools
    )

    response = agent_executor.invoke({"input": question})

    return response

Interaction avec l’agent IA

Enfin, nous allons créer une boucle pour interagir avec l’agent IA et obtenir des réponses à nos questions.

print("\033[92m" + "Welcome to the ZEROGAP AI QA Bot!" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\n")
while True:
    question = input("\033[93m" + "You: " + "\033[0m")
    print("\n")
    if question == "quit":
        break
    result = run_agent(question)
    print("\033[92m" + result + "\033[0m")
    print("\n")

Code complet

Voici le code complet de l’agent IA que nous avons développé dans ce tutoriel :

import os, subprocess
from azure.identity import ChainedTokenCredential, EnvironmentCredential
from langchain.vectorstores import Chroma
from langchain.embeddings import AzureOpenAIEmbeddings
from langchain.chat_models import AzureChatOpenAI
from langchain.tools import Tool
from langchain.agents import AgentExecutor, create_react_agent
from langchain.prompts import PromptTemplate
from dotenv import load_dotenv
load_dotenv()

# Place a .env file within the same folder with the following information:
# AZURE_TENANT_ID = "00000000-0000-0000-0000-000000000000"
# AZURE_CLIENT_ID = "00000000-0000-0000-0000-000000000000"
# AZURE_CLIENT_SECRET = "xxxxx"

credential = ChainedTokenCredential(EnvironmentCredential())
access_token = credential.get_token("https://cognitiveservices.azure.com/.default")

# Model
deployment = "zerogap-openai-ue2-gpt4-turbo"
# Model text-embedding-ada-002
embedding_deployment = "zerogap-openai-ue2-ada"

# Set OS environment variables
os.environ["AZURE_OPENAI_ENDPOINT"] = "https://zerogap.openai.azure.com/"
os.environ["AZURE_OPENAI_API_KEY"] = access_token.token
os.environ["OPENAI_API_TYPE"] = "azure_ad"
os.environ["OPENAI_DEPLOYMENT"] = deployment

llm = AzureChatOpenAI(openai_api_version="2023-07-01-preview", azure_deployment=deployment, temperature=0.5)

# Initialize the OpenAIEmbeddings class
embeddings = AzureOpenAIEmbeddings(
    azure_deployment=embedding_deployment,
    openai_api_version="2023-07-01-preview",
    chunk_size=1000
)

# Load documents from the persisted directory
# Assuming you already have the KB loaded to a vector database
persist_directory = "chroma_db_generic"
vectordb = Chroma(persist_directory=persist_directory, embedding_function=embeddings)
vectordb.get()

retriever = vectordb.as_retriever(search_type="similarity", search_kwargs={"k": 5})

# Join all the documents from the retriever together with newlines
def format_docs(docs):
    if docs:
        return "\n\n".join(doc.page_content for doc in docs)

# Function to get AD user
def get_ad_user(search_query):
    # Run the PowerShell command to retrieve user information including the specified attributes
    ps_command = f'get-aduser -Filter {{Name -like "*{search_query}*"}} -Properties Office, OfficePhone | Select-Object Name, Office, OfficePhone'
    result = subprocess.run(["powershell", ps_command], capture_output=True, text=True)
    # Return the output
    return result.stdout

run_ad_tool = Tool.from_function(
    name="get_ad_user",
    description="Get user information from Active Directory",
    func=get_ad_user
)

def get_kb(question):
    # Queries the Vector DB using user's question
    context = retriever.invoke(question)
    formated_context = format_docs(context)
    return formated_context

run_kb_tool = Tool.from_funcion(
    name="get_kb",
    description="Get information from the Knowledge Base",
    func=get_kb
)

tools = [run_ad_tool,run_kb_tool]

tool_names = [tool.name for tool in tools]

react_prompt = PromptTemplate.from_template("""
You are an assistant for question-answering tasks. Follow these instructions step by step:

1. If the question is about a person, try to get more information from Active Directory.
2. If the question is not about a person, try to get more information from your Knowledge Base
3. If you can not find the answer, respond with 'Sorry, I do not know'

These are examples:

Example 1:
Question: Who is John Doe?
Thought: The question is about a person, I should use the Active Directory tool.
Action: get_ad_user
Action Input: John Doe
Observation: The get_ad_user tool indicates John Doe is an Actor in Friends.
Thought: I now have the final answer.
Final Answer: John Doe is an Actor in the TV Show Friends.

Example 2:
Question: What is a transistor?
Thought: The question is not about a person, I need to use the Knowledge Base tool.
Action: get_kb
Action Input: What is a transistor?
Observation: A transistor is a semiconductor device used to amplify or switch electrical signals and power. It is one of the basic building blocks of modern electronics.
Thought: I now have the final answer.
Final Answer: A transistor is a semiconductor device used to amplify or switch electrical signals and power. It is one of the basic building blocks of modern electronics

You have access to the following tools:

{tools}

Use the following format:

Question: the input question you must answer
Thought: you should always think about what to do
Action: the action to take, should be one of [{tool_names}]
Action Input: the input to the action
Observation: the result of the action
... (this Thought/Action/Action Input/Observation can repeat N times)
Thought: I now know the final answer
Final Answer: the final answer to the original input question

Begin!

Question: {input}
Thought:{agent_scratchpad}
""")

def run_agent(question):
    agent = create_react_agent(
        llm=llm,
        prompt=react_prompt,
        tools=tools
    )
    agent_executor = AgentExecutor(
        agent=agent,
        verbose=True,
        tools=tools
    )

    response = agent_executor.invoke({"input": question})

    return response

# print welcome message in green
print("\033[92m" + "Welcome to the ZEROGAP AI QA Bot!" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\033[92m" + "###############################" + "\033[0m")
print("\n")
while True:
    #input in yellow
    question = input("\033[93m" + "You: " + "\033[0m")
    print("\n")
    if question == "quit":
        break
    result = run_agent(question)
    print("\033[92m" + result + "\033[0m")
    print("\n")

Maximiliano Díaz Doglia

AI Platform Engineer & Full-Stack Developer
Building Enterprise Integrations & Automations

Publié dans : IA