Generative AI Series
Prompt Engineering: Chain of thought and ReAct — SQL Agent
Implement Langchain agents to accomplish traditional transaction processing using LLM, to demonstrate ReAct Prompt Engineering technique
This blog will go through the Chain of Thought and ReAct Prompt Engineering techniques to guide the LLM to think with reasoning and act. We will also build an agent in Langchain to perform traditional transactions using SQL.
Prompt Engineering
Prompt engineering involves crafting carefully tailored input to language models to elicit desired responses. It’s a nuanced process that requires a deep understanding of the model’s capabilities and limitations. By refining prompts, engineers can guide models to produce more accurate, relevant, and creative outputs. Effective prompt engineering goes beyond mere manipulation of keywords. It involves providing context, setting the tone, and specifying the desired outcome.
While zero-short prompting is excellent for basic tasks, few-shot prompting allows the model to leverage pre-trained knowledge for more accurate responses. However, few-shot prompting falls short in tasks involving arithmetic, common sense, and symbolic reasoning.
To address the limitations of few-shot prompting, we use techniques such as “Chain of Thought” prompting. This method guides the language model through a step-by-step reasoning process by providing a few examples outlining the logic. This approach significantly improves the model’s performance on complex tasks, encouraging it to explain its reasoning along with the response.
Chain of Thought
The Chain of Thought is one of the most effective prompt engineering techniques, that takes prompt engineering to a new level by leveraging the natural progression of ideas. Instead of providing a static prompt, this method involves crafting a series of prompts that build upon each other. The idea is to guide the model through a chain of related thoughts, encouraging it to explore and expand on concepts coherently.
Chain of thought prompting helps in providing reasoning capabilities as you go through step by step process of observing the response, and building on top of it. Chain of Thought prompting involves guiding the model through sequential reasoning, much like a human thought process.
Despite the effectiveness of Chain of Thought prompting, there’s an issue with naive greedy decoding, where the model generates responses one sentence at a time without considering the overall coherence.
Self-consistency prompting is a technique that calls the language model multiple times on the same prompt, selecting the most consistent answer. This helps overcome issues related to arithmetic and common sense reasoning. This enhancement generates multiple reasoning paths for a problem, aggregating them to find the most consistent answer.
LangChain handles the complexity of different prompt modifiers, making the process entirely unsupervised. Self-consistency boosts response accuracy without requiring additional human input or models.
You can read more about the chain of thought prompting here.
Reasoning and Action Prompting Technique
ReAct. Short for “synergizing reasoning and acting,” ReAct builds on the concepts of Chain of Thought prompting techniques and is an even more powerful tool that aids Foundation models in tackling user-requested tasks.
ReAct is a reasoning technique designed to structure problems and guide Foundation models through a sequence of steps to arrive at a solution. The process involves three key elements: Thought, Action, and Observation.
- Thought: The reasoning step, or thought, serves as a guide to the Foundation model, demonstrating how to approach a problem. It involves formulating a sequence of questions that lead the model to the desired solution.
- Action: Once the thought is established, the next step is to define an action for the Foundation model to take. This action typically involves invoking an API from a predefined set, allowing the model to interact with external resources.
- Observation: Following the action, the model observes and analyzes the results. The observations become crucial input for further reasoning and decision-making.
To illustrate the practical application of React. The following is an example of how React works on chatGPT.
This may not be the perfect prompts :-D Please feel free to correct me if I am not using the right prompt.
But I think, you get the idea, of how ReAct technique
1. Considers overall coherence to prevent illogical responses.
2. Encourages diverse reasoning paths, ensuring alternative perspectives are thoroughly explored
3. Implements self-consistency prompting, calling the model multiple times on the same prompt for a consistent answer.
You can read more about ReAct here
Langchain allows us to integrate our tools, to build agents. These tools could be fetching more information, that might be useful to enhance the context.
Implementing a Langchain Agent to see ReAct in action
Let now implement this using Langchain, and implement an SQL agent, to demonstrate how reasoning is used to act and find the right response for the query. This is another implementation of Text2SQL. (you can read my blog on how we implement RAG based approach).
Let's get started…Let's first configure our local Postgres database
I have installed Postgres on my MacBook and created 2 tables.
product_master
: Where I store the product_id and the name of the product.inventor
: where I use the product_id and store the inventory of that product.
The following screenshots show the schema and the data that I inserted
Let's now create a requirements.txt
with all the dependent libraries that we need for this project.
langchain
openai
streamlit
python-dotenv
psycopg2
langchain_openai
The key libraries here other than llama-index
are sqlalchemy
, which is the Python SQL toolkit, and psycopg2
, which is the adapter we will be using to connect to Postgres.
Let’s set the environment variables in .env
file. In the env file, we provide the OPENAI_API_KEY and the database variables, as shown below
OPENAI_API_KEY=<<YourOPENAI key>>
DB_USER=orderadmin
DB_PASSWORD=orderadmin
DB_HOST=localhost
DB_NAME=postgres
Lets now walk through the application code
We are importing the standard libraries. I just want to call you create_sql_agent
. This is used to create the SQL Agent that will perform the ReAct. You can read more about that here. AgentExecutor is another important class, which provides the runtime for the agents. Please go through Agents and concepts here.
In the code above, we initiate the connection to the database and set up the necessary database parameters. Subsequently, we pass this information to the SQL agent, along with the Language Model (LLM). The agent utilizes these details to conduct reasoning, interacting with the database as required. The functionality is demonstrated in the accompanying video attached below.
In the provided code snippet, a method is being defined to invoke the agent using a specified prompt. Subsequently, in the subsequent code, we are developing a Streamlit chatbot application. This application utilizes the callAgent()
method to handle all the prompts supplied by the user.
In the above code, We are creating a streamlit application, with a chat kind of interface. We will be storing the message in the st.session_state
, and this will be printed in the main window as a chat. We are capturing the prompt that is given in the st.chat_input()
and calling the chat_engine()
that we created. LlamaIndex provides a convenient function to create a chat engine with the index that is created. This takes care of all the complexity of doing the RAG, and calling the appropriate LLM to get the response.
The following video shows the output.
There you go… you can see in the video and the screenshots how the agent can observe the results, apply reasoning, and act accordingly. This is a very powerful technique that agents use, to act as intelligent bots to get the job done. I will be going deeper into Agents and Agent orchestration in future blogs…
Conclusion
React proves to be a valuable technique for prompting the Foundation models for more domain-specific tasks. By guiding the model through structured problems, React empowers it to reason and act effectively and is more extensible with the help of integration with other external sources.
I hope this blog was useful, and please leave your feedback and comments. Take care and see you soon with more blogs sharing my experiences...
You can find the code on my GitHub here