使用工具完成 Amazon Bedrock 模型回應 - Amazon Bedrock

本文為英文版的機器翻譯版本,如內容有任何歧義或不一致之處,概以英文版為準。

使用工具完成 Amazon Bedrock 模型回應

您可以使用 Amazon Bedrock API 為模型提供工具的存取權,以協助其為您傳送至模型的訊息產生回應。例如,您可能有一個聊天應用程式,可以讓使用者知道廣播電台播放的熱門歌曲。為了回答熱門歌曲的請求,模型需要可以查詢並傳回歌曲資訊的工具。

注意

您現在可以搭配工具使用結構化輸出。如需詳細資訊,請參閱從模型取得經過驗證的 JSON 結果

在 Amazon Bedrock 中,模型不會直接呼叫工具。相反地,當您傳送訊息至模型時,您也會提供一或多個工具的定義,這些工具可能協助模型產生回應。在此範例中,您會為傳回指定廣播電台最熱門歌曲的工具提供定義。如果模型判斷需要工具來產生訊息的回應,根據用來叫用模型的 API,模型可以執行用戶端呼叫,或要求 Bedrock 使用伺服器端工具呼叫來呼叫工具。讓我們更詳細地討論這兩個選項。

用戶端工具呼叫

如果您使用回應 API、聊天完成 API、Converse API 或 InvokeModel API 來傳送請求,則模型會使用用戶端工具呼叫。這表示在您的程式碼中,您會代表模型呼叫 工具。在此情境中,假設工具實作是 API。該工具可以輕鬆成為資料庫、Lambda 函式或其他軟體。您可以決定如何實作工具。然後,透過提供具有工具結果的訊息,繼續與模型對話。最後,模型會為原始訊息產生回應,其中包含您傳送至模型的工具結果。

讓我們定義將用於工具的工具。下列 Python 範例示範如何使用在虛構廣播台上傳回最熱門歌曲的工具。

def get_most_popular_song(station_name: str) -> str: stations = { "Radio Free Mars": "Starman – David Bowie", "Neo Tokyo FM": "Plastic Love – Mariya Takeuchi", "Cloud Nine Radio": "Blinding Lights – The Weeknd", } return stations.get(station_name, "Unknown Station – No chart data available")

使用回應 API 進行用戶端工具

您可以使用 OpenAI 提供的函數呼叫功能來呼叫此工具。回應 API 是 OpenAI 偏好的 API。以下是用戶端工具的 Python 回應 API 程式碼:

from openai import OpenAI import json client = OpenAI() response = client.responses.create( model="oss-gpt-120b", input="What is the most popular song on Radio Free Mars?", tools=[ { "type": "function", "name": "get_most_popular_song", "description": "Returns the most popular song on a radio station", "parameters": { "type": "object", "properties": { "station_name": { "type": "string", "description": "Name of the radio station" } }, "required": ["station_name"] } } ] ) if response.output and response.output[0].content: tool_call = response.output[0].content[0] args = json.loads(tool_call["arguments"]) result = get_most_popular_song(args["station_name"]) final_response = client.responses.create( model="oss-gpt-120b", input=[ { "role": "tool", "tool_call_id": tool_call["id"], "content": result } ] ) print(final_response.output_text)

使用聊天完成 API 進行用戶端工具

您也可以使用聊天完成 API。以下是使用聊天完成的 Python 程式碼:

from openai import OpenAI import json client = OpenAI() completion = client.chat.completions.create( model="oss-gpt-120b", messages=[{"role": "user", "content": "What is the most popular song on Neo Tokyo FM?"}], tools=[{ "type": "function", "function": { "name": "get_most_popular_song", "description": "Returns the most popular song on a radio station", "parameters": { "type": "object", "properties": { "station_name": {"type": "string", "description": "Name of the radio station"} }, "required": ["station_name"] } } }] ) message = completion.choices[0].message if message.tool_calls: tool_call = message.tool_calls[0] args = json.loads(tool_call.function.arguments) result = get_most_popular_song(args["station_name"]) followup = client.chat.completions.create( model="oss-gpt-120b", messages=[ {"role": "user", "content": "What is the most popular song on Neo Tokyo FM?"}, message, {"role": "tool", "tool_call_id": tool_call.id, "content": result} ] ) print(followup.choices[0].message.content)

如需使用函數呼叫回應 API 和聊天完成 API 的 詳細資訊,請參閱 OpenAI 中的函數呼叫

使用 Converse API 進行用戶端工具

您可以使用 Converse API,讓模型在對話中使用工具。下列 Python 範例示範如何使用在虛構廣播台上傳回最熱門歌曲的工具。

# Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. # SPDX-License-Identifier: Apache-2.0 """Shows how to use tools with the Converse API and the Cohere Command R model.""" import logging import json import boto3 from botocore.exceptions import ClientError class StationNotFoundError(Exception): """Raised when a radio station isn't found.""" pass logger = logging.getLogger(__name__) logging.basicConfig(level=logging.INFO) def get_top_song(call_sign): """Returns the most popular song for the requested station. Args: call_sign (str): The call sign for the station for which you want the most popular song. Returns: response (json): The most popular song and artist. """ song = "" artist = "" if call_sign == 'WZPZ': song = "Elemental Hotel" artist = "8 Storey Hike" else: raise StationNotFoundError(f"Station {call_sign} not found.") return song, artist def generate_text(bedrock_client, model_id, tool_config, input_text): """Generates text using the supplied Amazon Bedrock model. If necessary, the function handles tool use requests and sends the result to the model. Args: bedrock_client: The Boto3 Bedrock runtime client. model_id (str): The Amazon Bedrock model ID. tool_config (dict): The tool configuration. input_text (str): The input text. Returns: Nothing. """ logger.info("Generating text with model %s", model_id) # Create the initial message from the user input. messages = [{"role": "user", "content": [{"text": input_text}]}] response = bedrock_client.converse(modelId=model_id, messages=messages, toolConfig=tool_config) output_message = response['output']['message'] messages.append(output_message) stop_reason = response['stopReason'] if stop_reason == 'tool_use': # Tool use requested. Call the tool and send the result to the model. tool_requests = response['output']['message']['content'] for tool_request in tool_requests: if 'toolUse' in tool_request: tool = tool_request['toolUse'] logger.info("Requesting tool %s. Request: %s", tool['name'], tool['toolUseId']) if tool['name'] == 'top_song': tool_result = {} try: song, artist = get_top_song(tool['input']['sign']) tool_result = {"toolUseId": tool['toolUseId'], "content": [{"json": {"song": song, "artist": artist}}]} except StationNotFoundError as err: tool_result = {"toolUseId": tool['toolUseId'], "content": [{"text": err.args[0]}], "status": 'error'} tool_result_message = {"role": "user", "content": [{"toolResult": tool_result}]} messages.append(tool_result_message) # Send the tool result to the model. response = bedrock_client.converse(modelId=model_id, messages=messages, toolConfig=tool_config) output_message = response['output']['message'] # print the final response from the model. for content in output_message['content']: print(json.dumps(content, indent=4)) def main(): """Entrypoint for tool use example.""" logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s") model_id = "cohere.command-r-v1:0" input_text = "What is the most popular song on WZPZ?" tool_config = { "tools": [ { "toolSpec": { "name": "top_song", "description": "Get the most popular song played on a radio station.", "inputSchema": { "json": { "type": "object", "properties": { "sign": { "type": "string", "description": "The call sign for the radio station for which you want the most popular song. Example calls signs are WZPZ, and WKRP." } }, "required": ["sign"] } } } } ] } bedrock_client = boto3.client(service_name='bedrock-runtime') try: print(f"Question: {input_text}") generate_text(bedrock_client, model_id, tool_config, input_text) except ClientError as err: message = err.response['Error']['Message'] logger.error("A client error occurred: %s", message) print(f"A client error occured: {message}") else: print(f"Finished generating text with model {model_id}.") if __name__ == "__main__": main()

將調用 APIs用於用戶端工具

您可以搭配基本推論操作 (InvokeModelInvokeModelWithResponseStream) 使用工具。若要尋找您在請求內文中傳遞的推論參數,請參閱所要使用模型的推論參數

伺服器端工具呼叫

如果您使用回應 API 來叫用模型,則除了我們之前討論的用戶端工具呼叫之外,它還可以使用伺服器端工具呼叫。伺服器端工具呼叫是一種機制,其中工具 APIs、函數、工作流程) 是在信任的後端環境中執行,而不是在用戶端上執行。這可改善應用程式的安全性、可靠性和控管狀態。在 Amazon Bedrock 執行實作工具使用的 Lambda 函數之前,它會確保 Lambda 函數具有與呼叫它的應用程式相同的 IAM 政策。隨著 Amazon Bedrock 推動工具的執行,用戶端可以專注於實作其商業邏輯,而不是新增工具功能。Amazon Bedrock 也支援最高的控管標準,例如符合 ISO、SOC 和 HIPAA 資格。客戶可以提交自己的自訂 Lambda 函數來執行工具,或使用現有的預先定義工具,例如備註和任務。使用 Responses API 的伺服器端工具從 OpenAI 的 GPT OSS 20B/120B 模型開始可用,並支援即將推出的其他模型。您可以使用模型 API 來探索可與回應 API 搭配使用的可用模型。如需回應 API 的詳細資訊,請參閱使用 OpenAI APIs產生回應

您可以搭配 Amazon Bedrock 使用兩種類型的工具:使用 Lambda 的自訂工具,或 Bedrock 支援的預先定義工具。在本節中,我們將檢閱如何使用 Responses API 建立自訂 Lambda 工具。讓我們詳細討論兩者。

在回應 API 中使用 Lambda 的自訂工具

透過使用 Lambda 函數作為 Bedrock 中的自訂工具,您可以透過將自訂 AWS Lambda 函數整合為工具來擴展代理程式的功能。這可讓您建立無伺服器、可擴展的工具,AI 助理和其他應用程式可透過模型內容通訊協定 (MCP) 呼叫這些工具。以下是此功能的優點:

  • 擴展功能:新增自訂商業邏輯、API 整合或資料處理功能。

  • 安全地執行工具:Lambda 允許工具存取 VPC 內的資源,而不必授予完整的 VPC 存取權。

  • 無伺服器架構:沒有基礎設施管理,Lambda 會自動處理擴展。

  • 成本效益:僅支付執行時間,而非閒置資源。

  • 輕鬆整合:Lambda 函數與內建工具一起無縫顯示。

若要讓 Amazon Bedrock 中的模型使用工具來完成訊息的回應,您可以將訊息和一或多個工具的定義傳送到模型。根據您應用程式的提示,如果模型判斷其中一個工具可協助產生回應,則會傳回 Bedrock 使用該工具的請求,並將工具結果傳回模型。模型接著會使用結果來產生對原始訊息的回應。

下列步驟說明如何搭配 Responses API 使用工具。

運作方式

  1. Lambda 函數:建立實作 MCP 通訊協定的 Lambda 函數

  2. 工具探索:Bedrock 呼叫您的 Lambda 函數來探索可用的工具

  3. 工具註冊:您的工具已向 Bedrock 註冊

  4. 工具執行:當代理程式請求您的工具時, Bedrock 會叫用您的 Lambda 函數

  5. 回應處理:結果會透過標準界面傳回給客服人員

步驟 1:定義 Lambda 函數以取得最熱門的歌曲

建立實作 MCP 通訊協定的 Lambda 函數。以下是簡單的 Python 範例:

import json def lambda_handler(event, context): # Parse JSON-RPC request method = event.get('method') params = event.get('params', {}) request_id = event.get('id') if method == 'tools/list': return { "jsonrpc": "2.0", "id": request_id, "result": { "tools": [ { "name": "my_custom_tool", "description": "My custom business logic tool", "inputSchema": { "type": "object", "properties": { "input": { "type": "string", "description": "Input text to process" } }, "required": ["input"] } } ] } } elif method == 'tools/call': tool_name = params.get('name') arguments = params.get('arguments', {}) if tool_name == 'my_custom_tool': # Your custom logic here result = f"Processed: {arguments.get('input', '')}" return { "jsonrpc": "2.0", "id": request_id, "result": { "content": [ { "type": "text", "text": result } ] } } # Error response for unsupported methods return { "jsonrpc": "2.0", "id": request_id, "error": { "code": -32601, "message": "Method not found" } }

步驟 2:部署 Lambda 函數

接著,使用您的 IAM 角色部署此 Lambda 函數以取得 ARN。您可以在此處閱讀更多有關部署 Lambda 函數的資訊。

# Example using AWS CLI aws lambda create-function \ --function-name my-custom-tool \ --runtime python3.14 \ --role arn:aws:iam::YOUR-ACCOUNT:role/lambda-execution-role \ --handler lambda_function.lambda_handler \ --zip-file fileb://function.zip

假設您的 ARN 是: arn:aws:lambda:us-west-2:123456789012:function:my-custom-tool

步驟 3:在推論請求中定義訊息和工具定義

若要傳送訊息和工具定義,您可以使用 Responses API 操作。Amazon Bedrock 使用 Responses API 的連接器和遠端 MCP 伺服器功能來提供工具使用功能。工具的定義是您在 mcp 請求參數中傳遞至建立操作的 JSON 結構描述。在回應連接器 API 的 connector_id 欄位中,您可以傳入您在上一個步驟中建立的 Lambda ARN。您不需要提供授權登入資料,因為 Bedrock 使用與叫用模型的應用程式相同的 IAM 角色和政策。以下是工具的範例結構描述,該工具會取得在廣播電台上播放的熱門歌曲。

from openai import OpenAI client = OpenAI() resp = client.responses.create( model="oss-gpt-120b", tools=[ { "type": "mcp", "server_label": "xamzn_arn", "connector_id": "arn:aws:lambda:us-west-2:123456789012:function:my-custom-tool", "require_approval": "never", }, ], input="My custom prompt.", ) print(resp.output_text)

步驟 4:Bedrock 呼叫工具並將回應傳遞回模型

支援 Responses API 的模型提供使用連接器工具的功能。在此處檢查哪些工具支援您的模型。當您使用 回應 API 使用工具時,您只需支付匯入工具定義或進行工具呼叫時使用的字符。每個工具呼叫不收取額外費用。

當您在 tools 參數中指定 Lambda 函數時,API 會嘗試從伺服器取得工具清單。如果成功擷取工具清單,新的mcp_list_tools輸出項目會出現在模型回應輸出中。此物件的 tools 屬性會顯示已成功匯入的工具。一旦模型可以存取這些工具定義,它可以選擇根據模型內容中的內容來呼叫它們。當模型決定呼叫 Lambda 工具時,API 將向 Lambda 函數提出請求,以呼叫該工具並將其輸出放入模型的內容中。您可以在 OpenAI 文件的清單工具和呼叫工具上閱讀更多資訊。請注意,您的 Lambda 函數必須與在 Bedrock 中呼叫模型的應用程式連接相同的 IAM 角色和政策,否則 Lambda 函數會失敗。以下是錯誤定義。

{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "Tool execution failed", "data": "Additional error details" } }

在回應 API 中使用 AWS 提供的工具

Bedrock 提供兩種 AWS 提供的工具:筆記功能 (備註工具) 和任務管理 (任務工具)。讓我們詳細介紹兩者。

Notes 工具概觀

notes工具可讓您在相同的對話工作階段中存放和擷取鍵/值對。這提供了簡單的記憶體機制,用於維護多個互動之間的內容。金鑰是區分大小寫的字串,金鑰長度或命名慣例沒有限制。系統會覆寫相同金鑰的先前值。值會儲存為字串 (JSON、URLs等),且在工具層級不會強制執行大小限制。值會在整個對話工作階段中保留。記憶體範圍僅限於目前的對話。

參數

參數 Type 必要 描述
operation string 要執行的操作: "store""recall"
key string 記憶體項目的金鑰識別符
value string 有條件 要存放的值 (僅"store"操作需要)

有效操作

  • store:將鍵/值對儲存至記憶體

  • recall:依索引鍵擷取值

您可以使用自然語言 (例如,「記住我最愛的顏色是藍色」、「我告訴過您我最愛的顏色是什麼?」、「儲存我偏好早會的事實」、「回想我說過的會議偏好設定」) 或您可以在提示中使用直接工具呼叫 (「使用筆記工具將我的電子郵件儲存為 john@example.com」、「查看我電子郵件地址的筆記」)。

任務工具概觀

tasks工具提供Last-In-First-Out(LIFO) 堆疊,用於管理對話工作階段中的任務。這可讓您將任務推送至堆疊,並以相反順序將其彈出,因此非常適合管理巢狀工作流程、暫時提醒或階層式任務管理。任務會在整個對話工作階段中保留。堆疊狀態會在多個互動之間維持。記憶體範圍僅限於目前的對話。

參數 Type 必要 描述
operation string 要執行的操作: "push""pop"
description string 有條件 任務項目的描述 (僅"push"操作需要)
summary string 有關任務項目的選用摘要 (僅適用於 "push"操作)

您可以使用自然語言 (例如「新增任務以檢閱預算」、「推送提醒以呼叫用戶端」、「我需要執行的下一個任務是什麼?」、「退出最新任務」、「從我的堆疊取得最新任務」) 或直接在提示中呼叫工具 (「使用任務工具來推送「完成簡報」、「從堆疊中提取任務」、「新增「排程會議」到我的任務清單」)。

伺服器端工具使用與 AgentCore Gateway 整合

Amazon Bedrock 現在支援 AgentCore Gateway 做為呼叫整合類型的伺服器端工具。此功能可讓您將模型直接連線至 AgentCore Gateway 端點,以便無縫存取透過閘道基礎設施管理的工具。

AgentCore Gateway 整合遵循與 Lambda 函數整合相同的模式,具有一個關鍵差異。

Lambda 整合:

  • 使用 Lambda ARNs

  • 直接叫用 AWS Lambda 函數

AgentCore Gateway 整合:

  • 使用 AgentCore Gateway ARNs

  • 透過 AgentCore Gateway 基礎設施路由工具呼叫

  • 提供集中式工具管理和探索

Configuration

請求結構

將 AgentCore Gateway 設定為工具來源時,請在回應 API 請求的tools陣列中使用下列結構。

{ "type":"mcp", "server_label":"agentcore_tools", "connector_id":"arn:aws:bedrock-agentcore:us-west-2:342789630635:gateway/agentcore-intro-gateway-v2-swvq44sovp", "server_description":"AgentCore Gateway providing custom tools", "require_approval":"never" }

參數

參數 Type 必要 描述
type string 必須設定為 mcp
server_label string 請求中此工具連接器的唯一識別符
connector_id string AgentCore Gateway 的 ARN
server_description string 此閘道所提供工具的人類可讀描述
require_approval string 欄位必須是 "never"

完成請求範例

{ "model":"openai.gpt-oss-120b", "stream":true, "background":false, "store":false, "tools": [ { "type":"mcp", "server_label":"agentcore_tools", "connector_id":"arn:aws:bedrock-agentcore:us-west-2:342789630635:gateway/agentcore-intro-gateway-v2-swvq44sovp", "server_description":"AgentCore Gateway providing custom tools", "require_approval":"never" } ], "input": [ { "type":"message", "role":"user", "content": [ { "type":"input_text", "text":"What is the weather in Seattle?" } ] } ] }

先決條件

使用 AgentCore Gateway 整合之前,請確定您有:

  1. 建立具有設定目標的 AgentCore Gateway (Lambda 函數、API Gateway 階段、OpenAPI 結構描述或 MCP 伺服器)

  2. 已設定的 IAM 許可,允許 Bedrock 服務角色叫用閘道。請注意,Bedrock 僅支援具有 IAM 身分驗證的閘道。

  3. 正確格式的閘道 ARN

AgentCore Gateway 整合的優點

  • 集中工具管理:透過單一閘道端點管理所有工具

  • 工具探索:客服人員可以透過閘道動態探索可用的工具

  • 安全性:透過 IAM 和閘道政策的內建身分驗證和授權

  • 觀測性:全面監控和記錄工具叫用

  • 彈性:支援多種目標類型 (Lambda、API Gateway、OpenAPI、MCP 伺服器)

IAM 許可

您的 Bedrock 執行角色需要許可才能叫用 AgentCore Gateway:

{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock-agentcore:InvokeGateway" ], "Resource": "arn:aws:bedrock-agentcore:us-west-2:342789630635:gateway/agentcore-intro-gateway-v2-swvq44sovp" } ] }

後續步驟