ai newsDo., 22. Okt.
EilmeldungYear-old AI research lab Flapping Airplanes raises $1B at a reported $6B valuation

Adaptive agentic intelligence framework using Strands Agents

The Adaptive Agentic Intelligence Framework (AAIF), built with Strands Agents, handles routine tasks locally with small language models and routes complex requests to cloud models through Amazon Bedrock. This post walks through building AAIF with local SLMs through Ollama and Amazon Bedrock, using a

AWS ML BlogMittwoch 23:23 · 21.10.9 Min. Lesezeit
Bild: AWS ML Blog

Organizations building AI agents face a common challenge: Every request, whether a routine status check or complex analysis, typically gets routed to a single large, expensive model. This one-size-fits-all approach can drive up API costs, introduce unpredictable latency, and remove the possibility of offline operation. Even routine queries that could resolve locally end up requiring a full network round-trip to a cloud-hosted large language model (LLM).

The Adaptive Agentic Intelligence Framework (AAIF), built with Strands Agents, takes a different approach. Instead of routing all requests to a single large model, AAIF uses small language models (SLMs) to handle routine tasks locally. More complex requests are routed to cloud-hosted models through Amazon Bedrock. This approach builds on the research position from Belcak et al. at NVIDIA. They argue that small language models are “sufficiently powerful, inherently more suitable, and necessarily more economical for many invocations in agentic systems.” Built on Strands Agents, the framework demonstrates how intelligent model orchestration can help reduce costs while maintaining low latency for local operations.

In this post, we walk through the key components of AAIF using Strands Agents with local SLMs through Ollama and cloud models through Amazon Bedrock. We use an Internet of Things (IoT) monitoring scenario as a reference implementation.

AAIF organizes AI processing into three layers, each optimized for different task types, as Figure 1 shows:

Figure 1: The three AAIF processing layers for smart orchestration, local processing, and cloud processing

Figure 1 shows the complete AAIF system architecture. At the center sits the Strands agent, which connects to an Ollama runtime hosting both the 1B-parameter orchestrator model and the vision model. The agent exposes three tools: get_device_telemetry for local sensor data retrieval, analyze_camera_feed for on-device vision processing through llama3.2-vision, and get_expert_insights which calls Amazon Bedrock through boto3 for complex analysis. Incoming user requests flow through the SLM orchestrator, which classifies each request and dispatches it to either a local tool or the cloud endpoint based on task complexity.

Figure 2: Complete AAIF system architecture showing the Strands agent, Ollama runtime, tool integrations, and Amazon Bedrock connectivity

The framework adapts to your deployment constraints rather than requiring you to restructure your infrastructure around it. This architecture runs on edge devices like a Raspberry Pi with 8 GB of memory, in full cloud deployments where all inference hits Amazon Bedrock, or in hybrid configurations that combine local speed with cloud reasoning. The flexibility comes from separating the routing logic (the SLM orchestrator) from the processing tools, which you can swap or reconfigure independently depending on available hardware and network connectivity.

For this walkthrough, you should have the following prerequisites:

Create a project directory and start the Ollama server:

mkdir aaif-demo && cd aaif-demo ollama serve Pull the required models:

ollama pull llama3.2:1b ollama pull llama3.2-vision Create a file called aaif_agent.py and add the following components.

Strands Agents uses the @tool decorator to define capabilities that agents can invoke. Start by creating tools for local processing.

The first tool retrieves device telemetry data. In a production environment, this would connect to actual IoT sensors. For this walkthrough, it uses simulated device data:

from strands import Agent, tool import random DEVICE_TELEMETRY = { "sensor-001": { "device_type": "Temperature Sensor", "location": "Building A - Floor 2", "temperature": 72.5, "humidity": 45.2, "status": "normal" }, "camera-001": { "device_type": "Security Camera", "location": "Main Entrance", "fps": 30, "resolution": "1080p", "status": "recording" }, "hvac-001": { "device_type": "HVAC Controller", "location": "Building A - Central", "set_temp": 71.0, "current_temp": 72.5, "mode": "cooling", "status": "active" } } @tool def get_device_telemetry() -> str: """Retrieve current telemetry data from connected IoT devices.""" device_id = random.choice(list(DEVICE_TELEMETRY.keys())) device_data = DEVICE_TELEMETRY[device_id] report = f"Device: {device_id} ({device_data['device_type']})\n" report += f"Location: {device_data['location']}\n" report += f"Status: {device_data['status']}\n" for key, value in device_data.items(): if key not in ['device_type', 'location', 'status']: report += f"{key}: {value}\n" return report The second tool performs vision analysis using a local SLM. The llama3.2-vision model runs entirely on local hardware, which means sensitive camera feeds don’t leave the device:

import ollama @tool def analyze_camera_feed(image_path: str) -> str: """Analyze visual data from cameras using local vision model.""" stream = ollama.chat( model='llama3.2-vision', messages=[{ 'role': 'user', 'content': 'Describe this image in one sentence. ' 'What are the 3 most important things you see?', 'images': [image_path] }], stream=True, ) full_response = "" for chunk in stream: chunk_content = chunk['message']['content'] print(chunk_content, end='', flush=True) full_response += chunk_content return f"Object Detection Report:\n{full_response}" Implement cloud processing For complex analysis that requires broader reasoning, create a tool that calls Amazon Bedrock. This tool is invoked only when the orchestrator determines that local models can’t handle the request:

import boto3 @tool def get_expert_insights(context_data: str, question: str) -> str: """Get advanced analysis and expert recommendations for complex questions via Amazon Bedrock.""" client = boto3.client("bedrock-runtime", region_name="us-east-1") conversation = [ { "role": "user", "content": [ {"text": f"Context: {context_data}\n\nQuestion: {question}"} ], } ] response = client.converse( modelId="<<model_id>", //Refer model id [details](https://docs.aws.amazon.com/bedrock/latest/userguide/foundation-models-reference.html) messages=conversation, inferenceConfig={ "maxTokens": 512, "temperature": 0.5, "topP": 0.9 } ) response_text = response["output"]["message"]["content"]["text"] return f"Expert Analysis:\n{response_text}" Configure the Strands agent with smart orchestration The core of AAIF is the Strands agent configuration. The agent uses a local SLM (llama3.2:1b) as its orchestrator. Strands Agents supports multiple model providers, and here we use the Ollama provider to run the orchestrator locally:

from strands.models.ollama import OllamaModel model = OllamaModel( model_id="llama3.2:1b", host="http://localhost:11434", params={ "max_tokens": 300, "temperature": 0.3, }, ) system_prompt = """You are a monitoring assistant for operational facilities. You have access to device telemetry tools, analysis capabilities, and expert insights to help monitor operations effectively. When users ask for: - Device status or telemetry: use get_device_telemetry - Image or data analysis: use analyze_camera_feed - Expert advice or complex questions: use get_expert_insights Always return the complete tool results directly to the user.""" agent = Agent( model=model, system_prompt=system_prompt, tools=[ get_device_telemetry, analyze_camera_feed, get_expert_insights, ], ) The SLM-powered orchestrator analyzes each request and routes it to the appropriate tool without hardcoded keyword matching.

The routing happens through the model’s understanding of the request:

Table 1: Request, routing, and latency estimates for local compared to cloud inference

With the agent configured, you can interact with it directly:

# Local processing - device telemetry response = agent("What's the current status of our devices?") print(response) # Local processing - vision analysis response = agent("Analyze the camera feed from camera-001") print(response) # Cloud processing - complex analysis response = agent( "Based on current telemetry patterns, " "what optimization strategies do you recommend?" ) print(response) The agent automatically classifies each request and routes it to the appropriate processing layer. No explicit routing rules are needed.

The AAIF architecture adapts to different infrastructure requirements by changing the model configuration:

When your workload runs entirely in the cloud and no edge hardware is available, replace the Ollama model configuration with Amazon Bedrock for all processing. This routes every request through managed cloud inference, giving you auto scaling without requiring local GPU resources. Teams with reliable low-latency connectivity and no data residency constraints benefit most from this configuration:

from strands.models import BedrockModel model = BedrockModel( model_id="<<model_id>", //Refer model id [details](https://docs.aws.amazon.com/bedrock/latest/userguide/foundation-models-reference.html) region_name="us-east-1" ) The hybrid configuration keeps the local SLM orchestrator intact while adding cloud models for requests that exceed local model capabilities. This is the default AAIF configuration shown in this walkthrough. It suits environments where most requests are routine enough to resolve locally, but some require the broader reasoning of a larger model. Cost savings can come from the roughly 80 percent of traffic that doesn’t hit a paid API endpoint.

For environments that are fully air-gapped or have strict data sovereignty requirements, replace the cloud tool with a larger local model and run all processing on-device. A 3B-parameter model running on hardware with adequate memory can handle moderately complex tasks that the 1B orchestrator would otherwise escalate. The trade-off is reduced reasoning depth on the hardest queries, but the benefit is data not leaving the premises:

model = OllamaModel( model_id="llama3.2:3b", # Larger local model for complex tasks host="http://localhost:11434", ) Looking ahead: Centralized tool calling with MCP servers The implementation in this post uses local tool calls defined directly in the agent code. For production deployments with multiple agents sharing tools across services, expose these tools as Model Context Protocol (MCP) servers. MCP provides a standardized interface for tool discovery and invocation, so you can centralize tool management and reuse tools across different agents and environments. In Figure 3, we show how to convert AAIF tools into MCP servers for distributed, centralized tool calling.

In the distributed configuration as shown in Figure 3, Device 1 acts as the orchestrating hub, running the Strands agent with the SLM router and a local telemetry tool. It connects through the MCP protocol to Device 2, which runs an edge vision processing server with llama3.2-vision. Device 3 serves as a cloud analytics gateway connected to Amazon Bedrock. From the orchestrator’s perspective, all remote tools appear as local function calls because the MCP transport layer handles serialization and network communication transparently.

Figure 3: Distributed intelligence with MCP servers

To avoid incurring future charges, complete the following cleanup steps:

ollama stop ollama rm llama3.2:1b ollama rm llama3.2-vision Delete the project directory if you no longer need the sample code: rm -rf aaif-demo Conclusion We showed how to build cost-effective AI agents using the Adaptive Agentic Intelligence Framework with Strands Agents. By routing routine requests to local SLMs and reserving cloud models on Amazon Bedrock for complex analysis, AAIF can help reduce API costs while maintaining low latency for routine operations.

Before you run this pattern in production, add responsible AI controls to the cloud inference path, since those requests carry tool outputs, retrieved data, and user input. You can attach Amazon Bedrock Guardrails to the Strands BedrockModel with a guardrail ID and version. It then applies content filters for harmful categories, prompt injection filters, and contextual grounding checks that block responses not supported by the source data. To apply the same policies to the local SLM tier, call the standalone ApplyGuardrail API on its inputs and outputs. This way, every request follows one safety standard no matter which model handles it.

This architectural pattern applies beyond IoT monitoring. A healthcare organization could run patient monitoring locally while routing diagnosis support to cloud models. A financial services firm could process transactions on-premises and reserve cloud capacity for risk analysis. A manufacturing team could run quality control vision models at the edge while sending optimization requests to the cloud.

To learn more about building agents with Strands Agents, visit the Strands Agents documentation. For information about available foundation models, see Amazon Bedrock.

Nitin is a Principal Solutions Architect at AWS, specializing in generative AI and agentic systems. He focuses on helping customers build intelligent, cost-effective AI solutions across cloud and edge environments.

Mani is a Principal Solutions Architect at AWS, focused on AI/ML and generative AI. She helps customers adopt scalable AI solutions and is passionate about advancing responsible AI practices.

Quelle: AWS ML Blog (AWS ML Blog). Original öffnen