A few weeks ago, our AI IDE confidently proposed scaffolding for a real‑time collaboration app on Kubernetes:
services.AddSignalR().AddStackExchangeRedisBackplane();
“Perfect,” it implied. “This is how you scale SignalR across multiple pods.”
On paper, that’s a standard pattern. In our architecture, it was a trap.
We at NuageBiz.Tech were building on Dapr sidecars, where the entire point is to decouple application code from infrastructure. Injecting Redis directly into the app layer would have:
- Broken the abstraction layer Dapr provides
- Created tight infrastructure coupling
- Added another managed service to maintain and monitor
- Violated the core principle of Dapr: app talks to the sidecar, not to infra directly
The code “worked,” but the architecture was wrong.
Our team then spent time rewriting what the AI had generated.
That’s when it clicked for us: We weren’t fighting Cursor. We were fighting our own lack of constraints.
What Dapr Is (And Why AI Keeps Ignoring It)
Dapr (Distributed Application Runtime) is a cloud‑native runtime that offloads common distributed systems concerns into a sidecar:
- State management
- Pub/sub messaging
- Service invocation
- Bindings, secrets, and more
Instead of a service talking directly to Redis, SQL, or Kafka, it talks to a Dapr sidecar, and Dapr talks to the underlying infrastructure.
The problem our team ran into:
Most public examples, StackOverflow answers, and blog posts that AI models train on still show older patterns:
- SignalR + Redis backplanes
- Direct SQL for session state
- Hand‑rolled retry logic and pub/sub
So when we asked for “real‑time SignalR on Kubernetes,” the AI reached for what it had seen the most: Redis, not Dapr.
It wasn’t being “stupid.” It was being predictably biased toward historical patterns.
The Cursor Mistake: Architecture Mismatch
When we asked Cursor to scaffold a SignalR app for Kubernetes, it produced something like this (simplified illustration):
// ❌ Cursor's default
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSignalR()
.AddStackExchangeRedisBackplane("redis:6379");
services.AddSingleton<IConnectionIdService, RedisConnectionService>();
}
}
// ❌ Direct Redis calls for session state
public async Task SaveSessionAsync(string userId, Session data)
{
using var redis = ConnectionMultiplexer.Connect(_redisConnectionString);
var db = redis.GetDatabase();
var key = $"session:{userId}";
var json = JsonSerializer.Serialize(data);
await db.StringSetAsync(key, json);
}
Technically fine. Architecturally wrong for a Dapr‑first system.
What this code bakes in for the team:
- Direct dependency on Redis and SQL from the app layer
- Extra operational burden (Redis availability, scaling, backups)
- A split mental model: some things go through Dapr, some bypass it
In other words, the AI was smuggling “old world” patterns into a “new world” architecture.
The Shift: Copilot as Prompt Architect for the Team
The turning point was realizing:
“We shouldn’t be hand‑crafting complex prompts for Cursor individually. We should use another AI to write those prompts for us, as a team artifact.”
So our team effectively promoted Copilot to “Prompt Architect.”
Instead of asking Copilot for code, we asked it for constraints the whole team could reuse.
Step 1: Ask Copilot for a Constraint‑Rich Prompt
We gave cursor following prompt:
“Write a detailed technical prompt for an AI code generator (Cursor IDE). The app is an ASP.NET Core microservice running on Kubernetes with Dapr sidecars. It uses real‑time communication via SignalR, but should NOT use Redis. Instead, it should use Dapr’s state store for session data and Dapr pub/sub for messaging.”
Copilot generated a long, precise prompt that described:
- The environment (ASP.NET Core, Kubernetes, Dapr)
- The constraints (no Redis, no direct SQL)
- The desired building blocks (Dapr state store + pub/sub)
- Non‑functional concerns (resilience, observability, clean separation of concerns)
At this point, our team wasn’t touching any C# yet. We were just shaping the rules of the game together.
Step 2: Paste That Prompt into Cursor
Next, we opened Cursor and pasted Copilot’s generated prompt as the instruction block for a new file.
Same AI model. New behavior.
This time, the code it produced looked like this (simplified illustration):
// ✅ Dapr-first design
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSignalR();
builder.Services.AddDaprClient();
builder.Services.AddScoped<IConnectionStateService, DaprConnectionStateService>();
var app = builder.Build();
app.MapHub<ChatHub>("/chat");
}
}
// ✅ Dapr state store for sessions
public interface IConnectionStateService
{
Task SaveConnectionAsync(string connectionId, string userId);
Task<string> GetUserIdAsync(string connectionId);
}
public class DaprConnectionStateService : IConnectionStateService
{
private readonly DaprClient _daprClient;
private const string StoreName = "connection-state-store";
public DaprConnectionStateService(DaprClient daprClient)
{
_daprClient = daprClient;
}
public async Task SaveConnectionAsync(string connectionId, string userId)
{
await _daprClient.SaveStateAsync(StoreName, connectionId, new { userId });
}
}
No Redis. No direct SQL. Everything flows through Dapr.
This wasn’t a different AI. It was the same AI, operating under a better architectural contract our team provided.
Results: Before vs After for the Team
When we compared the “Redis default” approach to the Dapr‑aligned approach, several differences were obvious:
Before (Redis default)
- Tight coupling between app code and Redis
- Extra setup time for Redis in every environment
- More custom glue code around connection management and retries
After (Dapr‑aligned)
- App code talks to Dapr only; infra can be swapped without touching business logic
- Faster deployments in environments that already inject Dapr sidecars
- Less custom plumbing; more reuse of a known Dapr pattern
- Clear mental model for the team: “If it touches infra, it goes through Dapr”
The AI didn’t get “smarter.” Our use of AI, as a team, got more disciplined.
Key Lessons for Our Team
- Cursor is not the problem. Underspecified prompts are. If the model doesn’t know the team’s architectural rules, it will fall back to whatever the internet did for the last decade.
- Meta‑prompting scales better than hand‑prompting. Using other AIs like Copilot to write prompts for Cursor when in a tough spot is faster than manually expressing every constraint.
- Docs are still the ground truth. After Cursor generates code, a quick pass through official Dapr documentation catches subtle mismatches before they hit production.
- Guardrails prevent drift across the team. Once we encode “no Redis, use Dapr state store/pubsub” as non‑negotiable constraints, every future AI interaction respects that design.
- AI debates beat AI oracles. Copilot and Cursor “disagree” through the team’s prompts. Docs act as the final arbiter. The team stays in control.
How Your Team Can Try This in a Dapr Project
If your team is using Dapr and AI tools today, here’s a practical way to experiment:
- Pick a small, non‑critical service.
- As a team, write down your architectural constraints as 5–10 bullet points.
- Ask Copilot (or similar) to turn those into a prompt for your code generator (Cursor or equivalent).
- Use that prompt as the instruction block for any new or refactored file.
- Validate the generated code against Dapr’s docs before merging pull requests.
You’ll likely notice:
- Less “fighting” with the IDE
- Less rework on AI‑generated code during code review
- More time spent on system design instead of syntax and plumbing
Closing Thought
The future of AI‑assisted development isn’t about one “perfect” assistant.
It’s about orchestrating a small team of specialized AIs around your human team:
- One to express constraints
- One to implement within those constraints
- One to anchor you in reality with up‑to‑date documentation
Your team remains the architect.
The next time an AI IDE reaches for Redis inside a Dapr app, don’t just fix the code.
Fix the workflow your team uses with AI.