← Back to list

Zero to AI Agent: Orchestrating Phi-4 and LocalStack with .NET Aspire

I recently set out to build a Sovereign AI Agent. The goal: A background worker that can monitor AWS infrastructure and make autonomous…

Mohammed Naved · 2026-05-12 21:00 · 0 claps · 1.8 min read
#dotnet #dotnet-aspire #ollama #localstack #agentic-ai
Open on Medium ↗
Wiki topics: LLM · Large Language Models AGT · AI Agents ☁️ · DevOps & Cloud

Zero to AI Agent: Orchestrating Phi-4 and LocalStack with .NET Aspire

I recently set out to build a Sovereign AI Agent. The goal: A background worker that can monitor AWS infrastructure and make autonomous “Janitor” decisions (like cleaning up old S3 buckets) without ever sending a single byte of data to the cloud.

The result is SovereignAgent. Here is exactly how I built the services and wired them together.

The Architecture: The “Three Pillars”

To make this work, I needed three distinct environments to talk to each other seamlessly:

  1. The Infrastructure: LocalStack (S3, SQS, DynamoDB).
  2. The Intelligence: Ollama (Running Microsoft’s Phi-4).
  3. The Execution: A C# Worker Service.

Step 1: Orchestration with the AppHost

The secret sauce is .NET Aspire. Instead of writing complex docker-compose files and fighting with static IP addresses, I defined my entire ecosystem in C#

// AppHost/Program.cs
var localstack = builder.AddLocalStack("localstack");
var ollama = builder.AddOllama("ollama").AddModel("phi4");

builder.AddProject<Projects.SovereignAgent_ApiService>("apiservice")
       .WithReference(localstack)
       .WithReference(ollama);

Why this matters: Aspire automatically handles the networking bridge between these containers.

Step 2: Connecting the Services (The “Localhost” Trap)

The hardest part of service-to-service communication in containers is discovery. I initially hit a “Connection Refused” error because my worker was looking for Ollama on localhost:11434.

The Fix: I leveraged Aspire’s dynamic environment variables. By querying the connection string injected by the AppHost, my code automatically finds the correct dynamic port (e.g., 53245) assigned by the orchestrator.

// Grab the dynamic endpoint injected by Aspire
var connectionString = builder.Configuration.GetConnectionString("ollama");

// Register the AI Client using the discovered port
builder.Services.AddSingleton<IChatClient>(sp => 
    new OllamaApiClient(new Uri(endpoint), "phi4"));

Step 3: The “Janitor” Logic

My JanitorWorker is a standard BackgroundService. It polls an SQS queue for tasks. When a task arrives, it doesn't just execute it—it asks the AI for a "Security Review."

  1. Pull: SQS message arrives: “Delete bucket ‘temp-logs-2023’.”
  2. Think: The worker sends the intent to Phi-4.
  3. Act: If Phi-4 returns ACTION: YES, the worker uses the AmazonS3Client (pointing to LocalStack) to wipe the bucket.

What I Achieved

  • Complete Privacy: Using Microsoft.Extensions.AI and Ollama means my "Agent" is 100% offline.
  • Developer Velocity: I can wipe my entire environment and spin it back up (AI model and all) with one F5 press.
  • Elastic Scaling: Because I used Aspire, I can scale my workers or swap Phi-4 for a larger model like Llama 3 with a single line of code.

Final Thoughts

Building AI Agents isn’t just about the prompt; it’s about the plumbing. .NET Aspire makes that plumbing invisible, letting us focus on the “Sovereign” part of the AI.


메타데이터
post_id
05e58d3db45c
slug
zero-to-ai-agent-orchestrating-phi-4-and-localstack-with-net-aspire-05e58d3db45c
url
https://medium.com/@naved-shaikh/zero-to-ai-agent-orchestrating-phi-4-and-localstack-with-net-aspire-05e58d3db45c
canonical_url
https://medium.com/@naved-shaikh/zero-to-ai-agent-orchestrating-phi-4-and-localstack-with-net-aspire-05e58d3db45c
author_url
https://medium.com/@naved-shaikh
status
ok
fetched_at
2026-06-09 15:37:30