本笔记本应该可以在 SageMaker Studio 中的
Data Science 3.0
内核上很好地运行。我们也可以在本地设置上运行,只要我们有正确的 IAM 凭证来通过 Bedrock 调用 Claude 模型
在这个演示笔记本中,我们演示了通过 Bedrock 使用 Anthropic 的 Claude 模型进行函数调用的实现。这个笔记本受到 原始工作 的启发,并将其修改以用于 Amazon Bedrock。
对话式界面,如聊天机器人和虚拟助手,可用于增强我们客户的用户体验。它们使用自然语言处理(NLP)和机器学习算法来理解和响应用户查询,可用于各种应用程序,如客户服务、销售和电子商务,提供快速高效的用户响应。通常,它们通过从各种渠道(如网站、社交媒体平台和消息应用程序)获取信息而得到增强,这涉及一个复杂的工作流程,如下所示。
构建上下文感知聊天机器人的第一个过程是识别可由 LLM 调用的工具。
第二个过程是用户请求编排、交互、调用和返回结果
我们搜索并查找纬度和经度,然后调用天气应用程序获取预报
#!pip install langchain==0.1.17
#!pip install langchain-anthropic
#!pip install boto3==1.34.95
#!pip install faiss-cpu==1.8.0
#!pip install pypdf
我们可以运行 pip install langchain-aws
要获取最新版本,请使用以下命令 #- 从我们机器上的终端运行 cd ~ mkdir temp_t cd temp_t git clone https://github.com/langchain-ai/langchain-aws/ pip install ./langchain-aws/libs/aws/
⚠️ ⚠️ ⚠️ 在运行此笔记本之前,请确保我们拥有所需的库和访问互联网以获取此笔记本中的天气 api。⚠️ ⚠️ ⚠️
import os
from typing import Optional
# 外部依赖项:
import boto3
from botocore.config import Config
def get_bedrock_client(assumed_role: Optional[str] = None, region: Optional[str] = 'us-east-1',runtime: Optional[bool] = True,external_id=None, ep_url=None):
"""创建一个 Amazon Bedrock 的 boto3 客户端,可以选择配置覆盖
"""
target_region = region
print(f"创建新客户端\n 使用区域: {target_region}:external_id={external_id}: ")
session_kwargs = {"region_name": target_region}
client_kwargs = {**session_kwargs}
profile_name = os.environ.get("AWS_PROFILE")
if profile_name:
print(f" 使用配置文件: {profile_name}")
session_kwargs["profile_name"] = profile_name
retry_config = Config(
region_name=target_region,
retries={
"max_attempts": 10,
"mode": "standard",
},
)
session = boto3.Session(**session_kwargs)
if assumed_role:
print(f" 使用角色: {assumed_role}", end='')
sts = session.client("sts")
if external_id:
response = sts.assume_role(
RoleArn=str(assumed_role),
RoleSessionName="langchain-llm-1",
ExternalId=external_id
)
else:
response = sts.assume_role(
RoleArn=str(assumed_role),
RoleSessionName="langchain-llm-1",
)
print(f"使用角色: {assumed_role} ... sts::successful!")
client_kwargs["aws_access_key_id"] = response["Credentials"]["AccessKeyId"]
client_kwargs["aws_secret_access_key"] = response["Credentials"]["SecretAccessKey"]
client_kwargs["aws_session_token"] = response["Credentials"]["SessionToken"]
if runtime:
service_name='bedrock-runtime'
else:
service_name='bedrock'
if ep_url:
bedrock_client = session.client(service_name=service_name,config=retry_config,endpoint_url = ep_url, **client_kwargs )
else:
bedrock_client = session.client(service_name=service_name,config=retry_config, **client_kwargs )
print("boto3 Bedrock 客户端成功创建!")
print(bedrock_client._endpoint)
return bedrock_client
import json
import os
import sys
import boto3
import botocore
# ---- ⚠️ 取消注释并根据我们的 AWS 设置编辑以下行 ⚠️ ----
# os.environ["AWS_DEFAULT_REGION"] = "<REGION_NAME>" # 例如 "us-east-1"
# os.environ["AWS_PROFILE"] = "<YOUR_PROFILE>"
# os.environ["BEDROCK_ASSUME_ROLE"] = "<YOUR_ROLE_ARN>" # 例如 "arn:aws:..."
bedrock_runtime = get_bedrock_client() #
# assumed_role=os.environ.get("BEDROCK_ASSUME_ROLE", None),
# region=os.environ.get("AWS_DEFAULT_REGION", None)
# )
"messages": [
{"role": "user", "content": "Hello, Claude"},
{"role": "assistant", "content": "Hello!"},
{"role": "user", "content": "Can you describe LLMs to me?"}
]
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 100,
"messages": messages,
"temperature": 0.5,
"top_p": 0.9
}
{
'id': 'msg_01T',
'type': 'message',
'role': 'assistant',
'content': [
{
'type': 'text',
'text': '当然,这个概念...'
}
],
'model': 'model_id',
'stop_reason': 'max_tokens',
'stop_sequence': None,
'usage': {'input_tokens':xy, 'output_tokens': yz}}
Anthropic Claude
使其工作的关键是让 LLM(即 Claude 模型)知道它可以调用的一组"工具”,即它可以在一组标签之间调用的函数。这是可能的,因为 Anthropic 的 Claude 模型已经在其训练语料库中广泛训练了这些标签。
然后提供一种逐步调用工具的方法,直到获得正确的答案。我们创建了一组可调用的函数,下面我们提供了一个示例函数,可以根据需要进行修改。
from io import StringIO
import sys
import textwrap
from langchain.llms.bedrock import Bedrock
from typing import Optional, List, Any
from langchain.callbacks.manager import CallbackManagerForLLMRun
def print_ww(*args, width: int = 100, **kwargs):
"""像 print()一样,但将输出换行到 `width` 个字符(默认为 100)"""
buffer = StringIO()
try:
_stdout = sys.stdout
sys.stdout = buffer
print(*args, **kwargs)
output = buffer.getvalue()
finally:
sys.stdout = _stdout
for line in output.splitlines():
print("\n".join(textwrap.wrap(line, width=width)))
调用模型以确保连接
import json
modelId = "anthropic.claude-3-sonnet-20240229-v1:0" #"anthropic.claude-v2"
messages=[
{
"role":'user',
"content":[{
'type':'text',
'text': "什么是量子力学? "
}]
},
{
"role":'assistant',
"content":[{
'type':'text',
'text': "它是物理学的一个分支,描述了物质和能量如何以离散的能量值进行交互"
}]
},
{
"role":'user',
"content":[{
'type':'text',
'text': "你能更详细地解释一下离散能量吗?"
}]
}
]
body=json.dumps(
{
"anthropic_version": "bedrock-2023-05-31",
"max_tokens": 100,
"messages": messages,
"temperature": 0.5,
"top_p": 0.9
}
)
response = bedrock_runtime.invoke_model(body=body, modelId=modelId)
response_body = json.loads(response.get('body').read())
print_ww(response_body)
创建一组辅助函数
我们将创建一组可以在我们的应用程序中重复使用的函数
添加到提示
。返回的结果需要添加到提示中,并再次调用模型以获得正确的结果from langchain_community.chat_models import BedrockChat
from langchain_core.messages import HumanMessage
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
递归添加可用的工具
现在使用 langchain 和注释来创建工具并调用函数
import requests
from langchain.tools import tool
from langchain.tools import StructuredTool
from langchain.agents import load_tools
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain import LLMMathChain
@tool ("get_lat_long")
def get_lat_long(place: str) -> dict:
"""返回给定地名的纬度和经度,作为 python 字典对象。"""
url = "https://nominatim.openstreetmap.org/search"
headers = {'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.95 Safari/537.36'}
params = {'q': place, 'format': 'json', 'limit': 1}
response = requests.get(url, params=params, headers=headers).json()
if response:
lat = response[0]["lat"]
lon = response[0]["lon"]
return {"latitude": lat, "longitude": lon}
else:
return None
@tool ("get_weather")
def get_weather(latitude: str, longitude: str) -> dict:
"""返回给定纬度和经度的天气数据。"""
url = f"https://api.open-meteo.com/v1/forecast?latitude={latitude}&longitude={longitude}¤t_weather=true"
response = requests.get(url)
print_ww(f"get_weather:tool:invoked::response={response}:")
return response.json()
#get_weather_tool = StructuredTool.from_function(get_weather)
tools_list = [get_lat_long,get_weather]
for tools_s in tools_list:
print_ww(f"Tool:name={tools_s.name}::args={tools_s.args}:: discription={tools_s.description}::")
使用默认提示模板
使用内存 FAISS DB
###
from langchain.agents import load_tools
from langchain.agents import initialize_agent, Tool
from langchain.agents import AgentType
from langchain.llms.bedrock import Bedrock
from langchain import LLMMathChain
from langchain.prompts import ChatPromptTemplate, SystemMessagePromptTemplate,HumanMessagePromptTemplate
from langchain_core.output_parsers import StrOutputParser
from langchain_core.prompts import ChatPromptTemplate
model_parameter = {"temperature": 0.0, "top_p": .5, "max_tokens_to_sample": 2000}
modelId = "anthropic.claude-3-sonnet-20240229-v1:0" #"anthropic.claude-v2"
react_agent_llm = BedrockChat(
model_id=modelId,
client=bedrock_runtime,
model_kwargs={"temperature": 0.1},
)
tools_list = [get_lat_long,get_weather]
react_agent = initialize_agent(
tools_list,
react_agent_llm,
agent=AgentType.STRUCTURED