Amazon Bedrock Runtime-Beispiele für die Verwendung von SDK Rust - AWS SDKCode-Beispiele

Weitere AWS SDK Beispiele sind im Repo AWS Doc SDK Examples GitHub verfügbar.

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

Amazon Bedrock Runtime-Beispiele für die Verwendung von SDK Rust

Die folgenden Codebeispiele zeigen Ihnen, wie Sie mithilfe von AWS SDK for Rust with Amazon Bedrock Runtime Aktionen ausführen und allgemeine Szenarien implementieren.

Jedes Beispiel enthält einen Link zum vollständigen Quellcode, in dem Sie Anweisungen zur Einrichtung und Ausführung des Codes im Kontext finden.

Anthropic Claude

Das folgende Codebeispiel zeigt, wie Sie mithilfe von Bedrocks Converse eine Textnachricht an Anthropic Claude senden. API

SDKfür Rust
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

Sende mit Bedrocks Converse eine Textnachricht an Anthropic Claude. API

#[tokio::main] async fn main() -> Result<(), BedrockConverseError> { tracing_subscriber::fmt::init(); let sdk_config = aws_config::defaults(BehaviorVersion::latest()) .region(CLAUDE_REGION) .load() .await; let client = Client::new(&sdk_config); let response = client .converse() .model_id(MODEL_ID) .messages( Message::builder() .role(ConversationRole::User) .content(ContentBlock::Text(USER_MESSAGE.to_string())) .build() .map_err(|_| "failed to build message")?, ) .send() .await; match response { Ok(output) => { let text = get_converse_output_text(output)?; println!("{}", text); Ok(()) } Err(e) => Err(e .as_service_error() .map(BedrockConverseError::from) .unwrap_or_else(|| BedrockConverseError("Unknown service error".into()))), } } fn get_converse_output_text(output: ConverseOutput) -> Result<String, BedrockConverseError> { let text = output .output() .ok_or("no output")? .as_message() .map_err(|_| "output not a message")? .content() .first() .ok_or("no content in message")? .as_text() .map_err(|_| "content is not text")? .to_string(); Ok(text) }

Verwenden Sie Anweisungen, das Error-Hilfsprogramm und Konstanten.

use aws_config::BehaviorVersion; use aws_sdk_bedrockruntime::{ operation::converse::{ConverseError, ConverseOutput}, types::{ContentBlock, ConversationRole, Message}, Client, }; // Set the model ID, e.g., Claude 3 Haiku. const MODEL_ID: &str = "anthropic.claude-3-haiku-20240307-v1:0"; const CLAUDE_REGION: &str = "us-east-1"; // Start a conversation with the user message. const USER_MESSAGE: &str = "Describe the purpose of a 'hello world' program in one line."; #[derive(Debug)] struct BedrockConverseError(String); impl std::fmt::Display for BedrockConverseError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Can't invoke '{}'. Reason: {}", MODEL_ID, self.0) } } impl std::error::Error for BedrockConverseError {} impl From<&str> for BedrockConverseError { fn from(value: &str) -> Self { BedrockConverseError(value.to_string()) } } impl From<&ConverseError> for BedrockConverseError { fn from(value: &ConverseError) -> Self { BedrockConverseError::from(match value { ConverseError::ModelTimeoutException(_) => "Model took too long", ConverseError::ModelNotReadyException(_) => "Model is not ready", _ => "Unknown", }) } }
  • APIEinzelheiten finden Sie unter Converse in der AWS SDKAPIRust-Referenz.

Das folgende Codebeispiel zeigt, wie Sie mithilfe von Bedrocks Converse eine Textnachricht an Anthropic Claude senden API und den Antwortstream in Echtzeit verarbeiten.

SDKfür Rust
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

Senden Sie eine Textnachricht an Anthropic Claude und streamen Sie Antwort-Token mit Bedrocks. ConverseStream API

#[tokio::main] async fn main() -> Result<(), BedrockConverseStreamError> { tracing_subscriber::fmt::init(); let sdk_config = aws_config::defaults(BehaviorVersion::latest()) .region(CLAUDE_REGION) .load() .await; let client = Client::new(&sdk_config); let response = client .converse_stream() .model_id(MODEL_ID) .messages( Message::builder() .role(ConversationRole::User) .content(ContentBlock::Text(USER_MESSAGE.to_string())) .build() .map_err(|_| "failed to build message")?, ) .send() .await; let mut stream = match response { Ok(output) => Ok(output.stream), Err(e) => Err(BedrockConverseStreamError::from( e.as_service_error().unwrap(), )), }?; loop { let token = stream.recv().await; match token { Ok(Some(text)) => { let next = get_converse_output_text(text)?; print!("{}", next); Ok(()) } Ok(None) => break, Err(e) => Err(e .as_service_error() .map(BedrockConverseStreamError::from) .unwrap_or(BedrockConverseStreamError( "Unknown error receiving stream".into(), ))), }? } println!(); Ok(()) } fn get_converse_output_text( output: ConverseStreamOutputType, ) -> Result<String, BedrockConverseStreamError> { Ok(match output { ConverseStreamOutputType::ContentBlockDelta(event) => match event.delta() { Some(delta) => delta.as_text().cloned().unwrap_or_else(|_| "".into()), None => "".into(), }, _ => "".into(), }) }

Verwenden Sie Anweisungen, das Error-Hilfsprogramm und Konstanten.

use aws_config::BehaviorVersion; use aws_sdk_bedrockruntime::{ error::ProvideErrorMetadata, operation::converse_stream::ConverseStreamError, types::{ error::ConverseStreamOutputError, ContentBlock, ConversationRole, ConverseStreamOutput as ConverseStreamOutputType, Message, }, Client, }; // Set the model ID, e.g., Claude 3 Haiku. const MODEL_ID: &str = "anthropic.claude-3-haiku-20240307-v1:0"; const CLAUDE_REGION: &str = "us-east-1"; // Start a conversation with the user message. const USER_MESSAGE: &str = "Describe the purpose of a 'hello world' program in one line."; #[derive(Debug)] struct BedrockConverseStreamError(String); impl std::fmt::Display for BedrockConverseStreamError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Can't invoke '{}'. Reason: {}", MODEL_ID, self.0) } } impl std::error::Error for BedrockConverseStreamError {} impl From<&str> for BedrockConverseStreamError { fn from(value: &str) -> Self { BedrockConverseStreamError(value.into()) } } impl From<&ConverseStreamError> for BedrockConverseStreamError { fn from(value: &ConverseStreamError) -> Self { BedrockConverseStreamError( match value { ConverseStreamError::ModelTimeoutException(_) => "Model took too long", ConverseStreamError::ModelNotReadyException(_) => "Model is not ready", _ => "Unknown", } .into(), ) } } impl From<&ConverseStreamOutputError> for BedrockConverseStreamError { fn from(value: &ConverseStreamOutputError) -> Self { match value { ConverseStreamOutputError::ValidationException(ve) => BedrockConverseStreamError( ve.message().unwrap_or("Unknown ValidationException").into(), ), ConverseStreamOutputError::ThrottlingException(te) => BedrockConverseStreamError( te.message().unwrap_or("Unknown ThrottlingException").into(), ), value => BedrockConverseStreamError( value .message() .unwrap_or("Unknown StreamOutput exception") .into(), ), } } }
  • APIEinzelheiten finden Sie ConverseStreamin der AWS SDKAPIRust-Referenz.

Das folgende Codebeispiel zeigt, wie eine typische Interaktion zwischen einer Anwendung, einem generativen KI-Modell und verbundenen Tools aufgebaut oder APIs Interaktionen zwischen der KI und der Außenwelt vermittelt werden. Es verwendet das Beispiel der Verbindung eines externen Wetters mit API dem KI-Modell, sodass Wetterinformationen in Echtzeit auf der Grundlage von Benutzereingaben bereitgestellt werden können.

SDKfür Rust
Anmerkung

Es gibt noch mehr dazu GitHub. Sie sehen das vollständige Beispiel und erfahren, wie Sie das AWS -Code-Beispiel-Repository einrichten und ausführen.

Das primäre Szenario und die Logik für die Demo. Dies orchestriert die Konversation zwischen dem Benutzer, dem Amazon Bedrock Converse und einem API Wetter-Tool.

#[derive(Debug)] #[allow(dead_code)] struct InvokeToolResult(String, ToolResultBlock); struct ToolUseScenario { client: Client, conversation: Vec<Message>, system_prompt: SystemContentBlock, tool_config: ToolConfiguration, } impl ToolUseScenario { fn new(client: Client) -> Self { let system_prompt = SystemContentBlock::Text(SYSTEM_PROMPT.into()); let tool_config = ToolConfiguration::builder() .tools(Tool::ToolSpec( ToolSpecification::builder() .name(TOOL_NAME) .description(TOOL_DESCRIPTION) .input_schema(ToolInputSchema::Json(make_tool_schema())) .build() .unwrap(), )) .build() .unwrap(); ToolUseScenario { client, conversation: vec![], system_prompt, tool_config, } } async fn run(&mut self) -> Result<(), ToolUseScenarioError> { loop { let input = get_input().await?; if input.is_none() { break; } let message = Message::builder() .role(User) .content(ContentBlock::Text(input.unwrap())) .build() .map_err(ToolUseScenarioError::from)?; self.conversation.push(message); let response = self.send_to_bedrock().await?; self.process_model_response(response).await?; } Ok(()) } async fn send_to_bedrock(&mut self) -> Result<ConverseOutput, ToolUseScenarioError> { debug!("Sending conversation to bedrock"); self.client .converse() .model_id(MODEL_ID) .set_messages(Some(self.conversation.clone())) .system(self.system_prompt.clone()) .tool_config(self.tool_config.clone()) .send() .await .map_err(ToolUseScenarioError::from) } async fn process_model_response( &mut self, mut response: ConverseOutput, ) -> Result<(), ToolUseScenarioError> { let mut iteration = 0; while iteration < MAX_RECURSIONS { iteration += 1; let message = if let Some(ref output) = response.output { if output.is_message() { Ok(output.as_message().unwrap().clone()) } else { Err(ToolUseScenarioError( "Converse Output is not a message".into(), )) } } else { Err(ToolUseScenarioError("Missing Converse Output".into())) }?; self.conversation.push(message.clone()); match response.stop_reason { StopReason::ToolUse => { response = self.handle_tool_use(&message).await?; } StopReason::EndTurn => { print_model_response(&message.content[0])?; return Ok(()); } _ => (), } } Err(ToolUseScenarioError( "Exceeded MAX_ITERATIONS when calling tools".into(), )) } async fn handle_tool_use( &mut self, message: &Message, ) -> Result<ConverseOutput, ToolUseScenarioError> { let mut tool_results: Vec<ContentBlock> = vec![]; for block in &message.content { match block { ContentBlock::Text(_) => print_model_response(block)?, ContentBlock::ToolUse(tool) => { let tool_response = self.invoke_tool(tool).await?; tool_results.push(ContentBlock::ToolResult(tool_response.1)); } _ => (), }; } let message = Message::builder() .role(User) .set_content(Some(tool_results)) .build()?; self.conversation.push(message); self.send_to_bedrock().await } async fn invoke_tool( &mut self, tool: &ToolUseBlock, ) -> Result<InvokeToolResult, ToolUseScenarioError> { match tool.name() { TOOL_NAME => { println!( "\x1b[0;90mExecuting tool: {TOOL_NAME} with input: {:?}...\x1b[0m", tool.input() ); let content = fetch_weather_data(tool).await?; println!( "\x1b[0;90mTool responded with {:?}\x1b[0m", content.content() ); Ok(InvokeToolResult(tool.tool_use_id.clone(), content)) } _ => Err(ToolUseScenarioError(format!( "The requested tool with name {} does not exist", tool.name() ))), } } } #[tokio::main] async fn main() { tracing_subscriber::fmt::init(); let sdk_config = aws_config::defaults(BehaviorVersion::latest()) .region(CLAUDE_REGION) .load() .await; let client = Client::new(&sdk_config); let mut scenario = ToolUseScenario::new(client); header(); if let Err(err) = scenario.run().await { println!("There was an error running the scenario! {}", err.0) } footer(); }

Das von der Demo verwendete Wetter-Tool. Dieses Skript definiert die Werkzeugspezifikation und implementiert die Logik zum Abrufen von Wetterdaten mithilfe von Open-MeteoAPI.

const ENDPOINT: &str = "https://api.open-meteo.com/v1/forecast"; async fn fetch_weather_data( tool_use: &ToolUseBlock, ) -> Result<ToolResultBlock, ToolUseScenarioError> { let input = tool_use.input(); let latitude = input .as_object() .unwrap() .get("latitude") .unwrap() .as_string() .unwrap(); let longitude = input .as_object() .unwrap() .get("longitude") .unwrap() .as_string() .unwrap(); let params = [ ("latitude", latitude), ("longitude", longitude), ("current_weather", "true"), ]; debug!("Calling {ENDPOINT} with {params:?}"); let response = reqwest::Client::new() .get(ENDPOINT) .query(&params) .send() .await .map_err(|e| ToolUseScenarioError(format!("Error requesting weather: {e:?}")))? .error_for_status() .map_err(|e| ToolUseScenarioError(format!("Failed to request weather: {e:?}")))?; debug!("Response: {response:?}"); let bytes = response .bytes() .await .map_err(|e| ToolUseScenarioError(format!("Error reading response: {e:?}")))?; let result = String::from_utf8(bytes.to_vec()) .map_err(|_| ToolUseScenarioError("Response was not utf8".into()))?; Ok(ToolResultBlock::builder() .tool_use_id(tool_use.tool_use_id()) .content(ToolResultContentBlock::Text(result)) .build()?) }

Hilfsprogramme zum Drucken der Nachrichteninhaltsblöcke

fn print_model_response(block: &ContentBlock) -> Result<(), ToolUseScenarioError> { if block.is_text() { let text = block.as_text().unwrap(); println!("\x1b[0;90mThe model's response:\x1b[0m\n{text}"); Ok(()) } else { Err(ToolUseScenarioError(format!( "Content block is not text ({block:?})" ))) } }

Verwenden Sie Anweisungen, das Error-Hilfsprogramm und Konstanten.

use std::{collections::HashMap, io::stdin}; use aws_config::BehaviorVersion; use aws_sdk_bedrockruntime::{ error::{BuildError, SdkError}, operation::converse::{ConverseError, ConverseOutput}, types::{ ContentBlock, ConversationRole::User, Message, StopReason, SystemContentBlock, Tool, ToolConfiguration, ToolInputSchema, ToolResultBlock, ToolResultContentBlock, ToolSpecification, ToolUseBlock, }, Client, }; use aws_smithy_runtime_api::http::Response; use aws_smithy_types::Document; use tracing::debug; /// This demo illustrates a tool use scenario using Amazon Bedrock's Converse API and a weather tool. /// The script interacts with a foundation model on Amazon Bedrock to provide weather information based on user /// input. It uses the Open-Meteo API (https://open-meteo.com) to retrieve current weather data for a given location. // Set the model ID, e.g., Claude 3 Haiku. const MODEL_ID: &str = "anthropic.claude-3-haiku-20240307-v1:0"; const CLAUDE_REGION: &str = "us-east-1"; const SYSTEM_PROMPT: &str = "You are a weather assistant that provides current weather data for user-specified locations using only the Weather_Tool, which expects latitude and longitude. Infer the coordinates from the location yourself. If the user provides coordinates, infer the approximate location and refer to it in your response. To use the tool, you strictly apply the provided tool specification. - Explain your step-by-step process, and give brief updates before each step. - Only use the Weather_Tool for data. Never guess or make up information. - Repeat the tool use for subsequent requests if necessary. - If the tool errors, apologize, explain weather is unavailable, and suggest other options. - Report temperatures in °C (°F) and wind in km/h (mph). Keep weather reports concise. Sparingly use emojis where appropriate. - Only respond to weather queries. Remind off-topic users of your purpose. - Never claim to search online, access external data, or use tools besides Weather_Tool. - Complete the entire process until you have all required data before sending the complete response. "; // The maximum number of recursive calls allowed in the tool_use_demo function. // This helps prevent infinite loops and potential performance issues. const MAX_RECURSIONS: i8 = 5; const TOOL_NAME: &str = "Weather_Tool"; const TOOL_DESCRIPTION: &str = "Get the current weather for a given location, based on its WGS84 coordinates."; fn make_tool_schema() -> Document { Document::Object(HashMap::<String, Document>::from([ ("type".into(), Document::String("object".into())), ( "properties".into(), Document::Object(HashMap::from([ ( "latitude".into(), Document::Object(HashMap::from([ ("type".into(), Document::String("string".into())), ( "description".into(), Document::String("Geographical WGS84 latitude of the location.".into()), ), ])), ), ( "longitude".into(), Document::Object(HashMap::from([ ("type".into(), Document::String("string".into())), ( "description".into(), Document::String( "Geographical WGS84 longitude of the location.".into(), ), ), ])), ), ])), ), ( "required".into(), Document::Array(vec![ Document::String("latitude".into()), Document::String("longitude".into()), ]), ), ])) } #[derive(Debug)] struct ToolUseScenarioError(String); impl std::fmt::Display for ToolUseScenarioError { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { write!(f, "Tool use error with '{}'. Reason: {}", MODEL_ID, self.0) } } impl From<&str> for ToolUseScenarioError { fn from(value: &str) -> Self { ToolUseScenarioError(value.into()) } } impl From<BuildError> for ToolUseScenarioError { fn from(value: BuildError) -> Self { ToolUseScenarioError(value.to_string().clone()) } } impl From<SdkError<ConverseError, Response>> for ToolUseScenarioError { fn from(value: SdkError<ConverseError, Response>) -> Self { ToolUseScenarioError(match value.as_service_error() { Some(value) => value.meta().message().unwrap_or("Unknown").into(), None => "Unknown".into(), }) } }
  • APIEinzelheiten finden Sie unter Converse in der AWS SDKAPIRust-Referenz.