Open a hundred agentic AI job postings and count the ones that list Python as a hard requirement. It will be close to a hundred. “Python required.” “Strong Python experience.” “LangChain or LlamaIndex a plus.” The message to every engineer reading them is unambiguous: if you want to build agents for a living, you write Python or you do not apply.
I have spent the better part of thirty years shipping production systems on the Microsoft stack, and I am here to tell you that requirement is, in a large and growing number of cases, wrong. Not arguable. Wrong. You do not need Python to deploy agentic AI systems. And if you already run a .NET shop, choosing Python for your agents is not the safe default everyone assumes it is. It is very often the more expensive, more fragile, and more operationally painful choice.
Let me make the case the way I make every case: from what actually happens when you put this stuff into production and then have to keep it running at three in the morning.
The category error hiding inside every job ad
The reason “Python required” appears on agentic job ads is that the industry has quietly conflated two entirely different jobs and given them the same two-letter name.
The first job is building the models. Pretraining a foundation model from scratch, inventing new architectures, pushing the research frontier, and the heavy data science that surrounds all of it: the tensor math, the notebooks, the PyTorch and Hugging Face universe. That work is Python’s home turf and I am not going to pretend otherwise. Nobody is rewriting PyTorch in C#, and nobody should. If your job is to train a frontier model or run a research lab, you live in Python and you are right to.
The second job is building agentic systems that call models that already exist. Orchestration. Tool calling. Retrieval. Memory. Multi-agent workflows. Wiring a language model into a business process so it can reason, act, and be observed and governed. This is application engineering. It is the discipline of taking a model you did not train and making it do useful, reliable work inside a real system, with real users, real data, and real uptime requirements.
These are not the same job. They barely rhyme. One is research and the other is production software engineering. But because both got branded “AI,” the hiring pipeline pattern-matched on the research meaning and stamped “Python required” onto roles that are, in practice, orchestration and integration work, which is work that .NET does at least as well and frequently better. The requirement is cargo cult. It got copied out of the data-science job description and into the application-engineering job description because nobody stopped to notice they had become different things.
Once you see that, the rest of the argument follows.
And no, fine-tuning does not force you into Python either
Here is where someone objects: what about fine-tuning? Surely if you want to adapt a model to your own data, you have to drop into Python and write a training loop. That used to be true. It is not true anymore, and it is worth saying plainly, because it is the single most common reason a .NET shop talks itself into standing up a Python service it does not actually need.
Applied fine-tuning, the kind an enterprise actually does, which is taking an existing model and teaching it your domain, your tone, and your task, has become a managed operation you configure rather than code. In Azure AI Foundry you prepare your examples as a JSONL file, pick a base model from the catalog, choose a technique, and start the job from the portal. Foundry runs the training on managed infrastructure, with no GPU quota to chase and no CUDA to babysit, and hands you back a deployable model. The serverless path covers supervised fine-tuning, direct preference optimization, and reinforcement fine-tuning across a deep catalog that includes the GPT-4.1 family, GPT-4o, reasoning models like o4-mini, and open-weight models like Llama and Qwen, and it is billed by the token rather than by a rack of GPUs you rent by the hour. There is no PyTorch anywhere in that workflow. There is barely any code at all.
Notice where that leaves a .NET shop. Fine-tuning becomes just another thing you do inside the Azure estate you already run, through the same portal, the same identity, and the same billing as everything else, with no Python detour at all. If you genuinely need deeper control, with custom training loops, exotic architectures, or models that are not in the catalog, the managed-compute path exists, and yes, that is where Python and AzureML legitimately come back in. But that is a specialist’s corner, not the main road, and it is emphatically not what the job ad means when it stamps Python required on a role that is really about shipping agents. The honest border is narrower than people assume: pretraining foundation models and frontier research belong to Python, and applied fine-tuning of existing models simply does not.
.NET 10+ (11, 12…), told honestly
Let me talk about the platform, and let me do it without the usual benchmark theater, because benchmark theater is exactly the kind of thing I spend my Substack tearing apart when executives do it.
Yes, .NET is faster than Python. This is not controversial and it is not close. C# is compiled and JIT-optimized; CPython is interpreted and carries the Global Interpreter Lock. On raw web-serving benchmarks, ASP.NET Core on Kestrel sits near the top of the TechEmpower charts while the fastest Python frameworks sit well below it, and independent request-per-second tests routinely show Kestrel handling far more throughput, at lower and more consistent latency, than FastAPI on Uvicorn. .NET 10, which shipped in November 2025 as a Long-Term Support release supported through November 2028, is the fastest .NET yet. The runtime team’s work on JIT inlining, method devirtualization, and stack allocation has produced double-digit-percentage throughput improvements and meaningful memory reductions over the previous release, according to both Microsoft’s own performance deep dives and third-party benchmarking.
Here is where I part company with the lazy version of this argument. If I stood up and told you my orchestration layer benchmarks faster, therefore my agents are faster, any architect worth hiring would tune me out, and they would be right to. In a single agent turn, the thing that dominates your latency is not your language. It is the round trip to the model. A model call takes anywhere from a few hundred milliseconds to several seconds to generate its tokens, and against that wall of network-and-inference latency, the difference between a compiled and an interpreted orchestration layer for that one call is a rounding error. Anyone who tells you .NET makes your agent respond faster on a single request is selling you something.
So where does the speed actually pay off? In everything around the model call, which is where agentic systems actually live or die.
First, parallelism. Real agentic workloads fan out. You are calling three tools at once, running a group of agents concurrently, embedding a batch of documents, hitting a vector store while streaming a response. Python’s Global Interpreter Lock means true CPU parallelism inside a single process is a fight you are always managing with multiprocessing workarounds and process pools. .NET gives you real threads and a mature async model that was not bolted on after the fact. It handles massive concurrency without the ceremony, and it does it in one process with shared memory.
Second, throughput and cost at scale. The model latency is fixed, but how many concurrent agent sessions one instance can hold, how much memory each one costs you, and how fast a cold container comes up are not fixed, and those are the numbers on your cloud bill. The NativeAOT support in .NET 10 lets you ship a trimmed, self-contained native binary with a small memory footprint and near-instant cold start, which is exactly what you want for containerized, scale-to-zero agent hosting. Lower memory per session and faster cold starts mean more sessions per node and a smaller bill for the identical workload. The model latency did not change; your infrastructure efficiency did.
Third, predictability under load. Production agentic systems are judged on their tail latency, not their happy path. .NET’s allocation discipline and garbage collector behavior under sustained concurrent load give you more predictable ninety-ninth-percentile response times than a Python service fighting the lock and reference-counting churn. When you are the one on call, predictable is worth more than clever.
And then there is the boring, decisive stuff that has nothing to do with speed and everything to do with running software for years. Compile-time type safety across a complex multi-agent orchestration catches whole classes of failure before they ship, the kind of failures that in a dynamically typed pipeline surface as a runtime exception three layers deep at the worst possible moment. .NET 10 ships with post-quantum cryptography support, a first-class dependency and security story, and an ecosystem of more than 478,000 NuGet packages, on the same runtime that powers Xbox, Bing, Teams, and Azure Cosmos DB in production. This is not a hobbyist platform playing catch-up. It is the platform a very large amount of the world’s critical software already runs on.
The framework excuse just died
The last honest reason to reach for Python was the frameworks. For a while, if you wanted mature agent orchestration primitives, the good stuff really was in Python: LangChain, then LangGraph, CrewAI, LlamaIndex, AutoGen. That gap is now closed, and it was closed by Microsoft.
On April 2, 2026, the Microsoft Agent Framework reached 1.0 General Availability. It is the convergence of two projects Microsoft had been running in parallel: AutoGen, which brought the multi-agent orchestration research, and Semantic Kernel, which brought the enterprise memory, plugin architecture, and connectors that .NET shops were already using in production. Both of those are now in maintenance mode. The future is the unified framework, and it shipped with stable, versioned APIs and a long-term support commitment. This is not a preview. This is not a research toy. It is a production SDK with a support contract behind it.
What you get in C#, natively, is the full modern agentic toolkit. Model Context Protocol support is generally available, so your agents discover and call external tools without you hand-writing an HTTP wrapper for every internal API. The Agent-to-Agent protocol lets agents coordinate across runtimes. You get stable implementations of the real orchestration patterns, including sequential handoffs, group chat, and the Magentic-One planning pattern, plus a middleware pipeline for injecting your own logic into the agent’s execution, an agent harness with shell and filesystem access and human-in-the-loop approval flows, and, if you want it, hosted agents on Foundry with per-session isolation, scale-to-zero, and OpenTelemetry traces flowing straight into Application Insights with zero extra wiring. It is model-agnostic and MIT-licensed, and it runs against anything, whether that is OpenAI, Azure, or a local Ollama or ONNX model on your own hardware.
Now the honest part, because I flag my own weak points before someone in the comments does it for me. The Microsoft Agent Framework is not a .NET-only framework. It ships with a first-class Python SDK too, with deliberately consistent APIs across both languages. So I am not going to insult your intelligence by claiming that the Microsoft Agent Framework proves .NET beats Python. What it actually proves is more useful than that. It proves that the capability gap is gone. For years the argument for Python in an agentic project was that it is where the good frameworks are. Microsoft just shipped the same framework, with the same capabilities, in both languages. Which means the decision no longer turns on capability at all. It turns on runtime and ecosystem, and that is a fight .NET wins.
While that consolidation was happening on the Microsoft side, the Python framework world was going the other direction. LangChain reached its own 1.0 in October 2025 and re-platformed onto LangGraph, which genuinely addressed some of the old black-box complaints. But the reputation was earned the hard way. The canonical critique, Octomind’s widely circulated account of why they no longer use LangChain, was about too many abstraction layers, APIs that broke on nearly every release, and errors that propagate through so many wrappers that the stack trace ends up pointing at the wrong layer entirely. Through early 2026 there has been a quiet but real migration of production teams off the heavy frameworks and back toward raw provider SDKs and direct API calls, on the logic that once the vendor APIs converged, the abstraction stopped paying for its own maintenance cost. That is the state of the art you are being told is mandatory: a framework ecosystem that a meaningful slice of its own senior users are actively backing out of. I am not telling you LangGraph or CrewAI are bad. They are capable tools built by serious people. I am telling you that the claim you must use them is a myth, and that the .NET alternative is not a compromise.
The real argument: you live in an ecosystem
Everything above matters, but if you take one thing from this piece, take this. Software does not run in a language. It runs in an ecosystem, and the cost of a technology choice is dominated by how it fits the ecosystem you already have.
Picture the common case. You are a .NET shop. Your services are C#. Your data layer is EF Core against SQL Server. Your identity is Entra. Your observability is already wired. Your team is a .NET team, your continuous integration builds .NET, your security scanning understands your .NET dependencies, and your on-call runbooks are written for .NET services. Now someone tells you the agent has to be Python.
Here is what that decision actually costs, and it is never on the slide. You now run a second language runtime in production. You maintain a second deployment target and a second packaging story. You carry a second dependency-management and vulnerability-scanning regime, because pip and NuGet are different worlds with different failure modes. You wire a second observability integration. You re-model your domain objects as transfer objects at the language boundary and then keep two definitions of the same types in sync forever, and every serialization mismatch across that boundary is a bug waiting to happen. You need people who can be on call for the Python service, which is a different skill set from the one your team has. You have, in a word, gone polyglot, and polyglot is a tax you pay every single day the system is alive, not a one-time cost at the kickoff meeting.
Now picture the .NET path. The agent is a C# service. It shares your domain types end to end, with no boundary, no duplication, and no drift. It builds through the same pipeline, ships as the same kind of artifact, and lives under the same security posture and the same identity story as everything else you run. Its telemetry flows through your existing OpenTelemetry setup into the same dashboards your team already watches. And here is the part that should settle it for anyone doing retrieval: your vector search does not have to leave your database. SQL Server 2025 has native vector search. Your embeddings, your retrieval, and your operational data can sit in the same engine, next to each other, under the same transactional guarantees, instead of being bolted onto a separate Python service talking to a separate vector store across a network hop. The agent stops being a foreign appendage grafted onto your estate and becomes what it should be, which is just another service, indistinguishable in operational terms from the dozen others your team already runs well.
That is the whole game. In an ecosystem, the best tool is very often the one that disappears into the stack you already have. For a .NET shop building agents, that tool is .NET.
Financial and government systems raise the stakes
Now raise the stakes. Suppose you are not shipping a chatbot for a marketing team. Suppose you are shipping into a bank, an insurer, a hospital, or a government agency, where a breach is not an incident report but a regulator, a headline, and sometimes a law. Here the platform choice stops being about developer preference and starts being about your attack surface and your audit trail. And here I have to be careful, because the lazy version of this argument, the one that goes Python is insecure and .NET is secure, is wrong, and if I said it the first security engineer to read this piece would be right to close the tab. Python is a memory-safe, managed language, the same as C#. Neither one carries the buffer-overflow and use-after-free vulnerability classes that haunt C and C++. And PyPI has hardened considerably, with mandatory two-factor authentication for maintainers and trusted publishing. The language is not the problem.
The real difference is the supply chain, and it is a difference of shape, not of registry. Every open package ecosystem is under active attack right now, including npm, PyPI, and yes, NuGet; no registry is immune, and anyone who tells you otherwise is not paying attention. But look at what a typical Python agentic stack actually installs. LangChain alone drags in a deep tree of transitive dependencies; add an orchestration proxy, a handful of provider SDKs, and a vector-store client, and you are now trusting dozens of independently maintained packages, any single one of which is a door. That is not a hypothetical. In March 2026, attackers published backdoored versions of LiteLLM, a widely used model gateway that agent frameworks and MCP servers pull in as a transitive dependency and that is downloaded on the order of millions of times a day, and for the window those versions were live, a plain install harvested cloud credentials, SSH keys, and Kubernetes secrets out of every environment that touched them. The compromise was serious enough that NHS England issued a national cyber alert over it. Read that again: an AI-orchestration package, installed transitively, turned into a credential stealer inside government health infrastructure. That is the exact category of system we are talking about, and that is the exact attack path.
A .NET agentic stack does not make you immune to any of this, and I am not going to pretend it does. But it shrinks the surface that gets you hit. Build on the Microsoft Agent Framework, the Microsoft.Extensions.AI abstractions, and ASP.NET Core, and the packages carrying your critical path are overwhelmingly first-party, signed, and patched by a single vendor on a predictable monthly cadence, rather than a sprawling tree of community packages each with its own maintainer, its own release discipline, and its own blast radius. NuGet supports package signing, and .NET ships built-in vulnerability auditing that flags known-bad dependencies at restore time, with the auditing story improved again in .NET 10. The whole platform sits under Microsoft’s Secure Future Initiative, which is the practical difference between a runtime that someone maintains and a runtime that a company has staked its reputation on securing. Fewer third parties inside your trust boundary, signed and audited, patched by one vendor you can actually hold accountable, is a materially smaller attack surface for the identical job. And the static typing helps here too, quietly: whole classes of defect that become a runtime surprise in a loosely typed pipeline simply do not compile in C#.
For government work specifically, there is a factor that tends to end the debate before it starts, and it is the compliance stack. .NET is the native, first-party runtime for the entire Microsoft government-cloud and compliance apparatus. Azure Government, FedRAMP High, the Department of Defense impact levels, Entra identity, managed identities, Key Vault, and the post-quantum cryptography that shipped in .NET 10 for exactly the harvest-now-decrypt-later threat that regulators have started asking about, all of it is designed for this stack, certified against it, and supported on it. You can absolutely run Python inside Azure Government. But you will be integrating a second runtime into an apparatus that treats .NET as the first-class citizen, and in a compliance audit, first-class-citizen integration and a single-vendor accountability chain are not conveniences. They are the difference between passing and explaining.
So, to be clear, the security argument is not that .NET is safe and Python is dangerous. It is that when a breach carries a regulator and a headline instead of a shrug, you want the smallest, most auditable, most single-vendor-accountable attack surface you can get your hands on, and for agentic systems inside a Microsoft shop, that is .NET. The higher the stakes, the more that gap matters.
Bottom line
So let me be precise, because precision is the point.
If you are pretraining a foundation model, pushing the research frontier, or doing the heavy data science underneath it, use Python. That is not a concession I am making grudgingly. It is simply correct, and anyone who tells you to rewrite a training pipeline like that in C# is as wrong as the job ads are. But that is a narrow slice of the work, and it is not what most of these AI engineer roles are actually asking for.
But if your job is to deploy agentic systems, to orchestrate models that already exist into reliable, observable, governable production software, then the “Python required” line on the job ad is describing a preference that someone forgot to question, not a technical necessity. .NET 10 is faster where speed actually matters, more predictable where predictability actually matters, smaller and more auditable in the attack surface that survives a compliance review, and backed by a production-grade agent framework that shipped in April with the same capabilities the Python world offers. And if you already live in the Microsoft ecosystem, .NET is not the tolerable second choice. It is the better one.
You do not need Python to deploy agentic AI. You need to ship. I have been doing it in .NET the whole time.
About the Author
Gal Ratner is a software architect with nearly thirty years of production experience on the Microsoft and .NET stack, and the founder and CTO of Inverted Software and WhiteStar Labs. He has delivered production systems for clients including Microsoft, Sony, Rockstar Games, 2K Games, Best Buy, and Allegiant Air, was an early engineer at Break.com, and is a Los Angeles Business Journal CTO of the Year finalist. His current work is squarely in production agentic AI, spanning MCP servers, retrieval pipelines, the Microsoft Agent Framework, SQL Server 2025 vector search, and his own PLogger observability framework, building the kind of systems this article is about rather than writing about them from the sidelines. He publishes as the .NET AI Guy That Ships, an anti-hype, practitioner-first take on the AI industry for the people who have to make this stuff actually work. He writes at galratner.com.



