Skip to content
Snippets Groups Projects
Unverified Commit 8fc45907 authored by Jerry Liu's avatar Jerry Liu Committed by GitHub
Browse files

return_direct notebook nits (#12691)

cr
parent 10591ff4
No related branches found
No related tags found
No related merge requests found
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
# Controlling Agent Reasoning Loop with Return Direct Tools # Controlling Agent Reasoning Loop with Return Direct Tools
All tools have an option for `return_direct` -- if this is set to `True`, and the associated tool is called (without any other tools being called), the agent resoning loop is ended and the tool output is returned directly. All tools have an option for `return_direct` -- if this is set to `True`, and the associated tool is called (without any other tools being called), the agent reasoning loop is ended and the tool output is returned directly.
This can be useful for speeding up resonse times when you know the tool output is good enough, to avoid the agent re-writing the response, and for ending the resoning loop. This can be useful for speeding up response times when you know the tool output is good enough, to avoid the agent re-writing the response, and for ending the reasoning loop.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
This notebook walks through a notebook where an agent needs to gather information from a user in order to make a resturant booking. This notebook walks through a notebook where an agent needs to gather information from a user in order to make a restaurant booking.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
!pip install llama-index-core llama-index-llms-anthropic !pip install llama-index-core llama-index-llms-anthropic
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
import os import os
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..." os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## Tools setup ## Tools setup
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
from typing import Optional from typing import Optional
from llama_index.core.tools import FunctionTool from llama_index.core.tools import FunctionTool
from llama_index.core.bridge.pydantic import BaseModel from llama_index.core.bridge.pydantic import BaseModel
# we will store booking under random IDs # we will store booking under random IDs
bookings = {} bookings = {}
# we will represent and track the state of a booking as a Pydantic model # we will represent and track the state of a booking as a Pydantic model
class Booking(BaseModel): class Booking(BaseModel):
name: Optional[str] = None name: Optional[str] = None
email: Optional[str] = None email: Optional[str] = None
phone: Optional[str] = None phone: Optional[str] = None
date: Optional[str] = None date: Optional[str] = None
time: Optional[str] = None time: Optional[str] = None
def get_booking_state(user_id: str) -> str: def get_booking_state(user_id: str) -> str:
"""Get the current state of a booking for a given booking ID.""" """Get the current state of a booking for a given booking ID."""
try: try:
return str(bookings[user_id].dict()) return str(bookings[user_id].dict())
except: except:
return f"Booking ID {user_id} not found" return f"Booking ID {user_id} not found"
def update_booking(user_id: str, property: str, value: str) -> str: def update_booking(user_id: str, property: str, value: str) -> str:
"""Update a property of a booking for a given booking ID. Only enter details that are explicitly provided.""" """Update a property of a booking for a given booking ID. Only enter details that are explicitly provided."""
booking = bookings[user_id] booking = bookings[user_id]
setattr(booking, property, value) setattr(booking, property, value)
return f"Booking ID {user_id} updated with {property} = {value}" return f"Booking ID {user_id} updated with {property} = {value}"
def create_booking(user_id: str) -> str: def create_booking(user_id: str) -> str:
"""Create a new booking and return the booking ID.""" """Create a new booking and return the booking ID."""
bookings[user_id] = Booking() bookings[user_id] = Booking()
return "Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time." return "Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time."
def confirm_booking(user_id: str) -> str: def confirm_booking(user_id: str) -> str:
"""Confirm a booking for a given booking ID.""" """Confirm a booking for a given booking ID."""
booking = bookings[user_id] booking = bookings[user_id]
if booking.name is None: if booking.name is None:
raise ValueError("Please provide your name.") raise ValueError("Please provide your name.")
if booking.email is None: if booking.email is None:
raise ValueError("Please provide your email.") raise ValueError("Please provide your email.")
if booking.phone is None: if booking.phone is None:
raise ValueError("Please provide your phone number.") raise ValueError("Please provide your phone number.")
if booking.date is None: if booking.date is None:
raise ValueError("Please provide the date of your booking.") raise ValueError("Please provide the date of your booking.")
if booking.time is None: if booking.time is None:
raise ValueError("Please provide the time of your booking.") raise ValueError("Please provide the time of your booking.")
return f"Booking ID {user_id} confirmed!" return f"Booking ID {user_id} confirmed!"
# create tools for each function # create tools for each function
get_booking_state_tool = FunctionTool.from_defaults(fn=get_booking_state) get_booking_state_tool = FunctionTool.from_defaults(fn=get_booking_state)
update_booking_tool = FunctionTool.from_defaults(fn=update_booking) update_booking_tool = FunctionTool.from_defaults(fn=update_booking)
create_booking_tool = FunctionTool.from_defaults( create_booking_tool = FunctionTool.from_defaults(
fn=create_booking, return_direct=True fn=create_booking, return_direct=True
) )
confirm_booking_tool = FunctionTool.from_defaults( confirm_booking_tool = FunctionTool.from_defaults(
fn=confirm_booking, return_direct=True fn=confirm_booking, return_direct=True
) )
``` ```
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
## A user has walked in! Lets help them make a booking ## A user has walked in! Let's help them make a booking
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
from llama_index.llms.anthropic import Anthropic from llama_index.llms.anthropic import Anthropic
from llama_index.core.llms import ChatMessage from llama_index.core.llms import ChatMessage
from llama_index.core.agent import FunctionCallingAgentWorker, AgentRunner from llama_index.core.agent import FunctionCallingAgentWorker, AgentRunner
llm = Anthropic(model="claude-3-sonnet-20240229", temperature=0.1) llm = Anthropic(model="claude-3-sonnet-20240229", temperature=0.1)
user = "user123" user = "user123"
prefix_messages = [ prefix_messages = [
ChatMessage( ChatMessage(
role="system", role="system",
content=( content=(
f"You are now connected to the booking system and helping {user} with making a booking. " f"You are now connected to the booking system and helping {user} with making a booking. "
"Only enter details that the user has explicitly provided. " "Only enter details that the user has explicitly provided. "
"Do not make up any details." "Do not make up any details."
), ),
) )
] ]
worker = FunctionCallingAgentWorker( worker = FunctionCallingAgentWorker(
tools=[ tools=[
get_booking_state_tool, get_booking_state_tool,
update_booking_tool, update_booking_tool,
create_booking_tool, create_booking_tool,
confirm_booking_tool, confirm_booking_tool,
], ],
llm=llm, llm=llm,
prefix_messages=prefix_messages, prefix_messages=prefix_messages,
max_function_calls=10, max_function_calls=10,
allow_parallel_tool_calls=False, allow_parallel_tool_calls=False,
verbose=True, verbose=True,
) )
agent = AgentRunner(worker) agent = AgentRunner(worker)
``` ```
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
response = agent.chat("Hello! I would like to make a booking, around 5pm?") response = agent.chat("Hello! I would like to make a booking, around 5pm?")
``` ```
%% Output %% Output
Added user message to memory: Hello! I would like to make a booking, around 5pm? Added user message to memory: Hello! I would like to make a booking, around 5pm?
=== LLM Response === === LLM Response ===
Okay, let's create a new booking for you. To do that, I'll invoke the create_booking tool with your user ID: Okay, let's create a new booking for you. To do that, I'll invoke the create_booking tool with your user ID:
=== Calling Function === === Calling Function ===
Calling function: create_booking with args: {"user_id": "user123"} Calling function: create_booking with args: {"user_id": "user123"}
=== Function Output === === Function Output ===
Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time. Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
print(str(response)) print(str(response))
``` ```
%% Output %% Output
Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time. Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time.
%% Cell type:markdown id: tags: %% Cell type:markdown id: tags:
Perfect, we can see the function output was retruned directly, with no modification or final LLM call! Perfect, we can see the function output was retruned directly, with no modification or final LLM call!
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
response = agent.chat("Sure! My name is Logan, and my email is test@gmail.com") response = agent.chat("Sure! My name is Logan, and my email is test@gmail.com")
``` ```
%% Output %% Output
Added user message to memory: Sure! My name is Logan, and my email is test@gmail.com Added user message to memory: Sure! My name is Logan, and my email is test@gmail.com
=== LLM Response === === LLM Response ===
Got it, thanks for providing your name and email. Let me update the booking with those details: Got it, thanks for providing your name and email. Let me update the booking with those details:
=== Calling Function === === Calling Function ===
Calling function: update_booking with args: {"user_id": "user123", "property": "name", "value": "Logan"} Calling function: update_booking with args: {"user_id": "user123", "property": "name", "value": "Logan"}
=== Function Output === === Function Output ===
Booking ID user123 updated with name = Logan Booking ID user123 updated with name = Logan
=== Calling Function === === Calling Function ===
Calling function: update_booking with args: {"user_id": "user123", "property": "email", "value": "test@gmail.com"} Calling function: update_booking with args: {"user_id": "user123", "property": "email", "value": "test@gmail.com"}
=== Function Output === === Function Output ===
Booking ID user123 updated with email = test@gmail.com Booking ID user123 updated with email = test@gmail.com
=== LLM Response === === LLM Response ===
I still need your phone number, date, and preferred time for the booking. Please provide those details. I still need your phone number, date, and preferred time for the booking. Please provide those details.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
print(str(response)) print(str(response))
``` ```
%% Output %% Output
assistant: I still need your phone number, date, and preferred time for the booking. Please provide those details. assistant: I still need your phone number, date, and preferred time for the booking. Please provide those details.
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
response = agent.chat( response = agent.chat(
"Right! My phone number is 1234567890, the date of the booking is April 5, at 5pm." "Right! My phone number is 1234567890, the date of the booking is April 5, at 5pm."
) )
``` ```
%% Output %% Output
Added user message to memory: Right! My phone number is 1234567890, the date of the booking is April 5, at 5pm. Added user message to memory: Right! My phone number is 1234567890, the date of the booking is April 5, at 5pm.
=== LLM Response === === LLM Response ===
Great, thank you for providing the remaining details. Let me update the booking: Great, thank you for providing the remaining details. Let me update the booking:
=== Calling Function === === Calling Function ===
Calling function: update_booking with args: {"user_id": "user123", "property": "phone", "value": "1234567890"} Calling function: update_booking with args: {"user_id": "user123", "property": "phone", "value": "1234567890"}
=== Function Output === === Function Output ===
Booking ID user123 updated with phone = 1234567890 Booking ID user123 updated with phone = 1234567890
=== Calling Function === === Calling Function ===
Calling function: update_booking with args: {"user_id": "user123", "property": "date", "value": "2023-04-05"} Calling function: update_booking with args: {"user_id": "user123", "property": "date", "value": "2023-04-05"}
=== Function Output === === Function Output ===
Booking ID user123 updated with date = 2023-04-05 Booking ID user123 updated with date = 2023-04-05
=== Calling Function === === Calling Function ===
Calling function: update_booking with args: {"user_id": "user123", "property": "time", "value": "17:00"} Calling function: update_booking with args: {"user_id": "user123", "property": "time", "value": "17:00"}
=== Function Output === === Function Output ===
Booking ID user123 updated with time = 17:00 Booking ID user123 updated with time = 17:00
=== LLM Response === === LLM Response ===
Your booking for April 5th at 5pm is now created with all the provided details. To confirm it, I'll invoke: Your booking for April 5th at 5pm is now created with all the provided details. To confirm it, I'll invoke:
=== Calling Function === === Calling Function ===
Calling function: confirm_booking with args: {"user_id": "user123"} Calling function: confirm_booking with args: {"user_id": "user123"}
=== Function Output === === Function Output ===
Booking ID user123 confirmed! Booking ID user123 confirmed!
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
print(str(response)) print(str(response))
``` ```
%% Output %% Output
Booking ID user123 confirmed! Booking ID user123 confirmed!
%% Cell type:code id: tags: %% Cell type:code id: tags:
``` python ``` python
print(bookings["user123"]) print(bookings["user123"])
``` ```
%% Output %% Output
name='Logan' email='test@gmail.com' phone='1234567890' date='2023-04-05' time='17:00' name='Logan' email='test@gmail.com' phone='1234567890' date='2023-04-05' time='17:00'
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment