使用Return Direct工具控制Agent推理循环¶
所有工具都有一个return_direct
选项--如果将其设置为True
,并且调用了相关工具(没有调用任何其他工具),则Agent推理循环将结束,并且工具输出将直接返回。
当您知道工具输出已经足够好时,可以使用这个选项来加快响应时间,避免Agent重新编写响应,并结束推理循环,这可能非常有用。
这个笔记本演示了一个代理需要从用户那里收集信息,以便进行餐厅预订的过程。
In [ ]:
Copied!
!pip install llama-index-core llama-index-llms-anthropic
!pip install llama-index-core llama-index-llms-anthropic
In [ ]:
Copied!
import os
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."
import os
os.environ["ANTHROPIC_API_KEY"] = "sk-ant-..."
工具设置¶
In [ ]:
Copied!
from typing import Optional
from llama_index.core.tools import FunctionTool
from llama_index.core.bridge.pydantic import BaseModel
# 我们将预订存储在随机生成的ID下
bookings = {}
# 我们将使用Pydantic模型表示和跟踪预订的状态
class Booking(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
phone: Optional[str] = None
date: Optional[str] = None
time: Optional[str] = None
def get_booking_state(user_id: str) -> str:
"""获取给定预订ID的预订当前状态。"""
try:
return str(bookings[user_id].dict())
except:
return f"未找到预订ID {user_id}"
def update_booking(user_id: str, property: str, value: str) -> str:
"""更新给定预订ID的预订属性。只输入明确提供的详细信息。"""
booking = bookings[user_id]
setattr(booking, property, value)
return f"预订ID {user_id} 已更新,{property} = {value}"
def create_booking(user_id: str) -> str:
"""创建新预订并返回预订ID。"""
bookings[user_id] = Booking()
return "预订已创建,但尚未确认。请提供您的姓名、电子邮件、电话、日期和时间。"
def confirm_booking(user_id: str) -> str:
"""确认给定预订ID的预订。"""
booking = bookings[user_id]
if booking.name is None:
raise ValueError("请提供您的姓名。")
if booking.email is None:
raise ValueError("请提供您的电子邮件。")
if booking.phone is None:
raise ValueError("请提供您的电话号码。")
if booking.date is None:
raise ValueError("请提供您的预订日期。")
if booking.time is None:
raise ValueError("请提供您的预订时间。")
return f"预订ID {user_id} 已确认!"
# 为每个函数创建工具
get_booking_state_tool = FunctionTool.from_defaults(fn=get_booking_state)
update_booking_tool = FunctionTool.from_defaults(fn=update_booking)
create_booking_tool = FunctionTool.from_defaults(
fn=create_booking, return_direct=True
)
confirm_booking_tool = FunctionTool.from_defaults(
fn=confirm_booking, return_direct=True
)
from typing import Optional
from llama_index.core.tools import FunctionTool
from llama_index.core.bridge.pydantic import BaseModel
# 我们将预订存储在随机生成的ID下
bookings = {}
# 我们将使用Pydantic模型表示和跟踪预订的状态
class Booking(BaseModel):
name: Optional[str] = None
email: Optional[str] = None
phone: Optional[str] = None
date: Optional[str] = None
time: Optional[str] = None
def get_booking_state(user_id: str) -> str:
"""获取给定预订ID的预订当前状态。"""
try:
return str(bookings[user_id].dict())
except:
return f"未找到预订ID {user_id}"
def update_booking(user_id: str, property: str, value: str) -> str:
"""更新给定预订ID的预订属性。只输入明确提供的详细信息。"""
booking = bookings[user_id]
setattr(booking, property, value)
return f"预订ID {user_id} 已更新,{property} = {value}"
def create_booking(user_id: str) -> str:
"""创建新预订并返回预订ID。"""
bookings[user_id] = Booking()
return "预订已创建,但尚未确认。请提供您的姓名、电子邮件、电话、日期和时间。"
def confirm_booking(user_id: str) -> str:
"""确认给定预订ID的预订。"""
booking = bookings[user_id]
if booking.name is None:
raise ValueError("请提供您的姓名。")
if booking.email is None:
raise ValueError("请提供您的电子邮件。")
if booking.phone is None:
raise ValueError("请提供您的电话号码。")
if booking.date is None:
raise ValueError("请提供您的预订日期。")
if booking.time is None:
raise ValueError("请提供您的预订时间。")
return f"预订ID {user_id} 已确认!"
# 为每个函数创建工具
get_booking_state_tool = FunctionTool.from_defaults(fn=get_booking_state)
update_booking_tool = FunctionTool.from_defaults(fn=update_booking)
create_booking_tool = FunctionTool.from_defaults(
fn=create_booking, return_direct=True
)
confirm_booking_tool = FunctionTool.from_defaults(
fn=confirm_booking, return_direct=True
)
有用户来了!让我们帮助他们预订¶
In [ ]:
Copied!
from llama_index.llms.anthropic import Anthropic
from llama_index.core.llms import ChatMessage
from llama_index.core.agent import FunctionCallingAgentWorker
llm = Anthropic(model="claude-3-sonnet-20240229", temperature=0.1)
user = "user123"
prefix_messages = [
ChatMessage(
role="system",
content=(
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. "
"Do not make up any details."
),
)
]
worker = FunctionCallingAgentWorker(
tools=[
get_booking_state_tool,
update_booking_tool,
create_booking_tool,
confirm_booking_tool,
],
llm=llm,
prefix_messages=prefix_messages,
max_function_calls=10,
allow_parallel_tool_calls=False,
verbose=True,
)
agent = worker.as_agent()
from llama_index.llms.anthropic import Anthropic
from llama_index.core.llms import ChatMessage
from llama_index.core.agent import FunctionCallingAgentWorker
llm = Anthropic(model="claude-3-sonnet-20240229", temperature=0.1)
user = "user123"
prefix_messages = [
ChatMessage(
role="system",
content=(
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. "
"Do not make up any details."
),
)
]
worker = FunctionCallingAgentWorker(
tools=[
get_booking_state_tool,
update_booking_tool,
create_booking_tool,
confirm_booking_tool,
],
llm=llm,
prefix_messages=prefix_messages,
max_function_calls=10,
allow_parallel_tool_calls=False,
verbose=True,
)
agent = worker.as_agent()
In [ ]:
Copied!
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?")
Added user message to memory: Hello! I would like to make a booking, around 5pm? === 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: === Calling Function === Calling function: create_booking with args: {"user_id": "user123"} === Function Output === Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time.
In [ ]:
Copied!
print(str(response))
print(str(response))
Booking created, but not yet confirmed. Please provide your name, email, phone, date, and time.
完美,我们可以看到函数的输出直接被返回,没有经过任何修改或最终的LLM调用!
In [ ]:
Copied!
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")
Added user message to memory: Sure! My name is Logan, and my email is test@gmail.com === LLM Response === Got it, thanks for providing your name and email. Let me update the booking with those details: === Calling Function === Calling function: update_booking with args: {"user_id": "user123", "property": "name", "value": "Logan"} === Function Output === Booking ID user123 updated with name = Logan === Calling Function === Calling function: update_booking with args: {"user_id": "user123", "property": "email", "value": "test@gmail.com"} === Function Output === Booking ID user123 updated with email = test@gmail.com === LLM Response === I still need your phone number, date, and preferred time for the booking. Please provide those details.
In [ ]:
Copied!
print(str(response))
print(str(response))
assistant: I still need your phone number, date, and preferred time for the booking. Please provide those details.
In [ ]:
Copied!
response = agent.chat(
"Right! My phone number is 1234567890, the date of the booking is April 5, at 5pm."
)
response = agent.chat(
"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 === Great, thank you for providing the remaining details. Let me update the booking: === Calling Function === Calling function: update_booking with args: {"user_id": "user123", "property": "phone", "value": "1234567890"} === Function Output === Booking ID user123 updated with phone = 1234567890 === Calling Function === Calling function: update_booking with args: {"user_id": "user123", "property": "date", "value": "2023-04-05"} === Function Output === Booking ID user123 updated with date = 2023-04-05 === Calling Function === Calling function: update_booking with args: {"user_id": "user123", "property": "time", "value": "17:00"} === Function Output === Booking ID user123 updated with time = 17:00 === LLM Response === 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: confirm_booking with args: {"user_id": "user123"} === Function Output === Booking ID user123 confirmed!
In [ ]:
Copied!
print(str(response))
print(str(response))
Booking ID user123 confirmed!
In [ ]:
Copied!
print(bookings["user123"])
print(bookings["user123"])
name='Logan' email='test@gmail.com' phone='1234567890' date='2023-04-05' time='17:00'