Agente IA

Tradotto dall'originale in spagnolo. Leggi in spagnolo

In questo tutorial impareremo a creare un Agente di Intelligenza Artificiale (IA) in grado di rispondere alle domande usando Active Directory e una Knowledge Base (KB). Useremo LangChain e Azure.

iStock AI Generator

Agenti

L’idea di fondo degli agenti è usare un modello linguistico per scegliere una sequenza di azioni da eseguire. Nelle chain la sequenza di azioni è predefinita (nel codice). Negli agenti, un modello linguistico funge da motore di ragionamento per decidere quali azioni compiere e in quale ordine.

Configurazione dell’ambiente

Prima di iniziare dobbiamo impostare alcune variabili d’ambiente e ottenere un token di accesso di Azure. Per farlo, metti un file .env nella stessa cartella con le seguenti informazioni:

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

Una volta pronto il file .env, aggiungeremo il codice necessario per ottenere il 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")

Configurazione del modello e delle variabili d’ambiente

Poi configureremo il modello di Azure OpenAI e imposteremo le variabili d’ambiente necessarie.

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"

Inizializzazione degli strumenti di IA

Inizializzeremo il modello di conversazione di Azure OpenAI, la classe AzureOpenAIEmbeddings e il modello di embedding.

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
)

Configurazione del Vector DB e del retriever

Caricheremo i documenti dalla cartella persistente, supponendo che tu abbia già caricato la KB in un database vettoriale (maggiori informazioni qui: QA AI Bot con un LLM locale e documenti – 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})

Strumenti per interagire con Active Directory e la Knowledge Base

Creare strumenti per interagire con Active Directory e ottenere informazioni dalla Knowledge Base.

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]

Creazione ed esecuzione dell’agente IA

Definiremo un template di prompt e la funzione che esegue l’agente.

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

Interazione con l’agente IA

Infine creeremo un ciclo per interagire con l’agente IA e ricevere risposte alle nostre domande.

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

Codice completo

Ecco il codice completo dell’agente IA che abbiamo sviluppato in questo tutorial:

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

Pubblicato in: IA