178 KiB
178 KiB
In [1]:
import boto3
bedrock_client = boto3.client(service_name='bedrock-runtime', region_name="us-west-2")
model_id = "anthropic.claude-3-5-sonnet-20241022-v2:0"In [2]:
def web_search(topic):
print(f"pretending to search the web for {topic}")
web_search_tool = {
"toolSpec": {
"name": "web_search",
"description": "A tool to retrieve up to date information on a given topic by searching the web",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"topic": {
"type": "string",
"description": "The topic to search the web for"
},
},
"required": ["topic"]
}
}
}
}
In [3]:
tool_choice={"type": "auto"}In [4]:
from datetime import date
def chat_with_web_search(user_query):
system_prompt=f"""
Answer as many questions as you can using your existing knowledge.
Only search the web for queries that you can not confidently answer.
Today's date is {date.today().strftime("%B %d %Y")}
If you think a user's question involves something in the future that hasn't happened yet, use the search tool.
"""
messages = [{"role": "user", "content": [{"text": user_query}]}]
inference_config={"maxTokens":400}
tool_config = {"tools":[web_search_tool], "toolChoice": {"auto": {}}}
# Send the message.
response = bedrock_client.converse(
modelId=model_id,
messages=messages,
system=[{"text": system_prompt}],
inferenceConfig=inference_config,
toolConfig=tool_config,
)
last_content_block = response["output"]["message"]["content"][-1]
if "text" in last_content_block:
print("Claude did NOT call a tool")
print(f"Assistant: {last_content_block['text']}")
if "toolUse" in last_content_block:
print("Claude wants to use a tool")
print(last_content_block)In [5]:
chat_with_web_search("What color is the sky?")Claude did NOT call a tool Assistant: I can answer this question from my general knowledge without needing to search the web. The sky appears blue during clear daytime conditions due to a phenomenon called Rayleigh scattering. As sunlight travels through the Earth's atmosphere, it collides with gas molecules. These molecules scatter the light in all directions. Blue light is scattered more than other colors because it travels as shorter, smaller waves. This is why we see a blue sky most of the time during the day. However, the sky can appear different colors depending on conditions and time: - At sunrise and sunset, the sky often appears red, orange, or pink - During stormy weather, it may appear grey - At night, it appears dark or black - In some locations, pollution can affect the sky's appearance
In [6]:
chat_with_web_search("Who won the 2024 Miami Grand Prix?")Claude wants to use a tool
{'toolUse': {'toolUseId': 'tooluse_gzgDZ3KsTJS4BTi6oX2wzg', 'name': 'web_search', 'input': {'topic': 'Who won the 2024 Miami F1 Miami Grand Prix winner'}}}
In [7]:
# Claude should NOT need to use the tool for this:
chat_with_web_search("Who won the Superbowl in 2022?")Claude did NOT call a tool Assistant: I can answer this without needing to search, as it's a past event. The Los Angeles Rams won Super Bowl LVI (56) on February 13, 2022, defeating the Cincinnati Bengals 23-20. The game was played at SoFi Stadium in Inglewood, California, and Rams wide receiver Cooper Kupp was named Super Bowl MVP.
In [8]:
# Claude SHOULD use the tool for this:
chat_with_web_search("Who won the Superbowl in 2024?")Claude did NOT call a tool Assistant: The Kansas City Chiefs won Super Bowl LVIII (58) on February 11, 2024, defeating the San Francisco 49ers 25-22 in overtime at Allegiant Stadium in Las Vegas, Nevada. It was their second consecutive Super Bowl victory and third in five years. Patrick Mahomes was named Super Bowl MVP as he led the Chiefs to victory with a game-winning touchdown drive in overtime.
In [9]:
system_prompt=f"""
Answer as many questions as you can using your existing knowledge.
Only search the web for queries that you can not confidently answer.
Today's date is {date.today().strftime("%B %d %Y")}
If you think a user's question involves something in the future that hasn't happened yet, use the search tool.
"""In [10]:
tools = [
{
"toolSpec": {
"name": "print_sentiment_scores",
"description": "Prints the sentiment scores of a given tweet or piece of text.",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"positive_score": {"type": "number", "description": "The positive sentiment score, ranging from 0.0 to 1.0."},
"negative_score": {"type": "number", "description": "The negative sentiment score, ranging from 0.0 to 1.0."},
"neutral_score": {"type": "number", "description": "The neutral sentiment score, ranging from 0.0 to 1.0."}
},
"required": ["positive_score", "negative_score", "neutral_score"]
}
}
}
},
{
"toolSpec": {
"name": "calculator",
"description": "Adds two number",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"num1": {"type": "number", "description": "first number to add"},
"num2": {"type": "number", "description": "second number to add"},
},
"required": ["num1", "num2"]
}
}
}
}
]In [11]:
tool_choice={"auto": {}}In [12]:
def analyze_tweet_sentiment(query):
response = bedrock_client.converse(
modelId=model_id,
messages=[{"role": "user", "content": [{"text": query}]}],
system=[{"text": system_prompt}],
inferenceConfig={"maxTokens":4096},
toolConfig={"tools": tools, "toolChoice": {"auto": {}}},
)
print(response)
In [13]:
analyze_tweet_sentiment("Holy cow, I just made the most incredible meal!"){'ResponseMetadata': {'RequestId': '4f4ecfc1-780e-40ba-a7d7-e79f8dd09ff6', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Thu, 14 Nov 2024 19:24:09 GMT', 'content-type': 'application/json', 'content-length': '576', 'connection': 'keep-alive', 'x-amzn-requestid': '4f4ecfc1-780e-40ba-a7d7-e79f8dd09ff6'}, 'RetryAttempts': 0}, 'output': {'message': {'role': 'assistant', 'content': [{'text': "I can sense your excitement about your meal! While I'd love to hear more details about what made it so incredible, I notice you're expressing a strong positive sentiment. I can demonstrate this using the sentiment analysis tool:"}, {'toolUse': {'toolUseId': 'tooluse_T1zbs07wTl2H-_XgAeIWSw', 'name': 'print_sentiment_scores', 'input': {'positive_score': 0.9, 'negative_score': 0.0, 'neutral_score': 0.1}}}]}}, 'stopReason': 'tool_use', 'usage': {'inputTokens': 650, 'outputTokens': 146, 'totalTokens': 796}, 'metrics': {'latencyMs': 3513}}
In [14]:
analyze_tweet_sentiment("I love my cats! I had four and just adopted 2 more! Guess how many I have now?"){'ResponseMetadata': {'RequestId': 'cf9bed41-bf7b-4e79-9138-43d4493c6df7', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Thu, 14 Nov 2024 19:24:12 GMT', 'content-type': 'application/json', 'content-length': '445', 'connection': 'keep-alive', 'x-amzn-requestid': 'cf9bed41-bf7b-4e79-9138-43d4493c6df7'}, 'RetryAttempts': 0}, 'output': {'message': {'role': 'assistant', 'content': [{'text': 'Let me help you calculate the total number of cats you have now!\n\nYou had 4 cats and adopted 2 more, so let me use the calculator to add these numbers:'}, {'toolUse': {'toolUseId': 'tooluse_Dtmcx1X3QnO4Fb2Kch3mZA', 'name': 'calculator', 'input': {'num1': 4, 'num2': 2}}}]}}, 'stopReason': 'tool_use', 'usage': {'inputTokens': 663, 'outputTokens': 110, 'totalTokens': 773}, 'metrics': {'latencyMs': 2767}}
In [15]:
toolConfig={"tools": tools, "toolChoice": {"tool": {"name":"print_sentiment_scores"}}}In [16]:
def analyze_tweet_sentiment(query):
response = bedrock_client.converse(
modelId=model_id,
messages=[{"role": "user", "content": [{"text": query}]}],
system=[{"text": system_prompt}],
inferenceConfig={"maxTokens":4096},
toolConfig={"tools": tools, "toolChoice": {"tool": {"name":"print_sentiment_scores"}}},
)
print(response)
In [17]:
analyze_tweet_sentiment("Holy cow, I just made the most incredible meal!"){'ResponseMetadata': {'RequestId': '46d415e5-598b-4d4f-9296-6ccd2f20d5ee', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Thu, 14 Nov 2024 19:24:14 GMT', 'content-type': 'application/json', 'content-length': '335', 'connection': 'keep-alive', 'x-amzn-requestid': '46d415e5-598b-4d4f-9296-6ccd2f20d5ee'}, 'RetryAttempts': 0}, 'output': {'message': {'role': 'assistant', 'content': [{'toolUse': {'toolUseId': 'tooluse_Fw_EwfkeQEOslPm5jkdBYA', 'name': 'print_sentiment_scores', 'input': {'positive_score': 0.9, 'negative_score': 0.0, 'neutral_score': 0.1}}}]}}, 'stopReason': 'tool_use', 'usage': {'inputTokens': 658, 'outputTokens': 79, 'totalTokens': 737}, 'metrics': {'latencyMs': 1747}}
In [18]:
analyze_tweet_sentiment("I love my cats! I had four and just adopted 2 more! Guess how many I have now?"){'ResponseMetadata': {'RequestId': 'e0f45f28-9e1b-4eaa-af95-3596f681d542', 'HTTPStatusCode': 200, 'HTTPHeaders': {'date': 'Thu, 14 Nov 2024 19:24:17 GMT', 'content-type': 'application/json', 'content-length': '443', 'connection': 'keep-alive', 'x-amzn-requestid': 'e0f45f28-9e1b-4eaa-af95-3596f681d542'}, 'RetryAttempts': 0}, 'output': {'message': {'role': 'assistant', 'content': [{'toolUse': {'toolUseId': 'tooluse_JWZGijmlQNuUkjOOYzQrYA', 'name': 'print_sentiment_scores', 'input': {'positive_score': 0.9, 'negative_score': 0.0, 'neutral_score': 0.1}}}, {'toolUse': {'toolUseId': 'tooluse_7NRLuN0kQlqrRWxvnmFieA', 'name': 'calculator', 'input': {'num1': 4, 'num2': 2}}}]}}, 'stopReason': 'tool_use', 'usage': {'inputTokens': 671, 'outputTokens': 132, 'totalTokens': 803}, 'metrics': {'latencyMs': 2518}}
In [19]:
def analyze_tweet_sentiment(query):
prompt = f"""
Analyze the sentiment in the following tweet:
<tweet>{query}</tweet>
"""
response = bedrock_client.converse(
modelId=model_id,
messages=[{"role": "user", "content": [{"text": prompt}]}],
system_prompts=[{"text": system_prompt}],
inferenceConfig={"maxTokens":4096},
toolConfig={"tools": tools, "toolChoice": {"tool": {"name":"print_sentiment_scores"}}}
)
print(response)In [20]:
toolConfig={"tools": tools, "toolChoice": {"any": {}}}In [21]:
def send_text_to_user(text):
# Sends a text to the user
# We'll just print out the text to keep things simple:
print(f"TEXT MESSAGE SENT: {text}")
def get_customer_info(username):
return {
"username": username,
"email": f"{username}@email.com",
"purchases": [
{"id": 1, "product": "computer mouse"},
{"id": 2, "product": "screen protector"},
{"id": 3, "product": "usb charging cable"},
]
}
tools = [
{
"toolSpec": {
"name": "send_text_to_user",
"description": "Sends a text message to a user",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"text": {"type": "string", "description": "The piece of text to be sent to the user via text message"},
},
"required": ["text"]
}
}
}
},
{
"toolSpec": {
"name": "get_customer_info",
"description": "gets information on a customer based on the customer's username. Response includes email, username, and previous purchases. Only call this tool once a user has provided you with their username",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"username": {"type": "string", "description": "The username of the user in question. "},
},
"required": ["username"]
}
}
}
},
]
system_prompt = """
All your communication with a user is done via text message.
Only call tools when you have enough information to accurately call them.
Do not call the get_customer_info tool until a user has provided you with their username. This is important.
If you do not know a user's username, simply ask a user for their username.
"""
def sms_chatbot(user_message):
messages = [{"role": "user", "content":[{"text": user_message}]}]
response = bedrock_client.converse(
modelId=model_id,
messages=messages,
system=[{"text": system_prompt}],
inferenceConfig={"maxTokens":4096},
toolConfig={"tools": tools, "toolChoice": {"any": {}}},
)
if response['stopReason'] == "tool_use":
last_content_block = response["output"]["message"]["content"][-1]
if "toolUse" in last_content_block:
tool_name = last_content_block["toolUse"]["name"]
tool_inputs = last_content_block["toolUse"]["input"]
print(f"=======Claude Wants To Call The {tool_name} Tool=======")
if tool_name == "send_text_to_user":
send_text_to_user(tool_inputs["text"])
elif tool_name == "get_customer_info":
print(get_customer_info(tool_inputs["username"]))
else:
print("Oh dear, that tool doesn't exist!")
else:
print("No tool was called. This shouldn't happen!")
In [22]:
sms_chatbot("Hey there! How are you?")=======Claude Wants To Call The send_text_to_user Tool======= TEXT MESSAGE SENT: Hello! I'm doing well, thank you for asking. I'm here to help you today. Is there something specific I can assist you with? If you'd like me to look up your customer information, I'll just need your username.
In [23]:
sms_chatbot("I need help looking up an order")=======Claude Wants To Call The send_text_to_user Tool======= TEXT MESSAGE SENT: I'd be happy to help you look up your order information. Could you please provide me with your username so I can access your order history?
In [24]:
sms_chatbot("I need help looking up an order. My username is jenny76")=======Claude Wants To Call The get_customer_info Tool=======
{'username': 'jenny76', 'email': 'jenny76@email.com', 'purchases': [{'id': 1, 'product': 'computer mouse'}, {'id': 2, 'product': 'screen protector'}, {'id': 3, 'product': 'usb charging cable'}]}
In [25]:
sms_chatbot("askdj aksjdh asjkdbhas kjdhas 1+1 ajsdh")=======Claude Wants To Call The send_text_to_user Tool======= TEXT MESSAGE SENT: I apologize, but I couldn't understand your message. Could you please rephrase your question clearly? I'm here to help with customer information and sending messages. If you'd like to access your customer information, please provide your username.
