Agentic AI Plan and Execute using LangChain

Nitin SharmaNitin Sharma
7 min read

Agentic AI refers to artificial intelligence systems that possess a degree of autonomy and decision-making capability, allowing them to act independently in specific contexts. Unlike traditional AI, which typically follows predetermined rules and algorithms, Agentic AI can evaluate situations, assess potential outcomes, and make choices based on its understanding of the environment and objectives. This includes the ability to adapt to new information and improve its performance over time.

Agentic AI systems are designed to perform tasks that require a level of judgment and reasoning, effectively enabling them to engage in complex interactions or to solve problems that were not explicitly programmed into them. This concept raises important discussions surrounding ethics, accountability, and the implications of delegating decision-making power to machines, as well as the potential impact on industries such as healthcare, transportation, and robotics.

Plan-and-execute agents utilize a language model (LLM) to develop detailed task plans, which are then carried out by a separate execution agent. This collaborative approach allows for more sophisticated task management, where the LLM generates strategies and instructions while the execution agent focuses on implementing the tasks effectively.

The strategy is composed of two key elements. The first element is a planner, which leverages the reasoning capabilities of large language models (LLMs) to develop a comprehensive plan by outlining specific steps. The second element is an executor, responsible for interpreting the steps outlined by the planner. This executor identifies the essential tools, resources, or actions required to successfully carry out each step of the plan. Together, these components work in harmony to ensure effective execution of tasks.

Develop a comprehensive plan and implement an agent strategy utilizing the LangChain framework. This involves outlining the objectives, defining the role of the agent, selecting appropriate tools and libraries, and executing a series of steps to ensure successful interaction with language models. Additionally, it includes monitoring performance and making adjustments as necessary to optimize outcomes.

The whole work flow is shown below

We will develop this application as a RESTful endpoint using FastAPI, a modern web framework for building APIs with Python. In a previous blog post, I outlined the process of creating and deploying a FastAPI endpoint RAG_CHATBOT, which I recommend checking out for background information.

For handling HTTP requests, we will utilize the popular requests library, which simplifies the process of sending requests and receiving responses. To extract and parse news articles efficiently, we will employ the newspaper package, a powerful tool designed for web scraping and article extraction.

Once we retrieve the articles, we will store them in DeepLake, a vector database optimized for managing embeddings. This method allows us to organize and access the articles in a format that enhances retrieval and analysis, as demonstrated in the accompanying workflow.

Load the libraries

from fastapi import FastAPI
import os
#from langchain.embeddings.openai import OpenAIEmbeddings
from langchain_openai import OpenAIEmbeddings
from langchain_deeplake.vectorstores import DeeplakeVectorStore
from langchain.text_splitter import CharacterTextSplitter, RecursiveCharacterTextSplitter

from langchain_community.document_loaders import SeleniumURLLoader
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.prompts import PromptTemplate
from langchain_openai import ChatOpenAI
import requests
from  newspaper import Article
import time
from langchain_core.tools import Tool
from langchain_experimental.plan_and_execute import PlanAndExecute, load_agent_executor, load_chat_planner

Save the OpenAI and DeepLake keys


os.environ["OPENAI_API_KEY"] = 'Key_Here'
os.environ["ACTIVELOOP_TOKEN"] = 'Key_Here'

After completing the initial setup, the next step is to create the foundational structure for your FastAPI application. This involves establishing the basic framework that will support your API's functionality, including defining the directory structure, setting up configuration files, and initializing the main application instance. This skeleton will serve as the groundwork for implementing endpoints, integrating middleware, and managing dependencies as you develop your project further.

FastAPI

app=FastAPI(
    title="Langchain Server",
    version="1.0",
    decsription="A simple API Server"

)

Now we will write code in below function for agents calling LLM and executing plan and execute pattern.

@app.get("/chat/")
async def root(query:str):
     return {response}

Custom Tool

We will develop a function that defines our custom tool within an agentic AI framework, utilizing Langchain. This function will be designed to efficiently retrieve relevant documents from a Deep Lake database. The database will contain previously fetched, parsed, and saved documents, enabling the AI to access and deliver pertinent information based on user queries or tasks. This process will enhance our AI's ability to provide accurate and contextually relevant responses by leveraging the structured data stored in Deep Lake.


def retrieve_n_docs_tool(query: str,) -> str:
    """Searches for relevant documents that may contain the answer to the query."""
    embeddings=OpenAIEmbeddings(model='text-embedding-ada-002')
    db = DeeplakeVectorStore(dataset_path="./my_deeplake/", embedding_function=embeddings, overwrite=True)
    # Get the retriever object from the deep lake db object and set the number
    # of retrieved documents to 3
    retriever = db.as_retriever()
    retriever.search_kwargs['k'] = 3
    # We define some variables that will be used inside our custom tool
    CUSTOM_TOOL_DOCS_SEPARATOR ="\n---------------\n" # how to join together the retrieved docs to form a single string
    docs = retriever.get_relevant_documents(query)
    texts = [doc.page_content for doc in docs]
    texts_merged = "---------------\n" + CUSTOM_TOOL_DOCS_SEPARATOR.join(texts) + "\n---------------"
    return texts_merged

In the function @app.get("/chat/"), we will implement the code necessary to retrieve content from specified URLs and subsequently store this data in the DeepLake database. To do this, we will first fetch the content from each URL. Next, we will utilize the RecursiveCharacterTextSplitter to divide the retrieved text into manageable chunks. These smaller segments will allow for easier processing and analysis. Finally, we will generate embeddings for each chunk and save them securely in the DeepLake database for future retrieval and use.

 headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36'
    }   

    article_urls = [
        "https://www.artificialintelligence-news.com/2023/05/23/meta-open-source-speech-ai-models-support-over-1100-languages/",
        "https://www.artificialintelligence-news.com/2023/05/18/beijing-launches-campaign-against-ai-generated-misinformation/"
        "https://www.artificialintelligence-news.com/2023/05/16/openai-ceo-ai-regulation-is-essential/",
        "https://www.artificialintelligence-news.com/2023/05/15/jay-migliaccio-ibm-watson-on-leveraging-ai-to-improve-productivity/",
        "https://www.artificialintelligence-news.com/2023/05/15/iurii-milovanov-softserve-how-ai-ml-is-helping-boost-innovation-and-personalisation/",
        "https://www.artificialintelligence-news.com/2023/05/11/ai-and-big-data-expo-north-america-begins-in-less-than-one-week/",
        "https://www.artificialintelligence-news.com/2023/05/11/eu-committees-green-light-ai-act/",
        "https://www.artificialintelligence-news.com/2023/05/09/wozniak-warns-ai-will-power-next-gen-scams/",
        "https://www.artificialintelligence-news.com/2023/05/09/infocepts-ceo-shashank-garg-on-the-da-market-shifts-and-impact-of-ai-on-data-analytics/",
        "https://www.artificialintelligence-news.com/2023/05/02/ai-godfather-warns-dangers-and-quits-google/",
        "https://www.artificialintelligence-news.com/2023/04/28/palantir-demos-how-ai-can-used-military/",
        "https://www.artificialintelligence-news.com/2023/04/26/ftc-chairwoman-no-ai-exemption-to-existing-laws/",
        "https://www.artificialintelligence-news.com/2023/04/24/bill-gates-ai-teaching-kids-literacy-within-18-months/",
        "https://www.artificialintelligence-news.com/2023/04/21/google-creates-new-ai-division-to-challenge-openai/"
    ]

    session=requests.Session()
    pages_content = [] # where we save the scraped articles
    for url in article_urls:
        try:
            time.sleep(2) # sleep two seconds for gentle scraping
            response = session.get(url, headers=headers, timeout=10)

            if response.status_code == 200:
                article = Article(url)
                article.download() # download HTML of webpage
                article.parse() # parse HTML to extract the article text
                pages_content.append({ "url": url, "text": article.text })
            else:
                print(f"Failed to fetch article at {url}")
        except Exception as e:
            print(f"Error occurred while fetching article at {url}: {e}")

    #If an error occurs while fetching an article, we catch the exception and print
    #an error message. This ensures that even if one article fails to download,
    #the rest of the articles can still be processed.


    embeddings=OpenAIEmbeddings(model='text-embedding-ada-002')

    db = DeeplakeVectorStore(dataset_path="./my_deeplake/", embedding_function=embeddings, overwrite=True)

    text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=100)
    all_texts = []
    for d in pages_content:
            chunks = text_splitter.split_text(d["text"])
            for chunk in chunks:
                all_texts.append(chunk)

    ids = db.add_texts(all_texts)

We are developing a tool within the Langchain framework that leverages the "retrieve_n_docs_tool" function. This function is designed to access and extract content stored in the DeepLake database, enabling us to efficiently retrieve and utilize relevant information as needed. By implementing this tool, we aim to streamline the process of accessing our data, ensuring that users can quickly obtain the necessary documents for their tasks.

   tools = [
        Tool(
            name="Search Private Docs",
            func=retrieve_n_docs_tool,
            description="useful for when you need to answer questions about current events about Artificial Intelligence"
        )
    ]

We will create a planning agent and an execution agent tailored to our specific dataset. This involves configuring the agents to effectively interpret and process the data, ensuring they can execute tasks efficiently and accurately

model = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0)

    planner = load_chat_planner(model)
    executor = load_agent_executor(model, tools, verbose=True)
    agent = PlanAndExecute(planner=planner, executor=executor, verbose=True)
    response = agent.run(query)

In browser type url 127.0.0.1:8000/chat/?query=”Write an overview of Artificial Intelligence regulations by governments by country”

Plan gets created with multiple steps by calling LLM


> Entering new PlanAndExecute chain...
steps=[Step(value='Research and gather information on Artificial Intelligence regulations 
by governments in different countries.'), Step(value='Organize the information by country, 
including details such as key regulations, policies, and guidelines related to Artificial 
Intelligence.'), Step(value='Summarize the regulations for each country in a concise 
manner.'), Step(value='Include any recent updates or developments in the field of 
Artificial Intelligence regulations.'), Step(value='Provide a comparison of the regulations
 across different countries, highlighting similarities and differences.'), 
Step(value='Check for any official government sources or reputable publications to verify
 the accuracy of the information.'), Step(value='Compile the overview in a clear and 
structured format for easy understanding.'), Step(value="Review the overview to ensure it is
 comprehensive and up-to-date.\nGiven the above steps taken, please respond to the user's 
original question. \n")]

Each of this steps are executed using our custom tool function we wrote

*****

Step: Research and gather information on Artificial Intelligence regulations by governments in different countries.

Response: I will now search the private documents for information on Artificial Intelligence regulations by governments in different countries to assist the user with their research objective.

> Entering new AgentExecutor chain...
Thought: The user needs assistance in organizing information on Artificial Intelligence regulations by country. I can help by searching the private documents for relevant details on key regulations, policies, and guidelines related to Artificial Intelligence in different countries.

Action:
```
{
  "action": "Search Private Docs",
  "action_input": {"type": "Artificial Intelligence regulations by country"}
}
```

The agent will systematically compile a comprehensive overview of artificial intelligence regulations by analyzing and synthesizing a variety of documents stored in the DeepLake database. This process will involve multiple iterations to ensure that all relevant information is captured and accurately represented, drawing from diverse sources to provide a well-rounded understanding of the current regulatory landscape surrounding AI technology.

0
Subscribe to my newsletter

Read articles from Nitin Sharma directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Nitin Sharma
Nitin Sharma