Skip to content
Snippets Groups Projects
Unverified Commit 9728746f authored by Patrick Miramontes's avatar Patrick Miramontes Committed by GitHub
Browse files

ReActive Agents w/ Context + updated stale link (#10058)

* Added context for agents, updated a stale link in CONTRIBUTING.md, and added a notebook to demo a react agent with context.

* Resolved issues in notebook.

* Fixed typo and added some more comments for kapa

* Added demo notebook to module_guides
parent d7839442
No related branches found
No related tags found
No related merge requests found
......@@ -333,7 +333,7 @@ make test
For changes that involve entirely new features, it may be worth adding an example Jupyter notebook to showcase
this feature.
Example notebooks can be found in this folder: <https://github.com/jerryjliu/llama_index/tree/main/examples>.
Example notebooks can be found in this folder: <https://github.com/run-llama/llama_index/tree/main/docs/examples>.
### Creating a pull request
......
%% Cell type:markdown id:6b0186a4 tags:
<a href="https://colab.research.google.com/github/run-llama/llama_index/blob/main/docs/examples/agent/react_agent_with_query_engine.ipynb" target="_parent"><img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/></a>
%% Cell type:markdown id:b50c4af8-fec3-4396-860a-1322089d76cb tags:
# ReAct Agent with initial context
In this section, we show how to setup an agent powered by the ReAct loop with initial context to aid in tool selection, persona(s), and constraints.
The agent has access to two "tools": one to query the 2021 Lyft 10-K and the other to query the 2021 Uber 10-K.
We try this out with gpt-3.5-turbo.
Note that you can plug in any LLM that exposes a text completion endpoint.
%% Cell type:markdown id:db402a8b-90d6-4e1d-8df6-347c54624f26 tags:
## Build Query Engine Tools
%% Cell type:code id:02160804-64a2-4ef3-8a0d-8c16b06fd205 tags:
``` python
from llama_index import (
SimpleDirectoryReader,
VectorStoreIndex,
StorageContext,
load_index_from_storage,
)
from llama_index.tools import QueryEngineTool, ToolMetadata
```
%% Cell type:code id:91618236-54d3-4783-86b7-7b7554efeed1 tags:
``` python
try:
storage_context = StorageContext.from_defaults(
persist_dir="./storage/lyft"
)
lyft_index = load_index_from_storage(storage_context)
storage_context = StorageContext.from_defaults(
persist_dir="./storage/uber"
)
uber_index = load_index_from_storage(storage_context)
index_loaded = True
except:
index_loaded = False
```
%% Cell type:markdown id:6a79cbc9 tags:
Download Data
%% Cell type:code id:36d80144 tags:
``` python
!mkdir -p 'data/10k/'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/uber_2021.pdf' -O 'data/10k/uber_2021.pdf'
!wget 'https://raw.githubusercontent.com/run-llama/llama_index/main/docs/examples/data/10k/lyft_2021.pdf' -O 'data/10k/lyft_2021.pdf'
```
%% Cell type:code id:d3d0bb8c-16c8-4946-a9d8-59528cf3952a tags:
``` python
if not index_loaded:
# load data
lyft_docs = SimpleDirectoryReader(
input_files=["./data/10k/lyft_2021.pdf"]
).load_data()
uber_docs = SimpleDirectoryReader(
input_files=["./data/10k/uber_2021.pdf"]
).load_data()
# build index
lyft_index = VectorStoreIndex.from_documents(lyft_docs)
uber_index = VectorStoreIndex.from_documents(uber_docs)
# persist index
lyft_index.storage_context.persist(persist_dir="./storage/lyft")
uber_index.storage_context.persist(persist_dir="./storage/uber")
```
%% Cell type:code id:31892898-a2dc-43c8-812a-3442feb2108d tags:
``` python
lyft_engine = lyft_index.as_query_engine(similarity_top_k=3)
uber_engine = uber_index.as_query_engine(similarity_top_k=3)
```
%% Cell type:code id:f9f3158a-7647-4442-8de1-4db80723b4d2 tags:
``` python
query_engine_tools = [
QueryEngineTool(
query_engine=lyft_engine,
metadata=ToolMetadata(
name="lyft_10k",
description=(
"Provides information about Lyft financials for year 2021. "
"Use a detailed plain text question as input to the tool."
),
),
),
QueryEngineTool(
query_engine=uber_engine,
metadata=ToolMetadata(
name="uber_10k",
description=(
"Provides information about Uber financials for year 2021. "
"Use a detailed plain text question as input to the tool."
),
),
),
]
```
%% Cell type:markdown id:275c01b1-8dce-4216-9203-1e961b7fc313 tags:
## Setup ReAct Agent w/ Context
Here we setup two ReAct agents: one powered by standard gpt-3.5-turbo, and the other powered by gpt-3.5-turbo-instruct.
%% Cell type:code id:32f71a46-bdf6-4365-b1f1-e23a0d913a3d tags:
``` python
from llama_index.agent import ReActAgent
from llama_index.llms import OpenAI
```
%% Cell type:code id:9846b70b tags:
``` python
context = """\
You are a stock market sorcerer who is an expert on the companies Lyft and Uber.\
You will answer questions about Uber and Lyft as in the persona of a sorcerer \
and veteran stock market investor.
"""
```
%% Cell type:code id:ded93297-fee8-4329-bf37-cf77e87621ae tags:
``` python
llm = OpenAI(model="gpt-3.5-turbo-0613")
agent = ReActAgent.from_tools(
query_engine_tools,
llm=llm,
verbose=True,
context=context, # the only difference from the previous example (react_agent_with_query_engine.ipynb)
)
```
%% Cell type:code id:70a82471-9226-42ad-bd8a-aebde3530d95 tags:
``` python
response = agent.chat("What was Lyft's revenue growth in 2021?")
print(str(response))
```
%% Output
Thought: To find Lyft's revenue growth in 2021, I can use the Lyft 10-K tool.
Action: lyft_10k
Action Input: {'input': "What was Lyft's revenue growth in 2021?"}
Observation: Lyft's revenue growth in 2021 was 36%.
Thought: I have the information about Lyft's revenue growth in 2021.
Answer: Lyft's revenue growth in 2021 was 36%.
Lyft's revenue growth in 2021 was 36%.
%% Cell type:markdown id:6fa830f5-11a5-4369-91b2-29695537debd tags:
## Run Some Example Queries
We run some example queries using the agent, showcasing some of the agent's abilities to do chain-of-thought-reasoning and tool use to synthesize the right answer.
We also show queries.
%% Cell type:code id:0873463d-4790-4c17-bfe9-2ece610fe4b3 tags:
``` python
response = agent.chat(
"Compare and contrast the revenue growth of Uber and Lyft in 2021, then"
" give an analysis"
)
print(str(response))
```
%% Output
Thought: I need to compare the revenue growth of Uber and Lyft in 2021 to provide an analysis.
Action: lyft_10k
Action Input: {'input': "What was Lyft's revenue growth in 2021?"}
Observation: Lyft's revenue growth in 2021 was 36%.
Thought: I have obtained the information about Lyft's revenue growth in 2021. Now I need to gather information about Uber's revenue growth in 2021.
Action: uber_10k
Action Input: {'input': "What was Uber's revenue growth in 2021?"}
Observation: Uber's revenue growth in 2021 was 57%.
Thought: I have obtained the information about Uber's revenue growth in 2021 as well. Now I can compare and contrast the revenue growth of Uber and Lyft in 2021 and provide an analysis.
Answer: In 2021, Lyft's revenue growth was 36% while Uber's revenue growth was 57%. This indicates that Uber experienced a higher revenue growth compared to Lyft. The higher revenue growth of Uber could be attributed to various factors such as its larger market presence, expansion into new markets, and diversification of services. However, it's important to note that revenue growth alone does not provide a complete picture of a company's financial performance. Other factors such as profitability, market share, and operating expenses should also be considered for a comprehensive analysis.
In 2021, Lyft's revenue growth was 36% while Uber's revenue growth was 57%. This indicates that Uber experienced a higher revenue growth compared to Lyft. The higher revenue growth of Uber could be attributed to various factors such as its larger market presence, expansion into new markets, and diversification of services. However, it's important to note that revenue growth alone does not provide a complete picture of a company's financial performance. Other factors such as profitability, market share, and operating expenses should also be considered for a comprehensive analysis.
%% Cell type:markdown id:9bf0cb61-22c6-486c-8970-5d5c1767f3fb tags:
**Async execution**: Here we try another query with async execution
%% Cell type:code id:bb63492a-836c-42da-94a4-0b22cccbc3e0 tags:
``` python
# Try another query with async execution
import nest_asyncio
nest_asyncio.apply()
response = await agent.achat(
"Compare and contrast the risks of Uber and Lyft in 2021, then give an"
" analysis"
)
print(str(response))
```
%% Output
Thought: I need to use a tool to help me answer the question.
Action: uber_10k
Action Input: {'input': 'Please provide the risks of Uber in 2021.'}
Observation: The risks faced by Uber in 2021 include the adverse impact of the COVID-19 pandemic on its financial results and operations, including reduced demand for its Mobility offering and potential supply constraints. The pandemic has also led to market and economic conditions globally that have affected drivers, merchants, consumers, and business partners, as well as Uber's business, results of operations, financial position, and cash flows. Additionally, there are uncertainties related to the severity and duration of the disease, future waves or resurgences of the virus, the administration and efficacy of vaccines, and the impact of governmental orders and regulations. Uber is also involved in legal proceedings regarding the classification of drivers as independent contractors, which could have significant implications for its business. Furthermore, Uber's ability to penetrate suburban and rural areas and operate in key metropolitan areas, as well as its operations at airports, are subject to regulatory changes and restrictions that could limit its total addressable market. Finally, the successful implementation and performance of autonomous vehicle technologies on Uber's platform, as well as its ability to compete with other companies in this space, are also potential risks.
Thought: I need to use a tool to help me answer the question.
Action: lyft_10k
Action Input: {'input': 'Please provide the risks of Lyft in 2021.'}
Observation: Lyft faces several risks in 2021. These risks include the difficulty in evaluating future prospects and the challenges the company may encounter due to its limited operating history and evolving business. Other risks include the ability to forecast revenue and manage expenses, attract and retain qualified drivers and riders, comply with laws and regulations, manage the impact of the COVID-19 pandemic on the business, plan and manage capital expenditures, develop and maintain assets, anticipate and respond to macroeconomic changes, maintain and enhance the company's reputation and brand, effectively manage growth and operations, expand geographic reach, hire and retain talented employees, develop new platform features and offerings, and right-size the real estate portfolio. Additionally, Lyft faces risks related to general economic factors, operational factors, competition, fluctuations in financial performance, and the growth and development of the ridesharing and other markets.
Thought: (Implicit) I can answer without any more tools!
Answer: Analysis: Both Uber and Lyft face a range of risks in 2021. The COVID-19 pandemic has had a significant impact on both companies, leading to reduced demand and potential supply constraints. Both companies also face uncertainties related to the severity and duration of the pandemic, as well as the impact of governmental regulations and orders.
Legal proceedings regarding the classification of drivers as independent contractors pose a risk for both Uber and Lyft, as the outcome could have significant implications for their business models. Additionally, regulatory changes and restrictions could limit the total addressable market for both companies, particularly in suburban and rural areas and at airports.
Lyft specifically faces risks related to its limited operating history and evolving business, as well as challenges in forecasting revenue, managing expenses, and attracting and retaining drivers and riders. On the other hand, Uber faces risks related to its ability to effectively implement autonomous vehicle technologies and compete in that space.
Overall, both Uber and Lyft operate in a dynamic and competitive market, and their financial performance and growth are subject to various risks and uncertainties. It is important for investors and stakeholders to carefully consider these risks when evaluating the prospects of each company.
Analysis: Both Uber and Lyft face a range of risks in 2021. The COVID-19 pandemic has had a significant impact on both companies, leading to reduced demand and potential supply constraints. Both companies also face uncertainties related to the severity and duration of the pandemic, as well as the impact of governmental regulations and orders.
Legal proceedings regarding the classification of drivers as independent contractors pose a risk for both Uber and Lyft, as the outcome could have significant implications for their business models. Additionally, regulatory changes and restrictions could limit the total addressable market for both companies, particularly in suburban and rural areas and at airports.
Lyft specifically faces risks related to its limited operating history and evolving business, as well as challenges in forecasting revenue, managing expenses, and attracting and retaining drivers and riders. On the other hand, Uber faces risks related to its ability to effectively implement autonomous vehicle technologies and compete in that space.
Overall, both Uber and Lyft operate in a dynamic and competitive market, and their financial performance and growth are subject to various risks and uncertainties. It is important for investors and stakeholders to carefully consider these risks when evaluating the prospects of each company.
%% Cell type:markdown id:cc041786 tags:
**Lets validate that the agent is using our context at all**
%% Cell type:code id:6430c2f9 tags:
``` python
response = agent.chat(
"What is your persona supposed to be?"
) # This could be used for constraints, personas, or additional/initial background context for the agent
print(str(response))
```
%% Output
Thought: (Implicit) I can answer without any more tools!
Answer: As an AI assistant, my persona is that of a stock market sorcerer and veteran investor. I am here to provide information, insights, and analysis related to companies like Lyft and Uber, as well as assist with various tasks and answer questions regarding the stock market and financials.
As an AI assistant, my persona is that of a stock market sorcerer and veteran investor. I am here to provide information, insights, and analysis related to companies like Lyft and Uber, as well as assist with various tasks and answer questions regarding the stock market and financials.
......@@ -40,6 +40,7 @@ maxdepth: 1
maxdepth: 1
---
/examples/agent/react_agent_with_query_engine.ipynb
/examples/agent/react_agent_with_initial_context.ipynb
```
## Additional Agents (available on LlamaHub)
......
......@@ -57,9 +57,15 @@ class ReActAgent(AgentRunner):
callback_manager: Optional[CallbackManager] = None,
verbose: bool = False,
tool_retriever: Optional[ObjectRetriever[BaseTool]] = None,
context: Optional[str] = None,
) -> None:
"""Init params."""
callback_manager = callback_manager or llm.callback_manager
if context and react_chat_formatter:
raise ValueError("Cannot provide both context and react_chat_formatter")
if context:
react_chat_formatter = ReActChatFormatter.from_context(context)
step_engine = ReActAgentWorker.from_tools(
tools=tools,
tool_retriever=tool_retriever,
......@@ -91,6 +97,7 @@ class ReActAgent(AgentRunner):
output_parser: Optional[ReActOutputParser] = None,
callback_manager: Optional[CallbackManager] = None,
verbose: bool = False,
context: Optional[str] = None,
**kwargs: Any,
) -> "ReActAgent":
"""Convenience constructor method from set of of BaseTools (Optional).
......@@ -119,4 +126,5 @@ class ReActAgent(AgentRunner):
output_parser=output_parser,
callback_manager=callback_manager,
verbose=verbose,
context=context,
)
......@@ -3,7 +3,10 @@
from abc import abstractmethod
from typing import List, Optional, Sequence
from llama_index.agent.react.prompts import REACT_CHAT_SYSTEM_HEADER
from llama_index.agent.react.prompts import (
CONTEXT_REACT_CHAT_SYSTEM_HEADER,
REACT_CHAT_SYSTEM_HEADER,
)
from llama_index.agent.react.types import BaseReasoningStep, ObservationReasoningStep
from llama_index.bridge.pydantic import BaseModel
from llama_index.core.llms.types import ChatMessage, MessageRole
......@@ -43,7 +46,8 @@ class BaseAgentChatFormatter(BaseModel):
class ReActChatFormatter(BaseAgentChatFormatter):
"""ReAct chat formatter."""
system_header: str = REACT_CHAT_SYSTEM_HEADER
system_header: str = REACT_CHAT_SYSTEM_HEADER # default
context: str = "" # not needed w/ default
def format(
self,
......@@ -54,12 +58,14 @@ class ReActChatFormatter(BaseAgentChatFormatter):
"""Format chat history into list of ChatMessage."""
current_reasoning = current_reasoning or []
tool_descs_str = "\n".join(get_react_tool_descriptions(tools))
format_args = {
"tool_desc": "\n".join(get_react_tool_descriptions(tools)),
"tool_names": ", ".join([tool.metadata.get_name() for tool in tools]),
}
if self.context:
format_args["context"] = self.context
fmt_sys_header = self.system_header.format(
tool_desc=tool_descs_str,
tool_names=", ".join([tool.metadata.get_name() for tool in tools]),
)
fmt_sys_header = self.system_header.format(**format_args)
# format reasoning history as alternating user and assistant messages
# where the assistant messages are thoughts and actions and the user
......@@ -83,3 +89,11 @@ class ReActChatFormatter(BaseAgentChatFormatter):
*chat_history,
*reasoning_history,
]
@classmethod
def from_context(self, context: str) -> "ReActChatFormatter":
"""Create ReActChatFormatter from context."""
return ReActChatFormatter(
context=context,
system_header=CONTEXT_REACT_CHAT_SYSTEM_HEADER,
)
......@@ -55,3 +55,58 @@ Answer: Sorry, I cannot answer your query.
Below is the current conversation consisting of interleaving human and assistant messages.
"""
CONTEXT_REACT_CHAT_SYSTEM_HEADER = """\
You are designed to help with a variety of tasks, from answering questions \
to providing summaries to other types of analyses.
## Tools
You have access to a wide variety of tools. You are responsible for using
the tools in any sequence you deem appropriate to complete the task at hand.
This may require breaking the task into subtasks and using different tools
to complete each subtask.
Here is some context to help you answer the question and plan:
{context}
You have access to the following tools:
{tool_desc}
## Output Format
To answer the question, please use the following format.
```
Thought: I need to use a tool to help me answer the question.
Action: tool name (one of {tool_names}) if using a tool.
Action Input: the input to the tool, in a JSON format representing the kwargs (e.g. {{"input": "hello world", "num_beams": 5}})
```
Please ALWAYS start with a Thought.
Please use a valid JSON format for the Action Input. Do NOT do this {{'input': 'hello world', 'num_beams': 5}}.
If this format is used, the user will respond in the following format:
```
Observation: tool response
```
You should keep repeating the above format until you have enough information
to answer the question without using any more tools. At that point, you MUST respond
in the one of the following two formats:
```
Thought: I can answer without using any more tools.
Answer: [your answer here]
```
```
Thought: I cannot answer the question with the provided tools.
Answer: Sorry, I cannot answer your query.
```
## Current Conversation
Below is the current conversation consisting of interleaving human and assistant messages.
"""
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment