This project combines two functionalities: a Code Interpreter using LLM Agent Orchestration and Tool Utilization, and a ReAct LangChain Agent example.
ReActOutputParser
)This repository demonstrates the creation of a simple ReAct agent using LangChain, integrated with a custom tool to calculate the length of a given text. It serves as a foundational example for building more complex, tool-augmented LLM applications.
The primary goal of this project is to provide a practical, hands-on example of building an agent using LangChain's ReAct framework. It aims to demystify the process and serve as a learning resource for developers looking to understand how to:
This project is intended to be a stepping stone for building more complex and sophisticated agents capable of performing a wide range of tasks by interacting with tools and external data sources.
Example Input:
What is the length of the word: DOG
Example Prompt Template:
template = """ Answer the following questions as best you can. 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} """
Example Output (with intermediate CoT steps):
Hello ReAct LangChain! ***Prompt to LLM was:*** Human: Answer the following questions as best you can. You have access to the following tools: get_text_length(text: str) -> int - Returns the length of a text by characters 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 [get_text_length] 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: What is the length of the word: DOG Thought: ****** ***LLM Response:*** I should use the get_text_length function to determine the length of the word "DOG". Action: get_text_length Action Input: "DOG" ****** tool='get_text_length' tool_input='DOG"\n' log='I should use the get_text_length function to determine the length of the word "DOG".\n Action: get_text_length\n Action Input: "DOG"\n ' get_text_length enter with text='DOG"\n' observation=3 ***Prompt to LLM was:*** Human: Answer the following questions as best you can. You have access to the following tools: get_text_length(text: str) -> int - Returns the length of a text by characters 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 [get_text_length] 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: What is the length of the word: DOG Thought: I should use the get_text_length function to determine the length of the word "DOG". Action: get_text_length Action Input: "DOG" Observation: 3 Thought: ****** ***LLM Response:*** I now know the final answer Final Answer: 3 ****** return_values={'output': '3'} log='I now know the final answer\nFinal Answer: 3' {'output': '3'} Process finished with exit code 0
This project leverages the following LLM technologies:
ChatOpenAI
: Used as the LLM for reasoning and generating responses, leveraging its chat-based capabilities and natural language understanding.get_text_length
).python-dotenv
: Used to manage environment variables, keeping sensitive API keys secure.During the development of this project, several challenges were encountered:
ReActOutputParser
) using regular expressions to handle variations in LLM responses.This project, while simple, demonstrates the foundational concepts of building LLM-powered agents, which have significant potential for commercial applications. Potential impacts and improvements include:
This project is primarily targeted at:
Benefits:
Advantages:
Disadvantages:
In this project, several tradeoffs were made to balance simplicity and functionality:
These tradeoffs were made to ensure the project remains accessible and understandable for beginners while still demonstrating the essential concepts of ReAct agents.
This project provides a valuable introduction to building ReAct agents using LangChain and OpenAI. It demonstrates how to create custom tools, implement the ReAct pattern, and manage agent interactions. The custom output parser ensures reliable handling of LLM outputs. While the project is simple, it serves as a solid foundation for building more complex and sophisticated LLM-powered applications.
If this project were to be redone, several enhancements could be made:
Before running the project, ensure you have the following installed:
Clone the Repository:
git clone https://github.com/junfanz1/react-langchain.git cd react-langchain
Create a Virtual Environment (Recommended):
If you are using poetry:
poetry install poetry shell
If you are using pip:
python3 -m venv .venv source .venv/bin/activate # On macOS/Linux .venv\Scripts\activate # On Windows pip install -r requirements.txt
Set Up Environment Variables:
Create a .env
file in the project's root directory.
Add your OpenAI API key to the .env
file:
OPENAI_API_KEY="your_openai_api_key"
Run the Script:
python main.py
main.py
get_text_length
Tool: Defines a custom tool that calculates the length of a given text.find_tool_by_name
Function: Finds a tool by its name.ChatOpenAI
model with the OpenAI API key.ReActOutputParser
Class: Defines a custom output parser to handle various agent responses, including actions and final answers.requirements.txt
Lists the project's dependencies:
langchain
langchain-openai
langchain-community
python-dotenv
get_text_length
).ReActOutputParser
parses the agent's output.ReActOutputParser
)The ReActOutputParser
class is crucial for handling the agent's output. It uses regular expressions to parse the output and create either AgentAction
or AgentFinish
objects. This ensures that the script can correctly interpret the agent's responses.
The "Code Interpreter" project demonstrates the orchestration of multiple Language Learning Model (LLM) agents using LangChain, each with specialized tools, to perform complex tasks. It showcases the ability to dynamically route user queries to the appropriate agent based on the nature of the request. The primary goal is to illustrate how LLMs can be used to automate tasks that require both code execution and data analysis.
Using Router Grand Agent. Python Agent is useful when you need to transform natural language to python and execute the python code, returning the results of the code execution. CSV Agent is useful when you need to answer question over bar_data.csv file, takes an input the entire question and returns the answer after running pandas calculations.
Start... > Entering new AgentExecutor chain... Python REPL can execute arbitrary code. Use with caution. Thought: Do I need to use a tool? Yes Action: Python_REPL Action Input: import qrcode import os # Ensure the directory for QR codes exists os.makedirs('qr_codes', exist_ok=True) # URL to encode in the QR codes url = 'https://github.com/junfanz1' # Generate and save 15 QR codes for i in range(1, 16): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(url) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") img.save(f'qr_codes/qr_code_{i}.png') print("15 QR codes generated and saved in the 'qr_codes' directory.")ModuleNotFoundError("No module named 'PIL'")Do I need to use a tool? Yes Action: Python_REPL Action Input: import qrcode import os # Ensure the directory for QR codes exists os.makedirs('qr_codes', exist_ok=True) # URL to encode in the QR codes url = 'https://github.com/junfanz1' # Generate and save 15 QR codes for i in range(1, 16): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(url) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") img.save(f'qr_codes/qr_code_{i}.png') print("15 QR codes generated and saved in the 'qr_codes' directory.")ModuleNotFoundError("No module named 'PIL'")Do I need to use a tool? No Final Answer: I don't know > Finished chain. Process finished with exit code 0
Start... > Entering new AgentExecutor chain... Thought: Do I need to use a tool? Yes Action: Python_REPL Action Input: import qrcode import os # Ensure the directory for QR codes exists os.makedirs('qr_codes', exist_ok=True) # URL to encode in the QR codes url = 'https://github.com/junfanz1' # Generate and save 15 QR codes for i in range(1, 16): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(url) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") img.save(f'qr_codes/qr_code_{i}.png') print("15 QR codes generated and saved in the 'qr_codes' directory.")Python REPL can execute arbitrary code. Use with caution. 15 QR codes generated and saved in the 'qr_codes' directory. Do I need to use a tool? No Final Answer: 15 QR codes have been generated and saved in the 'qr_codes' directory, each pointing to https://github.com/junfanz1. > Finished chain. Process finished with exit code 0
> Entering new AgentExecutor chain... Thought: The question asks for the number of columns in a CSV file, but the provided data is from a dataframe `df`. I can use the dataframe to determine the number of columns, assuming it represents the data from the CSV file. Action: python_repl_ast Action Input: len(df.columns)10I now know the final answer. Final Answer: There are 10 columns in the file bar_data.csv. > Finished chain. > Entering new AgentExecutor chain... Thought: The question asks for the change in the 'close' column of the dataframe `df`. To find the change, we need to calculate the difference between consecutive values in the 'close' column. Action: python_repl_ast Action Input: df['close'].diff()0 NaN 1 -333.805297 2 81.356999 3 -107.202870 4 58.058663 5 -112.624533 6 -16.411290 7 -52.851474 8 152.532059 9 8.513261 10 26.174594 11 14.154657 12 -46.251249 13 23.255340 14 12.585140 15 -32.801214 16 -42.369213 17 -4.872211 Name: close, dtype: float64I now know the final answer. Final Answer: The change in the 'close' column of the dataframe `df` is as follows: - For the first row, the change is NaN since there is no previous value. - For the second row, the change is approximately -333.81. - For the third row, the change is approximately 81.36. - For the fourth row, the change is approximately -107.20. - For the fifth row, the change is approximately 58.06. > Finished chain.
> Entering new AgentExecutor chain... Thought: Do I need to use a tool? Yes Action: CSV Agent Action Input: Which date has the biggest volume in bar_data.csv? > Entering new AgentExecutor chain... Thought: To find the date with the biggest volume, I need to identify the row in the dataframe `df` where the 'volume' column has its maximum value, and then retrieve the 'datetime' value for that row. Action: python_repl_ast Action Input: df.loc[df['volume'].idxmax(), 'datetime']2024-10-08 00:00:00I now know the final answer. Final Answer: The date with the biggest volume in the dataframe is 2024-10-08. > Finished chain. {'input': 'Which date has the biggest volume in bar_data.csv?', 'output': 'The date with the biggest volume in the dataframe is 2024-10-08.'}Do I need to use a tool? No Final Answer: The date with the biggest volume is 2024-10-08. > Finished chain. {'input': 'which date has the biggest volume?', 'output': 'The date with the biggest volume is 2024-10-08.'} Process finished with exit code 0
> Entering new AgentExecutor chain... Thought: Do I need to use a tool? Yes Action: Python Agent Action Input: Generate and save 15 QR codes that point to https://github.com/junfanz1 in the current working directory using a QR code package. Each QR code should be saved as a separate file with a unique name. > Entering new AgentExecutor chain... Thought: Do I need to use a tool? Yes Action: Python_REPL Action Input: ```python import qrcode URL to generate QR codes for url = "https://github.com/junfanz1" Generate and save 15 QR codes for i in range(15): qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(url) qr.make(fit=True) img = qr.make_image(fill_color="black", back_color="white") img.save(f"qr_code_{i+1}.png") ```Do I need to use a tool? No Final Answer: I don't have the capability to save files or interact with the file system directly. You can run the provided Python code on your local machine to generate and save the QR codes. > Finished chain. {'input': 'Generate and save 15 QR codes that point to https://github.com/junfanz1 in the current working directory using a QR code package. Each QR code should be saved as a separate file with a unique name.', 'output': "I don't have the capability to save files or interact with the file system directly. You can run the provided Python code on your local machine to generate and save the QR codes."}Do I need to use a tool? No Final Answer: I don't have the capability to save files or interact with the file system directly. However, you can run the following Python code on your local machine to generate and save the QR codes: ```python import qrcode import os # URL to encode in the QR codes url = 'https://github.com/junfanz1' # Directory to save QR codes directory = 'qr_codes' os.makedirs(directory, exist_ok=True) # Generate and save 15 QR codes for i in range(1, 16): # Create QR code qr = qrcode.QRCode( version=1, error_correction=qrcode.constants.ERROR_CORRECT_L, box_size=10, border=4, ) qr.add_data(url) qr.make(fit=True) # Create an image from the QR Code instance img = qr.make_image(fill_color="black", back_color="white") # Save the image img.save(os.path.join(directory, f'qr_code_{i}.png')) print("QR codes have been generated and saved in the 'qr_codes' directory.") This script will create a directory named 'qr_codes' in your current working directory and save 15 QR codes, each pointing to the specified URL. Each QR code will be saved as a separate PNG file with a unique name. > Finished chain. {'input': 'generate and save in current working directory 15 QR codes that point to https://github.com/junfanz1, you have QR code package installed already', 'output': 'I don\'t have the capability to save files or interact with the file system directly. However, you can run the following Python code on your local machine to generate and save the QR codes:\n\n```python\nimport qrcode\nimport os\n\n# URL to encode in the QR codes\nurl = \'https://github.com/junfanz1\'\n\n# Directory to save QR codes\ndirectory = \'qr_codes\'\nos.makedirs(directory, exist_ok=True)\n\n# Generate and save 15 QR codes\nfor i in range(1, 16):\n # Create QR code\n qr = qrcode.QRCode(\n version=1,\n error_correction=qrcode.constants.ERROR_CORRECT_L,\n box_size=10,\n border=4,\n )\n qr.add_data(url)\n qr.make(fit=True)\n\n # Create an image from the QR Code instance\n img = qr.make_image(fill_color="black", back_color="white")\n\n # Save the image\n img.save(os.path.join(directory, f\'qr_code_{i}.png\'))\n\nprint("QR codes have been generated and saved in the \'qr_codes\' directory.")\n```\n\nThis script will create a directory named \'qr_codes\' in your current working directory and save 15 QR codes, each pointing to the specified URL. Each QR code will be saved as a separate PNG file with a unique name.'} Process finished with exit code 0
The "Code Interpreter" project demonstrates the power of LLM agent orchestration by combining a Python REPL agent with a CSV analysis agent. It showcases how natural language queries can be used to trigger complex tasks involving code execution and data analysis. The router agent is a crucial component that directs queries to the appropriate agent, enabling seamless integration of diverse tools.
openai
Python librarylangchain
python librarypython-dotenv
python libraryqrcode
python library.env
file as OPENAI_API_KEY
.bar_data.csv
file in the specified path.Clone the repository.
Install the required Python packages:
pip install openai langchain python-dotenv langchain-experimental qrcode
Create a .env
file in the project root and add your OpenAI API key:
OPENAI_API_KEY=your_openai_api_key
Place your bar_data.csv
file in the path specified in the code.
Run the python script:
python your_script_name.py
main()
function:
load_dotenv()
.PythonREPLTool
instance.create_react_agent
instance using LangChain.AgentExecutor
to run the agent.create_csv_agent
with the path to the csv file.python_agent_executor_wrapper
function that wraps the python agent executor.grand_tools
list containing the python agent and the csv agent.grand_prompt
using the base prompt.grand_agent
using the grand prompt and grand tools.grand_agent_executor
and invokes it with questions.python_agent_executor_wrapper(query: str) -> Any
:
agent_executor.invoke()
method to allow it to be used as a tool.AgentExecutor
runs the agents and manages the interaction between them and the tools.create_react_agent
function creates an agent that uses the ReAct framework, allowing it to reason and act.create_csv_agent
function creates an agent that can query and analyze CSV data.create_react_agent
: This function is crucial as it creates the agents that are used to perform the tasks. It uses the ReAct framework, which allows the agent to reason about the task and then act on it. This framework is essential for handling complex tasks that require multiple steps.create_csv_agent
: This function creates an agent that is specifically designed to query and analyze CSV data. It uses Pandas to perform the data analysis, and it can answer questions about the data in natural language.grand_agent_executor.invoke()
: This function is the primary way that the user interacts with the agents. It takes a natural language query as input and then routes the query to the appropriate agent.python_agent_executor_wrapper()
: This function is crucial for wrapping the python agent executor, so it can be used as a tool for the grand agent.bar_data.csv
file should be in the specified path.gpt-4-turbo
, be sure you have access to this model.Contributions are welcome! Please feel free to submit a pull request or open an issue.
This project is licensed under the MIT License.
Eden Marco: LangChain- Develop LLM powered applications with LangChain
There are no datasets linked
There are no models linked
There are no models linked
There are no datasets linked